diff options
Diffstat (limited to 'libs/pbd/pathscanner.cc')
-rw-r--r-- | libs/pbd/pathscanner.cc | 93 |
1 files changed, 61 insertions, 32 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, ":"))); |