diff --git a/docs/classclutchlog-members.html b/docs/classclutchlog-members.html index ce4b863..c9753c5 100644 --- a/docs/classclutchlog-members.html +++ b/docs/classclutchlog-members.html @@ -71,20 +71,22 @@ $(function() { - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/docs/classclutchlog.html b/docs/classclutchlog.html index b825e41..0a9cac3 100644 --- a/docs/classclutchlog.html +++ b/docs/classclutchlog.html @@ -202,6 +202,10 @@ static std::string  + + +
_format_dumpclutchlogprotected
_format_logclutchlogprotected
_in_fileclutchlogprotected
_in_funcclutchlogprotected
_in_lineclutchlogprotected
_level_fmtclutchlogprotected
_level_wordclutchlogprotected
_outclutchlogprotected
_stageclutchlogprotected
_strip_callsclutchlogprotected
_word_levelclutchlogprotected
clutchlog(clutchlog const &)=delete (defined in clutchlog)clutchlog
critical enum value (defined in clutchlog)clutchlog
debug enum value (defined in clutchlog)clutchlog
default_depth_markclutchloginlineprotectedstatic
default_formatclutchloginlineprotectedstatic
_hfill_charclutchlogprotected
_in_fileclutchlogprotected
_in_funcclutchlogprotected
_in_lineclutchlogprotected
_level_fmtclutchlogprotected
_level_wordclutchlogprotected
_outclutchlogprotected
_stageclutchlogprotected
_strip_callsclutchlogprotected
_word_levelclutchlogprotected
clutchlog(clutchlog const &)=delete (defined in clutchlog)clutchlog
critical enum value (defined in clutchlog)clutchlog
debug enum value (defined in clutchlog)clutchlog
default_depth_markclutchloginlineprotectedstatic
default_formatclutchloginlineprotectedstatic
default_hfill_charclutchloginlineprotectedstatic
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
default_strip_calls = CLUTCHLOG_STRIP_CALLS
 Number of call stack levels to remove from depth display by default.
 
+static char default_hfill_char = CLUTCHLOG_HFILL_CHAR
 Default character used as a filling for right-align the right part of messages with "{hfill}".
 
@@ -249,6 +253,10 @@ std::string  + + + diff --git a/docs/clutchlog_8h.html b/docs/clutchlog_8h.html index 2f58642..c23689b 100644 --- a/docs/clutchlog_8h.html +++ b/docs/clutchlog_8h.html @@ -123,6 +123,9 @@ Macros #define  + + @@ -167,6 +170,10 @@ Macros #define  + + +

High-level API

_format_dump
 Current format of the file output.
 
+const char _hfill_char
 Character for filling.
 
std::ostream * _out
 Standard output.
CLUTCHLOG_HAVE_UNIX_SYSINFO   0
 POSIX headers necessary for stack depth management are available.
 
+#define CLUTCHLOG_HAVE_UNIX_SYSIOCTL   0
 
#define WITH_CLUTCHLOG
 Actually enable clutchlog features.
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}".
 
diff --git a/docs/clutchlog_8h_source.html b/docs/clutchlog_8h_source.html index a2093cd..d4f933a 100644 --- a/docs/clutchlog_8h_source.html +++ b/docs/clutchlog_8h_source.html @@ -102,832 +102,884 @@ $(function() {
32  #define CLUTCHLOG_HAVE_UNIX_SYSINFO 0
33 #endif
34 
-
35 /**********************************************************************
-
36  * Enable by default in Debug builds.
-
37  **********************************************************************/
-
38 #ifndef WITH_CLUTCHLOG
-
39  #ifndef NDEBUG
-
40  #define WITH_CLUTCHLOG
-
42  #endif
-
43 #endif
+
35 #if __has_include(<sys/ioctl.h>) && __has_include(<stdio.h>) && __has_include(<unistd.h>)
+
36  #include <sys/ioctl.h>
+
37  #include <stdio.h>
+
38  #include <unistd.h>
+
39  #define CLUTCHLOG_HAVE_UNIX_SYSIOCTL 1
+
40 #else
+
41  #define CLUTCHLOG_HAVE_UNIX_SYSIOCTL 0
+
42 #endif
+
43 
44 
45 /**********************************************************************
-
46  * Macros definitions
+
46  * Enable by default in Debug builds.
47  **********************************************************************/
-
48 #ifdef WITH_CLUTCHLOG
-
49 
-
53 #ifndef CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG
-
54  #define CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG clutchlog::level::progress
-
56 #endif // CLUTCHLOG_DEFAULT_DEPTH_BUILT
-
57 
-
64 #define CLUTCHLOC __FILE__, __FUNCTION__, __LINE__
-
66 
-
68 #ifndef NDEBUG
-
69  #define CLUTCHLOG( LEVEL, WHAT ) do { \
-
70  auto& clutchlog__logger = clutchlog::logger(); \
-
71  std::ostringstream clutchlog__msg ; clutchlog__msg << WHAT; \
-
72  clutchlog__logger.log(clutchlog::level::LEVEL, clutchlog__msg.str(), CLUTCHLOC); \
-
73  } while(0)
-
74 #else // not Debug build.
-
75  #define CLUTCHLOG( LEVEL, WHAT ) do { \
-
76  if(clutchlog::level::LEVEL <= CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG) { \
-
77  auto& clutchlog__logger = clutchlog::logger(); \
-
78  std::ostringstream clutchlog__msg ; clutchlog__msg << WHAT; \
-
79  clutchlog__logger.log(clutchlog::level::LEVEL, clutchlog__msg.str(), CLUTCHLOC); \
-
80  } \
-
81  } while(0)
-
82 #endif // NDEBUG
-
83 
-
85 #ifndef NDEBUG
-
86  #define CLUTCHDUMP( LEVEL, CONTAINER, FILENAME ) do { \
-
87  auto& clutchlog__logger = clutchlog::logger(); \
-
88  clutchlog__logger.dump(clutchlog::level::LEVEL, std::begin(CONTAINER), std::end(CONTAINER), \
-
89  CLUTCHLOC, FILENAME, CLUTCHDUMP_DEFAULT_SEP); \
-
90  } while(0)
-
91 #else // not Debug build.
-
92  #define CLUTCHDUMP( LEVEL, CONTAINER, FILENAME ) do { \
-
93  if(clutchlog::level::LEVEL <= CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG) { \
-
94  auto& clutchlog__logger = clutchlog::logger(); \
-
95  clutchlog__logger.dump(clutchlog::level::LEVEL, std::begin(CONTAINER), std::end(CONTAINER), \
-
96  CLUTCHLOC, FILENAME, CLUTCHDUMP_DEFAULT_SEP); \
-
97  } \
-
98  } while(0)
-
99 #endif // NDEBUG
-
100 
-
102 #ifndef NDEBUG
-
103  #define CLUTCHFUNC( LEVEL, FUNC, ... ) do { \
-
104  auto& clutchlog__logger = clutchlog::logger(); \
-
105  clutchlog::scope_t clutchlog__scope = clutchlog__logger.locate(clutchlog::level::LEVEL, CLUTCHLOC); \
-
106  if(clutchlog__scope.matches) { \
-
107  FUNC(__VA_ARGS__); \
-
108  } \
-
109  } while(0)
-
110 #else // not Debug build.
-
111  #define CLUTCHFUNC( LEVEL, FUNC, ... ) do { \
-
112  if(clutchlog::level::LEVEL <= CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG) { \
-
113  auto& clutchlog__logger = clutchlog::logger(); \
-
114  clutchlog::scope_t clutchlog__scope = clutchlog__logger.locate(clutchlog::level::LEVEL, CLUTCHLOC); \
-
115  if(clutchlog__scope.matches) { \
-
116  FUNC(__VA_ARGS__); \
-
117  } \
-
118  } \
+
48 #ifndef WITH_CLUTCHLOG
+
49  #ifndef NDEBUG
+
50  #define WITH_CLUTCHLOG
+
52  #endif
+
53 #endif
+
54 
+
55 /**********************************************************************
+
56  * Macros definitions
+
57  **********************************************************************/
+
58 #ifdef WITH_CLUTCHLOG
+
59 
+
63 #ifndef CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG
+
64  #define CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG clutchlog::level::progress
+
66 #endif // CLUTCHLOG_DEFAULT_DEPTH_BUILT
+
67 
+
74 #define CLUTCHLOC __FILE__, __FUNCTION__, __LINE__
+
76 
+
78 #ifndef NDEBUG
+
79  #define CLUTCHLOG( LEVEL, WHAT ) do { \
+
80  auto& clutchlog__logger = clutchlog::logger(); \
+
81  std::ostringstream clutchlog__msg ; clutchlog__msg << WHAT; \
+
82  clutchlog__logger.log(clutchlog::level::LEVEL, clutchlog__msg.str(), CLUTCHLOC); \
+
83  } while(0)
+
84 #else // not Debug build.
+
85  #define CLUTCHLOG( LEVEL, WHAT ) do { \
+
86  if(clutchlog::level::LEVEL <= CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG) { \
+
87  auto& clutchlog__logger = clutchlog::logger(); \
+
88  std::ostringstream clutchlog__msg ; clutchlog__msg << WHAT; \
+
89  clutchlog__logger.log(clutchlog::level::LEVEL, clutchlog__msg.str(), CLUTCHLOC); \
+
90  } \
+
91  } while(0)
+
92 #endif // NDEBUG
+
93 
+
95 #ifndef NDEBUG
+
96  #define CLUTCHDUMP( LEVEL, CONTAINER, FILENAME ) do { \
+
97  auto& clutchlog__logger = clutchlog::logger(); \
+
98  clutchlog__logger.dump(clutchlog::level::LEVEL, std::begin(CONTAINER), std::end(CONTAINER), \
+
99  CLUTCHLOC, FILENAME, CLUTCHDUMP_DEFAULT_SEP); \
+
100  } while(0)
+
101 #else // not Debug build.
+
102  #define CLUTCHDUMP( LEVEL, CONTAINER, FILENAME ) do { \
+
103  if(clutchlog::level::LEVEL <= CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG) { \
+
104  auto& clutchlog__logger = clutchlog::logger(); \
+
105  clutchlog__logger.dump(clutchlog::level::LEVEL, std::begin(CONTAINER), std::end(CONTAINER), \
+
106  CLUTCHLOC, FILENAME, CLUTCHDUMP_DEFAULT_SEP); \
+
107  } \
+
108  } while(0)
+
109 #endif // NDEBUG
+
110 
+
112 #ifndef NDEBUG
+
113  #define CLUTCHFUNC( LEVEL, FUNC, ... ) do { \
+
114  auto& clutchlog__logger = clutchlog::logger(); \
+
115  clutchlog::scope_t clutchlog__scope = clutchlog__logger.locate(clutchlog::level::LEVEL, CLUTCHLOC); \
+
116  if(clutchlog__scope.matches) { \
+
117  FUNC(__VA_ARGS__); \
+
118  } \
119  } while(0)
-
120 #endif // NDEBUG
-
121 
-
123 #ifndef NDEBUG
-
124  #define CLUTCHCODE( LEVEL, ... ) do { \
-
125  auto& clutchlog__logger = clutchlog::logger(); \
-
126  clutchlog::scope_t clutchlog__scope = clutchlog__logger.locate(clutchlog::level::LEVEL, CLUTCHLOC); \
-
127  if(clutchlog__scope.matches) { \
-
128  __VA_ARGS__ \
-
129  } \
-
130  } while(0)
-
131 #else // not Debug build.
-
132  #define CLUTCHCODE( LEVEL, CODE ) do { \
-
133  if(clutchlog::level::LEVEL <= CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG) { \
-
134  auto& clutchlog__logger = clutchlog::logger(); \
-
135  clutchlog::scope_t clutchlog__scope = clutchlog__logger.locate(clutchlog::level::LEVEL, CLUTCHLOC); \
-
136  if(clutchlog__scope.matches) { \
-
137  CODE \
-
138  } \
-
139  } \
+
120 #else // not Debug build.
+
121  #define CLUTCHFUNC( LEVEL, FUNC, ... ) do { \
+
122  if(clutchlog::level::LEVEL <= CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG) { \
+
123  auto& clutchlog__logger = clutchlog::logger(); \
+
124  clutchlog::scope_t clutchlog__scope = clutchlog__logger.locate(clutchlog::level::LEVEL, CLUTCHLOC); \
+
125  if(clutchlog__scope.matches) { \
+
126  FUNC(__VA_ARGS__); \
+
127  } \
+
128  } \
+
129  } while(0)
+
130 #endif // NDEBUG
+
131 
+
133 #ifndef NDEBUG
+
134  #define CLUTCHCODE( LEVEL, ... ) do { \
+
135  auto& clutchlog__logger = clutchlog::logger(); \
+
136  clutchlog::scope_t clutchlog__scope = clutchlog__logger.locate(clutchlog::level::LEVEL, CLUTCHLOC); \
+
137  if(clutchlog__scope.matches) { \
+
138  __VA_ARGS__ \
+
139  } \
140  } while(0)
-
141 #endif // NDEBUG
-
142 
-
145 #else // not WITH_CLUTCHLOG
-
146  // Disabled macros can still be called in Release builds.
-
147  #define CLUTCHLOG( LEVEL, WHAT ) do {/*nothing*/} while(0)
-
148  #define CLUTCHDUMP( LEVEL, CONTAINER, FILENAME ) do {/*nothing*/} while(0)
-
149  #define CLUTCHFUNC( LEVEL, FUNC, ... ) do {/*nothing*/} while(0)
-
150  #define CLUTCHCODE( LEVEL, CODE ) do {/*nothing*/} while(0)
-
151 #endif // WITH_CLUTCHLOG
+
141 #else // not Debug build.
+
142  #define CLUTCHCODE( LEVEL, CODE ) do { \
+
143  if(clutchlog::level::LEVEL <= CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG) { \
+
144  auto& clutchlog__logger = clutchlog::logger(); \
+
145  clutchlog::scope_t clutchlog__scope = clutchlog__logger.locate(clutchlog::level::LEVEL, CLUTCHLOC); \
+
146  if(clutchlog__scope.matches) { \
+
147  CODE \
+
148  } \
+
149  } \
+
150  } while(0)
+
151 #endif // NDEBUG
152 
-
153 /**********************************************************************
-
154  * Implementation
-
155  **********************************************************************/
-
156 
-
157 #ifdef WITH_CLUTCHLOG
-
158 
-
165 class clutchlog
-
166 {
-
167  protected:
+
155 #else // not WITH_CLUTCHLOG
+
156  // Disabled macros can still be called in Release builds.
+
157  #define CLUTCHLOG( LEVEL, WHAT ) do {/*nothing*/} while(0)
+
158  #define CLUTCHDUMP( LEVEL, CONTAINER, FILENAME ) do {/*nothing*/} while(0)
+
159  #define CLUTCHFUNC( LEVEL, FUNC, ... ) do {/*nothing*/} while(0)
+
160  #define CLUTCHCODE( LEVEL, CODE ) do {/*nothing*/} while(0)
+
161 #endif // WITH_CLUTCHLOG
+
162 
+
163 /**********************************************************************
+
164  * Implementation
+
165  **********************************************************************/
+
166 
+
167 #ifdef WITH_CLUTCHLOG
168 
-
171  #ifndef NDEBUG
-
172  #ifndef CLUTCHLOG_DEFAULT_FORMAT
-
173  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
175  #define CLUTCHLOG_DEFAULT_FORMAT "[{name}] {level_letter}:{depth_marks} {msg}\t\t\t\t\t{func} @ {file}:{line}\n"
-
176  #else
-
177  #define CLUTCHLOG_DEFAULT_FORMAT "{level_letter} {msg}\t\t\t\t\t{func} @ {file}:{line}\n"
-
178  #endif
-
179  #endif
-
180  #else
-
181  #ifndef CLUTCHLOG_DEFAULT_FORMAT
-
182  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
184  #define CLUTCHLOG_DEFAULT_FORMAT "[{name}] {level_letter}:{depth_marks} {msg}\n"
-
185  #else
-
186  #define CLUTCHLOG_DEFAULT_FORMAT "{level_letter} {msg}\n"
-
187  #endif
-
188  #endif
-
189  #endif
-
190  static inline std::string default_format = CLUTCHLOG_DEFAULT_FORMAT;
-
192 
-
193  #ifndef CLUTCHDUMP_DEFAULT_FORMAT
-
194  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
196  #define CLUTCHDUMP_DEFAULT_FORMAT "# [{name}] {level} in {func} (at depth {depth}) @ {file}:{line}"
-
197  #else
-
198  #define CLUTCHDUMP_DEFAULT_FORMAT "# {level} in {func} @ {file}:{line}"
-
199  #endif
-
200  #endif // CLUTCHDUMP_DEFAULT_FORMAT
-
201  static inline std::string dump_default_format = CLUTCHDUMP_DEFAULT_FORMAT;
-
203 
-
204  #ifndef CLUTCHDUMP_DEFAULT_SEP
-
205  #define CLUTCHDUMP_DEFAULT_SEP "\n"
-
207  #endif // CLUTCHDUMP_DEFAULT_SEP
-
208  static inline std::string dump_default_sep = CLUTCHDUMP_DEFAULT_SEP;
+
175 class clutchlog
+
176 {
+
177  protected:
+
178 
+
181  #ifndef NDEBUG
+
182  #ifndef CLUTCHLOG_DEFAULT_FORMAT
+
183  #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
185  #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
+
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"
+
189  #endif
+
190  #else
+
191  #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
+
192  #define CLUTCHLOG_DEFAULT_FORMAT "{level_letter} {msg} {hfill} {func} @ {file}:{line}\n"
+
193  #else
+
194  #define CLUTCHLOG_DEFAULT_FORMAT "{level_letter} {msg}\t\t\t\t\t{func} @ {file}:{line}\n"
+
195  #endif
+
196  #endif
+
197  #endif
+
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"
+
203  #else
+
204  #define CLUTCHLOG_DEFAULT_FORMAT "{level_letter} {msg}\n"
+
205  #endif
+
206  #endif
+
207  #endif
+
208  static inline std::string default_format = CLUTCHLOG_DEFAULT_FORMAT;
210 
-
211  #ifndef CLUTCHLOG_DEFAULT_DEPTH_MARK
-
212  #define CLUTCHLOG_DEFAULT_DEPTH_MARK ">"
-
214  #endif // CLUTCHLOG_DEFAULT_DEPTH_MARK
-
215  static inline std::string default_depth_mark = CLUTCHLOG_DEFAULT_DEPTH_MARK;
-
217 
-
218  #ifndef CLUTCHLOG_STRIP_CALLS
-
219  #define CLUTCHLOG_STRIP_CALLS 5
-
221  #endif // CLUTCHLOG_STRIP_CALLS
-
222  static inline unsigned int default_strip_calls = CLUTCHLOG_STRIP_CALLS;
-
224  /* @} */
-
225 
-
226 
-
227  public:
-
237  static clutchlog& logger()
-
238  {
-
239  static clutchlog instance;
-
240  return instance;
-
241  }
+
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 
-
244  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
-
245 
-
258  class fmt {
-
259  public:
-
261  enum class fg {
-
262  black = 30,
-
263  red = 31,
-
264  green = 32,
-
265  yellow = 33,
-
266  blue = 34,
-
267  magenta = 35,
-
268  cyan = 36,
-
269  white = 37,
-
270  none
-
271  } fore;
-
272 
-
274  enum class bg {
-
275  black = 40,
-
276  red = 41,
-
277  green = 42,
-
278  yellow = 43,
-
279  blue = 44,
-
280  magenta = 45,
-
281  cyan = 46,
-
282  white = 47,
-
283  none
-
284  } back;
-
285 
-
287  enum class typo {
-
288  reset = 0,
-
289  bold = 1,
-
290  underline = 4,
-
291  inverse = 7,
-
292  none
-
293  } style;
-
294 
-
296  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
+
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 
-
300  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
301  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
-
302  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
303  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
-
304  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
-
305  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
-
308  protected:
-
310  std::ostream& print_on( std::ostream& os) const
-
311  {
-
312  std::vector<int> codes; codes.reserve(3);
-
313  if(this->fore != fg::none) { codes.push_back(static_cast<int>(this->fore ));}
-
314  if(this->back != bg::none) { codes.push_back(static_cast<int>(this->back ));}
-
315  if(this->style != typo::none) { codes.push_back(static_cast<int>(this->style));}
-
316  if(codes.size() == 0) {return os;}
-
317 
-
318  os << "\033[";
-
319  assert(codes.size() > 0);
-
320  os << codes[0];
-
321  for(size_t i=1; i < codes.size(); ++i) {
-
322  os << ";" << codes[i];
-
323  }
-
324  os << "m";
-
325  return os;
-
326  }
-
327 
-
328  public:
-
340  friend std::ostream& operator<<(std::ostream& os, const fmt& fmt)
-
341  {
-
342  return fmt.print_on(os);
-
343  }
-
344 
-
355  std::string operator()( const std::string& msg ) const
-
356  {
-
357  std::ostringstream os;
-
358  this->print_on(os);
-
359  fmt reset(fmt::typo::reset);
-
360  os << msg;
-
361  reset.print_on(os);
-
362  return os.str();
-
363  }
-
364  }; // fmt class
-
365 
-
372  public:
-
373  clutchlog(clutchlog const&) = delete;
-
374  void operator=(clutchlog const&) = delete;
-
375 
-
376  private:
-
377  clutchlog() :
-
378  // system, main, log
-
379  _strip_calls(clutchlog::default_strip_calls),
-
380  _level_word({
-
381  {level::critical,"Critical"},
-
382  {level::error ,"Error"},
-
383  {level::warning ,"Warning"},
-
384  {level::progress,"Progress"},
-
385  {level::note ,"Note"},
-
386  {level::info ,"Info"},
-
387  {level::debug ,"Debug"},
-
388  {level::xdebug ,"XDebug"}
-
389  }),
-
390  _level_fmt({
-
391  {level::critical,fmt(fmt::fg::red, fmt::typo::underline)},
-
392  {level::error ,fmt(fmt::fg::red, fmt::typo::bold)},
-
393  {level::warning ,fmt(fmt::fg::magenta, fmt::typo::bold)},
-
394  {level::progress,fmt()},
-
395  {level::note ,fmt()},
-
396  {level::info ,fmt()},
-
397  {level::debug ,fmt()},
-
398  {level::xdebug ,fmt()}
-
399  }),
-
400  _format_log(clutchlog::default_format),
-
401  _format_dump(clutchlog::dump_default_format),
-
402  _out(&std::clog),
-
403 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
404  _depth(std::numeric_limits<size_t>::max() - _strip_calls),
-
405  _depth_mark(clutchlog::default_depth_mark),
-
406 #endif
-
407  _stage(level::error),
-
408  _in_file(".*"),
-
409  _in_func(".*"),
-
410  _in_line(".*")
-
411  {
-
412  // Reverse the level->word map into a word->level map.
-
413  for(auto& lw : _level_word) {
-
414  _word_level[lw.second] = lw.first;
-
415  }
-
416  }
-
417 
-
418  protected:
-
420  const size_t _strip_calls;
-
422  const std::map<level,std::string> _level_word;
-
424  std::map<std::string,level> _word_level;
-
426  std::map<level,fmt> _level_fmt;
-
428  std::string _format_log;
-
430  std::string _format_dump;
-
432  std::ostream* _out;
-
433 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
434 
-
435  size_t _depth;
-
437  std::string _depth_mark;
-
438 #endif
-
439 
-
440  level _stage;
-
442  std::regex _in_file;
-
444  std::regex _in_func;
-
446  std::regex _in_line;
-
447 
-
448 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
449 
-
450  static const size_t max_buffer = 4096;
-
451 #endif
-
452 
-
454  public:
-
455 
-
459  void format(const std::string& format) {_format_log = format;}
-
462  std::string format() const {return _format_log;}
-
463 
-
465  void format_comment(const std::string& format) {_format_dump = format;}
-
467  std::string format_comment() const {return _format_dump;}
-
468 
-
470  void out(std::ostream& out) {_out = &out;}
-
472  std::ostream& out() {return *_out;}
-
473 
-
474 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
475  void depth(size_t d) {_depth = d;}
-
478  size_t depth() const {return _depth;}
-
479 
-
481  void depth_mark(std::string mark) {_depth_mark = mark;}
-
483  std::string depth_mark() const {return _depth_mark;}
+
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 
-
487  void threshold(level l) {_stage = l;}
-
489  void threshold(const std::string& l) {_stage = this->level_of(l);}
-
491  level threshold() const {return _stage;}
-
493  const std::map<std::string,level>& levels() const { return _word_level;}
-
494 
-
499  level level_of(const std::string name)
-
500  {
-
501  const auto ilevel = _word_level.find(name);
-
502  if( ilevel != std::end(_word_level)) {
-
503  return ilevel->second;
-
504  } else {
-
505  throw std::out_of_range("'" + name + "' is not a valid log level name");
-
506  }
-
507  }
-
508 
-
510  void file(std::string file) {_in_file = file;}
-
512  void func(std::string func) {_in_func = func;}
-
514  void line(std::string line) {_in_line = line;}
-
515 
-
517  void location(
-
518  const std::string& in_file,
-
519  const std::string& in_function=".*",
-
520  const std::string& in_line=".*"
-
521  )
-
522  {
-
523  file(in_file);
-
524  func(in_function);
-
525  line(in_line);
-
526  }
-
527 
-
532  template<class ... FMT>
-
533  void style(level stage, FMT... styles) { this->style(stage,fmt(styles...)); }
-
535  void style(level stage, fmt style) { _level_fmt.at(stage) = style; }
-
537  fmt style(level stage) const { return _level_fmt.at(stage); }
-
538 
-
541  public:
-
542 
-
546  struct scope_t {
-
549  bool matches;
-
551  level stage;
-
552 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
+
486 #if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
+
487 
+
488  size_t _nb_columns;
+
489 #endif
+
490 
+
492  public:
+
493 
+
497  void format(const std::string& format) {_format_log = format;}
+
500  std::string format() const {return _format_log;}
+
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;}
+
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 
-
554  size_t depth;
-
555 #endif
-
556 
-
557  bool there;
-
559  scope_t() :
-
560  matches(false),
-
561  stage(level::xdebug),
-
562 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
563  depth(0),
-
564 #endif
-
565  there(false)
-
566  {}
-
567  }; // scope_t
-
568 
-
569 
-
571  scope_t locate(
-
572  const level& stage,
-
573  const std::string& file,
-
574  const std::string& func,
-
575  const size_t line
-
576  ) const
-
577  {
-
578  scope_t scope; // False scope by default.
-
579 
-
580  /***** Log level stage *****/
-
581  // Test stage first, because it's fastest.
-
582  scope.stage = stage;
-
583  if(not (scope.stage <= _stage)) {
-
584  // Bypass useless computations if no match
-
585  // because of the stage.
-
586  return scope;
-
587  }
-
588 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
589  /***** Stack depth *****/
-
590  // Backtrace in second, quite fast.
-
591  size_t stack_depth;
-
592  void *buffer[max_buffer];
-
593  stack_depth = backtrace(buffer, max_buffer);
-
594  scope.depth = stack_depth;
-
595  if(not (scope.depth <= _depth + _strip_calls)) {
-
596  // Bypass if no match.
-
597  return scope;
-
598  }
-
599 #endif
-
600 
-
601  /***** Location *****/
-
602  // Location last, slowest.
-
603  std::ostringstream sline; sline << line;
-
604  scope.there =
-
605  std::regex_search(file, _in_file)
-
606  and std::regex_search(func, _in_func)
-
607  and std::regex_search(sline.str(), _in_line);
-
608 
-
609  // No need to retest stage and depth, which are true here.
-
610  scope.matches = scope.there;
-
611 
-
612  return scope;
-
613  } // locate
-
614 
-
622  std::string replace(
-
623  const std::string& form,
-
624  const std::string& mark,
-
625  const std::string& tag
-
626  ) const
-
627  {
-
628  // Useless debug code, unless something fancy would be done with name tags.
-
629  // std::regex re;
-
630  // try {
-
631  // re = std::regex(mark);
-
632  //
-
633  // } catch(const std::regex_error& e) {
-
634  // std::cerr << "ERROR with a regular expression \"" << mark << "\": ";
-
635  // switch(e.code()) {
-
636  // case std::regex_constants::error_collate:
-
637  // std::cerr << "the expression contains an invalid collating element name";
-
638  // break;
-
639  // case std::regex_constants::error_ctype:
-
640  // std::cerr << "the expression contains an invalid character class name";
-
641  // break;
-
642  // case std::regex_constants::error_escape:
-
643  // std::cerr << "the expression contains an invalid escaped character or a trailing escape";
-
644  // break;
-
645  // case std::regex_constants::error_backref:
-
646  // std::cerr << "the expression contains an invalid back reference";
-
647  // break;
-
648  // case std::regex_constants::error_brack:
-
649  // std::cerr << "the expression contains mismatched square brackets ('[' and ']')";
-
650  // break;
-
651  // case std::regex_constants::error_paren:
-
652  // std::cerr << "the expression contains mismatched parentheses ('(' and ')')";
-
653  // break;
-
654  // case std::regex_constants::error_brace:
-
655  // std::cerr << "the expression contains mismatched curly braces ('{' and '}')";
-
656  // break;
-
657  // case std::regex_constants::error_badbrace:
-
658  // std::cerr << "the expression contains an invalid range in a {} expression";
-
659  // break;
-
660  // case std::regex_constants::error_range:
-
661  // std::cerr << "the expression contains an invalid character range (e.g. [b-a])";
-
662  // break;
-
663  // case std::regex_constants::error_space:
-
664  // std::cerr << "there was not enough memory to convert the expression into a finite state machine";
-
665  // break;
-
666  // case std::regex_constants::error_badrepeat:
-
667  // std::cerr << "one of *?+{ was not preceded by a valid regular expression";
-
668  // break;
-
669  // case std::regex_constants::error_complexity:
-
670  // std::cerr << "the complexity of an attempted match exceeded a predefined level";
-
671  // break;
-
672  // case std::regex_constants::error_stack:
-
673  // std::cerr << "there was not enough memory to perform a match";
-
674  // break;
-
675  // default:
-
676  // std::cerr << "unknown error";
-
677  // }
-
678  // std::cerr << std::endl;
-
679  // throw;
-
680  // } // catch
-
681 
-
682  const std::regex re(mark);
-
683  return std::regex_replace(form, re, tag);
-
684  }
-
685 
-
687  std::string replace(
-
688  const std::string& form,
-
689  const std::string& mark,
-
690  const size_t tag
-
691  ) const
-
692  {
-
693  std::ostringstream stag; stag << tag;
-
694  return replace(form, mark, stag.str());
-
695  }
-
696 
-
698  std::string format(
-
699  std::string format,
-
700  const std::string& what,
-
701 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
702  const std::string& name,
-
703 #endif
-
704  const level& stage,
-
705  const std::string& file,
-
706  const std::string& func,
-
707  const size_t line
-
708 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
709  ,
-
710  const size_t depth
-
711 #endif
-
712  ) const
-
713  {
-
714  format = replace(format, "\\{msg\\}", what);
-
715  format = replace(format, "\\{file\\}", file);
-
716  format = replace(format, "\\{func\\}", func);
-
717  format = replace(format, "\\{line\\}", line);
-
718 
-
719  format = replace(format, "\\{level\\}", _level_word.at(stage));
-
720  std::string letter(1, _level_word.at(stage).at(0)); // char -> string
-
721  format = replace(format, "\\{level_letter\\}", letter);
-
722 
-
723 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
724  format = replace(format, "\\{name\\}", name);
-
725  format = replace(format, "\\{depth\\}", depth - _strip_calls);
-
726 
-
727  std::ostringstream chevrons;
-
728  for(size_t i = _strip_calls; i < depth; ++i) {
-
729  chevrons << _depth_mark;
-
730  }
-
731  format = replace(format, "\\{depth_marks\\}", chevrons.str());
-
732 #endif
-
733 
-
734  return _level_fmt.at(stage)(format);
-
735  }
-
736 
-
738  void log(
-
739  const level& stage,
-
740  const std::string& what,
-
741  const std::string& file, const std::string& func, size_t line
-
742  ) const
-
743  {
-
744  scope_t scope = locate(stage, file, func, line);
-
745 
-
746  if(scope.matches) {
-
747 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
748  *_out << format(_format_log, what, basename(getenv("_")),
-
749  stage, file, func,
-
750  line, scope.depth );
-
751 #else
-
752  *_out << format(_format_log, what,
-
753  stage, file, func,
-
754  line );
-
755 
-
756 #endif
-
757  _out->flush();
-
758  } // if scopes.matches
-
759  }
+
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 
-
762  template<class In>
-
763  void dump(
-
764  const level& stage,
-
765  const In container_begin, const In container_end,
-
766  const std::string& file, const std::string& func, size_t line,
-
767  const std::string& filename_template = "dump_{n}.dat",
-
768  const std::string sep = dump_default_sep
-
769  ) const
-
770  {
-
771  scope_t scope = locate(stage, file, func, line);
-
772 
-
773  if(scope.matches) {
-
774  const std::string tag = "\\{n\\}";
-
775  const std::regex re(tag);
-
776  std::string outfile = "";
-
777 
-
778  // If the file name template has the {n} tag.
-
779  if(std::regex_search(filename_template, re)) {
-
780  // Increment n until a free one is found.
-
781  size_t n = 0;
-
782  do {
-
783  outfile = replace(filename_template, tag, n);
-
784  n++;
-
785  } while( fs::exists( outfile ) );
-
786 
-
787  } else {
-
788  // Use the parameter as is.
-
789  outfile = filename_template;
-
790  }
-
791 
-
792  std::ofstream fd(outfile);
-
793 
-
794  if(_format_dump.size() > 0) {
-
795 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
796  fd << format(_format_dump, "", basename(getenv("_")),
-
797  stage, file, func,
-
798  line, scope.depth );
-
799 #else
-
800  fd << format(_format_dump, "",
-
801  stage, file, func,
-
802  line );
-
803 #endif
-
804  fd << sep; // sep after comment line.
-
805  }
-
806 
-
807  std::copy(container_begin, container_end,
-
808  std::ostream_iterator<typename In::value_type>(fd, sep.c_str()));
-
809 
-
810  fd.close();
-
811  } // if scopes.matches
-
812  }
-
813 
-
815 };
-
816 
-
819 #else // not WITH_CLUTCHLOG
-
820 
-
821 
-
822 /**********************************************************************
-
823  * Fake implementation
-
824  **********************************************************************/
-
825 
-
826 // Equivalent class with empty methods, will be optimized out
-
827 // while allowing to actually have calls implemented without WITH_CLUTCHLOG guards.
-
828 #pragma GCC diagnostic push
-
829 #pragma GCC diagnostic ignored "-Wreturn-type"
-
830 class clutchlog
-
831 {
-
832  public:
-
833  static clutchlog& logger() {}
-
834  enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};
-
835  class fmt {
-
836  public:
-
837  enum class fg { black, red, green, yellow, blue, magenta, cyan, white, none } fore;
-
838  enum class bg { black, red, green, yellow, blue, magenta, cyan, white, none } back;
-
839  enum class typo { reset, bold, underline, inverse, none } style;
-
840  fmt() : fore(fg::none), back(bg::none), style(typo::none) {}
-
841  fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
842  fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {}
-
843  fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {}
-
844  fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {}
-
845  fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {}
-
846  fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {}
-
847  protected:
-
848  std::ostream& print_on(std::ostream&) const {}
-
849  public:
-
850  friend std::ostream& operator<<(std::ostream&, const fmt&) {}
-
851  std::string operator()(const std::string&) const {}
-
852  };
-
853  public:
-
854  clutchlog(clutchlog const&) = delete;
-
855  void operator=(clutchlog const&) = delete;
-
856  private:
-
857  clutchlog() {}
-
858  protected:
-
859  struct scope_t {};
-
860  scope_t locate(
-
861  const level&,
-
862  const std::string&,
-
863  const std::string&,
-
864  const size_t
-
865  ) const
-
866  {}
-
867  public:
-
868  void format(const std::string&) {}
-
869  std::string format() const {}
-
870 
-
871  void format_comment(const std::string&) {}
-
872  std::string format_comment() const {}
+
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
+
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  void out(std::ostream&) {}
-
875  std::ostream& out() {}
-
876 
-
877 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
878  void depth(size_t) {}
-
879  size_t depth() const {}
-
880 
-
881  void depth_mark(std::string) {}
-
882  std::string depth_mark() const {}
-
883 #endif
-
884 
-
885  void threshold(level) {}
-
886  void threshold(const std::string&) {}
-
887  level threshold() const {}
-
888  const std::map<std::string,level> levels() const {};
-
889  level level_of(const std::string) {}
-
890 
-
891  void file(std::string) {}
-
892  void func(std::string) {}
-
893  void line(std::string) {}
-
894 
-
895 #pragma GCC diagnostic push
-
896 #pragma GCC diagnostic ignored "-Wunused-parameter"
-
897  void location(
-
898  const std::string&,
-
899  const std::string& in_function=".*",
-
900  const std::string& in_line=".*"
-
901  )
-
902  {}
-
903 #pragma GCC diagnostic pop
-
904  void style(level, fmt) {}
-
905  fmt style(level) const {}
-
906  public:
-
907  std::string replace(
-
908  const std::string&,
-
909  const std::string&,
-
910  const std::string&
-
911  ) const
-
912  {}
-
913 
-
914  std::string replace(
+
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 std::string&,
-
917  const size_t
-
918  ) const
-
919  {}
-
920 
-
921  std::string format(
-
922  std::string,
-
923  const std::string&,
-
924 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
925  const std::string&,
-
926 #endif
-
927  const level&,
-
928  const std::string&,
-
929  const std::string&,
-
930  const size_t
-
931 #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
-
932  ,
-
933  const size_t
-
934 #endif
-
935  ) const
-
936  {}
-
937 
-
938  void log(
-
939  const level&,
-
940  const std::string&,
-
941  const std::string&, const std::string&, size_t
-
942  ) const
-
943  {}
-
944 
-
945  template<class In>
-
946  void dump(
-
947  const level&,
-
948  const In, const In,
-
949  const std::string&, const std::string&, size_t,
+
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) {}
+
946 
+
947 #pragma GCC diagnostic push
+
948 #pragma GCC diagnostic ignored "-Wunused-parameter"
+
949  void location(
950  const std::string&,
-
951  const std::string
-
952  ) const
-
953  {}
-
954 };
+
951  const std::string& in_function=".*",
+
952  const std::string& in_line=".*"
+
953  )
+
954  {}
955 #pragma GCC diagnostic pop
-
956 #endif // WITH_CLUTCHLOG
-
957 
-
958 #endif // __CLUTCHLOG_H__
+
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__
-
clutchlog::file
void file(std::string file)
Set the regular expression filtering the file location.
Definition: clutchlog.h:510
-
CLUTCHDUMP_DEFAULT_FORMAT
#define CLUTCHDUMP_DEFAULT_FORMAT
Compile-time default format of the comment line in file dump.
Definition: clutchlog.h:198
-
clutchlog::fmt::fg
fg
Foreground color codes.
Definition: clutchlog.h:261
-
clutchlog::dump_default_format
static std::string dump_default_format
Default format of the comment line in file dump.
Definition: clutchlog.h:202
-
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:493
-
clutchlog::out
void out(std::ostream &out)
Set the output stream on which to print.
Definition: clutchlog.h:470
-
clutchlog::fmt::fmt
fmt()
&#160;Empty constructor, only useful for a no-op formatter.
Definition: clutchlog.h:296
-
clutchlog::logger
static clutchlog & logger()
Get the logger instance.
Definition: clutchlog.h:237
-
clutchlog::line
void line(std::string line)
Set the regular expression filtering the line location.
Definition: clutchlog.h:514
-
clutchlog::format_comment
void format_comment(const std::string &format)
Set the template string for dumps.
Definition: clutchlog.h:465
-
clutchlog::fmt::typo
typo
Typographic style codes.
Definition: clutchlog.h:287
-
CLUTCHDUMP_DEFAULT_SEP
#define CLUTCHDUMP_DEFAULT_SEP
Compile-time default item separator for dump.
Definition: clutchlog.h:206
-
clutchlog::default_depth_mark
static std::string default_depth_mark
Default mark for stack depth.
Definition: clutchlog.h:216
-
CLUTCHLOG_DEFAULT_FORMAT
#define CLUTCHLOG_DEFAULT_FORMAT
Compile-time default format of the messages (debug mode: with absolute location).
Definition: clutchlog.h:177
-
clutchlog::format
std::string format() const
Get the template string.
Definition: clutchlog.h:462
-
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:738
-
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:499
-
clutchlog::_format_dump
std::string _format_dump
Current format of the file output.
Definition: clutchlog.h:430
-
clutchlog::fmt::operator()
std::string operator()(const std::string &msg) const
Format the given string with the currently encoded format.
Definition: clutchlog.h:355
-
clutchlog::format
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:698
-
clutchlog::_format_log
std::string _format_log
Current format of the standard output.
Definition: clutchlog.h:428
-
clutchlog::level
level
Available log levels.
Definition: clutchlog.h:244
-
clutchlog::scope_t::stage
level stage
Current log level.
Definition: clutchlog.h:551
-
CLUTCHLOG_DEFAULT_DEPTH_MARK
#define CLUTCHLOG_DEFAULT_DEPTH_MARK
Compile-time default mark for stack depth.
Definition: clutchlog.h:213
-
clutchlog::fmt::operator<<
friend std::ostream & operator<<(std::ostream &os, const fmt &fmt)
Output stream overload.
Definition: clutchlog.h:340
-
clutchlog::_level_fmt
std::map< level, fmt > _level_fmt
Dictionary of level identifier to their format.
Definition: clutchlog.h:426
-
clutchlog::_in_line
std::regex _in_line
Current line location filter.
Definition: clutchlog.h:446
+
clutchlog::file
void file(std::string file)
Set the regular expression filtering the file location.
Definition: clutchlog.h:548
+
CLUTCHDUMP_DEFAULT_FORMAT
#define CLUTCHDUMP_DEFAULT_FORMAT
Compile-time default format of the comment line in file dump.
Definition: clutchlog.h:216
+
clutchlog::fmt::fg
fg
Foreground color codes.
Definition: clutchlog.h:286
+
clutchlog::dump_default_format
static std::string dump_default_format
Default format of the comment line in file dump.
Definition: clutchlog.h:220
+
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:531
+
clutchlog::out
void out(std::ostream &out)
Set the output stream on which to print.
Definition: clutchlog.h:508
+
clutchlog::fmt::fmt
fmt()
&#160;Empty constructor, only useful for a no-op formatter.
Definition: clutchlog.h:321
+
clutchlog::logger
static clutchlog & logger()
Get the logger instance.
Definition: clutchlog.h:262
+
clutchlog::line
void line(std::string line)
Set the regular expression filtering the line location.
Definition: clutchlog.h:552
+
clutchlog::format_comment
void format_comment(const std::string &format)
Set the template string for dumps.
Definition: clutchlog.h:503
+
clutchlog::fmt::typo
typo
Typographic style codes.
Definition: clutchlog.h:312
+
CLUTCHDUMP_DEFAULT_SEP
#define CLUTCHDUMP_DEFAULT_SEP
Compile-time default item separator for dump.
Definition: clutchlog.h:224
+
clutchlog::default_depth_mark
static std::string default_depth_mark
Default mark for stack depth.
Definition: clutchlog.h:234
+
CLUTCHLOG_DEFAULT_FORMAT
#define CLUTCHLOG_DEFAULT_FORMAT
Compile-time default format of the messages (debug mode: with absolute location).
Definition: clutchlog.h:194
+
clutchlog::format
std::string format() const
Get the template string.
Definition: clutchlog.h:500
+
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:790
+
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:537
+
clutchlog::_format_dump
std::string _format_dump
Current format of the file output.
Definition: clutchlog.h:461
+
clutchlog::fmt::operator()
std::string operator()(const std::string &msg) const
Format the given string with the currently encoded format.
Definition: clutchlog.h:380
+
clutchlog::format
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
+
clutchlog::_format_log
std::string _format_log
Current format of the standard output.
Definition: clutchlog.h:459
+
clutchlog::level
level
Available log levels.
Definition: clutchlog.h:269
+
clutchlog::scope_t::stage
level stage
Current log level.
Definition: clutchlog.h:589
+
CLUTCHLOG_HFILL_CHAR
#define CLUTCHLOG_HFILL_CHAR
Character used as a filling for right-align the right part of messages with "{hfill}".
Definition: clutchlog.h:245
+
CLUTCHLOG_DEFAULT_DEPTH_MARK
#define CLUTCHLOG_DEFAULT_DEPTH_MARK
Compile-time default mark for stack depth.
Definition: clutchlog.h:231
+
clutchlog::fmt::operator<<
friend std::ostream & operator<<(std::ostream &os, const fmt &fmt)
Output stream overload.
Definition: clutchlog.h:365
+
clutchlog::_level_fmt
std::map< level, fmt > _level_fmt
Dictionary of level identifier to their format.
Definition: clutchlog.h:457
+
clutchlog::_in_line
std::regex _in_line
Current line location filter.
Definition: clutchlog.h:479
clutchlog::fmt::style
enum clutchlog::fmt::typo style
Typographic style.
-
clutchlog::_stage
level _stage
Current log level.
Definition: clutchlog.h:440
-
clutchlog::_strip_calls
const size_t _strip_calls
Current number of call stack levels to remove from depth display.
Definition: clutchlog.h:420
-
clutchlog::format_comment
std::string format_comment() const
Get the template string for dumps.
Definition: clutchlog.h:467
-
CLUTCHLOG_STRIP_CALLS
#define CLUTCHLOG_STRIP_CALLS
Compile-time number of call stack levels to remove from depth display by default.
Definition: clutchlog.h:220
-
clutchlog::_out
std::ostream * _out
Standard output.
Definition: clutchlog.h:432
-
clutchlog::func
void func(std::string func)
Set the regular expression filtering the function location.
Definition: clutchlog.h:512
-
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:517
-
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:763
-
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:687
-
clutchlog::fmt
Color and style formatter for ANSI terminal escape sequences.
Definition: clutchlog.h:258
-
clutchlog::_in_file
std::regex _in_file
Current file location filter.
Definition: clutchlog.h:442
-
clutchlog::out
std::ostream & out()
Get the output stream on which to print.
Definition: clutchlog.h:472
-
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:622
-
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:223
-
clutchlog::default_format
static std::string default_format
Default format of the messages.
Definition: clutchlog.h:191
+
clutchlog::_stage
level _stage
Current log level.
Definition: clutchlog.h:473
+
clutchlog::_strip_calls
const size_t _strip_calls
Current number of call stack levels to remove from depth display.
Definition: clutchlog.h:451
+
clutchlog::format_comment
std::string format_comment() const
Get the template string for dumps.
Definition: clutchlog.h:505
+
clutchlog::_hfill_char
const char _hfill_char
Character for filling.
Definition: clutchlog.h:463
+
CLUTCHLOG_STRIP_CALLS
#define CLUTCHLOG_STRIP_CALLS
Compile-time number of call stack levels to remove from depth display by default.
Definition: clutchlog.h:238
+
clutchlog::_out
std::ostream * _out
Standard output.
Definition: clutchlog.h:465
+
clutchlog::func
void func(std::string func)
Set the regular expression filtering the function location.
Definition: clutchlog.h:550
+
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:555
+
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:248
+
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:815
+
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:725
+
clutchlog::fmt
Color and style formatter for ANSI terminal escape sequences.
Definition: clutchlog.h:283
+
clutchlog::_in_file
std::regex _in_file
Current file location filter.
Definition: clutchlog.h:475
+
clutchlog::out
std::ostream & out()
Get the output stream on which to print.
Definition: clutchlog.h:510
+
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:660
+
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:241
+
clutchlog::default_format
static std::string default_format
Default format of the messages.
Definition: clutchlog.h:209
clutchlog::fmt::fore
enum clutchlog::fmt::fg fore
Foreground color.
-
clutchlog::threshold
void threshold(const std::string &l)
Set the log level (below which logs are not printed) with a string.
Definition: clutchlog.h:489
-
clutchlog::scope_t::there
bool there
Location is compatible.
Definition: clutchlog.h:557
-
clutchlog::scope_t
Structure holding a location matching.
Definition: clutchlog.h:547
-
clutchlog::_in_func
std::regex _in_func
Current function location filter.
Definition: clutchlog.h:444
-
clutchlog::threshold
void threshold(level l)
Set the log level (below which logs are not printed) with an identifier.
Definition: clutchlog.h:487
-
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:535
-
clutchlog::_level_word
const std::map< level, std::string > _level_word
Dictionary of level identifier to their string representation.
Definition: clutchlog.h:422
-
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:571
-
clutchlog::scope_t::matches
bool matches
Everything is compatible.
Definition: clutchlog.h:549
-
clutchlog::dump_default_sep
static std::string dump_default_sep
Default item separator for dump.
Definition: clutchlog.h:209
-
clutchlog::threshold
level threshold() const
Get the log level below which logs are not printed.
Definition: clutchlog.h:491
-
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:310
-
clutchlog::_word_level
std::map< std::string, level > _word_level
Dictionary of level string to their identifier.
Definition: clutchlog.h:424
-
clutchlog::style
void style(level stage, FMT... styles)
Set the style (color and typo) of the given log level.
Definition: clutchlog.h:533
-
clutchlog::scope_t::scope_t
scope_t()
Constructor.
Definition: clutchlog.h:559
+
clutchlog::threshold
void threshold(const std::string &l)
Set the log level (below which logs are not printed) with a string.
Definition: clutchlog.h:527
+
clutchlog::scope_t::there
bool there
Location is compatible.
Definition: clutchlog.h:595
+
clutchlog::scope_t
Structure holding a location matching.
Definition: clutchlog.h:585
+
clutchlog::_in_func
std::regex _in_func
Current function location filter.
Definition: clutchlog.h:477
+
clutchlog::threshold
void threshold(level l)
Set the log level (below which logs are not printed) with an identifier.
Definition: clutchlog.h:525
+
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:573
+
clutchlog::_level_word
const std::map< level, std::string > _level_word
Dictionary of level identifier to their string representation.
Definition: clutchlog.h:453
+
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:609
+
clutchlog::scope_t::matches
bool matches
Everything is compatible.
Definition: clutchlog.h:587
+
clutchlog::dump_default_sep
static std::string dump_default_sep
Default item separator for dump.
Definition: clutchlog.h:227
+
clutchlog::threshold
level threshold() const
Get the log level below which logs are not printed.
Definition: clutchlog.h:529
+
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:335
+
clutchlog::_word_level
std::map< std::string, level > _word_level
Dictionary of level string to their identifier.
Definition: clutchlog.h:455
+
clutchlog::style
void style(level stage, FMT... styles)
Set the style (color and typo) of the given log level.
Definition: clutchlog.h:571
+
clutchlog::scope_t::scope_t
scope_t()
Constructor.
Definition: clutchlog.h:597
CLUTCHLOG_HAVE_UNIX_SYSINFO
#define CLUTCHLOG_HAVE_UNIX_SYSINFO
POSIX headers necessary for stack depth management are available.
Definition: clutchlog.h:32
-
clutchlog
Definition: clutchlog.h:165
-
clutchlog::style
fmt style(level stage) const
Get the configured fmt instance of the given log level.
Definition: clutchlog.h:537
-
clutchlog::fmt::bg
bg
Background color codes.
Definition: clutchlog.h:274
+
clutchlog
Definition: clutchlog.h:175
+
clutchlog::style
fmt style(level stage) const
Get the configured fmt instance of the given log level.
Definition: clutchlog.h:575
+
clutchlog::fmt::bg
bg
Background color codes.
Definition: clutchlog.h:299
clutchlog::fmt::back
enum clutchlog::fmt::bg back
Background color.