27#include "boost/tokenizer.hpp"
29#include "boost/algorithm/string.hpp"
32#include "TClassEdit.h"
35#include "GaudiKernel/System.h"
37namespace 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";
69 return !libname.starts_with(SHLIB_PREFIX) && libname.ends_with(dll);
78 std::string getlibname(
const std::string& libname)
80 std::string lib = libname;
81 if (!lib.starts_with(
"lib")) {
82 lib = std::string(
"lib") + lib;
84 if (!lib.ends_with(SHLIB_SUFFIX)) {
90 const std::set<std::string>&
93 static const std::set<std::string>
s = {
123 "unsigned long long",
136 const std::map<std::string, std::string>&
139 static const std::map<std::string, std::string>
s =
140 {{
"ElementLinkInt_p1",
"ElementLink_p1<unsigned int>"},
141 {
"basic_string<char>",
"string"},
142 {
"vector<basic_string<char> >",
"vector<string>"},
143 {
"INavigable4MomentumCollection",
"DataVector<INavigable4Momentum>"},
144 {
"IParticleContainer",
"DataVector<IParticle>"},
149 const std::map<std::string, std::string>&
152 static const std::map<std::string, std::string>
s =
153 {{
"INavigable4MomentumCollection",
"DataVector<INavigable4Momentum>"},
154 {
"IParticleContainer",
"DataVector<IParticle>"},
163 to_rootmap_name(
const std::string& type_name_)
165 std::string type_name = type_name_;
166 boost::algorithm::replace_all(type_name,
", ",
",");
168 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
173 if (s_cxx_aliases().
find(type_name) != s_cxx_aliases().
end()) {
174 return ::to_rootmap_name(s_cxx_aliases().
find(type_name)->second);
181 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
182 type_name = TClassEdit::ShortType(type_name.c_str(),
183 TClassEdit::kDropDefaultAlloc|
184 TClassEdit::kDropStd);
186 boost::algorithm::replace_all(type_name,
"basic_string<char> >",
"string>");
187 boost::algorithm::replace_all(type_name,
"basic_string<char>",
"string");
195 to_rflx_name(
const std::string& type_name_)
197 std::string type_name = type_name_;
198 boost::algorithm::replace_all(type_name,
", ",
",");
200 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().
end()) {
205 if (s_cxx_typedefs().
find(type_name) != s_cxx_typedefs().
end()) {
206 return ::to_rflx_name(s_cxx_typedefs().
find(type_name)->second);
212 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
213 type_name = TClassEdit::ShortType(type_name.c_str(),
214 TClassEdit::kDropDefaultAlloc);
217 boost::algorithm::replace_all(type_name,
219 "std::basic_string<char> >");
220 boost::algorithm::replace_all(type_name,
222 "std::basic_string<char>");
263 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().end()) {
266 const std::string n = ::to_rootmap_name(type_name);
277 RootType t = this->rflx_type(type_name);
281 return std::string();
292 typedef boost::tokenizer<boost::char_separator<char> > Tokenizer_t;
293 typedef std::vector<fs::path> Paths_t;
295 std::set<std::string> dsofiles;
297 std::string dsopath = System::getEnv(
"LD_LIBRARY_PATH");
298 std::string rootsys = System::getEnv(
"ROOTSYS");
300 Tokenizer_t tok(dsopath, boost::char_separator<char>(
":"));
302 for (Tokenizer_t::iterator itr = tok.begin(), iend = tok.end();
305 if (itr->starts_with(rootsys)) {
309 if (!std::filesystem::exists(*itr)) {
312 Paths_t dir_content {fs::directory_iterator(p),
313 fs::directory_iterator()};
316 for (Paths_t::iterator ipath = dir_content.begin(),
317 ipath_end = dir_content.end();
320 const fs::path& dsomap = *ipath;
322 bool is_components =
false;
323 if (dsomap.extension() == Components)
324 is_components =
true;
325 else if (dsomap.extension() != RootMap)
328 if (!fs::exists(dsomap))
continue;
330 dsofiles.insert(dsomap.c_str());
331 std::ifstream f(dsomap.c_str());
337 std::getline(f, line);
338 boost::algorithm::trim(line);
345 else if (line.compare (0, 8,
"Library.")==0) {
347 boost::algorithm::split(ll, line,
348 boost::is_any_of(
" "),
349 boost::token_compress_on);
351 std::print (std::cerr,
352 "DsoDb:: **error** could not parse {}:{}\n"
353 "DsoDb:: (some) reflex-dicts may fail to be autoloaded",
354 dsomap.string(), line_nbr);
358 if (::is_rootcint_dict(libname)) {
362 libname = ::getlibname(libname);
363 boost::algorithm::replace_all(dso_key,
"Library.",
"");
364 boost::algorithm::replace_all(dso_key,
":",
"");
365 std::replace(dso_key.begin(), dso_key.end(),
'@',
':');
366 std::replace(dso_key.begin(), dso_key.end(),
'-',
' ');
369 else if (line[0] ==
'[') {
370 libname = line.substr (1, line.size()-2);
371 boost::algorithm::trim (libname);
372 if (::is_rootcint_dict(libname)) {
376 if (!libname.empty())
377 lastlib = ::getlibname (libname);
381 else if (line.compare(0, 8,
"# --End ")==0) {
386 else if (line.compare(0, 6,
"class ")==0) {
389 dso_key = std::move(line);
392 else if (is_components && line.compare(0, 3,
"lib") ==0) {
393 std::string::size_type pos = line.find (
':');
394 if (pos == std::string::npos)
continue;
395 libname = line.substr(0, pos);
396 line.erase (0, pos+1);
397 dso_key = std::move(line);
399 if (dso_key.compare(0, 6,
"_PERS_")==0 ||
400 dso_key.compare(0, 7,
"_TRANS_")==0)
403 if (libname.find (
"AthenaPoolPoolCnv") != std::string::npos)
407 if (libname.empty() || dso_key.empty())
continue;
409 const std::string fullpath_libname =
to_string(dsomap.parent_path() / fs::path(libname));
412 if (dso_key.starts_with(PluginNs) || is_components) {
417 if (
db->find(dso_key) ==
db->end()) {
418 db->insert(std::make_pair(dso_key, Strings_t()));
420 (*db)[dso_key].push_back(std::move(fullpath_libname));
426 std::copy(dsofiles.begin(), dsofiles.end(), std::back_inserter(
m_dsofiles));
431std::vector<std::string>
434 fs::path p(libname_);
436 const std::string libname = ::getlibname(
to_string(p.filename()));
437 std::set<std::string> caps;
440 for (std::size_t i = 0,
imax = 2; i <
imax; ++i) {
442 for (DsoMap_t::const_iterator idb =
db->begin(), iend=
db->end();
445 for (Libs_t::const_iterator ilib = idb->second.begin(),
446 ilibend = idb->second.end();
450 if (
to_string(lib.filename()) == libname) {
451 caps.insert(idb->first);
457 return std::vector<std::string>(caps.begin(), caps.end());
465 const std::string basename_lib =
to_string(fs::path(libname).filename());
466 std::vector<std::string> caps = this->
capabilities(libname);
469 for (std::size_t i = 0,
imax = 2; i <
imax; ++i) {
471 this->
get_dups(dup_db, *dbs[i], pedantic);
472 for (DsoMap_t::const_iterator
473 idb = dup_db.begin(),
474 idbend = dup_db.end();
477 if (std::find(caps.begin(), caps.end(), idb->first) != caps.end()) {
478 for (Libs_t::const_iterator
479 ilib = idb->second.begin(),
480 ilibend=idb->second.end();
486 dups[idb->first].push_back(*ilib);
518 std::set<std::string>
libs;
521 for (std::size_t i = 0,
imax = 2; i <
imax; ++i) {
523 for (DsoMap_t::const_iterator idb =
db.begin(), iend=
db.end();
526 for (Libs_t::const_iterator
527 ilib = idb->second.begin(),
528 ilibend=idb->second.end();
551 for (std::size_t i = 0,
imax = 2; i <
imax; ++i) {
553 for (DsoMap_t::const_iterator idb = d.begin(), idbend=d.end();
557 db[idb->first] = idb->second;
560 std::set<std::string> baselibs;
561 for (Libs_t::const_iterator
562 ilib = idb->second.begin(),
563 ilibend= idb->second.end();
566 const std::string baselib =
to_string(fs::path(*ilib).filename());
567 if (baselibs.find(baselib) == baselibs.end()) {
568 libs.push_back(*ilib);
569 baselibs.insert(std::move(baselib));
572 db[idb->first] = std::move(
libs);
584 for (DsoMap_t::const_iterator idb =
db.begin(), iend =
db.end();
587 if (idb->second.size() == 1) {
594 std::unordered_set<std::string> baselibs;
595 for (Libs_t::const_iterator
596 ilib = idb->second.begin(),
597 ilend= idb->second.end();
602 if (! baselibs.emplace (
to_string(p.filename())) . second) {
604 libs.push_back(*ilib);
608 if (
libs.size() > 1) {
609 dups[idb->first] = std::move(
libs);
618 const std::string rootmap_name = ::to_rootmap_name(type_name);
619 const std::string rflx_name = ::to_rflx_name(type_name);
621 if (s_cxx_builtins().
find(type_name) != s_cxx_builtins().end()) {
625 if (!this->has_type(rootmap_name)) {
626#ifdef ATH_DSODB_VERBOSE
627 std::println (std::cerr,
628 "DsoDb **error**: no such type [{}] in rootmap files",
633 DsoMap_t::const_iterator
idb = m_db.find(rootmap_name);
634 if (idb == m_db.end()) {
636 idb = m_pf.find(rootmap_name);
637 if (idb == m_pf.end()) {
641 const Libs_t&
libs =
idb->second;
643#ifdef ATH_DSODB_VERBOSE
644 std::println (std::cerr,
"DsoDb **error**: no library hosting [{}]",
650 System::ImageHandle
handle;
652 boost::algorithm::trim(libname);
653 if (libname.starts_with(SHLIB_PREFIX)) {
654 libname = libname.substr(SHLIB_PREFIX.size(), std::string::npos);
656 if (libname.ends_with(SHLIB_SUFFIX)) {
657 libname.resize(libname.size() - SHLIB_SUFFIX.size());
660 unsigned long err = System::loadDynamicLib( libname, &handle );
662 std::println (std::cerr,
663 "DsoDb **error**: could not load library [{}] ({})",
664 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)