fix: portability patch for OS other than Linux
- Test for sys headers and disable depth/name if not found - Update the doc and bump to 0.3.
This commit is contained in:
parent
008aa7cf31
commit
3a4bdc0d57
4 changed files with 85 additions and 19 deletions
|
|
@ -12,7 +12,7 @@ set(CMAKE_CXX_STANDARD 17)
|
|||
|
||||
## Current version
|
||||
set(VERSION_MAJOR 0 CACHE STRING "Major version number" )
|
||||
set(VERSION_MINOR 2 CACHE STRING "Minor version number" )
|
||||
set(VERSION_MINOR 3 CACHE STRING "Minor version number" )
|
||||
set(VERSION_PATCH 0 CACHE STRING "Patch version number" )
|
||||
mark_as_advanced(VERSION_MAJOR VERSION_MINOR VERSION_PATCH)
|
||||
|
||||
|
|
|
|||
16
README.md
16
README.md
|
|
@ -12,7 +12,8 @@ Clutchlog allows to select which log messages will be displayed, based on their
|
|||
- *source code location*: you can ask to display messages called from given files, functions and line number, all based on
|
||||
regular expressions.
|
||||
|
||||
Of course, Clutchlog is disabled by default if not in "Debug" mode.
|
||||
Additionally, Clutchlog will do its best to allow the compiler to optimize out calls,
|
||||
for instance debug messages in "Release" builds.
|
||||
|
||||
|
||||
Example
|
||||
|
|
@ -182,7 +183,7 @@ for log levels which are under or equal to `progress`.
|
|||
You can change this behavior at compile time by setting the
|
||||
`CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG` preprocessor variable
|
||||
to the desired maximum log level, for example:
|
||||
```
|
||||
```cpp
|
||||
// Will always allow to log everything even in Release mode.
|
||||
#define CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG clutchlog::level::xdebug
|
||||
```
|
||||
|
|
@ -223,8 +224,13 @@ log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), "main.cpp", "main",
|
|||
Limitations
|
||||
===========
|
||||
|
||||
Because the call stack depth and binary name access are system-dependent,
|
||||
Clutchlog is only implemented for Linux at the moment.
|
||||
Because the call stack depth and program name access are system-dependent,
|
||||
the features relying on the depth of the call stack and the display of the program name
|
||||
are only available for operating systems having the following headers:
|
||||
`execinfo.h`, `stdlib.h` and `libgen.h` (so far, tested with Linux).
|
||||
|
||||
Clutchlog needs `C++-17` with the `filesystem` feature.
|
||||
You may need to indicate `-std=c++17 -lstdc++fs` to your compiler.
|
||||
|
||||
|
||||
Build and tests
|
||||
|
|
@ -235,7 +241,7 @@ and either ensure that the `NDEBUG` preprocessor variable is not set,
|
|||
either define the `WITH_CLUTCHLOG` preprocessor variable.
|
||||
|
||||
If you're using CMake (or another modern build system),
|
||||
it will unset `NDEBUG` ---and thus enable clutchlog---
|
||||
it will unset `NDEBUG` —and thus enable clutchlog—
|
||||
only for the "Debug" build type,
|
||||
which is usually what you want if you use clutchlog, anyway.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,17 +8,19 @@
|
|||
#include <fstream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
// #include <iomanip>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <regex>
|
||||
#include <map>
|
||||
|
||||
// #ifdef __unix__
|
||||
#include <execinfo.h>
|
||||
#include <stdlib.h>
|
||||
#include <libgen.h>
|
||||
// #endif
|
||||
#if __has_include(<execinfo.h>) && __has_include(<stdlib.h>) && __has_include(<libgen.h>)
|
||||
#include <execinfo.h> // execinfo
|
||||
#include <stdlib.h> // getenv
|
||||
#include <libgen.h> // basename
|
||||
#define CLUTCHLOG_HAVE_UNIX_SYSINFO 1
|
||||
#else
|
||||
#define CLUTCHLOG_HAVE_UNIX_SYSINFO 0
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* Enable by default in Debug builds.
|
||||
|
|
@ -36,12 +38,20 @@
|
|||
|
||||
#ifndef CLUTCHLOG_DEFAULT_FORMAT
|
||||
//! Default format of the messages.
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
#define CLUTCHLOG_DEFAULT_FORMAT "[{name}] {level_letter}:{depth_marks} {msg}\t\t\t\t\t{func} @ {file}:{line}\n"
|
||||
#else
|
||||
#define CLUTCHLOG_DEFAULT_FORMAT "{level_letter} {msg}\t\t\t\t\t{func} @ {file}:{line}\n"
|
||||
#endif
|
||||
#endif // CLUTCHLOG_DEFAULT_FORMAT
|
||||
|
||||
#ifndef CLUTCHDUMP_DEFAULT_FORMAT
|
||||
//! Default format of the comment line in file dump.
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
#define CLUTCHDUMP_DEFAULT_FORMAT "# [{name}] {level} in {func} (at depth {depth}) @ {file}:{line}"
|
||||
#else
|
||||
#define CLUTCHDUMP_DEFAULT_FORMAT "# {level} in {func} @ {file}:{line}"
|
||||
#endif
|
||||
#endif // CLUTCHDUMP_DEFAULT_FORMAT
|
||||
|
||||
#ifndef CLUTCHDUMP_DEFAULT_SEP
|
||||
|
|
@ -150,12 +160,14 @@ class clutchlog
|
|||
_format_log(CLUTCHLOG_DEFAULT_FORMAT),
|
||||
_format_dump(CLUTCHDUMP_DEFAULT_FORMAT),
|
||||
_out(&std::clog),
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
_depth(std::numeric_limits<size_t>::max() - _strip_calls),
|
||||
_depth_mark(CLUTCHLOG_DEFAULT_DEPTH_MARK),
|
||||
#endif
|
||||
_stage(level::error),
|
||||
_in_file(".*"),
|
||||
_in_func(".*"),
|
||||
_in_line(".*"),
|
||||
_depth_mark(CLUTCHLOG_DEFAULT_DEPTH_MARK)
|
||||
_in_line(".*")
|
||||
{}
|
||||
|
||||
protected:
|
||||
|
|
@ -164,22 +176,28 @@ class clutchlog
|
|||
std::string _format_log;
|
||||
std::string _format_dump;
|
||||
std::ostream* _out;
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
size_t _depth;
|
||||
std::string _depth_mark;
|
||||
#endif
|
||||
level _stage;
|
||||
std::regex _in_file;
|
||||
std::regex _in_func;
|
||||
std::regex _in_line;
|
||||
std::string _depth_mark;
|
||||
|
||||
struct scope_t {
|
||||
bool matches; // everything is compatible
|
||||
level stage; // current log level
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
size_t depth; // current depth
|
||||
#endif
|
||||
bool there; // location is compatible
|
||||
scope_t() :
|
||||
matches(false),
|
||||
stage(level::xdebug),
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
depth(0),
|
||||
#endif
|
||||
there(false)
|
||||
{}
|
||||
};
|
||||
|
|
@ -203,6 +221,7 @@ class clutchlog
|
|||
return scope;
|
||||
}
|
||||
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
/***** Stack depth *****/
|
||||
// Backtrace in second, quite fast.
|
||||
const size_t max_buffer = 4096;
|
||||
|
|
@ -214,6 +233,7 @@ class clutchlog
|
|||
// Bypass if no match.
|
||||
return scope;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***** Location *****/
|
||||
// Location last, slowest.
|
||||
|
|
@ -244,11 +264,13 @@ class clutchlog
|
|||
void out(std::ostream& out) {_out = &out;}
|
||||
std::ostream& out() {return *_out;}
|
||||
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
void depth(size_t d) {_depth = d;}
|
||||
size_t depth() const {return _depth;}
|
||||
|
||||
void depth_mark(std::string mark) {_depth_mark = mark;}
|
||||
std::string depth_mark() const {return _depth_mark;}
|
||||
#endif
|
||||
|
||||
void threshold(level l) {_stage = l;}
|
||||
level threshold() const {return _stage;}
|
||||
|
|
@ -351,30 +373,38 @@ class clutchlog
|
|||
std::string format(
|
||||
std::string format,
|
||||
const std::string& what,
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
const std::string& name,
|
||||
#endif
|
||||
const level& stage,
|
||||
const std::string& file,
|
||||
const std::string& func,
|
||||
const size_t line,
|
||||
const size_t line
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
,
|
||||
const size_t depth
|
||||
#endif
|
||||
) const
|
||||
{
|
||||
format = replace(format, "\\{msg\\}", what);
|
||||
format = replace(format, "\\{name\\}", name);
|
||||
format = replace(format, "\\{file\\}", file);
|
||||
format = replace(format, "\\{func\\}", func);
|
||||
format = replace(format, "\\{level\\}", _level_words.at(stage));
|
||||
format = replace(format, "\\{line\\}", line);
|
||||
format = replace(format, "\\{depth\\}", depth);
|
||||
|
||||
std::string letter(1, _level_words.at(stage).at(0)); // char -> string
|
||||
format = replace(format, "\\{level_letter\\}", letter);
|
||||
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
format = replace(format, "\\{name\\}", name);
|
||||
format = replace(format, "\\{depth\\}", depth);
|
||||
|
||||
std::ostringstream chevrons;
|
||||
for(size_t i = _strip_calls; i < depth; ++i) {
|
||||
chevrons << ">";
|
||||
}
|
||||
format = replace(format, "\\{depth_marks\\}", chevrons.str());
|
||||
#endif
|
||||
|
||||
return format;
|
||||
}
|
||||
|
|
@ -388,9 +418,16 @@ class clutchlog
|
|||
scope_t scope = locate(stage, file, func, line);
|
||||
|
||||
if(scope.matches) {
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
*_out << format(_format_log, what, basename(getenv("_")),
|
||||
stage, file, func,
|
||||
line, scope.depth );
|
||||
#else
|
||||
*_out << format(_format_log, what,
|
||||
stage, file, func,
|
||||
line );
|
||||
|
||||
#endif
|
||||
_out->flush();
|
||||
} // if scopes.matches
|
||||
}
|
||||
|
|
@ -428,9 +465,15 @@ class clutchlog
|
|||
std::ofstream fd(outfile);
|
||||
|
||||
if(_format_dump.size() > 0) {
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
fd << format(_format_dump, "", basename(getenv("_")),
|
||||
stage, file, func,
|
||||
line, scope.depth );
|
||||
#else
|
||||
fd << format(_format_dump, "",
|
||||
stage, file, func,
|
||||
line );
|
||||
#endif
|
||||
fd << sep; // sep after comment line.
|
||||
}
|
||||
|
||||
|
|
@ -479,11 +522,13 @@ class clutchlog
|
|||
void out(std::ostream&) {}
|
||||
std::ostream& out() {}
|
||||
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
void depth(size_t) {}
|
||||
size_t depth() const {}
|
||||
|
||||
void depth_mark(std::string) {}
|
||||
std::string depth_mark() const {}
|
||||
#endif
|
||||
|
||||
void threshold(level) {}
|
||||
level threshold() const {}
|
||||
|
|
@ -519,12 +564,17 @@ class clutchlog
|
|||
std::string format(
|
||||
std::string,
|
||||
const std::string&,
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
const std::string&,
|
||||
#endif
|
||||
const level&,
|
||||
const std::string&,
|
||||
const std::string&,
|
||||
const size_t,
|
||||
const size_t
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
,
|
||||
const size_t
|
||||
#endif
|
||||
) const
|
||||
{ }
|
||||
|
||||
|
|
|
|||
|
|
@ -27,31 +27,41 @@ int main(/*const int argc, char* argv[]*/)
|
|||
log.out(std::clog);
|
||||
|
||||
std::clog << "depth: 99; threshold: xdebug; location: .*" << std::endl;
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
log.depth(99);
|
||||
#endif
|
||||
log.threshold(clutchlog::level::xdebug);
|
||||
log.location(".*",".*");
|
||||
f();
|
||||
|
||||
std::clog << "depth: 4; threshold: xdebug; location: ,*" << std::endl;
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
log.depth(4);
|
||||
#endif
|
||||
log.threshold(clutchlog::level::xdebug);
|
||||
log.location(".*");
|
||||
f();
|
||||
|
||||
std::clog << "depth: 99; threshold: warning; location: .*" << std::endl;
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
log.depth(99);
|
||||
#endif
|
||||
log.threshold(clutchlog::level::warning);
|
||||
log.location(".*");
|
||||
f();
|
||||
|
||||
std::clog << "depth: 99; threshold: xdebug; location: 'core','g'" << std::endl;
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
log.depth(99);
|
||||
#endif
|
||||
log.threshold(clutchlog::level::xdebug);
|
||||
log.location("core","g");
|
||||
f();
|
||||
|
||||
std::clog << "depth: 99; threshold: debug; location: '.*','(g|h)'" << std::endl;
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
log.depth(99);
|
||||
#endif
|
||||
log.threshold(clutchlog::level::debug);
|
||||
log.location(".*","(g|h)");
|
||||
f();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue