| //===--- Path.cpp -------------------------------------------*- C++-*------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "support/Path.h" |
| #include "llvm/Support/Path.h" |
| namespace clang { |
| namespace clangd { |
| |
| #ifdef CLANGD_PATH_CASE_INSENSITIVE |
| std::string maybeCaseFoldPath(PathRef Path) { return Path.lower(); } |
| bool pathEqual(PathRef A, PathRef B) { return A.equals_insensitive(B); } |
| #else // NOT CLANGD_PATH_CASE_INSENSITIVE |
| std::string maybeCaseFoldPath(PathRef Path) { return Path.str(); } |
| bool pathEqual(PathRef A, PathRef B) { return A == B; } |
| #endif // CLANGD_PATH_CASE_INSENSITIVE |
| |
| PathRef absoluteParent(PathRef Path) { |
| assert(llvm::sys::path::is_absolute(Path)); |
| #if defined(_WIN32) |
| // llvm::sys says "C:\" is absolute, and its parent is "C:" which is relative. |
| // This unhelpful behavior seems to have been inherited from boost. |
| if (llvm::sys::path::relative_path(Path).empty()) { |
| return PathRef(); |
| } |
| #endif |
| PathRef Result = llvm::sys::path::parent_path(Path); |
| assert(Result.empty() || llvm::sys::path::is_absolute(Result)); |
| return Result; |
| } |
| |
| bool pathStartsWith(PathRef Ancestor, PathRef Path, |
| llvm::sys::path::Style Style) { |
| assert(llvm::sys::path::is_absolute(Ancestor) && |
| llvm::sys::path::is_absolute(Path)); |
| // If ancestor ends with a separator drop that, so that we can match /foo/ as |
| // a parent of /foo. |
| if (llvm::sys::path::is_separator(Ancestor.back(), Style)) |
| Ancestor = Ancestor.drop_back(); |
| // Ensure Path starts with Ancestor. |
| if (!pathEqual(Ancestor, Path.take_front(Ancestor.size()))) |
| return false; |
| Path = Path.drop_front(Ancestor.size()); |
| // Then make sure either two paths are equal or Path has a separator |
| // afterwards. |
| return Path.empty() || llvm::sys::path::is_separator(Path.front(), Style); |
| } |
| } // namespace clangd |
| } // namespace clang |