Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:17:02

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