| 209 | } |
| 210 | |
| 211 | Result<std::string> MakeAbstractPathRelative(const std::string& base, |
| 212 | const std::string& path) { |
| 213 | if (base.empty() || base.front() != kSep) { |
| 214 | return Status::Invalid("MakeAbstractPathRelative called with non-absolute base '", |
| 215 | base, "'"); |
| 216 | } |
| 217 | auto b = EnsureLeadingSlash(RemoveTrailingSlash(base)); |
| 218 | auto p = std::string_view(path); |
| 219 | if (p.substr(0, b.size()) != std::string_view(b)) { |
| 220 | return Status::Invalid("Path '", path, "' is not relative to '", base, "'"); |
| 221 | } |
| 222 | p = p.substr(b.size()); |
| 223 | if (!p.empty() && p.front() != kSep && b.back() != kSep) { |
| 224 | return Status::Invalid("Path '", path, "' is not relative to '", base, "'"); |
| 225 | } |
| 226 | return std::string(RemoveLeadingSlash(p)); |
| 227 | } |
| 228 | |
| 229 | bool IsAncestorOf(std::string_view ancestor, std::string_view descendant) { |
| 230 | ancestor = RemoveTrailingSlash(ancestor); |