Misc cleanups to the FileSytem api.
[oota-llvm.git] / include / llvm / Support / FileSystem.h
index dbf8f9928bef7d21a70f41e0ee85d2c5ba588b47..87fc4875bd5c4c1c1cd92857556b90bd1a67350c 100644 (file)
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TimeValue.h"
-#include "llvm/Support/system_error.h"
 #include <ctime>
 #include <iterator>
 #include <stack>
 #include <string>
+#include <system_error>
 #include <tuple>
 #include <vector>
 
@@ -134,7 +134,7 @@ public:
 };
 
 /// file_status - Represents the result of a call to stat and friends. It has
-///               a platform specific member to store the result.
+///               a platform-specific member to store the result.
 class file_status
 {
   #if defined(LLVM_ON_UNIX)
@@ -273,16 +273,8 @@ private:
 ///
 /// @param path A path that is modified to be an absolute path.
 /// @returns errc::success if \a path has been made absolute, otherwise a
-///          platform specific error_code.
-error_code make_absolute(SmallVectorImpl<char> &path);
-
-/// @brief Normalize path separators in \a Path
-///
-/// If the path contains any '\' separators, they are transformed into '/'.
-/// This is particularly useful when cross-compiling Windows on Linux, but is
-/// safe to invoke on Windows, which accepts both characters as a path
-/// separator.
-error_code normalize_separators(SmallVectorImpl<char> &Path);
+///          platform-specific error_code.
+std::error_code make_absolute(SmallVectorImpl<char> &path);
 
 /// @brief Create all the non-existent directories in path.
 ///
@@ -290,7 +282,8 @@ error_code normalize_separators(SmallVectorImpl<char> &Path);
 /// @returns errc::success if is_directory(path), otherwise a platform
 ///          specific error_code. If IgnoreExisting is false, also returns
 ///          error if the directory already existed.
-error_code create_directories(const Twine &path, bool IgnoreExisting = true);
+std::error_code create_directories(const Twine &path,
+                                   bool IgnoreExisting = true);
 
 /// @brief Create the directory in path.
 ///
@@ -298,7 +291,7 @@ error_code create_directories(const Twine &path, bool IgnoreExisting = true);
 /// @returns errc::success if is_directory(path), otherwise a platform
 ///          specific error_code. If IgnoreExisting is false, also returns
 ///          error if the directory already existed.
-error_code create_directory(const Twine &path, bool IgnoreExisting = true);
+std::error_code create_directory(const Twine &path, bool IgnoreExisting = true);
 
 /// @brief Create a link from \a from to \a to.
 ///
@@ -311,36 +304,42 @@ error_code create_directory(const Twine &path, bool IgnoreExisting = true);
 /// @param from The path to hard link from. This is created.
 /// @returns errc::success if the link was created, otherwise a platform
 /// specific error_code.
-error_code create_link(const Twine &to, const Twine &from);
+std::error_code create_link(const Twine &to, const Twine &from);
 
 /// @brief Get the current path.
 ///
 /// @param result Holds the current path on return.
 /// @returns errc::success if the current path has been stored in result,
-///          otherwise a platform specific error_code.
-error_code current_path(SmallVectorImpl<char> &result);
+///          otherwise a platform-specific error_code.
+std::error_code current_path(SmallVectorImpl<char> &result);
 
 /// @brief Remove path. Equivalent to POSIX remove().
 ///
 /// @param path Input path.
 /// @returns errc::success if path has been removed or didn't exist, otherwise a
-///          platform specific error code. If IgnoreNonExisting is false, also
+///          platform-specific error code. If IgnoreNonExisting is false, also
 ///          returns error if the file didn't exist.
-error_code remove(const Twine &path, bool IgnoreNonExisting = true);
+std::error_code remove(const Twine &path, bool IgnoreNonExisting = true);
 
 /// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
 ///
 /// @param from The path to rename from.
 /// @param to The path to rename to. This is created.
-error_code rename(const Twine &from, const Twine &to);
+std::error_code rename(const Twine &from, const Twine &to);
+
+/// @brief Copy the contents of \a From to \a To.
+///
+/// @param From The path to copy from.
+/// @param To The path to copy to. This is created.
+std::error_code copy_file(const Twine &From, const Twine &To);
 
 /// @brief Resize path to size. File is resized as if by POSIX truncate().
 ///
 /// @param path Input path.
 /// @param size Size to resize to.
 /// @returns errc::success if \a path has been resized to \a size, otherwise a
-///          platform specific error_code.
-error_code resize_file(const Twine &path, uint64_t size);
+///          platform-specific error_code.
+std::error_code resize_file(const Twine &path, uint64_t size);
 
 /// @}
 /// @name Physical Observers
@@ -353,33 +352,37 @@ error_code resize_file(const Twine &path, uint64_t size);
 ///          not.
 bool exists(file_status status);
 
-/// @brief Does file exist?
+/// @brief Can the file be accessed?
 ///
 /// @param path Input path.
-/// @param result Set to true if the file represented by status exists, false if
-///               it does not. Undefined otherwise.
-/// @returns errc::success if result has been successfully set, otherwise a
-///          platform specific error_code.
-error_code exists(const Twine &path, bool &result);
+/// @returns errc::success if the path can be accessed, otherwise a
+///          platform-specific error_code.
+enum class AccessMode { Exist, Write, Execute };
+std::error_code access(const Twine &Path, AccessMode Mode);
 
-/// @brief Simpler version of exists for clients that don't need to
-///        differentiate between an error and false.
-inline bool exists(const Twine &path) {
-  bool result;
-  return !exists(path, result) && result;
+/// @brief Does file exist?
+///
+/// @param Path Input path.
+/// @returns True if it exists, false otherwise.
+inline bool exists(const Twine &Path) {
+  return !access(Path, AccessMode::Exist);
 }
 
 /// @brief Can we execute this file?
 ///
 /// @param Path Input path.
 /// @returns True if we can execute it, false otherwise.
-bool can_execute(const Twine &Path);
+inline bool can_execute(const Twine &Path) {
+  return !access(Path, AccessMode::Execute);
+}
 
 /// @brief Can we write this file?
 ///
 /// @param Path Input path.
 /// @returns True if we can write to it, false otherwise.
-bool can_write(const Twine &Path);
+inline bool can_write(const Twine &Path) {
+  return !access(Path, AccessMode::Write);
+}
 
 /// @brief Do file_status's represent the same thing?
 ///
@@ -401,8 +404,8 @@ bool equivalent(file_status A, file_status B);
 /// @param result Set to true if stat(A) and stat(B) have the same device and
 ///               inode (or equivalent).
 /// @returns errc::success if result has been successfully set, otherwise a
-///          platform specific error_code.
-error_code equivalent(const Twine &A, const Twine &B, bool &result);
+///          platform-specific error_code.
+std::error_code equivalent(const Twine &A, const Twine &B, bool &result);
 
 /// @brief Simpler version of equivalent for clients that don't need to
 ///        differentiate between an error and false.
@@ -423,8 +426,8 @@ bool is_directory(file_status status);
 /// @param result Set to true if \a path is a directory, false if it is not.
 ///               Undefined otherwise.
 /// @returns errc::success if result has been successfully set, otherwise a
-///          platform specific error_code.
-error_code is_directory(const Twine &path, bool &result);
+///          platform-specific error_code.
+std::error_code is_directory(const Twine &path, bool &result);
 
 /// @brief Simpler version of is_directory for clients that don't need to
 ///        differentiate between an error and false.
@@ -445,8 +448,8 @@ bool is_regular_file(file_status status);
 /// @param result Set to true if \a path is a regular file, false if it is not.
 ///               Undefined otherwise.
 /// @returns errc::success if result has been successfully set, otherwise a
-///          platform specific error_code.
-error_code is_regular_file(const Twine &path, bool &result);
+///          platform-specific error_code.
+std::error_code is_regular_file(const Twine &path, bool &result);
 
 /// @brief Simpler version of is_regular_file for clients that don't need to
 ///        differentiate between an error and false.
@@ -471,41 +474,41 @@ bool is_other(file_status status);
 /// @param result Set to true if \a path exists, but is not a directory, regular
 ///               file, or a symlink, false if it does not. Undefined otherwise.
 /// @returns errc::success if result has been successfully set, otherwise a
-///          platform specific error_code.
-error_code is_other(const Twine &path, bool &result);
+///          platform-specific error_code.
+std::error_code is_other(const Twine &path, bool &result);
 
 /// @brief Get file status as if by POSIX stat().
 ///
 /// @param path Input path.
 /// @param result Set to the file status.
 /// @returns errc::success if result has been successfully set, otherwise a
-///          platform specific error_code.
-error_code status(const Twine &path, file_status &result);
+///          platform-specific error_code.
+std::error_code status(const Twine &path, file_status &result);
 
 /// @brief A version for when a file descriptor is already available.
-error_code status(int FD, file_status &Result);
+std::error_code status(int FD, file_status &Result);
 
 /// @brief Get file size.
 ///
 /// @param Path Input path.
 /// @param Result Set to the size of the file in \a Path.
 /// @returns errc::success if result has been successfully set, otherwise a
-///          platform specific error_code.
-inline error_code file_size(const Twine &Path, uint64_t &Result) {
+///          platform-specific error_code.
+inline std::error_code file_size(const Twine &Path, uint64_t &Result) {
   file_status Status;
-  error_code EC = status(Path, Status);
+  std::error_code EC = status(Path, Status);
   if (EC)
     return EC;
   Result = Status.getSize();
-  return error_code();
+  return std::error_code();
 }
 
 /// @brief Set the file modification and access time.
 ///
 /// @returns errc::success if the file times were successfully set, otherwise a
-///          platform specific error_code or errc::not_supported on platforms
-///          where the functionality isn't available.
-error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
+///          platform-specific error_code or errc::function_not_supported on
+///          platforms where the functionality isn't available.
+std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
 
 /// @brief Is status available?
 ///
@@ -518,8 +521,8 @@ bool status_known(file_status s);
 /// @param path Input path.
 /// @param result Set to true if status() != status_error.
 /// @returns errc::success if result has been successfully set, otherwise a
-///          platform specific error_code.
-error_code status_known(const Twine &path, bool &result);
+///          platform-specific error_code.
+std::error_code status_known(const Twine &path, bool &result);
 
 /// @brief Create a uniquely named file.
 ///
@@ -541,14 +544,14 @@ error_code status_known(const Twine &path, bool &result);
 /// @param ResultFD Set to the opened file's file descriptor.
 /// @param ResultPath Set to the opened file's absolute path.
 /// @returns errc::success if Result{FD,Path} have been successfully set,
-///          otherwise a platform specific error_code.
-error_code createUniqueFile(const Twine &Model, int &ResultFD,
-                            SmallVectorImpl<char> &ResultPath,
-                            unsigned Mode = all_read | all_write);
+///          otherwise a platform-specific error_code.
+std::error_code createUniqueFile(const Twine &Model, int &ResultFD,
+                                 SmallVectorImpl<char> &ResultPath,
+                                 unsigned Mode = all_read | all_write);
 
 /// @brief Simpler version for clients that don't want an open file.
-error_code createUniqueFile(const Twine &Model,
-                            SmallVectorImpl<char> &ResultPath);
+std::error_code createUniqueFile(const Twine &Model,
+                                 SmallVectorImpl<char> &ResultPath);
 
 /// @brief Create a file in the system temporary directory.
 ///
@@ -558,16 +561,16 @@ error_code createUniqueFile(const Twine &Model,
 ///
 /// This should be used for things like a temporary .s that is removed after
 /// running the assembler.
-error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
-                               int &ResultFD,
-                               SmallVectorImpl<char> &ResultPath);
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+                                    int &ResultFD,
+                                    SmallVectorImpl<char> &ResultPath);
 
 /// @brief Simpler version for clients that don't want an open file.
-error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
-                               SmallVectorImpl<char> &ResultPath);
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+                                    SmallVectorImpl<char> &ResultPath);
 
-error_code createUniqueDirectory(const Twine &Prefix,
-                                 SmallVectorImpl<char> &ResultPath);
+std::error_code createUniqueDirectory(const Twine &Prefix,
+                                      SmallVectorImpl<char> &ResultPath);
 
 enum OpenFlags : unsigned {
   F_None = 0,
@@ -598,23 +601,10 @@ inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) {
   return A;
 }
 
-error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags,
-                            unsigned Mode = 0666);
-
-error_code openFileForRead(const Twine &Name, int &ResultFD);
+std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
+                                 OpenFlags Flags, unsigned Mode = 0666);
 
-/// @brief Get \a path's first \a len bytes.
-///
-/// @param path Input path.
-/// @param len Number of magic bytes to get.
-/// @param result Set to the first \a len bytes in the file pointed to by
-///               \a path. Or the entire file if file_size(path) < len, in which
-///               case result.size() returns the size of the file.
-/// @returns errc::success if result has been successfully set,
-///          errc::value_too_large if len is larger then the file pointed to by
-///          \a path, otherwise a platform specific error_code.
-error_code get_magic(const Twine &path, uint32_t len,
-                     SmallVectorImpl<char> &result);
+std::error_code openFileForRead(const Twine &Name, int &ResultFD);
 
 /// @brief Identify the type of a binary file based on how magical it is.
 file_magic identify_magic(StringRef magic);
@@ -624,10 +614,10 @@ file_magic identify_magic(StringRef magic);
 /// @param path Input path.
 /// @param result Set to the type of file, or file_magic::unknown.
 /// @returns errc::success if result has been successfully set, otherwise a
-///          platform specific error_code.
-error_code identify_magic(const Twine &path, file_magic &result);
+///          platform-specific error_code.
+std::error_code identify_magic(const Twine &path, file_magic &result);
 
-error_code getUniqueID(const Twine Path, UniqueID &Result);
+std::error_code getUniqueID(const Twine Path, UniqueID &Result);
 
 /// This class represents a memory mapped file. It is based on
 /// boost::iostreams::mapped_file.
@@ -644,7 +634,7 @@ public:
   };
 
 private:
-  /// Platform specific mapping state.
+  /// Platform-specific mapping state.
   mapmode Mode;
   uint64_t Size;
   void *Mapping;
@@ -654,7 +644,7 @@ private:
   void *FileMappingHandle;
 #endif
 
-  error_code init(int FD, bool CloseFD, uint64_t Offset);
+  std::error_code init(int FD, bool CloseFD, uint64_t Offset);
 
 public:
   typedef char char_type;
@@ -676,21 +666,14 @@ public:
   ///               mapped_file_region::alignment().
   /// \param ec This is set to errc::success if the map was constructed
   ///           successfully. Otherwise it is set to a platform dependent error.
-  mapped_file_region(const Twine &path,
-                     mapmode mode,
-                     uint64_t length,
-                     uint64_t offset,
-                     error_code &ec);
+  mapped_file_region(const Twine &path, mapmode mode, uint64_t length,
+                     uint64_t offset, std::error_code &ec);
 
   /// \param fd An open file descriptor to map. mapped_file_region takes
   ///   ownership if closefd is true. It must have been opended in the correct
   ///   mode.
-  mapped_file_region(int fd,
-                     bool closefd,
-                     mapmode mode,
-                     uint64_t length,
-                     uint64_t offset,
-                     error_code &ec);
+  mapped_file_region(int fd, bool closefd, mapmode mode, uint64_t length,
+                     uint64_t offset, std::error_code &ec);
 
   ~mapped_file_region();
 
@@ -737,7 +720,7 @@ public:
   void replace_filename(const Twine &filename, file_status st = file_status());
 
   const std::string &path() const { return Path; }
-  error_code status(file_status &result) const;
+  std::error_code status(file_status &result) const;
 
   bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; }
   bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); }
@@ -750,9 +733,9 @@ public:
 namespace detail {
   struct DirIterState;
 
-  error_code directory_iterator_construct(DirIterState&, StringRef);
-  error_code directory_iterator_increment(DirIterState&);
-  error_code directory_iterator_destruct(DirIterState&);
+  std::error_code directory_iterator_construct(DirIterState &, StringRef);
+  std::error_code directory_iterator_increment(DirIterState &);
+  std::error_code directory_iterator_destruct(DirIterState &);
 
   /// DirIterState - Keeps state for the directory_iterator. It is reference
   /// counted in order to preserve InputIterator semantics on copy.
@@ -776,14 +759,14 @@ class directory_iterator {
   IntrusiveRefCntPtr<detail::DirIterState> State;
 
 public:
-  explicit directory_iterator(const Twine &path, error_code &ec) {
+  explicit directory_iterator(const Twine &path, std::error_code &ec) {
     State = new detail::DirIterState;
     SmallString<128> path_storage;
     ec = detail::directory_iterator_construct(*State,
             path.toStringRef(path_storage));
   }
 
-  explicit directory_iterator(const directory_entry &de, error_code &ec) {
+  explicit directory_iterator(const directory_entry &de, std::error_code &ec) {
     State = new detail::DirIterState;
     ec = detail::directory_iterator_construct(*State, de.path());
   }
@@ -792,7 +775,7 @@ public:
   directory_iterator() : State(nullptr) {}
 
   // No operator++ because we need error_code.
-  directory_iterator &increment(error_code &ec) {
+  directory_iterator &increment(std::error_code &ec) {
     ec = directory_iterator_increment(*State);
     return *this;
   }
@@ -838,14 +821,14 @@ class recursive_directory_iterator {
 
 public:
   recursive_directory_iterator() {}
-  explicit recursive_directory_iterator(const Twine &path, error_code &ec)
-    : State(new detail::RecDirIterState) {
+  explicit recursive_directory_iterator(const Twine &path, std::error_code &ec)
+      : State(new detail::RecDirIterState) {
     State->Stack.push(directory_iterator(path, ec));
     if (State->Stack.top() == directory_iterator())
       State.reset();
   }
   // No operator++ because we need error_code.
-  recursive_directory_iterator &increment(error_code &ec) {
+  recursive_directory_iterator &increment(std::error_code &ec) {
     const directory_iterator end_itr;
 
     if (State->HasNoPushRequest)
@@ -894,7 +877,7 @@ public:
     assert(State->Level > 0 && "Cannot pop an iterator with level < 1");
 
     const directory_iterator end_itr;
-    error_code ec;
+    std::error_code ec;
     do {
       if (ec)
         report_fatal_error("Error incrementing directory iterator.");