00001
00002 #include "Rivet/AnalysisLoader.hh"
00003 #include "Rivet/Tools/Utils.hh"
00004 #include "Rivet/Tools/osdir.hh"
00005 #include "Rivet/Tools/Logging.hh"
00006 #include "Rivet/Analysis.hh"
00007 #include <dlfcn.h>
00008
00009 namespace Rivet {
00010
00011
00012
00013 AnalysisLoader::AnalysisBuilderMap AnalysisLoader::_ptrs;
00014
00015
00016 vector<string> AnalysisLoader::analysisNames() {
00017 _loadAnalysisPlugins();
00018 vector<string> names;
00019 foreach (const AnalysisBuilderMap::value_type& p, _ptrs) names += p.first;
00020 return names;
00021 }
00022
00023
00024 set<string> AnalysisLoader::getAllAnalysisNames() {
00025 set<string> anaset;
00026 vector<string> anas = analysisNames();
00027 foreach (const string &ana, anas) {
00028 anaset.insert(ana);
00029 }
00030 return anaset;
00031 }
00032
00033
00034 Analysis* AnalysisLoader::getAnalysis(const string& analysisname) {
00035 _loadAnalysisPlugins();
00036 AnalysisBuilderMap::const_iterator ai = _ptrs.find(analysisname);
00037 if (ai == _ptrs.end()) return 0;
00038 return ai->second->mkAnalysis();
00039 }
00040
00041
00042 vector<Analysis*> AnalysisLoader::getAllAnalyses() {
00043 _loadAnalysisPlugins();
00044 vector<Analysis*> analyses;
00045 foreach (const AnalysisBuilderMap::value_type& p, _ptrs) {
00046 analyses += p.second->mkAnalysis();
00047 }
00048 return analyses;
00049 }
00050
00051
00052 void AnalysisLoader::_registerBuilder(const AnalysisBuilderBase* ab) {
00053 if (!ab) return;
00054 const string name = ab->name();
00055 if (_ptrs.find(name) != _ptrs.end()) {
00056
00057
00058 Log::getLog("Rivet.AnalysisLoader") << Log::ERROR << "Tried to register a second plugin analysis called '" << name << "'" << endl;
00059 exit(1);
00060 }
00061 Log::getLog("Rivet.AnalysisLoader") << Log::TRACE << "Registering a plugin analysis called '" << name << "'" << endl;
00062 _ptrs[name] = ab;
00063 }
00064
00065
00066 void AnalysisLoader::_loadAnalysisPlugins() {
00067
00068 if (!_ptrs.empty()) return;
00069
00070
00071 const vector<string> dirs = getAnalysisLibPaths();
00072
00073
00074 const string libsuffix = ".so";
00075 vector<string> pluginfiles;
00076 foreach (const string& d, dirs) {
00077 if (d.empty()) continue;
00078 oslink::directory dir(d);
00079 while (dir) {
00080 string filename = dir.next();
00081
00082 if (filename.find("Rivet") != 0) continue;
00083 size_t posn = filename.find(libsuffix);
00084 if (posn == string::npos || posn != filename.length()-libsuffix.length()) continue;
00085
00086
00087 const string path = d + "/" + filename;
00088
00089 if (find(pluginfiles.begin(), pluginfiles.end(), path) == pluginfiles.end()) {
00090 pluginfiles += path;
00091 }
00092 }
00093 }
00094
00095
00096 Log::getLog("Rivet.AnalysisLoader") << Log::TRACE << "Candidate analysis plugin libs: " << pluginfiles << endl;
00097 foreach (const string& pf, pluginfiles) {
00098 Log::getLog("Rivet.AnalysisLoader") << Log::TRACE << "Trying to load plugin analyses from file " << pf << endl;
00099 void* handle = dlopen(pf.c_str(), RTLD_LAZY);
00100 if (!handle) {
00101 Log::getLog("Rivet.AnalysisLoader") << Log::WARN << "Cannot open " << pf << ": " << dlerror() << endl;
00102 continue;
00103 }
00104 }
00105 }
00106
00107
00108 }