#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>
namespace sys {
namespace fs {
-/// An "enum class" enumeration for the file system's view of the type.
-struct file_type {
- enum Impl {
- status_error,
- file_not_found,
- regular_file,
- directory_file,
- symlink_file,
- block_file,
- character_file,
- fifo_file,
- socket_file,
- type_unknown
- };
-
- file_type(Impl V) : V(V) {}
- operator Impl() const { return V; }
-
-private:
- Impl V;
+/// An enumeration for the file system's view of the type.
+enum class file_type {
+ status_error,
+ file_not_found,
+ regular_file,
+ directory_file,
+ symlink_file,
+ block_file,
+ character_file,
+ fifo_file,
+ socket_file,
+ type_unknown
};
/// space_info - Self explanatory.
};
/// 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)
///
/// @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.
///
/// @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.
///
/// @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.
///
/// @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
/// @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);
+/// platform-specific error_code.
+std::error_code exists(const Twine &path, bool &result);
/// @brief Simpler version of exists for clients that don't need to
/// differentiate between an error and false.
/// @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.
/// @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.
/// @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.
/// @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::success();
+ 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?
///
/// @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.
///
/// @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.
///
///
/// 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,
return A;
}
-error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags,
- unsigned Mode = 0666);
+std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
+ OpenFlags Flags, unsigned Mode = 0666);
-error_code openFileForRead(const Twine &Name, int &ResultFD);
-
-/// @brief Are \a path's first bytes \a magic?
-///
-/// @param path Input path.
-/// @param magic Byte sequence to compare \a path's first len(magic) bytes to.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_magic(const Twine &path, const Twine &magic, bool &result);
-
-/// @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);
/// @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.
};
private:
- /// Platform specific mapping state.
+ /// Platform-specific mapping state.
mapmode Mode;
uint64_t Size;
void *Mapping;
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;
/// 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();
static int alignment();
};
-/// @brief Memory maps the contents of a file
-///
-/// @param path Path to file to map.
-/// @param file_offset Byte offset in file where mapping should begin.
-/// @param size Byte length of range of the file to map.
-/// @param map_writable If true, the file will be mapped in r/w such
-/// that changes to the mapped buffer will be flushed back
-/// to the file. If false, the file will be mapped read-only
-/// and the buffer will be read-only.
-/// @param result Set to the start address of the mapped buffer.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,
- bool map_writable, void *&result);
-
-
-/// @brief Memory unmaps the contents of a file
-///
-/// @param base Pointer to the start of the buffer.
-/// @param size Byte length of the range to unmmap.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code unmap_file_pages(void *base, size_t size);
-
/// Return the path to the main executable, given the value of argv[0] from
/// program startup and the address of main itself. In extremis, this function
/// may fail and return an empty path.
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); }
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.
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());
}
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;
}
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)
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.");