From 11cf07fa9c1c3b5acccf9f42cb48a5865757221b Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sat, 2 Feb 2013 00:28:00 +0100 Subject: [PATCH] Config: implement support for wildcard includes Fixes #2771 --- lib/base/unix.h | 1 + lib/base/utility.cpp | 56 +++++++++++++++++++++++++++++++++++ lib/base/utility.h | 2 ++ lib/config/configcompiler.cpp | 20 +++++++++++-- lib/config/configcompiler.h | 2 ++ 5 files changed, 79 insertions(+), 2 deletions(-) diff --git a/lib/base/unix.h b/lib/base/unix.h index 09453a43c..e39af513d 100644 --- a/lib/base/unix.h +++ b/lib/base/unix.h @@ -35,6 +35,7 @@ #include #include #include +#include #include typedef int SOCKET; diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index b6cec477b..2595a1d94 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -283,6 +283,9 @@ String Utility::DirName(const String& path) } result = dir; + + if (result.IsEmpty()) + result = "."; #endif /* _WIN32 */ free(dir); @@ -438,3 +441,56 @@ String Utility::NewUUID(void) return boost::lexical_cast(uuid); } +/** + * Calls the specified callback for each file matching the path specification. + * + * @param pathSpec The path specification. + */ +bool Utility::Glob(const String& pathSpec, const function& callback) +{ +#ifdef _WIN32 + HANDLE handle; + WIN32_FIND_DATA wfd; + + handle = FindFirstFile(pathSpec.CStr(), &wfd); + + if (handle == INVALID_HANDLE_VALUE) { + DWORD errorCode = GetLastError(); + + if (errorCode == ERROR_FILE_NOT_FOUND) + return false; + + throw_exception(Win32Exception("FindFirstFile() failed", errorCode)); + } + + do { + callback(wfd.cFileName); + } while (FindNextFile(handle, &wfd)); + + if (!FindClose(handle)) + throw_exception(Win32Exception("FindClose() failed", GetLastError())); + + return true; +#else /* _WIN32 */ + glob_t gr; + + int rc = glob(pathSpec.CStr(), GLOB_ERR | GLOB_NOSORT, NULL, &gr); + + if (rc < 0) { + if (rc == GLOB_NOMATCH) + return false; + + throw_exception(PosixException("glob() failed", errno)); + } + + size_t left; + char **gp; + for (gp = gr.gl_pathv, left = gr.gl_pathc; left > 0; gp++, left--) { + callback(*gp); + } + + globfree(&gr); + + return true; +#endif /* _WIN32 */ +} diff --git a/lib/base/utility.h b/lib/base/utility.h index 9dc1d4d6c..347fd18ae 100644 --- a/lib/base/utility.h +++ b/lib/base/utility.h @@ -56,6 +56,8 @@ public: static String NewUUID(void); + static bool Glob(const String& pathSpec, const function& callback); + static #ifdef _WIN32 HMODULE diff --git a/lib/config/configcompiler.cpp b/lib/config/configcompiler.cpp index 77f614fb5..fa0427726 100644 --- a/lib/config/configcompiler.cpp +++ b/lib/config/configcompiler.cpp @@ -165,6 +165,18 @@ vector ConfigCompiler::CompileText(const String& path, return CompileStream(path, &stream); } +/** + * Compiles the specified file and returns the resulting config items in the passed vector. + * + * @param path The file that should be compiled. + * @param resultItems The vector that should be used to store the config items. + */ +void ConfigCompiler::CompileFileIncludeHelper(const String& path, vector& resultItems) +{ + vector items = CompileFile(path); + std::copy(items.begin(), items.end(), std::back_inserter(resultItems)); +} + /** * Default include handler. Includes the file and returns a list of * configuration items. @@ -195,8 +207,12 @@ vector ConfigCompiler::HandleFileInclude(const String& include, } } - /* TODO: implement wildcard includes */ - return CompileFile(includePath); + vector items; + + if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFileIncludeHelper, _1, boost::ref(items)))) + throw_exception(invalid_argument("Include file '" + include + "' does not exist (or no files found for pattern).")); + + return items; } /** diff --git a/lib/config/configcompiler.h b/lib/config/configcompiler.h index 2916df72f..95e66de93 100644 --- a/lib/config/configcompiler.h +++ b/lib/config/configcompiler.h @@ -73,6 +73,8 @@ private: void InitializeScanner(void); void DestroyScanner(void); + + static void CompileFileIncludeHelper(const String& path, vector& resultItems); }; } -- 2.40.0