26 #include "boost/tokenizer.hpp" 
   28 #include "boost/algorithm/string.hpp" 
   29 #include <boost/regex.hpp> 
   32 #include "TClassEdit.h" 
   35 #include "GaudiKernel/System.h" 
   37 namespace fs = std::filesystem;
 
   40   typedef std::vector<std::string> Strings_t;
 
   41   const std::string RootMap = 
".rootmap";
 
   42   const std::string Components = 
".components";
 
   43   const std::string PluginNs= 
"__pf__";
 
   46   const std::string SHLIB_PREFIX = 
"lib";
 
   47   const std::string SHLIB_SUFFIX = 
".dll";
 
   49   const std::string SHLIB_PREFIX = 
"lib";
 
   50   const std::string SHLIB_SUFFIX = 
".so";
 
   54   bool is_rootcint_dict(
const std::string& libname)
 
   56     if (libname == 
"liblistDict.so") 
return true;
 
   57     if (libname == 
"libmapDict.so") 
return true;
 
   58     if (libname == 
"libmap2Dict.so") 
return true;
 
   59     if (libname == 
"libmultimapDict.so") 
return true;
 
   60     if (libname == 
"libsetDict.so") 
return true;
 
   61     if (libname == 
"libvectorDict.so") 
return true;
 
   62     if (libname == 
"libCore.so") 
return true;
 
   63     if (libname == 
"libMathCore.so") 
return true;
 
   65     static const std::string dll = 
".dll";
 
   70     return !libname.starts_with(SHLIB_PREFIX) &&
 
   71             boost::regex_match(libname, 
e);
 
   80   std::string getlibname(
const std::string& libname)
 
   82     std::string lib = libname;
 
   83     if (!lib.starts_with( 
"lib")) {
 
   84       lib = std::string(
"lib") + lib;
 
   86     if (!lib.ends_with(SHLIB_SUFFIX)) {
 
   92   const std::set<std::string>& 
 
   95     static const std::set<std::string> 
s = {
 
  125       "unsigned long long",
 
  138   const std::map<std::string, std::string>&
 
  141     static const std::map<std::string, std::string> 
s =
 
  142       {{
"ElementLinkInt_p1",             
"ElementLink_p1<unsigned int>"},
 
  143        {
"basic_string<char>",            
"string"},
 
  144        {
"vector<basic_string<char> >",   
"vector<string>"},
 
  145        {
"INavigable4MomentumCollection", 
"DataVector<INavigable4Momentum>"},
 
  146        {
"IParticleContainer",            
"DataVector<IParticle>"},
 
  151   const std::map<std::string, std::string>&
 
  154     static const std::map<std::string, std::string> 
s =
 
  155       {{
"INavigable4MomentumCollection", 
"DataVector<INavigable4Momentum>"},
 
  156        {
"IParticleContainer",            
"DataVector<IParticle>"},
 
  165   to_rootmap_name(
const std::string& type_name_)
 
  167     std::string type_name = type_name_;
 
  168     boost::algorithm::replace_all(type_name, 
", ", 
",");
 
  170     if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
 
  175     if (s_cxx_aliases().
find(type_name) != s_cxx_aliases().
end()) {
 
  176       return ::to_rootmap_name(s_cxx_aliases().
find(type_name)->
second);
 
  183       R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
 
  184       type_name = TClassEdit::ShortType(type_name.c_str(), 
 
  185                                         TClassEdit::kDropDefaultAlloc|
 
  186                                         TClassEdit::kDropStd);
 
  188     boost::algorithm::replace_all(type_name, 
"basic_string<char> >", 
"string>");
 
  189     boost::algorithm::replace_all(type_name, 
"basic_string<char>", 
"string");
 
  197   to_rflx_name(
const std::string& type_name_)
 
  199     std::string type_name = type_name_;
 
  200     boost::algorithm::replace_all(type_name, 
", ", 
",");
 
  202     if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
 
  207     if (s_cxx_typedefs().
find(type_name) != s_cxx_typedefs().
end()) {
 
  208       return ::to_rflx_name(s_cxx_typedefs().
find(type_name)->
second);
 
  214       R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
 
  215       type_name = TClassEdit::ShortType(type_name.c_str(),
 
  216                                         TClassEdit::kDropDefaultAlloc);
 
  219     boost::algorithm::replace_all(type_name, 
 
  221                                   "std::basic_string<char> >");
 
  222     boost::algorithm::replace_all(type_name, 
 
  224                                   "std::basic_string<char>");
 
  265   if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
 
  268   const std::string 
n = ::to_rootmap_name(type_name);
 
  283   return std::string();
 
  296   typedef boost::tokenizer<boost::char_separator<char> > Tokenizer_t;
 
  297   typedef std::vector<fs::path> Paths_t;
 
  299   std::set<std::string> dsofiles;
 
  301   std::string dsopath = System::getEnv(
"LD_LIBRARY_PATH");
 
  302   std::string rootsys = System::getEnv(
"ROOTSYS");
 
  304   Tokenizer_t tok(dsopath, boost::char_separator<char>(
":"));
 
  310     if (itr->starts_with(rootsys)) {
 
  317     Paths_t dir_content {fs::directory_iterator(
p),
 
  318                          fs::directory_iterator()};
 
  319     std::sort(dir_content.begin(),
 
  322            ipath_end = dir_content.end();
 
  327       bool is_components = 
false;
 
  328       if (dsomap.extension() == Components)
 
  329         is_components = 
true;
 
  330       else if (dsomap.extension() != RootMap)
 
  336       dsofiles.insert(dsomap.c_str());
 
  337       std::ifstream 
f(dsomap.c_str());
 
  343         std::getline(
f, 
line);
 
  351         else if (
line.compare (0, 8, 
"Library.")==0) {
 
  354                                   boost::is_any_of(
" "),
 
  355                                   boost::token_compress_on);
 
  357             std::cerr << 
"DsoDb:: **error** could not parse "  
  358                       << dsomap << 
":" << line_nbr
 
  360                       << 
"DsoDb:: (some) reflex-dicts may fail to be autoloaded" 
  365           if (::is_rootcint_dict(libname)) {
 
  369           libname = ::getlibname(libname);
 
  370           boost::algorithm::replace_all(dso_key, 
"Library.", 
"");
 
  371           boost::algorithm::replace_all(dso_key, 
":", 
"");
 
  376         else if (
line[0] == 
'[') {
 
  377           libname = 
line.substr (1, 
line.size()-2);
 
  379           if (::is_rootcint_dict(libname)) {
 
  383           if (!libname.empty())
 
  384             lastlib = ::getlibname (libname);
 
  388         else if (
line.compare(0, 8, 
"# --End ")==0) {
 
  393         else if (
line.compare(0, 6, 
"class ")==0) {
 
  396           dso_key = std::move(
line);
 
  399         else if (is_components && 
line.compare(0, 3, 
"lib") ==0) {
 
  400           std::string::size_type 
pos = 
line.find (
':');
 
  401           if (
pos == std::string::npos) 
continue;
 
  404           dso_key = std::move(
line);
 
  406           if (dso_key.compare(0, 6, 
"_PERS_")==0 ||
 
  407               dso_key.compare(0, 7, 
"_TRANS_")==0)
 
  410           if (libname.find (
"AthenaPoolPoolCnv") != std::string::npos)
 
  414         if (libname.empty() || dso_key.empty()) 
continue;
 
  416         const std::string fullpath_libname = 
to_string(dsomap.parent_path() / 
fs::path(libname));
 
  421         if (dso_key.starts_with(PluginNs) || is_components) {
 
  426         if (
db->find(dso_key) == 
db->end()) {
 
  427           db->insert(std::make_pair(dso_key, Strings_t()));
 
  429         (*db)[dso_key].push_back(std::move(fullpath_libname));
 
  443 std::vector<std::string>
 
  448   const std::string libname = ::getlibname(
to_string(
p.filename()));
 
  449   std::set<std::string> caps;
 
  454     for (DsoMap_t::const_iterator 
idb = 
db->begin(), iend=
db->end();
 
  457       for (Libs_t::const_iterator ilib = 
idb->second.begin(),
 
  458              ilibend = 
idb->second.end();
 
  462         if (
to_string(lib.filename()) == libname) {
 
  463           caps.insert(
idb->first);
 
  469   return std::vector<std::string>(caps.begin(), caps.end());
 
  478   std::vector<std::string> caps = this->
capabilities(libname);
 
  484     for (DsoMap_t::const_iterator 
 
  485            idb = dup_db.begin(), 
 
  486            idbend = dup_db.end();
 
  489       if (
std::find(caps.begin(), caps.end(), 
idb->first) != caps.end()) {
 
  490         for (Libs_t::const_iterator 
 
  491                ilib = 
idb->second.begin(),
 
  492                ilibend=
idb->second.end();
 
  498             dups[
idb->first].push_back(*ilib);
 
  530   std::set<std::string> 
libs;
 
  535     for (DsoMap_t::const_iterator 
idb = 
db.begin(), iend=
db.end();
 
  538       for (Libs_t::const_iterator 
 
  539              ilib = 
idb->second.begin(),
 
  540              ilibend=
idb->second.end();
 
  565     for (DsoMap_t::const_iterator 
idb = 
d.begin(), idbend=
d.end();
 
  572         std::set<std::string> baselibs;
 
  573         for (Libs_t::const_iterator 
 
  574                ilib = 
idb->second.begin(),
 
  575                ilibend= 
idb->second.end();
 
  579           if (baselibs.find(baselib) == baselibs.end()) {
 
  580             libs.push_back(*ilib);
 
  581             baselibs.insert(std::move(baselib));
 
  596   for (DsoMap_t::const_iterator 
idb = 
db.begin(), iend = 
db.end();
 
  599     if (
idb->second.size() == 1) {
 
  606       std::unordered_set<std::string> baselibs;
 
  607       for (Libs_t::const_iterator 
 
  608              ilib = 
idb->second.begin(), 
 
  609              ilend= 
idb->second.end();
 
  616           libs.push_back(*ilib);
 
  620     if (
libs.size() > 1) {
 
  630   const std::string rootmap_name = ::to_rootmap_name(type_name);
 
  631   const std::string rflx_name = ::to_rflx_name(type_name);
 
  639   if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
 
  643   if (!this->has_type(rootmap_name)) {
 
  644 #ifdef ATH_DSODB_VERBOSE 
  645     std::cerr << 
"DsoDb **error**: no such type [" << rootmap_name << 
"]" 
  646               << 
" in rootmap files\n";
 
  650   DsoMap_t::const_iterator 
idb = m_db.find(rootmap_name);
 
  651   if (
idb == m_db.end()) {
 
  653     idb = m_pf.find(rootmap_name);
 
  654     if (
idb == m_pf.end()) {
 
  658   const Libs_t& 
libs = 
idb->second;
 
  660 #ifdef ATH_DSODB_VERBOSE 
  661     std::cerr << 
"DsoDb **error**: no library hosting [" << type_name << 
"]\n";
 
  666   System::ImageHandle handle;
 
  669   if (libname.starts_with(SHLIB_PREFIX)) {
 
  670     libname = libname.substr(SHLIB_PREFIX.size(), std::string::npos);
 
  672   if (libname.ends_with(SHLIB_SUFFIX)) {
 
  673     libname.resize(libname.size() - SHLIB_SUFFIX.size());
 
  676   unsigned long err = System::loadDynamicLib( libname, &handle );
 
  678     std::cerr << 
"DsoDb **error**: could not load library ["  
  679               << 
libs[0] << 
"] (" << System::getLastErrorString()