MCPcopy Create free account
hub / github.com/Kitware/CMake / ResolveComponent

Method ResolveComponent

Source/cmPathResolver.cxx:316–432  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

314
315template <class Policy>
316Control Impl<Policy>::ResolveComponent(Root root,
317 std::string::size_type root_slash,
318 std::string::size_type slash)
319{
320 // Look for the '/' or end-of-input that ends this component.
321 // The sample paths in comments below show the trailing slash
322 // even if it is actually beyond the end of the path.
323 std::string::size_type next_slash = P.find('/', slash + 1);
324 if (next_slash == std::string::npos) {
325 next_slash = P.size();
326 }
327 cm::string_view c =
328 cm::string_view(P).substr(slash + 1, next_slash - (slash + 1));
329
330 if (slash == root_slash) {
331 if (c.empty() || c == "."_s || c == ".."_s) {
332 // This is an empty, '.', or '..' component at the root.
333 // Drop the component and its trailing slash, if any,
334 // while preserving the root slash:
335 // "//" => "/"
336 // "/./" => "/"
337 // "/../" => "/"
338 // ^slash ^slash
339 P.erase(slash + 1, next_slash - slash);
340 return Control::Continue(slash);
341 }
342 } else {
343 if (c.empty() || c == "."_s) {
344 // This is an empty or '.' component not at the root.
345 // Drop the component and its leading slash:
346 // "*//" => "*/"
347 // "*/./" => "*/"
348 // ^slash ^slash
349 P.erase(slash, next_slash - slash);
350 return Control::Continue(slash);
351 }
352
353 if (c == ".."_s) {
354 // This is a '..' component not at the root.
355 // Rewind to the previous component:
356 // "*/prev/../" => "*/prev/../"
357 // ^slash ^slash
358 next_slash = slash;
359 slash = P.rfind('/', slash - 1);
360
361 if (Policy::Symlinks == Options::Symlinks::Lazy) {
362 cmsys::Status status;
363 std::string path = P.substr(0, next_slash);
364 if (cm::optional<std::string> maybe_symlink_target =
365 this->ReadSymlink(path, status)) {
366 return this->ResolveSymlink(root, slash, next_slash,
367 std::move(*maybe_symlink_target));
368 }
369 if (!status && Policy::Existence == Options::Existence::Required) {
370 P = std::move(path);
371 return Control::Error(status);
372 }
373 }

Callers 1

ResolvePathMethod · 0.95

Calls 14

ContinueEnum · 0.85
moveFunction · 0.85
eraseMethod · 0.80
rfindMethod · 0.80
ResolveSymlinkMethod · 0.80
lengthMethod · 0.80
ErrorClass · 0.70
findMethod · 0.45
sizeMethod · 0.45
substrMethod · 0.45
emptyMethod · 0.45
ReadSymlinkMethod · 0.45

Tested by

no test coverage detected