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