feats: adds {level_fmt} and fix hfill accordingly
Update t-demo to show more formatting.
This commit is contained in:
parent
2d094b2637
commit
1c6a6d8507
3 changed files with 119 additions and 58 deletions
34
README.md
34
README.md
|
|
@ -132,7 +132,7 @@ Log levels use a classical semantics for a human skilled in the art, in decreasi
|
||||||
- *Debug*: data that would help debugging the program if there was a bug later on.
|
- *Debug*: data that would help debugging the program if there was a bug later on.
|
||||||
- *XDebug*: debugging information that would be heavy to read.
|
- *XDebug*: debugging information that would be heavy to read.
|
||||||
|
|
||||||
Note: the log levels constants are lower case (for example: `clutchlog::level::xdebug`), but their string representation is not (e.g. "XDebug", this should be taken into account when using `threshold` or `level_of`).
|
Note: the log levels constants are lower case (for example: `clutchlog::level::xdebug`), but their string representation is not (e.g. "XDebug", this should be taken into account when using `clutchlog::threshold` or `clutchlog::level_of`).
|
||||||
|
|
||||||
|
|
||||||
Location filtering
|
Location filtering
|
||||||
|
|
@ -174,12 +174,12 @@ Note that the case of the log levels strings matters (see below).
|
||||||
Output Configuration
|
Output Configuration
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
The output stream can be configured using the `out` method:
|
The output stream can be configured using the `clutchlog::out` method:
|
||||||
```cpp
|
```cpp
|
||||||
log.out(std::clog); // Defaults to clog.
|
log.out(std::clog); // Defaults to clog.
|
||||||
```
|
```
|
||||||
|
|
||||||
The format of the messages can be defined with the `format` method, passing a string with standardized tags surrounded by `{}`:
|
The format of the messages can be defined with the `clutchlog::format` method, passing a string with standardized tags surrounded by `{}`:
|
||||||
```cpp
|
```cpp
|
||||||
log.format("{msg}");
|
log.format("{msg}");
|
||||||
```
|
```
|
||||||
|
|
@ -213,7 +213,7 @@ clutchlog will not put the location-related tags in the message formats
|
||||||
Output style
|
Output style
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The output can be colored differently depending on the log level.
|
Output lines can be colored differently depending on the log level.
|
||||||
```cpp
|
```cpp
|
||||||
// Print error messages in bold red:
|
// Print error messages in bold red:
|
||||||
log.style(clutchlog::level::error, // First, the log level.
|
log.style(clutchlog::level::error, // First, the log level.
|
||||||
|
|
@ -229,6 +229,9 @@ fmt warn(fmt::fg::magenta, fmt::typo::bold);
|
||||||
log.style(clutchlog::level::warning, warn);
|
log.style(clutchlog::level::warning, warn);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note: this inserts a style marker at the very beginning of the line.
|
||||||
|
If you add other styles later on the line, they will take precedence.
|
||||||
|
|
||||||
Using the `clutchlog::fmt` class, you can style:
|
Using the `clutchlog::fmt` class, you can style:
|
||||||
|
|
||||||
- the foreground color, passing a `clutchlog::fmt::fg`,
|
- the foreground color, passing a `clutchlog::fmt::fg`,
|
||||||
|
|
@ -272,11 +275,14 @@ log.format(format.str());
|
||||||
Note: messages at the "critical", "error" and "warning" log levels are colored by default.
|
Note: messages at the "critical", "error" and "warning" log levels are colored by default.
|
||||||
You may want to set their style to `none` if you want to stay in control of inserted colors in the format template.
|
You may want to set their style to `none` if you want to stay in control of inserted colors in the format template.
|
||||||
|
|
||||||
The horizontal filling line (the `{hfill}` tag) can be configured separately with `hfill_style`,
|
The horizontal filling line (the `{hfill}` tag) can be configured separately with `clutchlog::hfill_style`,
|
||||||
for example:
|
for example:
|
||||||
```cpp
|
```cpp
|
||||||
log.hfill_style(clutchlog::fmt::fg::black);
|
log.hfill_style(clutchlog::fmt::fg::black);
|
||||||
```
|
```
|
||||||
|
Note: this will actually reset any styling after the hfill,
|
||||||
|
disabling any style you would have set for the whole message using `clutchlog::format`
|
||||||
|
for the remaining of the message.
|
||||||
|
|
||||||
|
|
||||||
Advanced Usage
|
Advanced Usage
|
||||||
|
|
@ -304,13 +310,13 @@ clutchlog will not put the location-related tags in the message formats
|
||||||
|
|
||||||
### Marks
|
### Marks
|
||||||
|
|
||||||
The mark used with the `{depth_marks}` tag can be configured with the `depth_mark` method,
|
The mark used with the `{depth_marks}` tag can be configured with the `clutchlog::depth_mark` method,
|
||||||
and its default with the `CLUTCHLOG_DEFAULT_DEPTH_MARK` macro:
|
and its default with the `CLUTCHLOG_DEFAULT_DEPTH_MARK` macro:
|
||||||
```cpp
|
```cpp
|
||||||
log.depth_mark(CLUTCHLOG_DEFAULT_DEPTH_MARK); // Defaults to ">".
|
log.depth_mark(CLUTCHLOG_DEFAULT_DEPTH_MARK); // Defaults to ">".
|
||||||
```
|
```
|
||||||
|
|
||||||
The character used with the `{hfill}` tag can be configured wth the `hfill_mark` method,
|
The character used with the `{hfill}` tag can be configured wth the `clutchlog::hfill_mark` method,
|
||||||
and its default with the `CLUTCHLOG_DEFAULT_HFILL_MARK` macro:
|
and its default with the `CLUTCHLOG_DEFAULT_HFILL_MARK` macro:
|
||||||
```cpp
|
```cpp
|
||||||
log.hfill_mark(CLUTCHLOG_DEFAULT_HFILL_MARK); // Defaults to '.'.
|
log.hfill_mark(CLUTCHLOG_DEFAULT_HFILL_MARK); // Defaults to '.'.
|
||||||
|
|
@ -318,13 +324,13 @@ log.hfill_mark(CLUTCHLOG_DEFAULT_HFILL_MARK); // Defaults to '.'.
|
||||||
|
|
||||||
Clutchlog measures the width of the standard error channel.
|
Clutchlog measures the width of the standard error channel.
|
||||||
If it is redirected, it may be measured as very large.
|
If it is redirected, it may be measured as very large.
|
||||||
Thus, the `hfill_max` accessors allow to set a maximum width (in number of characters).
|
Thus, the `clutchlog::hfill_max` accessors allow to set a maximum width (in number of characters).
|
||||||
```cpp
|
```cpp
|
||||||
log.hfill_max(CLUTCHLOG_DEFAULT_HFILL_MAX); // Defaults to 300.
|
log.hfill_max(CLUTCHLOG_DEFAULT_HFILL_MAX); // Defaults to 300.
|
||||||
```
|
```
|
||||||
Note: clutchlog will select the minimum between `hfill_max`
|
Note: clutchlog will select the minimum between `clutchlog::hfill_max`
|
||||||
and the measured number of columns in the terminal,
|
and the measured number of columns in the terminal,
|
||||||
so that you may use `hfill_max` as a way to constraint the output width
|
so that you may use `clutchlog::hfill_max` as a way to constraint the output width
|
||||||
in any cases.
|
in any cases.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -333,7 +339,7 @@ in any cases.
|
||||||
By default, clutchlog removes 5 levels of the calls stack, so that your `main`
|
By default, clutchlog removes 5 levels of the calls stack, so that your `main`
|
||||||
entrypoint corresponds to a depth of zero.
|
entrypoint corresponds to a depth of zero.
|
||||||
You can change this behaviour by defining the `CLUTCHLOG_STRIP_CALLS` macro,
|
You can change this behaviour by defining the `CLUTCHLOG_STRIP_CALLS` macro,
|
||||||
or calling `strip_calls`.
|
or calling `clutchlog::strip_calls`.
|
||||||
```cpp
|
```cpp
|
||||||
log.strip_calls(CLUTCHLOG_STRIP_CALLS); // Defaults to 5.
|
log.strip_calls(CLUTCHLOG_STRIP_CALLS); // Defaults to 5.
|
||||||
```
|
```
|
||||||
|
|
@ -378,7 +384,7 @@ for example:
|
||||||
std::string mark = log.depth_mark();
|
std::string mark = log.depth_mark();
|
||||||
```
|
```
|
||||||
|
|
||||||
To control more precisely the logging, one can use the low-level `log` method:
|
To control more precisely the logging, one can use the low-level `clutchlog::log` method:
|
||||||
```cpp
|
```cpp
|
||||||
log.log(clutchlog::level::xdebug, "hello world", "main.cpp", "main", 122);
|
log.log(clutchlog::level::xdebug, "hello world", "main.cpp", "main", 122);
|
||||||
```
|
```
|
||||||
|
|
@ -392,7 +398,7 @@ log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), CLUTCHLOC, "dumped_
|
||||||
log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), "main.cpp", "main", 122, "dumped.dat", "\n\n");
|
log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), "main.cpp", "main", 122, "dumped.dat", "\n\n");
|
||||||
```
|
```
|
||||||
|
|
||||||
You can access the identifier of log levels with `level_of`:
|
You can access the identifier of log levels with `clutchlog::level_of`:
|
||||||
```cpp
|
```cpp
|
||||||
log.threshold( log.level_of("XDebug") ); // You have to know the exact string.
|
log.threshold( log.level_of("XDebug") ); // You have to know the exact string.
|
||||||
```
|
```
|
||||||
|
|
@ -474,7 +480,7 @@ And here are all the functions you may call to log something:
|
||||||
CLUTCHDUMP(note, my_list, "my_list_{n}.dat");
|
CLUTCHDUMP(note, my_list, "my_list_{n}.dat");
|
||||||
|
|
||||||
// Function call.
|
// Function call.
|
||||||
CLUTCHFUNC(warning, my_check, x, y); // Calls `my_check(x,y);`
|
CLUTCHFUNC(warning, my_check, x, y); // Calls: my_check(x,y);
|
||||||
|
|
||||||
// Declutchable asserts.
|
// Declutchable asserts.
|
||||||
#define ASSERT(...) { CLUTCHFUNC(critical, assert, __VA_ARGS__) }
|
#define ASSERT(...) { CLUTCHFUNC(critical, assert, __VA_ARGS__) }
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef CLUTCHLOG_H
|
#ifndef CLUTCHLOG_H
|
||||||
|
//! Header guard.
|
||||||
#define CLUTCHLOG_H
|
#define CLUTCHLOG_H
|
||||||
|
|
||||||
/** @file */
|
/** @file */
|
||||||
|
|
@ -22,7 +23,7 @@
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
//! POSIX headers necessary for stack depth management are available.
|
//! True if POSIX headers necessary for stack depth management are available.
|
||||||
#if __has_include(<execinfo.h>) && __has_include(<stdlib.h>) && __has_include(<libgen.h>)
|
#if __has_include(<execinfo.h>) && __has_include(<stdlib.h>) && __has_include(<libgen.h>)
|
||||||
#include <execinfo.h> // execinfo
|
#include <execinfo.h> // execinfo
|
||||||
#include <stdlib.h> // getenv
|
#include <stdlib.h> // getenv
|
||||||
|
|
@ -32,6 +33,7 @@
|
||||||
#define CLUTCHLOG_HAVE_UNIX_SYSINFO 0
|
#define CLUTCHLOG_HAVE_UNIX_SYSINFO 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//! True if the system can handle the `hfill` feature.
|
||||||
#if __has_include(<sys/ioctl.h>) && __has_include(<stdio.h>) && __has_include(<unistd.h>)
|
#if __has_include(<sys/ioctl.h>) && __has_include(<stdio.h>) && __has_include(<unistd.h>)
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -57,7 +59,7 @@
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#ifdef WITH_CLUTCHLOG
|
#ifdef WITH_CLUTCHLOG
|
||||||
|
|
||||||
/** @addtogroup DefaultConfigMacros Default configuration macros
|
/** @defgroup DefaultConfig Default configuration management
|
||||||
* @{ **/
|
* @{ **/
|
||||||
|
|
||||||
#ifndef CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG
|
#ifndef CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG
|
||||||
|
|
@ -65,10 +67,10 @@
|
||||||
#define CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG clutchlog::level::progress
|
#define CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG clutchlog::level::progress
|
||||||
#endif // CLUTCHLOG_DEFAULT_DEPTH_BUILT
|
#endif // CLUTCHLOG_DEFAULT_DEPTH_BUILT
|
||||||
|
|
||||||
/** @} */
|
/** @} DefaultConfig */
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup UseMacros High-level API macros
|
/** @defgroup UseMacros High-level API macros
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
//! Handy shortcuts to location.
|
//! Handy shortcuts to location.
|
||||||
|
|
@ -150,7 +152,7 @@
|
||||||
} while(0)
|
} while(0)
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
|
|
||||||
/** @} */
|
/** @} UseMacros */
|
||||||
|
|
||||||
#else // not WITH_CLUTCHLOG
|
#else // not WITH_CLUTCHLOG
|
||||||
// Disabled macros can still be called in Release builds.
|
// Disabled macros can still be called in Release builds.
|
||||||
|
|
@ -165,18 +167,20 @@
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#ifdef WITH_CLUTCHLOG
|
#ifdef WITH_CLUTCHLOG
|
||||||
|
/** @defgroup Main Main class
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/** The single class which holds everything.
|
/** The single class which holds everything.
|
||||||
*
|
*
|
||||||
* This is a Singleton class.
|
* This is a Singleton class.
|
||||||
*
|
|
||||||
* @addtogroup Main Main class
|
|
||||||
* @{
|
|
||||||
*/
|
*/
|
||||||
class clutchlog
|
class clutchlog
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** @addtogroup UseMacros High-level API macros
|
/** @name Default configuration members
|
||||||
|
* @{ */
|
||||||
|
/** @ingroup DefaultConfig
|
||||||
* @{ */
|
* @{ */
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
#ifndef CLUTCHLOG_DEFAULT_FORMAT
|
#ifndef CLUTCHLOG_DEFAULT_FORMAT
|
||||||
|
|
@ -265,10 +269,11 @@ class clutchlog
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
//! Default maximum number of character used as a filling for right-align the right part of messages with "{hfill}".
|
//! Default maximum number of character used as a filling for right-align the right part of messages with "{hfill}".
|
||||||
static inline unsigned short default_hfill_max = CLUTCHLOG_HFILL_MAX;
|
static inline size_t default_hfill_max = CLUTCHLOG_HFILL_MAX;
|
||||||
|
|
||||||
// NOTE: there is no CLUTCHLOG_HFILL_STYLE for defaulting,
|
// NOTE: there is no CLUTCHLOG_HFILL_STYLE for defaulting,
|
||||||
// but you can still set `hfill_style(...)` on the logger singleton.
|
// but you can still set `hfill_style(...)` on the logger singleton.
|
||||||
|
/* @} DefaultConfig */
|
||||||
/* @} */
|
/* @} */
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -297,9 +302,6 @@ class clutchlog
|
||||||
/** @addtogroup Formating Formating tools
|
/** @addtogroup Formating Formating tools
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
/** @name Formating API
|
|
||||||
* @{ */
|
|
||||||
|
|
||||||
/** Color and style formatter for ANSI terminal escape sequences.
|
/** Color and style formatter for ANSI terminal escape sequences.
|
||||||
*
|
*
|
||||||
* @note All styles may not be supported by a given terminal/operating system.
|
* @note All styles may not be supported by a given terminal/operating system.
|
||||||
|
|
@ -410,10 +412,18 @@ class clutchlog
|
||||||
reset.print_on(os);
|
reset.print_on(os);
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the formatting code as a string.
|
||||||
|
*/
|
||||||
|
std::string str() const
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
this->print_on(os);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
}; // fmt class
|
}; // fmt class
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** @name Internal details
|
/** @name Internal details
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
@ -470,7 +480,7 @@ class clutchlog
|
||||||
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
||||||
struct winsize w;
|
struct winsize w;
|
||||||
ioctl(STDERR_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDERR_FILENO, TIOCGWINSZ, &w);
|
||||||
_nb_columns = std::min(w.ws_col, default_hfill_max);
|
_nb_columns = std::min((size_t)w.ws_col, default_hfill_max);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -493,7 +503,7 @@ class clutchlog
|
||||||
/** Style of the filling. */
|
/** Style of the filling. */
|
||||||
fmt _hfill_fmt;
|
fmt _hfill_fmt;
|
||||||
/** Maximum number of fill char. */
|
/** Maximum number of fill char. */
|
||||||
unsigned short _hfill_max;
|
size_t _hfill_max;
|
||||||
#endif
|
#endif
|
||||||
/** Standard output. */
|
/** Standard output. */
|
||||||
std::ostream* _out;
|
std::ostream* _out;
|
||||||
|
|
@ -571,13 +581,13 @@ class clutchlog
|
||||||
* This version accept style arguments as if they were passed to `clutchlog::fmt`.
|
* This version accept style arguments as if they were passed to `clutchlog::fmt`.
|
||||||
*/
|
*/
|
||||||
template<class ... FMT>
|
template<class ... FMT>
|
||||||
void style(FMT... styles) { this->hfill_style(fmt(styles...)); }
|
void hfill_style(FMT... styles) { this->hfill_style(fmt(styles...)); }
|
||||||
//! Get the character for the stretching hfill marker.
|
//! Get the character for the stretching hfill marker.
|
||||||
fmt hfill_style() const {return _hfill_fmt;}
|
fmt hfill_style() const {return _hfill_fmt;}
|
||||||
//! Set the maximum number of hfill characters. */
|
//! Set the maximum number of hfill characters. */
|
||||||
void hfill_max(const size_t nmax) {_hfill_max = nmax;}
|
void hfill_max(const size_t nmax) {_hfill_max = nmax;}
|
||||||
//! Get the maximum number of hfill characters. */
|
//! Get the maximum number of hfill characters. */
|
||||||
unsigned short hfill_max() {return _hfill_max;}
|
size_t hfill_max() {return _hfill_max;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Set the log level (below which logs are not printed) with an identifier.
|
//! Set the log level (below which logs are not printed) with an identifier.
|
||||||
|
|
@ -793,7 +803,7 @@ class clutchlog
|
||||||
|
|
||||||
//! Substitute all tags in the format string with the corresponding information and apply the style corresponding to the log level.
|
//! Substitute all tags in the format string with the corresponding information and apply the style corresponding to the log level.
|
||||||
std::string format(
|
std::string format(
|
||||||
std::string format,
|
std::string row,
|
||||||
const std::string& what,
|
const std::string& what,
|
||||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
|
|
@ -808,52 +818,65 @@ class clutchlog
|
||||||
#endif
|
#endif
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
format = replace(format, "\\{msg\\}", what);
|
row = replace(row, "\\{msg\\}", what);
|
||||||
format = replace(format, "\\{file\\}", file);
|
row = replace(row, "\\{file\\}", file);
|
||||||
format = replace(format, "\\{func\\}", func);
|
row = replace(row, "\\{func\\}", func);
|
||||||
format = replace(format, "\\{line\\}", line);
|
row = replace(row, "\\{line\\}", line);
|
||||||
|
|
||||||
format = replace(format, "\\{level\\}", _level_word.at(stage));
|
row = replace(row, "\\{level\\}", _level_word.at(stage));
|
||||||
std::string letter(1, _level_word.at(stage).at(0)); // char -> string
|
std::string letter(1, _level_word.at(stage).at(0)); // char -> string
|
||||||
format = replace(format, "\\{level_letter\\}", letter);
|
row = replace(row, "\\{level_letter\\}", letter);
|
||||||
|
|
||||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||||
format = replace(format, "\\{name\\}", name);
|
row = replace(row, "\\{name\\}", name);
|
||||||
format = replace(format, "\\{depth\\}", depth - _strip_calls);
|
row = replace(row, "\\{depth\\}", depth - _strip_calls);
|
||||||
|
|
||||||
std::ostringstream chevrons;
|
std::ostringstream chevrons;
|
||||||
for(size_t i = _strip_calls; i < depth; ++i) {
|
for(size_t i = _strip_calls; i < depth; ++i) {
|
||||||
chevrons << _depth_mark;
|
chevrons << _depth_mark;
|
||||||
}
|
}
|
||||||
format = replace(format, "\\{depth_marks\\}", chevrons.str());
|
row = replace(row, "\\{depth_marks\\}", chevrons.str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
row = replace(row, "\\{level_fmt\\}", _level_fmt.at(stage).str());
|
||||||
|
|
||||||
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
||||||
|
// hfill is replaced last to allow for correct line width estimation.
|
||||||
|
const std::string raw_row = replace(row, "\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]", "");
|
||||||
const std::string hfill_tag = "{hfill}";
|
const std::string hfill_tag = "{hfill}";
|
||||||
const size_t hfill_pos = format.find(hfill_tag);
|
const size_t hfill_pos = row.find(hfill_tag);
|
||||||
|
const size_t raw_hfill_pos = raw_row.find(hfill_tag);
|
||||||
|
const size_t nb_columns = std::min(_nb_columns, _hfill_max);
|
||||||
if(hfill_pos != std::string::npos) {
|
if(hfill_pos != std::string::npos) {
|
||||||
if(_nb_columns > 0) {
|
assert(raw_hfill_pos != std::string::npos);
|
||||||
const size_t left_len = hfill_pos;
|
if(nb_columns > 0) {
|
||||||
const size_t right_len = format.size() - hfill_pos - hfill_tag.size();
|
const size_t left_len = raw_hfill_pos;
|
||||||
if(right_len+left_len > _nb_columns) {
|
const size_t right_len = raw_row.size() - raw_hfill_pos - hfill_tag.size();
|
||||||
// The right part would go over the terminal width: add a new line.
|
if(right_len+left_len > nb_columns) {
|
||||||
const std::string hfill(std::max((size_t)0, _nb_columns-right_len), _hfill_char);
|
// The right part would go over the terminal width: add a new row.
|
||||||
|
const std::string hfill(std::max((size_t)0, nb_columns-right_len), _hfill_char);
|
||||||
const std::string hfill_styled = _hfill_fmt(hfill);
|
const std::string hfill_styled = _hfill_fmt(hfill);
|
||||||
format = replace(format, "\\{hfill\\}", "\n"+hfill_styled);
|
row = replace(row, "\\{hfill\\}", "\n"+hfill_styled);
|
||||||
} else {
|
} else {
|
||||||
// There is some space in between left and right parts.
|
// There is some space in between left and right parts.
|
||||||
const std::string hfill(std::max((size_t)0, _nb_columns - (right_len+left_len)), _hfill_char);
|
const std::string hfill(std::max((size_t)0, nb_columns - (right_len+left_len)), _hfill_char);
|
||||||
const std::string hfill_styled = _hfill_fmt(hfill);
|
const std::string hfill_styled = _hfill_fmt(hfill);
|
||||||
format = replace(format, "\\{hfill\\}", hfill_styled);
|
row = replace(row, "\\{hfill\\}", hfill_styled);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We don't know the terminal width.
|
// We don't know the terminal width.
|
||||||
const std::string hfill(1, _hfill_char);
|
const std::string hfill(1, _hfill_char);
|
||||||
const std::string hfill_styled = _hfill_fmt(hfill);
|
const std::string hfill_styled = _hfill_fmt(hfill);
|
||||||
format = replace(format, "\\{hfill\\}", hfill_styled);
|
row = replace(row, "\\{hfill\\}", hfill_styled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// We cannot know the terminal width.
|
||||||
|
const std::string hfill(1, _hfill_char);
|
||||||
|
const std::string hfill_styled = _hfill_fmt(hfill);
|
||||||
|
row = replace(row, "\\{hfill\\}", hfill_styled);
|
||||||
#endif
|
#endif
|
||||||
return _level_fmt.at(stage)(format);
|
return _level_fmt.at(stage)(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Print a log message IF the location matches the given one.
|
//! Print a log message IF the location matches the given one.
|
||||||
|
|
@ -1011,7 +1034,7 @@ class clutchlog
|
||||||
void hfill_fmt(fmt) {}
|
void hfill_fmt(fmt) {}
|
||||||
fmt hfill_fmt() const {}
|
fmt hfill_fmt() const {}
|
||||||
void hfill_max(const size_t) {}
|
void hfill_max(const size_t) {}
|
||||||
unsigned short hfill_max() {}
|
size_t hfill_max() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void threshold(level) {}
|
void threshold(level) {}
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,42 @@ int main(const int argc, char* argv[])
|
||||||
{
|
{
|
||||||
auto& log = clutchlog::logger();
|
auto& log = clutchlog::logger();
|
||||||
|
|
||||||
|
log.style(clutchlog::level::critical,
|
||||||
|
clutchlog::fmt::fg::red);
|
||||||
|
log.style(clutchlog::level::error,
|
||||||
|
clutchlog::fmt::fg::red);
|
||||||
|
log.style(clutchlog::level::warning,
|
||||||
|
clutchlog::fmt::fg::magenta);
|
||||||
|
log.style(clutchlog::level::progress,
|
||||||
|
clutchlog::fmt::fg::yellow);
|
||||||
|
log.style(clutchlog::level::note,
|
||||||
|
clutchlog::fmt::fg::green);
|
||||||
|
log.style(clutchlog::level::info,
|
||||||
|
clutchlog::fmt::fg::magenta);
|
||||||
|
log.style(clutchlog::level::debug,
|
||||||
|
clutchlog::fmt::fg::cyan);
|
||||||
|
log.style(clutchlog::level::xdebug,
|
||||||
|
clutchlog::fmt::fg::blue);
|
||||||
|
std::ostringstream format;
|
||||||
|
clutchlog::fmt reset(clutchlog::fmt::typo::reset);
|
||||||
|
clutchlog::fmt discreet(clutchlog::fmt::fg::black);
|
||||||
|
clutchlog::fmt bold(clutchlog::fmt::typo::bold);
|
||||||
|
format << "{level_fmt}"
|
||||||
|
<< "{level_letter}:"
|
||||||
|
<< "{depth_marks} "
|
||||||
|
<< bold("{msg}")
|
||||||
|
<< discreet(" {hfill} ")
|
||||||
|
<< "{level_fmt}{func}"
|
||||||
|
<< discreet(" @ ")
|
||||||
|
<< "{level_fmt}{file}"
|
||||||
|
<< reset << ":"
|
||||||
|
<< "{level_fmt}{line}"
|
||||||
|
<< "\n";
|
||||||
|
log.format(format.str());
|
||||||
|
|
||||||
|
// log.hfill_max(100);
|
||||||
log.out(std::clog);
|
log.out(std::clog);
|
||||||
log.depth_mark("\t");
|
log.depth_mark(">");
|
||||||
log.format("[{name}] {level}: {depth_marks} {msg}\n");
|
|
||||||
log.style(clutchlog::level::progress,clutchlog::fmt::fg::blue);
|
|
||||||
log.threshold(clutchlog::level::warning);
|
log.threshold(clutchlog::level::warning);
|
||||||
|
|
||||||
if(argc <= 2) {
|
if(argc <= 2) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue