52 using namespace FileOperations;
61 template<
typename Action>
63 if constexpr (std::is_invocable_v<Action, std::string&, std::string_view, Stat&>) {
64 return std::tuple(action,
true);
65 }
else if constexpr (std::is_invocable_v<Action, std::string&, std::string_view>) {
66 return std::tuple([action](std::string& p, std::string_view f,
Stat& ) {
69 }
else if constexpr (std::is_invocable_v<Action, std::string&, Stat&>) {
70 return std::tuple([action](std::string& p, std::string_view ,
Stat& st) {
73 }
else if constexpr (std::is_invocable_v<Action, std::string&>) {
74 return std::tuple([action](std::string& p, std::string_view ,
Stat& ) {
78 static_assert((Action{},
false),
"Wrong signature for action");
85 template<
typename Action>
87 using ResultType = std::invoke_result_t<Action, std::string&, std::string_view, Stat&>;
88 if constexpr (std::is_same_v<ResultType, void>) {
89 return [=](
auto&&... params) {
90 action(std::forward<
decltype(params)>(params)...);
98 template<
typename FileAction,
typename DirAction>
99 bool foreach_dirent(std::string& path, FileAction fileAction, DirAction dirAction) {
100 auto [invokeFile, statFile] =
adaptParams(fileAction);
101 auto [invokeDir, statDir ] =
adaptParams(dirAction);
104 bool needStat = statFile || statDir;
107 bool addSlash = !path.empty() && (path.back() !=
'/');
108 if (addSlash) path +=
'/';
109 auto origLen = path.size();
110 while (dirent* d = dir.
getEntry()) {
111 std::string_view f(d->d_name);
112 if (f ==
one_of(
".",
".."))
continue;
114 auto file = std::string_view(path).substr(origLen);
118 auto type = needStat ?
static_cast<unsigned char>(DT_UNKNOWN) : d->d_type;
119 if (type == DT_REG) {
121 if (!invokeFileAction(path, file, dummy)) {
124 }
else if (type == DT_DIR) {
126 if (!invokeDirAction(path, file, dummy)) {
132 if (!invokeFileAction(path, file, *st)) {
136 if (!invokeDirAction(path, file, *st)) {
143 path.resize(origLen);
145 if (addSlash) path.pop_back();
151 template<
typename FileAction>
154 auto dirAction = [&](
const std::string& ) { };
158 template<
typename FileAction,
typename DirAction>
164 template<
typename FileAction>
167 std::function<bool(std::string&)> dirAction;
168 dirAction = [&](std::string& dirPath) {
171 return dirAction(path);
Simple wrapper around opendir() / readdir() / closedir() functions.
struct dirent * getEntry()
Get directory entry for next file.
bool isRegularFile(const Stat &st)
bool isDirectory(const Stat &st)
std::optional< Stat > getStat(zstring_view filename)
Call stat() and return the stat structure.
bool foreach_dirent(std::string &path, FileAction fileAction, DirAction dirAction)
auto adaptReturn(Action action)
auto adaptParams(Action action)
This file implemented 3 utility functions:
bool foreach_file_recursive(std::string path, FileAction fileAction)
bool foreach_file(std::string path, FileAction fileAction)
bool foreach_file_and_directory(std::string path, FileAction fileAction, DirAction dirAction)