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 vector<string> dirs;
00072 char* env = 0;
00073 env = getenv("RIVET_ANALYSIS_PATH");
00074 if (env) {
00075
00076 dirs += split(env);
00077 } else {
00078
00079 dirs += getLibPath();
00080 }
00081
00082
00083 const string libsuffix = ".so";
00084 vector<string> pluginfiles;
00085 foreach (const string& d, dirs) {
00086 if (d.empty()) continue;
00087 oslink::directory dir(d);
00088 while (dir) {
00089 string filename = dir.next();
00090
00091 if (filename.find("Rivet") != 0) continue;
00092 size_t posn = filename.find(libsuffix);
00093 if (posn == string::npos || posn != filename.length()-libsuffix.length()) continue;
00094
00095
00096 const string path = d + "/" + filename;
00097
00098 if (find(pluginfiles.begin(), pluginfiles.end(), path) == pluginfiles.end()) {
00099 pluginfiles += path;
00100 }
00101 }
00102 }
00103
00104
00105 Log::getLog("Rivet.AnalysisLoader") << Log::TRACE << "Candidate analysis plugin libs: " << pluginfiles << endl;
00106 foreach (const string& pf, pluginfiles) {
00107 Log::getLog("Rivet.AnalysisLoader") << Log::TRACE << "Trying to load plugin analyses from file " << pf << endl;
00108 void* handle = dlopen(pf.c_str(), RTLD_LAZY);
00109 if (!handle) {
00110 Log::getLog("Rivet.AnalysisLoader") << Log::WARN << "Cannot open " << pf << ": " << dlerror() << endl;
00111 continue;
00112 }
00113 }
00114 }
00115
00116
00117 }