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/COFF.h"
     15 #include "llvm/Support/MachO.h"
     16 #include "llvm/Support/Endian.h"
     17 #include "llvm/Support/Errc.h"
     18 #include "llvm/Support/ErrorHandling.h"
     19 #include "llvm/Support/FileSystem.h"
     20 #include "llvm/Support/Path.h"
     21 #include "llvm/Support/Process.h"
     22 #include <cctype>
     23 #include <cstring>
     24 
     25 #if !defined(_MSC_VER) && !defined(__MINGW32__)
     26 #include <unistd.h>
     27 #else
     28 #include <io.h>
     29 #endif
     30 
     31 using namespace llvm;
     32 using namespace llvm::support::endian;
     33 
     34 namespace {
     35   using llvm::StringRef;
     36   using llvm::sys::path::is_separator;
     37 
     38 #ifdef LLVM_ON_WIN32
     39   const char *separators = "\\/";
     40   const char preferred_separator = '\\';
     41 #else
     42   const char  separators = '/';
     43   const char preferred_separator = '/';
     44 #endif
     45 
     46   StringRef find_first_component(StringRef path) {
     47     // Look for this first component in the following order.
     48     // * empty (in this case we return an empty string)
     49     // * either C: or {//,\\}net.
     50     // * {/,\}
     51     // * {file,directory}name
     52 
     53     if (path.empty())
     54       return path;
     55 
     56 #ifdef LLVM_ON_WIN32
     57     // C:
     58     if (path.size() >= 2 && std::isalpha(static_cast<unsigned char>(path[0])) &&
     59         path[1] == ':')
     60       return path.substr(0, 2);
     61 #endif
     62 
     63     // //net
     64     if ((path.size() > 2) &&
     65         is_separator(path[0]) &&
     66         path[0] == path[1] &&
     67         !is_separator(path[2])) {
     68       // Find the next directory separator.
     69       size_t end = path.find_first_of(separators, 2);
     70       return path.substr(0, end);
     71     }
     72 
     73     // {/,\}
     74     if (is_separator(path[0]))
     75       return path.substr(0, 1);
     76 
     77     // * {file,directory}name
     78     size_t end = path.find_first_of(separators);
     79     return path.substr(0, end);
     80   }
     81 
     82   size_t filename_pos(StringRef str) {
     83     if (str.size() == 2 &&
     84         is_separator(str[0]) &&
     85         str[0] == str[1])
     86       return 0;
     87 
     88     if (str.size() > 0 && is_separator(str[str.size() - 1]))
     89       return str.size() - 1;
     90 
     91     size_t pos = str.find_last_of(separators, str.size() - 1);
     92 
     93 #ifdef LLVM_ON_WIN32
     94     if (pos == StringRef::npos)
     95       pos = str.find_last_of(':', str.size() - 2);
     96 #endif
     97 
     98     if (pos == StringRef::npos ||
     99         (pos == 1 && is_separator(str[0])))
    100       return 0;
    101 
    102     return pos + 1;
    103   }
    104 
    105   size_t root_dir_start(StringRef str) {
    106     // case "c:/"
    107 #ifdef LLVM_ON_WIN32
    108     if (str.size() > 2 &&
    109         str[1] == ':' &&
    110         is_separator(str[2]))
    111       return 2;
    112 #endif
    113 
    114     // case "//"
    115     if (str.size() == 2 &&
    116         is_separator(str[0]) &&
    117         str[0] == str[1])
    118       return StringRef::npos;
    119 
    120     // case "//net"
    121     if (str.size() > 3 &&
    122         is_separator(str[0]) &&
    123         str[0] == str[1] &&
    124         !is_separator(str[2])) {
    125       return str.find_first_of(separators, 2);
    126     }
    127 
    128     // case "/"
    129     if (str.size() > 0 && is_separator(str[0]))
    130       return 0;
    131 
    132     return StringRef::npos;
    133   }
    134 
    135   size_t parent_path_end(StringRef path) {
    136     size_t end_pos = filename_pos(path);
    137 
    138     bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
    139 
    140     // Skip separators except for root dir.
    141     size_t root_dir_pos = root_dir_start(path.substr(0, end_pos));
    142 
    143     while(end_pos > 0 &&
    144           (end_pos - 1) != root_dir_pos &&
    145           is_separator(path[end_pos - 1]))
    146       --end_pos;
    147 
    148     if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
    149       return StringRef::npos;
    150 
    151     return end_pos;
    152   }
    153 } // end unnamed namespace
    154 
    155 enum FSEntity {
    156   FS_Dir,
    157   FS_File,
    158   FS_Name
    159 };
    160 
    161 static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD,
    162                                           SmallVectorImpl<char> &ResultPath,
    163                                           bool MakeAbsolute, unsigned Mode,
    164                                           FSEntity Type) {
    165   SmallString<128> ModelStorage;
    166   Model.toVector(ModelStorage);
    167 
    168   if (MakeAbsolute) {
    169     // Make model absolute by prepending a temp directory if it's not already.
    170     if (!sys::path::is_absolute(Twine(ModelStorage))) {
    171       SmallString<128> TDir;
    172       sys::path::system_temp_directory(true, TDir);
    173       sys::path::append(TDir, Twine(ModelStorage));
    174       ModelStorage.swap(TDir);
    175     }
    176   }
    177 
    178   // From here on, DO NOT modify model. It may be needed if the randomly chosen
    179   // path already exists.
    180   ResultPath = ModelStorage;
    181   // Null terminate.
    182   ResultPath.push_back(0);
    183   ResultPath.pop_back();
    184 
    185 retry_random_path:
    186   // Replace '%' with random chars.
    187   for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
    188     if (ModelStorage[i] == '%')
    189       ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
    190   }
    191 
    192   // Try to open + create the file.
    193   switch (Type) {
    194   case FS_File: {
    195     if (std::error_code EC =
    196             sys::fs::openFileForWrite(Twine(ResultPath.begin()), ResultFD,
    197                                       sys::fs::F_RW | sys::fs::F_Excl, Mode)) {
    198       if (EC == errc::file_exists)
    199         goto retry_random_path;
    200       return EC;
    201     }
    202 
    203     return std::error_code();
    204   }
    205 
    206   case FS_Name: {
    207     std::error_code EC =
    208         sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist);
    209     if (EC == errc::no_such_file_or_directory)
    210       return std::error_code();
    211     if (EC)
    212       return EC;
    213     goto retry_random_path;
    214   }
    215 
    216   case FS_Dir: {
    217     if (std::error_code EC =
    218             sys::fs::create_directory(ResultPath.begin(), false)) {
    219       if (EC == errc::file_exists)
    220         goto retry_random_path;
    221       return EC;
    222     }
    223     return std::error_code();
    224   }
    225   }
    226   llvm_unreachable("Invalid Type");
    227 }
    228 
    229 namespace llvm {
    230 namespace sys  {
    231 namespace path {
    232 
    233 const_iterator begin(StringRef path) {
    234   const_iterator i;
    235   i.Path      = path;
    236   i.Component = find_first_component(path);
    237   i.Position  = 0;
    238   return i;
    239 }
    240 
    241 const_iterator end(StringRef path) {
    242   const_iterator i;
    243   i.Path      = path;
    244   i.Position  = path.size();
    245   return i;
    246 }
    247 
    248 const_iterator &const_iterator::operator++() {
    249   assert(Position < Path.size() && "Tried to increment past end!");
    250 
    251   // Increment Position to past the current component
    252   Position += Component.size();
    253 
    254   // Check for end.
    255   if (Position == Path.size()) {
    256     Component = StringRef();
    257     return *this;
    258   }
    259 
    260   // Both POSIX and Windows treat paths that begin with exactly two separators
    261   // specially.
    262   bool was_net = Component.size() > 2 &&
    263     is_separator(Component[0]) &&
    264     Component[1] == Component[0] &&
    265     !is_separator(Component[2]);
    266 
    267   // Handle separators.
    268   if (is_separator(Path[Position])) {
    269     // Root dir.
    270     if (was_net
    271 #ifdef LLVM_ON_WIN32
    272         // c:/
    273         || Component.endswith(":")
    274 #endif
    275         ) {
    276       Component = Path.substr(Position, 1);
    277       return *this;
    278     }
    279 
    280     // Skip extra separators.
    281     while (Position != Path.size() &&
    282            is_separator(Path[Position])) {
    283       ++Position;
    284     }
    285 
    286     // Treat trailing '/' as a '.'.
    287     if (Position == Path.size()) {
    288       --Position;
    289       Component = ".";
    290       return *this;
    291     }
    292   }
    293 
    294   // Find next component.
    295   size_t end_pos = Path.find_first_of(separators, Position);
    296   Component = Path.slice(Position, end_pos);
    297 
    298   return *this;
    299 }
    300 
    301 bool const_iterator::operator==(const const_iterator &RHS) const {
    302   return Path.begin() == RHS.Path.begin() && Position == RHS.Position;
    303 }
    304 
    305 ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
    306   return Position - RHS.Position;
    307 }
    308 
    309 reverse_iterator rbegin(StringRef Path) {
    310   reverse_iterator I;
    311   I.Path = Path;
    312   I.Position = Path.size();
    313   return ++I;
    314 }
    315 
    316 reverse_iterator rend(StringRef Path) {
    317   reverse_iterator I;
    318   I.Path = Path;
    319   I.Component = Path.substr(0, 0);
    320   I.Position = 0;
    321   return I;
    322 }
    323 
    324 reverse_iterator &reverse_iterator::operator++() {
    325   // If we're at the end and the previous char was a '/', return '.' unless
    326   // we are the root path.
    327   size_t root_dir_pos = root_dir_start(Path);
    328   if (Position == Path.size() &&
    329       Path.size() > root_dir_pos + 1 &&
    330       is_separator(Path[Position - 1])) {
    331     --Position;
    332     Component = ".";
    333     return *this;
    334   }
    335 
    336   // Skip separators unless it's the root directory.
    337   size_t end_pos = Position;
    338 
    339   while(end_pos > 0 &&
    340         (end_pos - 1) != root_dir_pos &&
    341         is_separator(Path[end_pos - 1]))
    342     --end_pos;
    343 
    344   // Find next separator.
    345   size_t start_pos = filename_pos(Path.substr(0, end_pos));
    346   Component = Path.slice(start_pos, end_pos);
    347   Position = start_pos;
    348   return *this;
    349 }
    350 
    351 bool reverse_iterator::operator==(const reverse_iterator &RHS) const {
    352   return Path.begin() == RHS.Path.begin() && Component == RHS.Component &&
    353          Position == RHS.Position;
    354 }
    355 
    356 ptrdiff_t reverse_iterator::operator-(const reverse_iterator &RHS) const {
    357   return Position - RHS.Position;
    358 }
    359 
    360 StringRef root_path(StringRef path) {
    361   const_iterator b = begin(path),
    362                  pos = b,
    363                  e = end(path);
    364   if (b != e) {
    365     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
    366     bool has_drive =
    367 #ifdef LLVM_ON_WIN32
    368       b->endswith(":");
    369 #else
    370       false;
    371 #endif
    372 
    373     if (has_net || has_drive) {
    374       if ((++pos != e) && is_separator((*pos)[0])) {
    375         // {C:/,//net/}, so get the first two components.
    376         return path.substr(0, b->size() + pos->size());
    377       } else {
    378         // just {C:,//net}, return the first component.
    379         return *b;
    380       }
    381     }
    382 
    383     // POSIX style root directory.
    384     if (is_separator((*b)[0])) {
    385       return *b;
    386     }
    387   }
    388 
    389   return StringRef();
    390 }
    391 
    392 StringRef root_name(StringRef path) {
    393   const_iterator b = begin(path),
    394                  e = end(path);
    395   if (b != e) {
    396     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
    397     bool has_drive =
    398 #ifdef LLVM_ON_WIN32
    399       b->endswith(":");
    400 #else
    401       false;
    402 #endif
    403 
    404     if (has_net || has_drive) {
    405       // just {C:,//net}, return the first component.
    406       return *b;
    407     }
    408   }
    409 
    410   // No path or no name.
    411   return StringRef();
    412 }
    413 
    414 StringRef root_directory(StringRef path) {
    415   const_iterator b = begin(path),
    416                  pos = b,
    417                  e = end(path);
    418   if (b != e) {
    419     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
    420     bool has_drive =
    421 #ifdef LLVM_ON_WIN32
    422       b->endswith(":");
    423 #else
    424       false;
    425 #endif
    426 
    427     if ((has_net || has_drive) &&
    428         // {C:,//net}, skip to the next component.
    429         (++pos != e) && is_separator((*pos)[0])) {
    430       return *pos;
    431     }
    432 
    433     // POSIX style root directory.
    434     if (!has_net && is_separator((*b)[0])) {
    435       return *b;
    436     }
    437   }
    438 
    439   // No path or no root.
    440   return StringRef();
    441 }
    442 
    443 StringRef relative_path(StringRef path) {
    444   StringRef root = root_path(path);
    445   return path.substr(root.size());
    446 }
    447 
    448 void append(SmallVectorImpl<char> &path, const Twine &a,
    449                                          const Twine &b,
    450                                          const Twine &c,
    451                                          const Twine &d) {
    452   SmallString<32> a_storage;
    453   SmallString<32> b_storage;
    454   SmallString<32> c_storage;
    455   SmallString<32> d_storage;
    456 
    457   SmallVector<StringRef, 4> components;
    458   if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
    459   if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
    460   if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
    461   if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
    462 
    463   for (auto &component : components) {
    464     bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
    465     bool component_has_sep = !component.empty() && is_separator(component[0]);
    466     bool is_root_name = has_root_name(component);
    467 
    468     if (path_has_sep) {
    469       // Strip separators from beginning of component.
    470       size_t loc = component.find_first_not_of(separators);
    471       StringRef c = component.substr(loc);
    472 
    473       // Append it.
    474       path.append(c.begin(), c.end());
    475       continue;
    476     }
    477 
    478     if (!component_has_sep && !(path.empty() || is_root_name)) {
    479       // Add a separator.
    480       path.push_back(preferred_separator);
    481     }
    482 
    483     path.append(component.begin(), component.end());
    484   }
    485 }
    486 
    487 void append(SmallVectorImpl<char> &path,
    488             const_iterator begin, const_iterator end) {
    489   for (; begin != end; ++begin)
    490     path::append(path, *begin);
    491 }
    492 
    493 StringRef parent_path(StringRef path) {
    494   size_t end_pos = parent_path_end(path);
    495   if (end_pos == StringRef::npos)
    496     return StringRef();
    497   else
    498     return path.substr(0, end_pos);
    499 }
    500 
    501 void remove_filename(SmallVectorImpl<char> &path) {
    502   size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
    503   if (end_pos != StringRef::npos)
    504     path.set_size(end_pos);
    505 }
    506 
    507 void replace_extension(SmallVectorImpl<char> &path, const Twine &extension) {
    508   StringRef p(path.begin(), path.size());
    509   SmallString<32> ext_storage;
    510   StringRef ext = extension.toStringRef(ext_storage);
    511 
    512   // Erase existing extension.
    513   size_t pos = p.find_last_of('.');
    514   if (pos != StringRef::npos && pos >= filename_pos(p))
    515     path.set_size(pos);
    516 
    517   // Append '.' if needed.
    518   if (ext.size() > 0 && ext[0] != '.')
    519     path.push_back('.');
    520 
    521   // Append extension.
    522   path.append(ext.begin(), ext.end());
    523 }
    524 
    525 void replace_path_prefix(SmallVectorImpl<char> &Path,
    526                          const StringRef &OldPrefix,
    527                          const StringRef &NewPrefix) {
    528   if (OldPrefix.empty() && NewPrefix.empty())
    529     return;
    530 
    531   StringRef OrigPath(Path.begin(), Path.size());
    532   if (!OrigPath.startswith(OldPrefix))
    533     return;
    534 
    535   // If prefixes have the same size we can simply copy the new one over.
    536   if (OldPrefix.size() == NewPrefix.size()) {
    537     std::copy(NewPrefix.begin(), NewPrefix.end(), Path.begin());
    538     return;
    539   }
    540 
    541   StringRef RelPath = OrigPath.substr(OldPrefix.size());
    542   SmallString<256> NewPath;
    543   path::append(NewPath, NewPrefix);
    544   path::append(NewPath, RelPath);
    545   Path.swap(NewPath);
    546 }
    547 
    548 void native(const Twine &path, SmallVectorImpl<char> &result) {
    549   assert((!path.isSingleStringRef() ||
    550           path.getSingleStringRef().data() != result.data()) &&
    551          "path and result are not allowed to overlap!");
    552   // Clear result.
    553   result.clear();
    554   path.toVector(result);
    555   native(result);
    556 }
    557 
    558 void native(SmallVectorImpl<char> &Path) {
    559 #ifdef LLVM_ON_WIN32
    560   std::replace(Path.begin(), Path.end(), '/', '\\');
    561 #else
    562   for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
    563     if (*PI == '\\') {
    564       auto PN = PI + 1;
    565       if (PN < PE && *PN == '\\')
    566         ++PI; // increment once, the for loop will move over the escaped slash
    567       else
    568         *PI = '/';
    569     }
    570   }
    571 #endif
    572 }
    573 
    574 StringRef filename(StringRef path) {
    575   return *rbegin(path);
    576 }
    577 
    578 StringRef stem(StringRef path) {
    579   StringRef fname = filename(path);
    580   size_t pos = fname.find_last_of('.');
    581   if (pos == StringRef::npos)
    582     return fname;
    583   else
    584     if ((fname.size() == 1 && fname == ".") ||
    585         (fname.size() == 2 && fname == ".."))
    586       return fname;
    587     else
    588       return fname.substr(0, pos);
    589 }
    590 
    591 StringRef extension(StringRef path) {
    592   StringRef fname = filename(path);
    593   size_t pos = fname.find_last_of('.');
    594   if (pos == StringRef::npos)
    595     return StringRef();
    596   else
    597     if ((fname.size() == 1 && fname == ".") ||
    598         (fname.size() == 2 && fname == ".."))
    599       return StringRef();
    600     else
    601       return fname.substr(pos);
    602 }
    603 
    604 bool is_separator(char value) {
    605   switch(value) {
    606 #ifdef LLVM_ON_WIN32
    607     case '\\': // fall through
    608 #endif
    609     case '/': return true;
    610     default: return false;
    611   }
    612 }
    613 
    614 static const char preferred_separator_string[] = { preferred_separator, '\0' };
    615 
    616 StringRef get_separator() {
    617   return preferred_separator_string;
    618 }
    619 
    620 bool has_root_name(const Twine &path) {
    621   SmallString<128> path_storage;
    622   StringRef p = path.toStringRef(path_storage);
    623 
    624   return !root_name(p).empty();
    625 }
    626 
    627 bool has_root_directory(const Twine &path) {
    628   SmallString<128> path_storage;
    629   StringRef p = path.toStringRef(path_storage);
    630 
    631   return !root_directory(p).empty();
    632 }
    633 
    634 bool has_root_path(const Twine &path) {
    635   SmallString<128> path_storage;
    636   StringRef p = path.toStringRef(path_storage);
    637 
    638   return !root_path(p).empty();
    639 }
    640 
    641 bool has_relative_path(const Twine &path) {
    642   SmallString<128> path_storage;
    643   StringRef p = path.toStringRef(path_storage);
    644 
    645   return !relative_path(p).empty();
    646 }
    647 
    648 bool has_filename(const Twine &path) {
    649   SmallString<128> path_storage;
    650   StringRef p = path.toStringRef(path_storage);
    651 
    652   return !filename(p).empty();
    653 }
    654 
    655 bool has_parent_path(const Twine &path) {
    656   SmallString<128> path_storage;
    657   StringRef p = path.toStringRef(path_storage);
    658 
    659   return !parent_path(p).empty();
    660 }
    661 
    662 bool has_stem(const Twine &path) {
    663   SmallString<128> path_storage;
    664   StringRef p = path.toStringRef(path_storage);
    665 
    666   return !stem(p).empty();
    667 }
    668 
    669 bool has_extension(const Twine &path) {
    670   SmallString<128> path_storage;
    671   StringRef p = path.toStringRef(path_storage);
    672 
    673   return !extension(p).empty();
    674 }
    675 
    676 bool is_absolute(const Twine &path) {
    677   SmallString<128> path_storage;
    678   StringRef p = path.toStringRef(path_storage);
    679 
    680   bool rootDir = has_root_directory(p),
    681 #ifdef LLVM_ON_WIN32
    682        rootName = has_root_name(p);
    683 #else
    684        rootName = true;
    685 #endif
    686 
    687   return rootDir && rootName;
    688 }
    689 
    690 bool is_relative(const Twine &path) { return !is_absolute(path); }
    691 
    692 StringRef remove_leading_dotslash(StringRef Path) {
    693   // Remove leading "./" (or ".//" or "././" etc.)
    694   while (Path.size() > 2 && Path[0] == '.' && is_separator(Path[1])) {
    695     Path = Path.substr(2);
    696     while (Path.size() > 0 && is_separator(Path[0]))
    697       Path = Path.substr(1);
    698   }
    699   return Path;
    700 }
    701 
    702 static SmallString<256> remove_dots(StringRef path, bool remove_dot_dot) {
    703   SmallVector<StringRef, 16> components;
    704 
    705   // Skip the root path, then look for traversal in the components.
    706   StringRef rel = path::relative_path(path);
    707   for (StringRef C : llvm::make_range(path::begin(rel), path::end(rel))) {
    708     if (C == ".")
    709       continue;
    710     // Leading ".." will remain in the path unless it's at the root.
    711     if (remove_dot_dot && C == "..") {
    712       if (!components.empty() && components.back() != "..") {
    713         components.pop_back();
    714         continue;
    715       }
    716       if (path::is_absolute(path))
    717         continue;
    718     }
    719     components.push_back(C);
    720   }
    721 
    722   SmallString<256> buffer = path::root_path(path);
    723   for (StringRef C : components)
    724     path::append(buffer, C);
    725   return buffer;
    726 }
    727 
    728 bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot) {
    729   StringRef p(path.data(), path.size());
    730 
    731   SmallString<256> result = remove_dots(p, remove_dot_dot);
    732   if (result == path)
    733     return false;
    734 
    735   path.swap(result);
    736   return true;
    737 }
    738 
    739 } // end namespace path
    740 
    741 namespace fs {
    742 
    743 std::error_code getUniqueID(const Twine Path, UniqueID &Result) {
    744   file_status Status;
    745   std::error_code EC = status(Path, Status);
    746   if (EC)
    747     return EC;
    748   Result = Status.getUniqueID();
    749   return std::error_code();
    750 }
    751 
    752 std::error_code createUniqueFile(const Twine &Model, int &ResultFd,
    753                                  SmallVectorImpl<char> &ResultPath,
    754                                  unsigned Mode) {
    755   return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
    756 }
    757 
    758 std::error_code createUniqueFile(const Twine &Model,
    759                                  SmallVectorImpl<char> &ResultPath) {
    760   int Dummy;
    761   return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
    762 }
    763 
    764 static std::error_code
    765 createTemporaryFile(const Twine &Model, int &ResultFD,
    766                     llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
    767   SmallString<128> Storage;
    768   StringRef P = Model.toNullTerminatedStringRef(Storage);
    769   assert(P.find_first_of(separators) == StringRef::npos &&
    770          "Model must be a simple filename.");
    771   // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
    772   return createUniqueEntity(P.begin(), ResultFD, ResultPath,
    773                             true, owner_read | owner_write, Type);
    774 }
    775 
    776 static std::error_code
    777 createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
    778                     llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
    779   const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
    780   return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
    781                              Type);
    782 }
    783 
    784 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
    785                                     int &ResultFD,
    786                                     SmallVectorImpl<char> &ResultPath) {
    787   return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
    788 }
    789 
    790 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
    791                                     SmallVectorImpl<char> &ResultPath) {
    792   int Dummy;
    793   return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
    794 }
    795 
    796 
    797 // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
    798 // for consistency. We should try using mkdtemp.
    799 std::error_code createUniqueDirectory(const Twine &Prefix,
    800                                       SmallVectorImpl<char> &ResultPath) {
    801   int Dummy;
    802   return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
    803                             true, 0, FS_Dir);
    804 }
    805 
    806 static std::error_code make_absolute(const Twine &current_directory,
    807                                      SmallVectorImpl<char> &path,
    808                                      bool use_current_directory) {
    809   StringRef p(path.data(), path.size());
    810 
    811   bool rootDirectory = path::has_root_directory(p),
    812 #ifdef LLVM_ON_WIN32
    813        rootName = path::has_root_name(p);
    814 #else
    815        rootName = true;
    816 #endif
    817 
    818   // Already absolute.
    819   if (rootName && rootDirectory)
    820     return std::error_code();
    821 
    822   // All of the following conditions will need the current directory.
    823   SmallString<128> current_dir;
    824   if (use_current_directory)
    825     current_directory.toVector(current_dir);
    826   else if (std::error_code ec = current_path(current_dir))
    827     return ec;
    828 
    829   // Relative path. Prepend the current directory.
    830   if (!rootName && !rootDirectory) {
    831     // Append path to the current directory.
    832     path::append(current_dir, p);
    833     // Set path to the result.
    834     path.swap(current_dir);
    835     return std::error_code();
    836   }
    837 
    838   if (!rootName && rootDirectory) {
    839     StringRef cdrn = path::root_name(current_dir);
    840     SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
    841     path::append(curDirRootName, p);
    842     // Set path to the result.
    843     path.swap(curDirRootName);
    844     return std::error_code();
    845   }
    846 
    847   if (rootName && !rootDirectory) {
    848     StringRef pRootName      = path::root_name(p);
    849     StringRef bRootDirectory = path::root_directory(current_dir);
    850     StringRef bRelativePath  = path::relative_path(current_dir);
    851     StringRef pRelativePath  = path::relative_path(p);
    852 
    853     SmallString<128> res;
    854     path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
    855     path.swap(res);
    856     return std::error_code();
    857   }
    858 
    859   llvm_unreachable("All rootName and rootDirectory combinations should have "
    860                    "occurred above!");
    861 }
    862 
    863 std::error_code make_absolute(const Twine &current_directory,
    864                               SmallVectorImpl<char> &path) {
    865   return make_absolute(current_directory, path, true);
    866 }
    867 
    868 std::error_code make_absolute(SmallVectorImpl<char> &path) {
    869   return make_absolute(Twine(), path, false);
    870 }
    871 
    872 std::error_code create_directories(const Twine &Path, bool IgnoreExisting,
    873                                    perms Perms) {
    874   SmallString<128> PathStorage;
    875   StringRef P = Path.toStringRef(PathStorage);
    876 
    877   // Be optimistic and try to create the directory
    878   std::error_code EC = create_directory(P, IgnoreExisting, Perms);
    879   // If we succeeded, or had any error other than the parent not existing, just
    880   // return it.
    881   if (EC != errc::no_such_file_or_directory)
    882     return EC;
    883 
    884   // We failed because of a no_such_file_or_directory, try to create the
    885   // parent.
    886   StringRef Parent = path::parent_path(P);
    887   if (Parent.empty())
    888     return EC;
    889 
    890   if ((EC = create_directories(Parent, IgnoreExisting, Perms)))
    891       return EC;
    892 
    893   return create_directory(P, IgnoreExisting, Perms);
    894 }
    895 
    896 std::error_code copy_file(const Twine &From, const Twine &To) {
    897   int ReadFD, WriteFD;
    898   if (std::error_code EC = openFileForRead(From, ReadFD))
    899     return EC;
    900   if (std::error_code EC = openFileForWrite(To, WriteFD, F_None)) {
    901     close(ReadFD);
    902     return EC;
    903   }
    904 
    905   const size_t BufSize = 4096;
    906   char *Buf = new char[BufSize];
    907   int BytesRead = 0, BytesWritten = 0;
    908   for (;;) {
    909     BytesRead = read(ReadFD, Buf, BufSize);
    910     if (BytesRead <= 0)
    911       break;
    912     while (BytesRead) {
    913       BytesWritten = write(WriteFD, Buf, BytesRead);
    914       if (BytesWritten < 0)
    915         break;
    916       BytesRead -= BytesWritten;
    917     }
    918     if (BytesWritten < 0)
    919       break;
    920   }
    921   close(ReadFD);
    922   close(WriteFD);
    923   delete[] Buf;
    924 
    925   if (BytesRead < 0 || BytesWritten < 0)
    926     return std::error_code(errno, std::generic_category());
    927   return std::error_code();
    928 }
    929 
    930 bool exists(file_status status) {
    931   return status_known(status) && status.type() != file_type::file_not_found;
    932 }
    933 
    934 bool status_known(file_status s) {
    935   return s.type() != file_type::status_error;
    936 }
    937 
    938 bool is_directory(file_status status) {
    939   return status.type() == file_type::directory_file;
    940 }
    941 
    942 std::error_code is_directory(const Twine &path, bool &result) {
    943   file_status st;
    944   if (std::error_code ec = status(path, st))
    945     return ec;
    946   result = is_directory(st);
    947   return std::error_code();
    948 }
    949 
    950 bool is_regular_file(file_status status) {
    951   return status.type() == file_type::regular_file;
    952 }
    953 
    954 std::error_code is_regular_file(const Twine &path, bool &result) {
    955   file_status st;
    956   if (std::error_code ec = status(path, st))
    957     return ec;
    958   result = is_regular_file(st);
    959   return std::error_code();
    960 }
    961 
    962 bool is_other(file_status status) {
    963   return exists(status) &&
    964          !is_regular_file(status) &&
    965          !is_directory(status);
    966 }
    967 
    968 std::error_code is_other(const Twine &Path, bool &Result) {
    969   file_status FileStatus;
    970   if (std::error_code EC = status(Path, FileStatus))
    971     return EC;
    972   Result = is_other(FileStatus);
    973   return std::error_code();
    974 }
    975 
    976 void directory_entry::replace_filename(const Twine &filename, file_status st) {
    977   SmallString<128> path = path::parent_path(Path);
    978   path::append(path, filename);
    979   Path = path.str();
    980   Status = st;
    981 }
    982 
    983 template <size_t N>
    984 static bool startswith(StringRef Magic, const char (&S)[N]) {
    985   return Magic.startswith(StringRef(S, N - 1));
    986 }
    987 
    988 /// @brief Identify the magic in magic.
    989 file_magic identify_magic(StringRef Magic) {
    990   if (Magic.size() < 4)
    991     return file_magic::unknown;
    992   switch ((unsigned char)Magic[0]) {
    993     case 0x00: {
    994       // COFF bigobj, CL.exe's LTO object file, or short import library file
    995       if (startswith(Magic, "\0\0\xFF\xFF")) {
    996         size_t MinSize = offsetof(COFF::BigObjHeader, UUID) + sizeof(COFF::BigObjMagic);
    997         if (Magic.size() < MinSize)
    998           return file_magic::coff_import_library;
    999 
   1000         const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID);
   1001         if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) == 0)
   1002           return file_magic::coff_object;
   1003         if (memcmp(Start, COFF::ClGlObjMagic, sizeof(COFF::BigObjMagic)) == 0)
   1004           return file_magic::coff_cl_gl_object;
   1005         return file_magic::coff_import_library;
   1006       }
   1007       // Windows resource file
   1008       if (startswith(Magic, "\0\0\0\0\x20\0\0\0\xFF"))
   1009         return file_magic::windows_resource;
   1010       // 0x0000 = COFF unknown machine type
   1011       if (Magic[1] == 0)
   1012         return file_magic::coff_object;
   1013       if (startswith(Magic, "\0asm"))
   1014         return file_magic::wasm_object;
   1015       break;
   1016     }
   1017     case 0xDE:  // 0x0B17C0DE = BC wraper
   1018       if (startswith(Magic, "\xDE\xC0\x17\x0B"))
   1019         return file_magic::bitcode;
   1020       break;
   1021     case 'B':
   1022       if (startswith(Magic, "BC\xC0\xDE"))
   1023         return file_magic::bitcode;
   1024       break;
   1025     case '!':
   1026       if (startswith(Magic, "!<arch>\n") || startswith(Magic, "!<thin>\n"))
   1027         return file_magic::archive;
   1028       break;
   1029 
   1030     case '\177':
   1031       if (startswith(Magic, "\177ELF") && Magic.size() >= 18) {
   1032         bool Data2MSB = Magic[5] == 2;
   1033         unsigned high = Data2MSB ? 16 : 17;
   1034         unsigned low  = Data2MSB ? 17 : 16;
   1035         if (Magic[high] == 0) {
   1036           switch (Magic[low]) {
   1037             default: return file_magic::elf;
   1038             case 1: return file_magic::elf_relocatable;
   1039             case 2: return file_magic::elf_executable;
   1040             case 3: return file_magic::elf_shared_object;
   1041             case 4: return file_magic::elf_core;
   1042           }
   1043         }
   1044         // It's still some type of ELF file.
   1045         return file_magic::elf;
   1046       }
   1047       break;
   1048 
   1049     case 0xCA:
   1050       if (startswith(Magic, "\xCA\xFE\xBA\xBE") ||
   1051           startswith(Magic, "\xCA\xFE\xBA\xBF")) {
   1052         // This is complicated by an overlap with Java class files.
   1053         // See the Mach-O section in /usr/share/file/magic for details.
   1054         if (Magic.size() >= 8 && Magic[7] < 43)
   1055           return file_magic::macho_universal_binary;
   1056       }
   1057       break;
   1058 
   1059       // The two magic numbers for mach-o are:
   1060       // 0xfeedface - 32-bit mach-o
   1061       // 0xfeedfacf - 64-bit mach-o
   1062     case 0xFE:
   1063     case 0xCE:
   1064     case 0xCF: {
   1065       uint16_t type = 0;
   1066       if (startswith(Magic, "\xFE\xED\xFA\xCE") ||
   1067           startswith(Magic, "\xFE\xED\xFA\xCF")) {
   1068         /* Native endian */
   1069         size_t MinSize;
   1070         if (Magic[3] == char(0xCE))
   1071           MinSize = sizeof(MachO::mach_header);
   1072         else
   1073           MinSize = sizeof(MachO::mach_header_64);
   1074         if (Magic.size() >= MinSize)
   1075           type = Magic[12] << 24 | Magic[13] << 12 | Magic[14] << 8 | Magic[15];
   1076       } else if (startswith(Magic, "\xCE\xFA\xED\xFE") ||
   1077                  startswith(Magic, "\xCF\xFA\xED\xFE")) {
   1078         /* Reverse endian */
   1079         size_t MinSize;
   1080         if (Magic[0] == char(0xCE))
   1081           MinSize = sizeof(MachO::mach_header);
   1082         else
   1083           MinSize = sizeof(MachO::mach_header_64);
   1084         if (Magic.size() >= MinSize)
   1085           type = Magic[15] << 24 | Magic[14] << 12 |Magic[13] << 8 | Magic[12];
   1086       }
   1087       switch (type) {
   1088         default: break;
   1089         case 1: return file_magic::macho_object;
   1090         case 2: return file_magic::macho_executable;
   1091         case 3: return file_magic::macho_fixed_virtual_memory_shared_lib;
   1092         case 4: return file_magic::macho_core;
   1093         case 5: return file_magic::macho_preload_executable;
   1094         case 6: return file_magic::macho_dynamically_linked_shared_lib;
   1095         case 7: return file_magic::macho_dynamic_linker;
   1096         case 8: return file_magic::macho_bundle;
   1097         case 9: return file_magic::macho_dynamically_linked_shared_lib_stub;
   1098         case 10: return file_magic::macho_dsym_companion;
   1099         case 11: return file_magic::macho_kext_bundle;
   1100       }
   1101       break;
   1102     }
   1103     case 0xF0: // PowerPC Windows
   1104     case 0x83: // Alpha 32-bit
   1105     case 0x84: // Alpha 64-bit
   1106     case 0x66: // MPS R4000 Windows
   1107     case 0x50: // mc68K
   1108     case 0x4c: // 80386 Windows
   1109     case 0xc4: // ARMNT Windows
   1110       if (Magic[1] == 0x01)
   1111         return file_magic::coff_object;
   1112 
   1113     case 0x90: // PA-RISC Windows
   1114     case 0x68: // mc68K Windows
   1115       if (Magic[1] == 0x02)
   1116         return file_magic::coff_object;
   1117       break;
   1118 
   1119     case 'M': // Possible MS-DOS stub on Windows PE file
   1120       if (startswith(Magic, "MZ")) {
   1121         uint32_t off = read32le(Magic.data() + 0x3c);
   1122         // PE/COFF file, either EXE or DLL.
   1123         if (off < Magic.size() &&
   1124             memcmp(Magic.data()+off, COFF::PEMagic, sizeof(COFF::PEMagic)) == 0)
   1125           return file_magic::pecoff_executable;
   1126       }
   1127       break;
   1128 
   1129     case 0x64: // x86-64 Windows.
   1130       if (Magic[1] == char(0x86))
   1131         return file_magic::coff_object;
   1132       break;
   1133 
   1134     default:
   1135       break;
   1136   }
   1137   return file_magic::unknown;
   1138 }
   1139 
   1140 std::error_code identify_magic(const Twine &Path, file_magic &Result) {
   1141   int FD;
   1142   if (std::error_code EC = openFileForRead(Path, FD))
   1143     return EC;
   1144 
   1145   char Buffer[32];
   1146   int Length = read(FD, Buffer, sizeof(Buffer));
   1147   if (close(FD) != 0 || Length < 0)
   1148     return std::error_code(errno, std::generic_category());
   1149 
   1150   Result = identify_magic(StringRef(Buffer, Length));
   1151   return std::error_code();
   1152 }
   1153 
   1154 std::error_code directory_entry::status(file_status &result) const {
   1155   return fs::status(Path, result);
   1156 }
   1157 
   1158 } // end namespace fs
   1159 } // end namespace sys
   1160 } // end namespace llvm
   1161 
   1162 // Include the truly platform-specific parts.
   1163 #if defined(LLVM_ON_UNIX)
   1164 #include "Unix/Path.inc"
   1165 #endif
   1166 #if defined(LLVM_ON_WIN32)
   1167 #include "Windows/Path.inc"
   1168 #endif
   1169 
   1170 namespace llvm {
   1171 namespace sys {
   1172 namespace path {
   1173 
   1174 bool user_cache_directory(SmallVectorImpl<char> &Result, const Twine &Path1,
   1175                           const Twine &Path2, const Twine &Path3) {
   1176   if (getUserCacheDir(Result)) {
   1177     append(Result, Path1, Path2, Path3);
   1178     return true;
   1179   }
   1180   return false;
   1181 }
   1182 
   1183 } // end namespace path
   1184 } // end namsspace sys
   1185 } // end namespace llvm
   1186