MCPcopy Create free account
hub / github.com/emscripten-core/emscripten / lexically_normal

Method lexically_normal

system/lib/libcxx/src/filesystem/path.cpp:160–235  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

158}
159
160path path::lexically_normal() const {
161 if (__pn_.empty())
162 return *this;
163
164 using PartKindPair = pair<string_view_t, PathPartKind>;
165 vector<PartKindPair> Parts;
166 // Guess as to how many elements the path has to avoid reallocating.
167 Parts.reserve(32);
168
169 // Track the total size of the parts as we collect them. This allows the
170 // resulting path to reserve the correct amount of memory.
171 size_t NewPathSize = 0;
172 auto AddPart = [&](PathPartKind K, string_view_t P) {
173 NewPathSize += P.size();
174 Parts.emplace_back(P, K);
175 };
176 auto LastPartKind = [&]() {
177 if (Parts.empty())
178 return PK_None;
179 return Parts.back().second;
180 };
181
182 bool MaybeNeedTrailingSep = false;
183 // Build a stack containing the remaining elements of the path, popping off
184 // elements which occur before a '..' entry.
185 for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) {
186 auto Part = *PP;
187 PathPartKind Kind = ClassifyPathPart(Part);
188 switch (Kind) {
189 case PK_Filename:
190 case PK_RootSep: {
191 // Add all non-dot and non-dot-dot elements to the stack of elements.
192 AddPart(Kind, Part);
193 MaybeNeedTrailingSep = false;
194 break;
195 }
196 case PK_DotDot: {
197 // Only push a ".." element if there are no elements preceding the "..",
198 // or if the preceding element is itself "..".
199 auto LastKind = LastPartKind();
200 if (LastKind == PK_Filename) {
201 NewPathSize -= Parts.back().first.size();
202 Parts.pop_back();
203 } else if (LastKind != PK_RootSep)
204 AddPart(PK_DotDot, PATHSTR(".."));
205 MaybeNeedTrailingSep = LastKind == PK_Filename;
206 break;
207 }
208 case PK_Dot:
209 case PK_TrailingSep: {
210 MaybeNeedTrailingSep = true;
211 break;
212 }
213 case PK_None:
214 __libcpp_unreachable();
215 }
216 }
217 // [fs.path.generic]p6.8: If the path is empty, add a dot.

Callers 1

__weakly_canonicalFunction · 0.80

Calls 8

ClassifyPathPartFunction · 0.85
__libcpp_unreachableFunction · 0.85
emplace_backMethod · 0.80
sizeMethod · 0.65
emptyMethod · 0.45
reserveMethod · 0.45
backMethod · 0.45
pop_backMethod · 0.45

Tested by

no test coverage detected