X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FFileSystem.h;h=bf2e514d409b6c27f9f67dd812bee1f71f24f37b;hb=217a29303dfbd51093d2cefa3c24460520935f85;hp=8380d5046d9e56268008a48eb4336469aa71f6c2;hpb=9f439059e60053ae1b8bb40efbe5df0966add03c;p=oota-llvm.git diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 8380d5046d9..bf2e514d409 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -73,22 +73,6 @@ private: int v_; }; -/// copy_option - An "enum class" enumeration of copy semantics for copy -/// operations. -struct copy_option { - enum _ { - fail_if_exists, - overwrite_if_exists - }; - - copy_option(_ v) : v_(v) {} - explicit copy_option(int v) : v_(_(v)) {} - operator int() const {return v_;} - -private: - int v_; -}; - /// space_info - Self explanatory. struct space_info { uint64_t capacity; @@ -141,8 +125,25 @@ inline perms operator~(perms x) { return static_cast(~static_cast(x)); } +class UniqueID { + uint64_t Device; + uint64_t File; + +public: + UniqueID() {} + UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {} + bool operator==(const UniqueID &Other) const { + return Device == Other.Device && File == Other.File; + } + bool operator!=(const UniqueID &Other) const { return !(*this == Other); } + bool operator<(const UniqueID &Other) const { + return Device < Other.Device || + (Device == Other.Device && File < Other.File); + } + uint64_t getDevice() const { return Device; } + uint64_t getFile() const { return File; } +}; - /// file_status - Represents the result of a call to stat and friends. It has /// a platform specific member to store the result. class file_status @@ -153,6 +154,7 @@ class file_status time_t fs_st_mtime; uid_t fs_st_uid; gid_t fs_st_gid; + off_t fs_st_size; #elif defined (LLVM_ON_WIN32) uint32_t LastWriteTimeHigh; uint32_t LastWriteTimeLow; @@ -163,23 +165,39 @@ class file_status uint32_t FileIndexLow; #endif friend bool equivalent(file_status A, file_status B); - friend error_code status(const Twine &path, file_status &result); - friend error_code getUniqueID(const Twine Path, uint64_t &Result); file_type Type; perms Perms; public: - explicit file_status(file_type v=file_type::status_error, - perms prms=perms_not_known) - : Type(v), Perms(prms) {} + file_status() : Type(file_type::status_error) {} + file_status(file_type Type) : Type(Type) {} + + #if defined(LLVM_ON_UNIX) + file_status(file_type Type, perms Perms, dev_t Dev, ino_t Ino, time_t MTime, + uid_t UID, gid_t GID, off_t Size) + : fs_st_dev(Dev), fs_st_ino(Ino), fs_st_mtime(MTime), fs_st_uid(UID), + fs_st_gid(GID), fs_st_size(Size), Type(Type), Perms(Perms) {} + #elif defined(LLVM_ON_WIN32) + file_status(file_type Type, uint32_t LastWriteTimeHigh, + uint32_t LastWriteTimeLow, uint32_t VolumeSerialNumber, + uint32_t FileSizeHigh, uint32_t FileSizeLow, + uint32_t FileIndexHigh, uint32_t FileIndexLow) + : LastWriteTimeHigh(LastWriteTimeHigh), + LastWriteTimeLow(LastWriteTimeLow), + VolumeSerialNumber(VolumeSerialNumber), FileSizeHigh(FileSizeHigh), + FileSizeLow(FileSizeLow), FileIndexHigh(FileIndexHigh), + FileIndexLow(FileIndexLow), Type(Type), Perms(perms_not_known) {} + #endif // getters file_type type() const { return Type; } perms permissions() const { return Perms; } TimeValue getLastModificationTime() const; + UniqueID getUniqueID() const; #if defined(LLVM_ON_UNIX) uint32_t getUser() const { return fs_st_uid; } uint32_t getGroup() const { return fs_st_gid; } + uint64_t getSize() const { return fs_st_size; } #elif defined (LLVM_ON_WIN32) uint32_t getUser() const { return 9999; // Not applicable to Windows, so... @@ -187,6 +205,9 @@ public: uint32_t getGroup() const { return 9999; // Not applicable to Windows, so... } + uint64_t getSize() const { + return (uint64_t(FileSizeHigh) << 32) + FileSizeLow; + } #endif // setters @@ -217,7 +238,9 @@ struct file_magic { macho_dsym_companion, ///< Mach-O dSYM companion file macho_universal_binary, ///< Mach-O universal binary coff_object, ///< COFF object file - pecoff_executable ///< PECOFF executable file + coff_import_library, ///< COFF import library + pecoff_executable, ///< PECOFF executable file + windows_resource ///< Windows compiled resource file (.rc) }; bool is_object() const { @@ -249,18 +272,6 @@ private: /// platform specific error_code. error_code make_absolute(SmallVectorImpl &path); -/// @brief Copy the file at \a from to the path \a to. -/// -/// @param from The path to copy the file from. -/// @param to The path to copy the file to. -/// @param copt Behavior if \a to already exists. -/// @returns errc::success if the file has been successfully copied. -/// errc::file_exists if \a to already exists and \a copt == -/// copy_option::fail_if_exists. Otherwise a platform specific -/// error_code. -error_code copy_file(const Twine &from, const Twine &to, - copy_option copt = copy_option::fail_if_exists); - /// @brief Create all the non-existent directories in path. /// /// @param path Directories to create. @@ -429,14 +440,6 @@ inline bool equivalent(const Twine &A, const Twine &B) { return !equivalent(A, B, result) && 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. -error_code file_size(const Twine &path, uint64_t &result); - /// @brief Does status represent a directory? /// /// @param status A file_status previously returned from status. @@ -452,6 +455,13 @@ bool is_directory(file_status status); /// platform specific error_code. 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. +inline bool is_directory(const Twine &Path) { + bool Result; + return !is_directory(Path, Result) && Result; +} + /// @brief Does status represent a regular file? /// /// @param status A file_status previously returned from status. @@ -517,6 +527,29 @@ error_code is_symlink(const Twine &path, bool &result); /// platform specific error_code. 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); + +/// @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) { + file_status Status; + error_code EC = status(Path, Status); + if (EC) + return EC; + Result = Status.getSize(); + return error_code::success(); +} + +/// @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); /// @brief Is status available? @@ -581,16 +614,36 @@ error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl &ResultPath); -/// @brief Canonicalize path. -/// -/// Sets result to the file system's idea of what path is. The result is always -/// absolute and has the same capitalization as the file system. -/// -/// @param path Input path. -/// @param result Set to the canonicalized version of \a path. -/// @returns errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code canonicalize(const Twine &path, SmallVectorImpl &result); +enum OpenFlags { + F_None = 0, + + /// F_Excl - When opening a file, this flag makes raw_fd_ostream + /// report an error if the file already exists. + F_Excl = 1, + + /// F_Append - When opening a file, if it already exists append to the + /// existing file instead of returning an error. This may not be specified + /// with F_Excl. + F_Append = 2, + + /// F_Binary - The file should be opened in binary mode on platforms that + /// make this distinction. + F_Binary = 4 +}; + +inline OpenFlags operator|(OpenFlags A, OpenFlags B) { + return OpenFlags(unsigned(A) | unsigned(B)); +} + +inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) { + A = A | B; + return A; +} + +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? /// @@ -624,7 +677,7 @@ file_magic identify_magic(StringRef magic); /// platform specific error_code. error_code identify_magic(const Twine &path, file_magic &result); -error_code getUniqueID(const Twine Path, uint64_t &Result); +error_code getUniqueID(const Twine Path, UniqueID &Result); /// This class represents a memory mapped file. It is based on /// boost::iostreams::mapped_file. @@ -674,7 +727,7 @@ public: /// should begin. Must be a multiple of /// mapped_file_region::alignment(). /// \param ec This is set to errc::success if the map was constructed - /// sucessfully. Otherwise it is set to a platform dependent error. + /// successfully. Otherwise it is set to a platform dependent error. mapped_file_region(const Twine &path, mapmode mode, uint64_t length, @@ -812,7 +865,7 @@ public: } /// Construct end iterator. - directory_iterator() : State(new detail::DirIterState) {} + directory_iterator() : State(0) {} // No operator++ because we need error_code. directory_iterator &increment(error_code &ec) { @@ -824,6 +877,12 @@ public: const directory_entry *operator->() const { return &State->CurrentEntry; } bool operator==(const directory_iterator &RHS) const { + if (State == RHS.State) + return true; + if (RHS.State == 0) + return State->CurrentEntry == directory_entry(); + if (State == 0) + return RHS.State->CurrentEntry == directory_entry(); return State->CurrentEntry == RHS.State->CurrentEntry; } @@ -863,7 +922,7 @@ public: } // No operator++ because we need error_code. recursive_directory_iterator &increment(error_code &ec) { - static const directory_iterator end_itr; + const directory_iterator end_itr; if (State->HasNoPushRequest) State->HasNoPushRequest = false; @@ -907,10 +966,10 @@ public: // modifiers /// Goes up one level if Level > 0. void pop() { - assert(State && "Cannot pop and end itertor!"); + assert(State && "Cannot pop an end iterator!"); assert(State->Level > 0 && "Cannot pop an iterator with level < 1"); - static const directory_iterator end_itr; + const directory_iterator end_itr; error_code ec; do { if (ec)