PathV2.cpp revision 34ab1f6087bc0da1df0e3a73ac99762ef070d419
1dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//===-- PathV2.cpp - Implement OS Path Concept ------------------*- C++ -*-===// 2dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// 3dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// The LLVM Compiler Infrastructure 4dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// 5dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// This file is distributed under the University of Illinois Open Source 6dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// License. See LICENSE.TXT for details. 7dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// 8dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//===----------------------------------------------------------------------===// 9dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// 10dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// This file implements the operating system PathV2 API. 11dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// 12dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer//===----------------------------------------------------------------------===// 13dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 14dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "llvm/Support/PathV2.h" 15dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "llvm/Support/ErrorHandling.h" 16dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include <cctype> 17dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 18dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace { 19dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer using llvm::StringRef; 20dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 21dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool is_separator(const char value) { 22dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer switch(value) { 23dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32 24dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer case '\\': // fall through 25dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif 26dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer case '/': return true; 27dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer default: return false; 28dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 29dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 30dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 31dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32 32dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const StringRef separators = "\\/"; 33dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const char prefered_separator = '\\'; 34dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else 35dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const StringRef separators = "/"; 36dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const char prefered_separator = '/'; 37dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif 38dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 39dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef find_first_component(const StringRef &path) { 40dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Look for this first component in the following order. 41dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // * empty (in this case we return an empty string) 42dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // * either C: or {//,\\}net. 43dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // * {/,\} 44dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // * {.,..} 45dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // * {file,directory}name 46dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 47dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (path.empty()) 48dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return path; 49dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 50dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // C: 51dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (path.size() >= 2 && std::isalpha(path[0]) && path[1] == ':') 52dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return StringRef(path.begin(), 2); 53dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 54dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // //net 55dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if ((path.size() > 2) && 56dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer (path.startswith("\\\\") || path.startswith("//")) && 57dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer (path[2] != '\\' && path[2] != '/')) { 58dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Find the next directory separator. 59dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer size_t end = path.find_first_of("\\/", 2); 60dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (end == StringRef::npos) 61dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return path; 62dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer else 63dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return StringRef(path.begin(), end); 64dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 65dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 66dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // {/,\} 67dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (path[0] == '\\' || path[0] == '/') 68dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return StringRef(path.begin(), 1); 69dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 70dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (path.startswith("..")) 71dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return StringRef(path.begin(), 2); 72dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 73dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (path[0] == '.') 74dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return StringRef(path.begin(), 1); 75dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 76dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // * {file,directory}name 77dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer size_t end = path.find_first_of("\\/", 2); 78dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (end == StringRef::npos) 79dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return path; 80dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer else 81dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return StringRef(path.begin(), end); 82dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 83dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return StringRef(); 84dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 85a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 86a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t filename_pos(const StringRef &str) { 87a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (str.size() == 2 && 88a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer is_separator(str[0]) && 89a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer is_separator(str[1])) 90a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return 0; 91a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 92a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (str.size() > 0 && is_separator(str[str.size() - 1])) 93a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return str.size() - 1; 94a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 95a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t pos = str.find_last_of(separators, str.size() - 1); 96a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 97a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#ifdef LLVM_ON_WIN32 98a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (pos == StringRef::npos) 99a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer pos = str.find_last_of(':', str.size() - 2); 100a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#endif 101a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 102a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (pos == StringRef::npos || 103a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer (pos == 1 && is_separator(str[0]))) 104a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return 0; 105a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 106a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return pos + 1; 107a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer } 108a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 109a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t root_dir_start(const StringRef &str) { 110a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer // case "c:/" 111a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#ifdef LLVM_ON_WIN32 112a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (str.size() > 2 && 113a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer str[1] == ':' && 114a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer is_separator(str[2])) 115a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return 2; 116a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#endif 117a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 118a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer // case "//" 119a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (str.size() == 2 && 120a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer is_separator(str[0]) && 121a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer str[0] == str[1]) 122a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return StringRef::npos; 123a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 124a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer // case "//net" 125a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (str.size() > 3 && 126a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer is_separator(str[0]) && 127a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer str[0] == str[1] && 128a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer !is_separator(str[2])) { 129a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return str.find_first_of(separators, 2); 130a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer } 131a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 132a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer // case "/" 133a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (str.size() > 0 && is_separator(str[0])) 134a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return 0; 135a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 136a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return StringRef::npos; 137a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer } 138a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 139a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t parent_path_end(const StringRef &path) { 140a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t end_pos = filename_pos(path); 141a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 142a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]); 143a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 144a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer // Skip separators except for root dir. 145a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t root_dir_pos = root_dir_start(StringRef(path.begin(), end_pos)); 146a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 147a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer while(end_pos > 0 && 148a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer (end_pos - 1) != root_dir_pos && 149a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer is_separator(path[end_pos - 1])) 150a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer --end_pos; 151a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 152a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep) 153a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return StringRef::npos; 154a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 155a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return end_pos; 156a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer } 157dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 158dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 159dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace llvm { 160dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace sys { 161dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencernamespace path { 162dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 163dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerconst_iterator begin(const StringRef &path) { 164dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const_iterator i; 165dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer i.Path = path; 166dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer i.Component = find_first_component(path); 167dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer i.Position = 0; 168dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return i; 169dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 170dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 171dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerconst_iterator end(const StringRef &path) { 172dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const_iterator i; 173dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer i.Path = path; 174dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer i.Position = path.size(); 175dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return i; 176dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 177dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 178dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerconst_iterator &const_iterator::operator++() { 179dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer assert(Position < Path.size() && "Tried to increment past end!"); 180dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 181dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Increment Position to past the current component 182dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer Position += Component.size(); 183dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 184dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Check for end. 185dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (Position == Path.size()) { 186dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer Component = StringRef(); 187dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return *this; 188dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 189dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 190dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Both POSIX and Windows treat paths that begin with exactly two separators 191dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // specially. 192dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool was_net = Component.size() > 2 && 193dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer is_separator(Component[0]) && 194dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer Component[1] == Component[0] && 195dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer !is_separator(Component[2]); 196dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 197dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Handle separators. 198dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (is_separator(Path[Position])) { 199dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Root dir. 200dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (was_net 201dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32 202dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // c:/ 203dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer || Component.endswith(":") 204dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif 205dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer ) { 206dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer Component = StringRef(Path.begin() + Position, 1); 207dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return *this; 208dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 209dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 210dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Skip extra separators. 211dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer while (Position != Path.size() && 212dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer is_separator(Path[Position])) { 213dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer ++Position; 214dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 215dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 216dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Treat trailing '/' as a '.'. 217dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (Position == Path.size()) { 218dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer --Position; 219dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer Component = "."; 220dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return *this; 221dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 222dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 223dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 224dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Find next component. 225dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer size_t end_pos = Path.find_first_of(separators, Position); 226dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (end_pos == StringRef::npos) 227dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer end_pos = Path.size(); 228dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer Component = StringRef(Path.begin() + Position, end_pos - Position); 229dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 230dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return *this; 231dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 232dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 233a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencerconst_iterator &const_iterator::operator--() { 234a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer // If we're at the end and the previous char was a '/', return '.'. 235a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (Position == Path.size() && 236a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer Path.size() > 1 && 237a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer is_separator(Path[Position - 1]) 238a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#ifdef LLVM_ON_WIN32 239a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer && Path[Position - 2] != ':' 240a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer#endif 241a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer ) { 242a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer --Position; 243a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer Component = "."; 244a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return *this; 245a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer } 246a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 247a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer // Skip separators unless it's the root directory. 248a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t root_dir_pos = root_dir_start(Path); 249a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t end_pos = Position; 250a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 251a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer while(end_pos > 0 && 252a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer (end_pos - 1) != root_dir_pos && 253a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer is_separator(Path[end_pos - 1])) 254a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer --end_pos; 255a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 256a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer // Find next separator. 257a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t start_pos = filename_pos(StringRef(Path.begin(), end_pos)); 258a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer Component = StringRef(Path.begin() + start_pos, end_pos - start_pos); 259a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer Position = start_pos; 260a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return *this; 261a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer} 262a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 263dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerbool const_iterator::operator==(const const_iterator &RHS) const { 264dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return Path.begin() == RHS.Path.begin() && 265dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer Position == RHS.Position; 266dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 267dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 268dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerbool const_iterator::operator!=(const const_iterator &RHS) const { 269dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return !(*this == RHS); 270dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 271dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 272a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencerptrdiff_t const_iterator::operator-(const const_iterator &RHS) const { 273a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return Position - RHS.Position; 274a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer} 275a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 276dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code root_path(const StringRef &path, StringRef &result) { 277dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const_iterator b = begin(path), 278dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer pos = b, 279dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer e = end(path); 280dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (b != e) { 281dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0]; 282dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool has_drive = 283dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32 284dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer b->endswith(":"); 285dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else 286dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer false; 287dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif 288dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 289dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (has_net || has_drive) { 290dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if ((++pos != e) && is_separator((*pos)[0])) { 291dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // {C:/,//net/}, so get the first two components. 292dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = StringRef(path.begin(), b->size() + pos->size()); 293dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 294dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } else { 295dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // just {C:,//net}, return the first component. 296dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = *b; 297dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 298dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 299dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 300dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 301dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // POSIX style root directory. 302dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (is_separator((*b)[0])) { 303dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = *b; 304dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 305dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 306dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 307dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // No root_path. 308dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = StringRef(); 309dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 310dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 311dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 312dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // No path :(. 313dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = StringRef(); 314dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 315dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 316dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 317dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code root_name(const StringRef &path, StringRef &result) { 318dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const_iterator b = begin(path), 319dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer e = end(path); 320dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (b != e) { 321dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0]; 322dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool has_drive = 323dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32 324dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer b->endswith(":"); 325dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else 326dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer false; 327dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif 328dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 329dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (has_net || has_drive) { 330dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // just {C:,//net}, return the first component. 331dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = *b; 332dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 333dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 334dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 335dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 336dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // No path or no name. 337dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = StringRef(); 338dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 339dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 340dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 341dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code root_directory(const StringRef &path, StringRef &result) { 342dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const_iterator b = begin(path), 343dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer pos = b, 344dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer e = end(path); 345dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (b != e) { 346dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0]; 347dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool has_drive = 348dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#ifdef LLVM_ON_WIN32 349dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer b->endswith(":"); 350dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#else 351dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer false; 352dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif 353dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 354dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if ((has_net || has_drive) && 355dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // {C:,//net}, skip to the next component. 356dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer (++pos != e) && is_separator((*pos)[0])) { 357dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = *pos; 358dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 359dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 360dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 361dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // POSIX style root directory. 362dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (!has_net && is_separator((*b)[0])) { 363dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = *b; 364dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 365dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 366dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 367dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 368dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // No path or no root. 369dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = StringRef(); 370dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 371dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 372dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 373dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code has_root_name(const Twine &path, bool &result) { 374dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallString<128> storage; 375dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef p = path.toStringRef(storage); 376dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 377dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = root_name(p, p)) return ec; 378dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = !p.empty(); 379dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 380dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 381dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 382dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code has_root_directory(const Twine &path, bool &result) { 383dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallString<128> storage; 384dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef p = path.toStringRef(storage); 385dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 386dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = root_directory(p, p)) return ec; 387dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = !p.empty(); 388dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 389dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 390dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 391dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code relative_path(const StringRef &path, StringRef &result) { 392dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef root; 393dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = root_path(path, root)) return ec; 394dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer result = StringRef(path.begin() + root.size(), path.size() - root.size()); 395dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 396dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 397dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 398dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code append(SmallVectorImpl<char> &path, const Twine &a, 399dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const Twine &b, 400dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const Twine &c, 401dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer const Twine &d) { 402dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallString<32> a_storage; 403dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallString<32> b_storage; 404dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallString<32> c_storage; 405dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallString<32> d_storage; 406dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 407dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallVector<StringRef, 4> components; 408dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage)); 409dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage)); 410dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage)); 411dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage)); 412dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 413dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer for (SmallVectorImpl<StringRef>::const_iterator i = components.begin(), 414dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer e = components.end(); 415dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer i != e; ++i) { 416dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]); 417dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool component_has_sep = !i->empty() && is_separator((*i)[0]); 418dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool is_root_name; 419dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = has_root_name(*i, is_root_name)) return ec; 420dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 421dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (path_has_sep) { 422dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Strip separators from beginning of component. 423dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer size_t loc = i->find_first_not_of(separators); 424dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef c = StringRef(i->begin() + loc, i->size() - loc); 425dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 426dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Append it. 427dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer path.append(c.begin(), c.end()); 428dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer continue; 429dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 430dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 431dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (!component_has_sep && !(path.empty() && is_root_name)) { 432dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Add a separator. 433dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer path.push_back(prefered_separator); 434dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 435dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 436dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer path.append(i->begin(), i->end()); 437dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 438dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 439dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 440dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 441dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 442dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencererror_code make_absolute(SmallVectorImpl<char> &path) { 443dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef p(path.data(), path.size()); 444dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 445dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bool rootName, rootDirectory; 446dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = has_root_name(p, rootName)) return ec; 447dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = has_root_directory(p, rootDirectory)) return ec; 448dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 449dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Already absolute. 450dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (rootName && rootDirectory) 451dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 452dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 453dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // All of the following conditions will need the current directory. 454dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallString<128> current_dir; 455dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = current_path(current_dir)) return ec; 456dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 457dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Relative path. Prepend the current directory. 458dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (!rootName && !rootDirectory) { 459dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Append path to the current directory. 460dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = append(current_dir, p)) return ec; 461dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Set path to the result. 462dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer path.swap(current_dir); 463dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 464dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 465dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 466dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (!rootName && rootDirectory) { 467dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef cdrn; 468dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = root_name(current_dir, cdrn)) return ec; 469dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallString<128> curDirRootName(cdrn.begin(), cdrn.end()); 470dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = append(curDirRootName, p)) return ec; 471dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer // Set path to the result. 472dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer path.swap(curDirRootName); 473dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 474dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 475dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 476dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (rootName && !rootDirectory) { 477dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef pRootName; 478dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef bRootDirectory; 479dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef bRelativePath; 480dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer StringRef pRelativePath; 481dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = root_name(p, pRootName)) return ec; 482dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = root_directory(current_dir, bRootDirectory)) return ec; 483dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = relative_path(current_dir, bRelativePath)) return ec; 484dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = relative_path(p, pRelativePath)) return ec; 485dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 486dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer SmallString<128> res; 487dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer if (error_code ec = append(res, pRootName, bRootDirectory, 488dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer bRelativePath, pRelativePath)) return ec; 489dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer path.swap(res); 490dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer return make_error_code(errc::success); 491dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer } 492dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 493dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer llvm_unreachable("All rootName and rootDirectory combinations should have " 494dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer "occurred above!"); 495dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 496dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 497a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencererror_code parent_path(const StringRef &path, StringRef &result) { 498a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer size_t end_pos = parent_path_end(path); 499a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer if (end_pos == StringRef::npos) 500a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer result = StringRef(); 501a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer else 502a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer result = StringRef(path.data(), end_pos); 503a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer return make_error_code(errc::success); 504a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer} 505a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer 506dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencererror_code remove_filename(SmallVectorImpl<char> &path) { 507dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer size_t end_pos = parent_path_end(StringRef(path.begin(), path.size())); 508dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer if (end_pos == StringRef::npos) 509dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer return make_error_code(errc::success); 510dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer path.set_size(end_pos); 511dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer return make_error_code(errc::success); 512dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer} 513dbfb56bebdb279a2a94096a821d3b7d3345962c2Michael J. Spencer 51452ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencererror_code replace_extension(SmallVectorImpl<char> &path, 51552ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer const Twine &extension) { 51652ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer StringRef p(path.begin(), path.size()); 51752ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer SmallString<32> ext_storage; 51852ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer StringRef ext = extension.toStringRef(ext_storage); 51952ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer 52052ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer // Erase existing extension. 52152ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer size_t pos = p.find_last_of('.'); 52252ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer if (pos != StringRef::npos && pos >= filename_pos(p)) 52352ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer path.set_size(pos); 52452ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer 52552ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer // Append '.' if needed. 52652ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer if (ext.size() > 0 && ext[0] != '.') 52752ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer path.push_back('.'); 52852ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer 52952ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer // Append extension. 53052ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer path.append(ext.begin(), ext.end()); 53152ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer return make_error_code(errc::success); 53252ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer} 53352ed867801b3ddb5569b7f823e63555e9c322c99Michael J. Spencer 534722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencererror_code native(const Twine &path, SmallVectorImpl<char> &result) { 535722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer // Clear result. 536722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer result.set_size(0); 537722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer#ifdef LLVM_ON_WIN32 538722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer SmallString<128> path_storage; 539722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer StringRef p = path.toStringRef(path_storage); 540722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer result.reserve(p.size()); 541722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer for (StringRef::const_iterator i = p.begin(), 542722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer e = p.end(); 543722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer i != e; 544722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer ++i) { 545722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer if (*i == '/') 546722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer result.push_back('\\'); 547722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer else 548722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer result.push_back(*i); 549722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer } 550722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer#else 551722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer path.toVector(result); 552722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer#endif 553722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer return make_error_code(errc::success); 554722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer} 555722d5adac1c3af88e785088eda594c7f656e9ed8Michael J. Spencer 556a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencererror_code filename(const StringRef &path, StringRef &result) { 557a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer result = *(--end(path)); 558a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer return make_error_code(errc::success); 559a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer} 560a9793559942dd055d460f8e3d438b49889eb4f5cMichael J. Spencer 56134ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencererror_code stem(const StringRef &path, StringRef &result) { 56234ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer StringRef fname; 56334ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer if (error_code ec = filename(path, fname)) return ec; 56434ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer size_t pos = fname.find_last_of('.'); 56534ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer if (pos == StringRef::npos) 56634ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer result = fname; 56734ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer else 56834ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer if ((fname.size() == 1 && fname == ".") || 56934ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer (fname.size() == 2 && fname == "..")) 57034ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer result = fname; 57134ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer else 57234ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer result = StringRef(fname.begin(), pos); 57334ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer 57434ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer return make_error_code(errc::success); 57534ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer} 57634ab1f6087bc0da1df0e3a73ac99762ef070d419Michael J. Spencer 577dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 578dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 579dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer} 580dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer 581dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer// Include the truly platform-specific parts. 582dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#if defined(LLVM_ON_UNIX) 583dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "Unix/PathV2.inc" 584dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif 585dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#if defined(LLVM_ON_WIN32) 586dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#include "Windows/PathV2.inc" 587dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer#endif 588