From a49d5bf648e060d413b98a6f93d178fb8b64b2fd Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Tue, 14 Sep 2010 15:23:23 +0200 Subject: [PATCH] portable directory traversal --- include/mitsuba/core/plugin.h | 9 ++- src/libcore/plugin.cpp | 18 +++--- src/mitsuba/mtsutil.cpp | 118 ++++++++++++++-------------------- 3 files changed, 65 insertions(+), 80 deletions(-) diff --git a/include/mitsuba/core/plugin.h b/include/mitsuba/core/plugin.h index 28cd1fcd..ea93de5f 100644 --- a/include/mitsuba/core/plugin.h +++ b/include/mitsuba/core/plugin.h @@ -20,6 +20,9 @@ #define __PLUGIN_H #include +#include + +namespace fs = boost::filesystem; MTS_NAMESPACE_BEGIN @@ -36,7 +39,7 @@ class MTS_EXPORT_CORE Plugin { typedef char *(*GetDescriptionFunc)(); public: /// Load a plugin from the supplied path - Plugin(const std::string &shortName, const std::string &path); + Plugin(const std::string &shortName, const fs::path &path); /// Virtual destructor virtual ~Plugin(); @@ -54,7 +57,7 @@ public: std::string getDescription() const; /// Return the path of this plugin - inline const std::string &getPath() const { return m_path; } + inline const fs::path &getPath() const { return m_path; } /// Return a short name of this plugin inline const std::string &getShortName() const { return m_shortName; } @@ -68,7 +71,7 @@ private: void *m_handle; #endif std::string m_shortName; - std::string m_path; + fs::path m_path; bool m_isUtility; GetDescriptionFunc m_getDescription; CreateInstanceFunc m_createInstance; diff --git a/src/libcore/plugin.cpp b/src/libcore/plugin.cpp index e13ccff4..fc3410ee 100644 --- a/src/libcore/plugin.cpp +++ b/src/libcore/plugin.cpp @@ -33,19 +33,19 @@ MTS_NAMESPACE_BEGIN // Abstract plugin module implementation // ----------------------------------------------------------------------- -Plugin::Plugin(const std::string &shortName, const std::string &path) +Plugin::Plugin(const std::string &shortName, const fs::path &path) : m_shortName(shortName), m_path(path) { #if defined(WIN32) - m_handle = LoadLibrary(path.c_str()); + m_handle = LoadLibrary(path.file_string().c_str()); if (!m_handle) { - SLog(EError, "Error while loading plugin \"%s\": %s", m_path.c_str(), - lastErrorText().c_str()); + SLog(EError, "Error while loading plugin \"%s\": %s", + m_path.file_string().c_str(), lastErrorText().c_str()); } #else - m_handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL); + m_handle = dlopen(path.file_string().c_str(), RTLD_LAZY | RTLD_LOCAL); if (!m_handle) { - SLog(EError, "Error while loading plugin \"%s\": %s", m_path.c_str(), - dlerror()); + SLog(EError, "Error while loading plugin \"%s\": %s", + m_path.file_string().c_str(), dlerror()); } #endif try { @@ -80,13 +80,13 @@ void *Plugin::getSymbol(const std::string &sym) { void *data = GetProcAddress(m_handle, sym.c_str()); if (!data) { SLog(EError, "Could not resolve symbol \"%s\" in \"%s\": %s", - sym.c_str(), m_path.c_str(), lastErrorText().c_str()); + sym.c_str(), m_path.file_string().c_str(), lastErrorText().c_str()); } #else void *data = dlsym(m_handle, sym.c_str()); if (!data) { SLog(EError, "Could not resolve symbol \"%s\" in \"%s\": %s", - sym.c_str(), m_path.c_str(), dlerror()); + sym.c_str(), m_path.file_string().c_str(), dlerror()); } #endif return data; diff --git a/src/mitsuba/mtsutil.cpp b/src/mitsuba/mtsutil.cpp index fa93d781..14e9daee 100644 --- a/src/mitsuba/mtsutil.cpp +++ b/src/mitsuba/mtsutil.cpp @@ -31,12 +31,6 @@ #include #include #include -#include - -#if !defined(WIN32) -#include -#include -#endif #if defined(WIN32) #include "getopt.h" @@ -79,36 +73,34 @@ void help() { std::set seen; for (size_t i=0; id_name); - if (!boost::ends_with(fname, ".dylib") && !boost::ends_with(fname, ".so")) + for (; it != end; ++it) { + if (!fs::is_regular_file(it->status())) + continue; + std::string extension(boost::to_lower_copy(it->path().extension())); +#if defined(WIN32) + if (extension != ".dll") + continue; +#elif defined(__OSX__) + if (extension != ".dylib") + continue; +#elif defined(__LINUX__) + if (extension != ".so") continue; - std::string fullName = dirPath + "/" + fname; #else - HANDLE hFind; - WIN32_FIND_DATA findFileData; - - if ((hFind = FindFirstFile((dirPath + "\\*.dll").c_str(), &findFileData)) == INVALID_HANDLE_VALUE) - SLog(EInfo, "Could not open plugin directory"); - - do { - std::string fname = findFileData.cFileName; - std::string fullName = dirPath + "\\" + fname; +#error Unknown operating system! #endif - std::string shortName = fname.substr(0, strrchr(fname.c_str(), '.') - fname.c_str()); + std::string shortName = it->path().stem(); if (seen.find(shortName) != seen.end()) continue; seen.insert(shortName); - Plugin utility(shortName, fullName); + Plugin utility(shortName, it->path()); if (!utility.isUtility()) continue; if (boost::starts_with(shortName, "test_")) { @@ -122,13 +114,7 @@ void help() { utilities << ' '; utilities << utility.getDescription() << endl; } -#if !defined(WIN32) } - closedir(directory); -#else - } while (FindNextFile(hFind, &findFileData)); - FindClose(hFind); -#endif } cout << testcases.str() << utilities.str(); @@ -275,43 +261,41 @@ int ubi_main(int argc, char **argv) { std::vector dirPaths = fileResolver->resolveAll("plugins"); std::set seen; int executed = 0, succeeded = 0; - + for (size_t i=0; id_name); - if (!boost::ends_with(fname, ".dylib") && !boost::ends_with(fname, ".so")) + for (; it != end; ++it) { + if (!fs::is_regular_file(it->status())) + continue; + std::string extension(boost::to_lower_copy(it->path().extension())); +#if defined(WIN32) + if (extension != ".dll") + continue; +#elif defined(__OSX__) + if (extension != ".dylib") + continue; +#elif defined(__LINUX__) + if (extension != ".so") continue; - std::string fullName = dirPath + "/" + fname; #else - HANDLE hFind; - WIN32_FIND_DATA findFileData; - - if ((hFind = FindFirstFile((dirPath + "\\*.dll").c_str(), &findFileData)) == INVALID_HANDLE_VALUE) - SLog(EInfo, "Could not open plugin directory"); - - do { - std::string fname = findFileData.cFileName; - std::string fullName = dirPath + "\\" + fname; +#error Unknown operating system! #endif - std::string shortName = fname.substr(0, strrchr(fname.c_str(), '.') - fname.c_str()); - if (!boost::starts_with(shortName, "test_") || seen.find(shortName) != seen.end()) + std::string shortName = it->path().stem(); + if (seen.find(shortName) != seen.end() || !boost::starts_with(shortName, "test_")) continue; seen.insert(shortName); - Plugin plugin(shortName, fullName); + Plugin plugin(shortName, it->path()); if (!plugin.isUtility()) continue; ref utility = plugin.createUtility(); - + TestCase *testCase = static_cast(utility.get()); if (!utility->getClass()->derivesFrom(TestCase::m_theClass)) SLog(EError, "This is not a test case!"); @@ -321,13 +305,7 @@ int ubi_main(int argc, char **argv) { executed += testCase->getExecuted(); succeeded += testCase->getSucceeded(); -#if !defined(WIN32) } - closedir(directory); -#else - } while (FindNextFile(hFind, &findFileData)); - FindClose(hFind); -#endif } SLog(EInfo, "Ran %i tests, %i succeeded, %i failed.", executed, succeeded, executed-succeeded); @@ -336,22 +314,26 @@ int ubi_main(int argc, char **argv) { std::cerr << "A utility name must be supplied!" << endl; return -1; } + fs::path pluginName(argv[optind]); /* Build the full plugin file name */ #if defined(WIN32) - std::string shortName = std::string("plugins/") + argv[optind] + std::string(".dll"); + pluginName.replace_extension(".dll"); #elif defined(__OSX__) - std::string shortName = std::string("plugins/") + argv[optind] + std::string(".dylib"); + pluginName.replace_extension(".dylib"); +#elif defined(__LINUX__) + pluginName.replace_extension(".so"); #else - std::string shortName = std::string("plugins/") + argv[optind] + std::string(".so"); +#error Unknown operating system! #endif - std::string fullName = fileResolver->resolve(shortName).file_string(); + fs::path fullName = fileResolver->resolve(fs::path("plugins") / pluginName); if (!fs::exists(fullName)) { /* Plugin not found! */ SLog(EError, "Utility \"%s\" not found (run \"mtsutil\" without arguments to " - "see a list of available utilities)", fullName.c_str()); + "see a list of available utilities)", fullName.file_string().c_str()); } + SLog(EInfo, "Loading utility \"%s\" ..", argv[optind]); Plugin *plugin = new Plugin(argv[optind], fullName); if (!plugin->isUtility())