static void addFiles2(std::map<std::string, std::size_t> &files, const std::string &path, const std::set<std::string> &extra, bool recursive, const PathMatch& ignored ) { struct stat file_stat; if (stat(path.c_str(), &file_stat) != -1) { if ((file_stat.st_mode & S_IFMT) == S_IFDIR) { DIR * dir = opendir(path.c_str()); if (!dir) return; dirent entry; dirent * dir_result; std::string new_path; new_path.reserve(path.length() + 100);// prealloc some memory to avoid constant new/deletes in loop while ((readdir_r(dir, &entry, &dir_result) == 0) && (dir_result != NULL)) { if ((std::strcmp(dir_result->d_name, ".") == 0) || (std::strcmp(dir_result->d_name, "..") == 0)) continue; new_path = path + '/' + dir_result->d_name; if (dir_result->d_type == DT_DIR || (dir_result->d_type == DT_UNKNOWN && FileLister::isDirectory(new_path))) { if (recursive && !ignored.Match(new_path)) { addFiles2(files, new_path, extra, recursive, ignored); } } else { if (Path::acceptFile(new_path, extra) && !ignored.Match(new_path)) { files[new_path] = file_stat.st_size; } } } closedir(dir); } else files[path] = file_stat.st_size; } }
void emptymaskpath3() const { ASSERT(!emptyMatcher.Match("/home/user/code/src/")); }
void emptymaskpath2() const { ASSERT(!emptyMatcher.Match("../src/")); }
void emptymaskpath1() const { ASSERT(!emptyMatcher.Match("src/")); }
// Test empty PathMatch void emptymaskemptyfile() const { ASSERT(!emptyMatcher.Match("")); }
void filemaskpath4() const { ASSERT(!srcFooCppMatcher.Match("bar/foo.cpp")); }
void onemaskdifferentdir1() const { ASSERT(!srcMatcher.Match("srcfiles/file.txt")); }
void filemask2() const { ASSERT(fooCppMatcher.Match("../foo.cpp")); }
void onemasklongerpath3() const { ASSERT(srcMatcher.Match("project/src/module/")); }
// Test PathMatch containing "foo.cpp" void filemask1() const { ASSERT(fooCppMatcher.Match("foo.cpp")); }
void onemasklongerpath2() const { ASSERT(srcMatcher.Match("src/module/")); }
void onemasklongerpath1() const { ASSERT(srcMatcher.Match("/tmp/src/")); }
void onemaskdifferentdir4() const { ASSERT(!srcMatcher.Match("proj/mysrcfiles/file.txt")); }
// Test PathMatch containing "src/" void onemaskemptypath() const { ASSERT(!srcMatcher.Match("")); }
void filemask3() const { ASSERT(fooCppMatcher.Match("src/foo.cpp")); }
void onemasksamepath() const { ASSERT(srcMatcher.Match("src/")); }
void filemaskpath2() const { ASSERT(srcFooCppMatcher.Match("proj/src/foo.cpp")); }
void FileLister::recursiveAddFiles(std::map<std::string, std::size_t> &files, const std::string &path, const std::set<std::string> &extra, const PathMatch& ignored) { const std::string cleanedPath = Path::toNativeSeparators(path); // basedir is the base directory which is used to form pathnames. // It always has a trailing backslash available for concatenation. std::string basedir; // searchPattern is the search string passed into FindFirst and FindNext. std::string searchPattern = cleanedPath; // The user wants to check all files in a dir const bool checkAllFilesInDir = (MyIsDirectory(cleanedPath) != FALSE); if (checkAllFilesInDir) { char c = cleanedPath.back(); switch (c) { case '\\': searchPattern += '*'; basedir = cleanedPath; break; case '*': basedir = cleanedPath.substr(0, cleanedPath.length() - 1); break; default: searchPattern += "\\*"; if (cleanedPath != ".") basedir = cleanedPath + '\\'; } } else { std::string::size_type pos = cleanedPath.find_last_of('\\'); if (std::string::npos != pos) { basedir = cleanedPath.substr(0, pos + 1); } } WIN32_FIND_DATAA ffd; HANDLE hFind = MyFindFirstFile(searchPattern, &ffd); if (INVALID_HANDLE_VALUE == hFind) return; do { if (ffd.cFileName[0] == '.' || ffd.cFileName[0] == '\0') continue; const char* ansiFfd = ffd.cFileName; if (std::strchr(ansiFfd,'?')) { ansiFfd = ffd.cAlternateFileName; } const std::string fname(basedir + ansiFfd); if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { // File if ((!checkAllFilesInDir || Path::acceptFile(fname, extra)) && !ignored.Match(fname)) { const std::string nativename = Path::fromNativeSeparators(fname); // Limitation: file sizes are assumed to fit in a 'size_t' #ifdef _WIN64 files[nativename] = (static_cast<std::size_t>(ffd.nFileSizeHigh) << 32) | ffd.nFileSizeLow; #else files[nativename] = ffd.nFileSizeLow; #endif } } else { // Directory if (!ignored.Match(fname)) FileLister::recursiveAddFiles(files, fname, extra, ignored); } } while (FindNextFileA(hFind, &ffd) != FALSE); FindClose(hFind); }
void onemasksamepathwithfile() const { ASSERT(srcMatcher.Match("src/file.txt")); }