59 template<
typename Action>
61 if constexpr (std::is_invocable_v<Action, std::string&, std::string_view, const FileOperations::Stat&>) {
62 return std::tuple(action,
true);
63 }
else if constexpr (std::is_invocable_v<Action, std::string&, std::string_view>) {
67 }
else if constexpr (std::is_invocable_v<Action, std::string&, const FileOperations::Stat&>) {
71 }
else if constexpr (std::is_invocable_v<Action, std::string&>) {
76 static_assert((Action{},
false),
"Wrong signature for action");
83 template<
typename Action>
85 using ResultType = std::invoke_result_t<Action, std::string&, std::string_view, const FileOperations::Stat&>;
86 if constexpr (std::is_same_v<ResultType, void>) {
87 return [=]<
typename... Params>(Params&&... params) {
88 action(std::forward<Params>(params)...);
96 template<
typename FileAction,
typename DirAction>
97 bool foreach_dirent(std::string& path, FileAction fileAction, DirAction dirAction) {
98 auto [invokeFile, statFile] =
adaptParams(fileAction);
99 auto [invokeDir, statDir ] =
adaptParams(dirAction);
102 bool needStat = statFile || statDir;
105 bool addSlash = !path.empty() && (path.back() !=
'/');
106 if (addSlash) path +=
'/';
107 auto origLen = path.size();
108 while (
const dirent* d = dir.
getEntry()) {
109 std::string_view f(d->d_name);
110 if (f ==
one_of(
".",
".."))
continue;
112 auto file = std::string_view(path).substr(origLen);
116 auto type = needStat ?
static_cast<unsigned char>(DT_UNKNOWN) : d->d_type;
117 if (type == DT_REG) {
119 if (!invokeFileAction(path, file, dummy)) {
122 }
else if (type == DT_DIR) {
124 if (!invokeDirAction(path, file, dummy)) {
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 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)