DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
Printout.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
15 #include <DD4hep/Printout.h>
16 
17 // C/C++ include files
18 #include <mutex>
19 #include <cstring>
20 #include <cstdarg>
21 #include <sstream>
22 #include <iostream>
23 #include <stdexcept>
24 
25 // Disable some diagnostics for ROOT dictionaries
26 #ifdef __GNUC__
27 #pragma GCC diagnostic ignored "-Wvarargs"
28 #endif
29 
30 namespace {
31  std::mutex s_output_synchronization;
32 
33  size_t _the_printer_1(void*, dd4hep::PrintLevel lvl, const char* src, const char* text);
34  size_t _the_printer_2(void* par, dd4hep::PrintLevel lvl, const char* src, const char* fmt, va_list& args);
35 
36  std::string print_fmt = "%-16s %5s %s";
37  dd4hep::PrintLevel print_lvl = dd4hep::INFO;
38  void* print_arg = 0;
39  dd4hep::output_function1_t print_func_1 = 0;
40  dd4hep::output_function2_t print_func_2 = _the_printer_2;
41 
42  const char* print_level(dd4hep::PrintLevel lvl) {
43  switch(lvl) {
44  case dd4hep::NOLOG: return "NOLOG";
45  case dd4hep::VERBOSE: return "VERB ";
46  case dd4hep::DEBUG: return "DEBUG";
47  case dd4hep::INFO: return "INFO ";
48  case dd4hep::WARNING: return "WARN ";
49  case dd4hep::ERROR: return "ERROR";
50  case dd4hep::FATAL: return "FATAL";
51  case dd4hep::ALWAYS: return " ";
52  default:
53  if ( lvl> dd4hep::ALWAYS )
54  return print_level(dd4hep::ALWAYS);
55  return print_level(dd4hep::NOLOG);
56  }
57  }
58 
59  size_t _the_printer_1(void*, dd4hep::PrintLevel lvl, const char* src, const char* text) {
60  std::lock_guard<std::mutex> lock(s_output_synchronization);
61  ::fflush(stdout);
62  ::fflush(stderr);
63  std::cout << std::flush;
64  std::cerr << std::flush;
65  size_t len = ::fprintf(stdout, print_fmt.c_str(), src, print_level(lvl), text);
66  ::fputc('\n',stdout);
67  return len;
68  }
69 
70  size_t _the_printer_2(void* par, dd4hep::PrintLevel lvl, const char* src, const char* fmt, va_list& args) {
71  if ( !print_func_1 ) {
72  char text[4096];
73  std::lock_guard<std::mutex> lock(s_output_synchronization);
74  ::fflush(stdout);
75  ::fflush(stderr);
76  std::cout << std::flush;
77  std::cerr << std::flush;
78  ::snprintf(text,sizeof(text),print_fmt.c_str(),src,print_level(lvl),fmt);
79  size_t len = ::vfprintf(stdout, text, args);
80  ::fputc('\n',stdout);
81  return len;
82  }
83  char str[4096];
84  ::vsnprintf(str, sizeof(str), fmt, args);
85  return print_func_1(par, lvl, src, str);
86  }
87 
88  std::string __format(const char* fmt, va_list& args) {
89  char str[4096];
90  ::vsnprintf(str, sizeof(str), fmt, args);
91  return std::string(str);
92  }
93 }
94 
95 dd4hep::PrintLevel dd4hep::decodePrintLevel(const std::string& val) {
96  switch(::toupper(val[0])) {
97  case '1':
98  case 'V':
99  return dd4hep::VERBOSE;
100  case '2':
101  case 'D':
102  return dd4hep::DEBUG;
103  case '3':
104  case 'I':
105  return dd4hep::INFO;
106  case '4':
107  case 'W':
108  return dd4hep::WARNING;
109  case '5':
110  case 'E':
111  return dd4hep::ERROR;
112  case '6':
113  case 'F':
114  return dd4hep::FATAL;
115  case '7':
116  case 'A':
117  return dd4hep::FATAL;
118  default:
119  std::cout << "Unknown print level supplied:'" << val << "'. Argument ignored." << std::endl;
120  throw std::runtime_error("Invalid printLevel:"+val);
121  }
122 }
123 
125 
130 std::string dd4hep::arguments(int argc, char** argv) {
131  std::stringstream str;
132  for(int i=0; i<argc;) {
133  str << argv[i];
134  if ( ++i < argc ) str << " ";
135  }
136  return str.str();
137 }
138 
140 
147 int dd4hep::printout(PrintLevel severity, const char* src, std::stringstream& str) {
148  int ret = 1;
149  if (severity >= print_lvl) {
150  ret = printout(severity, src, str.str().c_str());
151  }
152  str.str("");
153  return ret;
154 }
155 
157 
164 int dd4hep::printout(PrintLevel severity, const std::string& src, std::stringstream& str) {
165  int ret = 1;
166  if (severity >= print_lvl) {
167  ret = printout(severity, src, str.str().c_str());
168  }
169  str.str("");
170  return ret;
171 }
172 
179 int dd4hep::printout(PrintLevel severity, const char* src, const char* fmt, ...) {
180  if (severity >= print_lvl) {
181  va_list args;
182  va_start(args, fmt);
183  printout(severity, src, fmt, args);
184  va_end(args);
185  }
186  return 1;
187 }
188 
195 int dd4hep::printout(PrintLevel severity, const std::string& src, const char* fmt, ...) {
196  if (severity >= print_lvl) {
197  va_list args;
198  va_start(args, fmt);
199  printout(severity, src.c_str(), fmt, args);
200  va_end(args);
201  }
202  return 1;
203 }
204 
211 int dd4hep::printout(PrintLevel severity, const char* src, const std::string& fmt, ...) {
212  if (severity >= print_lvl) {
213  va_list args;
214  va_start(args, &fmt);
215  printout(severity, src, fmt.c_str(), args);
216  va_end(args);
217  }
218  return 1;
219 }
220 
227 int dd4hep::printout(PrintLevel severity, const std::string& src, const std::string& fmt, ...) {
228  if (severity >= print_lvl) {
229  va_list args;
230  va_start(args, &fmt);
231  printout(severity, src.c_str(), fmt.c_str(), args);
232  va_end(args);
233  }
234  return 1;
235 }
236 
243 int dd4hep::printout(PrintLevel severity, const char* src, const char* fmt, va_list& args) {
244  if (severity >= print_lvl) {
245  print_func_2(print_arg, PrintLevel(severity&(~FORCE_LEVEL)), src, fmt, args);
246  }
247  return 1;
248 }
249 
256 int dd4hep::printout(PrintLevel severity, const std::string& src, const char* fmt, va_list& args) {
257  return printout(severity, src.c_str(), fmt, args);
258 }
259 
266 int dd4hep::printout(PrintLevel severity, const char* src, const std::string& fmt, va_list& args) {
267  return printout(severity, src, fmt.c_str(), args);
268 }
269 
276 int dd4hep::printout(PrintLevel severity, const std::string& src, const std::string& fmt, va_list& args) {
277  return printout(severity, src.c_str(), fmt.c_str(), args);
278 }
279 
285 int dd4hep::except(const std::string& src, const std::string& fmt, ...) {
286  va_list args;
287  va_start(args, &fmt);
288  return except(src.c_str(),fmt.c_str(), args);
289 }
290 
296 int dd4hep::except(const char* src, const char* fmt, ...) {
297  va_list args;
298  va_start(args, fmt);
299  return except(src, fmt, args);
300 }
301 
308 int dd4hep::except(const std::string& src, const std::string& fmt, va_list& args) {
309  std::string msg = __format(fmt.c_str(), args);
310  va_end(args);
311  printout(ERROR, src.c_str(), "%s", msg.c_str());
312  // No return. Must call va_end here!
313  throw std::runtime_error((src+": "+msg).c_str());
314 }
315 
322 int dd4hep::except(const char* src, const char* fmt, va_list& args) {
323  std::string msg = __format(fmt, args);
324  va_end(args);
325  printout(ERROR, src, "%s", msg.c_str());
326  // No return. Must call va_end here!
327  throw std::runtime_error((std::string(src)+": "+msg).c_str());
328 }
329 
335 std::string dd4hep::format(const std::string& src, const std::string& fmt, ...) {
336  va_list args;
337  va_start(args, &fmt);
338  std::string str = format(src, fmt, args);
339  va_end(args);
340  return str;
341 }
342 
348 std::string dd4hep::format(const char* src, const char* fmt, ...) {
349  va_list args;
350  va_start(args, fmt);
351  std::string str = format(src, fmt, args);
352  va_end(args);
353  return str;
354 }
355 
362 std::string dd4hep::format(const std::string& src, const std::string& fmt, va_list& args) {
363  return format(src.c_str(), fmt.c_str(), args);
364 }
365 
372 std::string dd4hep::format(const char* src, const char* fmt, va_list& args) {
373  char str[4096];
374  size_t len1 = 0;
375  if ( src && *src ) ::snprintf(str, sizeof(str), "%s: ", src);
376  size_t len2 = ::vsnprintf(str + len1, sizeof(str) - len1, fmt, args);
377  if ( len2 > sizeof(str) - len1 ) {
378  len2 = sizeof(str) - len1 - 1;
379  str[sizeof(str)-1] = 0;
380  }
381  return std::string(str);
382 }
383 
385 dd4hep::PrintLevel dd4hep::setPrintLevel(PrintLevel new_level) {
386  PrintLevel old = print_lvl;
387  print_lvl = new_level;
388  return old;
389 }
390 
392 dd4hep::PrintLevel dd4hep::printLevel() {
393  return print_lvl;
394 }
395 
397 dd4hep::PrintLevel dd4hep::printLevel(const char* value) {
398  if ( !value ) except("Printout","Invalid printlevel requested [EINVAL: Null-pointer argument]");
399  // Explicit values
400  if ( strcmp(value,"NOLOG") == 0 ) return dd4hep::NOLOG;
401  if ( strcmp(value,"VERBOSE") == 0 ) return dd4hep::VERBOSE;
402  if ( strcmp(value,"DEBUG") == 0 ) return dd4hep::DEBUG;
403  if ( strcmp(value,"INFO") == 0 ) return dd4hep::INFO;
404  if ( strcmp(value,"WARNING") == 0 ) return dd4hep::WARNING;
405  if ( strcmp(value,"ERROR") == 0 ) return dd4hep::ERROR;
406  if ( strcmp(value,"FATAL") == 0 ) return dd4hep::FATAL;
407  if ( strcmp(value,"ALWAYS") == 0 ) return dd4hep::ALWAYS;
408  // Numeric values
409  if ( strcmp(value,"0") == 0 ) return dd4hep::NOLOG;
410  if ( strcmp(value,"1") == 0 ) return dd4hep::VERBOSE;
411  if ( strcmp(value,"2") == 0 ) return dd4hep::DEBUG;
412  if ( strcmp(value,"3") == 0 ) return dd4hep::INFO;
413  if ( strcmp(value,"4") == 0 ) return dd4hep::WARNING;
414  if ( strcmp(value,"5") == 0 ) return dd4hep::ERROR;
415  if ( strcmp(value,"6") == 0 ) return dd4hep::FATAL;
416  if ( strcmp(value,"7") == 0 ) return dd4hep::ALWAYS;
417  except("Printout","Unknown printlevel requested:%s",value);
418  return dd4hep::ALWAYS;
419 }
420 
422 dd4hep::PrintLevel dd4hep::printLevel(const std::string& value) {
423  return printLevel(value.c_str());
424 }
425 
427 bool dd4hep::isActivePrintLevel(int severity) {
428  return severity >= print_lvl;
429 }
430 
432 std::string dd4hep::setPrintFormat(const std::string& new_format) {
433  std::string old = print_fmt;
434  print_fmt = new_format;
435  return old;
436 }
437 
439 void dd4hep::setPrinter(void* arg, output_function1_t fcn) {
440  print_arg = arg;
441  print_func_1 = fcn ? fcn : _the_printer_1;
442 }
443 
445 void dd4hep::setPrinter2(void* arg, output_function2_t fcn) {
446  print_arg = arg;
447  print_func_2 = fcn ? fcn : _the_printer_2;
448 }
Printout.h