Home | History | Annotate | Download | only in Support
      1 //===-- Path.cpp - Implement OS Path Concept ------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file implements the operating system Path API.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/Support/Path.h"
     15 #include "llvm/Support/Endian.h"
     16 #include "llvm/Support/ErrorHandling.h"
     17 #include "llvm/Support/FileSystem.h"
     18 #include <cctype>
     19 #include <cstdio>
     20 #include <cstring>
     21 #include <fcntl.h>
     22 
     23 #if !defined(_MSC_VER) && !defined(__MINGW32__)
     24 #include <unistd.h>
     25 #else
     26 #include <io.h>
     27 #endif
     28 
     29 namespace {
     30   using llvm::StringRef;
     31   using llvm::sys::path::is_separator;
     32 
     33 #ifdef LLVM_ON_WIN32
     34   const char *separators = "\\/";
     35   const char  prefered_separator = '\\';
     36 #else
     37   const char  separators = '/';
     38   const char  prefered_separator = '/';
     39 #endif
     40 
     41   StringRef find_first_component(StringRef path) {
     42     // Look for this first component in the following order.
     43     // * empty (in this case we return an empty string)
     44     // * either C: or {//,\\}net.
     45     // * {/,\}
     46     // * {.,..}
     47     // * {file,directory}name
     48 
     49     if (path.empty())
     50       return path;
     51 
     52 #ifdef LLVM_ON_WIN32
     53     // C:
     54     if (path.size() >= 2 && std::isalpha(static_cast<unsigned char>(path[0])) &&
     55         path[1] == ':')
     56       return path.substr(0, 2);
     57 #endif
     58 
     59     // //net
     60     if ((path.size() > 2) &&
     61         is_separator(path[0]) &&
     62         path[0] == path[1] &&
     63         !is_separator(path[2])) {
     64       // Find the next directory separator.
     65       size_t end = path.find_first_of(separators, 2);
     66       return path.substr(0, end);
     67     }
     68 
     69     // {/,\}
     70     if (is_separator(path[0]))
     71       return path.substr(0, 1);
     72 
     73     if (path.startswith(".."))
     74       return path.substr(0, 2);
     75 
     76     if (path[0] == '.')
     77       return path.substr(0, 1);
     78 
     79     // * {file,directory}name
     80     size_t end = path.find_first_of(separators, 2);
     81     return path.substr(0, end);
     82   }
     83 
     84   size_t filename_pos(StringRef str) {
     85     if (str.size() == 2 &&
     86         is_separator(str[0]) &&
     87         str[0] == str[1])
     88       return 0;
     89 
     90     if (str.size() > 0 && is_separator(str[str.size() - 1]))
     91       return str.size() - 1;
     92 
     93     size_t pos = str.find_last_of(separators, str.size() - 1);
     94 
     95 #ifdef LLVM_ON_WIN32
     96     if (pos == StringRef::npos)
     97       pos = str.find_last_of(':', str.size() - 2);
     98 #endif
     99 
    100     if (pos == StringRef::npos ||
    101         (pos == 1 && is_separator(str[0])))
    102       return 0;
    103 
    104     return pos + 1;
    105   }
    106 
    107   size_t root_dir_start(StringRef str) {
    108     // case "c:/"
    109 #ifdef LLVM_ON_WIN32
    110     if (str.size() > 2 &&
    111         str[1] == ':' &&
    112         is_separator(str[2]))
    113       return 2;
    114 #endif
    115 
    116     // case "//"
    117     if (str.size() == 2 &&
    118         is_separator(str[0]) &&
    119         str[0] == str[1])
    120       return StringRef::npos;
    121 
    122     // case "//net"
    123     if (str.size() > 3 &&
    124         is_separator(str[0]) &&
    125         str[0] == str[1] &&
    126         !is_separator(str[2])) {
    127       return str.find_first_of(separators, 2);
    128     }
    129 
    130     // case "/"
    131     if (str.size() > 0 && is_separator(str[0]))
    132       return 0;
    133 
    134     return StringRef::npos;
    135   }
    136 
    137   size_t parent_path_end(StringRef path) {
    138     size_t end_pos = filename_pos(path);
    139 
    140     bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
    141 
    142     // Skip separators except for root dir.
    143     size_t root_dir_pos = root_dir_start(path.substr(0, end_pos));
    144 
    145     while(end_pos > 0 &&
    146           (end_pos - 1) != root_dir_pos &&
    147           is_separator(path[end_pos - 1]))
    148       --end_pos;
    149 
    150     if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
    151       return StringRef::npos;
    152 
    153     return end_pos;
    154   }
    155 } // end unnamed namespace
    156 
    157 enum FSEntity {
    158   FS_Dir,
    159   FS_File,
    160   FS_Name
    161 };
    162 
    163 // Implemented in Unix/Path.inc and Windows/Path.inc.
    164 static llvm::error_code
    165 createUniqueEntity(const llvm::Twine &Model, int &ResultFD,
    166                    llvm::SmallVectorImpl<char> &ResultPath,
    167                    bool MakeAbsolute, unsigned Mode, FSEntity Type);
    168 
    169 namespace llvm {
    170 namespace sys  {
    171 namespace path {
    172 
    173 const_iterator begin(StringRef path) {
    174   const_iterator i;
    175   i.Path      = path;
    176   i.Component = find_first_component(path);
    177   i.Position  = 0;
    178   return i;
    179 }
    180 
    181 const_iterator end(StringRef path) {
    182   const_iterator i;
    183   i.Path      = path;
    184   i.Position  = path.size();
    185   return i;
    186 }
    187 
    188 const_iterator &const_iterator::operator++() {
    189   assert(Position < Path.size() && "Tried to increment past end!");
    190 
    191   // Increment Position to past the current component
    192   Position += Component.size();
    193 
    194   // Check for end.
    195   if (Position == Path.size()) {
    196     Component = StringRef();
    197     return *this;
    198   }
    199 
    200   // Both POSIX and Windows treat paths that begin with exactly two separators
    201   // specially.
    202   bool was_net = Component.size() > 2 &&
    203     is_separator(Component[0]) &&
    204     Component[1] == Component[0] &&
    205     !is_separator(Component[2]);
    206 
    207   // Handle separators.
    208   if (is_separator(Path[Position])) {
    209     // Root dir.
    210     if (was_net
    211 #ifdef LLVM_ON_WIN32
    212         // c:/
    213         || Component.endswith(":")
    214 #endif
    215         ) {
    216       Component = Path.substr(Position, 1);
    217       return *this;
    218     }
    219 
    220     // Skip extra separators.
    221     while (Position != Path.size() &&
    222            is_separator(Path[Position])) {
    223       ++Position;
    224     }
    225 
    226     // Treat trailing '/' as a '.'.
    227     if (Position == Path.size()) {
    228       --Position;
    229       Component = ".";
    230       return *this;
    231     }
    232   }
    233 
    234   // Find next component.
    235   size_t end_pos = Path.find_first_of(separators, Position);
    236   Component = Path.slice(Position, end_pos);
    237 
    238   return *this;
    239 }
    240 
    241 const_iterator &const_iterator::operator--() {
    242   // If we're at the end and the previous char was a '/', return '.'.
    243   if (Position == Path.size() &&
    244       Path.size() > 1 &&
    245       is_separator(Path[Position - 1])
    246 #ifdef LLVM_ON_WIN32
    247       && Path[Position - 2] != ':'
    248 #endif
    249       ) {
    250     --Position;
    251     Component = ".";
    252     return *this;
    253   }
    254 
    255   // Skip separators unless it's the root directory.
    256   size_t root_dir_pos = root_dir_start(Path);
    257   size_t end_pos = Position;
    258 
    259   while(end_pos > 0 &&
    260         (end_pos - 1) != root_dir_pos &&
    261         is_separator(Path[end_pos - 1]))
    262     --end_pos;
    263 
    264   // Find next separator.
    265   size_t start_pos = filename_pos(Path.substr(0, end_pos));
    266   Component = Path.slice(start_pos, end_pos);
    267   Position = start_pos;
    268   return *this;
    269 }
    270 
    271 bool const_iterator::operator==(const const_iterator &RHS) const {
    272   return Path.begin() == RHS.Path.begin() &&
    273          Position == RHS.Position;
    274 }
    275 
    276 bool const_iterator::operator!=(const const_iterator &RHS) const {
    277   return !(*this == RHS);
    278 }
    279 
    280 ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
    281   return Position - RHS.Position;
    282 }
    283 
    284 const StringRef root_path(StringRef path) {
    285   const_iterator b = begin(path),
    286                  pos = b,
    287                  e = end(path);
    288   if (b != e) {
    289     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
    290     bool has_drive =
    291 #ifdef LLVM_ON_WIN32
    292       b->endswith(":");
    293 #else
    294       false;
    295 #endif
    296 
    297     if (has_net || has_drive) {
    298       if ((++pos != e) && is_separator((*pos)[0])) {
    299         // {C:/,//net/}, so get the first two components.
    300         return path.substr(0, b->size() + pos->size());
    301       } else {
    302         // just {C:,//net}, return the first component.
    303         return *b;
    304       }
    305     }
    306 
    307     // POSIX style root directory.
    308     if (is_separator((*b)[0])) {
    309       return *b;
    310     }
    311   }
    312 
    313   return StringRef();
    314 }
    315 
    316 const StringRef root_name(StringRef path) {
    317   const_iterator b = begin(path),
    318                  e = end(path);
    319   if (b != e) {
    320     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
    321     bool has_drive =
    322 #ifdef LLVM_ON_WIN32
    323       b->endswith(":");
    324 #else
    325       false;
    326 #endif
    327 
    328     if (has_net || has_drive) {
    329       // just {C:,//net}, return the first component.
    330       return *b;
    331     }
    332   }
    333 
    334   // No path or no name.
    335   return StringRef();
    336 }
    337 
    338 const StringRef root_directory(StringRef path) {
    339   const_iterator b = begin(path),
    340                  pos = b,
    341                  e = end(path);
    342   if (b != e) {
    343     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
    344     bool has_drive =
    345 #ifdef LLVM_ON_WIN32
    346       b->endswith(":");
    347 #else
    348       false;
    349 #endif
    350 
    351     if ((has_net || has_drive) &&
    352         // {C:,//net}, skip to the next component.
    353         (++pos != e) && is_separator((*pos)[0])) {
    354       return *pos;
    355     }
    356 
    357     // POSIX style root directory.
    358     if (!has_net && is_separator((*b)[0])) {
    359       return *b;
    360     }
    361   }
    362 
    363   // No path or no root.
    364   return StringRef();
    365 }
    366 
    367 const StringRef relative_path(StringRef path) {
    368   StringRef root = root_path(path);
    369   return path.substr(root.size());
    370 }
    371 
    372 void append(SmallVectorImpl<char> &path, const Twine &a,
    373                                          const Twine &b,
    374                                          const Twine &c,
    375                                          const Twine &d) {
    376   SmallString<32> a_storage;
    377   SmallString<32> b_storage;
    378   SmallString<32> c_storage;
    379   SmallString<32> d_storage;
    380 
    381   SmallVector<StringRef, 4> components;
    382   if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
    383   if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
    384   if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
    385   if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
    386 
    387   for (SmallVectorImpl<StringRef>::const_iterator i = components.begin(),
    388                                                   e = components.end();
    389                                                   i != e; ++i) {
    390     bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
    391     bool component_has_sep = !i->empty() && is_separator((*i)[0]);
    392     bool is_root_name = has_root_name(*i);
    393 
    394     if (path_has_sep) {
    395       // Strip separators from beginning of component.
    396       size_t loc = i->find_first_not_of(separators);
    397       StringRef c = i->substr(loc);
    398 
    399       // Append it.
    400       path.append(c.begin(), c.end());
    401       continue;
    402     }
    403 
    404     if (!component_has_sep && !(path.empty() || is_root_name)) {
    405       // Add a separator.
    406       path.push_back(prefered_separator);
    407     }
    408 
    409     path.append(i->begin(), i->end());
    410   }
    411 }
    412 
    413 void append(SmallVectorImpl<char> &path,
    414             const_iterator begin, const_iterator end) {
    415   for (; begin != end; ++begin)
    416     path::append(path, *begin);
    417 }
    418 
    419 const StringRef parent_path(StringRef path) {
    420   size_t end_pos = parent_path_end(path);
    421   if (end_pos == StringRef::npos)
    422     return StringRef();
    423   else
    424     return path.substr(0, end_pos);
    425 }
    426 
    427 void remove_filename(SmallVectorImpl<char> &path) {
    428   size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
    429   if (end_pos != StringRef::npos)
    430     path.set_size(end_pos);
    431 }
    432 
    433 void replace_extension(SmallVectorImpl<char> &path, const Twine &extension) {
    434   StringRef p(path.begin(), path.size());
    435   SmallString<32> ext_storage;
    436   StringRef ext = extension.toStringRef(ext_storage);
    437 
    438   // Erase existing extension.
    439   size_t pos = p.find_last_of('.');
    440   if (pos != StringRef::npos && pos >= filename_pos(p))
    441     path.set_size(pos);
    442 
    443   // Append '.' if needed.
    444   if (ext.size() > 0 && ext[0] != '.')
    445     path.push_back('.');
    446 
    447   // Append extension.
    448   path.append(ext.begin(), ext.end());
    449 }
    450 
    451 void native(const Twine &path, SmallVectorImpl<char> &result) {
    452   // Clear result.
    453   result.clear();
    454 #ifdef LLVM_ON_WIN32
    455   SmallString<128> path_storage;
    456   StringRef p = path.toStringRef(path_storage);
    457   result.reserve(p.size());
    458   for (StringRef::const_iterator i = p.begin(),
    459                                  e = p.end();
    460                                  i != e;
    461                                  ++i) {
    462     if (*i == '/')
    463       result.push_back('\\');
    464     else
    465       result.push_back(*i);
    466   }
    467 #else
    468   path.toVector(result);
    469 #endif
    470 }
    471 
    472 const StringRef filename(StringRef path) {
    473   return *(--end(path));
    474 }
    475 
    476 const StringRef stem(StringRef path) {
    477   StringRef fname = filename(path);
    478   size_t pos = fname.find_last_of('.');
    479   if (pos == StringRef::npos)
    480     return fname;
    481   else
    482     if ((fname.size() == 1 && fname == ".") ||
    483         (fname.size() == 2 && fname == ".."))
    484       return fname;
    485     else
    486       return fname.substr(0, pos);
    487 }
    488 
    489 const StringRef extension(StringRef path) {
    490   StringRef fname = filename(path);
    491   size_t pos = fname.find_last_of('.');
    492   if (pos == StringRef::npos)
    493     return StringRef();
    494   else
    495     if ((fname.size() == 1 && fname == ".") ||
    496         (fname.size() == 2 && fname == ".."))
    497       return StringRef();
    498     else
    499       return fname.substr(pos);
    500 }
    501 
    502 bool is_separator(char value) {
    503   switch(value) {
    504 #ifdef LLVM_ON_WIN32
    505     case '\\': // fall through
    506 #endif
    507     case '/': return true;
    508     default: return false;
    509   }
    510 }
    511 
    512 void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
    513   result.clear();
    514 
    515 #ifdef __APPLE__
    516   // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
    517   int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR
    518                                : _CS_DARWIN_USER_CACHE_DIR;
    519   size_t ConfLen = confstr(ConfName, 0, 0);
    520   if (ConfLen > 0) {
    521     do {
    522       result.resize(ConfLen);
    523       ConfLen = confstr(ConfName, result.data(), result.size());
    524     } while (ConfLen > 0 && ConfLen != result.size());
    525 
    526     if (ConfLen > 0) {
    527       assert(result.back() == 0);
    528       result.pop_back();
    529       return;
    530     }
    531 
    532     result.clear();
    533   }
    534 #endif
    535 
    536   // Check whether the temporary directory is specified by an environment
    537   // variable.
    538   const char *EnvironmentVariable;
    539 #ifdef LLVM_ON_WIN32
    540   EnvironmentVariable = "TEMP";
    541 #else
    542   EnvironmentVariable = "TMPDIR";
    543 #endif
    544   if (char *RequestedDir = getenv(EnvironmentVariable)) {
    545     result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
    546     return;
    547   }
    548 
    549   // Fall back to a system default.
    550   const char *DefaultResult;
    551 #ifdef LLVM_ON_WIN32
    552   (void)erasedOnReboot;
    553   DefaultResult = "C:\\TEMP";
    554 #else
    555   if (erasedOnReboot)
    556     DefaultResult = "/tmp";
    557   else
    558     DefaultResult = "/var/tmp";
    559 #endif
    560   result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
    561 }
    562 
    563 bool has_root_name(const Twine &path) {
    564   SmallString<128> path_storage;
    565   StringRef p = path.toStringRef(path_storage);
    566 
    567   return !root_name(p).empty();
    568 }
    569 
    570 bool has_root_directory(const Twine &path) {
    571   SmallString<128> path_storage;
    572   StringRef p = path.toStringRef(path_storage);
    573 
    574   return !root_directory(p).empty();
    575 }
    576 
    577 bool has_root_path(const Twine &path) {
    578   SmallString<128> path_storage;
    579   StringRef p = path.toStringRef(path_storage);
    580 
    581   return !root_path(p).empty();
    582 }
    583 
    584 bool has_relative_path(const Twine &path) {
    585   SmallString<128> path_storage;
    586   StringRef p = path.toStringRef(path_storage);
    587 
    588   return !relative_path(p).empty();
    589 }
    590 
    591 bool has_filename(const Twine &path) {
    592   SmallString<128> path_storage;
    593   StringRef p = path.toStringRef(path_storage);
    594 
    595   return !filename(p).empty();
    596 }
    597 
    598 bool has_parent_path(const Twine &path) {
    599   SmallString<128> path_storage;
    600   StringRef p = path.toStringRef(path_storage);
    601 
    602   return !parent_path(p).empty();
    603 }
    604 
    605 bool has_stem(const Twine &path) {
    606   SmallString<128> path_storage;
    607   StringRef p = path.toStringRef(path_storage);
    608 
    609   return !stem(p).empty();
    610 }
    611 
    612 bool has_extension(const Twine &path) {
    613   SmallString<128> path_storage;
    614   StringRef p = path.toStringRef(path_storage);
    615 
    616   return !extension(p).empty();
    617 }
    618 
    619 bool is_absolute(const Twine &path) {
    620   SmallString<128> path_storage;
    621   StringRef p = path.toStringRef(path_storage);
    622 
    623   bool rootDir = has_root_directory(p),
    624 #ifdef LLVM_ON_WIN32
    625        rootName = has_root_name(p);
    626 #else
    627        rootName = true;
    628 #endif
    629 
    630   return rootDir && rootName;
    631 }
    632 
    633 bool is_relative(const Twine &path) {
    634   return !is_absolute(path);
    635 }
    636 
    637 } // end namespace path
    638 
    639 namespace fs {
    640 
    641 error_code getUniqueID(const Twine Path, UniqueID &Result) {
    642   file_status Status;
    643   error_code EC = status(Path, Status);
    644   if (EC)
    645     return EC;
    646   Result = Status.getUniqueID();
    647   return error_code::success();
    648 }
    649 
    650 error_code createUniqueFile(const Twine &Model, int &ResultFd,
    651                             SmallVectorImpl<char> &ResultPath, unsigned Mode) {
    652   return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
    653 }
    654 
    655 error_code createUniqueFile(const Twine &Model,
    656                             SmallVectorImpl<char> &ResultPath) {
    657   int Dummy;
    658   return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
    659 }
    660 
    661 static error_code createTemporaryFile(const Twine &Model, int &ResultFD,
    662                                       llvm::SmallVectorImpl<char> &ResultPath,
    663                                       FSEntity Type) {
    664   SmallString<128> Storage;
    665   StringRef P = Model.toNullTerminatedStringRef(Storage);
    666   assert(P.find_first_of(separators) == StringRef::npos &&
    667          "Model must be a simple filename.");
    668   // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
    669   return createUniqueEntity(P.begin(), ResultFD, ResultPath,
    670                             true, owner_read | owner_write, Type);
    671 }
    672 
    673 static error_code
    674 createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
    675                     llvm::SmallVectorImpl<char> &ResultPath,
    676                     FSEntity Type) {
    677   const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
    678   return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
    679                              Type);
    680 }
    681 
    682 
    683 error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
    684                                int &ResultFD,
    685                                SmallVectorImpl<char> &ResultPath) {
    686   return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
    687 }
    688 
    689 error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
    690                                SmallVectorImpl<char> &ResultPath) {
    691   int Dummy;
    692   return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
    693 }
    694 
    695 
    696 // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
    697 // for consistency. We should try using mkdtemp.
    698 error_code createUniqueDirectory(const Twine &Prefix,
    699                                  SmallVectorImpl<char> &ResultPath) {
    700   int Dummy;
    701   return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
    702                             true, 0, FS_Dir);
    703 }
    704 
    705 error_code make_absolute(SmallVectorImpl<char> &path) {
    706   StringRef p(path.data(), path.size());
    707 
    708   bool rootDirectory = path::has_root_directory(p),
    709 #ifdef LLVM_ON_WIN32
    710        rootName = path::has_root_name(p);
    711 #else
    712        rootName = true;
    713 #endif
    714 
    715   // Already absolute.
    716   if (rootName && rootDirectory)
    717     return error_code::success();
    718 
    719   // All of the following conditions will need the current directory.
    720   SmallString<128> current_dir;
    721   if (error_code ec = current_path(current_dir)) return ec;
    722 
    723   // Relative path. Prepend the current directory.
    724   if (!rootName && !rootDirectory) {
    725     // Append path to the current directory.
    726     path::append(current_dir, p);
    727     // Set path to the result.
    728     path.swap(current_dir);
    729     return error_code::success();
    730   }
    731 
    732   if (!rootName && rootDirectory) {
    733     StringRef cdrn = path::root_name(current_dir);
    734     SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
    735     path::append(curDirRootName, p);
    736     // Set path to the result.
    737     path.swap(curDirRootName);
    738     return error_code::success();
    739   }
    740 
    741   if (rootName && !rootDirectory) {
    742     StringRef pRootName      = path::root_name(p);
    743     StringRef bRootDirectory = path::root_directory(current_dir);
    744     StringRef bRelativePath  = path::relative_path(current_dir);
    745     StringRef pRelativePath  = path::relative_path(p);
    746 
    747     SmallString<128> res;
    748     path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
    749     path.swap(res);
    750     return error_code::success();
    751   }
    752 
    753   llvm_unreachable("All rootName and rootDirectory combinations should have "
    754                    "occurred above!");
    755 }
    756 
    757 error_code create_directories(const Twine &path, bool &existed) {
    758   SmallString<128> path_storage;
    759   StringRef p = path.toStringRef(path_storage);
    760 
    761   StringRef parent = path::parent_path(p);
    762   if (!parent.empty()) {
    763     bool parent_exists;
    764     if (error_code ec = fs::exists(parent, parent_exists)) return ec;
    765 
    766     if (!parent_exists)
    767       if (error_code ec = create_directories(parent, existed)) return ec;
    768   }
    769 
    770   return create_directory(p, existed);
    771 }
    772 
    773 bool exists(file_status status) {
    774   return status_known(status) && status.type() != file_type::file_not_found;
    775 }
    776 
    777 bool status_known(file_status s) {
    778   return s.type() != file_type::status_error;
    779 }
    780 
    781 bool is_directory(file_status status) {
    782   return status.type() == file_type::directory_file;
    783 }
    784 
    785 error_code is_directory(const Twine &path, bool &result) {
    786   file_status st;
    787   if (error_code ec = status(path, st))
    788     return ec;
    789   result = is_directory(st);
    790   return error_code::success();
    791 }
    792 
    793 bool is_regular_file(file_status status) {
    794   return status.type() == file_type::regular_file;
    795 }
    796 
    797 error_code is_regular_file(const Twine &path, bool &result) {
    798   file_status st;
    799   if (error_code ec = status(path, st))
    800     return ec;
    801   result = is_regular_file(st);
    802   return error_code::success();
    803 }
    804 
    805 bool is_symlink(file_status status) {
    806   return status.type() == file_type::symlink_file;
    807 }
    808 
    809 error_code is_symlink(const Twine &path, bool &result) {
    810   file_status st;
    811   if (error_code ec = status(path, st))
    812     return ec;
    813   result = is_symlink(st);
    814   return error_code::success();
    815 }
    816 
    817 bool is_other(file_status status) {
    818   return exists(status) &&
    819          !is_regular_file(status) &&
    820          !is_directory(status) &&
    821          !is_symlink(status);
    822 }
    823 
    824 void directory_entry::replace_filename(const Twine &filename, file_status st) {
    825   SmallString<128> path(Path.begin(), Path.end());
    826   path::remove_filename(path);
    827   path::append(path, filename);
    828   Path = path.str();
    829   Status = st;
    830 }
    831 
    832 error_code has_magic(const Twine &path, const Twine &magic, bool &result) {
    833   SmallString<32>  MagicStorage;
    834   StringRef Magic = magic.toStringRef(MagicStorage);
    835   SmallString<32> Buffer;
    836 
    837   if (error_code ec = get_magic(path, Magic.size(), Buffer)) {
    838     if (ec == errc::value_too_large) {
    839       // Magic.size() > file_size(Path).
    840       result = false;
    841       return error_code::success();
    842     }
    843     return ec;
    844   }
    845 
    846   result = Magic == Buffer;
    847   return error_code::success();
    848 }
    849 
    850 /// @brief Identify the magic in magic.
    851   file_magic identify_magic(StringRef Magic) {
    852   if (Magic.size() < 4)
    853     return file_magic::unknown;
    854   switch ((unsigned char)Magic[0]) {
    855     case 0xDE:  // 0x0B17C0DE = BC wraper
    856       if (Magic[1] == (char)0xC0 && Magic[2] == (char)0x17 &&
    857           Magic[3] == (char)0x0B)
    858         return file_magic::bitcode;
    859       break;
    860     case 'B':
    861       if (Magic[1] == 'C' && Magic[2] == (char)0xC0 && Magic[3] == (char)0xDE)
    862         return file_magic::bitcode;
    863       break;
    864     case '!':
    865       if (Magic.size() >= 8)
    866         if (memcmp(Magic.data(),"!<arch>\n",8) == 0)
    867           return file_magic::archive;
    868       break;
    869 
    870     case '\177':
    871       if (Magic.size() >= 18 && Magic[1] == 'E' && Magic[2] == 'L' &&
    872           Magic[3] == 'F') {
    873         bool Data2MSB = Magic[5] == 2;
    874         unsigned high = Data2MSB ? 16 : 17;
    875         unsigned low  = Data2MSB ? 17 : 16;
    876         if (Magic[high] == 0)
    877           switch (Magic[low]) {
    878             default: break;
    879             case 1: return file_magic::elf_relocatable;
    880             case 2: return file_magic::elf_executable;
    881             case 3: return file_magic::elf_shared_object;
    882             case 4: return file_magic::elf_core;
    883           }
    884       }
    885       break;
    886 
    887     case 0xCA:
    888       if (Magic[1] == char(0xFE) && Magic[2] == char(0xBA) &&
    889           Magic[3] == char(0xBE)) {
    890         // This is complicated by an overlap with Java class files.
    891         // See the Mach-O section in /usr/share/file/magic for details.
    892         if (Magic.size() >= 8 && Magic[7] < 43)
    893           return file_magic::macho_universal_binary;
    894       }
    895       break;
    896 
    897       // The two magic numbers for mach-o are:
    898       // 0xfeedface - 32-bit mach-o
    899       // 0xfeedfacf - 64-bit mach-o
    900     case 0xFE:
    901     case 0xCE:
    902     case 0xCF: {
    903       uint16_t type = 0;
    904       if (Magic[0] == char(0xFE) && Magic[1] == char(0xED) &&
    905           Magic[2] == char(0xFA) &&
    906           (Magic[3] == char(0xCE) || Magic[3] == char(0xCF))) {
    907         /* Native endian */
    908         if (Magic.size() >= 16) type = Magic[14] << 8 | Magic[15];
    909       } else if ((Magic[0] == char(0xCE) || Magic[0] == char(0xCF)) &&
    910                  Magic[1] == char(0xFA) && Magic[2] == char(0xED) &&
    911                  Magic[3] == char(0xFE)) {
    912         /* Reverse endian */
    913         if (Magic.size() >= 14) type = Magic[13] << 8 | Magic[12];
    914       }
    915       switch (type) {
    916         default: break;
    917         case 1: return file_magic::macho_object;
    918         case 2: return file_magic::macho_executable;
    919         case 3: return file_magic::macho_fixed_virtual_memory_shared_lib;
    920         case 4: return file_magic::macho_core;
    921         case 5: return file_magic::macho_preload_executable;
    922         case 6: return file_magic::macho_dynamically_linked_shared_lib;
    923         case 7: return file_magic::macho_dynamic_linker;
    924         case 8: return file_magic::macho_bundle;
    925         case 9: return file_magic::macho_dynamic_linker;
    926         case 10: return file_magic::macho_dsym_companion;
    927       }
    928       break;
    929     }
    930     case 0xF0: // PowerPC Windows
    931     case 0x83: // Alpha 32-bit
    932     case 0x84: // Alpha 64-bit
    933     case 0x66: // MPS R4000 Windows
    934     case 0x50: // mc68K
    935     case 0x4c: // 80386 Windows
    936       if (Magic[1] == 0x01)
    937         return file_magic::coff_object;
    938 
    939     case 0x90: // PA-RISC Windows
    940     case 0x68: // mc68K Windows
    941       if (Magic[1] == 0x02)
    942         return file_magic::coff_object;
    943       break;
    944 
    945     case 0x4d: // Possible MS-DOS stub on Windows PE file
    946       if (Magic[1] == 0x5a) {
    947         uint32_t off =
    948           *reinterpret_cast<const support::ulittle32_t*>(Magic.data() + 0x3c);
    949         // PE/COFF file, either EXE or DLL.
    950         if (off < Magic.size() && memcmp(Magic.data() + off, "PE\0\0",4) == 0)
    951           return file_magic::pecoff_executable;
    952       }
    953       break;
    954 
    955     case 0x64: // x86-64 Windows.
    956       if (Magic[1] == char(0x86))
    957         return file_magic::coff_object;
    958       break;
    959 
    960     default:
    961       break;
    962   }
    963   return file_magic::unknown;
    964 }
    965 
    966 error_code identify_magic(const Twine &path, file_magic &result) {
    967   SmallString<32> Magic;
    968   error_code ec = get_magic(path, Magic.capacity(), Magic);
    969   if (ec && ec != errc::value_too_large)
    970     return ec;
    971 
    972   result = identify_magic(Magic);
    973   return error_code::success();
    974 }
    975 
    976 namespace {
    977 error_code remove_all_r(StringRef path, file_type ft, uint32_t &count) {
    978   if (ft == file_type::directory_file) {
    979     // This code would be a lot better with exceptions ;/.
    980     error_code ec;
    981     directory_iterator i(path, ec);
    982     if (ec) return ec;
    983     for (directory_iterator e; i != e; i.increment(ec)) {
    984       if (ec) return ec;
    985       file_status st;
    986       if (error_code ec = i->status(st)) return ec;
    987       if (error_code ec = remove_all_r(i->path(), st.type(), count)) return ec;
    988     }
    989     bool obviously_this_exists;
    990     if (error_code ec = remove(path, obviously_this_exists)) return ec;
    991     assert(obviously_this_exists);
    992     ++count; // Include the directory itself in the items removed.
    993   } else {
    994     bool obviously_this_exists;
    995     if (error_code ec = remove(path, obviously_this_exists)) return ec;
    996     assert(obviously_this_exists);
    997     ++count;
    998   }
    999 
   1000   return error_code::success();
   1001 }
   1002 } // end unnamed namespace
   1003 
   1004 error_code remove_all(const Twine &path, uint32_t &num_removed) {
   1005   SmallString<128> path_storage;
   1006   StringRef p = path.toStringRef(path_storage);
   1007 
   1008   file_status fs;
   1009   if (error_code ec = status(path, fs))
   1010     return ec;
   1011   num_removed = 0;
   1012   return remove_all_r(p, fs.type(), num_removed);
   1013 }
   1014 
   1015 error_code directory_entry::status(file_status &result) const {
   1016   return fs::status(Path, result);
   1017 }
   1018 
   1019 } // end namespace fs
   1020 } // end namespace sys
   1021 } // end namespace llvm
   1022 
   1023 // Include the truly platform-specific parts.
   1024 #if defined(LLVM_ON_UNIX)
   1025 #include "Unix/Path.inc"
   1026 #endif
   1027 #if defined(LLVM_ON_WIN32)
   1028 #include "Windows/Path.inc"
   1029 #endif
   1030