1 #ifndef FOREACH_FILE_HH
2 #define FOREACH_FILE_HH
51 using namespace FileOperations;
60 template<
typename Action>
62 if constexpr (std::is_invocable_v<Action, std::string&, std::string_view, Stat&>) {
63 return std::tuple(action,
true);
64 }
else if constexpr (std::is_invocable_v<Action, std::string&, std::string_view>) {
65 return std::tuple([action](std::string& p, std::string_view f,
Stat& ) {
68 }
else if constexpr (std::is_invocable_v<Action, std::string&, Stat&>) {
69 return std::tuple([action](std::string& p, std::string_view ,
Stat& st) {
72 }
else if constexpr (std::is_invocable_v<Action, std::string&>) {
73 return std::tuple([action](std::string& p, std::string_view ,
Stat& ) {
77 static_assert((Action{},
false),
"Wrong signature for action");
84 template<
typename Action>
86 using ResultType = std::invoke_result_t<Action, std::string&, std::string_view, Stat&>;
87 if constexpr (std::is_same_v<ResultType, void>) {
88 return [=](
auto&&... params) {
89 action(std::forward<decltype(params)>(params)...);
97 template<
typename FileAction,
typename DirAction>
98 bool foreach_dirent(std::string& path, FileAction fileAction, DirAction dirAction) {
99 auto [invokeFile, statFile] =
adaptParams(fileAction);
100 auto [invokeDir, statDir ] =
adaptParams(dirAction);
103 bool needStat = statFile || statDir;
106 bool addSlash = !path.empty() && (path.back() !=
'/');
107 if (addSlash) path +=
'/';
108 auto origLen = path.size();
109 while (dirent* d = dir.
getEntry()) {
110 std::string_view f(d->d_name);
111 if (f ==
one_of(
".",
".."))
continue;
113 auto file = std::string_view(path).substr(origLen);
117 auto type = needStat ?
static_cast<unsigned char>(DT_UNKNOWN) : d->d_type;
119 if (type == DT_REG) {
120 if (!invokeFileAction(path, file, st)) {
123 }
else if (type == DT_DIR) {
124 if (!invokeDirAction(path, file, st)) {
130 if (!invokeFileAction(path, file, st)) {
134 if (!invokeDirAction(path, file, st)) {
141 path.resize(origLen);
143 if (addSlash) path.pop_back();
149 template<
typename FileAction>
152 auto dirAction = [&](
const std::string& ) { };
156 template<
typename FileAction,
typename DirAction>
162 template<
typename FileAction>
165 std::function<bool(std::string&)> dirAction;
166 dirAction = [&](std::string& dirPath) {
169 return dirAction(path);
Simple wrapper around opendir() / readdir() / closedir() functions.
struct dirent * getEntry()
Get directory entry for next file.
bool getStat(zstring_view filename, Stat &st)
Call stat() and return the stat structure.
bool isRegularFile(const Stat &st)
bool isDirectory(const Stat &st)
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)