Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:59

0001 /*****************************************************************************\
0002 * (c) Copyright 2013 CERN                                                     *
0003 *                                                                             *
0004 * This software is distributed under the terms of the GNU General Public      *
0005 * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENCE".   *
0006 *                                                                             *
0007 * In applying this licence, CERN does not waive the privileges and immunities *
0008 * granted to it by virtue of its status as an Intergovernmental Organization  *
0009 * or submit itself to any jurisdiction.                                       *
0010 \*****************************************************************************/
0011 
0012 /// @author Marco Clemencic <marco.clemencic@cern.ch>
0013 
0014 #include <cstdlib>
0015 #include <fstream>
0016 #include <iostream>
0017 #include <list>
0018 #include <memory>
0019 #include <set>
0020 #include <string>
0021 
0022 #include <dlfcn.h>
0023 #include <getopt.h>
0024 
0025 #define GAUDI_PLUGIN_SERVICE_V2
0026 #include <Gaudi/PluginService.h>
0027 #include <Gaudi/PluginServiceV1.h>
0028 
0029 void help( std::string argv0 ) {
0030   std::cout << "Usage: " << argv0
0031             << " [option] library1 [library2 ...]\n"
0032                "\n list the component factories present in the given libraries\n\n"
0033                "Options:\n\n"
0034                "  -h, --help       show this help message and exit\n"
0035                "  -o OUTPUT, --output OUTPUT\n"
0036                "                   write the list of factories on the file OUTPUT, use - for\n"
0037                "                   standard output (default)\n"
0038             << std::endl;
0039 }
0040 
0041 void usage( std::string argv0 ) {
0042   std::cout << "Usage: " << argv0
0043             << " [option] library1 [library2 ...]\n"
0044                "Try `"
0045             << argv0 << " -h' for more information.\n"
0046             << std::endl;
0047 }
0048 
0049 int main( int argc, char* argv[] ) {
0050   auto& reg2 = Gaudi::PluginService::v2::Details::Registry::instance();
0051   auto& reg1 = Gaudi::PluginService::v1::Details::Registry::instance();
0052 
0053   using key_type = Gaudi::PluginService::v2::Details::Registry::KeyType;
0054 
0055   // cache to keep track of the loaded factories
0056   std::map<key_type, std::string> loaded;
0057   // initialize the local cache
0058   for ( const auto& name : reg2.loadedFactoryNames() ) loaded.emplace( name, "<preloaded>" );
0059   for ( const auto& name : reg1.loadedFactoryNames() ) loaded.emplace( name, "<preloaded>" );
0060 
0061   // Parse command line
0062   std::list<char*> libs;
0063   std::string      output_opt( "-" );
0064   {
0065     std::string argv0( argv[0] );
0066     {
0067       auto i = argv0.rfind( '/' );
0068       if ( i != std::string::npos ) argv0 = argv0.substr( i + 1 );
0069     }
0070 
0071     int i = 1;
0072     while ( i < argc ) {
0073       const std::string arg( argv[i] );
0074       if ( arg == "-o" || arg == "--output" ) {
0075         if ( ++i < argc ) {
0076           output_opt = argv[i];
0077         } else {
0078           std::cerr << "ERROR: missing argument for option " << arg << std::endl;
0079           std::cerr << "See `" << argv0 << " -h' for more details." << std::endl;
0080           return EXIT_FAILURE;
0081         }
0082       } else if ( arg == "-h" || arg == "--help" ) {
0083         help( argv0 );
0084         return EXIT_SUCCESS;
0085       } else {
0086         libs.push_back( argv[i] );
0087       }
0088       ++i;
0089     }
0090     if ( libs.empty() ) {
0091       usage( std::move(argv0) );
0092       return EXIT_FAILURE;
0093     }
0094   }
0095 
0096   // handle output option
0097   std::unique_ptr<std::ostream> output_file;
0098   if ( output_opt != "-" ) { output_file.reset( new std::ofstream{output_opt} ); }
0099   std::ostream& output = ( output_file ? *output_file : std::cout );
0100 
0101   auto dump_from = [&output, &loaded]( auto& reg, const char* lib, const char* prefix ) {
0102     for ( const auto& factoryName : reg.loadedFactoryNames() ) {
0103       auto f = loaded.find( factoryName );
0104       if ( f == loaded.end() ) {
0105         output << prefix << "::" << lib << ":" << factoryName << std::endl;
0106         loaded.emplace( factoryName, lib );
0107       } else
0108         std::cerr << "WARNING: factory '" << factoryName << "' already found in " << f->second << std::endl;
0109     }
0110   };
0111 
0112   // loop over the list of libraries passed on the command line
0113   for ( const char* aLib : libs ) {
0114     if ( dlopen( aLib, RTLD_LAZY | RTLD_LOCAL ) ) {
0115       dump_from( reg2, aLib, "v2" );
0116       dump_from( reg1, aLib, "v1" );
0117     } else {
0118       std::cerr << "ERROR: failed to load " << aLib << ": " << dlerror() << std::endl;
0119       return EXIT_FAILURE;
0120     }
0121   }
0122   return EXIT_SUCCESS;
0123 }