1b63cd4dbSSam McCall //===--- Path.cpp -------------------------------------------*- C++-*------===//
2b63cd4dbSSam McCall //
3b63cd4dbSSam McCall // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b63cd4dbSSam McCall // See https://llvm.org/LICENSE.txt for license information.
5b63cd4dbSSam McCall // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b63cd4dbSSam McCall //
7b63cd4dbSSam McCall //===----------------------------------------------------------------------===//
8b63cd4dbSSam McCall
9b63cd4dbSSam McCall #include "support/Path.h"
10ecea7218SKadir Cetinkaya #include "llvm/Support/Path.h"
11b63cd4dbSSam McCall namespace clang {
12b63cd4dbSSam McCall namespace clangd {
13b63cd4dbSSam McCall
14ecea7218SKadir Cetinkaya #ifdef CLANGD_PATH_CASE_INSENSITIVE
maybeCaseFoldPath(PathRef Path)15ecea7218SKadir Cetinkaya std::string maybeCaseFoldPath(PathRef Path) { return Path.lower(); }
pathEqual(PathRef A,PathRef B)16*86029e4cSMartin Storsjö bool pathEqual(PathRef A, PathRef B) { return A.equals_insensitive(B); }
17ecea7218SKadir Cetinkaya #else // NOT CLANGD_PATH_CASE_INSENSITIVE
18ecea7218SKadir Cetinkaya std::string maybeCaseFoldPath(PathRef Path) { return Path.str(); }
19ecea7218SKadir Cetinkaya bool pathEqual(PathRef A, PathRef B) { return A == B; }
20ecea7218SKadir Cetinkaya #endif // CLANGD_PATH_CASE_INSENSITIVE
21b63cd4dbSSam McCall
absoluteParent(PathRef Path)226329ce75SKadir Cetinkaya PathRef absoluteParent(PathRef Path) {
236329ce75SKadir Cetinkaya assert(llvm::sys::path::is_absolute(Path));
246329ce75SKadir Cetinkaya #if defined(_WIN32)
256329ce75SKadir Cetinkaya // llvm::sys says "C:\" is absolute, and its parent is "C:" which is relative.
266329ce75SKadir Cetinkaya // This unhelpful behavior seems to have been inherited from boost.
276329ce75SKadir Cetinkaya if (llvm::sys::path::relative_path(Path).empty()) {
286329ce75SKadir Cetinkaya return PathRef();
296329ce75SKadir Cetinkaya }
306329ce75SKadir Cetinkaya #endif
316329ce75SKadir Cetinkaya PathRef Result = llvm::sys::path::parent_path(Path);
326329ce75SKadir Cetinkaya assert(Result.empty() || llvm::sys::path::is_absolute(Result));
336329ce75SKadir Cetinkaya return Result;
346329ce75SKadir Cetinkaya }
356329ce75SKadir Cetinkaya
pathStartsWith(PathRef Ancestor,PathRef Path,llvm::sys::path::Style Style)36ecea7218SKadir Cetinkaya bool pathStartsWith(PathRef Ancestor, PathRef Path,
37ecea7218SKadir Cetinkaya llvm::sys::path::Style Style) {
38cdef5a71SKadir Cetinkaya assert(llvm::sys::path::is_absolute(Ancestor) &&
39cdef5a71SKadir Cetinkaya llvm::sys::path::is_absolute(Path));
40ecea7218SKadir Cetinkaya // If ancestor ends with a separator drop that, so that we can match /foo/ as
41ecea7218SKadir Cetinkaya // a parent of /foo.
42ecea7218SKadir Cetinkaya if (llvm::sys::path::is_separator(Ancestor.back(), Style))
43ecea7218SKadir Cetinkaya Ancestor = Ancestor.drop_back();
44ecea7218SKadir Cetinkaya // Ensure Path starts with Ancestor.
45ecea7218SKadir Cetinkaya if (!pathEqual(Ancestor, Path.take_front(Ancestor.size())))
46ecea7218SKadir Cetinkaya return false;
47ecea7218SKadir Cetinkaya Path = Path.drop_front(Ancestor.size());
48ecea7218SKadir Cetinkaya // Then make sure either two paths are equal or Path has a separator
49ecea7218SKadir Cetinkaya // afterwards.
50ecea7218SKadir Cetinkaya return Path.empty() || llvm::sys::path::is_separator(Path.front(), Style);
51b63cd4dbSSam McCall }
52b63cd4dbSSam McCall } // namespace clangd
53b63cd4dbSSam McCall } // namespace clang
54