119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===-- PathV2.cpp - Implement OS Path Concept ------------------*- C++ -*-===// 219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// The LLVM Compiler Infrastructure 419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source 619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details. 719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file implements the operating system PathV2 API. 1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/PathV2.h" 1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/FileSystem.h" 1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ErrorHandling.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <cctype> 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <cstdio> 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <cstring> 2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace { 2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman using llvm::StringRef; 2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman using llvm::sys::path::is_separator; 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const StringRef separators = "\\/"; 2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const char prefered_separator = '\\'; 2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else 2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const StringRef separators = "/"; 3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const char prefered_separator = '/'; 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const llvm::error_code success; 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef find_first_component(StringRef path) { 3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Look for this first component in the following order. 3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * empty (in this case we return an empty string) 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * either C: or {//,\\}net. 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * {/,\} 4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * {.,..} 4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * {file,directory}name 4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (path.empty()) 4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return path; 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // C: 4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (path.size() >= 2 && std::isalpha(path[0]) && path[1] == ':') 4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return path.substr(0, 2); 5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // //net 5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((path.size() > 2) && 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(path[0]) && 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path[0] == path[1] && 5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !is_separator(path[2])) { 5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Find the next directory separator. 5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t end = path.find_first_of(separators, 2); 5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return path.substr(0, end); 6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // {/,\} 6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (is_separator(path[0])) 6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return path.substr(0, 1); 6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (path.startswith("..")) 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return path.substr(0, 2); 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (path[0] == '.') 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return path.substr(0, 1); 7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * {file,directory}name 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t end = path.find_first_of(separators, 2); 7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return path.substr(0, end); 7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t filename_pos(StringRef str) { 7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (str.size() == 2 && 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(str[0]) && 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman str[0] == str[1]) 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 0; 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (str.size() > 0 && is_separator(str[str.size() - 1])) 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return str.size() - 1; 8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t pos = str.find_last_of(separators, str.size() - 1); 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (pos == StringRef::npos) 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman pos = str.find_last_of(':', str.size() - 2); 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (pos == StringRef::npos || 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (pos == 1 && is_separator(str[0]))) 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 0; 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return pos + 1; 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t root_dir_start(StringRef str) { 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // case "c:/" 10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (str.size() > 2 && 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman str[1] == ':' && 10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(str[2])) 10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 2; 10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // case "//" 11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (str.size() == 2 && 11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(str[0]) && 11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman str[0] == str[1]) 11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return StringRef::npos; 11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // case "//net" 11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (str.size() > 3 && 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(str[0]) && 11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman str[0] == str[1] && 11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !is_separator(str[2])) { 12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return str.find_first_of(separators, 2); 12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // case "/" 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (str.size() > 0 && is_separator(str[0])) 12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 0; 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return StringRef::npos; 12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t parent_path_end(StringRef path) { 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t end_pos = filename_pos(path); 13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]); 13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Skip separators except for root dir. 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t root_dir_pos = root_dir_start(path.substr(0, end_pos)); 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman while(end_pos > 0 && 13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (end_pos - 1) != root_dir_pos && 14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(path[end_pos - 1])) 14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman --end_pos; 14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep) 14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return StringRef::npos; 14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return end_pos; 14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} // end unnamed namespace 14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace llvm { 15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace sys { 15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace path { 15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst_iterator begin(StringRef path) { 15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const_iterator i; 15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman i.Path = path; 15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman i.Component = find_first_component(path); 15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman i.Position = 0; 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return i; 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst_iterator end(StringRef path) { 16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const_iterator i; 16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman i.Path = path; 16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman i.Position = path.size(); 16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return i; 16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst_iterator &const_iterator::operator++() { 17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Position < Path.size() && "Tried to increment past end!"); 17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Increment Position to past the current component 17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Position += Component.size(); 17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Check for end. 17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Position == Path.size()) { 17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Component = StringRef(); 17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *this; 17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Both POSIX and Windows treat paths that begin with exactly two separators 18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // specially. 18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool was_net = Component.size() > 2 && 18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(Component[0]) && 18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Component[1] == Component[0] && 18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !is_separator(Component[2]); 18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Handle separators. 18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (is_separator(Path[Position])) { 19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Root dir. 19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (was_net 19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // c:/ 19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman || Component.endswith(":") 19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ) { 19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Component = Path.substr(Position, 1); 19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *this; 19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Skip extra separators. 20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman while (Position != Path.size() && 20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(Path[Position])) { 20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++Position; 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Treat trailing '/' as a '.'. 20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Position == Path.size()) { 20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman --Position; 21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Component = "."; 21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *this; 21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Find next component. 21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t end_pos = Path.find_first_of(separators, Position); 21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Component = Path.slice(Position, end_pos); 21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *this; 22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst_iterator &const_iterator::operator--() { 22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If we're at the end and the previous char was a '/', return '.'. 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Position == Path.size() && 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Path.size() > 1 && 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(Path[Position - 1]) 22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman && Path[Position - 2] != ':' 22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ) { 23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman --Position; 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Component = "."; 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *this; 23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Skip separators unless it's the root directory. 23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t root_dir_pos = root_dir_start(Path); 23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t end_pos = Position; 23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman while(end_pos > 0 && 24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (end_pos - 1) != root_dir_pos && 24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman is_separator(Path[end_pos - 1])) 24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman --end_pos; 24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Find next separator. 24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t start_pos = filename_pos(Path.substr(0, end_pos)); 24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Component = Path.slice(start_pos, end_pos); 24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Position = start_pos; 24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *this; 25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool const_iterator::operator==(const const_iterator &RHS) const { 25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Path.begin() == RHS.Path.begin() && 25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Position == RHS.Position; 25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool const_iterator::operator!=(const const_iterator &RHS) const { 25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !(*this == RHS); 25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanptrdiff_t const_iterator::operator-(const const_iterator &RHS) const { 26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Position - RHS.Position; 26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst StringRef root_path(StringRef path) { 26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const_iterator b = begin(path), 26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman pos = b, 26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman e = end(path); 26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (b != e) { 27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0]; 27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool has_drive = 27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman b->endswith(":"); 27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else 27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false; 27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (has_net || has_drive) { 27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((++pos != e) && is_separator((*pos)[0])) { 28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // {C:/,//net/}, so get the first two components. 28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return path.substr(0, b->size() + pos->size()); 28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // just {C:,//net}, return the first component. 28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *b; 28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // POSIX style root directory. 28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (is_separator((*b)[0])) { 29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *b; 29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return StringRef(); 29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst StringRef root_name(StringRef path) { 29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const_iterator b = begin(path), 29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman e = end(path); 30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (b != e) { 30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0]; 30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool has_drive = 30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman b->endswith(":"); 30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else 30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false; 30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (has_net || has_drive) { 31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // just {C:,//net}, return the first component. 31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *b; 31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // No path or no name. 31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return StringRef(); 31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst StringRef root_directory(StringRef path) { 32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const_iterator b = begin(path), 32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman pos = b, 32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman e = end(path); 32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (b != e) { 32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0]; 32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool has_drive = 32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman b->endswith(":"); 32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else 32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false; 33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((has_net || has_drive) && 33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // {C:,//net}, skip to the next component. 33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (++pos != e) && is_separator((*pos)[0])) { 33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *pos; 33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // POSIX style root directory. 33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!has_net && is_separator((*b)[0])) { 34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *b; 34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // No path or no root. 34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return StringRef(); 34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst StringRef relative_path(StringRef path) { 34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef root = root_path(path); 35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return root.substr(root.size()); 35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid append(SmallVectorImpl<char> &path, const Twine &a, 35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const Twine &b, 35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const Twine &c, 35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const Twine &d) { 35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<32> a_storage; 35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<32> b_storage; 35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<32> c_storage; 36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<32> d_storage; 36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<StringRef, 4> components; 36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage)); 36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage)); 36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage)); 36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage)); 36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (SmallVectorImpl<StringRef>::const_iterator i = components.begin(), 36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman e = components.end(); 37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman i != e; ++i) { 37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]); 37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool component_has_sep = !i->empty() && is_separator((*i)[0]); 37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool is_root_name = has_root_name(*i); 37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (path_has_sep) { 37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Strip separators from beginning of component. 37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t loc = i->find_first_not_of(separators); 37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef c = i->substr(loc); 37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Append it. 38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.append(c.begin(), c.end()); 38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!component_has_sep && !(path.empty() || is_root_name)) { 38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Add a separator. 38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.push_back(prefered_separator); 38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.append(i->begin(), i->end()); 39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid append(SmallVectorImpl<char> &path, 39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const_iterator begin, const_iterator end) { 39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (; begin != end; ++begin) 39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path::append(path, *begin); 39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst StringRef parent_path(StringRef path) { 40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t end_pos = parent_path_end(path); 40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (end_pos == StringRef::npos) 40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return StringRef(); 40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return path.substr(0, end_pos); 40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid remove_filename(SmallVectorImpl<char> &path) { 40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t end_pos = parent_path_end(StringRef(path.begin(), path.size())); 41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (end_pos != StringRef::npos) 41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.set_size(end_pos); 41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid replace_extension(SmallVectorImpl<char> &path, const Twine &extension) { 41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p(path.begin(), path.size()); 41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<32> ext_storage; 41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef ext = extension.toStringRef(ext_storage); 41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Erase existing extension. 42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t pos = p.find_last_of('.'); 42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (pos != StringRef::npos && pos >= filename_pos(p)) 42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.set_size(pos); 42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Append '.' if needed. 42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ext.size() > 0 && ext[0] != '.') 42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.push_back('.'); 42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Append extension. 42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.append(ext.begin(), ext.end()); 43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid native(const Twine &path, SmallVectorImpl<char> &result) { 43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Clear result. 43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result.clear(); 43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result.reserve(p.size()); 43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (StringRef::const_iterator i = p.begin(), 44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman e = p.end(); 44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman i != e; 44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++i) { 44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (*i == '/') 44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result.push_back('\\'); 44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result.push_back(*i); 44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else 44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.toVector(result); 45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst StringRef filename(StringRef path) { 45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *(--end(path)); 45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst StringRef stem(StringRef path) { 45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef fname = filename(path); 45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t pos = fname.find_last_of('.'); 46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (pos == StringRef::npos) 46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return fname; 46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((fname.size() == 1 && fname == ".") || 46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (fname.size() == 2 && fname == "..")) 46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return fname; 46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return fname.substr(0, pos); 46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst StringRef extension(StringRef path) { 47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef fname = filename(path); 47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman size_t pos = fname.find_last_of('.'); 47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (pos == StringRef::npos) 47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return StringRef(); 47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((fname.size() == 1 && fname == ".") || 47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (fname.size() == 2 && fname == "..")) 47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return StringRef(); 47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return fname.substr(pos); 48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool is_separator(char value) { 48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch(value) { 48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case '\\': // fall through 48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case '/': return true; 48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: return false; 49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) { 49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result.clear(); 49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Check whether the temporary directory is specified by an environment 49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // variable. 49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const char *EnvironmentVariable; 49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EnvironmentVariable = "TEMP"; 50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else 50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EnvironmentVariable = "TMPDIR"; 50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (char *RequestedDir = getenv(EnvironmentVariable)) { 50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result.append(RequestedDir, RequestedDir + strlen(RequestedDir)); 50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Fall back to a system default. 51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const char *DefaultResult; 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (void)erasedOnReboot; 51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DefaultResult = "C:\\TEMP"; 51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else 51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (erasedOnReboot) 51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DefaultResult = "/tmp"; 51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DefaultResult = "/var/tmp"; 51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result.append(DefaultResult, DefaultResult + strlen(DefaultResult)); 52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool has_root_name(const Twine &path) { 52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !root_name(p).empty(); 52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool has_root_directory(const Twine &path) { 53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !root_directory(p).empty(); 53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool has_root_path(const Twine &path) { 53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !root_path(p).empty(); 54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool has_relative_path(const Twine &path) { 54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !relative_path(p).empty(); 54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool has_filename(const Twine &path) { 55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !filename(p).empty(); 55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool has_parent_path(const Twine &path) { 55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !parent_path(p).empty(); 56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool has_stem(const Twine &path) { 56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !stem(p).empty(); 57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool has_extension(const Twine &path) { 57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !extension(p).empty(); 57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool is_absolute(const Twine &path) { 58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool rootDir = has_root_directory(p), 58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef LLVM_ON_WIN32 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rootName = has_root_name(p); 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else 58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rootName = true; 58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return rootDir && rootName; 59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool is_relative(const Twine &path) { 59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return !is_absolute(path); 59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} // end namespace path 59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace fs { 60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code make_absolute(SmallVectorImpl<char> &path) { 60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p(path.data(), path.size()); 60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool rootName = path::has_root_name(p), 60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman rootDirectory = path::has_root_directory(p); 60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Already absolute. 60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (rootName && rootDirectory) 60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // All of the following conditions will need the current directory. 61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> current_dir; 61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = current_path(current_dir)) return ec; 61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Relative path. Prepend the current directory. 61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!rootName && !rootDirectory) { 61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Append path to the current directory. 61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path::append(current_dir, p); 61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Set path to the result. 62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.swap(current_dir); 62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!rootName && rootDirectory) { 62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef cdrn = path::root_name(current_dir); 62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> curDirRootName(cdrn.begin(), cdrn.end()); 62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path::append(curDirRootName, p); 62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Set path to the result. 62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.swap(curDirRootName); 63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (rootName && !rootDirectory) { 63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef pRootName = path::root_name(p); 63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef bRootDirectory = path::root_directory(current_dir); 63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef bRelativePath = path::relative_path(current_dir); 63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef pRelativePath = path::relative_path(p); 63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> res; 64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath); 64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path.swap(res); 64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm_unreachable("All rootName and rootDirectory combinations should have " 64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "occurred above!"); 64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code create_directories(const Twine &path, bool &existed) { 65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef parent = path::parent_path(p); 65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool parent_exists; 65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = fs::exists(parent, parent_exists)) return ec; 65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!parent_exists) 65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = create_directories(parent, existed)) return ec; 66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return create_directory(p, existed); 66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool exists(file_status status) { 66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return status_known(status) && status.type() != file_type::file_not_found; 66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool status_known(file_status s) { 66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return s.type() != file_type::status_error; 67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool is_directory(file_status status) { 67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return status.type() == file_type::directory_file; 67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code is_directory(const Twine &path, bool &result) { 67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman file_status st; 67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = status(path, st)) 67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return ec; 68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = is_directory(st); 68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool is_regular_file(file_status status) { 68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return status.type() == file_type::regular_file; 68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code is_regular_file(const Twine &path, bool &result) { 68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman file_status st; 69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = status(path, st)) 69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return ec; 69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = is_regular_file(st); 69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 69519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool is_symlink(file_status status) { 69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return status.type() == file_type::symlink_file; 69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code is_symlink(const Twine &path, bool &result) { 70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman file_status st; 70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = status(path, st)) 70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return ec; 70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = is_symlink(st); 70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool is_other(file_status status) { 70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return exists(status) && 71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !is_regular_file(status) && 71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !is_directory(status) && 71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !is_symlink(status); 71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid directory_entry::replace_filename(const Twine &filename, file_status st) { 71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path(Path.begin(), Path.end()); 71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path::remove_filename(path); 71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman path::append(path, filename); 71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Path = path.str(); 72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Status = st; 72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code has_magic(const Twine &path, const Twine &magic, bool &result) { 72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<32> MagicStorage; 72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef Magic = magic.toStringRef(MagicStorage); 72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<32> Buffer; 72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = get_magic(path, Magic.size(), Buffer)) { 72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ec == errc::value_too_large) { 73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Magic.size() > file_size(Path). 73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = false; 73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return ec; 73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = Magic == Buffer; 73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code identify_magic(const Twine &path, LLVMFileType &result) { 74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<32> Magic; 74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman error_code ec = get_magic(path, Magic.capacity(), Magic); 74419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ec && ec != errc::value_too_large) 74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return ec; 74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman result = IdentifyFileType(Magic.data(), Magic.size()); 74819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace { 75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code remove_all_r(StringRef path, file_type ft, uint32_t &count) { 75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ft == file_type::directory_file) { 75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This code would be a lot better with exceptions ;/. 75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman error_code ec; 75619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (directory_iterator i(path, ec), e; i != e; i.increment(ec)) { 75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ec) return ec; 75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman file_status st; 75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = i->status(st)) return ec; 76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = remove_all_r(i->path(), st.type(), count)) return ec; 76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool obviously_this_exists; 76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = remove(path, obviously_this_exists)) return ec; 76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(obviously_this_exists); 76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++count; // Include the directory itself in the items removed. 76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool obviously_this_exists; 76819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = remove(path, obviously_this_exists)) return ec; 76919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(obviously_this_exists); 77019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++count; 77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return success; 77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} // end unnamed namespace 77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code remove_all(const Twine &path, uint32_t &num_removed) { 77819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> path_storage; 77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringRef p = path.toStringRef(path_storage); 78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman file_status fs; 78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (error_code ec = status(path, fs)) 78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return ec; 78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman num_removed = 0; 78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return remove_all_r(p, fs.type(), num_removed); 78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanerror_code directory_entry::status(file_status &result) const { 78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return fs::status(Path, result); 79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} // end namespace fs 79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} // end namespace sys 79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} // end namespace llvm 79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Include the truly platform-specific parts. 79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#if defined(LLVM_ON_UNIX) 79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "Unix/PathV2.inc" 79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#if defined(LLVM_ON_WIN32) 80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "Windows/PathV2.inc" 80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif 803