diff options
-rw-r--r-- | libs/pbd/pathscanner.cc | 93 | ||||
-rw-r--r-- | libs/pbd/pbd/pathscanner.h | 104 |
2 files changed, 118 insertions, 79 deletions
diff --git a/libs/pbd/pathscanner.cc b/libs/pbd/pathscanner.cc index a9847ad250..8f37477147 100644 --- a/libs/pbd/pathscanner.cc +++ b/libs/pbd/pathscanner.cc @@ -18,23 +18,24 @@ $Id$ */ -#include <cstring> #include <cstdlib> #include <cstdio> #include <cstring> #include <vector> #include <dirent.h> +#include <sys/types.h> +#include <sys/stat.h> -#include "pbd/error.h" -#include "pbd/pathscanner.h" -#include "pbd/stl_delete.h" +#include <pbd/error.h> +#include <pbd/pathscanner.h> +#include <pbd/stl_delete.h> using namespace PBD; vector<string *> * PathScanner::operator() (const string &dirpath, const string ®exp, bool match_fullpath, bool return_fullpath, - long limit) + long limit, bool recurse) { int err; @@ -59,7 +60,7 @@ PathScanner::operator() (const string &dirpath, const string ®exp, 0, match_fullpath, return_fullpath, - limit); + limit, recurse); } vector<string *> * @@ -68,10 +69,22 @@ PathScanner::run_scan (const string &dirpath, bool (*filter)(const string &, void *), void *arg, bool match_fullpath, bool return_fullpath, - long limit) - + long limit, + bool recurse) +{ + return run_scan_internal ((vector<string*>*) 0, dirpath, memberfilter, filter, arg, match_fullpath, return_fullpath, limit, recurse); +} + +vector<string *> * +PathScanner::run_scan_internal (vector<string *> *result, + const string &dirpath, + bool (PathScanner::*memberfilter)(const string &), + bool (*filter)(const string &, void *), + void *arg, + bool match_fullpath, bool return_fullpath, + long limit, + bool recurse) { - vector<string *> *result = 0; DIR *dir; struct dirent *finfo; char *pathcopy = strdup (dirpath.c_str()); @@ -87,7 +100,9 @@ PathScanner::run_scan (const string &dirpath, return 0; } - result = new vector<string *>; + if (result == 0) { + result = new vector<string *>; + } do { @@ -97,37 +112,51 @@ PathScanner::run_scan (const string &dirpath, while ((finfo = readdir (dir)) != 0) { + if ((finfo->d_name[0] == '.' && finfo->d_name[1] == '\0') || + (finfo->d_name[0] == '.' && finfo->d_name[1] == '.' && finfo->d_name[2] == '\0')) { + continue; + } + snprintf (fullpath, sizeof(fullpath), "%s/%s", thisdir, finfo->d_name); - if (match_fullpath) { - search_str = fullpath; - } else { - search_str = finfo->d_name; + struct stat statbuf; + if (stat (fullpath, &statbuf) < 0) { + continue; } - /* handle either type of function ptr */ - - if (memberfilter) { - if (!(this->*memberfilter)(search_str)) { - continue; - } + if (statbuf.st_mode & S_IFDIR && recurse) { + run_scan_internal (result, fullpath, memberfilter, filter, arg, match_fullpath, return_fullpath, limit, recurse); } else { - if (!filter(search_str, arg)) { - continue; + + if (match_fullpath) { + search_str = fullpath; + } else { + search_str = finfo->d_name; } + + /* handle either type of function ptr */ + + if (memberfilter) { + if (!(this->*memberfilter)(search_str)) { + continue; + } + } else { + if (!filter(search_str, arg)) { + continue; + } + } + + if (return_fullpath) { + newstr = new string (fullpath); + } else { + newstr = new string (finfo->d_name); + } + + result->push_back (newstr); + nfound++; } - - if (return_fullpath) { - newstr = new string (fullpath); - } else { - newstr = new string (finfo->d_name); - } - - result->push_back (newstr); - nfound++; } - closedir (dir); } while ((limit < 0 || (nfound < limit)) && (thisdir = strtok (0, ":"))); diff --git a/libs/pbd/pbd/pathscanner.h b/libs/pbd/pbd/pathscanner.h index 0a48d4d949..550aab163a 100644 --- a/libs/pbd/pbd/pathscanner.h +++ b/libs/pbd/pbd/pathscanner.h @@ -31,55 +31,65 @@ class PathScanner { public: - vector<string *> *operator() (const string &dirpath, - bool (*filter)(const string &, void *arg), - void *arg, - bool match_fullpath = true, - bool return_fullpath = true, - long limit = -1) { - return run_scan (dirpath, - (bool (PathScanner::*)(const string &)) 0, - filter, - arg, - match_fullpath, - return_fullpath, - limit); - } - - vector<string *> *operator() (const string &dirpath, - const string ®exp, - bool match_fullpath = true, - bool return_fullpath = true, - long limit = -1); - + vector<string *> *operator() (const string &dirpath, + bool (*filter)(const string &, void *arg), + void *arg, + bool match_fullpath = true, + bool return_fullpath = true, + long limit = -1, + bool recurse = false) { + return run_scan (dirpath, + (bool (PathScanner::*)(const string &)) 0, + filter, + arg, + match_fullpath, + return_fullpath, + limit, recurse); + } + + vector<string *> *operator() (const string &dirpath, + const string ®exp, + bool match_fullpath = true, + bool return_fullpath = true, + long limit = -1, + bool recurse = false); - string *find_first (const string &dirpath, - const string ®exp, - bool match_fullpath = true, - bool return_fullpath = true); - - string *find_first (const string &dirpath, - bool (*filter)(const string &, void *), - void *arg, - bool match_fullpath = true, - bool return_fullpath = true); - + string *find_first (const string &dirpath, + const string ®exp, + bool match_fullpath = true, + bool return_fullpath = true); + + string *find_first (const string &dirpath, + bool (*filter)(const string &, void *), + void *arg, + bool match_fullpath = true, + bool return_fullpath = true); + private: - regex_t compiled_pattern; - - bool regexp_filter (const string &str) { - return regexec (&compiled_pattern, str.c_str(), 0, 0, 0) == 0; - } - - vector<string *> *run_scan (const string &dirpath, - bool (PathScanner::*mfilter) (const string &), - bool (*filter)(const string &, void *), - void *arg, - bool match_fullpath, - bool return_fullpath, - long limit); - - + regex_t compiled_pattern; + + bool regexp_filter (const string &str) { + return regexec (&compiled_pattern, str.c_str(), 0, 0, 0) == 0; + } + + vector<string *> *run_scan (const string &dirpath, + bool (PathScanner::*mfilter) (const string &), + bool (*filter)(const string &, void *), + void *arg, + bool match_fullpath, + bool return_fullpath, + long limit, + bool recurse = false); + + vector<string *> *run_scan_internal (vector<string*>*, + const string &dirpath, + bool (PathScanner::*mfilter) (const string &), + bool (*filter)(const string &, void *), + void *arg, + bool match_fullpath, + bool return_fullpath, + long limit, + bool recurse = false); }; #endif // __libmisc_pathscanner_h__ |