From 41a8b75cd086d4d688a73778a4db0bd025965332 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 30 Aug 2021 02:38:46 +0300 Subject: [PATCH] Add platform-specific implemenrations of FS::list_filtered Microsoft's stdlib does not have opendir and friends. --- source/fs/dir.cpp | 25 ------------------------- source/fs/unix/dir.cpp | 24 ++++++++++++++++++++++++ source/fs/windows/dir.cpp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 25 deletions(-) diff --git a/source/fs/dir.cpp b/source/fs/dir.cpp index 218a7a5..066d88b 100644 --- a/source/fs/dir.cpp +++ b/source/fs/dir.cpp @@ -1,8 +1,5 @@ -#include #include #include -#include -#include #include #include "dir.h" #include "path.h" @@ -108,28 +105,6 @@ vector list_files(const Path &path) return list_filtered(path, string()); } -vector list_filtered(const Path &path, const string &filter) -{ - Regex r_filter(filter); - - vector result; - DIR *dir = opendir(path.str().c_str()); - if(!dir) - throw system_error("opendir"); - - while(dirent *de = readdir(dir)) - { - const char *fn = de->d_name; - if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0))) - continue; - if(r_filter.match(fn)) - result.push_back(fn); - } - closedir(dir); - - return result; -} - Path get_sys_conf_dir() { const char *argv0 = Application::get_argv0(); diff --git a/source/fs/unix/dir.cpp b/source/fs/unix/dir.cpp index 0dc950b..a13cbbb 100644 --- a/source/fs/unix/dir.cpp +++ b/source/fs/unix/dir.cpp @@ -1,6 +1,8 @@ #include +#include #include #include +#include #include "dir.h" using namespace std; @@ -20,6 +22,28 @@ void rmdir(const Path &path) throw system_error("rmdir"); } +vector list_filtered(const Path &path, const string &filter) +{ + Regex r_filter(filter); + + vector result; + DIR *dir = opendir(path.str().c_str()); + if(!dir) + throw system_error("opendir"); + + while(dirent *de = readdir(dir)) + { + const char *fn = de->d_name; + if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0))) + continue; + if(r_filter.match(fn)) + result.push_back(fn); + } + closedir(dir); + + return result; +} + Path getcwd() { char buf[1024]; diff --git a/source/fs/windows/dir.cpp b/source/fs/windows/dir.cpp index 3d2bf6e..c6f6b9b 100644 --- a/source/fs/windows/dir.cpp +++ b/source/fs/windows/dir.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "dir.h" using namespace std; @@ -20,6 +21,40 @@ void rmdir(const Path &path) throw system_error("RemoveDirectory"); } +vector list_filtered(const Path &path, const string &filter) +{ + Regex r_filter(filter); + + vector result; + WIN32_FIND_DATA entry; + string pattern = path.str()+"\\*"; + HANDLE search_handle = FindFirstFileEx(pattern.c_str(), FindExInfoBasic, &entry, FindExSearchNameMatch, 0, 0); + if(search_handle==INVALID_HANDLE_VALUE) + { + DWORD err = GetLastError(); + if(err==ERROR_FILE_NOT_FOUND) + return result; + throw system_error("FindFirstFileEx"); + } + + bool more = true; + for(; more; more=FindNextFile(search_handle, &entry)) + { + const char *fn = entry.cFileName; + if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0))) + continue; + if(r_filter.match(fn)) + result.push_back(fn); + } + + DWORD err = GetLastError(); + FindClose(search_handle); + if(err!=ERROR_NO_MORE_FILES) + throw system_error("FindNextFile"); + + return result; +} + /* Windows documentation says Get/SetCurrentDirectory use a global buffer and are not thread safe. */ static Mutex &cwd_mutex() -- 2.43.0