nestlog: choose function-printing style

This commit is contained in:
Roland Conybeare 2023-09-12 15:21:48 -04:00
commit 2871874dd8
7 changed files with 81 additions and 24 deletions

View file

@ -9,6 +9,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "")
add_subdirectory(ex1)
add_subdirectory(ex2)
add_subdirectory(ex3)
# ----------------------------------------------------------------
# make standard directories for std:: includes explicit

View file

@ -26,7 +26,7 @@ main(int argc, char ** argv) {
int n = 4;
scope log(XO_SSETUP0(), ":n", 4);
scope log(XO_SSETUP0(), ":n ", 4);
int fn = fib(n);

View file

@ -0,0 +1,2 @@
add_executable(ex3 ex3.cpp)
xo_include_options(ex3)

36
example/ex3/ex3.cpp Normal file
View file

@ -0,0 +1,36 @@
/* examples ex3/ex3.cpp */
#include "nestlog/scope.hpp"
using namespace xo;
int
fib(int n) {
scope log(XO_SSETUP0(), ":n ", n);
int retval = 1;
if (n >= 2) {
retval = fib(n - 1) + fib(n - 2);
log(":n ", n);
}
log.end_scope("<- :retval ", retval);
return retval;
}
int
main(int argc, char ** argv) {
log_config::style = FS_Pretty;
log_config::indent_width = 4;
int n = 4;
scope log(XO_SSETUP0(), ":n ", 4);
int fn = fib(n);
log(":n ", n);
log("<- :fib(n) ", fn);
}

View file

@ -2,6 +2,7 @@
#pragma once
#include "function.hpp"
#include <cstdint>
namespace xo {
@ -10,12 +11,18 @@ namespace xo {
struct log_config_impl {
/* spaces per indent level */
static std::uint32_t indent_width;
/* display style for function names. FS_Simple|FS_Pretty|FS_Streamlined */
static function_style style;
}; /*log_config_impl*/
template <typename Tag>
std::uint32_t
log_config_impl<Tag>::indent_width = 1;
template <typename Tag>
function_style
log_config_impl<Tag>::style = FS_Streamlined;
using log_config = log_config_impl<class log_config_tag>;
} /*namespace xo*/

View file

@ -27,11 +27,11 @@ namespace xo {
std::ostream & ss() { return ss_; }
/* call on entry to new scope */
void preamble(std::string_view name1, std::string_view name2);
void preamble(function_style style, std::string_view name1, std::string_view name2);
/* call before each new log entry */
void indent(char pad_char);
/* call on exit from scope */
void postamble(std::string_view name1, std::string_view name2);
void postamble(function_style style, std::string_view name1, std::string_view name2);
/* write collected output to *p_sbuf */
void flush2sbuf(std::streambuf * p_sbuf);
@ -44,7 +44,8 @@ namespace xo {
private:
/* common implementation for .preamble(), .postamble() */
void entryexit_aux(std::string_view name1,
void entryexit_aux(function_style style,
std::string_view name1,
std::string_view name2,
char label_char);
@ -107,7 +108,8 @@ namespace xo {
template <typename CharT, typename Traits>
void
state_impl<CharT, Traits>::entryexit_aux(std::string_view name1,
state_impl<CharT, Traits>::entryexit_aux(function_style style,
std::string_view name1,
std::string_view name2,
char label_char)
{
@ -119,24 +121,29 @@ namespace xo {
/* mnemonic for scope entry/exit */
this->ss_ << label_char;
if (log_config::indent_width > 1)
this->ss_ << ' ';
/* scope name */
this->ss_ << name1 << name2;
this->ss_ << function_name(style, name1) << name2;
} /*entryexit_aux*/
template <typename CharT, typename Traits>
void
state_impl<CharT, Traits>::preamble(std::string_view name1,
state_impl<CharT, Traits>::preamble(function_style style,
std::string_view name1,
std::string_view name2)
{
this->entryexit_aux(name1, name2, '+' /*label_char*/);
this->entryexit_aux(style, name1, name2, '+' /*label_char*/);
} /*preamble*/
template <typename CharT, typename Traits>
void
state_impl<CharT, Traits>::postamble(std::string_view name1,
state_impl<CharT, Traits>::postamble(function_style style,
std::string_view name1,
std::string_view name2)
{
this->entryexit_aux(name1, name2, '-' /*label_char*/);
this->entryexit_aux(style, name1, name2, '-' /*label_char*/);
} /*postamble*/
template <typename CharT, typename Traits>

View file

@ -16,28 +16,29 @@ namespace xo {
class state_impl;
//# define XO_SSETUP0() xo::scope_setup(__FUNCTION__)
# define XO_SSETUP0() xo::scope_setup(__PRETTY_FUNCTION__)
# define XO_SSETUP0() xo::scope_setup(log_config::style, __PRETTY_FUNCTION__)
/* throw exception if condition not met*/
# define XO_EXPECT(f,msg) if(!(f)) { throw std::runtime_error(msg); }
/* establish scope using current function name */
# define XO_SCOPE(name) xo::scope name(xo::scope_setup(__FUNCTION__))
# define XO_SCOPE(name) xo::scope name(xo::scope_setup(log_config::style, __PRETTY_FUNCTION__))
/* like XO_SCOPE(name), but also set enabled flag */
# define XO_SCOPE2(name, debug_flag) xo::scope name(xo::scope_setup(__FUNCTION__, debug_flag))
# define XO_SCOPE_DISABLED(name) xo::scope name(xo::scope_setup(__FUNCTION__, false))
# define XOf_SCOPE2(name, debug_flag) xo::scope name(xo::scope_setup(log_config::style, __PRETTY_FUNCTION__, debug_flag))
# define XO_SCOPE_DISABLED(name) xo::scope name(xo::scope_setup(log_config::style, __PRETTY_FUNCTION__, false))
# define XO_STUB() { XO_SCOPE(logr); logr.log("STUB"); }
/* convenience class for basic_scope<..> construction (see below).
* use to disambiguate setup from other arguments
*/
struct scope_setup {
scope_setup(std::string_view name1, std::string_view name2, bool enabled_flag)
: name1_{name1}, name2_{name2}, enabled_flag_{enabled_flag} {}
scope_setup(std::string_view name1, bool enabled_flag)
: scope_setup(name1, "", enabled_flag) {}
scope_setup(std::string_view name1)
: scope_setup(name1, true /*enabled_flag*/) {}
scope_setup(function_style style, std::string_view name1, std::string_view name2, bool enabled_flag)
: style_{style}, name1_{name1}, name2_{name2}, enabled_flag_{enabled_flag} {}
scope_setup(function_style style, std::string_view name1, bool enabled_flag)
: scope_setup(style, name1, "", enabled_flag) {}
scope_setup(function_style style, std::string_view name1)
: scope_setup(style, name1, true /*enabled_flag*/) {}
function_style style_ = FS_Pretty;
std::string_view name1_ = "<.name1>";
std::string_view name2_ = "<.name2>";
bool enabled_flag_ = false;
@ -142,6 +143,8 @@ namespace xo {
/* send indented output to this streambuf (e.g. std::clog.rdbuf()) */
std::streambuf * dest_sbuf_ = std::clog.rdbuf();
/* style for displaying .name1 */
function_style style_ = FS_Pretty;
/* name of this scope (part 1) */
std::string_view name1_ = "<name1>";
/* name of this scope (part 2) */
@ -154,14 +157,15 @@ namespace xo {
template <typename... Tn>
basic_scope<CharT, Traits>::basic_scope(scope_setup setup, Tn&&... args)
: name1_{std::move(setup.name1_)},
: style_{setup.style_},
name1_{std::move(setup.name1_)},
name2_{std::move(setup.name2_)},
finalized_{!setup.enabled_flag_}
{
if(setup.enabled_flag_) {
state_impl_type * logstate = basic_scope::require_thread_local_state();
logstate->preamble(this->name1_, this->name2_);
logstate->preamble(this->style_, this->name1_, this->name2_);
tosn(logstate2stream(logstate), " ", std::forward<Tn>(args)...);
@ -240,7 +244,7 @@ namespace xo {
logstate->decr_nesting();
logstate->postamble(this->name1_, this->name2_);
logstate->postamble(this->style_, this->name1_, this->name2_);
tosn(logstate2stream(logstate), " ", std::forward<Tn>(args)...);