Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:28

0001 // Plugins.h is a part of the PYTHIA event generator.
0002 // Copyright (C) 2024 Philip Ilten, Manuel Szewc, and Torbjorn Sjostrand.
0003 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
0004 // Please respect the MCnet Guidelines, see GUIDELINES for details.
0005 
0006 // Header file for the runtime loading of plugins.
0007 
0008 #ifndef Pythia8_Plugins_H
0009 #define Pythia8_Plugins_H
0010 
0011 #include "Pythia8/Pythia.h"
0012 
0013 // Allow the use of dlopen without warnings for some GCC versions.
0014 #if defined (__GNUC__) && ((__GNUC__ + 0) < 5)
0015 #pragma GCC system_header
0016 #endif
0017 
0018 namespace Pythia8 {
0019 
0020 //==========================================================================
0021 
0022 // Demangle a symbol name, if the necessary demangling libraries are present.
0023 
0024 string demangle(string name);
0025 
0026 //==========================================================================
0027 
0028 // Determine a plugin type.
0029 
0030 string type_plugin(string libName, string className,
0031   Logger* loggerPtr = nullptr);
0032 
0033 //==========================================================================
0034 
0035 // Load a plugin library with dlopen.
0036 
0037 shared_ptr<void> dlopen_plugin(string libName, Logger* loggerPtr);
0038 
0039 //==========================================================================
0040 
0041 // Load a symbol from a plugin library.
0042 
0043 template <typename T> function<T> dlsym_plugin(void* libPtr, string symbol) {
0044   return (T*)dlsym(libPtr, symbol.c_str());}
0045 
0046 template <typename T> function<T> dlsym_plugin(shared_ptr<void> libPtr,
0047   string symbol) {
0048   return (T*)dlsym( static_cast<void*>(libPtr.get()), symbol.c_str());}
0049 
0050 //==========================================================================
0051 
0052 // Load a plugin, given a full set of arguments.
0053 
0054 template <typename T> shared_ptr<T> make_plugin(
0055   string libName, string className, Pythia* pythiaPtr,
0056   Settings* settingsPtr, Logger* loggerPtr) {
0057 
0058   // Set up the available pointers.
0059   if (loggerPtr == nullptr && pythiaPtr != nullptr)
0060     loggerPtr = &pythiaPtr->logger;
0061   if (settingsPtr == nullptr && pythiaPtr != nullptr)
0062     settingsPtr = &pythiaPtr->settings;
0063 
0064   // Load the library.
0065   shared_ptr<void> libPtr = dlopen_plugin(libName, loggerPtr);
0066   if (libPtr == nullptr) return shared_ptr<T>(nullptr);
0067 
0068   // Check the plugin object type.
0069   string objType = type_plugin(libName, className, loggerPtr);
0070   if (objType != typeid(T).name()) {
0071     string msg = "class " + className + " from library " + libName +
0072       " must be loaded as type " + demangle(objType);
0073     if (loggerPtr != nullptr) loggerPtr->errorMsg("make_plugin", msg);
0074     else cout << msg << "\n";
0075     return shared_ptr<T>(nullptr);
0076   }
0077 
0078   // Check the pointers required by the plugin object.
0079   for (string ptr : {"PYTHIA", "SETTINGS", "LOGGER"}) {
0080     auto ptrsObject =
0081       dlsym_plugin<bool()>(libPtr, "REQUIRE_" + ptr + "_" + className);
0082     if (dlerror() != nullptr) continue;
0083     if (!ptrsObject()) continue;
0084     if (ptr == "PYTHIA" && pythiaPtr != nullptr) continue;
0085     if (ptr == "SETTINGS" && settingsPtr != nullptr) continue;
0086     if (ptr == "LOGGER" && loggerPtr != nullptr) continue;
0087     string msg = "class " + className + " requires a " + ptr + " pointer";
0088     if (loggerPtr != nullptr) loggerPtr->errorMsg("make_plugin", msg);
0089     else cout << msg << "\n";
0090     return shared_ptr<T>(nullptr);
0091   }
0092 
0093   // Load the symbol to construct the plugin object.
0094   auto newObject =
0095     dlsym_plugin<T*(Pythia*, Settings*, Logger*)>(libPtr, "NEW_" + className);
0096   const char* error = dlerror();
0097   if (error != nullptr) {
0098     string msg = "class " + className + " not available from library " +
0099       libName;
0100     if (loggerPtr != nullptr) loggerPtr->errorMsg("make_plugin", msg);
0101     else cout << msg << "\n";
0102     return shared_ptr<T>(nullptr);
0103   }
0104 
0105   // Construct the plugin object shared pointer.
0106   return shared_ptr<T>(
0107     newObject(pythiaPtr, settingsPtr, loggerPtr),
0108     // Use a custom destructor.
0109     [libPtr, className](T* objectPtr) {
0110 
0111       // Destroy the plugin object.
0112       auto deleteObject =
0113         dlsym_plugin<void(T*)>(libPtr, "DELETE_" + className);
0114       if (dlerror() == nullptr && deleteObject != nullptr)
0115         deleteObject(objectPtr);});
0116 
0117 }
0118 
0119 //==========================================================================
0120 
0121 // Load a plugin, given no pointers.
0122 
0123 template <typename T> shared_ptr<T> make_plugin(
0124   string libName, string className) {return make_plugin<T>(
0125     libName, className, nullptr, nullptr, nullptr);}
0126 
0127 //==========================================================================
0128 
0129 // Load a plugin, given a Pythia pointer.
0130 template <typename T> shared_ptr<T> make_plugin(
0131   string libName, string className, Pythia* pythiaPtr) {
0132   return make_plugin<T>(
0133     libName, className, pythiaPtr, nullptr, nullptr);}
0134 
0135 //==========================================================================
0136 
0137 // Load a plugin, given a Pythia pointer and command vector pointer.
0138 
0139 template <typename T> shared_ptr<T> make_plugin(
0140   string libName, string className, Pythia* pythiaPtr,
0141   const vector<string>& cmnds) {
0142   pythiaPtr->settings.registerPluginLibrary(libName);
0143   for (string cmnd : cmnds) pythiaPtr->readString(cmnd);
0144   return make_plugin<T>(libName, className, pythiaPtr);
0145 }
0146 
0147 //==========================================================================
0148 
0149 // Load a plugin, given a Pythia pointer, command file, and subrun.
0150 
0151 template <typename T> shared_ptr<T> make_plugin(
0152   string libName, string className, Pythia* pythiaPtr,
0153   string fileName, int subrun = SUBRUNDEFAULT) {
0154   pythiaPtr->settings.registerPluginLibrary(libName);
0155   if (fileName != "") pythiaPtr->readFile(fileName, subrun);
0156   return make_plugin<T>(libName, className, pythiaPtr);
0157 }
0158 
0159 //==========================================================================
0160 
0161 // Macro to declare a plugin class.
0162 
0163 #define PYTHIA8_PLUGIN_CLASS(BASE, CLASS, PYTHIA, SETTINGS, LOGGER) \
0164   extern "C" {                                                      \
0165     bool REQUIRE_PYTHIA_##CLASS() {return PYTHIA;}                  \
0166     bool REQUIRE_SETTINGS_##CLASS() {return SETTINGS;}              \
0167     bool REQUIRE_LOGGER_##CLASS() {return LOGGER;}                  \
0168     const char* TYPE_##CLASS() {return typeid(BASE).name();}        \
0169     CLASS* NEW_##CLASS(Pythia* pythiaPtr, Settings* settingsPtr,    \
0170       Logger* loggerPtr) {                                          \
0171       return new CLASS(pythiaPtr, settingsPtr, loggerPtr);}         \
0172     void DELETE_##CLASS(CLASS* ptr) {delete ptr;}}
0173 
0174 //==========================================================================
0175 
0176 // Macro to register settings for a plugin library.
0177 
0178 #define PYTHIA8_PLUGIN_SETTINGS(METHOD) \
0179   extern "C" {                          \
0180     void REGISTER_SETTINGS(Settings* settingsPtr) {METHOD(settingsPtr);}}
0181 
0182 //==========================================================================
0183 
0184 // Macro to register an XML settings index file.
0185 
0186 #define PYTHIA8_PLUGIN_XML(INDEX) \
0187   extern "C" {const char* RETURN_XML() {return INDEX;}}
0188 
0189 //==========================================================================
0190 
0191 // Macro to return compatible Pythia versions and the compiled version.
0192 
0193 #define PYTHIA8_PLUGIN_VERSIONS(...)                                       \
0194   extern "C" {                                                             \
0195     bool CHECK_COMPATIBLE_VERSION(int ver) {set<int> vers = {__VA_ARGS__}; \
0196       return vers.find(ver) != vers.end();}                                \
0197     bool CHECK_COMPILED_VERSION(int ver) {                                 \
0198       return ver == PYTHIA_VERSION_INTEGER;}}
0199 
0200 //==========================================================================
0201 
0202 } // end namespace Pythia8
0203 
0204 #endif // Pythia8_Plugins_H