DD4hep  1.32.0
Detector Description Toolkit for High Energy Physics
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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  size_t _the_printer_1(void*, dd4hep::PrintLevel lvl, const char* src, const char* text);
33  size_t _the_printer_2(void* par, dd4hep::PrintLevel lvl, const char* src, const char* fmt, va_list& args);
34 
35  std::string print_fmt = "%-16s %5s %s";
36  dd4hep::PrintLevel print_lvl = dd4hep::INFO;
37  void* print_arg = 0;
38  dd4hep::output_function1_t print_func_1 = 0;
39  dd4hep::output_function2_t print_func_2 = _the_printer_2;
40 
41  const char* print_level(dd4hep::PrintLevel lvl) {
42  switch(lvl) {
43  case dd4hep::NOLOG: return "NOLOG";
44  case dd4hep::VERBOSE: return "VERB ";
45  case dd4hep::DEBUG: return "DEBUG";
46  case dd4hep::INFO: return "INFO ";
47  case dd4hep::WARNING: return "WARN ";
48  case dd4hep::ERROR: return "ERROR";
49  case dd4hep::FATAL: return "FATAL";
50  case dd4hep::ALWAYS: return " ";
51  default:
52  if ( lvl> dd4hep::ALWAYS )
53  return print_level(dd4hep::ALWAYS);
54  return print_level(dd4hep::NOLOG);
55  }
56  }
57 
58  size_t _the_printer_1(void*, dd4hep::PrintLevel lvl, const char* src, const char* text) {
59  std::lock_guard<std::mutex> lock(s_output_synchronization);
60  ::fflush(stdout);
61  ::fflush(stderr);
62  std::cout << std::flush;
63  std::cerr << std::flush;
64  size_t len = ::fprintf(stdout, print_fmt.c_str(), src, print_level(lvl), text);
65  ::fputc('\n',stdout);
66  return len;
67  }
68 
69  size_t _the_printer_2(void* par, dd4hep::PrintLevel lvl, const char* src, const char* fmt, va_list& args) {
70  if ( !print_func_1 ) {
71  char text[4096];
72  std::lock_guard<std::mutex> lock(s_output_synchronization);
73  ::fflush(stdout);
74  ::fflush(stderr);
75  std::cout << std::flush;
76  std::cerr << std::flush;
77  ::snprintf(text,sizeof(text),print_fmt.c_str(),src,print_level(lvl),fmt);
78  size_t len = ::vfprintf(stdout, text, args);
79  ::fputc('\n',stdout);
80  return len;
81  }
82  char str[4096];
83  ::vsnprintf(str, sizeof(str), fmt, args);
84  return print_func_1(par, lvl, src, str);
85  }
86 
87  std::string __format(const char* fmt, va_list& args) {
88  char str[4096];
89  ::vsnprintf(str, sizeof(str), fmt, args);
90  return std::string(str);
91  }
92 }
93 
94 namespace dd4hep {
95  namespace detail {
96 
97  std::size_t printf(const char* fmt, ...) {
98  std::lock_guard<std::mutex> lock(s_output_synchronization);
99  va_list args;
100  va_start(args, fmt);
101  std::size_t len = ::vfprintf(stdout, fmt, args);
102  va_end(args);
103  return len;
104  }
105  std::size_t errprintf(const char* fmt, ...) {
106  std::lock_guard<std::mutex> lock(s_output_synchronization);
107  va_list args;
108  va_start(args, fmt);
109  std::size_t len = ::vfprintf(stderr, fmt, args);
110  va_end(args);
111  return len;
112  }
113  }
114 }
115 
116 dd4hep::PrintLevel dd4hep::decodePrintLevel(const std::string& val) {
117  switch(::toupper(val[0])) {
118  case '1':
119  case 'V':
120  return dd4hep::VERBOSE;
121  case '2':
122  case 'D':
123  return dd4hep::DEBUG;
124  case '3':
125  case 'I':
126  return dd4hep::INFO;
127  case '4':
128  case 'W':
129  return dd4hep::WARNING;
130  case '5':
131  case 'E':
132  return dd4hep::ERROR;
133  case '6':
134  case 'F':
135  return dd4hep::FATAL;
136  case '7':
137  case 'A':
138  return dd4hep::FATAL;
139  default:
140  std::cout << "Unknown print level supplied:'" << val << "'. Argument ignored." << std::endl;
141  throw std::runtime_error("Invalid printLevel:"+val);
142  }
143 }
144 
146 
151 std::string dd4hep::arguments(int argc, char** argv) {
152  std::stringstream str;
153  for(int i=0; i<argc;) {
154  str << argv[i];
155  if ( ++i < argc ) str << " ";
156  }
157  return str.str();
158 }
159 
161 
168 int dd4hep::printout(PrintLevel severity, const char* src, std::stringstream& str) {
169  int ret = 1;
170  if (severity >= print_lvl) {
171  ret = printout(severity, src, str.str().c_str());
172  }
173  str.str("");
174  return ret;
175 }
176 
178 
185 int dd4hep::printout(PrintLevel severity, const std::string& src, std::stringstream& str) {
186  int ret = 1;
187  if (severity >= print_lvl) {
188  ret = printout(severity, src, str.str().c_str());
189  }
190  str.str("");
191  return ret;
192 }
193 
200 int dd4hep::printout(PrintLevel severity, const char* src, const char* fmt, ...) {
201  if (severity >= print_lvl) {
202  va_list args;
203  va_start(args, fmt);
204  printout(severity, src, fmt, args);
205  va_end(args);
206  }
207  return 1;
208 }
209 
216 int dd4hep::printout(PrintLevel severity, const std::string& src, const char* fmt, ...) {
217  if (severity >= print_lvl) {
218  va_list args;
219  va_start(args, fmt);
220  printout(severity, src.c_str(), fmt, args);
221  va_end(args);
222  }
223  return 1;
224 }
225 
232 int dd4hep::printout(PrintLevel severity, const char* src, const std::string& fmt, ...) {
233  if (severity >= print_lvl) {
234  va_list args;
235  va_start(args, &fmt);
236  printout(severity, src, fmt.c_str(), args);
237  va_end(args);
238  }
239  return 1;
240 }
241 
248 int dd4hep::printout(PrintLevel severity, const std::string& src, const std::string& fmt, ...) {
249  if (severity >= print_lvl) {
250  va_list args;
251  va_start(args, &fmt);
252  printout(severity, src.c_str(), fmt.c_str(), args);
253  va_end(args);
254  }
255  return 1;
256 }
257 
264 int dd4hep::printout(PrintLevel severity, const char* src, const char* fmt, va_list& args) {
265  if (severity >= print_lvl) {
266  print_func_2(print_arg, PrintLevel(severity&(~FORCE_LEVEL)), src, fmt, args);
267  }
268  return 1;
269 }
270 
277 int dd4hep::printout(PrintLevel severity, const std::string& src, const char* fmt, va_list& args) {
278  return printout(severity, src.c_str(), fmt, args);
279 }
280 
287 int dd4hep::printout(PrintLevel severity, const char* src, const std::string& fmt, va_list& args) {
288  return printout(severity, src, fmt.c_str(), args);
289 }
290 
297 int dd4hep::printout(PrintLevel severity, const std::string& src, const std::string& fmt, va_list& args) {
298  return printout(severity, src.c_str(), fmt.c_str(), args);
299 }
300 
306 int dd4hep::except(const std::string& src, const std::string& fmt, ...) {
307  va_list args;
308  va_start(args, &fmt);
309  return except(src.c_str(),fmt.c_str(), args);
310 }
311 
317 int dd4hep::except(const char* src, const char* fmt, ...) {
318  va_list args;
319  va_start(args, fmt);
320  return except(src, fmt, args);
321 }
322 
329 int dd4hep::except(const std::string& src, const std::string& fmt, va_list& args) {
330  std::string msg = __format(fmt.c_str(), args);
331  va_end(args);
332  printout(ERROR, src.c_str(), "%s", msg.c_str());
333  // No return. Must call va_end here!
334  throw std::runtime_error((src+": "+msg).c_str());
335 }
336 
343 int dd4hep::except(const char* src, const char* fmt, va_list& args) {
344  std::string msg = __format(fmt, args);
345  va_end(args);
346  printout(ERROR, src, "%s", msg.c_str());
347  // No return. Must call va_end here!
348  throw std::runtime_error((std::string(src)+": "+msg).c_str());
349 }
350 
356 std::string dd4hep::format(const std::string& src, const std::string& fmt, ...) {
357  va_list args;
358  va_start(args, &fmt);
359  std::string str = format(src, fmt, args);
360  va_end(args);
361  return str;
362 }
363 
369 std::string dd4hep::format(const char* src, const char* fmt, ...) {
370  va_list args;
371  va_start(args, fmt);
372  std::string str = format(src, fmt, args);
373  va_end(args);
374  return str;
375 }
376 
383 std::string dd4hep::format(const std::string& src, const std::string& fmt, va_list& args) {
384  return format(src.c_str(), fmt.c_str(), args);
385 }
386 
393 std::string dd4hep::format(const char* src, const char* fmt, va_list& args) {
394  char str[4096];
395  size_t len1 = 0;
396  if ( src && *src ) ::snprintf(str, sizeof(str), "%s: ", src);
397  size_t len2 = ::vsnprintf(str + len1, sizeof(str) - len1, fmt, args);
398  if ( len2 > sizeof(str) - len1 ) {
399  len2 = sizeof(str) - len1 - 1;
400  str[sizeof(str)-1] = 0;
401  }
402  return std::string(str);
403 }
404 
406 dd4hep::PrintLevel dd4hep::setPrintLevel(PrintLevel new_level) {
407  PrintLevel old = print_lvl;
408  print_lvl = new_level;
409  return old;
410 }
411 
413 dd4hep::PrintLevel dd4hep::printLevel() {
414  return print_lvl;
415 }
416 
418 dd4hep::PrintLevel dd4hep::printLevel(const char* value) {
419  if ( !value ) except("Printout","Invalid printlevel requested [EINVAL: Null-pointer argument]");
420  // Explicit values
421  if ( strcmp(value,"NOLOG") == 0 ) return dd4hep::NOLOG;
422  if ( strcmp(value,"VERBOSE") == 0 ) return dd4hep::VERBOSE;
423  if ( strcmp(value,"DEBUG") == 0 ) return dd4hep::DEBUG;
424  if ( strcmp(value,"INFO") == 0 ) return dd4hep::INFO;
425  if ( strcmp(value,"WARNING") == 0 ) return dd4hep::WARNING;
426  if ( strcmp(value,"ERROR") == 0 ) return dd4hep::ERROR;
427  if ( strcmp(value,"FATAL") == 0 ) return dd4hep::FATAL;
428  if ( strcmp(value,"ALWAYS") == 0 ) return dd4hep::ALWAYS;
429  // Numeric values
430  if ( strcmp(value,"0") == 0 ) return dd4hep::NOLOG;
431  if ( strcmp(value,"1") == 0 ) return dd4hep::VERBOSE;
432  if ( strcmp(value,"2") == 0 ) return dd4hep::DEBUG;
433  if ( strcmp(value,"3") == 0 ) return dd4hep::INFO;
434  if ( strcmp(value,"4") == 0 ) return dd4hep::WARNING;
435  if ( strcmp(value,"5") == 0 ) return dd4hep::ERROR;
436  if ( strcmp(value,"6") == 0 ) return dd4hep::FATAL;
437  if ( strcmp(value,"7") == 0 ) return dd4hep::ALWAYS;
438  except("Printout","Unknown printlevel requested:%s",value);
439  return dd4hep::ALWAYS;
440 }
441 
443 dd4hep::PrintLevel dd4hep::printLevel(const std::string& value) {
444  return printLevel(value.c_str());
445 }
446 
448 bool dd4hep::isActivePrintLevel(int severity) {
449  return severity >= print_lvl;
450 }
451 
453 std::string dd4hep::setPrintFormat(const std::string& new_format) {
454  std::string old = print_fmt;
455  print_fmt = new_format;
456  return old;
457 }
458 
460 void dd4hep::setPrinter(void* arg, output_function1_t fcn) {
461  print_arg = arg;
462  print_func_1 = fcn ? fcn : _the_printer_1;
463 }
464 
466 void dd4hep::setPrinter2(void* arg, output_function2_t fcn) {
467  print_arg = arg;
468  print_func_2 = fcn ? fcn : _the_printer_2;
469 }
dd4hep::detail::printf
std::size_t printf(const char *fmt,...)
Definition: Printout.cpp:97
dd4hep::detail::errprintf
std::size_t errprintf(const char *fmt,...)
Definition: Printout.cpp:105
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
Printout.h