Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 07:54:20

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework include files
0015 #include <DD4hep/Printout.h>
0016 
0017 // C/C++ include files
0018 #include <mutex>
0019 #include <cstring>
0020 #include <cstdarg>
0021 #include <sstream>
0022 #include <iostream>
0023 #include <stdexcept>
0024 
0025 // Disable some diagnostics for ROOT dictionaries
0026 #ifdef __GNUC__
0027 #pragma GCC diagnostic ignored "-Wvarargs"
0028 #endif
0029 
0030 namespace {
0031   std::mutex s_output_synchronization;
0032   size_t _the_printer_1(void*, dd4hep::PrintLevel lvl, const char* src, const char* text);
0033   size_t _the_printer_2(void* par, dd4hep::PrintLevel lvl, const char* src, const char* fmt, va_list& args);
0034 
0035   std::string print_fmt = "%-16s %5s %s";
0036   dd4hep::PrintLevel print_lvl = dd4hep::INFO;
0037   void* print_arg = 0;
0038   dd4hep::output_function1_t print_func_1 = 0;
0039   dd4hep::output_function2_t print_func_2 = _the_printer_2;
0040 
0041   const char* print_level(dd4hep::PrintLevel lvl)   {
0042     switch(lvl)   {
0043     case dd4hep::NOLOG:     return "NOLOG";
0044     case dd4hep::VERBOSE:   return "VERB ";
0045     case dd4hep::DEBUG:     return "DEBUG";
0046     case dd4hep::INFO:      return "INFO ";
0047     case dd4hep::WARNING:   return "WARN ";
0048     case dd4hep::ERROR:     return "ERROR";
0049     case dd4hep::FATAL:     return "FATAL";
0050     case dd4hep::ALWAYS:    return "     ";
0051     default:
0052       if ( lvl> dd4hep::ALWAYS )
0053         return print_level(dd4hep::ALWAYS);
0054       return print_level(dd4hep::NOLOG);
0055     }
0056   }
0057 
0058   size_t _the_printer_1(void*, dd4hep::PrintLevel lvl, const char* src, const char* text) {
0059     std::lock_guard<std::mutex> lock(s_output_synchronization);
0060     ::fflush(stdout);
0061     ::fflush(stderr);
0062     std::cout << std::flush;
0063     std::cerr << std::flush;
0064     size_t len = ::fprintf(stdout, print_fmt.c_str(), src, print_level(lvl), text);
0065     ::fputc('\n',stdout);
0066     return len;
0067   }
0068 
0069   size_t _the_printer_2(void* par, dd4hep::PrintLevel lvl, const char* src, const char* fmt, va_list& args) {
0070     if ( !print_func_1 )  {
0071       char text[4096];
0072       std::lock_guard<std::mutex> lock(s_output_synchronization);
0073       ::fflush(stdout);
0074       ::fflush(stderr);
0075       std::cout << std::flush;
0076       std::cerr << std::flush;
0077       ::snprintf(text,sizeof(text),print_fmt.c_str(),src,print_level(lvl),fmt);
0078       size_t len = ::vfprintf(stdout, text, args);
0079       ::fputc('\n',stdout);
0080       return len;
0081     }
0082     char str[4096];
0083     ::vsnprintf(str, sizeof(str), fmt, args);
0084     return print_func_1(par, lvl, src, str);
0085   }
0086 
0087   std::string __format(const char* fmt, va_list& args) {
0088     char str[4096];
0089     ::vsnprintf(str, sizeof(str), fmt, args);
0090     return std::string(str);
0091   }
0092 }
0093 
0094 namespace dd4hep  {
0095   namespace detail {
0096 
0097     std::size_t printf(const char* fmt, ...)  {
0098       std::lock_guard<std::mutex> lock(s_output_synchronization);
0099       va_list args;
0100       va_start(args, fmt);
0101       std::size_t len = ::vfprintf(stdout, fmt, args);
0102       va_end(args);
0103       return len;
0104     }
0105     std::size_t errprintf(const char* fmt, ...)  {
0106       std::lock_guard<std::mutex> lock(s_output_synchronization);
0107       va_list args;
0108       va_start(args, fmt);
0109       std::size_t len = ::vfprintf(stderr, fmt, args);
0110       va_end(args);
0111       return len;
0112     }
0113   }
0114 }
0115 
0116 dd4hep::PrintLevel dd4hep::decodePrintLevel(const std::string& val)   {
0117   switch(::toupper(val[0]))  {
0118   case '1':
0119   case 'V':
0120     return dd4hep::VERBOSE;
0121   case '2':
0122   case 'D':
0123     return dd4hep::DEBUG;
0124   case '3':
0125   case 'I':
0126     return dd4hep::INFO;
0127   case '4':
0128   case 'W':
0129     return dd4hep::WARNING;
0130   case '5':
0131   case 'E':
0132     return dd4hep::ERROR;
0133   case '6':
0134   case 'F':
0135     return dd4hep::FATAL;
0136   case '7':
0137   case 'A':
0138     return dd4hep::FATAL;
0139   default:
0140     std::cout << "Unknown print level supplied:'" << val << "'. Argument ignored." << std::endl;
0141     throw std::runtime_error("Invalid printLevel:"+val);
0142   }
0143 }
0144 
0145 /// Helper function to serialize argument list to a single string
0146 /**
0147  *  \arg argc       [int,read-only]      Number of arguments.
0148  *  \arg argv       [char**,read-only]   Argument strings
0149  *  \return String containing the concatenated arguments
0150  */
0151 std::string dd4hep::arguments(int argc, char** argv)   {
0152   std::stringstream str;
0153   for(int i=0; i<argc;)  {
0154     str << argv[i];
0155     if ( ++i < argc ) str << " ";
0156   }
0157   return str.str();
0158 }  
0159 
0160 /// Calls the display action with a given severity level
0161 /**
0162  *  @arg severity   [int,read-only]      Display severity flag (see enum)
0163  *  @arg src        [string,read-only]   Information source (component, etc.)
0164  *  @arg str        [stringstream, RW]   string stream containing data to be printed.
0165  *                                       Object is reset after use.
0166  *  @return Status code indicating success or failure
0167  */
0168 int dd4hep::printout(PrintLevel severity, const char* src, std::stringstream& str)   {
0169   int ret = 1;
0170   if (severity >= print_lvl) {
0171     ret = printout(severity, src, str.str().c_str());
0172   }
0173   str.str("");
0174   return ret;
0175 }
0176 
0177 /// Calls the display action with a given severity level
0178 /**
0179  *  @arg severity   [int,read-only]      Display severity flag (see enum)
0180  *  @arg src        [string,read-only]   Information source (component, etc.)
0181  *  @arg str        [stringstream, RW]   string stream containing data to be printed.
0182  *                                       Object is reset after use.
0183  *  @return Status code indicating success or failure
0184  */
0185 int dd4hep::printout(PrintLevel severity, const std::string& src, std::stringstream& str)   {
0186   int ret = 1;
0187   if (severity >= print_lvl) {
0188     ret = printout(severity, src, str.str().c_str());
0189   }
0190   str.str("");
0191   return ret;
0192 }
0193 
0194 /** Calls the display action
0195  *  \arg severity   [int,read-only]      Display severity flag
0196  *  \arg src        [string,read-only]   Information source (component, etc.)
0197  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0198  *  \return Status code indicating success or failure
0199  */
0200 int dd4hep::printout(PrintLevel severity, const char* src, const char* fmt, ...) {
0201   if (severity >= print_lvl) {
0202     va_list args;
0203     va_start(args, fmt);
0204     printout(severity, src, fmt, args);
0205     va_end(args);
0206   }
0207   return 1;
0208 }
0209 
0210 /** Calls the display action
0211  *  \arg severity   [int,read-only]      Display severity flag
0212  *  \arg src        [string,read-only]   Information source (component, etc.)
0213  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0214  *  \return Status code indicating success or failure
0215  */
0216 int dd4hep::printout(PrintLevel severity, const std::string& src, const char* fmt, ...) {
0217   if (severity >= print_lvl) {
0218     va_list args;
0219     va_start(args, fmt);
0220     printout(severity, src.c_str(), fmt, args);
0221     va_end(args);
0222   }
0223   return 1;
0224 }
0225 
0226 /** Calls the display action
0227  *  \arg severity   [int,read-only]      Display severity flag
0228  *  \arg src        [string,read-only]   Information source (component, etc.)
0229  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0230  *  \return Status code indicating success or failure
0231  */
0232 int dd4hep::printout(PrintLevel severity, const char* src, const std::string& fmt, ...) {
0233   if (severity >= print_lvl) {
0234     va_list args;
0235     va_start(args, &fmt);
0236     printout(severity, src, fmt.c_str(), args);
0237     va_end(args);
0238   }
0239   return 1;
0240 }
0241 
0242 /** Calls the display action
0243  *  \arg severity   [int,read-only]      Display severity flag
0244  *  \arg src        [string,read-only]   Information source (component, etc.)
0245  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0246  *  \return Status code indicating success or failure
0247  */
0248 int dd4hep::printout(PrintLevel severity, const std::string& src, const std::string& fmt, ...) {
0249   if (severity >= print_lvl) {
0250     va_list args;
0251     va_start(args, &fmt);
0252     printout(severity, src.c_str(), fmt.c_str(), args);
0253     va_end(args);
0254   }
0255   return 1;
0256 }
0257 
0258 /** Calls the display action
0259  *  \arg severity   [int,read-only]      Display severity flag
0260  *  \arg src        [string,read-only]   Information source (component, etc.)
0261  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0262  *  \return Status code indicating success or failure
0263  */
0264 int dd4hep::printout(PrintLevel severity, const char* src, const char* fmt, va_list& args) {
0265   if (severity >= print_lvl) {
0266     print_func_2(print_arg, PrintLevel(severity&(~FORCE_LEVEL)), src, fmt, args);
0267   }
0268   return 1;
0269 }
0270 
0271 /** Calls the display action
0272  *  \arg severity   [int,read-only]      Display severity flag
0273  *  \arg src        [string,read-only]   Information source (component, etc.)
0274  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0275  *  \return Status code indicating success or failure
0276  */
0277 int dd4hep::printout(PrintLevel severity, const std::string& src, const char* fmt, va_list& args) {
0278   return printout(severity, src.c_str(), fmt, args);
0279 }
0280 
0281 /** Calls the display action
0282  *  \arg severity   [int,read-only]      Display severity flag
0283  *  \arg src        [string,read-only]   Information source (component, etc.)
0284  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0285  *  \return Status code indicating success or failure
0286  */
0287 int dd4hep::printout(PrintLevel severity, const char* src, const std::string& fmt, va_list& args) {
0288   return printout(severity, src, fmt.c_str(), args);
0289 }
0290 
0291 /** Calls the display action
0292  *  \arg severity   [int,read-only]      Display severity flag
0293  *  \arg src        [string,read-only]   Information source (component, etc.)
0294  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0295  *  \return Status code indicating success or failure
0296  */
0297 int dd4hep::printout(PrintLevel severity, const std::string& src, const std::string& fmt, va_list& args) {
0298   return printout(severity, src.c_str(), fmt.c_str(), args);
0299 }
0300 
0301 /** Calls the display action with ERROR and throws an std::runtime_error exception
0302  *  \arg src        [string,read-only]   Information source (component, etc.)
0303  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0304  *  \return Status code indicating success or failure
0305  */
0306 int dd4hep::except(const std::string& src, const std::string& fmt, ...) {
0307   va_list args;
0308   va_start(args, &fmt);
0309   return except(src.c_str(),fmt.c_str(), args);
0310 }
0311 
0312 /** Calls the display action with ERROR and throws an std::runtime_error exception
0313  *  \arg src        [string,read-only]   Information source (component, etc.)
0314  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0315  *  \return Status code indicating success or failure
0316  */
0317 int dd4hep::except(const char* src, const char* fmt, ...) {
0318   va_list args;
0319   va_start(args, fmt);
0320   return except(src, fmt, args);
0321 }
0322 
0323 /** Calls the display action with ERROR and throws an std::runtime_error exception
0324  *  \arg src        [string,read-only]   Information source (component, etc.)
0325  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0326  *  \arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
0327  *  \return Status code indicating success or failure
0328  */
0329 int dd4hep::except(const std::string& src, const std::string& fmt, va_list& args) {
0330   std::string msg = __format(fmt.c_str(), args);
0331   va_end(args);
0332   printout(ERROR, src.c_str(), "%s", msg.c_str());
0333   // No return. Must call va_end here!
0334   throw std::runtime_error((src+": "+msg).c_str());
0335 }
0336 
0337 /** Calls the display action with ERROR and throws an std::runtime_error exception
0338  *  \arg src        [string,read-only]   Information source (component, etc.)
0339  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0340  *  \arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
0341  *  \return Status code indicating success or failure
0342  */
0343 int dd4hep::except(const char* src, const char* fmt, va_list& args) {
0344   std::string msg = __format(fmt, args);
0345   va_end(args);
0346   printout(ERROR, src, "%s", msg.c_str());
0347   // No return. Must call va_end here!
0348   throw std::runtime_error((std::string(src)+": "+msg).c_str());
0349 }
0350 
0351 /** Build exception string
0352  *  \arg src        [string,read-only]   Information source (component, etc.)
0353  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0354  *  \return Status code indicating success or failure
0355  */
0356 std::string dd4hep::format(const std::string& src, const std::string& fmt, ...) {
0357   va_list args;
0358   va_start(args, &fmt);
0359   std::string str = format(src, fmt, args);
0360   va_end(args);
0361   return str;
0362 }
0363 
0364 /** Build exception string
0365  *  \arg src        [string,read-only]   Information source (component, etc.)
0366  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0367  *  \return Status code indicating success or failure
0368  */
0369 std::string dd4hep::format(const char* src, const char* fmt, ...) {
0370   va_list args;
0371   va_start(args, fmt);
0372   std::string str = format(src, fmt, args);
0373   va_end(args);
0374   return str;
0375 }
0376 
0377 /** Build exception string and throw std::runtime_error
0378  *  \arg src        [string,read-only]   Information source (component, etc.)
0379  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0380  *  \arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
0381  *  \return Status code indicating success or failure
0382  */
0383 std::string dd4hep::format(const std::string& src, const std::string& fmt, va_list& args) {
0384   return format(src.c_str(), fmt.c_str(), args);
0385 }
0386 
0387 /** Build exception string and throw std::runtime_error
0388  *  \arg src        [string,read-only]   Information source (component, etc.)
0389  *  \arg fmt        [string,read-only]   Format string for ellipsis args
0390  *  \arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
0391  *  \return Status code indicating success or failure
0392  */
0393 std::string dd4hep::format(const char* src, const char* fmt, va_list& args) {
0394   char str[4096];
0395   size_t len1 = 0;
0396   if ( src && *src ) ::snprintf(str, sizeof(str), "%s: ", src);
0397   size_t len2 = ::vsnprintf(str + len1, sizeof(str) - len1, fmt, args);
0398   if ( len2 > sizeof(str) - len1 )  {
0399     len2 = sizeof(str) - len1 - 1;
0400     str[sizeof(str)-1] = 0;
0401   }
0402   return std::string(str);
0403 }
0404 
0405 /// Set new print level. Returns the old print level
0406 dd4hep::PrintLevel dd4hep::setPrintLevel(PrintLevel new_level) {
0407   PrintLevel old = print_lvl;
0408   print_lvl = new_level;
0409   return old;
0410 }
0411 
0412 /// Access the current printer level
0413 dd4hep::PrintLevel dd4hep::printLevel()  {
0414   return print_lvl;
0415 }
0416 
0417 /// Translate the printer level from string to value
0418 dd4hep::PrintLevel dd4hep::printLevel(const char* value)  {
0419   if ( !value ) except("Printout","Invalid printlevel requested [EINVAL: Null-pointer argument]");
0420   // Explicit values
0421   if ( strcmp(value,"NOLOG")   == 0 ) return dd4hep::NOLOG;
0422   if ( strcmp(value,"VERBOSE") == 0 ) return dd4hep::VERBOSE;
0423   if ( strcmp(value,"DEBUG")   == 0 ) return dd4hep::DEBUG;
0424   if ( strcmp(value,"INFO")    == 0 ) return dd4hep::INFO;
0425   if ( strcmp(value,"WARNING") == 0 ) return dd4hep::WARNING;
0426   if ( strcmp(value,"ERROR")   == 0 ) return dd4hep::ERROR;
0427   if ( strcmp(value,"FATAL")   == 0 ) return dd4hep::FATAL;
0428   if ( strcmp(value,"ALWAYS")  == 0 ) return dd4hep::ALWAYS;
0429   // Numeric values
0430   if ( strcmp(value,"0")       == 0 ) return dd4hep::NOLOG;
0431   if ( strcmp(value,"1")       == 0 ) return dd4hep::VERBOSE;
0432   if ( strcmp(value,"2")       == 0 ) return dd4hep::DEBUG;
0433   if ( strcmp(value,"3")       == 0 ) return dd4hep::INFO;
0434   if ( strcmp(value,"4")       == 0 ) return dd4hep::WARNING;
0435   if ( strcmp(value,"5")       == 0 ) return dd4hep::ERROR;
0436   if ( strcmp(value,"6")       == 0 ) return dd4hep::FATAL;
0437   if ( strcmp(value,"7")       == 0 ) return dd4hep::ALWAYS;
0438   except("Printout","Unknown printlevel requested:%s",value);
0439   return dd4hep::ALWAYS;
0440 }
0441 
0442 /// Translate the printer level from string to value
0443 dd4hep::PrintLevel dd4hep::printLevel(const std::string& value)  {
0444   return printLevel(value.c_str());
0445 }
0446 
0447 /// Check if this print level would result in some output
0448 bool dd4hep::isActivePrintLevel(int severity)   {
0449   return severity >= print_lvl;
0450 }
0451 
0452 /// Set new printout format for the 3 fields: source-level-message. All 3 are strings
0453 std::string dd4hep::setPrintFormat(const std::string& new_format) {
0454   std::string old = print_fmt;
0455   print_fmt  = new_format;
0456   return old;
0457 }
0458 
0459 /// Customize printer function
0460 void dd4hep::setPrinter(void* arg, output_function1_t fcn) {
0461   print_arg  = arg;
0462   print_func_1 = fcn ? fcn : _the_printer_1;
0463 }
0464 
0465 /// Customize printer function
0466 void dd4hep::setPrinter2(void* arg, output_function2_t fcn) {
0467   print_arg = arg;
0468   print_func_2 = fcn ? fcn : _the_printer_2;
0469 }