27 #ifndef WPIUTIL_WPI_FILESYSTEM_H
28 #define WPIUTIL_WPI_FILESYSTEM_H
30 #include "wpi/SmallString.h"
31 #include "wpi/StringRef.h"
32 #include "wpi/Twine.h"
40 #include <system_error>
51 enum class file_type {
69 owner_all = owner_read | owner_write | owner_exe,
73 group_all = group_read | group_write | group_exe,
77 others_all = others_read | others_write | others_exe,
78 all_read = owner_read | group_read | others_read,
79 all_write = owner_write | group_write | others_write,
80 all_exe = owner_exe | group_exe | others_exe,
81 all_all = owner_all | group_all | others_all,
82 set_uid_on_exe = 04000,
83 set_gid_on_exe = 02000,
85 all_perms = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit,
86 perms_not_known = 0xFFFF
90 inline perms operator|(perms l, perms r) {
91 return static_cast<perms
>(
static_cast<unsigned short>(l) |
92 static_cast<unsigned short>(r));
94 inline perms operator&(perms l, perms r) {
95 return static_cast<perms
>(
static_cast<unsigned short>(l) &
96 static_cast<unsigned short>(r));
98 inline perms &operator|=(perms &l, perms r) {
102 inline perms &operator&=(perms &l, perms r) {
106 inline perms operator~(perms x) {
108 return static_cast<perms
>(
109 static_cast<unsigned short>(~static_cast<
unsigned short>(x)));
118 UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {}
120 bool operator==(
const UniqueID &Other)
const {
121 return Device == Other.Device && File == Other.File;
123 bool operator!=(
const UniqueID &Other)
const {
return !(*
this == Other); }
124 bool operator<(
const UniqueID &Other)
const {
125 return std::tie(Device, File) < std::tie(Other.Device, Other.File);
128 uint64_t getDevice()
const {
return Device; }
129 uint64_t getFile()
const {
return File; }
138 time_t fs_st_atime = 0;
139 time_t fs_st_mtime = 0;
142 off_t fs_st_size = 0;
144 uint32_t LastAccessedTimeHigh = 0;
145 uint32_t LastAccessedTimeLow = 0;
146 uint32_t LastWriteTimeHigh = 0;
147 uint32_t LastWriteTimeLow = 0;
148 uint32_t FileSizeHigh = 0;
149 uint32_t FileSizeLow = 0;
151 file_type Type = file_type::status_error;
152 perms Perms = perms_not_known;
161 uid_t UID, gid_t GID, off_t Size)
162 : fs_st_atime(ATime), fs_st_mtime(MTime), fs_st_uid(UID), fs_st_gid(GID),
163 fs_st_size(Size), Type(Type), Perms(Perms) {}
166 uint32_t LastAccessTimeLow, uint32_t LastWriteTimeHigh,
167 uint32_t LastWriteTimeLow, uint32_t FileSizeHigh,
168 uint32_t FileSizeLow)
169 : LastAccessedTimeHigh(LastAccessTimeHigh),
170 LastAccessedTimeLow(LastAccessTimeLow),
171 LastWriteTimeHigh(LastWriteTimeHigh),
172 LastWriteTimeLow(LastWriteTimeLow), FileSizeHigh(FileSizeHigh),
173 FileSizeLow(FileSizeLow), Type(Type), Perms(Perms) {}
177 file_type type()
const {
return Type; }
178 perms permissions()
const {
return Perms; }
181 uint32_t getUser()
const {
return fs_st_uid; }
182 uint32_t getGroup()
const {
return fs_st_gid; }
183 uint64_t getSize()
const {
return fs_st_size; }
185 uint32_t getUser()
const {
189 uint32_t getGroup()
const {
193 uint64_t getSize()
const {
194 return (uint64_t(FileSizeHigh) << 32) + FileSizeLow;
199 void type(file_type v) { Type = v; }
200 void permissions(perms p) { Perms = p; }
209 nlink_t fs_st_nlinks = 0;
212 uint32_t NumLinks = 0;
213 uint32_t VolumeSerialNumber = 0;
214 uint32_t FileIndexHigh = 0;
215 uint32_t FileIndexLow = 0;
224 file_status(file_type Type, perms Perms, dev_t Dev, nlink_t Links, ino_t Ino,
225 time_t ATime, time_t MTime, uid_t UID, gid_t GID, off_t Size)
227 fs_st_dev(Dev), fs_st_nlinks(Links), fs_st_ino(Ino) {}
229 file_status(file_type Type, perms Perms, uint32_t LinkCount,
230 uint32_t LastAccessTimeHigh, uint32_t LastAccessTimeLow,
231 uint32_t LastWriteTimeHigh, uint32_t LastWriteTimeLow,
232 uint32_t VolumeSerialNumber, uint32_t FileSizeHigh,
233 uint32_t FileSizeLow, uint32_t FileIndexHigh,
234 uint32_t FileIndexLow)
236 LastWriteTimeHigh, LastWriteTimeLow, FileSizeHigh,
238 NumLinks(LinkCount), VolumeSerialNumber(VolumeSerialNumber),
239 FileIndexHigh(FileIndexHigh), FileIndexLow(FileIndexLow) {}
243 uint32_t getLinkCount()
const;
261 std::error_code make_absolute(
const Twine ¤t_directory,
295 enum class AccessMode { Exist, Write, Execute };
302 std::error_code access(
const Twine &Path, AccessMode Mode);
308 inline bool exists(
const Twine &Path) {
309 return !access(Path, AccessMode::Exist);
316 inline bool can_write(
const Twine &Path) {
317 return !access(Path, AccessMode::Write);
329 bool equivalent(file_status A, file_status B);
341 std::error_code equivalent(
const Twine &A,
const Twine &B,
bool &result);
345 inline bool equivalent(
const Twine &A,
const Twine &B) {
347 return !equivalent(A, B, result) && result;
354 bool is_directory(
const basic_file_status &status);
363 std::error_code is_directory(
const Twine &path,
bool &result);
367 inline bool is_directory(
const Twine &Path) {
369 return !is_directory(Path, Result) && Result;
376 bool is_regular_file(
const basic_file_status &status);
385 std::error_code is_regular_file(
const Twine &path,
bool &result);
389 inline bool is_regular_file(
const Twine &Path) {
391 if (is_regular_file(Path, Result))
400 bool is_symlink_file(
const basic_file_status &status);
409 std::error_code is_symlink_file(
const Twine &path,
bool &result);
413 inline bool is_symlink_file(
const Twine &Path) {
415 if (is_symlink_file(Path, Result))
425 bool is_other(
const basic_file_status &status);
435 std::error_code is_other(
const Twine &path,
bool &result);
445 std::error_code status(
const Twine &path, file_status &result,
449 std::error_code status(
int FD, file_status &Result);
455 bool status_known(
const basic_file_status &s);
463 std::error_code status_known(
const Twine &path,
bool &result);
465 enum OpenFlags :
unsigned {
493 inline OpenFlags operator|(OpenFlags A, OpenFlags B) {
494 return OpenFlags(
unsigned(A) |
unsigned(B));
497 inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) {
517 std::error_code openFileForWrite(
const Twine &Name,
int &ResultFD,
518 OpenFlags Flags,
unsigned Mode = 0666);
534 std::error_code openFileForRead(
const Twine &Name,
int &ResultFD,
535 SmallVectorImpl<char> *RealPath =
nullptr);
537 std::error_code getUniqueID(
const Twine Path, UniqueID &Result);
554 : Path(path.
str()), FollowSymlinks(follow_symlinks), Status(st) {}
563 void replace_filename(
const Twine &filename,
566 const std::string &path()
const {
return Path; }
569 bool operator==(
const directory_entry& rhs)
const {
return Path == rhs.Path; }
570 bool operator!=(
const directory_entry& rhs)
const {
return !(*
this == rhs); }
581 std::error_code directory_iterator_construct(DirIterState &,
StringRef,
bool);
582 std::error_code directory_iterator_increment(DirIterState &);
583 std::error_code directory_iterator_destruct(DirIterState &);
588 directory_iterator_destruct(*
this);
591 intptr_t IterationHandle = 0;
601 std::shared_ptr<detail::DirIterState> State;
602 bool FollowSymlinks =
true;
606 bool follow_symlinks =
true)
607 : FollowSymlinks(follow_symlinks) {
608 State = std::make_shared<detail::DirIterState>();
610 ec = detail::directory_iterator_construct(
611 *State, path.
toStringRef(path_storage), FollowSymlinks);
612 update_error_code_for_current_entry(ec);
616 bool follow_symlinks =
true)
617 : FollowSymlinks(follow_symlinks) {
618 State = std::make_shared<detail::DirIterState>();
619 ec = detail::directory_iterator_construct(
620 *State, de.path(), FollowSymlinks);
621 update_error_code_for_current_entry(ec);
629 ec = directory_iterator_increment(*State);
630 update_error_code_for_current_entry(ec);
634 const directory_entry &operator*()
const {
return State->CurrentEntry; }
635 const directory_entry *operator->()
const {
return &State->CurrentEntry; }
638 if (State == RHS.State)
644 return State->CurrentEntry == RHS.State->CurrentEntry;
648 return !(*
this == RHS);
656 void update_error_code_for_current_entry(std::error_code &ec) {
668 ec = status.getError();
676 std::stack<directory_iterator, std::vector<directory_iterator>> Stack;
678 bool HasNoPushRequest =
false;
686 std::shared_ptr<detail::RecDirIterState> State;
692 bool follow_symlinks =
true)
693 : State(std::make_shared<detail::RecDirIterState>()),
694 Follow(follow_symlinks) {
704 if (State->HasNoPushRequest)
705 State->HasNoPushRequest =
false;
708 if (status && is_directory(*status)) {
710 if (State->Stack.top() != end_itr) {
718 while (!State->Stack.empty()
719 && State->Stack.top().increment(ec) == end_itr) {
725 if (State->Stack.empty())
731 const directory_entry &operator*()
const {
return *State->Stack.top(); }
732 const directory_entry *operator->()
const {
return &*State->Stack.top(); }
736 int level()
const {
return State->Level; }
744 assert(State &&
"Cannot pop an end iterator!");
745 assert(State->Level > 0 &&
"Cannot pop an iterator with level < 1");
752 while (!State->Stack.empty()) State->Stack.pop();
757 }
while (!State->Stack.empty()
758 && State->Stack.top().increment(ec) == end_itr);
761 if (State->Stack.empty())
766 void no_push() { State->HasNoPushRequest =
true; }
769 return State == RHS.State;
772 bool operator!=(
const recursive_directory_iterator &RHS)
const {
773 return !(*
this == RHS);
785 #endif // LLVM_SUPPORT_FILESYSTEM_H
recursive_directory_iterator - Same as directory_iterator except for it recurses down into child dire...
Definition: FileSystem.h:685
int level() const
Gets the current level. Starting path is at level 0.
Definition: FileSystem.h:736
directory_entry - A single entry in a directory.
Definition: FileSystem.h:546
friend bool equivalent(file_status A, file_status B)
Do file_status's represent the same thing?
Definition: FileSystem.h:112
Represents the result of a call to sys::fs::status().
Definition: FileSystem.h:204
Keeps state for the recursive_directory_iterator.
Definition: FileSystem.h:675
namespace to hold default to_json function
Definition: SmallString.h:21
void pop()
Goes up one level if Level > 0.
Definition: FileSystem.h:743
directory_iterator()=default
Construct end iterator.
directory_iterator - Iterates through the entries in path.
Definition: FileSystem.h:600
bool no_push_request() const
Returns true if no_push has been called for this directory_entry.
Definition: FileSystem.h:739
std::string str() const
Return the twine contents as a std::string.
void no_push()
Does not go down into the current directory_entry.
Definition: FileSystem.h:766
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Keeps state for the directory_iterator.
Definition: FileSystem.h:586
Represents either an error or a value T.
Definition: ErrorOr.h:69
Provides ErrorOr smart pointer.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
Definition: Twine.h:444
Represents the result of a call to directory_iterator::status().
Definition: FileSystem.h:135