| 491 | } |
| 492 | |
| 493 | std::string Path::Canonicalize(const std::string_view path) |
| 494 | { |
| 495 | std::vector<std::string_view> components = Path::SplitNativePath(path); |
| 496 | std::vector<std::string_view> new_components; |
| 497 | new_components.reserve(components.size()); |
| 498 | for (const std::string_view& component : components) |
| 499 | { |
| 500 | if (component == ".") |
| 501 | { |
| 502 | // current directory, so it can be skipped, unless it's the only component |
| 503 | if (components.size() == 1) |
| 504 | new_components.push_back(std::move(component)); |
| 505 | } |
| 506 | else if (component == "..") |
| 507 | { |
| 508 | // parent directory, pop one off if we're not at the beginning, otherwise preserve. |
| 509 | if (!new_components.empty()) |
| 510 | new_components.pop_back(); |
| 511 | else |
| 512 | new_components.push_back(std::move(component)); |
| 513 | } |
| 514 | else |
| 515 | { |
| 516 | // anything else, preserve |
| 517 | new_components.push_back(std::move(component)); |
| 518 | } |
| 519 | } |
| 520 | |
| 521 | return Path::JoinNativePath(new_components); |
| 522 | } |
| 523 | |
| 524 | void Path::Canonicalize(std::string* path) |
| 525 | { |