diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d2be5f..90fce70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.10 FATAL_ERROR) project("clutchlog" - VERSION 0.11.1 + VERSION 0.12 DESCRIPTION "A logging system which targets versatile debugging") enable_language(CXX) # C++ diff --git a/docs/annotated.html b/docs/annotated.html index a0df3f9..6ccc27a 100644 --- a/docs/annotated.html +++ b/docs/annotated.html @@ -28,7 +28,7 @@ Logo
clutchlog -  0.11.1 +  0.12
diff --git a/docs/classclutchlog-members.html b/docs/classclutchlog-members.html index 3d10653..e2ac279 100644 --- a/docs/classclutchlog-members.html +++ b/docs/classclutchlog-members.html @@ -28,7 +28,7 @@ Logo
clutchlog -  0.11.1 +  0.12
@@ -110,42 +110,43 @@ $(document).ready(function(){initNavTree('classclutchlog.html',''); initResizabl default_formatclutchloginlineprotectedstatic default_hfill_charclutchloginlineprotectedstatic default_hfill_maxclutchloginlineprotectedstatic - default_strip_callsclutchloginlineprotectedstatic - 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) constclutchloginline - dump_default_formatclutchloginlineprotectedstatic - dump_default_sepclutchloginlineprotectedstatic - error enum value (defined in clutchlog)clutchlog - file(std::string file)clutchloginline - format(const std::string &format)clutchloginline - format() constclutchloginline - format(std::string row, const std::string &what, const level &stage, const std::string &file, const std::string &func, const size_t line) constclutchloginline - format_comment(const std::string &format)clutchloginline - format_comment() constclutchloginline - func(std::string func)clutchloginline - info enum value (defined in clutchlog)clutchlog - level enum nameclutchlog - level_of(const std::string name)clutchloginline - levels() constclutchloginline - line(std::string line)clutchloginline - locate(const level &stage, const std::string &file, const std::string &func, const size_t line) constclutchloginline - location(const std::string &in_file, const std::string &in_function=".*", const std::string &in_line=".*")clutchloginline - log(const level &stage, const std::string &what, const std::string &file, const std::string &func, size_t line) constclutchloginline - logger()clutchloginlinestatic - note enum value (defined in clutchlog)clutchlog - operator=(clutchlog const &)=delete (defined in clutchlog)clutchlog - out(std::ostream &out)clutchloginline - out()clutchloginline - progress enum value (defined in clutchlog)clutchlog - replace(const std::string &form, const std::string &mark, const std::string &tag) constclutchloginline - replace(const std::string &form, const std::string &mark, const size_t tag) constclutchloginline - style(level stage, FMT... styles)clutchloginline - style(level stage, fmt style)clutchloginline - style(level stage) constclutchloginline - threshold(level l)clutchloginline - threshold(const std::string &l)clutchloginline - threshold() constclutchloginline - warning enum value (defined in clutchlog)clutchlog - xdebug enum value (defined in clutchlog)clutchlog + default_hfill_minclutchloginlineprotectedstatic + default_strip_callsclutchloginlineprotectedstatic + 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) constclutchloginline + dump_default_formatclutchloginlineprotectedstatic + dump_default_sepclutchloginlineprotectedstatic + error enum value (defined in clutchlog)clutchlog + file(std::string file)clutchloginline + format(const std::string &format)clutchloginline + format() constclutchloginline + format(std::string row, const std::string &what, const level &stage, const std::string &file, const std::string &func, const size_t line) constclutchloginline + format_comment(const std::string &format)clutchloginline + format_comment() constclutchloginline + func(std::string func)clutchloginline + info enum value (defined in clutchlog)clutchlog + level enum nameclutchlog + level_of(const std::string name)clutchloginline + levels() constclutchloginline + line(std::string line)clutchloginline + locate(const level &stage, const std::string &file, const std::string &func, const size_t line) constclutchloginline + location(const std::string &in_file, const std::string &in_function=".*", const std::string &in_line=".*")clutchloginline + log(const level &stage, const std::string &what, const std::string &file, const std::string &func, size_t line) constclutchloginline + logger()clutchloginlinestatic + note enum value (defined in clutchlog)clutchlog + operator=(clutchlog const &)=delete (defined in clutchlog)clutchlog + out(std::ostream &out)clutchloginline + out()clutchloginline + progress enum value (defined in clutchlog)clutchlog + replace(const std::string &form, const std::string &mark, const std::string &tag) constclutchloginline + replace(const std::string &form, const std::string &mark, const size_t tag) constclutchloginline + style(level stage, FMT... styles)clutchloginline + style(level stage, fmt style)clutchloginline + style(level stage) constclutchloginline + threshold(level l)clutchloginline + threshold(const std::string &l)clutchloginline + threshold() constclutchloginline + warning enum value (defined in clutchlog)clutchlog + xdebug enum value (defined in clutchlog)clutchlog diff --git a/docs/classclutchlog.html b/docs/classclutchlog.html index c423188..4ea2c00 100644 --- a/docs/classclutchlog.html +++ b/docs/classclutchlog.html @@ -28,7 +28,7 @@ Logo
clutchlog -  0.11.1 +  0.12
@@ -226,13 +226,17 @@ static unsigned int  Number of call stack levels to remove from depth display by default.
 
-static char default_hfill_char = CLUTCHLOG_HFILL_MARK +static char default_hfill_char = CLUTCHLOG_DEFAULT_HFILL_MARK  Default character used as a filling for right-align the right part of messages with "{hfill}".
  -static size_t default_hfill_max = CLUTCHLOG_HFILL_MAX - Default maximum number of character used as a filling for right-align the right part of messages with "{hfill}".
+static size_t default_hfill_max = CLUTCHLOG_DEFAULT_HFILL_MAX + Default maximum width (number of characters) for which to fill for right-aligning the right part of messages (using "{hfill}").
  + +static size_t default_hfill_min = CLUTCHLOG_DEFAULT_HFILL_MIN + Default minimum width (number of characters) at which to fill for right-aligning the right part of messages (using "{hfill}").
+  @@ -346,7 +350,7 @@ void  diff --git a/docs/classclutchlog_1_1fmt.html b/docs/classclutchlog_1_1fmt.html index 4fc7db5..fe445ce 100644 --- a/docs/classclutchlog_1_1fmt.html +++ b/docs/classclutchlog_1_1fmt.html @@ -28,7 +28,7 @@ @@ -104,7 +104,7 @@ $(document).ready(function(){initNavTree('classclutchlog_1_1fmt.html',''); initR

Color and style formatter for ANSI terminal escape sequences.

Note
All styles may not be supported by a given terminal/operating system.
-

Definition at line 309 of file clutchlog.h.

+

Definition at line 314 of file clutchlog.h.

Classes

operator= (Get the logger instance.

-

Definition at line 291 of file clutchlog.h.

+

Definition at line 296 of file clutchlog.h.

@@ -377,11 +381,11 @@ void 
operator= (Return the log level tag corresponding to the given pre-configured name.

Note
This is case sensitive, see the pre-configured _level_word.
-

Definition at line 606 of file clutchlog.h.

+

Definition at line 618 of file clutchlog.h.

-

References _word_level.

+

References _word_level.

-

Referenced by threshold().

+

Referenced by threshold().

@@ -424,11 +428,11 @@ template<class ... FMT>

Set the style (color and typo) of the given log level.

This version accept style arguments as if they were passed to clutchlog::fmt.

-

Definition at line 640 of file clutchlog.h.

+

Definition at line 652 of file clutchlog.h.

-

References style().

+

References style().

-

Referenced by style().

+

Referenced by style().

@@ -476,9 +480,9 @@ template<class ... FMT>
log.replace("{greet} {world}", "\\{greet\\}", "hello");
// returns "hello {world}"
-

Definition at line 729 of file clutchlog.h.

+

Definition at line 741 of file clutchlog.h.

-

Referenced by dump(), format(), and replace().

+

Referenced by dump(), format(), and replace().

@@ -487,8 +491,8 @@ template<class ... FMT> -
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:891
-
static clutchlog & logger()
Get the logger instance.
Definition: clutchlog.h:291
+
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:903
+
static clutchlog & logger()
Get the logger instance.
Definition: clutchlog.h:296
clutchlog -  0.11.1 +  0.12
clutchlog -  0.11.1 +  0.12
@@ -243,9 +243,9 @@ Friends
std::cout << error("ERROR") << std::endl;
Note
A formatter called this way WILL output a reset escape code at the end.
-

Definition at line 406 of file clutchlog.h.

+

Definition at line 411 of file clutchlog.h.

-

References print_on().

+

References print_on().

@@ -290,7 +290,7 @@ Friends
std::cout << error << "ERROR" << end << std::endl;
Note
An formatter called this way will NOT output a reset escape code.
-

Definition at line 391 of file clutchlog.h.

+

Definition at line 396 of file clutchlog.h.

@@ -299,7 +299,7 @@ Friends -
clutchlog::fmt
Color and style formatter for ANSI terminal escape sequences.
Definition: clutchlog.h:309
+
clutchlog::fmt
Color and style formatter for ANSI terminal escape sequences.
Definition: clutchlog.h:314
diff --git a/docs/clutchlog_8h.html b/docs/clutchlog_8h.html index fe514a5..cef3212 100644 --- a/docs/clutchlog_8h.html +++ b/docs/clutchlog_8h.html @@ -28,7 +28,7 @@ @@ -190,10 +190,10 @@ Macros #define  - - - + + +

Public Member Functions

clutchlog -  0.11.1 +  0.12
clutchlog -  0.11.1 +  0.12
CLUTCHLOG_STRIP_CALLS   5
 Compile-time number of call stack levels to remove from depth display by default.
 
-#define CLUTCHLOG_HFILL_MARK   '.'
 Character used as a filling for right-align the right part of messages with "{hfill}".
 
+#define CLUTCHLOG_DEFAULT_HFILL_MARK   '.'
 Character used as a filling for right-align the right part of messages with "{hfill}".
 
diff --git a/docs/clutchlog_8h.js b/docs/clutchlog_8h.js index fdaabbb..05cb530 100644 --- a/docs/clutchlog_8h.js +++ b/docs/clutchlog_8h.js @@ -16,5 +16,5 @@ var clutchlog_8h = [ "CLUTCHDUMP_DEFAULT_SEP", "group___default_config.html#ga54d29e956575e1c731eab5406135c5df", null ], [ "CLUTCHLOG_DEFAULT_DEPTH_MARK", "group___default_config.html#ga45c4c964fad4ad1641d5c9c28c4645b9", null ], [ "CLUTCHLOG_STRIP_CALLS", "group___default_config.html#ga98f30d814d4913a8a7c93a8793f49adf", null ], - [ "CLUTCHLOG_HFILL_MARK", "group___default_config.html#gad5fbbacf74b8e4669b8f9efdfe81bd25", null ] + [ "CLUTCHLOG_DEFAULT_HFILL_MARK", "group___default_config.html#ga4eda0c1bfded5df89351b8ce8b9c2805", null ] ]; \ No newline at end of file diff --git a/docs/clutchlog_8h_source.html b/docs/clutchlog_8h_source.html index 72c011a..a58c8ef 100644 --- a/docs/clutchlog_8h_source.html +++ b/docs/clutchlog_8h_source.html @@ -28,7 +28,7 @@ Logo
clutchlog -  0.11.1 +  0.12
@@ -301,800 +301,811 @@ $(document).ready(function(){initNavTree('clutchlog_8h_source.html',''); initRes
254  #endif // CLUTCHLOG_STRIP_CALLS
255  static inline unsigned int default_strip_calls = CLUTCHLOG_STRIP_CALLS;
257 
-
258  #ifndef CLUTCHLOG_HFILL_MARK
-
259  #define CLUTCHLOG_HFILL_MARK '.'
-
261  #endif // CLUTCHLOG_HFILL_MARK
-
262  static inline char default_hfill_char = CLUTCHLOG_HFILL_MARK;
+
258  #ifndef CLUTCHLOG_DEFAULT_HFILL_MARK
+
259  #define CLUTCHLOG_DEFAULT_HFILL_MARK '.'
+
261  #endif // CLUTCHLOG_DEFAULT_HFILL_MARK
+
262  static inline char default_hfill_char = CLUTCHLOG_DEFAULT_HFILL_MARK;
264 
265 
266  #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
-
267  #ifndef CLUTCHLOG_HFILL_MAX
-
268  #define CLUTCHLOG_HFILL_MAX 300
+
267  #ifndef CLUTCHLOG_DEFAULT_HFILL_MAX
+
268  #define CLUTCHLOG_DEFAULT_HFILL_MAX 300
269  #endif
-
270  #endif
-
271  static inline size_t default_hfill_max = CLUTCHLOG_HFILL_MAX;
-
273 
-
274  // NOTE: there is no CLUTCHLOG_HFILL_STYLE for defaulting,
-
275  // but you can still set `hfill_style(...)` on the logger singleton.
-
276  /* @} DefaultConfig */
-
277  /* @} */
+
270  #ifndef CLUTCHLOG_DEFAULT_HFILL_MIN
+
271  #define CLUTCHLOG_DEFAULT_HFILL_MIN 150
+
272  #endif
+
273  #endif
+
274  static inline size_t default_hfill_max = CLUTCHLOG_DEFAULT_HFILL_MAX;
+
277  static inline size_t default_hfill_min = CLUTCHLOG_DEFAULT_HFILL_MIN;
278 
-
279 
-
280  public:
-
281 
-
291  static clutchlog& logger()
-
292  {
-
293  static clutchlog instance;
-
294  return instance;
-
295  }
-
296 
-
298  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
-
299 
-
309  class fmt {
-
310  public:
-
312  enum class fg {
-
313  black = 30,
-
314  red = 31,
-
315  green = 32,
-
316  yellow = 33,
-
317  blue = 34,
-
318  magenta = 35,
-
319  cyan = 36,
-
320  white = 37,
-
321  none
-
322  } fore;
-
323 
-
325  enum class bg {
-
326  black = 40,
-
327  red = 41,
-
328  green = 42,
-
329  yellow = 43,
-
330  blue = 44,
-
331  magenta = 45,
-
332  cyan = 46,
-
333  white = 47,
-
334  none
-
335  } back;
-
336 
-
338  enum class typo {
-
339  reset = 0,
-
340  bold = 1,
-
341  underline = 4,
-
342  inverse = 7,
-
343  none
-
344  } style;
-
345 
-
347  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
-
348 
-
351  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
352  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
-
353  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
354  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
-
355  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
-
356  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
-
359  protected:
-
361  std::ostream& print_on( std::ostream& os) const
-
362  {
-
363  std::vector<int> codes; codes.reserve(3);
-
364  if(this->fore != fg::none) { codes.push_back(static_cast<int>(this->fore ));}
-
365  if(this->back != bg::none) { codes.push_back(static_cast<int>(this->back ));}
-
366  if(this->style != typo::none) { codes.push_back(static_cast<int>(this->style));}
-
367  if(codes.size() == 0) {return os;}
-
368 
-
369  os << "\033[";
-
370  assert(codes.size() > 0);
-
371  os << codes[0];
-
372  for(size_t i=1; i < codes.size(); ++i) {
-
373  os << ";" << codes[i];
-
374  }
-
375  os << "m";
-
376  return os;
-
377  }
-
378 
-
379  public:
-
391  friend std::ostream& operator<<(std::ostream& os, const fmt& fmt)
-
392  {
-
393  return fmt.print_on(os);
-
394  }
-
395 
-
406  std::string operator()( const std::string& msg ) const
-
407  {
-
408  std::ostringstream os;
-
409  this->print_on(os);
-
410  fmt reset(fmt::typo::reset);
-
411  os << msg;
-
412  reset.print_on(os);
-
413  return os.str();
-
414  }
-
415 
-
418  std::string str() const
-
419  {
-
420  std::ostringstream os;
-
421  this->print_on(os);
-
422  return os.str();
-
423  }
-
424  }; // fmt class
-
425 
-
431  public:
-
432  clutchlog(clutchlog const&) = delete;
-
433  void operator=(clutchlog const&) = delete;
-
434 
-
435  private:
-
436  clutchlog() :
-
437  // system, main, log
-
438  _strip_calls(clutchlog::default_strip_calls),
-
439  _level_word({
-
440  {level::critical,"Critical"},
-
441  {level::error ,"Error"},
-
442  {level::warning ,"Warning"},
-
443  {level::progress,"Progress"},
-
444  {level::note ,"Note"},
-
445  {level::info ,"Info"},
-
446  {level::debug ,"Debug"},
-
447  {level::xdebug ,"XDebug"}
-
448  }),
-
449  _level_fmt({
-
450  {level::critical,fmt(fmt::fg::red, fmt::typo::underline)},
-
451  {level::error ,fmt(fmt::fg::red, fmt::typo::bold)},
-
452  {level::warning ,fmt(fmt::fg::magenta, fmt::typo::bold)},
-
453  {level::progress,fmt()},
-
454  {level::note ,fmt()},
-
455  {level::info ,fmt()},
-
456  {level::debug ,fmt()},
-
457  {level::xdebug ,fmt()}
-
458  }),
-
459  _format_log(clutchlog::default_format),
-
460  _format_dump(clutchlog::dump_default_format),
-
461  #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
-
462  _hfill_char(clutchlog::default_hfill_char),
-
463  _hfill_fmt(fmt::fg::none),
-
464  _hfill_max(clutchlog::default_hfill_max),
-
465  #endif
-
466  _out(&std::clog),
-
467  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
468  _depth(std::numeric_limits<size_t>::max() - _strip_calls),
-
469  _depth_mark(clutchlog::default_depth_mark),
-
470  #endif
-
471  _stage(level::error),
-
472  _in_file(".*"),
-
473  _in_func(".*"),
-
474  _in_line(".*")
-
475  {
-
476  // Reverse the level->word map into a word->level map.
-
477  for(auto& lw : _level_word) {
-
478  _word_level[lw.second] = lw.first;
-
479  }
-
480 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
-
481  struct winsize w;
-
482  ioctl(STDERR_FILENO, TIOCGWINSZ, &w);
-
483  _nb_columns = std::min((size_t)w.ws_col, default_hfill_max);
-
484 #endif
-
485  }
-
486 
-
487  protected:
-
489  size_t _strip_calls;
-
491  const std::map<level,std::string> _level_word;
-
493  std::map<std::string,level> _word_level;
-
495  std::map<level,fmt> _level_fmt;
-
497  std::string _format_log;
-
499  std::string _format_dump;
-
500  #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
-
501 
-
502  char _hfill_char;
-
504  fmt _hfill_fmt;
-
506  size_t _hfill_max;
-
507  #endif
-
508 
-
509  std::ostream* _out;
-
510  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
511 
-
512  size_t _depth;
-
514  std::string _depth_mark;
+
279  // NOTE: there is no CLUTCHLOG_HFILL_STYLE for defaulting,
+
280  // but you can still set `hfill_style(...)` on the logger singleton.
+
281  /* @} DefaultConfig */
+
282  /* @} */
+
283 
+
284 
+
285  public:
+
286 
+
296  static clutchlog& logger()
+
297  {
+
298  static clutchlog instance;
+
299  return instance;
+
300  }
+
301 
+
303  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
+
304 
+
314  class fmt {
+
315  public:
+
317  enum class fg {
+
318  black = 30,
+
319  red = 31,
+
320  green = 32,
+
321  yellow = 33,
+
322  blue = 34,
+
323  magenta = 35,
+
324  cyan = 36,
+
325  white = 37,
+
326  none
+
327  } fore;
+
328 
+
330  enum class bg {
+
331  black = 40,
+
332  red = 41,
+
333  green = 42,
+
334  yellow = 43,
+
335  blue = 44,
+
336  magenta = 45,
+
337  cyan = 46,
+
338  white = 47,
+
339  none
+
340  } back;
+
341 
+
343  enum class typo {
+
344  reset = 0,
+
345  bold = 1,
+
346  underline = 4,
+
347  inverse = 7,
+
348  none
+
349  } style;
+
350 
+
352  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
+
353 
+
356  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
+
357  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
+
358  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
+
359  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
+
360  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
+
361  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
+
364  protected:
+
366  std::ostream& print_on( std::ostream& os) const
+
367  {
+
368  std::vector<int> codes; codes.reserve(3);
+
369  if(this->fore != fg::none) { codes.push_back(static_cast<int>(this->fore ));}
+
370  if(this->back != bg::none) { codes.push_back(static_cast<int>(this->back ));}
+
371  if(this->style != typo::none) { codes.push_back(static_cast<int>(this->style));}
+
372  if(codes.size() == 0) {return os;}
+
373 
+
374  os << "\033[";
+
375  assert(codes.size() > 0);
+
376  os << codes[0];
+
377  for(size_t i=1; i < codes.size(); ++i) {
+
378  os << ";" << codes[i];
+
379  }
+
380  os << "m";
+
381  return os;
+
382  }
+
383 
+
384  public:
+
396  friend std::ostream& operator<<(std::ostream& os, const fmt& fmt)
+
397  {
+
398  return fmt.print_on(os);
+
399  }
+
400 
+
411  std::string operator()( const std::string& msg ) const
+
412  {
+
413  std::ostringstream os;
+
414  this->print_on(os);
+
415  fmt reset(fmt::typo::reset);
+
416  os << msg;
+
417  reset.print_on(os);
+
418  return os.str();
+
419  }
+
420 
+
423  std::string str() const
+
424  {
+
425  std::ostringstream os;
+
426  this->print_on(os);
+
427  return os.str();
+
428  }
+
429  }; // fmt class
+
430 
+
436  public:
+
437  clutchlog(clutchlog const&) = delete;
+
438  void operator=(clutchlog const&) = delete;
+
439 
+
440  private:
+
441  clutchlog() :
+
442  // system, main, log
+
443  _strip_calls(clutchlog::default_strip_calls),
+
444  _level_word({
+
445  {level::critical,"Critical"},
+
446  {level::error ,"Error"},
+
447  {level::warning ,"Warning"},
+
448  {level::progress,"Progress"},
+
449  {level::note ,"Note"},
+
450  {level::info ,"Info"},
+
451  {level::debug ,"Debug"},
+
452  {level::xdebug ,"XDebug"}
+
453  }),
+
454  _level_fmt({
+
455  {level::critical,fmt(fmt::fg::red, fmt::typo::underline)},
+
456  {level::error ,fmt(fmt::fg::red, fmt::typo::bold)},
+
457  {level::warning ,fmt(fmt::fg::magenta, fmt::typo::bold)},
+
458  {level::progress,fmt()},
+
459  {level::note ,fmt()},
+
460  {level::info ,fmt()},
+
461  {level::debug ,fmt()},
+
462  {level::xdebug ,fmt()}
+
463  }),
+
464  _format_log(clutchlog::default_format),
+
465  _format_dump(clutchlog::dump_default_format),
+
466  #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
+
467  _hfill_char(clutchlog::default_hfill_char),
+
468  _hfill_fmt(fmt::fg::none),
+
469  _hfill_max(clutchlog::default_hfill_max),
+
470  _hfill_min(clutchlog::default_hfill_min),
+
471  #endif
+
472  _out(&std::clog),
+
473  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
474  _depth(std::numeric_limits<size_t>::max() - _strip_calls),
+
475  _depth_mark(clutchlog::default_depth_mark),
+
476  #endif
+
477  _stage(level::error),
+
478  _in_file(".*"),
+
479  _in_func(".*"),
+
480  _in_line(".*")
+
481  {
+
482  // Reverse the level->word map into a word->level map.
+
483  for(auto& lw : _level_word) {
+
484  _word_level[lw.second] = lw.first;
+
485  }
+
486 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
+
487  struct winsize w;
+
488  ioctl(STDERR_FILENO, TIOCGWINSZ, &w);
+
489  _nb_columns = std::max(std::min((size_t)w.ws_col, default_hfill_max), default_hfill_min);
+
490 #endif
+
491  }
+
492 
+
493  protected:
+
495  size_t _strip_calls;
+
497  const std::map<level,std::string> _level_word;
+
499  std::map<std::string,level> _word_level;
+
501  std::map<level,fmt> _level_fmt;
+
503  std::string _format_log;
+
505  std::string _format_dump;
+
506  #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
+
507 
+
508  char _hfill_char;
+
510  fmt _hfill_fmt;
+
512  size_t _hfill_max;
+
514  size_t _hfill_min;
515  #endif
516 
-
517  level _stage;
-
519  std::regex _in_file;
-
521  std::regex _in_func;
-
523  std::regex _in_line;
+
517  std::ostream* _out;
+
518  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
519 
+
520  size_t _depth;
+
522  std::string _depth_mark;
+
523  #endif
524 
-
525 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
526 
-
527  static const size_t _max_buffer = 4096;
-
528 #endif
-
529 
-
530 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
-
531 
-
532  size_t _nb_columns;
-
533 #endif
+
525  level _stage;
+
527  std::regex _in_file;
+
529  std::regex _in_func;
+
531  std::regex _in_line;
+
532 
+
533 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
534 
-
536  public:
+
535  static const size_t _max_buffer = 4096;
+
536 #endif
537 
-
541  void format(const std::string& format) {_format_log = format;}
-
544  std::string format() const {return _format_log;}
+
538 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
+
539 
+
540  size_t _nb_columns;
+
541 #endif
+
542 
+
544  public:
545 
-
547  void format_comment(const std::string& format) {_format_dump = format;}
-
549  std::string format_comment() const {return _format_dump;}
-
550 
-
552  void out(std::ostream& out) {_out = &out;}
-
554  std::ostream& out() {return *_out;}
-
555 
-
556 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
557  void depth(size_t d) {_depth = d;}
-
560  size_t depth() const {return _depth;}
-
561 
-
563  void depth_mark(const std::string mark) {_depth_mark = mark;}
-
565  std::string depth_mark() const {return _depth_mark;}
-
566 
-
568  void strip_calls(const size_t n) {_strip_calls = n;}
-
570  size_t strip_calls() const {return _strip_calls;}
-
571 #endif
-
572 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
-
573  void hfill_mark(const char mark) {_hfill_char = mark;}
-
576  char hfill_mark() const {return _hfill_char;}
-
578  void hfill_style(fmt style) {_hfill_fmt = style;}
-
583  template<class ... FMT>
-
584  void hfill_style(FMT... styles) { this->hfill_style(fmt(styles...)); }
-
586  fmt hfill_style() const {return _hfill_fmt;}
-
588  void hfill_max(const size_t nmax) {_hfill_max = nmax;}
-
590  size_t hfill_max() {return _hfill_max;}
-
591 #endif
-
592 
-
594  void threshold(level l) {_stage = l;}
-
596  void threshold(const std::string& l) {_stage = this->level_of(l);}
-
598  level threshold() const {return _stage;}
-
600  const std::map<std::string,level>& levels() const { return _word_level;}
-
601 
-
606  level level_of(const std::string name)
-
607  {
-
608  const auto ilevel = _word_level.find(name);
-
609  if( ilevel != std::end(_word_level)) {
-
610  return ilevel->second;
-
611  } else {
-
612  throw std::out_of_range("'" + name + "' is not a valid log level name");
-
613  }
-
614  }
-
615 
-
617  void file(std::string file) {_in_file = file;}
-
619  void func(std::string func) {_in_func = func;}
-
621  void line(std::string line) {_in_line = line;}
-
622 
-
624  void location(
-
625  const std::string& in_file,
-
626  const std::string& in_function=".*",
-
627  const std::string& in_line=".*"
-
628  )
-
629  {
-
630  file(in_file);
-
631  func(in_function);
-
632  line(in_line);
-
633  }
+
549  void format(const std::string& format) {_format_log = format;}
+
552  std::string format() const {return _format_log;}
+
553 
+
555  void format_comment(const std::string& format) {_format_dump = format;}
+
557  std::string format_comment() const {return _format_dump;}
+
558 
+
560  void out(std::ostream& out) {_out = &out;}
+
562  std::ostream& out() {return *_out;}
+
563 
+
564 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
565  void depth(size_t d) {_depth = d;}
+
568  size_t depth() const {return _depth;}
+
569 
+
571  void depth_mark(const std::string mark) {_depth_mark = mark;}
+
573  std::string depth_mark() const {return _depth_mark;}
+
574 
+
576  void strip_calls(const size_t n) {_strip_calls = n;}
+
578  size_t strip_calls() const {return _strip_calls;}
+
579 #endif
+
580 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
+
581  void hfill_mark(const char mark) {_hfill_char = mark;}
+
584  char hfill_mark() const {return _hfill_char;}
+
586  void hfill_style(fmt style) {_hfill_fmt = style;}
+
591  template<class ... FMT>
+
592  void hfill_style(FMT... styles) { this->hfill_style(fmt(styles...)); }
+
594  fmt hfill_style() const {return _hfill_fmt;}
+
596  void hfill_max(const size_t nmax) {_hfill_max = nmax;}
+
598  size_t hfill_max() {return _hfill_max;}
+
600  void hfill_min(const size_t nmin) {_hfill_min = nmin;}
+
602  size_t hfill_min() {return _hfill_min;}
+
603 #endif
+
604 
+
606  void threshold(level l) {_stage = l;}
+
608  void threshold(const std::string& l) {_stage = this->level_of(l);}
+
610  level threshold() const {return _stage;}
+
612  const std::map<std::string,level>& levels() const { return _word_level;}
+
613 
+
618  level level_of(const std::string name)
+
619  {
+
620  const auto ilevel = _word_level.find(name);
+
621  if( ilevel != std::end(_word_level)) {
+
622  return ilevel->second;
+
623  } else {
+
624  throw std::out_of_range("'" + name + "' is not a valid log level name");
+
625  }
+
626  }
+
627 
+
629  void file(std::string file) {_in_file = file;}
+
631  void func(std::string func) {_in_func = func;}
+
633  void line(std::string line) {_in_line = line;}
634 
-
639  template<class ... FMT>
-
640  void style(level stage, FMT... styles) { this->style(stage,fmt(styles...)); }
-
642  void style(level stage, fmt style) { _level_fmt.at(stage) = style; }
-
644  fmt style(level stage) const { return _level_fmt.at(stage); }
-
645 
-
648  public:
-
649 
-
653  struct scope_t {
-
656  bool matches;
-
658  level stage;
-
659 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
660 
-
661  size_t depth;
-
662 #endif
-
663 
-
664  bool there;
-
666  scope_t() :
-
667  matches(false),
-
668  stage(level::xdebug),
-
669 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
670  depth(0),
-
671 #endif
-
672  there(false)
-
673  {}
-
674  }; // scope_t
+
636  void location(
+
637  const std::string& in_file,
+
638  const std::string& in_function=".*",
+
639  const std::string& in_line=".*"
+
640  )
+
641  {
+
642  file(in_file);
+
643  func(in_function);
+
644  line(in_line);
+
645  }
+
646 
+
651  template<class ... FMT>
+
652  void style(level stage, FMT... styles) { this->style(stage,fmt(styles...)); }
+
654  void style(level stage, fmt style) { _level_fmt.at(stage) = style; }
+
656  fmt style(level stage) const { return _level_fmt.at(stage); }
+
657 
+
660  public:
+
661 
+
665  struct scope_t {
+
668  bool matches;
+
670  level stage;
+
671 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
672 
+
673  size_t depth;
+
674 #endif
675 
-
676 
-
678  scope_t locate(
-
679  const level& stage,
-
680  const std::string& file,
-
681  const std::string& func,
-
682  const size_t line
-
683  ) const
-
684  {
-
685  scope_t scope; // False scope by default.
-
686 
-
687  /***** Log level stage *****/
-
688  // Test stage first, because it's fastest.
-
689  scope.stage = stage;
-
690  if(not (scope.stage <= _stage)) {
-
691  // Bypass useless computations if no match
-
692  // because of the stage.
-
693  return scope;
-
694  }
-
695 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
696  /***** Stack depth *****/
-
697  // Backtrace in second, quite fast.
-
698  size_t stack_depth;
-
699  void *buffer[_max_buffer];
-
700  stack_depth = backtrace(buffer, _max_buffer);
-
701  scope.depth = stack_depth;
-
702  if(not (scope.depth <= _depth + _strip_calls)) {
-
703  // Bypass if no match.
-
704  return scope;
-
705  }
-
706 #endif
-
707 
-
708  /***** Location *****/
-
709  // Location last, slowest.
-
710  std::ostringstream sline; sline << line;
-
711  scope.there =
-
712  std::regex_search(file, _in_file)
-
713  and std::regex_search(func, _in_func)
-
714  and std::regex_search(sline.str(), _in_line);
-
715 
-
716  // No need to retest stage and depth, which are true here.
-
717  scope.matches = scope.there;
-
718 
-
719  return scope;
-
720  } // locate
-
721 
-
729  std::string replace(
-
730  const std::string& form,
-
731  const std::string& mark,
-
732  const std::string& tag
-
733  ) const
-
734  {
-
735  // Useless debug code, unless something fancy would be done with name tags.
-
736  // std::regex re;
-
737  // try {
-
738  // re = std::regex(mark);
-
739  //
-
740  // } catch(const std::regex_error& e) {
-
741  // std::cerr << "ERROR with a regular expression \"" << mark << "\": ";
-
742  // switch(e.code()) {
-
743  // case std::regex_constants::error_collate:
-
744  // std::cerr << "the expression contains an invalid collating element name";
-
745  // break;
-
746  // case std::regex_constants::error_ctype:
-
747  // std::cerr << "the expression contains an invalid character class name";
-
748  // break;
-
749  // case std::regex_constants::error_escape:
-
750  // std::cerr << "the expression contains an invalid escaped character or a trailing escape";
-
751  // break;
-
752  // case std::regex_constants::error_backref:
-
753  // std::cerr << "the expression contains an invalid back reference";
-
754  // break;
-
755  // case std::regex_constants::error_brack:
-
756  // std::cerr << "the expression contains mismatched square brackets ('[' and ']')";
+
676  bool there;
+
678  scope_t() :
+
679  matches(false),
+
680  stage(level::xdebug),
+
681 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
682  depth(0),
+
683 #endif
+
684  there(false)
+
685  {}
+
686  }; // scope_t
+
687 
+
688 
+
690  scope_t locate(
+
691  const level& stage,
+
692  const std::string& file,
+
693  const std::string& func,
+
694  const size_t line
+
695  ) const
+
696  {
+
697  scope_t scope; // False scope by default.
+
698 
+
699  /***** Log level stage *****/
+
700  // Test stage first, because it's fastest.
+
701  scope.stage = stage;
+
702  if(not (scope.stage <= _stage)) {
+
703  // Bypass useless computations if no match
+
704  // because of the stage.
+
705  return scope;
+
706  }
+
707 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
708  /***** Stack depth *****/
+
709  // Backtrace in second, quite fast.
+
710  size_t stack_depth;
+
711  void *buffer[_max_buffer];
+
712  stack_depth = backtrace(buffer, _max_buffer);
+
713  scope.depth = stack_depth;
+
714  if(not (scope.depth <= _depth + _strip_calls)) {
+
715  // Bypass if no match.
+
716  return scope;
+
717  }
+
718 #endif
+
719 
+
720  /***** Location *****/
+
721  // Location last, slowest.
+
722  std::ostringstream sline; sline << line;
+
723  scope.there =
+
724  std::regex_search(file, _in_file)
+
725  and std::regex_search(func, _in_func)
+
726  and std::regex_search(sline.str(), _in_line);
+
727 
+
728  // No need to retest stage and depth, which are true here.
+
729  scope.matches = scope.there;
+
730 
+
731  return scope;
+
732  } // locate
+
733 
+
741  std::string replace(
+
742  const std::string& form,
+
743  const std::string& mark,
+
744  const std::string& tag
+
745  ) const
+
746  {
+
747  // Useless debug code, unless something fancy would be done with name tags.
+
748  // std::regex re;
+
749  // try {
+
750  // re = std::regex(mark);
+
751  //
+
752  // } catch(const std::regex_error& e) {
+
753  // std::cerr << "ERROR with a regular expression \"" << mark << "\": ";
+
754  // switch(e.code()) {
+
755  // case std::regex_constants::error_collate:
+
756  // std::cerr << "the expression contains an invalid collating element name";
757  // break;
-
758  // case std::regex_constants::error_paren:
-
759  // std::cerr << "the expression contains mismatched parentheses ('(' and ')')";
+
758  // case std::regex_constants::error_ctype:
+
759  // std::cerr << "the expression contains an invalid character class name";
760  // break;
-
761  // case std::regex_constants::error_brace:
-
762  // std::cerr << "the expression contains mismatched curly braces ('{' and '}')";
+
761  // case std::regex_constants::error_escape:
+
762  // std::cerr << "the expression contains an invalid escaped character or a trailing escape";
763  // break;
-
764  // case std::regex_constants::error_badbrace:
-
765  // std::cerr << "the expression contains an invalid range in a {} expression";
+
764  // case std::regex_constants::error_backref:
+
765  // std::cerr << "the expression contains an invalid back reference";
766  // break;
-
767  // case std::regex_constants::error_range:
-
768  // std::cerr << "the expression contains an invalid character range (e.g. [b-a])";
+
767  // case std::regex_constants::error_brack:
+
768  // std::cerr << "the expression contains mismatched square brackets ('[' and ']')";
769  // break;
-
770  // case std::regex_constants::error_space:
-
771  // std::cerr << "there was not enough memory to convert the expression into a finite state machine";
+
770  // case std::regex_constants::error_paren:
+
771  // std::cerr << "the expression contains mismatched parentheses ('(' and ')')";
772  // break;
-
773  // case std::regex_constants::error_badrepeat:
-
774  // std::cerr << "one of *?+{ was not preceded by a valid regular expression";
+
773  // case std::regex_constants::error_brace:
+
774  // std::cerr << "the expression contains mismatched curly braces ('{' and '}')";
775  // break;
-
776  // case std::regex_constants::error_complexity:
-
777  // std::cerr << "the complexity of an attempted match exceeded a predefined level";
+
776  // case std::regex_constants::error_badbrace:
+
777  // std::cerr << "the expression contains an invalid range in a {} expression";
778  // break;
-
779  // case std::regex_constants::error_stack:
-
780  // std::cerr << "there was not enough memory to perform a match";
+
779  // case std::regex_constants::error_range:
+
780  // std::cerr << "the expression contains an invalid character range (e.g. [b-a])";
781  // break;
-
782  // default:
-
783  // std::cerr << "unknown error";
-
784  // }
-
785  // std::cerr << std::endl;
-
786  // throw;
-
787  // } // catch
-
788 
-
789  const std::regex re(mark);
-
790  return std::regex_replace(form, re, tag);
-
791  }
-
792 
-
794  std::string replace(
-
795  const std::string& form,
-
796  const std::string& mark,
-
797  const size_t tag
-
798  ) const
-
799  {
-
800  std::ostringstream stag; stag << tag;
-
801  return replace(form, mark, stag.str());
-
802  }
-
803 
-
805  std::string format(
-
806  std::string row,
-
807  const std::string& what,
-
808 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
809  const std::string& name,
-
810 #endif
-
811  const level& stage,
-
812  const std::string& file,
-
813  const std::string& func,
-
814  const size_t line
-
815 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
816  ,
-
817  const size_t depth
-
818 #endif
-
819  ) const
-
820  {
-
821  row = replace(row, "\\{msg\\}", what);
-
822  row = replace(row, "\\{file\\}", file);
-
823  row = replace(row, "\\{func\\}", func);
-
824  row = replace(row, "\\{line\\}", line);
-
825 
-
826  row = replace(row, "\\{level\\}", _level_word.at(stage));
-
827  std::string letter(1, _level_word.at(stage).at(0)); // char -> string
-
828  row = replace(row, "\\{level_letter\\}", letter);
-
829 
-
830 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
831  row = replace(row, "\\{name\\}", name);
-
832  row = replace(row, "\\{depth\\}", depth - _strip_calls);
-
833 
-
834  std::ostringstream chevrons;
-
835  for(size_t i = _strip_calls; i < depth; ++i) {
-
836  chevrons << _depth_mark;
-
837  }
-
838  row = replace(row, "\\{depth_marks\\}", chevrons.str());
-
839 #endif
-
840 
-
841  row = replace(row, "\\{level_fmt\\}", _level_fmt.at(stage).str());
-
842 
-
843 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
-
844  // hfill is replaced last to allow for correct line width estimation.
-
845  const std::string raw_row = replace(row, "\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]", "");
-
846  const std::string hfill_tag = "{hfill}";
-
847  const size_t hfill_pos = row.find(hfill_tag);
-
848  const size_t raw_hfill_pos = raw_row.find(hfill_tag);
-
849  const size_t nb_columns = std::min(_nb_columns, _hfill_max);
-
850  if(hfill_pos != std::string::npos) {
-
851  assert(raw_hfill_pos != std::string::npos);
-
852  if(nb_columns > 0) {
-
853  const size_t left_len = raw_hfill_pos;
-
854  const size_t right_len = raw_row.size() - raw_hfill_pos - hfill_tag.size();
-
855  if(right_len+left_len > nb_columns) {
-
856  // The right part would go over the terminal width: add a new row.
-
857  if(right_len < nb_columns) {
-
858  // There is room for the right part on a new line.
-
859  const std::string hfill(std::max((size_t)0, nb_columns-right_len), _hfill_char);
-
860  const std::string hfill_styled = _hfill_fmt(hfill);
-
861  row = replace(row, "\\{hfill\\}", "\n"+hfill_styled);
-
862  } else {
-
863  // Right part still goes over columns: let it go.
-
864  const std::string hfill(1, _hfill_char);
-
865  const std::string hfill_styled = _hfill_fmt(hfill);
-
866  row = replace(row, "\\{hfill\\}", "\n"+hfill_styled);
-
867  }
-
868  } else {
-
869  // There is some space in between left and right parts.
-
870  const std::string hfill(std::max((size_t)0, nb_columns - (right_len+left_len)), _hfill_char);
-
871  const std::string hfill_styled = _hfill_fmt(hfill);
-
872  row = replace(row, "\\{hfill\\}", hfill_styled);
-
873  }
-
874  } else {
-
875  // We don't know the terminal width.
-
876  const std::string hfill(1, _hfill_char);
-
877  const std::string hfill_styled = _hfill_fmt(hfill);
-
878  row = replace(row, "\\{hfill\\}", hfill_styled);
-
879  }
-
880  }
-
881 #else
-
882  // We cannot know the terminal width.
-
883  const std::string hfill(1, _hfill_char);
-
884  const std::string hfill_styled = _hfill_fmt(hfill);
-
885  row = replace(row, "\\{hfill\\}", hfill_styled);
-
886 #endif
-
887  return _level_fmt.at(stage)(row);
-
888  }
-
889 
-
891  void log(
-
892  const level& stage,
-
893  const std::string& what,
-
894  const std::string& file, const std::string& func, size_t line
-
895  ) const
-
896  {
-
897  scope_t scope = locate(stage, file, func, line);
-
898 
-
899  if(scope.matches) {
-
900 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
901  *_out << format(_format_log, what, basename(getenv("_")),
-
902  stage, file, func,
-
903  line, scope.depth );
-
904 #else
-
905  *_out << format(_format_log, what,
-
906  stage, file, func,
-
907  line );
-
908 
-
909 #endif
-
910  _out->flush();
-
911  } // if scopes.matches
-
912  }
-
913 
-
915  template<class In>
-
916  void dump(
-
917  const level& stage,
-
918  const In container_begin, const In container_end,
-
919  const std::string& file, const std::string& func, size_t line,
-
920  const std::string& filename_template = "dump_{n}.dat",
-
921  const std::string sep = dump_default_sep
-
922  ) const
-
923  {
-
924  scope_t scope = locate(stage, file, func, line);
+
782  // case std::regex_constants::error_space:
+
783  // std::cerr << "there was not enough memory to convert the expression into a finite state machine";
+
784  // break;
+
785  // case std::regex_constants::error_badrepeat:
+
786  // std::cerr << "one of *?+{ was not preceded by a valid regular expression";
+
787  // break;
+
788  // case std::regex_constants::error_complexity:
+
789  // std::cerr << "the complexity of an attempted match exceeded a predefined level";
+
790  // break;
+
791  // case std::regex_constants::error_stack:
+
792  // std::cerr << "there was not enough memory to perform a match";
+
793  // break;
+
794  // default:
+
795  // std::cerr << "unknown error";
+
796  // }
+
797  // std::cerr << std::endl;
+
798  // throw;
+
799  // } // catch
+
800 
+
801  const std::regex re(mark);
+
802  return std::regex_replace(form, re, tag);
+
803  }
+
804 
+
806  std::string replace(
+
807  const std::string& form,
+
808  const std::string& mark,
+
809  const size_t tag
+
810  ) const
+
811  {
+
812  std::ostringstream stag; stag << tag;
+
813  return replace(form, mark, stag.str());
+
814  }
+
815 
+
817  std::string format(
+
818  std::string row,
+
819  const std::string& what,
+
820 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
821  const std::string& name,
+
822 #endif
+
823  const level& stage,
+
824  const std::string& file,
+
825  const std::string& func,
+
826  const size_t line
+
827 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
828  ,
+
829  const size_t depth
+
830 #endif
+
831  ) const
+
832  {
+
833  row = replace(row, "\\{msg\\}", what);
+
834  row = replace(row, "\\{file\\}", file);
+
835  row = replace(row, "\\{func\\}", func);
+
836  row = replace(row, "\\{line\\}", line);
+
837 
+
838  row = replace(row, "\\{level\\}", _level_word.at(stage));
+
839  std::string letter(1, _level_word.at(stage).at(0)); // char -> string
+
840  row = replace(row, "\\{level_letter\\}", letter);
+
841 
+
842 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
843  row = replace(row, "\\{name\\}", name);
+
844  row = replace(row, "\\{depth\\}", depth - _strip_calls);
+
845 
+
846  std::ostringstream chevrons;
+
847  for(size_t i = _strip_calls; i < depth; ++i) {
+
848  chevrons << _depth_mark;
+
849  }
+
850  row = replace(row, "\\{depth_marks\\}", chevrons.str());
+
851 #endif
+
852 
+
853  row = replace(row, "\\{level_fmt\\}", _level_fmt.at(stage).str());
+
854 
+
855 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
+
856  // hfill is replaced last to allow for correct line width estimation.
+
857  const std::string raw_row = replace(row, "\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]", "");
+
858  const std::string hfill_tag = "{hfill}";
+
859  const size_t hfill_pos = row.find(hfill_tag);
+
860  const size_t raw_hfill_pos = raw_row.find(hfill_tag);
+
861  const size_t nb_columns = std::max(std::min((size_t)_nb_columns, _hfill_max), _hfill_min);
+
862  if(hfill_pos != std::string::npos) {
+
863  assert(raw_hfill_pos != std::string::npos);
+
864  if(nb_columns > 0) {
+
865  const size_t left_len = raw_hfill_pos;
+
866  const size_t right_len = raw_row.size() - raw_hfill_pos - hfill_tag.size();
+
867  if(right_len+left_len > nb_columns) {
+
868  // The right part would go over the terminal width: add a new row.
+
869  if(right_len < nb_columns) {
+
870  // There is room for the right part on a new line.
+
871  const std::string hfill(std::max((size_t)0, nb_columns-right_len), _hfill_char);
+
872  const std::string hfill_styled = _hfill_fmt(hfill);
+
873  row = replace(row, "\\{hfill\\}", "\n"+hfill_styled);
+
874  } else {
+
875  // Right part still goes over columns: let it go.
+
876  const std::string hfill(1, _hfill_char);
+
877  const std::string hfill_styled = _hfill_fmt(hfill);
+
878  row = replace(row, "\\{hfill\\}", "\n"+hfill_styled);
+
879  }
+
880  } else {
+
881  // There is some space in between left and right parts.
+
882  const std::string hfill(std::max((size_t)0, nb_columns - (right_len+left_len)), _hfill_char);
+
883  const std::string hfill_styled = _hfill_fmt(hfill);
+
884  row = replace(row, "\\{hfill\\}", hfill_styled);
+
885  }
+
886  } else {
+
887  // We don't know the terminal width.
+
888  const std::string hfill(1, _hfill_char);
+
889  const std::string hfill_styled = _hfill_fmt(hfill);
+
890  row = replace(row, "\\{hfill\\}", hfill_styled);
+
891  }
+
892  }
+
893 #else
+
894  // We cannot know the terminal width.
+
895  const std::string hfill(1, _hfill_char);
+
896  const std::string hfill_styled = _hfill_fmt(hfill);
+
897  row = replace(row, "\\{hfill\\}", hfill_styled);
+
898 #endif
+
899  return _level_fmt.at(stage)(row);
+
900  }
+
901 
+
903  void log(
+
904  const level& stage,
+
905  const std::string& what,
+
906  const std::string& file, const std::string& func, size_t line
+
907  ) const
+
908  {
+
909  scope_t scope = locate(stage, file, func, line);
+
910 
+
911  if(scope.matches) {
+
912 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
913  *_out << format(_format_log, what, basename(getenv("_")),
+
914  stage, file, func,
+
915  line, scope.depth );
+
916 #else
+
917  *_out << format(_format_log, what,
+
918  stage, file, func,
+
919  line );
+
920 
+
921 #endif
+
922  _out->flush();
+
923  } // if scopes.matches
+
924  }
925 
-
926  if(scope.matches) {
-
927  const std::string tag = "\\{n\\}";
-
928  const std::regex re(tag);
-
929  std::string outfile = "";
-
930 
-
931  // If the file name template has the {n} tag.
-
932  if(std::regex_search(filename_template, re)) {
-
933  // Increment n until a free one is found.
-
934  size_t n = 0;
-
935  do {
-
936  outfile = replace(filename_template, tag, n);
-
937  n++;
-
938  } while( fs::exists( outfile ) );
-
939 
-
940  } else {
-
941  // Use the parameter as is.
-
942  outfile = filename_template;
-
943  }
-
944 
-
945  std::ofstream fd(outfile);
-
946 
-
947  if(_format_dump.size() > 0) {
-
948 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
949  fd << format(_format_dump, "", basename(getenv("_")),
-
950  stage, file, func,
-
951  line, scope.depth );
-
952 #else
-
953  fd << format(_format_dump, "",
-
954  stage, file, func,
-
955  line );
-
956 #endif
-
957  fd << sep; // sep after comment line.
-
958  }
-
959 
-
960  std::copy(container_begin, container_end,
-
961  std::ostream_iterator<typename In::value_type>(fd, sep.c_str()));
-
962 
-
963  fd.close();
-
964  } // if scopes.matches
-
965  }
-
966 
-
968 };
-
969 
-
972 #else // not WITH_CLUTCHLOG
-
973 
+
927  template<class In>
+
928  void dump(
+
929  const level& stage,
+
930  const In container_begin, const In container_end,
+
931  const std::string& file, const std::string& func, size_t line,
+
932  const std::string& filename_template = "dump_{n}.dat",
+
933  const std::string sep = dump_default_sep
+
934  ) const
+
935  {
+
936  scope_t scope = locate(stage, file, func, line);
+
937 
+
938  if(scope.matches) {
+
939  const std::string tag = "\\{n\\}";
+
940  const std::regex re(tag);
+
941  std::string outfile = "";
+
942 
+
943  // If the file name template has the {n} tag.
+
944  if(std::regex_search(filename_template, re)) {
+
945  // Increment n until a free one is found.
+
946  size_t n = 0;
+
947  do {
+
948  outfile = replace(filename_template, tag, n);
+
949  n++;
+
950  } while( fs::exists( outfile ) );
+
951 
+
952  } else {
+
953  // Use the parameter as is.
+
954  outfile = filename_template;
+
955  }
+
956 
+
957  std::ofstream fd(outfile);
+
958 
+
959  if(_format_dump.size() > 0) {
+
960 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
961  fd << format(_format_dump, "", basename(getenv("_")),
+
962  stage, file, func,
+
963  line, scope.depth );
+
964 #else
+
965  fd << format(_format_dump, "",
+
966  stage, file, func,
+
967  line );
+
968 #endif
+
969  fd << sep; // sep after comment line.
+
970  }
+
971 
+
972  std::copy(container_begin, container_end,
+
973  std::ostream_iterator<typename In::value_type>(fd, sep.c_str()));
974 
-
975 /**********************************************************************
-
976  * Fake implementation
-
977  **********************************************************************/
+
975  fd.close();
+
976  } // if scopes.matches
+
977  }
978 
-
979 // Equivalent class with empty methods, will be optimized out
-
980 // while allowing to actually have calls implemented without WITH_CLUTCHLOG guards.
-
981 #pragma GCC diagnostic push
-
982 #pragma GCC diagnostic ignored "-Wreturn-type"
-
983 class clutchlog
-
984 {
-
985  public:
-
986  static clutchlog& logger() {}
-
987  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
-
988  class fmt {
-
989  public:
-
990  enum class fg { black, red, green, yellow, blue, magenta, cyan, white, none } fore;
-
991  enum class bg { black, red, green, yellow, blue, magenta, cyan, white, none } back;
-
992  enum class typo { reset, bold, underline, inverse, none } style;
-
993  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
-
994  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
995  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
-
996  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
997  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
-
998  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
-
999  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
-
1000  protected:
-
1001  std::ostream& print_on(std::ostream&) const {}
-
1002  public:
-
1003  friend std::ostream& operator<<(std::ostream&, const fmt&) {}
-
1004  std::string operator()(const std::string&) const {}
-
1005  };
-
1006  public:
-
1007  clutchlog(clutchlog const&) = delete;
-
1008  void operator=(clutchlog const&) = delete;
-
1009  private:
-
1010  clutchlog() {}
-
1011  protected:
-
1012  struct scope_t {};
-
1013  scope_t locate(
-
1014  const level&,
-
1015  const std::string&,
-
1016  const std::string&,
-
1017  const size_t
-
1018  ) const
-
1019  {}
-
1020  public:
-
1021  void format(const std::string&) {}
-
1022  std::string format() const {}
-
1023 
-
1024  void format_comment(const std::string&) {}
-
1025  std::string format_comment() const {}
-
1026 
-
1027  void out(std::ostream&) {}
-
1028  std::ostream& out() {}
-
1029 
-
1030 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
1031  void depth(size_t) {}
-
1032  size_t depth() const {}
-
1033 
-
1034  void depth_mark(const std::string) {}
-
1035  std::string depth_mark() const {}
-
1036  void strip_calls(const size_t) {}
-
1037  size_t strip_calls() const {}
-
1038 #endif
-
1039 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
-
1040  void hfill_mark(const char) {}
-
1041  char hfill_mark() const {}
-
1042  void hfill_fmt(fmt) {}
-
1043  fmt hfill_fmt() const {}
-
1044  void hfill_max(const size_t) {}
-
1045  size_t hfill_max() {}
-
1046 #endif
-
1047 
-
1048  void threshold(level) {}
-
1049  void threshold(const std::string&) {}
-
1050  level threshold() const {}
-
1051  const std::map<std::string,level> levels() const {}
-
1052  level level_of(const std::string) {}
-
1053 
-
1054  void file(std::string) {}
-
1055  void func(std::string) {}
-
1056  void line(std::string) {}
-
1057 
-
1058 #pragma GCC diagnostic push
-
1059 #pragma GCC diagnostic ignored "-Wunused-parameter"
-
1060  void location(
-
1061  const std::string&,
-
1062  const std::string& in_function=".*",
-
1063  const std::string& in_line=".*"
-
1064  )
-
1065  {}
-
1066 #pragma GCC diagnostic pop
-
1067  template<class ... FMT>
-
1068  void style(level, FMT...) {}
-
1069  void style(level, fmt) {}
-
1070  fmt style(level) const {}
-
1071  public:
-
1072  std::string replace(
-
1073  const std::string&,
-
1074  const std::string&,
-
1075  const std::string&
-
1076  ) const
-
1077  {}
-
1078 
-
1079  std::string replace(
-
1080  const std::string&,
-
1081  const std::string&,
-
1082  const size_t
-
1083  ) const
-
1084  {}
-
1085 
-
1086  std::string format(
-
1087  std::string,
+
980 };
+
981 
+
984 #else // not WITH_CLUTCHLOG
+
985 
+
986 
+
987 /**********************************************************************
+
988  * Fake implementation
+
989  **********************************************************************/
+
990 
+
991 // Equivalent class with empty methods, will be optimized out
+
992 // while allowing to actually have calls implemented without WITH_CLUTCHLOG guards.
+
993 #pragma GCC diagnostic push
+
994 #pragma GCC diagnostic ignored "-Wreturn-type"
+
995 class clutchlog
+
996 {
+
997  public:
+
998  static clutchlog& logger() {}
+
999  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
+
1000  class fmt {
+
1001  public:
+
1002  enum class fg { black, red, green, yellow, blue, magenta, cyan, white, none } fore;
+
1003  enum class bg { black, red, green, yellow, blue, magenta, cyan, white, none } back;
+
1004  enum class typo { reset, bold, underline, inverse, none } style;
+
1005  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
+
1006  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
+
1007  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
+
1008  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
+
1009  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
+
1010  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
+
1011  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
+
1012  protected:
+
1013  std::ostream& print_on(std::ostream&) const {}
+
1014  public:
+
1015  friend std::ostream& operator<<(std::ostream&, const fmt&) {}
+
1016  std::string operator()(const std::string&) const {}
+
1017  };
+
1018  public:
+
1019  clutchlog(clutchlog const&) = delete;
+
1020  void operator=(clutchlog const&) = delete;
+
1021  private:
+
1022  clutchlog() {}
+
1023  protected:
+
1024  struct scope_t {};
+
1025  scope_t locate(
+
1026  const level&,
+
1027  const std::string&,
+
1028  const std::string&,
+
1029  const size_t
+
1030  ) const
+
1031  {}
+
1032  public:
+
1033  void format(const std::string&) {}
+
1034  std::string format() const {}
+
1035 
+
1036  void format_comment(const std::string&) {}
+
1037  std::string format_comment() const {}
+
1038 
+
1039  void out(std::ostream&) {}
+
1040  std::ostream& out() {}
+
1041 
+
1042 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
1043  void depth(size_t) {}
+
1044  size_t depth() const {}
+
1045 
+
1046  void depth_mark(const std::string) {}
+
1047  std::string depth_mark() const {}
+
1048  void strip_calls(const size_t) {}
+
1049  size_t strip_calls() const {}
+
1050 #endif
+
1051 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
+
1052  void hfill_mark(const char) {}
+
1053  char hfill_mark() const {}
+
1054  void hfill_fmt(fmt) {}
+
1055  fmt hfill_fmt() const {}
+
1056  void hfill_min(const size_t) {}
+
1057  size_t hfill_min() {}
+
1058  void hfill_max(const size_t) {}
+
1059  size_t hfill_max() {}
+
1060 #endif
+
1061 
+
1062  void threshold(level) {}
+
1063  void threshold(const std::string&) {}
+
1064  level threshold() const {}
+
1065  const std::map<std::string,level> levels() const {}
+
1066  level level_of(const std::string) {}
+
1067 
+
1068  void file(std::string) {}
+
1069  void func(std::string) {}
+
1070  void line(std::string) {}
+
1071 
+
1072 #pragma GCC diagnostic push
+
1073 #pragma GCC diagnostic ignored "-Wunused-parameter"
+
1074  void location(
+
1075  const std::string&,
+
1076  const std::string& in_function=".*",
+
1077  const std::string& in_line=".*"
+
1078  )
+
1079  {}
+
1080 #pragma GCC diagnostic pop
+
1081  template<class ... FMT>
+
1082  void style(level, FMT...) {}
+
1083  void style(level, fmt) {}
+
1084  fmt style(level) const {}
+
1085  public:
+
1086  std::string replace(
+
1087  const std::string&,
1088  const std::string&,
-
1089 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
1090  const std::string&,
-
1091 #endif
-
1092  const level&,
-
1093  const std::string&,
+
1089  const std::string&
+
1090  ) const
+
1091  {}
+
1092 
+
1093  std::string replace(
1094  const std::string&,
-
1095  const size_t
-
1096 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
1097  ,
-
1098  const size_t
-
1099 #endif
-
1100  ) const
-
1101  {}
-
1102 
-
1103  void log(
-
1104  const level&,
-
1105  const std::string&,
-
1106  const std::string&, const std::string&, size_t
-
1107  ) const
-
1108  {}
-
1109 
-
1110  template<class In>
-
1111  void dump(
-
1112  const level&,
-
1113  const In, const In,
-
1114  const std::string&, const std::string&, size_t,
-
1115  const std::string&,
-
1116  const std::string
-
1117  ) const
-
1118  {}
-
1119 };
-
1120 #pragma GCC diagnostic pop
-
1121 #endif // WITH_CLUTCHLOG
-
1122 
-
1123 #endif // CLUTCHLOG_H
+
1095  const std::string&,
+
1096  const size_t
+
1097  ) const
+
1098  {}
+
1099 
+
1100  std::string format(
+
1101  std::string,
+
1102  const std::string&,
+
1103 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
1104  const std::string&,
+
1105 #endif
+
1106  const level&,
+
1107  const std::string&,
+
1108  const std::string&,
+
1109  const size_t
+
1110 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
1111  ,
+
1112  const size_t
+
1113 #endif
+
1114  ) const
+
1115  {}
+
1116 
+
1117  void log(
+
1118  const level&,
+
1119  const std::string&,
+
1120  const std::string&, const std::string&, size_t
+
1121  ) const
+
1122  {}
+
1123 
+
1124  template<class In>
+
1125  void dump(
+
1126  const level&,
+
1127  const In, const In,
+
1128  const std::string&, const std::string&, size_t,
+
1129  const std::string&,
+
1130  const std::string
+
1131  ) const
+
1132  {}
+
1133 };
+
1134 #pragma GCC diagnostic pop
+
1135 #endif // WITH_CLUTCHLOG
+
1136 
+
1137 #endif // CLUTCHLOG_H
clutchlog::default_depth_mark
static std::string default_depth_mark
Default mark for stack depth.
Definition: clutchlog.h:249
-
clutchlog::_format_log
std::string _format_log
Current format of the standard output.
Definition: clutchlog.h:497
-
clutchlog::_level_fmt
std::map< level, fmt > _level_fmt
Dictionary of level identifier to their format.
Definition: clutchlog.h:495
-
clutchlog::log
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:891
-
clutchlog::fmt::str
std::string str() const
Return the formatting code as a string.
Definition: clutchlog.h:418
-
clutchlog::line
void line(std::string line)
Set the regular expression filtering the line location.
Definition: clutchlog.h:621
+
clutchlog::_format_log
std::string _format_log
Current format of the standard output.
Definition: clutchlog.h:503
+
clutchlog::_level_fmt
std::map< level, fmt > _level_fmt
Dictionary of level identifier to their format.
Definition: clutchlog.h:501
+
clutchlog::log
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:903
+
clutchlog::fmt::str
std::string str() const
Return the formatting code as a string.
Definition: clutchlog.h:423
+
clutchlog::line
void line(std::string line)
Set the regular expression filtering the line location.
Definition: clutchlog.h:633
clutchlog::dump_default_format
static std::string dump_default_format
Default format of the comment line in file dump.
Definition: clutchlog.h:235
-
clutchlog::out
void out(std::ostream &out)
Set the output stream on which to print.
Definition: clutchlog.h:552
+
clutchlog::out
void out(std::ostream &out)
Set the output stream on which to print.
Definition: clutchlog.h:560
clutchlog::dump_default_sep
static std::string dump_default_sep
Default item separator for dump.
Definition: clutchlog.h:242
-
clutchlog::format
std::string format(std::string row, 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:805
+
clutchlog::format
std::string format(std::string row, 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:817
CLUTCHLOG_DEFAULT_DEPTH_MARK
#define CLUTCHLOG_DEFAULT_DEPTH_MARK
Compile-time default mark for stack depth.
Definition: clutchlog.h:246
clutchlog::default_strip_calls
static unsigned int default_strip_calls
Number of call stack levels to remove from depth display by default.
Definition: clutchlog.h:256
-
clutchlog::replace
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:729
+
clutchlog::default_hfill_min
static size_t default_hfill_min
Default minimum width (number of characters) at which to fill for right-aligning the right part of me...
Definition: clutchlog.h:277
+
clutchlog::replace
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:741
clutchlog::fmt::back
enum clutchlog::fmt::bg back
Background color.
-
clutchlog::fmt::fg
fg
Foreground color codes.
Definition: clutchlog.h:312
+
clutchlog::fmt::fg
fg
Foreground color codes.
Definition: clutchlog.h:317
clutchlog::fmt::fore
enum clutchlog::fmt::fg fore
Foreground color.
clutchlog::default_hfill_char
static char default_hfill_char
Default character used as a filling for right-align the right part of messages with "{hfill}".
Definition: clutchlog.h:263
-
clutchlog::scope_t::matches
bool matches
Everything is compatible.
Definition: clutchlog.h:656
+
clutchlog::scope_t::matches
bool matches
Everything is compatible.
Definition: clutchlog.h:668
clutchlog::fmt::style
enum clutchlog::fmt::typo style
Typographic style.
-
CLUTCHLOG_HFILL_MARK
#define CLUTCHLOG_HFILL_MARK
Character used as a filling for right-align the right part of messages with "{hfill}".
Definition: clutchlog.h:260
-
clutchlog::format_comment
void format_comment(const std::string &format)
Set the template string for dumps.
Definition: clutchlog.h:547
-
clutchlog::file
void file(std::string file)
Set the regular expression filtering the file location.
Definition: clutchlog.h:617
-
clutchlog::locate
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:678
-
clutchlog::fmt::fmt
fmt()
&#160;Empty constructor, only useful for a no-op formatter.
Definition: clutchlog.h:347
-
clutchlog::style
void style(level stage, fmt style)
Set the style (color and typo) of the given log level, passing a fmt instance.
Definition: clutchlog.h:642
-
clutchlog::threshold
void threshold(level l)
Set the log level (below which logs are not printed) with an identifier.
Definition: clutchlog.h:594
-
clutchlog::threshold
level threshold() const
Get the log level below which logs are not printed.
Definition: clutchlog.h:598
-
clutchlog::level
level
Available log levels.
Definition: clutchlog.h:298
-
clutchlog::default_hfill_max
static size_t default_hfill_max
Default maximum number of character used as a filling for right-align the right part of messages with...
Definition: clutchlog.h:272
-
clutchlog::scope_t::scope_t
scope_t()
Constructor.
Definition: clutchlog.h:666
-
clutchlog::_in_func
std::regex _in_func
Current function location filter.
Definition: clutchlog.h:521
-
clutchlog::fmt::bg
bg
Background color codes.
Definition: clutchlog.h:325
+
clutchlog::format_comment
void format_comment(const std::string &format)
Set the template string for dumps.
Definition: clutchlog.h:555
+
clutchlog::file
void file(std::string file)
Set the regular expression filtering the file location.
Definition: clutchlog.h:629
+
clutchlog::locate
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:690
+
clutchlog::fmt::fmt
fmt()
&#160;Empty constructor, only useful for a no-op formatter.
Definition: clutchlog.h:352
+
clutchlog::style
void style(level stage, fmt style)
Set the style (color and typo) of the given log level, passing a fmt instance.
Definition: clutchlog.h:654
+
clutchlog::threshold
void threshold(level l)
Set the log level (below which logs are not printed) with an identifier.
Definition: clutchlog.h:606
+
clutchlog::threshold
level threshold() const
Get the log level below which logs are not printed.
Definition: clutchlog.h:610
+
clutchlog::level
level
Available log levels.
Definition: clutchlog.h:303
+
clutchlog::default_hfill_max
static size_t default_hfill_max
Default maximum width (number of characters) for which to fill for right-aligning the right part of m...
Definition: clutchlog.h:275
+
clutchlog::scope_t::scope_t
scope_t()
Constructor.
Definition: clutchlog.h:678
+
clutchlog::_in_func
std::regex _in_func
Current function location filter.
Definition: clutchlog.h:529
+
clutchlog::fmt::bg
bg
Background color codes.
Definition: clutchlog.h:330
clutchlog::default_format
static std::string default_format
Default format of the messages.
Definition: clutchlog.h:213
-
clutchlog::logger
static clutchlog & logger()
Get the logger instance.
Definition: clutchlog.h:291
-
clutchlog::dump
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:916
-
clutchlog::fmt
Color and style formatter for ANSI terminal escape sequences.
Definition: clutchlog.h:309
-
clutchlog::func
void func(std::string func)
Set the regular expression filtering the function location.
Definition: clutchlog.h:619
-
clutchlog::format
std::string format() const
Get the template string.
Definition: clutchlog.h:544
-
clutchlog::_in_file
std::regex _in_file
Current file location filter.
Definition: clutchlog.h:519
-
clutchlog::style
void style(level stage, FMT... styles)
Set the style (color and typo) of the given log level.
Definition: clutchlog.h:640
-
clutchlog::level_of
level level_of(const std::string name)
Return the log level tag corresponding to the given pre-configured name.
Definition: clutchlog.h:606
-
clutchlog::_level_word
const std::map< level, std::string > _level_word
Dictionary of level identifier to their string representation.
Definition: clutchlog.h:491
-
clutchlog::fmt::operator()
std::string operator()(const std::string &msg) const
Format the given string with the currently encoded format.
Definition: clutchlog.h:406
+
clutchlog::logger
static clutchlog & logger()
Get the logger instance.
Definition: clutchlog.h:296
+
clutchlog::dump
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:928
+
clutchlog::fmt
Color and style formatter for ANSI terminal escape sequences.
Definition: clutchlog.h:314
+
clutchlog::func
void func(std::string func)
Set the regular expression filtering the function location.
Definition: clutchlog.h:631
+
clutchlog::format
std::string format() const
Get the template string.
Definition: clutchlog.h:552
+
clutchlog::_in_file
std::regex _in_file
Current file location filter.
Definition: clutchlog.h:527
+
clutchlog::style
void style(level stage, FMT... styles)
Set the style (color and typo) of the given log level.
Definition: clutchlog.h:652
+
clutchlog::level_of
level level_of(const std::string name)
Return the log level tag corresponding to the given pre-configured name.
Definition: clutchlog.h:618
+
clutchlog::_level_word
const std::map< level, std::string > _level_word
Dictionary of level identifier to their string representation.
Definition: clutchlog.h:497
+
clutchlog::fmt::operator()
std::string operator()(const std::string &msg) const
Format the given string with the currently encoded format.
Definition: clutchlog.h:411
CLUTCHLOG_DEFAULT_FORMAT
#define CLUTCHLOG_DEFAULT_FORMAT
Compile-time default format of the messages (debug mode: with absolute location).
Definition: clutchlog.h:198
-
clutchlog::_in_line
std::regex _in_line
Current line location filter.
Definition: clutchlog.h:523
-
clutchlog::replace
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:794
-
clutchlog::format_comment
std::string format_comment() const
Get the template string for dumps.
Definition: clutchlog.h:549
-
clutchlog::_format_dump
std::string _format_dump
Current format of the file output.
Definition: clutchlog.h:499
+
clutchlog::_in_line
std::regex _in_line
Current line location filter.
Definition: clutchlog.h:531
+
clutchlog::replace
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:806
+
clutchlog::format_comment
std::string format_comment() const
Get the template string for dumps.
Definition: clutchlog.h:557
+
clutchlog::_format_dump
std::string _format_dump
Current format of the file output.
Definition: clutchlog.h:505
CLUTCHDUMP_DEFAULT_SEP
#define CLUTCHDUMP_DEFAULT_SEP
Compile-time default item separator for dump.
Definition: clutchlog.h:239
-
clutchlog::scope_t
Structure holding a location matching.
Definition: clutchlog.h:654
-
clutchlog::fmt::print_on
std::ostream & print_on(std::ostream &os) const
Print the currently encoded format escape code on the given output stream.
Definition: clutchlog.h:361
-
clutchlog::_out
std::ostream * _out
Standard output.
Definition: clutchlog.h:509
-
clutchlog::out
std::ostream & out()
Get the output stream on which to print.
Definition: clutchlog.h:554
-
clutchlog::threshold
void threshold(const std::string &l)
Set the log level (below which logs are not printed) with a string.
Definition: clutchlog.h:596
-
clutchlog::levels
const std::map< std::string, level > & levels() const
Get the map of available log levels string representations toward their identifier....
Definition: clutchlog.h:600
-
clutchlog::_strip_calls
size_t _strip_calls
Current number of call stack levels to remove from depth display.
Definition: clutchlog.h:489
-
clutchlog::scope_t::stage
level stage
Current log level.
Definition: clutchlog.h:658
-
clutchlog::scope_t::there
bool there
Location is compatible.
Definition: clutchlog.h:664
+
clutchlog::scope_t
Structure holding a location matching.
Definition: clutchlog.h:666
+
CLUTCHLOG_DEFAULT_HFILL_MARK
#define CLUTCHLOG_DEFAULT_HFILL_MARK
Character used as a filling for right-align the right part of messages with "{hfill}".
Definition: clutchlog.h:260
+
clutchlog::fmt::print_on
std::ostream & print_on(std::ostream &os) const
Print the currently encoded format escape code on the given output stream.
Definition: clutchlog.h:366
+
clutchlog::_out
std::ostream * _out
Standard output.
Definition: clutchlog.h:517
+
clutchlog::out
std::ostream & out()
Get the output stream on which to print.
Definition: clutchlog.h:562
+
clutchlog::threshold
void threshold(const std::string &l)
Set the log level (below which logs are not printed) with a string.
Definition: clutchlog.h:608
+
clutchlog::levels
const std::map< std::string, level > & levels() const
Get the map of available log levels string representations toward their identifier....
Definition: clutchlog.h:612
+
clutchlog::_strip_calls
size_t _strip_calls
Current number of call stack levels to remove from depth display.
Definition: clutchlog.h:495
+
clutchlog::scope_t::stage
level stage
Current log level.
Definition: clutchlog.h:670
+
clutchlog::scope_t::there
bool there
Location is compatible.
Definition: clutchlog.h:676
CLUTCHLOG_STRIP_CALLS
#define CLUTCHLOG_STRIP_CALLS
Compile-time number of call stack levels to remove from depth display by default.
Definition: clutchlog.h:253
-
clutchlog::fmt::operator<<
friend std::ostream & operator<<(std::ostream &os, const fmt &fmt)
Output stream overload.
Definition: clutchlog.h:391
-
clutchlog::_word_level
std::map< std::string, level > _word_level
Dictionary of level string to their identifier.
Definition: clutchlog.h:493
-
clutchlog::_stage
level _stage
Current log level.
Definition: clutchlog.h:517
-
clutchlog::style
fmt style(level stage) const
Get the configured fmt instance of the given log level.
Definition: clutchlog.h:644
-
clutchlog::fmt::typo
typo
Typographic style codes.
Definition: clutchlog.h:338
-
clutchlog::location
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:624
+
clutchlog::fmt::operator<<
friend std::ostream & operator<<(std::ostream &os, const fmt &fmt)
Output stream overload.
Definition: clutchlog.h:396
+
clutchlog::_word_level
std::map< std::string, level > _word_level
Dictionary of level string to their identifier.
Definition: clutchlog.h:499
+
clutchlog::_stage
level _stage
Current log level.
Definition: clutchlog.h:525
+
clutchlog::style
fmt style(level stage) const
Get the configured fmt instance of the given log level.
Definition: clutchlog.h:656
+
clutchlog::fmt::typo
typo
Typographic style codes.
Definition: clutchlog.h:343
+
clutchlog::location
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:636
CLUTCHLOG_HAVE_UNIX_SYSINFO
#define CLUTCHLOG_HAVE_UNIX_SYSINFO
True if POSIX headers necessary for stack depth management are available.
Definition: clutchlog.h:33
clutchlog
The single class which holds everything.
Definition: clutchlog.h:177
CLUTCHDUMP_DEFAULT_FORMAT
#define CLUTCHDUMP_DEFAULT_FORMAT
Compile-time default format of the comment line in file dump.
Definition: clutchlog.h:221
diff --git a/docs/clutchlog_logo.png b/docs/clutchlog_logo.png index 573d2d0..841a245 100644 Binary files a/docs/clutchlog_logo.png and b/docs/clutchlog_logo.png differ diff --git a/docs/clutchlog_logo.svg b/docs/clutchlog_logo.svg index 84b8e3f..f06c5e1 100644 --- a/docs/clutchlog_logo.svg +++ b/docs/clutchlog_logo.svg @@ -35,7 +35,7 @@ showgrid="false" showguides="false" inkscape:zoom="0.3724553" - inkscape:cx="994.75025" + inkscape:cx="387.96602" inkscape:cy="1388.086" inkscape:current-layer="layer1"> v0.11 + y="457.33154">v0.12