26#include "boost/tokenizer.hpp"
28#include "boost/algorithm/string.hpp"
31#include "TClassEdit.h"
34#include "GaudiKernel/System.h"
36namespace fs = std::filesystem;
39 typedef std::vector<std::string> Strings_t;
40 const std::string RootMap =
".rootmap";
41 const std::string Components =
".components";
42 const std::string PluginNs=
"__pf__";
45 const std::string SHLIB_PREFIX =
"lib";
46 const std::string SHLIB_SUFFIX =
".dll";
48 const std::string SHLIB_PREFIX =
"lib";
49 const std::string SHLIB_SUFFIX =
".so";
53 bool is_rootcint_dict(
const std::string& libname)
55 if (libname ==
"liblistDict.so")
return true;
56 if (libname ==
"libmapDict.so")
return true;
57 if (libname ==
"libmap2Dict.so")
return true;
58 if (libname ==
"libmultimapDict.so")
return true;
59 if (libname ==
"libsetDict.so")
return true;
60 if (libname ==
"libvectorDict.so")
return true;
61 if (libname ==
"libCore.so")
return true;
62 if (libname ==
"libMathCore.so")
return true;
64 static const std::string dll =
".dll";
68 return !libname.starts_with(SHLIB_PREFIX) && libname.ends_with(dll);
77 std::string getlibname(
const std::string& libname)
79 std::string lib = libname;
80 if (!lib.starts_with(
"lib")) {
81 lib = std::string(
"lib") + lib;
83 if (!lib.ends_with(SHLIB_SUFFIX)) {
89 const std::set<std::string>&
92 static const std::set<std::string>
s = {
122 "unsigned long long",
135 const std::map<std::string, std::string>&
138 static const std::map<std::string, std::string>
s =
139 {{
"ElementLinkInt_p1",
"ElementLink_p1<unsigned int>"},
140 {
"basic_string<char>",
"string"},
141 {
"vector<basic_string<char> >",
"vector<string>"},
142 {
"INavigable4MomentumCollection",
"DataVector<INavigable4Momentum>"},
143 {
"IParticleContainer",
"DataVector<IParticle>"},
148 const std::map<std::string, std::string>&
151 static const std::map<std::string, std::string>
s =
152 {{
"INavigable4MomentumCollection",
"DataVector<INavigable4Momentum>"},
153 {
"IParticleContainer",
"DataVector<IParticle>"},
162 to_rootmap_name(
const std::string& type_name_)
164 std::string type_name = type_name_;
165 boost::algorithm::replace_all(type_name,
", ",
",");
167 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
172 if (s_cxx_aliases().
find(type_name) != s_cxx_aliases().
end()) {
173 return ::to_rootmap_name(s_cxx_aliases().
find(type_name)->second);
180 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
181 type_name = TClassEdit::ShortType(type_name.c_str(),
182 TClassEdit::kDropDefaultAlloc|
183 TClassEdit::kDropStd);
185 boost::algorithm::replace_all(type_name,
"basic_string<char> >",
"string>");
186 boost::algorithm::replace_all(type_name,
"basic_string<char>",
"string");
194 to_rflx_name(
const std::string& type_name_)
196 std::string type_name = type_name_;
197 boost::algorithm::replace_all(type_name,
", ",
",");
199 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
204 if (s_cxx_typedefs().
find(type_name) != s_cxx_typedefs().
end()) {
205 return ::to_rflx_name(s_cxx_typedefs().
find(type_name)->second);
211 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
212 type_name = TClassEdit::ShortType(type_name.c_str(),
213 TClassEdit::kDropDefaultAlloc);
216 boost::algorithm::replace_all(type_name,
218 "std::basic_string<char> >");
219 boost::algorithm::replace_all(type_name,
221 "std::basic_string<char>");
262 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().end()) {
265 const std::string n = ::to_rootmap_name(type_name);
276 RootType t = this->rflx_type(type_name);
280 return std::string();
293 typedef boost::tokenizer<boost::char_separator<char> > Tokenizer_t;
294 typedef std::vector<fs::path> Paths_t;
296 std::set<std::string> dsofiles;
298 std::string dsopath = System::getEnv(
"LD_LIBRARY_PATH");
299 std::string rootsys = System::getEnv(
"ROOTSYS");
301 Tokenizer_t tok(dsopath, boost::char_separator<char>(
":"));
303 for (Tokenizer_t::iterator itr = tok.begin(), iend = tok.end();
307 if (itr->starts_with(rootsys)) {
311 if (!std::filesystem::exists(*itr)) {
314 Paths_t dir_content {fs::directory_iterator(p),
315 fs::directory_iterator()};
318 for (Paths_t::iterator ipath = dir_content.begin(),
319 ipath_end = dir_content.end();
322 const fs::path& dsomap = *ipath;
324 bool is_components =
false;
325 if (dsomap.extension() == Components)
326 is_components =
true;
327 else if (dsomap.extension() != RootMap)
330 if (!fs::exists(dsomap))
continue;
333 dsofiles.insert(dsomap.c_str());
334 std::ifstream f(dsomap.c_str());
340 std::getline(f, line);
341 boost::algorithm::trim(line);
348 else if (line.compare (0, 8,
"Library.")==0) {
350 boost::algorithm::split(ll, line,
351 boost::is_any_of(
" "),
352 boost::token_compress_on);
354 std::cerr <<
"DsoDb:: **error** could not parse "
355 << dsomap <<
":" << line_nbr
357 <<
"DsoDb:: (some) reflex-dicts may fail to be autoloaded"
362 if (::is_rootcint_dict(libname)) {
366 libname = ::getlibname(libname);
367 boost::algorithm::replace_all(dso_key,
"Library.",
"");
368 boost::algorithm::replace_all(dso_key,
":",
"");
369 std::replace(dso_key.begin(), dso_key.end(),
'@',
':');
370 std::replace(dso_key.begin(), dso_key.end(),
'-',
' ');
373 else if (line[0] ==
'[') {
374 libname = line.substr (1, line.size()-2);
375 boost::algorithm::trim (libname);
376 if (::is_rootcint_dict(libname)) {
380 if (!libname.empty())
381 lastlib = ::getlibname (libname);
385 else if (line.compare(0, 8,
"# --End ")==0) {
390 else if (line.compare(0, 6,
"class ")==0) {
393 dso_key = std::move(line);
396 else if (is_components && line.compare(0, 3,
"lib") ==0) {
397 std::string::size_type pos = line.find (
':');
398 if (pos == std::string::npos)
continue;
399 libname = line.substr(0, pos);
400 line.erase (0, pos+1);
401 dso_key = std::move(line);
403 if (dso_key.compare(0, 6,
"_PERS_")==0 ||
404 dso_key.compare(0, 7,
"_TRANS_")==0)
407 if (libname.find (
"AthenaPoolPoolCnv") != std::string::npos)
411 if (libname.empty() || dso_key.empty())
continue;
413 const std::string fullpath_libname =
to_string(dsomap.parent_path() / fs::path(libname));
418 if (dso_key.starts_with(PluginNs) || is_components) {
423 if (
db->find(dso_key) ==
db->end()) {
424 db->insert(std::make_pair(dso_key, Strings_t()));
426 (*db)[dso_key].push_back(std::move(fullpath_libname));
434 std::copy(dsofiles.begin(), dsofiles.end(), std::back_inserter(
m_dsofiles));
440std::vector<std::string>
443 fs::path p(libname_);
445 const std::string libname = ::getlibname(
to_string(p.filename()));
446 std::set<std::string> caps;
449 for (std::size_t i = 0,
imax = 2; i <
imax; ++i) {
451 for (DsoMap_t::const_iterator idb =
db->begin(), iend=
db->end();
454 for (Libs_t::const_iterator ilib = idb->second.begin(),
455 ilibend = idb->second.end();
459 if (
to_string(lib.filename()) == libname) {
460 caps.insert(idb->first);
466 return std::vector<std::string>(caps.begin(), caps.end());
474 const std::string basename_lib =
to_string(fs::path(libname).filename());
475 std::vector<std::string> caps = this->
capabilities(libname);
478 for (std::size_t i = 0,
imax = 2; i <
imax; ++i) {
480 this->
get_dups(dup_db, *dbs[i], pedantic);
481 for (DsoMap_t::const_iterator
482 idb = dup_db.begin(),
483 idbend = dup_db.end();
486 if (std::find(caps.begin(), caps.end(), idb->first) != caps.end()) {
487 for (Libs_t::const_iterator
488 ilib = idb->second.begin(),
489 ilibend=idb->second.end();
495 dups[idb->first].push_back(*ilib);
527 std::set<std::string>
libs;
530 for (std::size_t i = 0,
imax = 2; i <
imax; ++i) {
532 for (DsoMap_t::const_iterator idb =
db.begin(), iend=
db.end();
535 for (Libs_t::const_iterator
536 ilib = idb->second.begin(),
537 ilibend=idb->second.end();
560 for (std::size_t i = 0,
imax = 2; i <
imax; ++i) {
562 for (DsoMap_t::const_iterator idb = d.begin(), idbend=d.end();
566 db[idb->first] = idb->second;
569 std::set<std::string> baselibs;
570 for (Libs_t::const_iterator
571 ilib = idb->second.begin(),
572 ilibend= idb->second.end();
575 const std::string baselib =
to_string(fs::path(*ilib).filename());
576 if (baselibs.find(baselib) == baselibs.end()) {
577 libs.push_back(*ilib);
578 baselibs.insert(std::move(baselib));
581 db[idb->first] = std::move(
libs);
593 for (DsoMap_t::const_iterator idb =
db.begin(), iend =
db.end();
596 if (idb->second.size() == 1) {
603 std::unordered_set<std::string> baselibs;
604 for (Libs_t::const_iterator
605 ilib = idb->second.begin(),
606 ilend= idb->second.end();
611 if (! baselibs.emplace (
to_string(p.filename())) . second) {
613 libs.push_back(*ilib);
617 if (
libs.size() > 1) {
618 dups[idb->first] = std::move(
libs);
627 const std::string rootmap_name = ::to_rootmap_name(type_name);
628 const std::string rflx_name = ::to_rflx_name(type_name);
636 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().end()) {
640 if (!this->has_type(rootmap_name)) {
641#ifdef ATH_DSODB_VERBOSE
642 std::cerr <<
"DsoDb **error**: no such type [" << rootmap_name <<
"]"
643 <<
" in rootmap files\n";
647 DsoMap_t::const_iterator
idb = m_db.find(rootmap_name);
648 if (idb == m_db.end()) {
650 idb = m_pf.find(rootmap_name);
651 if (idb == m_pf.end()) {
655 const Libs_t&
libs =
idb->second;
657#ifdef ATH_DSODB_VERBOSE
658 std::cerr <<
"DsoDb **error**: no library hosting [" << type_name <<
"]\n";
663 System::ImageHandle
handle;
665 boost::algorithm::trim(libname);
666 if (libname.starts_with(SHLIB_PREFIX)) {
667 libname = libname.substr(SHLIB_PREFIX.size(), std::string::npos);
669 if (libname.ends_with(SHLIB_SUFFIX)) {
670 libname.resize(libname.size() - SHLIB_SUFFIX.size());
673 unsigned long err = System::loadDynamicLib( libname, &handle );
675 std::cerr <<
"DsoDb **error**: could not load library ["
676 <<
libs[0] <<
"] (" << System::getLastErrorString()
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
DsoMap_t pf_duplicates(bool pedantic=false) const
table of plugin-factories-duplicates: {type: [lib1, lib2, ...]}
DsoMap_t m_db
repository of components
std::vector< std::string > Libs_t
Libs_t libs(bool detailed=false) const
list of all libraries we know about
std::vector< std::string > m_dsofiles
list of dsofiles
std::unordered_map< std::string, Libs_t > DsoMap_t
void build_repository()
initialize the repository of dso file names
DsoDb()
Default constructor:
std::vector< std::string > capabilities(const std::string &libname) const
list of reflex-types associated with a library name
bool has_type(const std::string &type_name) const
void get_dups(DsoMap_t &dups, const DsoMap_t &db, bool pedantic) const
get the duplicates for a given repository of components
const DsoMap_t & db() const
repository of components
static const DsoDb * instance()
factory for the DsoDb
DsoMap_t dict_duplicates(bool pedantic=false) const
table of dict-duplicates: {type: [lib1, lib2, ...]}
DsoMap_t m_pf
repository of plugin factories
DsoMap_t content(bool pedantic) const
return the table {type: [lib1, ...]} - concatenation of all dict-entries and plugin-factories entries...
DsoMap_t duplicates(const std::string &libname, bool pedantic=false) const
list of libraries hosting duplicate reflex-types
std::string find(const std::string &s)
return a remapped string
virtual void handle(const Incident &inc)
Handle end of run incidents to save the metadata at that point.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
std::string basename(std::string name)