CodeCompass
139 строк · 3.2 Кб
1#include <parser/pluginhandler.h>2
3#include <boost/filesystem.hpp>4#include <boost/program_options.hpp>5
6#include <util/logutil.h>7
8namespace fs = ::boost::filesystem;9
10namespace
11{
12/**13* This function returns the real plugin name from path by removing the
14* file extension and the `lib` prefix.
15*/
16std::string getPluginName(const boost::filesystem::path& path_)17{18// Filename without extension.19std::string filename = path_.stem().string();20// Remove "lib" from filename.21filename.erase(filename.begin(), filename.begin() + 3);22
23return filename;24}25}
26
27namespace cc28{
29namespace parser30{
31
32PluginHandler::PluginHandler(const std::string& pluginDir_)33: _pluginDir(pluginDir_)34{
35if (!fs::exists(_pluginDir) || !fs::is_directory(_pluginDir))36throw std::runtime_error(_pluginDir + " is not a directory!");37}
38
39void PluginHandler::loadPlugins(std::vector<std::string>& skipParserList_)40{
41fs::directory_iterator endIter;42for (fs::directory_iterator dirIter(_pluginDir);43dirIter != endIter;44++dirIter)45{46if (fs::is_regular_file(dirIter->status()) &&47fs::extension(*dirIter) == util::DynamicLibrary::extension())48{49std::string filename = getPluginName(dirIter->path());50
51if (std::find(skipParserList_.begin(), skipParserList_.end(), filename) ==52skipParserList_.end())53{54std::string dynamicLibraryPath = dirIter->path().string();55_dynamicLibraries[filename] = util::DynamicLibraryPtr(56new util::DynamicLibrary(dynamicLibraryPath));57}58else59{60LOG(info) << "[" << filename << "] skipped!";61}62}63}64}
65
66std::vector<std::string> PluginHandler::getLoadedPluginNames() const67{
68std::vector<std::string> plugins;69
70for (const auto& lib : _dynamicLibraries)71{72plugins.push_back(lib.first);73}74
75return plugins;76}
77
78std::vector<std::string> PluginHandler::getPluginNames() const79{
80std::vector<std::string> plugins;81
82fs::directory_iterator endIter;83for (fs::directory_iterator dirIter(_pluginDir);84dirIter != endIter;85++dirIter)86{87if (fs::is_regular_file(dirIter->status()) &&88fs::extension(*dirIter) == util::DynamicLibrary::extension())89{90plugins.push_back(getPluginName(dirIter->path()));91}92}93
94return plugins;95}
96
97bool PluginHandler::createPlugins(ParserContext& ctx_)98{
99for (const auto& lib : _dynamicLibraries)100{101typedef std::shared_ptr<AbstractParser> (*makeParser)(ParserContext& _ctx);102auto make = reinterpret_cast<makeParser>(lib.second->getSymbol("make"));103std::shared_ptr<AbstractParser> parser = make(ctx_);104_parsers[lib.first] = parser;105}106return true;107}
108
109boost::program_options::options_description PluginHandler::getOptions() const110{
111namespace po = ::boost::program_options;112
113po::options_description desc("Options of plugins");114for (const auto& lib : _dynamicLibraries)115{116typedef po::options_description (*GetOptsFuncPtr)();117
118GetOptsFuncPtr getOptions = reinterpret_cast<GetOptsFuncPtr>(119lib.second->getSymbol("getOptions"));120
121desc.add(getOptions());122}123
124return desc;125}
126
127std::shared_ptr<AbstractParser>& PluginHandler::getParser(128const std::string& parserName_)129{
130return _parsers.at(parserName_);131}
132
133PluginHandler::~PluginHandler()134{
135_parsers.clear();136}
137
138}
139}
140