LLVM  mainline
Path.cpp
Go to the documentation of this file.
00001 //===-- Path.cpp - Implement OS Path Concept ------------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements the operating system Path API.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/Support/COFF.h"
00015 #include "llvm/Support/Endian.h"
00016 #include "llvm/Support/Errc.h"
00017 #include "llvm/Support/ErrorHandling.h"
00018 #include "llvm/Support/FileSystem.h"
00019 #include "llvm/Support/Path.h"
00020 #include "llvm/Support/Process.h"
00021 #include <cctype>
00022 #include <cstring>
00023 
00024 #if !defined(_MSC_VER) && !defined(__MINGW32__)
00025 #include <unistd.h>
00026 #else
00027 #include <io.h>
00028 #endif
00029 
00030 using namespace llvm;
00031 using namespace llvm::support::endian;
00032 
00033 namespace {
00034   using llvm::StringRef;
00035   using llvm::sys::path::is_separator;
00036 
00037 #ifdef LLVM_ON_WIN32
00038   const char *separators = "\\/";
00039   const char preferred_separator = '\\';
00040 #else
00041   const char  separators = '/';
00042   const char preferred_separator = '/';
00043 #endif
00044 
00045   StringRef find_first_component(StringRef path) {
00046     // Look for this first component in the following order.
00047     // * empty (in this case we return an empty string)
00048     // * either C: or {//,\\}net.
00049     // * {/,\}
00050     // * {file,directory}name
00051 
00052     if (path.empty())
00053       return path;
00054 
00055 #ifdef LLVM_ON_WIN32
00056     // C:
00057     if (path.size() >= 2 && std::isalpha(static_cast<unsigned char>(path[0])) &&
00058         path[1] == ':')
00059       return path.substr(0, 2);
00060 #endif
00061 
00062     // //net
00063     if ((path.size() > 2) &&
00064         is_separator(path[0]) &&
00065         path[0] == path[1] &&
00066         !is_separator(path[2])) {
00067       // Find the next directory separator.
00068       size_t end = path.find_first_of(separators, 2);
00069       return path.substr(0, end);
00070     }
00071 
00072     // {/,\}
00073     if (is_separator(path[0]))
00074       return path.substr(0, 1);
00075 
00076     // * {file,directory}name
00077     size_t end = path.find_first_of(separators);
00078     return path.substr(0, end);
00079   }
00080 
00081   size_t filename_pos(StringRef str) {
00082     if (str.size() == 2 &&
00083         is_separator(str[0]) &&
00084         str[0] == str[1])
00085       return 0;
00086 
00087     if (str.size() > 0 && is_separator(str[str.size() - 1]))
00088       return str.size() - 1;
00089 
00090     size_t pos = str.find_last_of(separators, str.size() - 1);
00091 
00092 #ifdef LLVM_ON_WIN32
00093     if (pos == StringRef::npos)
00094       pos = str.find_last_of(':', str.size() - 2);
00095 #endif
00096 
00097     if (pos == StringRef::npos ||
00098         (pos == 1 && is_separator(str[0])))
00099       return 0;
00100 
00101     return pos + 1;
00102   }
00103 
00104   size_t root_dir_start(StringRef str) {
00105     // case "c:/"
00106 #ifdef LLVM_ON_WIN32
00107     if (str.size() > 2 &&
00108         str[1] == ':' &&
00109         is_separator(str[2]))
00110       return 2;
00111 #endif
00112 
00113     // case "//"
00114     if (str.size() == 2 &&
00115         is_separator(str[0]) &&
00116         str[0] == str[1])
00117       return StringRef::npos;
00118 
00119     // case "//net"
00120     if (str.size() > 3 &&
00121         is_separator(str[0]) &&
00122         str[0] == str[1] &&
00123         !is_separator(str[2])) {
00124       return str.find_first_of(separators, 2);
00125     }
00126 
00127     // case "/"
00128     if (str.size() > 0 && is_separator(str[0]))
00129       return 0;
00130 
00131     return StringRef::npos;
00132   }
00133 
00134   size_t parent_path_end(StringRef path) {
00135     size_t end_pos = filename_pos(path);
00136 
00137     bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
00138 
00139     // Skip separators except for root dir.
00140     size_t root_dir_pos = root_dir_start(path.substr(0, end_pos));
00141 
00142     while(end_pos > 0 &&
00143           (end_pos - 1) != root_dir_pos &&
00144           is_separator(path[end_pos - 1]))
00145       --end_pos;
00146 
00147     if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
00148       return StringRef::npos;
00149 
00150     return end_pos;
00151   }
00152 } // end unnamed namespace
00153 
00154 enum FSEntity {
00155   FS_Dir,
00156   FS_File,
00157   FS_Name
00158 };
00159 
00160 static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD,
00161                                           SmallVectorImpl<char> &ResultPath,
00162                                           bool MakeAbsolute, unsigned Mode,
00163                                           FSEntity Type) {
00164   SmallString<128> ModelStorage;
00165   Model.toVector(ModelStorage);
00166 
00167   if (MakeAbsolute) {
00168     // Make model absolute by prepending a temp directory if it's not already.
00169     if (!sys::path::is_absolute(Twine(ModelStorage))) {
00170       SmallString<128> TDir;
00171       sys::path::system_temp_directory(true, TDir);
00172       sys::path::append(TDir, Twine(ModelStorage));
00173       ModelStorage.swap(TDir);
00174     }
00175   }
00176 
00177   // From here on, DO NOT modify model. It may be needed if the randomly chosen
00178   // path already exists.
00179   ResultPath = ModelStorage;
00180   // Null terminate.
00181   ResultPath.push_back(0);
00182   ResultPath.pop_back();
00183 
00184 retry_random_path:
00185   // Replace '%' with random chars.
00186   for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
00187     if (ModelStorage[i] == '%')
00188       ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
00189   }
00190 
00191   // Try to open + create the file.
00192   switch (Type) {
00193   case FS_File: {
00194     if (std::error_code EC =
00195             sys::fs::openFileForWrite(Twine(ResultPath.begin()), ResultFD,
00196                                       sys::fs::F_RW | sys::fs::F_Excl, Mode)) {
00197       if (EC == errc::file_exists)
00198         goto retry_random_path;
00199       return EC;
00200     }
00201 
00202     return std::error_code();
00203   }
00204 
00205   case FS_Name: {
00206     std::error_code EC =
00207         sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist);
00208     if (EC == errc::no_such_file_or_directory)
00209       return std::error_code();
00210     if (EC)
00211       return EC;
00212     goto retry_random_path;
00213   }
00214 
00215   case FS_Dir: {
00216     if (std::error_code EC =
00217             sys::fs::create_directory(ResultPath.begin(), false)) {
00218       if (EC == errc::file_exists)
00219         goto retry_random_path;
00220       return EC;
00221     }
00222     return std::error_code();
00223   }
00224   }
00225   llvm_unreachable("Invalid Type");
00226 }
00227 
00228 namespace llvm {
00229 namespace sys  {
00230 namespace path {
00231 
00232 const_iterator begin(StringRef path) {
00233   const_iterator i;
00234   i.Path      = path;
00235   i.Component = find_first_component(path);
00236   i.Position  = 0;
00237   return i;
00238 }
00239 
00240 const_iterator end(StringRef path) {
00241   const_iterator i;
00242   i.Path      = path;
00243   i.Position  = path.size();
00244   return i;
00245 }
00246 
00247 const_iterator &const_iterator::operator++() {
00248   assert(Position < Path.size() && "Tried to increment past end!");
00249 
00250   // Increment Position to past the current component
00251   Position += Component.size();
00252 
00253   // Check for end.
00254   if (Position == Path.size()) {
00255     Component = StringRef();
00256     return *this;
00257   }
00258 
00259   // Both POSIX and Windows treat paths that begin with exactly two separators
00260   // specially.
00261   bool was_net = Component.size() > 2 &&
00262     is_separator(Component[0]) &&
00263     Component[1] == Component[0] &&
00264     !is_separator(Component[2]);
00265 
00266   // Handle separators.
00267   if (is_separator(Path[Position])) {
00268     // Root dir.
00269     if (was_net
00270 #ifdef LLVM_ON_WIN32
00271         // c:/
00272         || Component.endswith(":")
00273 #endif
00274         ) {
00275       Component = Path.substr(Position, 1);
00276       return *this;
00277     }
00278 
00279     // Skip extra separators.
00280     while (Position != Path.size() &&
00281            is_separator(Path[Position])) {
00282       ++Position;
00283     }
00284 
00285     // Treat trailing '/' as a '.'.
00286     if (Position == Path.size()) {
00287       --Position;
00288       Component = ".";
00289       return *this;
00290     }
00291   }
00292 
00293   // Find next component.
00294   size_t end_pos = Path.find_first_of(separators, Position);
00295   Component = Path.slice(Position, end_pos);
00296 
00297   return *this;
00298 }
00299 
00300 bool const_iterator::operator==(const const_iterator &RHS) const {
00301   return Path.begin() == RHS.Path.begin() && Position == RHS.Position;
00302 }
00303 
00304 ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
00305   return Position - RHS.Position;
00306 }
00307 
00308 reverse_iterator rbegin(StringRef Path) {
00309   reverse_iterator I;
00310   I.Path = Path;
00311   I.Position = Path.size();
00312   return ++I;
00313 }
00314 
00315 reverse_iterator rend(StringRef Path) {
00316   reverse_iterator I;
00317   I.Path = Path;
00318   I.Component = Path.substr(0, 0);
00319   I.Position = 0;
00320   return I;
00321 }
00322 
00323 reverse_iterator &reverse_iterator::operator++() {
00324   // If we're at the end and the previous char was a '/', return '.' unless
00325   // we are the root path.
00326   size_t root_dir_pos = root_dir_start(Path);
00327   if (Position == Path.size() &&
00328       Path.size() > root_dir_pos + 1 &&
00329       is_separator(Path[Position - 1])) {
00330     --Position;
00331     Component = ".";
00332     return *this;
00333   }
00334 
00335   // Skip separators unless it's the root directory.
00336   size_t end_pos = Position;
00337 
00338   while(end_pos > 0 &&
00339         (end_pos - 1) != root_dir_pos &&
00340         is_separator(Path[end_pos - 1]))
00341     --end_pos;
00342 
00343   // Find next separator.
00344   size_t start_pos = filename_pos(Path.substr(0, end_pos));
00345   Component = Path.slice(start_pos, end_pos);
00346   Position = start_pos;
00347   return *this;
00348 }
00349 
00350 bool reverse_iterator::operator==(const reverse_iterator &RHS) const {
00351   return Path.begin() == RHS.Path.begin() && Component == RHS.Component &&
00352          Position == RHS.Position;
00353 }
00354 
00355 StringRef root_path(StringRef path) {
00356   const_iterator b = begin(path),
00357                  pos = b,
00358                  e = end(path);
00359   if (b != e) {
00360     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
00361     bool has_drive =
00362 #ifdef LLVM_ON_WIN32
00363       b->endswith(":");
00364 #else
00365       false;
00366 #endif
00367 
00368     if (has_net || has_drive) {
00369       if ((++pos != e) && is_separator((*pos)[0])) {
00370         // {C:/,//net/}, so get the first two components.
00371         return path.substr(0, b->size() + pos->size());
00372       } else {
00373         // just {C:,//net}, return the first component.
00374         return *b;
00375       }
00376     }
00377 
00378     // POSIX style root directory.
00379     if (is_separator((*b)[0])) {
00380       return *b;
00381     }
00382   }
00383 
00384   return StringRef();
00385 }
00386 
00387 StringRef root_name(StringRef path) {
00388   const_iterator b = begin(path),
00389                  e = end(path);
00390   if (b != e) {
00391     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
00392     bool has_drive =
00393 #ifdef LLVM_ON_WIN32
00394       b->endswith(":");
00395 #else
00396       false;
00397 #endif
00398 
00399     if (has_net || has_drive) {
00400       // just {C:,//net}, return the first component.
00401       return *b;
00402     }
00403   }
00404 
00405   // No path or no name.
00406   return StringRef();
00407 }
00408 
00409 StringRef root_directory(StringRef path) {
00410   const_iterator b = begin(path),
00411                  pos = b,
00412                  e = end(path);
00413   if (b != e) {
00414     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
00415     bool has_drive =
00416 #ifdef LLVM_ON_WIN32
00417       b->endswith(":");
00418 #else
00419       false;
00420 #endif
00421 
00422     if ((has_net || has_drive) &&
00423         // {C:,//net}, skip to the next component.
00424         (++pos != e) && is_separator((*pos)[0])) {
00425       return *pos;
00426     }
00427 
00428     // POSIX style root directory.
00429     if (!has_net && is_separator((*b)[0])) {
00430       return *b;
00431     }
00432   }
00433 
00434   // No path or no root.
00435   return StringRef();
00436 }
00437 
00438 StringRef relative_path(StringRef path) {
00439   StringRef root = root_path(path);
00440   return path.substr(root.size());
00441 }
00442 
00443 void append(SmallVectorImpl<char> &path, const Twine &a,
00444                                          const Twine &b,
00445                                          const Twine &c,
00446                                          const Twine &d) {
00447   SmallString<32> a_storage;
00448   SmallString<32> b_storage;
00449   SmallString<32> c_storage;
00450   SmallString<32> d_storage;
00451 
00452   SmallVector<StringRef, 4> components;
00453   if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
00454   if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
00455   if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
00456   if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
00457 
00458   for (auto &component : components) {
00459     bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
00460     bool component_has_sep = !component.empty() && is_separator(component[0]);
00461     bool is_root_name = has_root_name(component);
00462 
00463     if (path_has_sep) {
00464       // Strip separators from beginning of component.
00465       size_t loc = component.find_first_not_of(separators);
00466       StringRef c = component.substr(loc);
00467 
00468       // Append it.
00469       path.append(c.begin(), c.end());
00470       continue;
00471     }
00472 
00473     if (!component_has_sep && !(path.empty() || is_root_name)) {
00474       // Add a separator.
00475       path.push_back(preferred_separator);
00476     }
00477 
00478     path.append(component.begin(), component.end());
00479   }
00480 }
00481 
00482 void append(SmallVectorImpl<char> &path,
00483             const_iterator begin, const_iterator end) {
00484   for (; begin != end; ++begin)
00485     path::append(path, *begin);
00486 }
00487 
00488 StringRef parent_path(StringRef path) {
00489   size_t end_pos = parent_path_end(path);
00490   if (end_pos == StringRef::npos)
00491     return StringRef();
00492   else
00493     return path.substr(0, end_pos);
00494 }
00495 
00496 void remove_filename(SmallVectorImpl<char> &path) {
00497   size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
00498   if (end_pos != StringRef::npos)
00499     path.set_size(end_pos);
00500 }
00501 
00502 void replace_extension(SmallVectorImpl<char> &path, const Twine &extension) {
00503   StringRef p(path.begin(), path.size());
00504   SmallString<32> ext_storage;
00505   StringRef ext = extension.toStringRef(ext_storage);
00506 
00507   // Erase existing extension.
00508   size_t pos = p.find_last_of('.');
00509   if (pos != StringRef::npos && pos >= filename_pos(p))
00510     path.set_size(pos);
00511 
00512   // Append '.' if needed.
00513   if (ext.size() > 0 && ext[0] != '.')
00514     path.push_back('.');
00515 
00516   // Append extension.
00517   path.append(ext.begin(), ext.end());
00518 }
00519 
00520 void native(const Twine &path, SmallVectorImpl<char> &result) {
00521   assert((!path.isSingleStringRef() ||
00522           path.getSingleStringRef().data() != result.data()) &&
00523          "path and result are not allowed to overlap!");
00524   // Clear result.
00525   result.clear();
00526   path.toVector(result);
00527   native(result);
00528 }
00529 
00530 void native(SmallVectorImpl<char> &Path) {
00531 #ifdef LLVM_ON_WIN32
00532   std::replace(Path.begin(), Path.end(), '/', '\\');
00533 #else
00534   for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
00535     if (*PI == '\\') {
00536       auto PN = PI + 1;
00537       if (PN < PE && *PN == '\\')
00538         ++PI; // increment once, the for loop will move over the escaped slash
00539       else
00540         *PI = '/';
00541     }
00542   }
00543 #endif
00544 }
00545 
00546 StringRef filename(StringRef path) {
00547   return *rbegin(path);
00548 }
00549 
00550 StringRef stem(StringRef path) {
00551   StringRef fname = filename(path);
00552   size_t pos = fname.find_last_of('.');
00553   if (pos == StringRef::npos)
00554     return fname;
00555   else
00556     if ((fname.size() == 1 && fname == ".") ||
00557         (fname.size() == 2 && fname == ".."))
00558       return fname;
00559     else
00560       return fname.substr(0, pos);
00561 }
00562 
00563 StringRef extension(StringRef path) {
00564   StringRef fname = filename(path);
00565   size_t pos = fname.find_last_of('.');
00566   if (pos == StringRef::npos)
00567     return StringRef();
00568   else
00569     if ((fname.size() == 1 && fname == ".") ||
00570         (fname.size() == 2 && fname == ".."))
00571       return StringRef();
00572     else
00573       return fname.substr(pos);
00574 }
00575 
00576 bool is_separator(char value) {
00577   switch(value) {
00578 #ifdef LLVM_ON_WIN32
00579     case '\\': // fall through
00580 #endif
00581     case '/': return true;
00582     default: return false;
00583   }
00584 }
00585 
00586 static const char preferred_separator_string[] = { preferred_separator, '\0' };
00587 
00588 StringRef get_separator() {
00589   return preferred_separator_string;
00590 }
00591 
00592 bool has_root_name(const Twine &path) {
00593   SmallString<128> path_storage;
00594   StringRef p = path.toStringRef(path_storage);
00595 
00596   return !root_name(p).empty();
00597 }
00598 
00599 bool has_root_directory(const Twine &path) {
00600   SmallString<128> path_storage;
00601   StringRef p = path.toStringRef(path_storage);
00602 
00603   return !root_directory(p).empty();
00604 }
00605 
00606 bool has_root_path(const Twine &path) {
00607   SmallString<128> path_storage;
00608   StringRef p = path.toStringRef(path_storage);
00609 
00610   return !root_path(p).empty();
00611 }
00612 
00613 bool has_relative_path(const Twine &path) {
00614   SmallString<128> path_storage;
00615   StringRef p = path.toStringRef(path_storage);
00616 
00617   return !relative_path(p).empty();
00618 }
00619 
00620 bool has_filename(const Twine &path) {
00621   SmallString<128> path_storage;
00622   StringRef p = path.toStringRef(path_storage);
00623 
00624   return !filename(p).empty();
00625 }
00626 
00627 bool has_parent_path(const Twine &path) {
00628   SmallString<128> path_storage;
00629   StringRef p = path.toStringRef(path_storage);
00630 
00631   return !parent_path(p).empty();
00632 }
00633 
00634 bool has_stem(const Twine &path) {
00635   SmallString<128> path_storage;
00636   StringRef p = path.toStringRef(path_storage);
00637 
00638   return !stem(p).empty();
00639 }
00640 
00641 bool has_extension(const Twine &path) {
00642   SmallString<128> path_storage;
00643   StringRef p = path.toStringRef(path_storage);
00644 
00645   return !extension(p).empty();
00646 }
00647 
00648 bool is_absolute(const Twine &path) {
00649   SmallString<128> path_storage;
00650   StringRef p = path.toStringRef(path_storage);
00651 
00652   bool rootDir = has_root_directory(p),
00653 #ifdef LLVM_ON_WIN32
00654        rootName = has_root_name(p);
00655 #else
00656        rootName = true;
00657 #endif
00658 
00659   return rootDir && rootName;
00660 }
00661 
00662 bool is_relative(const Twine &path) { return !is_absolute(path); }
00663 
00664 StringRef remove_leading_dotslash(StringRef Path) {
00665   // Remove leading "./" (or ".//" or "././" etc.)
00666   while (Path.size() > 2 && Path[0] == '.' && is_separator(Path[1])) {
00667     Path = Path.substr(2);
00668     while (Path.size() > 0 && is_separator(Path[0]))
00669       Path = Path.substr(1);
00670   }
00671   return Path;
00672 }
00673 
00674 static SmallString<256> remove_dots(StringRef path, bool remove_dot_dot) {
00675   SmallVector<StringRef, 16> components;
00676 
00677   // Skip the root path, then look for traversal in the components.
00678   StringRef rel = path::relative_path(path);
00679   for (StringRef C : llvm::make_range(path::begin(rel), path::end(rel))) {
00680     if (C == ".")
00681       continue;
00682     if (remove_dot_dot) {
00683       if (C == "..") {
00684         if (!components.empty())
00685           components.pop_back();
00686         continue;
00687       }
00688     }
00689     components.push_back(C);
00690   }
00691 
00692   SmallString<256> buffer = path::root_path(path);
00693   for (StringRef C : components)
00694     path::append(buffer, C);
00695   return buffer;
00696 }
00697 
00698 bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot) {
00699   StringRef p(path.data(), path.size());
00700 
00701   SmallString<256> result = remove_dots(p, remove_dot_dot);
00702   if (result == path)
00703     return false;
00704 
00705   path.swap(result);
00706   return true;
00707 }
00708 
00709 } // end namespace path
00710 
00711 namespace fs {
00712 
00713 std::error_code getUniqueID(const Twine Path, UniqueID &Result) {
00714   file_status Status;
00715   std::error_code EC = status(Path, Status);
00716   if (EC)
00717     return EC;
00718   Result = Status.getUniqueID();
00719   return std::error_code();
00720 }
00721 
00722 std::error_code createUniqueFile(const Twine &Model, int &ResultFd,
00723                                  SmallVectorImpl<char> &ResultPath,
00724                                  unsigned Mode) {
00725   return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
00726 }
00727 
00728 std::error_code createUniqueFile(const Twine &Model,
00729                                  SmallVectorImpl<char> &ResultPath) {
00730   int Dummy;
00731   return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
00732 }
00733 
00734 static std::error_code
00735 createTemporaryFile(const Twine &Model, int &ResultFD,
00736                     llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
00737   SmallString<128> Storage;
00738   StringRef P = Model.toNullTerminatedStringRef(Storage);
00739   assert(P.find_first_of(separators) == StringRef::npos &&
00740          "Model must be a simple filename.");
00741   // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
00742   return createUniqueEntity(P.begin(), ResultFD, ResultPath,
00743                             true, owner_read | owner_write, Type);
00744 }
00745 
00746 static std::error_code
00747 createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
00748                     llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
00749   const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
00750   return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
00751                              Type);
00752 }
00753 
00754 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
00755                                     int &ResultFD,
00756                                     SmallVectorImpl<char> &ResultPath) {
00757   return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
00758 }
00759 
00760 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
00761                                     SmallVectorImpl<char> &ResultPath) {
00762   int Dummy;
00763   return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
00764 }
00765 
00766 
00767 // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
00768 // for consistency. We should try using mkdtemp.
00769 std::error_code createUniqueDirectory(const Twine &Prefix,
00770                                       SmallVectorImpl<char> &ResultPath) {
00771   int Dummy;
00772   return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
00773                             true, 0, FS_Dir);
00774 }
00775 
00776 static std::error_code make_absolute(const Twine &current_directory,
00777                                      SmallVectorImpl<char> &path,
00778                                      bool use_current_directory) {
00779   StringRef p(path.data(), path.size());
00780 
00781   bool rootDirectory = path::has_root_directory(p),
00782 #ifdef LLVM_ON_WIN32
00783        rootName = path::has_root_name(p);
00784 #else
00785        rootName = true;
00786 #endif
00787 
00788   // Already absolute.
00789   if (rootName && rootDirectory)
00790     return std::error_code();
00791 
00792   // All of the following conditions will need the current directory.
00793   SmallString<128> current_dir;
00794   if (use_current_directory)
00795     current_directory.toVector(current_dir);
00796   else if (std::error_code ec = current_path(current_dir))
00797     return ec;
00798 
00799   // Relative path. Prepend the current directory.
00800   if (!rootName && !rootDirectory) {
00801     // Append path to the current directory.
00802     path::append(current_dir, p);
00803     // Set path to the result.
00804     path.swap(current_dir);
00805     return std::error_code();
00806   }
00807 
00808   if (!rootName && rootDirectory) {
00809     StringRef cdrn = path::root_name(current_dir);
00810     SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
00811     path::append(curDirRootName, p);
00812     // Set path to the result.
00813     path.swap(curDirRootName);
00814     return std::error_code();
00815   }
00816 
00817   if (rootName && !rootDirectory) {
00818     StringRef pRootName      = path::root_name(p);
00819     StringRef bRootDirectory = path::root_directory(current_dir);
00820     StringRef bRelativePath  = path::relative_path(current_dir);
00821     StringRef pRelativePath  = path::relative_path(p);
00822 
00823     SmallString<128> res;
00824     path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
00825     path.swap(res);
00826     return std::error_code();
00827   }
00828 
00829   llvm_unreachable("All rootName and rootDirectory combinations should have "
00830                    "occurred above!");
00831 }
00832 
00833 std::error_code make_absolute(const Twine &current_directory,
00834                               SmallVectorImpl<char> &path) {
00835   return make_absolute(current_directory, path, true);
00836 }
00837 
00838 std::error_code make_absolute(SmallVectorImpl<char> &path) {
00839   return make_absolute(Twine(), path, false);
00840 }
00841 
00842 std::error_code create_directories(const Twine &Path, bool IgnoreExisting,
00843                                    perms Perms) {
00844   SmallString<128> PathStorage;
00845   StringRef P = Path.toStringRef(PathStorage);
00846 
00847   // Be optimistic and try to create the directory
00848   std::error_code EC = create_directory(P, IgnoreExisting, Perms);
00849   // If we succeeded, or had any error other than the parent not existing, just
00850   // return it.
00851   if (EC != errc::no_such_file_or_directory)
00852     return EC;
00853 
00854   // We failed because of a no_such_file_or_directory, try to create the
00855   // parent.
00856   StringRef Parent = path::parent_path(P);
00857   if (Parent.empty())
00858     return EC;
00859 
00860   if ((EC = create_directories(Parent, IgnoreExisting, Perms)))
00861       return EC;
00862 
00863   return create_directory(P, IgnoreExisting, Perms);
00864 }
00865 
00866 std::error_code copy_file(const Twine &From, const Twine &To) {
00867   int ReadFD, WriteFD;
00868   if (std::error_code EC = openFileForRead(From, ReadFD))
00869     return EC;
00870   if (std::error_code EC = openFileForWrite(To, WriteFD, F_None)) {
00871     close(ReadFD);
00872     return EC;
00873   }
00874 
00875   const size_t BufSize = 4096;
00876   char *Buf = new char[BufSize];
00877   int BytesRead = 0, BytesWritten = 0;
00878   for (;;) {
00879     BytesRead = read(ReadFD, Buf, BufSize);
00880     if (BytesRead <= 0)
00881       break;
00882     while (BytesRead) {
00883       BytesWritten = write(WriteFD, Buf, BytesRead);
00884       if (BytesWritten < 0)
00885         break;
00886       BytesRead -= BytesWritten;
00887     }
00888     if (BytesWritten < 0)
00889       break;
00890   }
00891   close(ReadFD);
00892   close(WriteFD);
00893   delete[] Buf;
00894 
00895   if (BytesRead < 0 || BytesWritten < 0)
00896     return std::error_code(errno, std::generic_category());
00897   return std::error_code();
00898 }
00899 
00900 bool exists(file_status status) {
00901   return status_known(status) && status.type() != file_type::file_not_found;
00902 }
00903 
00904 bool status_known(file_status s) {
00905   return s.type() != file_type::status_error;
00906 }
00907 
00908 bool is_directory(file_status status) {
00909   return status.type() == file_type::directory_file;
00910 }
00911 
00912 std::error_code is_directory(const Twine &path, bool &result) {
00913   file_status st;
00914   if (std::error_code ec = status(path, st))
00915     return ec;
00916   result = is_directory(st);
00917   return std::error_code();
00918 }
00919 
00920 bool is_regular_file(file_status status) {
00921   return status.type() == file_type::regular_file;
00922 }
00923 
00924 std::error_code is_regular_file(const Twine &path, bool &result) {
00925   file_status st;
00926   if (std::error_code ec = status(path, st))
00927     return ec;
00928   result = is_regular_file(st);
00929   return std::error_code();
00930 }
00931 
00932 bool is_other(file_status status) {
00933   return exists(status) &&
00934          !is_regular_file(status) &&
00935          !is_directory(status);
00936 }
00937 
00938 std::error_code is_other(const Twine &Path, bool &Result) {
00939   file_status FileStatus;
00940   if (std::error_code EC = status(Path, FileStatus))
00941     return EC;
00942   Result = is_other(FileStatus);
00943   return std::error_code();
00944 }
00945 
00946 void directory_entry::replace_filename(const Twine &filename, file_status st) {
00947   SmallString<128> path = path::parent_path(Path);
00948   path::append(path, filename);
00949   Path = path.str();
00950   Status = st;
00951 }
00952 
00953 /// @brief Identify the magic in magic.
00954 file_magic identify_magic(StringRef Magic) {
00955   if (Magic.size() < 4)
00956     return file_magic::unknown;
00957   switch ((unsigned char)Magic[0]) {
00958     case 0x00: {
00959       // COFF bigobj or short import library file
00960       if (Magic[1] == (char)0x00 && Magic[2] == (char)0xff &&
00961           Magic[3] == (char)0xff) {
00962         size_t MinSize = offsetof(COFF::BigObjHeader, UUID) + sizeof(COFF::BigObjMagic);
00963         if (Magic.size() < MinSize)
00964           return file_magic::coff_import_library;
00965 
00966         int BigObjVersion = read16le(
00967             Magic.data() + offsetof(COFF::BigObjHeader, Version));
00968         if (BigObjVersion < COFF::BigObjHeader::MinBigObjectVersion)
00969           return file_magic::coff_import_library;
00970 
00971         const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID);
00972         if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) != 0)
00973           return file_magic::coff_import_library;
00974         return file_magic::coff_object;
00975       }
00976       // Windows resource file
00977       const char Expected[] = { 0, 0, 0, 0, '\x20', 0, 0, 0, '\xff' };
00978       if (Magic.size() >= sizeof(Expected) &&
00979           memcmp(Magic.data(), Expected, sizeof(Expected)) == 0)
00980         return file_magic::windows_resource;
00981       // 0x0000 = COFF unknown machine type
00982       if (Magic[1] == 0)
00983         return file_magic::coff_object;
00984       break;
00985     }
00986     case 0xDE:  // 0x0B17C0DE = BC wraper
00987       if (Magic[1] == (char)0xC0 && Magic[2] == (char)0x17 &&
00988           Magic[3] == (char)0x0B)
00989         return file_magic::bitcode;
00990       break;
00991     case 'B':
00992       if (Magic[1] == 'C' && Magic[2] == (char)0xC0 && Magic[3] == (char)0xDE)
00993         return file_magic::bitcode;
00994       break;
00995     case '!':
00996       if (Magic.size() >= 8)
00997         if (memcmp(Magic.data(), "!<arch>\n", 8) == 0 ||
00998             memcmp(Magic.data(), "!<thin>\n", 8) == 0)
00999           return file_magic::archive;
01000       break;
01001 
01002     case '\177':
01003       if (Magic.size() >= 18 && Magic[1] == 'E' && Magic[2] == 'L' &&
01004           Magic[3] == 'F') {
01005         bool Data2MSB = Magic[5] == 2;
01006         unsigned high = Data2MSB ? 16 : 17;
01007         unsigned low  = Data2MSB ? 17 : 16;
01008         if (Magic[high] == 0)
01009           switch (Magic[low]) {
01010             default: return file_magic::elf;
01011             case 1: return file_magic::elf_relocatable;
01012             case 2: return file_magic::elf_executable;
01013             case 3: return file_magic::elf_shared_object;
01014             case 4: return file_magic::elf_core;
01015           }
01016         else
01017           // It's still some type of ELF file.
01018           return file_magic::elf;
01019       }
01020       break;
01021 
01022     case 0xCA:
01023       if (Magic[1] == char(0xFE) && Magic[2] == char(0xBA) &&
01024           Magic[3] == char(0xBE)) {
01025         // This is complicated by an overlap with Java class files.
01026         // See the Mach-O section in /usr/share/file/magic for details.
01027         if (Magic.size() >= 8 && Magic[7] < 43)
01028           return file_magic::macho_universal_binary;
01029       }
01030       break;
01031 
01032       // The two magic numbers for mach-o are:
01033       // 0xfeedface - 32-bit mach-o
01034       // 0xfeedfacf - 64-bit mach-o
01035     case 0xFE:
01036     case 0xCE:
01037     case 0xCF: {
01038       uint16_t type = 0;
01039       if (Magic[0] == char(0xFE) && Magic[1] == char(0xED) &&
01040           Magic[2] == char(0xFA) &&
01041           (Magic[3] == char(0xCE) || Magic[3] == char(0xCF))) {
01042         /* Native endian */
01043         if (Magic.size() >= 16) type = Magic[14] << 8 | Magic[15];
01044       } else if ((Magic[0] == char(0xCE) || Magic[0] == char(0xCF)) &&
01045                  Magic[1] == char(0xFA) && Magic[2] == char(0xED) &&
01046                  Magic[3] == char(0xFE)) {
01047         /* Reverse endian */
01048         if (Magic.size() >= 14) type = Magic[13] << 8 | Magic[12];
01049       }
01050       switch (type) {
01051         default: break;
01052         case 1: return file_magic::macho_object;
01053         case 2: return file_magic::macho_executable;
01054         case 3: return file_magic::macho_fixed_virtual_memory_shared_lib;
01055         case 4: return file_magic::macho_core;
01056         case 5: return file_magic::macho_preload_executable;
01057         case 6: return file_magic::macho_dynamically_linked_shared_lib;
01058         case 7: return file_magic::macho_dynamic_linker;
01059         case 8: return file_magic::macho_bundle;
01060         case 9: return file_magic::macho_dynamically_linked_shared_lib_stub;
01061         case 10: return file_magic::macho_dsym_companion;
01062         case 11: return file_magic::macho_kext_bundle;
01063       }
01064       break;
01065     }
01066     case 0xF0: // PowerPC Windows
01067     case 0x83: // Alpha 32-bit
01068     case 0x84: // Alpha 64-bit
01069     case 0x66: // MPS R4000 Windows
01070     case 0x50: // mc68K
01071     case 0x4c: // 80386 Windows
01072     case 0xc4: // ARMNT Windows
01073       if (Magic[1] == 0x01)
01074         return file_magic::coff_object;
01075 
01076     case 0x90: // PA-RISC Windows
01077     case 0x68: // mc68K Windows
01078       if (Magic[1] == 0x02)
01079         return file_magic::coff_object;
01080       break;
01081 
01082     case 'M': // Possible MS-DOS stub on Windows PE file
01083       if (Magic[1] == 'Z') {
01084         uint32_t off = read32le(Magic.data() + 0x3c);
01085         // PE/COFF file, either EXE or DLL.
01086         if (off < Magic.size() &&
01087             memcmp(Magic.data()+off, COFF::PEMagic, sizeof(COFF::PEMagic)) == 0)
01088           return file_magic::pecoff_executable;
01089       }
01090       break;
01091 
01092     case 0x64: // x86-64 Windows.
01093       if (Magic[1] == char(0x86))
01094         return file_magic::coff_object;
01095       break;
01096 
01097     default:
01098       break;
01099   }
01100   return file_magic::unknown;
01101 }
01102 
01103 std::error_code identify_magic(const Twine &Path, file_magic &Result) {
01104   int FD;
01105   if (std::error_code EC = openFileForRead(Path, FD))
01106     return EC;
01107 
01108   char Buffer[32];
01109   int Length = read(FD, Buffer, sizeof(Buffer));
01110   if (close(FD) != 0 || Length < 0)
01111     return std::error_code(errno, std::generic_category());
01112 
01113   Result = identify_magic(StringRef(Buffer, Length));
01114   return std::error_code();
01115 }
01116 
01117 std::error_code directory_entry::status(file_status &result) const {
01118   return fs::status(Path, result);
01119 }
01120 
01121 } // end namespace fs
01122 } // end namespace sys
01123 } // end namespace llvm
01124 
01125 // Include the truly platform-specific parts.
01126 #if defined(LLVM_ON_UNIX)
01127 #include "Unix/Path.inc"
01128 #endif
01129 #if defined(LLVM_ON_WIN32)
01130 #include "Windows/Path.inc"
01131 #endif
01132 
01133 namespace llvm {
01134 namespace sys {
01135 namespace path {
01136 
01137 bool user_cache_directory(SmallVectorImpl<char> &Result, const Twine &Path1,
01138                           const Twine &Path2, const Twine &Path3) {
01139   if (getUserCacheDir(Result)) {
01140     append(Result, Path1, Path2, Path3);
01141     return true;
01142   }
01143   return false;
01144 }
01145 
01146 } // end namespace path
01147 } // end namsspace sys
01148 } // end namespace llvm