File indexing completed on 2025-01-30 09:17:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/Printout.h>
0016
0017
0018 #include <mutex>
0019 #include <cstring>
0020 #include <cstdarg>
0021 #include <sstream>
0022 #include <iostream>
0023 #include <stdexcept>
0024
0025
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
0125
0126
0127
0128
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
0140
0141
0142
0143
0144
0145
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
0157
0158
0159
0160
0161
0162
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
0174
0175
0176
0177
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
0190
0191
0192
0193
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
0206
0207
0208
0209
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
0222
0223
0224
0225
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
0238
0239
0240
0241
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
0251
0252
0253
0254
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
0261
0262
0263
0264
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
0271
0272
0273
0274
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
0281
0282
0283
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
0292
0293
0294
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
0303
0304
0305
0306
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
0313 throw std::runtime_error((src+": "+msg).c_str());
0314 }
0315
0316
0317
0318
0319
0320
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
0327 throw std::runtime_error((std::string(src)+": "+msg).c_str());
0328 }
0329
0330
0331
0332
0333
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
0344
0345
0346
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
0357
0358
0359
0360
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
0367
0368
0369
0370
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
0385 dd4hep::PrintLevel dd4hep::setPrintLevel(PrintLevel new_level) {
0386 PrintLevel old = print_lvl;
0387 print_lvl = new_level;
0388 return old;
0389 }
0390
0391
0392 dd4hep::PrintLevel dd4hep::printLevel() {
0393 return print_lvl;
0394 }
0395
0396
0397 dd4hep::PrintLevel dd4hep::printLevel(const char* value) {
0398 if ( !value ) except("Printout","Invalid printlevel requested [EINVAL: Null-pointer argument]");
0399
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
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
0422 dd4hep::PrintLevel dd4hep::printLevel(const std::string& value) {
0423 return printLevel(value.c_str());
0424 }
0425
0426
0427 bool dd4hep::isActivePrintLevel(int severity) {
0428 return severity >= print_lvl;
0429 }
0430
0431
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
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
0445 void dd4hep::setPrinter2(void* arg, output_function2_t fcn) {
0446 print_arg = arg;
0447 print_func_2 = fcn ? fcn : _the_printer_2;
0448 }