From 1822209cb9a3fc044fbf27e0861440313cd52bab Mon Sep 17 00:00:00 2001 From: nojhan Date: Thu, 1 Sep 2022 22:55:13 +0200 Subject: [PATCH] fix: const correctness --- clutchlog/clutchlog.h | 6 +- docs/classclutchlog-members.html | 2 +- docs/classclutchlog.html | 10 +- docs/clutchlog_8h.html | 8 +- docs/clutchlog_8h_source.html | 1469 +++++++++++++++--------------- docs/functions.html | 2 +- docs/functions_vars.html | 2 +- docs/globals.html | 4 +- docs/globals_defs.html | 4 +- docs/group__UseMacros.html | 26 +- docs/index.html | 73 +- docs/search/all_0.js | 2 +- docs/search/all_2.js | 2 +- docs/search/variables_0.js | 2 +- 14 files changed, 830 insertions(+), 782 deletions(-) diff --git a/clutchlog/clutchlog.h b/clutchlog/clutchlog.h index 19bd4f8..6332e50 100644 --- a/clutchlog/clutchlog.h +++ b/clutchlog/clutchlog.h @@ -471,7 +471,7 @@ class clutchlog /** Current format of the file output. */ std::string _format_dump; /** Character for filling. */ - const char _hfill_char; + char _hfill_char; /** Standard output. */ std::ostream* _out; #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1 @@ -794,11 +794,11 @@ class clutchlog const size_t right_len = format.size() - hfill_pos - hfill_tag.size(); if(right_len+left_len > _nb_columns) { // The right part would go over the terminal width: add a new line. - const std::string hfill(std::max(0, _nb_columns-right_len), _hfill_char); + const std::string hfill(std::max((size_t)0, _nb_columns-right_len), _hfill_char); format = replace(format, "\\{hfill\\}", "\n"+hfill); } else { // There is some space in between left and right parts. - const std::string hfill(std::max(0, _nb_columns - (right_len+left_len)), _hfill_char); + const std::string hfill(std::max((size_t)0, _nb_columns - (right_len+left_len)), _hfill_char); format = replace(format, "\\{hfill\\}", hfill); } } else { diff --git a/docs/classclutchlog-members.html b/docs/classclutchlog-members.html index c9753c5..1c9fa81 100644 --- a/docs/classclutchlog-members.html +++ b/docs/classclutchlog-members.html @@ -71,7 +71,7 @@ $(function() { - + diff --git a/docs/classclutchlog.html b/docs/classclutchlog.html index 0a9cac3..a47de9a 100644 --- a/docs/classclutchlog.html +++ b/docs/classclutchlog.html @@ -203,7 +203,7 @@ static unsigned int  +static char 
_format_dumpclutchlogprotected
_format_logclutchlogprotected
_hfill_charclutchlogprotected
_hfill_charclutchlogprotected
_in_fileclutchlogprotected
_in_funcclutchlogprotected
_in_lineclutchlogprotected
 Number of call stack levels to remove from depth display by default.
 
-static char default_hfill_char = CLUTCHLOG_HFILL_CHAR
default_hfill_char = CLUTCHLOG_HFILL_MARK
 Default character used as a filling for right-align the right part of messages with "{hfill}".
 
@@ -253,10 +253,10 @@ std::string  - - - + + + diff --git a/docs/clutchlog_8h.html b/docs/clutchlog_8h.html index c23689b..3cfe27e 100644 --- a/docs/clutchlog_8h.html +++ b/docs/clutchlog_8h.html @@ -170,10 +170,10 @@ Macros #define  - - - + + +
_format_dump
 Current format of the file output.
 
-const char _hfill_char
 Character for filling.
 
+char _hfill_char
 Character for filling.
 
std::ostream * _out
 Standard output.
CLUTCHLOG_STRIP_CALLS   5
 Compile-time number of call stack levels to remove from depth display by default.
 
-#define CLUTCHLOG_HFILL_CHAR   '.'
 Character used as a filling for right-align the right part of messages with "{hfill}".
 
+#define CLUTCHLOG_HFILL_MARK   '.'
 Character used as a filling for right-align the right part of messages with "{hfill}".
 
diff --git a/docs/clutchlog_8h_source.html b/docs/clutchlog_8h_source.html index d4f933a..c47e305 100644 --- a/docs/clutchlog_8h_source.html +++ b/docs/clutchlog_8h_source.html @@ -224,8 +224,8 @@ $(function() {
178 
181  #ifndef NDEBUG
182  #ifndef CLUTCHLOG_DEFAULT_FORMAT
-
183  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
185  #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
+
183  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1 // Enables: name, depth and depth_marks
+
185  #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1 // Enables: hfill
186  #define CLUTCHLOG_DEFAULT_FORMAT "[{name}] {level_letter}:{depth_marks} {msg} {hfill} {func} @ {file}:{line}\n"
187  #else
188  #define CLUTCHLOG_DEFAULT_FORMAT "[{name}] {level_letter}:{depth_marks} {msg}\t\t\t\t\t{func} @ {file}:{line}\n"
@@ -241,745 +241,770 @@ $(function() {
198  #else
199  #ifndef CLUTCHLOG_DEFAULT_FORMAT
200  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
202  #define CLUTCHLOG_DEFAULT_FORMAT "[{name}] {level_letter}:{depth_marks} {msg}\n"
+
202  #define CLUTCHLOG_DEFAULT_FORMAT "{level_letter}:{depth_marks} {msg} {hfill} {func}\n"
203  #else
-
204  #define CLUTCHLOG_DEFAULT_FORMAT "{level_letter} {msg}\n"
+
204  #define CLUTCHLOG_DEFAULT_FORMAT "{level_letter} {msg}\t\t\t\t\t{func}\n"
205  #endif
206  #endif
207  #endif
208  static inline std::string default_format = CLUTCHLOG_DEFAULT_FORMAT;
210 
-
211  #ifndef CLUTCHDUMP_DEFAULT_FORMAT
-
212  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
214  #define CLUTCHDUMP_DEFAULT_FORMAT "# [{name}] {level} in {func} (at depth {depth}) @ {file}:{line}"
-
215  #else
-
216  #define CLUTCHDUMP_DEFAULT_FORMAT "# {level} in {func} @ {file}:{line}"
-
217  #endif
-
218  #endif // CLUTCHDUMP_DEFAULT_FORMAT
-
219  static inline std::string dump_default_format = CLUTCHDUMP_DEFAULT_FORMAT;
-
221 
-
222  #ifndef CLUTCHDUMP_DEFAULT_SEP
-
223  #define CLUTCHDUMP_DEFAULT_SEP "\n"
-
225  #endif // CLUTCHDUMP_DEFAULT_SEP
-
226  static inline std::string dump_default_sep = CLUTCHDUMP_DEFAULT_SEP;
-
228 
-
229  #ifndef CLUTCHLOG_DEFAULT_DEPTH_MARK
-
230  #define CLUTCHLOG_DEFAULT_DEPTH_MARK ">"
-
232  #endif // CLUTCHLOG_DEFAULT_DEPTH_MARK
-
233  static inline std::string default_depth_mark = CLUTCHLOG_DEFAULT_DEPTH_MARK;
-
235 
-
236  #ifndef CLUTCHLOG_STRIP_CALLS
-
237  #define CLUTCHLOG_STRIP_CALLS 5
-
239  #endif // CLUTCHLOG_STRIP_CALLS
-
240  static inline unsigned int default_strip_calls = CLUTCHLOG_STRIP_CALLS;
-
242 
-
243  #ifndef CLUTCHLOG_HFILL_CHAR
-
244  #define CLUTCHLOG_HFILL_CHAR '.'
-
246  #endif // CLUTCHLOG_HFILL_CHAR
-
247  static inline char default_hfill_char = CLUTCHLOG_HFILL_CHAR;
-
249  /* @} */
-
250 
-
251 
-
252  public:
-
262  static clutchlog& logger()
-
263  {
-
264  static clutchlog instance;
-
265  return instance;
-
266  }
-
267 
-
269  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
-
270 
-
283  class fmt {
-
284  public:
-
286  enum class fg {
-
287  black = 30,
-
288  red = 31,
-
289  green = 32,
-
290  yellow = 33,
-
291  blue = 34,
-
292  magenta = 35,
-
293  cyan = 36,
-
294  white = 37,
-
295  none
-
296  } fore;
-
297 
-
299  enum class bg {
-
300  black = 40,
-
301  red = 41,
-
302  green = 42,
-
303  yellow = 43,
-
304  blue = 44,
-
305  magenta = 45,
-
306  cyan = 46,
-
307  white = 47,
-
308  none
-
309  } back;
-
310 
-
312  enum class typo {
-
313  reset = 0,
-
314  bold = 1,
-
315  underline = 4,
-
316  inverse = 7,
-
317  none
-
318  } style;
-
319 
-
321  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
-
322 
-
325  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
326  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
-
327  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
328  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
-
329  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
-
330  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
-
333  protected:
-
335  std::ostream& print_on( std::ostream& os) const
-
336  {
-
337  std::vector<int> codes; codes.reserve(3);
-
338  if(this->fore != fg::none) { codes.push_back(static_cast<int>(this->fore ));}
-
339  if(this->back != bg::none) { codes.push_back(static_cast<int>(this->back ));}
-
340  if(this->style != typo::none) { codes.push_back(static_cast<int>(this->style));}
-
341  if(codes.size() == 0) {return os;}
-
342 
-
343  os << "\033[";
-
344  assert(codes.size() > 0);
-
345  os << codes[0];
-
346  for(size_t i=1; i < codes.size(); ++i) {
-
347  os << ";" << codes[i];
-
348  }
-
349  os << "m";
-
350  return os;
-
351  }
-
352 
-
353  public:
-
365  friend std::ostream& operator<<(std::ostream& os, const fmt& fmt)
-
366  {
-
367  return fmt.print_on(os);
-
368  }
-
369 
-
380  std::string operator()( const std::string& msg ) const
-
381  {
-
382  std::ostringstream os;
-
383  this->print_on(os);
-
384  fmt reset(fmt::typo::reset);
-
385  os << msg;
-
386  reset.print_on(os);
-
387  return os.str();
-
388  }
-
389  }; // fmt class
-
390 
-
397  public:
-
398  clutchlog(clutchlog const&) = delete;
-
399  void operator=(clutchlog const&) = delete;
-
400 
-
401  private:
-
402  clutchlog() :
-
403  // system, main, log
-
404  _strip_calls(clutchlog::default_strip_calls),
-
405  _level_word({
-
406  {level::critical,"Critical"},
-
407  {level::error ,"Error"},
-
408  {level::warning ,"Warning"},
-
409  {level::progress,"Progress"},
-
410  {level::note ,"Note"},
-
411  {level::info ,"Info"},
-
412  {level::debug ,"Debug"},
-
413  {level::xdebug ,"XDebug"}
-
414  }),
-
415  _level_fmt({
-
416  {level::critical,fmt(fmt::fg::red, fmt::typo::underline)},
-
417  {level::error ,fmt(fmt::fg::red, fmt::typo::bold)},
-
418  {level::warning ,fmt(fmt::fg::magenta, fmt::typo::bold)},
-
419  {level::progress,fmt()},
-
420  {level::note ,fmt()},
-
421  {level::info ,fmt()},
-
422  {level::debug ,fmt()},
-
423  {level::xdebug ,fmt()}
-
424  }),
-
425  _format_log(clutchlog::default_format),
-
426  _format_dump(clutchlog::dump_default_format),
-
427  _hfill_char(clutchlog::default_hfill_char),
-
428  _out(&std::clog),
-
429 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
430  _depth(std::numeric_limits<size_t>::max() - _strip_calls),
-
431  _depth_mark(clutchlog::default_depth_mark),
-
432 #endif
-
433  _stage(level::error),
-
434  _in_file(".*"),
-
435  _in_func(".*"),
-
436  _in_line(".*")
-
437  {
-
438  // Reverse the level->word map into a word->level map.
-
439  for(auto& lw : _level_word) {
-
440  _word_level[lw.second] = lw.first;
-
441  }
-
442 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
-
443  struct winsize w;
-
444  ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
-
445  _nb_columns = w.ws_col;
-
446 #endif
-
447  }
-
448 
-
449  protected:
-
451  const size_t _strip_calls;
-
453  const std::map<level,std::string> _level_word;
-
455  std::map<std::string,level> _word_level;
-
457  std::map<level,fmt> _level_fmt;
-
459  std::string _format_log;
-
461  std::string _format_dump;
-
463  const char _hfill_char;
-
465  std::ostream* _out;
-
466 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
467 
-
468  size_t _depth;
-
470  std::string _depth_mark;
-
471 #endif
-
472 
-
473  level _stage;
-
475  std::regex _in_file;
-
477  std::regex _in_func;
-
479  std::regex _in_line;
-
480 
-
481 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
482 
-
483  static const size_t _max_buffer = 4096;
-
484 #endif
-
485 
-
486 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
-
487 
-
488  size_t _nb_columns;
-
489 #endif
-
490 
-
492  public:
+
211  #ifndef NDEBUG
+
212  #ifndef CLUTCHDUMP_DEFAULT_FORMAT
+
213  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
215  #define CLUTCHDUMP_DEFAULT_FORMAT "# [{name}] {level} in {func} (at depth {depth}) @ {file}:{line}"
+
216  #else
+
217  #define CLUTCHDUMP_DEFAULT_FORMAT "# {level} in {func} @ {file}:{line}"
+
218  #endif
+
219  #endif // CLUTCHDUMP_DEFAULT_FORMAT
+
220  #else
+
221  #ifndef CLUTCHDUMP_DEFAULT_FORMAT
+
222  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
224  #define CLUTCHDUMP_DEFAULT_FORMAT "# [{name}] {level} in {func} (at depth {depth})"
+
225  #else
+
226  #define CLUTCHDUMP_DEFAULT_FORMAT "# {level} in {func}"
+
227  #endif
+
228  #endif // CLUTCHDUMP_DEFAULT_FORMAT
+
229  #endif
+
230  static inline std::string dump_default_format = CLUTCHDUMP_DEFAULT_FORMAT;
+
232 
+
233  #ifndef CLUTCHDUMP_DEFAULT_SEP
+
234  #define CLUTCHDUMP_DEFAULT_SEP "\n"
+
236  #endif // CLUTCHDUMP_DEFAULT_SEP
+
237  static inline std::string dump_default_sep = CLUTCHDUMP_DEFAULT_SEP;
+
239 
+
240  #ifndef CLUTCHLOG_DEFAULT_DEPTH_MARK
+
241  #define CLUTCHLOG_DEFAULT_DEPTH_MARK ">"
+
243  #endif // CLUTCHLOG_DEFAULT_DEPTH_MARK
+
244  static inline std::string default_depth_mark = CLUTCHLOG_DEFAULT_DEPTH_MARK;
+
246 
+
247  #ifndef CLUTCHLOG_STRIP_CALLS
+
248  #define CLUTCHLOG_STRIP_CALLS 5
+
250  #endif // CLUTCHLOG_STRIP_CALLS
+
251  static inline unsigned int default_strip_calls = CLUTCHLOG_STRIP_CALLS;
+
253 
+
254  #ifndef CLUTCHLOG_HFILL_MARK
+
255  #define CLUTCHLOG_HFILL_MARK '.'
+
257  #endif // CLUTCHLOG_HFILL_MARK
+
258  static inline char default_hfill_char = CLUTCHLOG_HFILL_MARK;
+
260  /* @} */
+
261 
+
262 
+
263  public:
+
273  static clutchlog& logger()
+
274  {
+
275  static clutchlog instance;
+
276  return instance;
+
277  }
+
278 
+
280  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
+
281 
+
294  class fmt {
+
295  public:
+
297  enum class fg {
+
298  black = 30,
+
299  red = 31,
+
300  green = 32,
+
301  yellow = 33,
+
302  blue = 34,
+
303  magenta = 35,
+
304  cyan = 36,
+
305  white = 37,
+
306  none
+
307  } fore;
+
308 
+
310  enum class bg {
+
311  black = 40,
+
312  red = 41,
+
313  green = 42,
+
314  yellow = 43,
+
315  blue = 44,
+
316  magenta = 45,
+
317  cyan = 46,
+
318  white = 47,
+
319  none
+
320  } back;
+
321 
+
323  enum class typo {
+
324  reset = 0,
+
325  bold = 1,
+
326  underline = 4,
+
327  inverse = 7,
+
328  none
+
329  } style;
+
330 
+
332  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
+
333 
+
336  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
+
337  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
+
338  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
+
339  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
+
340  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
+
341  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
+
344  protected:
+
346  std::ostream& print_on( std::ostream& os) const
+
347  {
+
348  std::vector<int> codes; codes.reserve(3);
+
349  if(this->fore != fg::none) { codes.push_back(static_cast<int>(this->fore ));}
+
350  if(this->back != bg::none) { codes.push_back(static_cast<int>(this->back ));}
+
351  if(this->style != typo::none) { codes.push_back(static_cast<int>(this->style));}
+
352  if(codes.size() == 0) {return os;}
+
353 
+
354  os << "\033[";
+
355  assert(codes.size() > 0);
+
356  os << codes[0];
+
357  for(size_t i=1; i < codes.size(); ++i) {
+
358  os << ";" << codes[i];
+
359  }
+
360  os << "m";
+
361  return os;
+
362  }
+
363 
+
364  public:
+
376  friend std::ostream& operator<<(std::ostream& os, const fmt& fmt)
+
377  {
+
378  return fmt.print_on(os);
+
379  }
+
380 
+
391  std::string operator()( const std::string& msg ) const
+
392  {
+
393  std::ostringstream os;
+
394  this->print_on(os);
+
395  fmt reset(fmt::typo::reset);
+
396  os << msg;
+
397  reset.print_on(os);
+
398  return os.str();
+
399  }
+
400  }; // fmt class
+
401 
+
408  public:
+
409  clutchlog(clutchlog const&) = delete;
+
410  void operator=(clutchlog const&) = delete;
+
411 
+
412  private:
+
413  clutchlog() :
+
414  // system, main, log
+
415  _strip_calls(clutchlog::default_strip_calls),
+
416  _level_word({
+
417  {level::critical,"Critical"},
+
418  {level::error ,"Error"},
+
419  {level::warning ,"Warning"},
+
420  {level::progress,"Progress"},
+
421  {level::note ,"Note"},
+
422  {level::info ,"Info"},
+
423  {level::debug ,"Debug"},
+
424  {level::xdebug ,"XDebug"}
+
425  }),
+
426  _level_fmt({
+
427  {level::critical,fmt(fmt::fg::red, fmt::typo::underline)},
+
428  {level::error ,fmt(fmt::fg::red, fmt::typo::bold)},
+
429  {level::warning ,fmt(fmt::fg::magenta, fmt::typo::bold)},
+
430  {level::progress,fmt()},
+
431  {level::note ,fmt()},
+
432  {level::info ,fmt()},
+
433  {level::debug ,fmt()},
+
434  {level::xdebug ,fmt()}
+
435  }),
+
436  _format_log(clutchlog::default_format),
+
437  _format_dump(clutchlog::dump_default_format),
+
438  _hfill_char(clutchlog::default_hfill_char),
+
439  _out(&std::clog),
+
440 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
441  _depth(std::numeric_limits<size_t>::max() - _strip_calls),
+
442  _depth_mark(clutchlog::default_depth_mark),
+
443 #endif
+
444  _stage(level::error),
+
445  _in_file(".*"),
+
446  _in_func(".*"),
+
447  _in_line(".*")
+
448  {
+
449  // Reverse the level->word map into a word->level map.
+
450  for(auto& lw : _level_word) {
+
451  _word_level[lw.second] = lw.first;
+
452  }
+
453 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
+
454  struct winsize w;
+
455  ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
+
456  _nb_columns = w.ws_col;
+
457 #endif
+
458  }
+
459 
+
460  protected:
+
462  const size_t _strip_calls;
+
464  const std::map<level,std::string> _level_word;
+
466  std::map<std::string,level> _word_level;
+
468  std::map<level,fmt> _level_fmt;
+
470  std::string _format_log;
+
472  std::string _format_dump;
+
474  char _hfill_char;
+
476  std::ostream* _out;
+
477 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
478 
+
479  size_t _depth;
+
481  std::string _depth_mark;
+
482 #endif
+
483 
+
484  level _stage;
+
486  std::regex _in_file;
+
488  std::regex _in_func;
+
490  std::regex _in_line;
+
491 
+
492 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
493 
-
497  void format(const std::string& format) {_format_log = format;}
-
500  std::string format() const {return _format_log;}
+
494  static const size_t _max_buffer = 4096;
+
495 #endif
+
496 
+
497 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
+
498 
+
499  size_t _nb_columns;
+
500 #endif
501 
-
503  void format_comment(const std::string& format) {_format_dump = format;}
-
505  std::string format_comment() const {return _format_dump;}
-
506 
-
508  void out(std::ostream& out) {_out = &out;}
-
510  std::ostream& out() {return *_out;}
-
511 
-
512 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
513  void depth(size_t d) {_depth = d;}
-
516  size_t depth() const {return _depth;}
+
503  public:
+
504 
+
508  void format(const std::string& format) {_format_log = format;}
+
511  std::string format() const {return _format_log;}
+
512 
+
514  void format_comment(const std::string& format) {_format_dump = format;}
+
516  std::string format_comment() const {return _format_dump;}
517 
-
519  void depth_mark(std::string mark) {_depth_mark = mark;}
-
521  std::string depth_mark() const {return _depth_mark;}
-
522 #endif
-
523 
-
525  void threshold(level l) {_stage = l;}
-
527  void threshold(const std::string& l) {_stage = this->level_of(l);}
-
529  level threshold() const {return _stage;}
-
531  const std::map<std::string,level>& levels() const { return _word_level;}
-
532 
-
537  level level_of(const std::string name)
-
538  {
-
539  const auto ilevel = _word_level.find(name);
-
540  if( ilevel != std::end(_word_level)) {
-
541  return ilevel->second;
-
542  } else {
-
543  throw std::out_of_range("'" + name + "' is not a valid log level name");
-
544  }
-
545  }
-
546 
-
548  void file(std::string file) {_in_file = file;}
-
550  void func(std::string func) {_in_func = func;}
-
552  void line(std::string line) {_in_line = line;}
-
553 
-
555  void location(
-
556  const std::string& in_file,
-
557  const std::string& in_function=".*",
-
558  const std::string& in_line=".*"
-
559  )
-
560  {
-
561  file(in_file);
-
562  func(in_function);
-
563  line(in_line);
-
564  }
-
565 
-
570  template<class ... FMT>
-
571  void style(level stage, FMT... styles) { this->style(stage,fmt(styles...)); }
-
573  void style(level stage, fmt style) { _level_fmt.at(stage) = style; }
-
575  fmt style(level stage) const { return _level_fmt.at(stage); }
-
576 
-
579  public:
-
580 
-
584  struct scope_t {
-
587  bool matches;
-
589  level stage;
-
590 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
591 
-
592  size_t depth;
-
593 #endif
-
594 
-
595  bool there;
-
597  scope_t() :
-
598  matches(false),
-
599  stage(level::xdebug),
-
600 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
601  depth(0),
-
602 #endif
-
603  there(false)
-
604  {}
-
605  }; // scope_t
-
606 
-
607 
-
609  scope_t locate(
-
610  const level& stage,
-
611  const std::string& file,
-
612  const std::string& func,
-
613  const size_t line
-
614  ) const
-
615  {
-
616  scope_t scope; // False scope by default.
-
617 
-
618  /***** Log level stage *****/
-
619  // Test stage first, because it's fastest.
-
620  scope.stage = stage;
-
621  if(not (scope.stage <= _stage)) {
-
622  // Bypass useless computations if no match
-
623  // because of the stage.
-
624  return scope;
-
625  }
-
626 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
627  /***** Stack depth *****/
-
628  // Backtrace in second, quite fast.
-
629  size_t stack_depth;
-
630  void *buffer[_max_buffer];
-
631  stack_depth = backtrace(buffer, _max_buffer);
-
632  scope.depth = stack_depth;
-
633  if(not (scope.depth <= _depth + _strip_calls)) {
-
634  // Bypass if no match.
-
635  return scope;
-
636  }
-
637 #endif
-
638 
-
639  /***** Location *****/
-
640  // Location last, slowest.
-
641  std::ostringstream sline; sline << line;
-
642  scope.there =
-
643  std::regex_search(file, _in_file)
-
644  and std::regex_search(func, _in_func)
-
645  and std::regex_search(sline.str(), _in_line);
-
646 
-
647  // No need to retest stage and depth, which are true here.
-
648  scope.matches = scope.there;
-
649 
-
650  return scope;
-
651  } // locate
-
652 
-
660  std::string replace(
-
661  const std::string& form,
-
662  const std::string& mark,
-
663  const std::string& tag
-
664  ) const
-
665  {
-
666  // Useless debug code, unless something fancy would be done with name tags.
-
667  // std::regex re;
-
668  // try {
-
669  // re = std::regex(mark);
-
670  //
-
671  // } catch(const std::regex_error& e) {
-
672  // std::cerr << "ERROR with a regular expression \"" << mark << "\": ";
-
673  // switch(e.code()) {
-
674  // case std::regex_constants::error_collate:
-
675  // std::cerr << "the expression contains an invalid collating element name";
-
676  // break;
-
677  // case std::regex_constants::error_ctype:
-
678  // std::cerr << "the expression contains an invalid character class name";
-
679  // break;
-
680  // case std::regex_constants::error_escape:
-
681  // std::cerr << "the expression contains an invalid escaped character or a trailing escape";
-
682  // break;
-
683  // case std::regex_constants::error_backref:
-
684  // std::cerr << "the expression contains an invalid back reference";
-
685  // break;
-
686  // case std::regex_constants::error_brack:
-
687  // std::cerr << "the expression contains mismatched square brackets ('[' and ']')";
-
688  // break;
-
689  // case std::regex_constants::error_paren:
-
690  // std::cerr << "the expression contains mismatched parentheses ('(' and ')')";
-
691  // break;
-
692  // case std::regex_constants::error_brace:
-
693  // std::cerr << "the expression contains mismatched curly braces ('{' and '}')";
-
694  // break;
-
695  // case std::regex_constants::error_badbrace:
-
696  // std::cerr << "the expression contains an invalid range in a {} expression";
-
697  // break;
-
698  // case std::regex_constants::error_range:
-
699  // std::cerr << "the expression contains an invalid character range (e.g. [b-a])";
-
700  // break;
-
701  // case std::regex_constants::error_space:
-
702  // std::cerr << "there was not enough memory to convert the expression into a finite state machine";
-
703  // break;
-
704  // case std::regex_constants::error_badrepeat:
-
705  // std::cerr << "one of *?+{ was not preceded by a valid regular expression";
-
706  // break;
-
707  // case std::regex_constants::error_complexity:
-
708  // std::cerr << "the complexity of an attempted match exceeded a predefined level";
-
709  // break;
-
710  // case std::regex_constants::error_stack:
-
711  // std::cerr << "there was not enough memory to perform a match";
-
712  // break;
-
713  // default:
-
714  // std::cerr << "unknown error";
-
715  // }
-
716  // std::cerr << std::endl;
-
717  // throw;
-
718  // } // catch
-
719 
-
720  const std::regex re(mark);
-
721  return std::regex_replace(form, re, tag);
-
722  }
-
723 
-
725  std::string replace(
-
726  const std::string& form,
-
727  const std::string& mark,
-
728  const size_t tag
-
729  ) const
-
730  {
-
731  std::ostringstream stag; stag << tag;
-
732  return replace(form, mark, stag.str());
-
733  }
-
734 
-
736  std::string format(
-
737  std::string format,
-
738  const std::string& what,
-
739 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
740  const std::string& name,
-
741 #endif
-
742  const level& stage,
-
743  const std::string& file,
-
744  const std::string& func,
-
745  const size_t line
-
746 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
747  ,
-
748  const size_t depth
-
749 #endif
-
750  ) const
-
751  {
-
752  format = replace(format, "\\{msg\\}", what);
-
753  format = replace(format, "\\{file\\}", file);
-
754  format = replace(format, "\\{func\\}", func);
-
755  format = replace(format, "\\{line\\}", line);
-
756 
-
757  format = replace(format, "\\{level\\}", _level_word.at(stage));
-
758  std::string letter(1, _level_word.at(stage).at(0)); // char -> string
-
759  format = replace(format, "\\{level_letter\\}", letter);
-
760 
-
761 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
762  format = replace(format, "\\{name\\}", name);
-
763  format = replace(format, "\\{depth\\}", depth - _strip_calls);
-
764 
-
765  std::ostringstream chevrons;
-
766  for(size_t i = _strip_calls; i < depth; ++i) {
-
767  chevrons << _depth_mark;
-
768  }
-
769  format = replace(format, "\\{depth_marks\\}", chevrons.str());
-
770 #endif
-
771 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
-
772  const std::string hfill_tag = "{hfill}";
-
773  const size_t hfill_pos = format.find(hfill_tag);
-
774  if(hfill_pos != std::string::npos) {
-
775  const size_t left_len = hfill_pos;
-
776  const size_t right_len = format.size() - hfill_pos - hfill_tag.size();
-
777  if(right_len+left_len > _nb_columns) {
-
778  const std::string hfill(_nb_columns-right_len, _hfill_char);
-
779  format = replace(format, "\\{hfill\\}", "\n"+hfill);
-
780  } else {
-
781  const std::string hfill(_nb_columns - (right_len+left_len), _hfill_char);
-
782  format = replace(format, "\\{hfill\\}", hfill);
-
783  }
-
784  }
-
785 #endif
-
786  return _level_fmt.at(stage)(format);
-
787  }
-
788 
-
790  void log(
-
791  const level& stage,
-
792  const std::string& what,
-
793  const std::string& file, const std::string& func, size_t line
-
794  ) const
-
795  {
-
796  scope_t scope = locate(stage, file, func, line);
-
797 
-
798  if(scope.matches) {
-
799 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
800  *_out << format(_format_log, what, basename(getenv("_")),
-
801  stage, file, func,
-
802  line, scope.depth );
-
803 #else
-
804  *_out << format(_format_log, what,
-
805  stage, file, func,
-
806  line );
-
807 
-
808 #endif
-
809  _out->flush();
-
810  } // if scopes.matches
+
519  void out(std::ostream& out) {_out = &out;}
+
521  std::ostream& out() {return *_out;}
+
522 
+
523 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
524  void depth(size_t d) {_depth = d;}
+
527  size_t depth() const {return _depth;}
+
528 
+
530  void depth_mark(const std::string mark) {_depth_mark = mark;}
+
532  std::string depth_mark() const {return _depth_mark;}
+
533 #endif
+
534 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
+
535  void hfill_mark(const char mark) {_hfill_char = mark;}
+
538  char hfill_mark() const {return _hfill_char;}
+
539 #endif
+
540 
+
542  void threshold(level l) {_stage = l;}
+
544  void threshold(const std::string& l) {_stage = this->level_of(l);}
+
546  level threshold() const {return _stage;}
+
548  const std::map<std::string,level>& levels() const { return _word_level;}
+
549 
+
554  level level_of(const std::string name)
+
555  {
+
556  const auto ilevel = _word_level.find(name);
+
557  if( ilevel != std::end(_word_level)) {
+
558  return ilevel->second;
+
559  } else {
+
560  throw std::out_of_range("'" + name + "' is not a valid log level name");
+
561  }
+
562  }
+
563 
+
565  void file(std::string file) {_in_file = file;}
+
567  void func(std::string func) {_in_func = func;}
+
569  void line(std::string line) {_in_line = line;}
+
570 
+
572  void location(
+
573  const std::string& in_file,
+
574  const std::string& in_function=".*",
+
575  const std::string& in_line=".*"
+
576  )
+
577  {
+
578  file(in_file);
+
579  func(in_function);
+
580  line(in_line);
+
581  }
+
582 
+
587  template<class ... FMT>
+
588  void style(level stage, FMT... styles) { this->style(stage,fmt(styles...)); }
+
590  void style(level stage, fmt style) { _level_fmt.at(stage) = style; }
+
592  fmt style(level stage) const { return _level_fmt.at(stage); }
+
593 
+
596  public:
+
597 
+
601  struct scope_t {
+
604  bool matches;
+
606  level stage;
+
607 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
608 
+
609  size_t depth;
+
610 #endif
+
611 
+
612  bool there;
+
614  scope_t() :
+
615  matches(false),
+
616  stage(level::xdebug),
+
617 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
618  depth(0),
+
619 #endif
+
620  there(false)
+
621  {}
+
622  }; // scope_t
+
623 
+
624 
+
626  scope_t locate(
+
627  const level& stage,
+
628  const std::string& file,
+
629  const std::string& func,
+
630  const size_t line
+
631  ) const
+
632  {
+
633  scope_t scope; // False scope by default.
+
634 
+
635  /***** Log level stage *****/
+
636  // Test stage first, because it's fastest.
+
637  scope.stage = stage;
+
638  if(not (scope.stage <= _stage)) {
+
639  // Bypass useless computations if no match
+
640  // because of the stage.
+
641  return scope;
+
642  }
+
643 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
644  /***** Stack depth *****/
+
645  // Backtrace in second, quite fast.
+
646  size_t stack_depth;
+
647  void *buffer[_max_buffer];
+
648  stack_depth = backtrace(buffer, _max_buffer);
+
649  scope.depth = stack_depth;
+
650  if(not (scope.depth <= _depth + _strip_calls)) {
+
651  // Bypass if no match.
+
652  return scope;
+
653  }
+
654 #endif
+
655 
+
656  /***** Location *****/
+
657  // Location last, slowest.
+
658  std::ostringstream sline; sline << line;
+
659  scope.there =
+
660  std::regex_search(file, _in_file)
+
661  and std::regex_search(func, _in_func)
+
662  and std::regex_search(sline.str(), _in_line);
+
663 
+
664  // No need to retest stage and depth, which are true here.
+
665  scope.matches = scope.there;
+
666 
+
667  return scope;
+
668  } // locate
+
669 
+
677  std::string replace(
+
678  const std::string& form,
+
679  const std::string& mark,
+
680  const std::string& tag
+
681  ) const
+
682  {
+
683  // Useless debug code, unless something fancy would be done with name tags.
+
684  // std::regex re;
+
685  // try {
+
686  // re = std::regex(mark);
+
687  //
+
688  // } catch(const std::regex_error& e) {
+
689  // std::cerr << "ERROR with a regular expression \"" << mark << "\": ";
+
690  // switch(e.code()) {
+
691  // case std::regex_constants::error_collate:
+
692  // std::cerr << "the expression contains an invalid collating element name";
+
693  // break;
+
694  // case std::regex_constants::error_ctype:
+
695  // std::cerr << "the expression contains an invalid character class name";
+
696  // break;
+
697  // case std::regex_constants::error_escape:
+
698  // std::cerr << "the expression contains an invalid escaped character or a trailing escape";
+
699  // break;
+
700  // case std::regex_constants::error_backref:
+
701  // std::cerr << "the expression contains an invalid back reference";
+
702  // break;
+
703  // case std::regex_constants::error_brack:
+
704  // std::cerr << "the expression contains mismatched square brackets ('[' and ']')";
+
705  // break;
+
706  // case std::regex_constants::error_paren:
+
707  // std::cerr << "the expression contains mismatched parentheses ('(' and ')')";
+
708  // break;
+
709  // case std::regex_constants::error_brace:
+
710  // std::cerr << "the expression contains mismatched curly braces ('{' and '}')";
+
711  // break;
+
712  // case std::regex_constants::error_badbrace:
+
713  // std::cerr << "the expression contains an invalid range in a {} expression";
+
714  // break;
+
715  // case std::regex_constants::error_range:
+
716  // std::cerr << "the expression contains an invalid character range (e.g. [b-a])";
+
717  // break;
+
718  // case std::regex_constants::error_space:
+
719  // std::cerr << "there was not enough memory to convert the expression into a finite state machine";
+
720  // break;
+
721  // case std::regex_constants::error_badrepeat:
+
722  // std::cerr << "one of *?+{ was not preceded by a valid regular expression";
+
723  // break;
+
724  // case std::regex_constants::error_complexity:
+
725  // std::cerr << "the complexity of an attempted match exceeded a predefined level";
+
726  // break;
+
727  // case std::regex_constants::error_stack:
+
728  // std::cerr << "there was not enough memory to perform a match";
+
729  // break;
+
730  // default:
+
731  // std::cerr << "unknown error";
+
732  // }
+
733  // std::cerr << std::endl;
+
734  // throw;
+
735  // } // catch
+
736 
+
737  const std::regex re(mark);
+
738  return std::regex_replace(form, re, tag);
+
739  }
+
740 
+
742  std::string replace(
+
743  const std::string& form,
+
744  const std::string& mark,
+
745  const size_t tag
+
746  ) const
+
747  {
+
748  std::ostringstream stag; stag << tag;
+
749  return replace(form, mark, stag.str());
+
750  }
+
751 
+
753  std::string format(
+
754  std::string format,
+
755  const std::string& what,
+
756 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
757  const std::string& name,
+
758 #endif
+
759  const level& stage,
+
760  const std::string& file,
+
761  const std::string& func,
+
762  const size_t line
+
763 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
764  ,
+
765  const size_t depth
+
766 #endif
+
767  ) const
+
768  {
+
769  format = replace(format, "\\{msg\\}", what);
+
770  format = replace(format, "\\{file\\}", file);
+
771  format = replace(format, "\\{func\\}", func);
+
772  format = replace(format, "\\{line\\}", line);
+
773 
+
774  format = replace(format, "\\{level\\}", _level_word.at(stage));
+
775  std::string letter(1, _level_word.at(stage).at(0)); // char -> string
+
776  format = replace(format, "\\{level_letter\\}", letter);
+
777 
+
778 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
779  format = replace(format, "\\{name\\}", name);
+
780  format = replace(format, "\\{depth\\}", depth - _strip_calls);
+
781 
+
782  std::ostringstream chevrons;
+
783  for(size_t i = _strip_calls; i < depth; ++i) {
+
784  chevrons << _depth_mark;
+
785  }
+
786  format = replace(format, "\\{depth_marks\\}", chevrons.str());
+
787 #endif
+
788 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
+
789  const std::string hfill_tag = "{hfill}";
+
790  const size_t hfill_pos = format.find(hfill_tag);
+
791  if(hfill_pos != std::string::npos) {
+
792  if(_nb_columns > 0) {
+
793  const size_t left_len = hfill_pos;
+
794  const size_t right_len = format.size() - hfill_pos - hfill_tag.size();
+
795  if(right_len+left_len > _nb_columns) {
+
796  // The right part would go over the terminal width: add a new line.
+
797  const std::string hfill(std::max((size_t)0, _nb_columns-right_len), _hfill_char);
+
798  format = replace(format, "\\{hfill\\}", "\n"+hfill);
+
799  } else {
+
800  // There is some space in between left and right parts.
+
801  const std::string hfill(std::max((size_t)0, _nb_columns - (right_len+left_len)), _hfill_char);
+
802  format = replace(format, "\\{hfill\\}", hfill);
+
803  }
+
804  } else {
+
805  // We don't know the terminal width.
+
806  format = replace(format, "\\{hfill\\}", _hfill_char);
+
807  }
+
808  }
+
809 #endif
+
810  return _level_fmt.at(stage)(format);
811  }
812 
-
814  template<class In>
-
815  void dump(
-
816  const level& stage,
-
817  const In container_begin, const In container_end,
-
818  const std::string& file, const std::string& func, size_t line,
-
819  const std::string& filename_template = "dump_{n}.dat",
-
820  const std::string sep = dump_default_sep
-
821  ) const
-
822  {
-
823  scope_t scope = locate(stage, file, func, line);
-
824 
-
825  if(scope.matches) {
-
826  const std::string tag = "\\{n\\}";
-
827  const std::regex re(tag);
-
828  std::string outfile = "";
-
829 
-
830  // If the file name template has the {n} tag.
-
831  if(std::regex_search(filename_template, re)) {
-
832  // Increment n until a free one is found.
-
833  size_t n = 0;
-
834  do {
-
835  outfile = replace(filename_template, tag, n);
-
836  n++;
-
837  } while( fs::exists( outfile ) );
-
838 
-
839  } else {
-
840  // Use the parameter as is.
-
841  outfile = filename_template;
-
842  }
-
843 
-
844  std::ofstream fd(outfile);
-
845 
-
846  if(_format_dump.size() > 0) {
-
847 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
848  fd << format(_format_dump, "", basename(getenv("_")),
-
849  stage, file, func,
-
850  line, scope.depth );
-
851 #else
-
852  fd << format(_format_dump, "",
-
853  stage, file, func,
-
854  line );
-
855 #endif
-
856  fd << sep; // sep after comment line.
-
857  }
-
858 
-
859  std::copy(container_begin, container_end,
-
860  std::ostream_iterator<typename In::value_type>(fd, sep.c_str()));
-
861 
-
862  fd.close();
-
863  } // if scopes.matches
-
864  }
-
865 
-
867 };
-
868 
-
871 #else // not WITH_CLUTCHLOG
-
872 
-
873 
-
874 /**********************************************************************
-
875  * Fake implementation
-
876  **********************************************************************/
-
877 
-
878 // Equivalent class with empty methods, will be optimized out
-
879 // while allowing to actually have calls implemented without WITH_CLUTCHLOG guards.
-
880 #pragma GCC diagnostic push
-
881 #pragma GCC diagnostic ignored "-Wreturn-type"
-
882 class clutchlog
-
883 {
-
884  public:
-
885  static clutchlog& logger() {}
-
886  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
-
887  class fmt {
-
888  public:
-
889  enum class fg { black, red, green, yellow, blue, magenta, cyan, white, none } fore;
-
890  enum class bg { black, red, green, yellow, blue, magenta, cyan, white, none } back;
-
891  enum class typo { reset, bold, underline, inverse, none } style;
-
892  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
-
893  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
894  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
-
895  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
896  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
-
897  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
-
898  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
-
899  protected:
-
900  std::ostream& print_on(std::ostream&) const {}
-
901  public:
-
902  friend std::ostream& operator<<(std::ostream&, const fmt&) {}
-
903  std::string operator()(const std::string&) const {}
-
904  };
-
905  public:
-
906  clutchlog(clutchlog const&) = delete;
-
907  void operator=(clutchlog const&) = delete;
-
908  private:
-
909  clutchlog() {}
-
910  protected:
-
911  struct scope_t {};
-
912  scope_t locate(
-
913  const level&,
-
914  const std::string&,
-
915  const std::string&,
-
916  const size_t
-
917  ) const
-
918  {}
-
919  public:
-
920  void format(const std::string&) {}
-
921  std::string format() const {}
-
922 
-
923  void format_comment(const std::string&) {}
-
924  std::string format_comment() const {}
-
925 
-
926  void out(std::ostream&) {}
-
927  std::ostream& out() {}
-
928 
-
929 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
930  void depth(size_t) {}
-
931  size_t depth() const {}
-
932 
-
933  void depth_mark(std::string) {}
-
934  std::string depth_mark() const {}
-
935 #endif
-
936 
-
937  void threshold(level) {}
-
938  void threshold(const std::string&) {}
-
939  level threshold() const {}
-
940  const std::map<std::string,level> levels() const {};
-
941  level level_of(const std::string) {}
-
942 
-
943  void file(std::string) {}
-
944  void func(std::string) {}
-
945  void line(std::string) {}
+
814  void log(
+
815  const level& stage,
+
816  const std::string& what,
+
817  const std::string& file, const std::string& func, size_t line
+
818  ) const
+
819  {
+
820  scope_t scope = locate(stage, file, func, line);
+
821 
+
822  if(scope.matches) {
+
823 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
824  *_out << format(_format_log, what, basename(getenv("_")),
+
825  stage, file, func,
+
826  line, scope.depth );
+
827 #else
+
828  *_out << format(_format_log, what,
+
829  stage, file, func,
+
830  line );
+
831 
+
832 #endif
+
833  _out->flush();
+
834  } // if scopes.matches
+
835  }
+
836 
+
838  template<class In>
+
839  void dump(
+
840  const level& stage,
+
841  const In container_begin, const In container_end,
+
842  const std::string& file, const std::string& func, size_t line,
+
843  const std::string& filename_template = "dump_{n}.dat",
+
844  const std::string sep = dump_default_sep
+
845  ) const
+
846  {
+
847  scope_t scope = locate(stage, file, func, line);
+
848 
+
849  if(scope.matches) {
+
850  const std::string tag = "\\{n\\}";
+
851  const std::regex re(tag);
+
852  std::string outfile = "";
+
853 
+
854  // If the file name template has the {n} tag.
+
855  if(std::regex_search(filename_template, re)) {
+
856  // Increment n until a free one is found.
+
857  size_t n = 0;
+
858  do {
+
859  outfile = replace(filename_template, tag, n);
+
860  n++;
+
861  } while( fs::exists( outfile ) );
+
862 
+
863  } else {
+
864  // Use the parameter as is.
+
865  outfile = filename_template;
+
866  }
+
867 
+
868  std::ofstream fd(outfile);
+
869 
+
870  if(_format_dump.size() > 0) {
+
871 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
872  fd << format(_format_dump, "", basename(getenv("_")),
+
873  stage, file, func,
+
874  line, scope.depth );
+
875 #else
+
876  fd << format(_format_dump, "",
+
877  stage, file, func,
+
878  line );
+
879 #endif
+
880  fd << sep; // sep after comment line.
+
881  }
+
882 
+
883  std::copy(container_begin, container_end,
+
884  std::ostream_iterator<typename In::value_type>(fd, sep.c_str()));
+
885 
+
886  fd.close();
+
887  } // if scopes.matches
+
888  }
+
889 
+
891 };
+
892 
+
895 #else // not WITH_CLUTCHLOG
+
896 
+
897 
+
898 /**********************************************************************
+
899  * Fake implementation
+
900  **********************************************************************/
+
901 
+
902 // Equivalent class with empty methods, will be optimized out
+
903 // while allowing to actually have calls implemented without WITH_CLUTCHLOG guards.
+
904 #pragma GCC diagnostic push
+
905 #pragma GCC diagnostic ignored "-Wreturn-type"
+
906 class clutchlog
+
907 {
+
908  public:
+
909  static clutchlog& logger() {}
+
910  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
+
911  class fmt {
+
912  public:
+
913  enum class fg { black, red, green, yellow, blue, magenta, cyan, white, none } fore;
+
914  enum class bg { black, red, green, yellow, blue, magenta, cyan, white, none } back;
+
915  enum class typo { reset, bold, underline, inverse, none } style;
+
916  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
+
917  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
+
918  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
+
919  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
+
920  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
+
921  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
+
922  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
+
923  protected:
+
924  std::ostream& print_on(std::ostream&) const {}
+
925  public:
+
926  friend std::ostream& operator<<(std::ostream&, const fmt&) {}
+
927  std::string operator()(const std::string&) const {}
+
928  };
+
929  public:
+
930  clutchlog(clutchlog const&) = delete;
+
931  void operator=(clutchlog const&) = delete;
+
932  private:
+
933  clutchlog() {}
+
934  protected:
+
935  struct scope_t {};
+
936  scope_t locate(
+
937  const level&,
+
938  const std::string&,
+
939  const std::string&,
+
940  const size_t
+
941  ) const
+
942  {}
+
943  public:
+
944  void format(const std::string&) {}
+
945  std::string format() const {}
946 
-
947 #pragma GCC diagnostic push
-
948 #pragma GCC diagnostic ignored "-Wunused-parameter"
-
949  void location(
-
950  const std::string&,
-
951  const std::string& in_function=".*",
-
952  const std::string& in_line=".*"
-
953  )
-
954  {}
-
955 #pragma GCC diagnostic pop
-
956  void style(level, fmt) {}
-
957  fmt style(level) const {}
-
958  public:
-
959  std::string replace(
-
960  const std::string&,
-
961  const std::string&,
-
962  const std::string&
-
963  ) const
-
964  {}
-
965 
-
966  std::string replace(
-
967  const std::string&,
-
968  const std::string&,
-
969  const size_t
-
970  ) const
-
971  {}
-
972 
-
973  std::string format(
-
974  std::string,
-
975  const std::string&,
-
976 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
977  const std::string&,
-
978 #endif
-
979  const level&,
-
980  const std::string&,
-
981  const std::string&,
-
982  const size_t
-
983 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
984  ,
-
985  const size_t
-
986 #endif
-
987  ) const
-
988  {}
-
989 
-
990  void log(
-
991  const level&,
-
992  const std::string&,
-
993  const std::string&, const std::string&, size_t
-
994  ) const
-
995  {}
-
996 
-
997  template<class In>
-
998  void dump(
-
999  const level&,
-
1000  const In, const In,
-
1001  const std::string&, const std::string&, size_t,
-
1002  const std::string&,
-
1003  const std::string
-
1004  ) const
-
1005  {}
-
1006 };
-
1007 #pragma GCC diagnostic pop
-
1008 #endif // WITH_CLUTCHLOG
-
1009 
-
1010 #endif // __CLUTCHLOG_H__
+
947  void format_comment(const std::string&) {}
+
948  std::string format_comment() const {}
+
949 
+
950  void out(std::ostream&) {}
+
951  std::ostream& out() {}
+
952 
+
953 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
954  void depth(size_t) {}
+
955  size_t depth() const {}
+
956 
+
957  void depth_mark(const std::string) {}
+
958  std::string depth_mark() const {}
+
959 #endif
+
960 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
+
961  void hfill_mark(const char) {}
+
962  char hfill_mark() const {}
+
963 #endif
+
964 
+
965  void threshold(level) {}
+
966  void threshold(const std::string&) {}
+
967  level threshold() const {}
+
968  const std::map<std::string,level> levels() const {};
+
969  level level_of(const std::string) {}
+
970 
+
971  void file(std::string) {}
+
972  void func(std::string) {}
+
973  void line(std::string) {}
+
974 
+
975 #pragma GCC diagnostic push
+
976 #pragma GCC diagnostic ignored "-Wunused-parameter"
+
977  void location(
+
978  const std::string&,
+
979  const std::string& in_function=".*",
+
980  const std::string& in_line=".*"
+
981  )
+
982  {}
+
983 #pragma GCC diagnostic pop
+
984  void style(level, fmt) {}
+
985  fmt style(level) const {}
+
986  public:
+
987  std::string replace(
+
988  const std::string&,
+
989  const std::string&,
+
990  const std::string&
+
991  ) const
+
992  {}
+
993 
+
994  std::string replace(
+
995  const std::string&,
+
996  const std::string&,
+
997  const size_t
+
998  ) const
+
999  {}
+
1000 
+
1001  std::string format(
+
1002  std::string,
+
1003  const std::string&,
+
1004 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
1005  const std::string&,
+
1006 #endif
+
1007  const level&,
+
1008  const std::string&,
+
1009  const std::string&,
+
1010  const size_t
+
1011 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
1012  ,
+
1013  const size_t
+
1014 #endif
+
1015  ) const
+
1016  {}
+
1017 
+
1018  void log(
+
1019  const level&,
+
1020  const std::string&,
+
1021  const std::string&, const std::string&, size_t
+
1022  ) const
+
1023  {}
+
1024 
+
1025  template<class In>
+
1026  void dump(
+
1027  const level&,
+
1028  const In, const In,
+
1029  const std::string&, const std::string&, size_t,
+
1030  const std::string&,
+
1031  const std::string
+
1032  ) const
+
1033  {}
+
1034 };
+
1035 #pragma GCC diagnostic pop
+
1036 #endif // WITH_CLUTCHLOG
+
1037 
+
1038 #endif // __CLUTCHLOG_H__
-
void file(std::string file)
Set the regular expression filtering the file location.
Definition: clutchlog.h:548
-
#define CLUTCHDUMP_DEFAULT_FORMAT
Compile-time default format of the comment line in file dump.
Definition: clutchlog.h:216
-
fg
Foreground color codes.
Definition: clutchlog.h:286
-
static std::string dump_default_format
Default format of the comment line in file dump.
Definition: clutchlog.h:220
-
const std::map< std::string, level > & levels() const
Get the map of available log levels string representations toward their identifier....
Definition: clutchlog.h:531
-
void out(std::ostream &out)
Set the output stream on which to print.
Definition: clutchlog.h:508
-
fmt()
&#160;Empty constructor, only useful for a no-op formatter.
Definition: clutchlog.h:321
-
static clutchlog & logger()
Get the logger instance.
Definition: clutchlog.h:262
-
void line(std::string line)
Set the regular expression filtering the line location.
Definition: clutchlog.h:552
-
void format_comment(const std::string &format)
Set the template string for dumps.
Definition: clutchlog.h:503
-
typo
Typographic style codes.
Definition: clutchlog.h:312
-
#define CLUTCHDUMP_DEFAULT_SEP
Compile-time default item separator for dump.
Definition: clutchlog.h:224
-
static std::string default_depth_mark
Default mark for stack depth.
Definition: clutchlog.h:234
+
void file(std::string file)
Set the regular expression filtering the file location.
Definition: clutchlog.h:565
+
#define CLUTCHDUMP_DEFAULT_FORMAT
Compile-time default format of the comment line in file dump.
Definition: clutchlog.h:217
+
fg
Foreground color codes.
Definition: clutchlog.h:297
+
static std::string dump_default_format
Default format of the comment line in file dump.
Definition: clutchlog.h:231
+
const std::map< std::string, level > & levels() const
Get the map of available log levels string representations toward their identifier....
Definition: clutchlog.h:548
+
void out(std::ostream &out)
Set the output stream on which to print.
Definition: clutchlog.h:519
+
fmt()
&#160;Empty constructor, only useful for a no-op formatter.
Definition: clutchlog.h:332
+
static clutchlog & logger()
Get the logger instance.
Definition: clutchlog.h:273
+
void line(std::string line)
Set the regular expression filtering the line location.
Definition: clutchlog.h:569
+
void format_comment(const std::string &format)
Set the template string for dumps.
Definition: clutchlog.h:514
+
typo
Typographic style codes.
Definition: clutchlog.h:323
+
#define CLUTCHDUMP_DEFAULT_SEP
Compile-time default item separator for dump.
Definition: clutchlog.h:235
+
#define CLUTCHLOG_HFILL_MARK
Character used as a filling for right-align the right part of messages with "{hfill}".
Definition: clutchlog.h:256
+
static std::string default_depth_mark
Default mark for stack depth.
Definition: clutchlog.h:245
#define CLUTCHLOG_DEFAULT_FORMAT
Compile-time default format of the messages (debug mode: with absolute location).
Definition: clutchlog.h:194
-
std::string format() const
Get the template string.
Definition: clutchlog.h:500
-
void log(const level &stage, const std::string &what, const std::string &file, const std::string &func, size_t line) const
Print a log message IF the location matches the given one.
Definition: clutchlog.h:790
-
level level_of(const std::string name)
Return the log level tag corresponding to the given pre-configured name.
Definition: clutchlog.h:537
-
std::string _format_dump
Current format of the file output.
Definition: clutchlog.h:461
-
std::string operator()(const std::string &msg) const
Format the given string with the currently encoded format.
Definition: clutchlog.h:380
-
std::string format(std::string format, const std::string &what, const level &stage, const std::string &file, const std::string &func, const size_t line) const
Substitute all tags in the format string with the corresponding information and apply the style corre...
Definition: clutchlog.h:736
-
std::string _format_log
Current format of the standard output.
Definition: clutchlog.h:459
-
level
Available log levels.
Definition: clutchlog.h:269
-
level stage
Current log level.
Definition: clutchlog.h:589
-
#define CLUTCHLOG_HFILL_CHAR
Character used as a filling for right-align the right part of messages with "{hfill}".
Definition: clutchlog.h:245
-
#define CLUTCHLOG_DEFAULT_DEPTH_MARK
Compile-time default mark for stack depth.
Definition: clutchlog.h:231
-
friend std::ostream & operator<<(std::ostream &os, const fmt &fmt)
Output stream overload.
Definition: clutchlog.h:365
-
std::map< level, fmt > _level_fmt
Dictionary of level identifier to their format.
Definition: clutchlog.h:457
-
std::regex _in_line
Current line location filter.
Definition: clutchlog.h:479
+
std::string format() const
Get the template string.
Definition: clutchlog.h:511
+
void log(const level &stage, const std::string &what, const std::string &file, const std::string &func, size_t line) const
Print a log message IF the location matches the given one.
Definition: clutchlog.h:814
+
level level_of(const std::string name)
Return the log level tag corresponding to the given pre-configured name.
Definition: clutchlog.h:554
+
std::string _format_dump
Current format of the file output.
Definition: clutchlog.h:472
+
std::string operator()(const std::string &msg) const
Format the given string with the currently encoded format.
Definition: clutchlog.h:391
+
std::string format(std::string format, const std::string &what, const level &stage, const std::string &file, const std::string &func, const size_t line) const
Substitute all tags in the format string with the corresponding information and apply the style corre...
Definition: clutchlog.h:753
+
std::string _format_log
Current format of the standard output.
Definition: clutchlog.h:470
+
level
Available log levels.
Definition: clutchlog.h:280
+
level stage
Current log level.
Definition: clutchlog.h:606
+
#define CLUTCHLOG_DEFAULT_DEPTH_MARK
Compile-time default mark for stack depth.
Definition: clutchlog.h:242
+
friend std::ostream & operator<<(std::ostream &os, const fmt &fmt)
Output stream overload.
Definition: clutchlog.h:376
+
std::map< level, fmt > _level_fmt
Dictionary of level identifier to their format.
Definition: clutchlog.h:468
+
std::regex _in_line
Current line location filter.
Definition: clutchlog.h:490
enum clutchlog::fmt::typo style
Typographic style.
-
level _stage
Current log level.
Definition: clutchlog.h:473
-
const size_t _strip_calls
Current number of call stack levels to remove from depth display.
Definition: clutchlog.h:451
-
std::string format_comment() const
Get the template string for dumps.
Definition: clutchlog.h:505
-
const char _hfill_char
Character for filling.
Definition: clutchlog.h:463
-
#define CLUTCHLOG_STRIP_CALLS
Compile-time number of call stack levels to remove from depth display by default.
Definition: clutchlog.h:238
-
std::ostream * _out
Standard output.
Definition: clutchlog.h:465
-
void func(std::string func)
Set the regular expression filtering the function location.
Definition: clutchlog.h:550
-
void location(const std::string &in_file, const std::string &in_function=".*", const std::string &in_line=".*")
Set the regular expressions filtering the location.
Definition: clutchlog.h:555
-
static char default_hfill_char
Default character used as a filling for right-align the right part of messages with "{hfill}".
Definition: clutchlog.h:248
-
void dump(const level &stage, const In container_begin, const In container_end, const std::string &file, const std::string &func, size_t line, const std::string &filename_template="dump_{n}.dat", const std::string sep=dump_default_sep) const
Dump a serializable container after a comment line with log information.
Definition: clutchlog.h:815
-
std::string replace(const std::string &form, const std::string &mark, const size_t tag) const
Replace mark by tag in form, converting tag to its string representation first.
Definition: clutchlog.h:725
-
Color and style formatter for ANSI terminal escape sequences.
Definition: clutchlog.h:283
-
std::regex _in_file
Current file location filter.
Definition: clutchlog.h:475
-
std::ostream & out()
Get the output stream on which to print.
Definition: clutchlog.h:510
-
std::string replace(const std::string &form, const std::string &mark, const std::string &tag) const
Replace mark by tag in form.
Definition: clutchlog.h:660
-
static unsigned int default_strip_calls
Number of call stack levels to remove from depth display by default.
Definition: clutchlog.h:241
+
level _stage
Current log level.
Definition: clutchlog.h:484
+
const size_t _strip_calls
Current number of call stack levels to remove from depth display.
Definition: clutchlog.h:462
+
std::string format_comment() const
Get the template string for dumps.
Definition: clutchlog.h:516
+
#define CLUTCHLOG_STRIP_CALLS
Compile-time number of call stack levels to remove from depth display by default.
Definition: clutchlog.h:249
+
std::ostream * _out
Standard output.
Definition: clutchlog.h:476
+
void func(std::string func)
Set the regular expression filtering the function location.
Definition: clutchlog.h:567
+
void location(const std::string &in_file, const std::string &in_function=".*", const std::string &in_line=".*")
Set the regular expressions filtering the location.
Definition: clutchlog.h:572
+
static char default_hfill_char
Default character used as a filling for right-align the right part of messages with "{hfill}".
Definition: clutchlog.h:259
+
void dump(const level &stage, const In container_begin, const In container_end, const std::string &file, const std::string &func, size_t line, const std::string &filename_template="dump_{n}.dat", const std::string sep=dump_default_sep) const
Dump a serializable container after a comment line with log information.
Definition: clutchlog.h:839
+
std::string replace(const std::string &form, const std::string &mark, const size_t tag) const
Replace mark by tag in form, converting tag to its string representation first.
Definition: clutchlog.h:742
+
Color and style formatter for ANSI terminal escape sequences.
Definition: clutchlog.h:294
+
std::regex _in_file
Current file location filter.
Definition: clutchlog.h:486
+
std::ostream & out()
Get the output stream on which to print.
Definition: clutchlog.h:521
+
std::string replace(const std::string &form, const std::string &mark, const std::string &tag) const
Replace mark by tag in form.
Definition: clutchlog.h:677
+
static unsigned int default_strip_calls
Number of call stack levels to remove from depth display by default.
Definition: clutchlog.h:252
+
char _hfill_char
Character for filling.
Definition: clutchlog.h:474
static std::string default_format
Default format of the messages.
Definition: clutchlog.h:209
enum clutchlog::fmt::fg fore
Foreground color.
-
void threshold(const std::string &l)
Set the log level (below which logs are not printed) with a string.
Definition: clutchlog.h:527
-
bool there
Location is compatible.
Definition: clutchlog.h:595
-
Structure holding a location matching.
Definition: clutchlog.h:585
-
std::regex _in_func
Current function location filter.
Definition: clutchlog.h:477
-
void threshold(level l)
Set the log level (below which logs are not printed) with an identifier.
Definition: clutchlog.h:525
-
void style(level stage, fmt style)
Set the style (color and typo) of the given log level, passing a fmt instance.
Definition: clutchlog.h:573
-
const std::map< level, std::string > _level_word
Dictionary of level identifier to their string representation.
Definition: clutchlog.h:453
-
scope_t locate(const level &stage, const std::string &file, const std::string &func, const size_t line) const
Gather information on the current location of the call.
Definition: clutchlog.h:609
-
bool matches
Everything is compatible.
Definition: clutchlog.h:587
-
static std::string dump_default_sep
Default item separator for dump.
Definition: clutchlog.h:227
-
level threshold() const
Get the log level below which logs are not printed.
Definition: clutchlog.h:529
-
std::ostream & print_on(std::ostream &os) const
Print the currently encoded format escape code on the given output stream.
Definition: clutchlog.h:335
-
std::map< std::string, level > _word_level
Dictionary of level string to their identifier.
Definition: clutchlog.h:455
-
void style(level stage, FMT... styles)
Set the style (color and typo) of the given log level.
Definition: clutchlog.h:571
-
scope_t()
Constructor.
Definition: clutchlog.h:597
+
void threshold(const std::string &l)
Set the log level (below which logs are not printed) with a string.
Definition: clutchlog.h:544
+
bool there
Location is compatible.
Definition: clutchlog.h:612
+
Structure holding a location matching.
Definition: clutchlog.h:602
+
std::regex _in_func
Current function location filter.
Definition: clutchlog.h:488
+
void threshold(level l)
Set the log level (below which logs are not printed) with an identifier.
Definition: clutchlog.h:542
+
void style(level stage, fmt style)
Set the style (color and typo) of the given log level, passing a fmt instance.
Definition: clutchlog.h:590
+
const std::map< level, std::string > _level_word
Dictionary of level identifier to their string representation.
Definition: clutchlog.h:464
+
scope_t locate(const level &stage, const std::string &file, const std::string &func, const size_t line) const
Gather information on the current location of the call.
Definition: clutchlog.h:626
+
bool matches
Everything is compatible.
Definition: clutchlog.h:604
+
static std::string dump_default_sep
Default item separator for dump.
Definition: clutchlog.h:238
+
level threshold() const
Get the log level below which logs are not printed.
Definition: clutchlog.h:546
+
std::ostream & print_on(std::ostream &os) const
Print the currently encoded format escape code on the given output stream.
Definition: clutchlog.h:346
+
std::map< std::string, level > _word_level
Dictionary of level string to their identifier.
Definition: clutchlog.h:466
+
void style(level stage, FMT... styles)
Set the style (color and typo) of the given log level.
Definition: clutchlog.h:588
+
scope_t()
Constructor.
Definition: clutchlog.h:614
#define CLUTCHLOG_HAVE_UNIX_SYSINFO
POSIX headers necessary for stack depth management are available.
Definition: clutchlog.h:32
Definition: clutchlog.h:175
-
fmt style(level stage) const
Get the configured fmt instance of the given log level.
Definition: clutchlog.h:575
-
bg
Background color codes.
Definition: clutchlog.h:299
+
fmt style(level stage) const
Get the configured fmt instance of the given log level.
Definition: clutchlog.h:592
+
bg
Background color codes.
Definition: clutchlog.h:310
enum clutchlog::fmt::bg back
Background color.