From 46165dbccfda35428aa106f5f2037cf27a5dadf0 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 22 May 2014 13:11:59 +0200 Subject: [PATCH] Make sort order for Utility::{Glob,GlobRecursive} deterministic. Fixes #5854 --- lib/base/utility.cpp | 100 ++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 98b79dcfb..c11a43e09 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -450,6 +450,8 @@ String Utility::NewUniqueID(void) */ bool Utility::Glob(const String& pathSpec, const boost::function& callback, int type) { + std::vector files, dirs; + #ifdef _WIN32 HANDLE handle; WIN32_FIND_DATA wfd; @@ -472,13 +474,12 @@ bool Utility::Glob(const String& pathSpec, const boost::function& callback, int type) { + std::vector files, dirs, alldirs; + #ifdef _WIN32 HANDLE handle; WIN32_FIND_DATA wfd; @@ -573,18 +581,16 @@ bool Utility::GlobRecursive(const String& path, const String& pattern, const boo String cpath = path + "/" + wfd.cFileName; if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - GlobRecursive(cpath, pattern, callback, type); - - if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !(type & GlobDirectory)) - continue; - - if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !(type & GlobFile)) - continue; + alldirs.push_back(cpath); if (!Utility::Match(pattern, wfd.cFileName)) continue; - callback(cpath); + if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (type & GlobFile)) + files.push_back(cpath); + + if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (type & GlobDirectory)) + dirs.push_back(cpath); } while (FindNextFile(handle, &wfd)); if (!FindClose(handle)) { @@ -625,44 +631,40 @@ bool Utility::GlobRecursive(const String& path, const String& pattern, const boo struct stat statbuf; - if (lstat(cpath.CStr(), &statbuf) < 0) { - closedir(dirp); - - BOOST_THROW_EXCEPTION(posix_error() - << boost::errinfo_api_function("lstat") - << boost::errinfo_errno(errno) - << boost::errinfo_file_name(cpath)); - } + if (lstat(cpath.CStr(), &statbuf) < 0) + continue; if (S_ISDIR(statbuf.st_mode)) - GlobRecursive(cpath, pattern, callback, type); + alldirs.push_back(cpath); - if (stat(cpath.CStr(), &statbuf) < 0) { - closedir(dirp); + if (!Utility::Match(pattern, ent.d_name)) + continue; - BOOST_THROW_EXCEPTION(posix_error() - << boost::errinfo_api_function("stat") - << boost::errinfo_errno(errno) - << boost::errinfo_file_name(cpath)); - } + if (S_ISDIR(statbuf.st_mode) && (type & GlobDirectory)) + dirs.push_back(cpath); - if (!S_ISDIR(statbuf.st_mode) && !S_ISREG(statbuf.st_mode)) - continue; + if (!S_ISDIR(statbuf.st_mode) && (type & GlobFile)) + files.push_back(cpath); + } - if (S_ISDIR(statbuf.st_mode) && !(type & GlobDirectory)) - continue; + closedir(dirp); - if (!S_ISDIR(statbuf.st_mode) && !(type & GlobFile)) - continue; +#endif /* _WIN32 */ - if (!Utility::Match(pattern, ent.d_name)) - continue; + std::sort(files.begin(), files.end()); + BOOST_FOREACH(const String& cpath, files) { + callback(cpath); + } + std::sort(dirs.begin(), dirs.end()); + BOOST_FOREACH(const String& cpath, dirs) { callback(cpath); } - closedir(dirp); -#endif /* _WIN32 */ + std::sort(alldirs.begin(), alldirs.end()); + BOOST_FOREACH(const String& cpath, alldirs) { + GlobRecursive(cpath, pattern, callback, type); + } return true; } -- 2.40.0