nestlog: print [file:line] on rhs of log line
This commit is contained in:
parent
f7c19c338f
commit
a150913045
6 changed files with 206 additions and 46 deletions
|
|
@ -24,6 +24,7 @@ int
|
||||||
main(int argc, char ** argv) {
|
main(int argc, char ** argv) {
|
||||||
log_config::style = FS_Pretty;
|
log_config::style = FS_Pretty;
|
||||||
log_config::indent_width = 4;
|
log_config::indent_width = 4;
|
||||||
|
log_config::location_tab = 40;
|
||||||
|
|
||||||
int n = 4;
|
int n = 4;
|
||||||
|
|
||||||
|
|
@ -34,3 +35,5 @@ main(int argc, char ** argv) {
|
||||||
log(xtag("n", n));
|
log(xtag("n", n));
|
||||||
log("<-", xtag("fib(n)", fn));
|
log("<-", xtag("fib(n)", fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ex3/ex3.cpp */
|
||||||
|
|
|
||||||
70
include/nestlog/filename.hpp
Normal file
70
include/nestlog/filename.hpp
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* @file filename.hpp */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace xo {
|
||||||
|
/* Example:
|
||||||
|
* os << basename("/path/to/basename.cpp")
|
||||||
|
* prints
|
||||||
|
* basename.cpp
|
||||||
|
* on os
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Tag to drive header-only expression */
|
||||||
|
template <typename Tag>
|
||||||
|
class basename_impl {
|
||||||
|
public:
|
||||||
|
basename_impl(std::string_view path)
|
||||||
|
: path_{path} {}
|
||||||
|
|
||||||
|
std::string_view const & path() const { return path_; }
|
||||||
|
|
||||||
|
/* /home/roland/proj/nestlog/include/nestlog/filename.hpp
|
||||||
|
* <-basename->
|
||||||
|
*/
|
||||||
|
static void print_basename(std::ostream & os, std::string_view const & s) {
|
||||||
|
std::size_t p = exclude_dirname(s);
|
||||||
|
|
||||||
|
os << s.substr(p);
|
||||||
|
} /*print_basename*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::size_t exclude_dirname(std::string_view const & s) {
|
||||||
|
std::size_t z = s.size();
|
||||||
|
|
||||||
|
if (z == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (s[z-1] == '/') {
|
||||||
|
/* ignore trailing '/' */
|
||||||
|
return exclude_dirname(s.substr(0, z-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t p = s.find_last_of('/');
|
||||||
|
|
||||||
|
if (p == std::string_view::npos)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return p + 1;
|
||||||
|
} /*exclude_dirname*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* some unix pathname, e.g. [/home/roland/proj/nestlog/include/nestlog/filename.hpp] */
|
||||||
|
std::string_view path_;
|
||||||
|
}; /*basename_impl*/
|
||||||
|
|
||||||
|
using basename = basename_impl<class basename_impl_tag>;
|
||||||
|
|
||||||
|
inline std::ostream &
|
||||||
|
operator<<(std::ostream & os,
|
||||||
|
basename const & bn)
|
||||||
|
{
|
||||||
|
basename::print_basename(os, bn.path());
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
} /*xo*/
|
||||||
|
|
||||||
|
/* end filename.hpp */
|
||||||
|
|
@ -13,6 +13,10 @@ namespace xo {
|
||||||
static std::uint32_t indent_width;
|
static std::uint32_t indent_width;
|
||||||
/* display style for function names. FS_Simple|FS_Pretty|FS_Streamlined */
|
/* display style for function names. FS_Simple|FS_Pretty|FS_Streamlined */
|
||||||
static function_style style;
|
static function_style style;
|
||||||
|
/* if true, append [file:line] to output */
|
||||||
|
static bool location_enabled;
|
||||||
|
/* when .location_enabled, write [file:line] starting this many chars from left margin */
|
||||||
|
static std::uint32_t location_tab;
|
||||||
}; /*log_config_impl*/
|
}; /*log_config_impl*/
|
||||||
|
|
||||||
template <typename Tag>
|
template <typename Tag>
|
||||||
|
|
@ -23,6 +27,14 @@ namespace xo {
|
||||||
function_style
|
function_style
|
||||||
log_config_impl<Tag>::style = FS_Streamlined;
|
log_config_impl<Tag>::style = FS_Streamlined;
|
||||||
|
|
||||||
|
template <typename Tag>
|
||||||
|
bool
|
||||||
|
log_config_impl<Tag>::location_enabled = true;
|
||||||
|
|
||||||
|
template <typename Tag>
|
||||||
|
std::uint32_t
|
||||||
|
log_config_impl<Tag>::location_tab = 80;
|
||||||
|
|
||||||
using log_config = log_config_impl<class log_config_tag>;
|
using log_config = log_config_impl<class log_config_tag>;
|
||||||
} /*namespace xo*/
|
} /*namespace xo*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@
|
||||||
#include "log_config.hpp"
|
#include "log_config.hpp"
|
||||||
#include "log_streambuf.hpp"
|
#include "log_streambuf.hpp"
|
||||||
#include "pad.hpp"
|
#include "pad.hpp"
|
||||||
|
#include "filename.hpp"
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <sstream>
|
||||||
#include <memory> // for std::unique_ptr
|
#include <memory> // for std::unique_ptr
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
|
|
@ -42,6 +44,12 @@ namespace xo {
|
||||||
p_sbuf_phase2_->reset_stream();
|
p_sbuf_phase2_->reset_stream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_location(std::string_view file, std::uint32_t line) {
|
||||||
|
this->location_flag_ = true;
|
||||||
|
this->file_ = std::move(file);
|
||||||
|
this->line_ = line;
|
||||||
|
} /*set_location*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* common implementation for .preamble(), .postamble() */
|
/* common implementation for .preamble(), .postamble() */
|
||||||
void entryexit_aux(function_style style,
|
void entryexit_aux(function_style style,
|
||||||
|
|
@ -59,6 +67,21 @@ namespace xo {
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<log_streambuf_type> p_sbuf_phase1_;
|
std::unique_ptr<log_streambuf_type> p_sbuf_phase1_;
|
||||||
|
|
||||||
|
/* #of characters found in .p_sbuf_phase1 since last \n.
|
||||||
|
* this value is established+updated in .flush2sbuf().
|
||||||
|
* (in particular ignored by stream .ss())
|
||||||
|
*/
|
||||||
|
std::size_t lpos_ = 0;
|
||||||
|
|
||||||
|
/* whenever .set_location() is called:
|
||||||
|
* - capture (file, line)
|
||||||
|
* - print them near right margin with next output line
|
||||||
|
* - ..and reset .location_flag
|
||||||
|
*/
|
||||||
|
bool location_flag_ = false;
|
||||||
|
std::string_view file_;
|
||||||
|
std::uint32_t line_ = 0;
|
||||||
|
|
||||||
/* buffer space for handling scope::log() calls that span multiple lines;
|
/* buffer space for handling scope::log() calls that span multiple lines;
|
||||||
* inserts extra characters in effort to indent gracefully
|
* inserts extra characters in effort to indent gracefully
|
||||||
*/
|
*/
|
||||||
|
|
@ -99,11 +122,6 @@ namespace xo {
|
||||||
|
|
||||||
/* indent to nesting level */
|
/* indent to nesting level */
|
||||||
this->ss_ << pad(this->nesting_level_ * log_config::indent_width, pad_char);
|
this->ss_ << pad(this->nesting_level_ * log_config::indent_width, pad_char);
|
||||||
#ifdef OBSOLETE
|
|
||||||
for(uint32_t i = 0, n = this->nesting_level_; i<n; ++i) {
|
|
||||||
this->ss_ << pad_char;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} /*indent*/
|
} /*indent*/
|
||||||
|
|
||||||
template <typename CharT, typename Traits>
|
template <typename CharT, typename Traits>
|
||||||
|
|
@ -124,7 +142,7 @@ namespace xo {
|
||||||
if (log_config::indent_width > 1)
|
if (log_config::indent_width > 1)
|
||||||
this->ss_ << ' ';
|
this->ss_ << ' ';
|
||||||
|
|
||||||
/* scope name */
|
/* scope name - note no trailing newline; expect .preamble()/.postamble() caller to supply */
|
||||||
this->ss_ << function_name(style, name1) << name2;
|
this->ss_ << function_name(style, name1) << name2;
|
||||||
} /*entryexit_aux*/
|
} /*entryexit_aux*/
|
||||||
|
|
||||||
|
|
@ -153,12 +171,15 @@ namespace xo {
|
||||||
log_streambuf_type * sbuf1 = this->p_sbuf_phase1_.get();
|
log_streambuf_type * sbuf1 = this->p_sbuf_phase1_.get();
|
||||||
log_streambuf_type * sbuf2 = this->p_sbuf_phase2_.get();
|
log_streambuf_type * sbuf2 = this->p_sbuf_phase2_.get();
|
||||||
|
|
||||||
/* expecting sbuf to contain one line of output.
|
/* generally expecting sbuf to contain one line of output.
|
||||||
* if it contains multiple newlines, need to indent
|
* if it contains multiple newlines, need to indent
|
||||||
* after each one.
|
* after each one.
|
||||||
*
|
*
|
||||||
* will scan output in *sbuf1, post-process to *sbuf2,
|
* will scan output in *sbuf1, post-process to *sbuf2,
|
||||||
* then write *sbuf2 to clog
|
* then write *sbuf2 to output stream
|
||||||
|
*
|
||||||
|
* note: we inherit .lpos from prec call to .flush2sbuf(),
|
||||||
|
* in the unlikely event that it's non-zero
|
||||||
*/
|
*/
|
||||||
char const * s = sbuf1->lo();
|
char const * s = sbuf1->lo();
|
||||||
char const * e = s + sbuf1->pos();
|
char const * e = s + sbuf1->pos();
|
||||||
|
|
@ -177,6 +198,8 @@ namespace xo {
|
||||||
|
|
||||||
/* for indenting, looking for first 'space following non-space, on first line', if any */
|
/* for indenting, looking for first 'space following non-space, on first line', if any */
|
||||||
|
|
||||||
|
std::size_t lpos_on_newline = 0;
|
||||||
|
|
||||||
while(p < e) {
|
while(p < e) {
|
||||||
if(space_after_nonspace) {
|
if(space_after_nonspace) {
|
||||||
;
|
;
|
||||||
|
|
@ -191,18 +214,50 @@ namespace xo {
|
||||||
|
|
||||||
if(*p == '\n') {
|
if(*p == '\n') {
|
||||||
++p;
|
++p;
|
||||||
|
/* reset .pos on newline */
|
||||||
|
lpos_on_newline = this->lpos_;
|
||||||
|
this->lpos_ = 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
++p;
|
++p;
|
||||||
|
|
||||||
|
/* increment .lpos on non-newline */
|
||||||
|
++(this->lpos_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* p=e or *p=\n */
|
/* p=e or *p=\n */
|
||||||
|
|
||||||
/* charseq [s,p) does not contain any newlines, print it */
|
/* charseq [s,p) does not contain any newlines, print it */
|
||||||
sbuf2->sputn(s, p - s);
|
if (lpos_on_newline > 0) {
|
||||||
|
/* charseq [s,p) does not contain any newlines, print it */
|
||||||
|
sbuf2->sputn(s, p - s - 1);
|
||||||
|
|
||||||
if(p == e) {
|
if (this->location_flag_) {
|
||||||
|
/* 'tab' to position 80 */
|
||||||
|
sbuf2->sputc(' ');
|
||||||
|
for (std::uint32_t i = lpos_on_newline + 1; i < log_config::location_tab; ++i)
|
||||||
|
sbuf2->sputc(' ');
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "[" << basename(this->file_) << ":" << this->line_ << "]";
|
||||||
|
|
||||||
|
std::string ss_str = std::move(ss.str()); /*c++20*/
|
||||||
|
sbuf2->sputn(ss_str.c_str(), ss_str.size());
|
||||||
|
|
||||||
|
this->location_flag_ = false;
|
||||||
|
this->file_ = "";
|
||||||
|
this->line_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sbuf2->sputc('\n');
|
||||||
|
} else {
|
||||||
|
/* control here if .flush2sbuf() called without trailing newline in .p_sbuf_phase1 */
|
||||||
|
sbuf2->sputn(s, p - s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == e) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,30 +36,30 @@ namespace xo {
|
||||||
protected:
|
protected:
|
||||||
virtual std::streamsize
|
virtual std::streamsize
|
||||||
xsputn(char const * s, std::streamsize n) override {
|
xsputn(char const * s, std::streamsize n) override {
|
||||||
/* s must be an address in [this->lo() .. this->lo() + capacity()] */
|
/* s must be an address in [this->lo() .. this->lo() + capacity()] */
|
||||||
|
|
||||||
assert(this->hi() >= this->pptr());
|
assert(this->hi() >= this->pptr());
|
||||||
|
|
||||||
#ifdef NOT_USING_DEBUG
|
#ifdef NOT_USING_DEBUG
|
||||||
std::cout << "xsputn: pbase=" << (void *)(this->pbase())
|
std::cout << "xsputn: pbase=" << (void *)(this->pbase())
|
||||||
<< ", pptr=" << (void*)(this->pptr())
|
<< ", pptr=" << (void*)(this->pptr())
|
||||||
<< "(+" << (this->pptr() - this->lo()) << ")"
|
<< "(+" << (this->pptr() - this->lo()) << ")"
|
||||||
<< ", n=" << n << " -> (+" << (this->pptr() + n - this->lo()) << ")"
|
<< ", n=" << n << " -> (+" << (this->pptr() + n - this->lo()) << ")"
|
||||||
<< ", buf_v.size=" << this->buf_v_.size()
|
<< ", buf_v.size=" << this->buf_v_.size()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
//std::cout << "xsputn: s=" << quoted(string_view(s, n)) << ", n=" << n << std::endl;
|
//std::cout << "xsputn: s=" << quoted(string_view(s, n)) << ", n=" << n << std::endl;
|
||||||
|
|
||||||
if (this->pptr() + n > this->hi()) {
|
if (this->pptr() + n > this->hi()) {
|
||||||
n = this->hi() - this->pptr();
|
n = this->hi() - this->pptr();
|
||||||
std::memcpy(this->pptr(), s, n);
|
std::memcpy(this->pptr(), s, n);
|
||||||
} else {
|
} else {
|
||||||
std::memcpy(this->pptr(), s, n);
|
std::memcpy(this->pptr(), s, n);
|
||||||
}
|
}
|
||||||
this->pbump(n);
|
this->pbump(n);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
} /*xsputn*/
|
} /*xsputn*/
|
||||||
|
|
||||||
virtual int_type
|
virtual int_type
|
||||||
overflow(int_type new_ch) override
|
overflow(int_type new_ch) override
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
/* @file scopẹhpp */
|
/* @file scope.hpp */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "log_state.hpp"
|
#include "log_state.hpp"
|
||||||
|
#include "filename.hpp"
|
||||||
#include "tostr.hpp"
|
#include "tostr.hpp"
|
||||||
#include "tag.hpp"
|
#include "tag.hpp"
|
||||||
|
|
||||||
|
|
@ -15,38 +16,44 @@ namespace xo {
|
||||||
template <typename ChartT, typename Traits>
|
template <typename ChartT, typename Traits>
|
||||||
class state_impl;
|
class state_impl;
|
||||||
|
|
||||||
# define XO_ENTER0() xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__)
|
# define XO_ENTER0() xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__)
|
||||||
# define XO_ENTER1(debug_flag) xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, debug_flag)
|
# define XO_ENTER1(debug_flag) xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__, debug_flag)
|
||||||
|
|
||||||
//# define XO_SSETUP0() xo::scope_setup(__FUNCTION__)
|
//# define XO_SSETUP0() xo::scope_setup(__FUNCTION__)
|
||||||
# define XO_SSETUP0() xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__)
|
# define XO_SSETUP0() xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__)
|
||||||
|
|
||||||
/* throw exception if condition not met*/
|
/* throw exception if condition not met*/
|
||||||
# define XO_EXPECT(f,msg) if(!(f)) { throw std::runtime_error(msg); }
|
# define XO_EXPECT(f,msg) if(!(f)) { throw std::runtime_error(msg); }
|
||||||
/* establish scope using current function name */
|
/* establish scope using current function name */
|
||||||
# define XO_SCOPE(name) xo::scope name(xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__))
|
# define XO_SCOPE(name) xo::scope name(xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__))
|
||||||
/* like XO_SCOPE(name), but also set enabled flag */
|
/* like XO_SCOPE(name), but also set enabled flag */
|
||||||
# define XO_SCOPE2(name, debug_flag) xo::scope name(xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, debug_flag))
|
# define XO_SCOPE2(name, debug_flag) xo::scope name(xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__, debug_flag))
|
||||||
# define XO_SCOPE_DISABLED(name) xo::scope name(xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, false))
|
# define XO_SCOPE_DISABLED(name) xo::scope name(xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__, false))
|
||||||
# define XO_STUB() { XO_SCOPE(logr); logr.log("STUB"); }
|
# define XO_STUB() { XO_SCOPE(logr); logr.log("STUB"); }
|
||||||
|
|
||||||
/* convenience class for basic_scope<..> construction (see below).
|
/* convenience class for basic_scope<..> construction (see below).
|
||||||
* use to disambiguate setup from other arguments
|
* use to disambiguate setup from other arguments
|
||||||
*/
|
*/
|
||||||
struct scope_setup {
|
struct scope_setup {
|
||||||
scope_setup(function_style style, std::string_view name1, std::string_view name2, bool enabled_flag)
|
scope_setup(function_style style, std::string_view name1, std::string_view name2,
|
||||||
: style_{style}, name1_{name1}, name2_{name2}, enabled_flag_{enabled_flag} {}
|
std::string_view file, std::uint32_t line, bool enabled_flag)
|
||||||
scope_setup(function_style style, std::string_view name1, bool enabled_flag)
|
: style_{style}, name1_{name1}, name2_{name2}, file_{file}, line_{line}, enabled_flag_{enabled_flag} {}
|
||||||
: scope_setup(style, name1, "", enabled_flag) {}
|
scope_setup(function_style style, std::string_view name1, std::string_view file, std::uint32_t line, bool enabled_flag)
|
||||||
scope_setup(function_style style, std::string_view name1)
|
: scope_setup(style, name1, "", file, line, enabled_flag) {}
|
||||||
: scope_setup(style, name1, true /*enabled_flag*/) {}
|
scope_setup(function_style style, std::string_view name1, std::string_view file, std::uint32_t line)
|
||||||
|
: scope_setup(style, name1, file, line, true /*enabled_flag*/) {}
|
||||||
|
|
||||||
static scope_setup literal(std::string_view name1, bool enabled_flag = true) { return scope_setup(FS_Literal, name1, enabled_flag); }
|
//static scope_setup literal(std::string_view name1, bool enabled_flag = true) { return scope_setup(FS_Literal, name1, enabled_flag); }
|
||||||
static scope_setup literal(std::string_view name1, std::string_view name2, bool enabled_flag = true) { return scope_setup(FS_Literal, name1, name2, enabled_flag); }
|
//static scope_setup literal(std::string_view name1, std::string_view name2, bool enabled_flag = true) { return scope_setup(FS_Literal, name1, name2, enabled_flag); }
|
||||||
|
|
||||||
function_style style_ = FS_Pretty;
|
function_style style_ = FS_Pretty;
|
||||||
std::string_view name1_ = "<.name1>";
|
std::string_view name1_ = "<.name1>";
|
||||||
std::string_view name2_ = "<.name2>";
|
std::string_view name2_ = "<.name2>";
|
||||||
|
/* __FILE__ */
|
||||||
|
std::string_view file_ = "<.file>";
|
||||||
|
/* __LINE__ */
|
||||||
|
std::uint32_t line_ = 0;
|
||||||
|
/* true iff output enabled for this scope */
|
||||||
bool enabled_flag_ = false;
|
bool enabled_flag_ = false;
|
||||||
}; /*scope_setup*/
|
}; /*scope_setup*/
|
||||||
|
|
||||||
|
|
@ -155,6 +162,10 @@ namespace xo {
|
||||||
std::string_view name1_ = "<name1>";
|
std::string_view name1_ = "<name1>";
|
||||||
/* name of this scope (part 2) */
|
/* name of this scope (part 2) */
|
||||||
std::string_view name2_ = "::<name2>";
|
std::string_view name2_ = "::<name2>";
|
||||||
|
/* captured value of __FILE__ */
|
||||||
|
std::string_view file_ = "<file>";
|
||||||
|
/* captured value of __LINE__ */
|
||||||
|
std::uint32_t line_ = 0;
|
||||||
/* set once per scope .finalized=true <-> logging disabled */
|
/* set once per scope .finalized=true <-> logging disabled */
|
||||||
bool finalized_ = false;
|
bool finalized_ = false;
|
||||||
}; /*basic_scope*/
|
}; /*basic_scope*/
|
||||||
|
|
@ -166,14 +177,23 @@ namespace xo {
|
||||||
: style_{setup.style_},
|
: style_{setup.style_},
|
||||||
name1_{std::move(setup.name1_)},
|
name1_{std::move(setup.name1_)},
|
||||||
name2_{std::move(setup.name2_)},
|
name2_{std::move(setup.name2_)},
|
||||||
|
file_{std::move(setup.file_)},
|
||||||
|
line_{setup.line_},
|
||||||
finalized_{!setup.enabled_flag_}
|
finalized_{!setup.enabled_flag_}
|
||||||
{
|
{
|
||||||
if(setup.enabled_flag_) {
|
if(setup.enabled_flag_) {
|
||||||
state_impl_type * logstate = basic_scope::require_thread_local_state();
|
state_impl_type * logstate = basic_scope::require_thread_local_state();
|
||||||
|
std::ostream & os = logstate2stream(logstate);
|
||||||
|
|
||||||
logstate->preamble(this->style_, this->name1_, this->name2_);
|
logstate->preamble(this->style_, this->name1_, this->name2_);
|
||||||
|
|
||||||
tosn(logstate2stream(logstate), " ", std::forward<Tn>(args)...);
|
tosn(os, " ", std::forward<Tn>(args)...);
|
||||||
|
|
||||||
|
if (log_config::location_enabled) {
|
||||||
|
/* prints on next call to flush2sbuf */
|
||||||
|
logstate->set_location(this->file_, this->line_);
|
||||||
|
//tosn(os, " [", basename(this->file_), ":", this->line_, "]");
|
||||||
|
}
|
||||||
|
|
||||||
logstate->flush2sbuf(std::clog.rdbuf());
|
logstate->flush2sbuf(std::clog.rdbuf());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue