portable directory traversal
parent
5253cb594c
commit
a49d5bf648
|
@ -20,6 +20,9 @@
|
|||
#define __PLUGIN_H
|
||||
|
||||
#include <mitsuba/mitsuba.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -31,12 +31,6 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined(WIN32)
|
||||
#include <dlfcn.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#if defined(WIN32)
|
||||
#include "getopt.h"
|
||||
|
@ -79,36 +73,34 @@ void help() {
|
|||
std::set<std::string> seen;
|
||||
|
||||
for (size_t i=0; i<dirPaths.size(); ++i) {
|
||||
std::string dirPath = fs::complete(dirPaths[i]).file_string();
|
||||
fs::path dirPath = fs::complete(dirPaths[i]);
|
||||
|
||||
#if !defined(WIN32)
|
||||
DIR *directory;
|
||||
struct dirent *dirinfo;
|
||||
if (!fs::exists(dirPath) || !fs::is_directory(dirPath))
|
||||
break;
|
||||
|
||||
if ((directory = opendir(dirPath.c_str())) == NULL)
|
||||
SLog(EInfo, "Could not open plugin directory");
|
||||
fs::directory_iterator end, it(dirPath);
|
||||
|
||||
while ((dirinfo = readdir(directory)) != NULL) {
|
||||
std::string fname(dirinfo->d_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<fs::path> dirPaths = fileResolver->resolveAll("plugins");
|
||||
std::set<std::string> seen;
|
||||
int executed = 0, succeeded = 0;
|
||||
|
||||
|
||||
for (size_t i=0; i<dirPaths.size(); ++i) {
|
||||
std::string dirPath = fs::complete(dirPaths[i]).file_string();
|
||||
fs::path dirPath = fs::complete(dirPaths[i]);
|
||||
|
||||
#if !defined(WIN32)
|
||||
DIR *directory;
|
||||
struct dirent *dirinfo;
|
||||
if (!fs::exists(dirPath) || !fs::is_directory(dirPath))
|
||||
break;
|
||||
|
||||
if ((directory = opendir(dirPath.c_str())) == NULL)
|
||||
SLog(EInfo, "Could not open plugin directory");
|
||||
fs::directory_iterator end, it(dirPath);
|
||||
|
||||
while ((dirinfo = readdir(directory)) != NULL) {
|
||||
std::string fname(dirinfo->d_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> utility = plugin.createUtility();
|
||||
|
||||
|
||||
TestCase *testCase = static_cast<TestCase *>(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())
|
||||
|
|
Loading…
Reference in New Issue