00001
00002 #include "Rivet/AnalysisLoader.hh"
00003 #include "Rivet/Tools/Utils.hh"
00004 #include "osdir.hh"
00005 #include <dlfcn.h>
00006
00007 namespace Rivet {
00008
00009 bool AnalysisLoader::_loaded = false;
00010 AnalysisBuilders AnalysisLoader::_analysisbuilders;
00011 set<void*> AnalysisLoader::_handles;
00012
00013
00014 set<string> AnalysisLoader::getAllAnalysisNames() {
00015 if (!_loaded) loadAnalyses();
00016 set<string> names;
00017 for (AnalysisBuilders::const_iterator ab = _analysisbuilders.begin();
00018 ab != _analysisbuilders.end(); ++ab) {
00019 names.insert(ab->first);
00020 }
00021 return names;
00022 }
00023
00024
00025 Analysis* AnalysisLoader::getAnalysis(const string& analysisname) {
00026 if (!_loaded) loadAnalyses();
00027 AnalysisBuilders::iterator ab = _analysisbuilders.find(toUpper(analysisname));
00028 if (ab != _analysisbuilders.end()) {
00029 return ab->second();
00030 } else {
00031 return 0;
00032 }
00033 }
00034
00035
00036 set<Analysis*> AnalysisLoader::getAllAnalyses() {
00037 if (!_loaded) loadAnalyses();
00038 set<Analysis*> analyses;
00039 const set<string> names = getAllAnalysisNames();
00040 for (set<string>::const_iterator n = names.begin(); n != names.end(); ++n) {
00041 analyses.insert(getAnalysis(*n));
00042 }
00043 return analyses;
00044 }
00045
00046
00047 AnalysisBuilders& AnalysisLoader::loadAnalysisBuildersFromFile(const string& filename, AnalysisBuilders& builders) {
00048 void* handle = dlopen((filename).c_str(), RTLD_LAZY);
00049 if (!handle) {
00050 cerr << "Cannot open " << filename << ": " << dlerror() << endl;
00051 return builders;
00052 } else {
00053
00054 _handles.insert(handle);
00055 }
00056
00057
00058 anabuilders_fn getBuilders = (anabuilders_fn) dlsym(handle, "getAnalysisBuilders");
00059 if (!getBuilders) {
00060
00061 dlclose(handle);
00062 return builders;
00063 }
00064
00065
00066 AnalysisBuilders mybuilders = getBuilders();
00067
00068 for (AnalysisBuilders::iterator b = mybuilders.begin(); b != mybuilders.end(); ++b) {
00069 builders[b->first] = b->second;
00070 }
00071
00072 return builders;
00073 }
00074
00075
00076 void AnalysisLoader::closeAnalysisBuilders() {
00077 for (set<void*>::iterator h = _handles.begin(); h != _handles.end(); ++h) {
00078 if (*h) dlclose(*h);
00079 _handles.erase(*h);
00080 }
00081 }
00082
00083
00084 AnalysisBuilders& AnalysisLoader::loadAnalysisBuildersFromDir(const string& dirname, AnalysisBuilders& builders) {
00085 set<string> libfiles;
00086 oslink::directory dir(dirname);
00087 while (dir) {
00088 string filename = dir.next();
00089
00090
00091
00092 #define SYSDSO string(".so")
00093 size_t posn = filename.find(SYSDSO);
00094 if (posn == string::npos || posn != filename.length()-SYSDSO.length()) continue;
00095 if (filename.find("Rivet") == string::npos) continue;
00096
00097 libfiles.insert(filename);
00098 }
00099
00100 for (set<string>::const_iterator l = libfiles.begin(); l != libfiles.end(); ++l) {
00101
00102
00103 loadAnalysisBuildersFromFile(dirname + "/" + *l, builders);
00104 }
00105
00106 return builders;
00107 }
00108
00109
00110 AnalysisBuilders& AnalysisLoader::loadAnalysisBuildersFromDirs(const vector<string>& dirnames, AnalysisBuilders& builders) {
00111 for (vector<string>::const_iterator d = dirnames.begin(); d != dirnames.end(); ++d) {
00112 loadAnalysisBuildersFromDir(*d, builders);
00113 }
00114 return builders;
00115 }
00116
00117
00118 void AnalysisLoader::loadAnalyses() {
00119 vector<string> dirs;
00120 char* env = 0;
00121
00122
00123 dirs.push_back(getInstalledLibPath());
00124
00125
00126 env = getenv("RIVET_ANALYSIS_PATH");
00127 if (env) dirs += split(env);
00128
00129
00130 env = getenv("LD_LIBRARY_PATH");
00131 if (env) dirs += split(env);
00132
00133
00134 dirs.push_back(".");
00135
00136
00137 loadAnalysisBuildersFromDirs(dirs, _analysisbuilders);
00138 _loaded = true;
00139 }
00140
00141
00142 }