From 14236d6864fbf5ad9ff38dbd56b29f4c6101dceb Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Wed, 25 Mar 2015 14:38:47 +0000 Subject: [PATCH] Protect against douple instantiation of static storage --- DDCore/include/XML/UnicodeValues.h | 2 ++ DDCore/include/XML/XMLElements.h | 6 ++++ DDCore/src/XML/XMLTags.cpp | 54 +++++++++++++++++++++--------- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h index 882e98a8a..8a8bfc4c7 100644 --- a/DDCore/include/XML/UnicodeValues.h +++ b/DDCore/include/XML/UnicodeValues.h @@ -233,6 +233,7 @@ namespace DD4hep { UNICODE (name); UNICODE (nmodules); UNICODE (nModules); + UNICODE (normal); UNICODE (nonprojective_cylinder); UNICODE (nPads); UNICODE (nphi); @@ -278,6 +279,7 @@ namespace DD4hep { UNICODE (physvolid); UNICODE (plugin); UNICODE (plugins); + UNICODE (point); UNICODE (polyhedra); UNICODE (polycone); UNICODE (position); diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h index 7faaa184d..1f93556d0 100644 --- a/DDCore/include/XML/XMLElements.h +++ b/DDCore/include/XML/XMLElements.h @@ -249,6 +249,12 @@ namespace DD4hep { Tag_t(const std::string& s) : Strng_t(s), m_str(s) { } + /// Constructor from STL string with registration. + /// ONLY to be used for static global entries to protect against duplicated static memory. + Tag_t(const std::string& v, const std::string& s, void (*register_func)(const std::string&, Tag_t*)) + : Strng_t(s), m_str(s) { + register_func(v, this); + } /// Destructor ~Tag_t() { } diff --git a/DDCore/src/XML/XMLTags.cpp b/DDCore/src/XML/XMLTags.cpp index 1f80738f7..3954ccdb3 100644 --- a/DDCore/src/XML/XMLTags.cpp +++ b/DDCore/src/XML/XMLTags.cpp @@ -1,46 +1,68 @@ +// $Id$ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#include <stdexcept> #include <iostream> +#include <map> + #include "XML/XMLElements.h" #ifndef __TIXML__ #include "xercesc/util/XMLString.hpp" #include "xercesc/util/PlatformUtils.hpp" +#endif namespace { struct __Init { + typedef std::map<std::string,DD4hep::XML::Tag_t*> Inventory_t; + Inventory_t m_inventory; __Init() { +#ifndef __TIXML__ try { xercesc::XMLPlatformUtils::Initialize(); } catch (const xercesc::XMLException& e) { - std::cout << "Xerces-c error in initialization:" << xercesc::XMLString::transcode(e.getMessage()) << std::endl; + std::string xml_err = xercesc::XMLString::transcode(e.getMessage()); + std::string err = "xercesc::XMLPlatformUtils: Xerces-c error in initialization:"+xml_err; + std::cout << err << std::endl; + throw std::runtime_error(err); } +#endif } ~__Init() { +#ifndef __TIXML__ xercesc::XMLPlatformUtils::Terminate(); +#endif } + static void register_tag(const std::string& name, DD4hep::XML::Tag_t* tag); }; __Init __In__; + void __Init::register_tag(const std::string& name, DD4hep::XML::Tag_t* tag) { + Inventory_t::const_iterator i = __In__.m_inventory.find(name); + if ( i != __In__.m_inventory.end() ) { + std::string err = "XMLTags: Failed to register XML tag: "+name+". [Tag already exists]"; + std::cout << err << std::endl; + throw std::runtime_error(err); + } + __In__.m_inventory[name] = tag; + } } -#else -namespace { - struct __Init { - __Init() { - } - }; - __Init __In__; -} -#endif -#define UNICODE(x) extern const Tag_t Unicode_##x (#x) +#define UNICODE(x) extern const Tag_t Unicode_##x (#x, #x, __Init::register_tag) #include "XML/UnicodeValues.h" namespace DD4hep { namespace XML { - extern const Tag_t Unicode_NULL("0"); - extern const Tag_t Unicode_empty(""); - extern const Tag_t Unicode_star("*"); - extern const Tag_t Unicode_PI("3.14159265358979323846"); - extern const Tag_t Unicode_TWOPI("6.28318530717958647692"); + extern const Tag_t Unicode_NULL("NULL", "0", __Init::register_tag); + extern const Tag_t Unicode_empty("", "", __Init::register_tag); + extern const Tag_t Unicode_star("star", "*", __Init::register_tag); + extern const Tag_t Unicode_PI("PI", "3.14159265358979323846", __Init::register_tag); + extern const Tag_t Unicode_TWOPI("TWOPI", "6.28318530717958647692", __Init::register_tag); void tags_init() { static __Init i; -- GitLab