aboutsummaryrefslogtreecommitdiff
path: root/fileutil.cc
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-07-05 15:48:28 +0900
committerShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-07-05 15:48:28 +0900
commit0e3873a2bed37cc4668919184cf338af80740cc5 (patch)
tree150e6bcac7e4ff6f0c271797603a050f7c9c40f2 /fileutil.cc
parent0541651e3e8196e2847374b3e30e42b42f5d44bc (diff)
downloadkati-0e3873a2bed37cc4668919184cf338af80740cc5.tar.gz
[C++] Fix wildcard_cache.mk
Diffstat (limited to 'fileutil.cc')
-rw-r--r--fileutil.cc43
1 files changed, 43 insertions, 0 deletions
diff --git a/fileutil.cc b/fileutil.cc
index 9a686e5..eb4fc22 100644
--- a/fileutil.cc
+++ b/fileutil.cc
@@ -17,12 +17,15 @@
#include "fileutil.h"
#include <errno.h>
+#include <glob.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <unordered_map>
+
#include "log.h"
bool Exists(StringPiece filename) {
@@ -91,3 +94,43 @@ int RunCommand(const string& shell, const string& cmd, bool redirect_stderr,
}
abort();
}
+
+namespace {
+
+class GlobCache {
+ public:
+ ~GlobCache() {
+ for (auto& p : cache_) {
+ delete p.second;
+ }
+ }
+
+ void Get(const char* pat, vector<string>** files) {
+ auto p = cache_.emplace(pat, nullptr);
+ if (p.second) {
+ vector<string>* files = p.first->second = new vector<string>;
+ if (strcspn(pat, "?*[\\") != strlen(pat)) {
+ glob_t gl;
+ glob(pat, GLOB_NOSORT, NULL, &gl);
+ for (size_t i = 0; i < gl.gl_pathc; i++) {
+ files->push_back(gl.gl_pathv[i]);
+ }
+ globfree(&gl);
+ } else {
+ if (Exists(pat))
+ files->push_back(pat);
+ }
+ }
+ *files = p.first->second;
+ }
+
+ private:
+ unordered_map<string, vector<string>*> cache_;
+};
+
+} // namespace
+
+void Glob(const char* pat, vector<string>** files) {
+ static GlobCache gc;
+ gc.Get(pat, files);
+}