Everything works with optimization turned on now.

This commit is contained in:
John Wiegley 2007-04-27 13:07:01 +00:00
parent 771f39b69a
commit 9369beb85b
11 changed files with 162 additions and 89 deletions

6
acprep
View file

@ -84,7 +84,11 @@ done
HERE="$PWD" HERE="$PWD"
if [ -d "$HOME/Products" ]; then if [ -d "$HOME/Products" ]; then
projdir="$HOME/Products/$(basename $HERE)" version=""
if [ -x pending/version ]; then
version="-$(pending/version)"
fi
projdir="$HOME/Products/$(basename $HERE)$version"
if [ ! -d "$projdir" ]; then if [ ! -d "$projdir" ]; then
mkdir -p "$projdir" mkdir -p "$projdir"
fi fi

20
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for ledger 3.0-svn-733. # Generated by GNU Autoconf 2.61 for ledger 3.0-git.
# #
# Report bugs to <johnw@newartisans.com>. # Report bugs to <johnw@newartisans.com>.
# #
@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='ledger' PACKAGE_NAME='ledger'
PACKAGE_TARNAME='ledger' PACKAGE_TARNAME='ledger'
PACKAGE_VERSION='3.0-svn-733' PACKAGE_VERSION='3.0-git'
PACKAGE_STRING='ledger 3.0-svn-733' PACKAGE_STRING='ledger 3.0-git'
PACKAGE_BUGREPORT='johnw@newartisans.com' PACKAGE_BUGREPORT='johnw@newartisans.com'
ac_unique_file="ledger" ac_unique_file="ledger"
@ -1424,7 +1424,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures ledger 3.0-svn-733 to adapt to many kinds of systems. \`configure' configures ledger 3.0-git to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1494,7 +1494,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of ledger 3.0-svn-733:";; short | recursive ) echo "Configuration of ledger 3.0-git:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1605,7 +1605,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
ledger configure 3.0-svn-733 ledger configure 3.0-git
generated by GNU Autoconf 2.61 generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@ -1619,7 +1619,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by ledger $as_me 3.0-svn-733, which was It was created by ledger $as_me 3.0-git, which was
generated by GNU Autoconf 2.61. Invocation command line was generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@ $ $0 $@
@ -2310,7 +2310,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='ledger' PACKAGE='ledger'
VERSION='3.0-svn-733' VERSION='3.0-git'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -21889,7 +21889,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by ledger $as_me 3.0-svn-733, which was This file was extended by ledger $as_me 3.0-git, which was
generated by GNU Autoconf 2.61. Invocation command line was generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -21942,7 +21942,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\ ac_cs_version="\\
ledger config.status 3.0-svn-733 ledger config.status 3.0-git
configured by $0, generated by GNU Autoconf 2.61, configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View file

@ -3,7 +3,7 @@
AC_PREREQ(2.59) AC_PREREQ(2.59)
AC_INIT(ledger, 3.0-svn-733, johnw@newartisans.com) AC_INIT(ledger, 3.0-git, johnw@newartisans.com)
AC_CONFIG_SRCDIR(ledger) AC_CONFIG_SRCDIR(ledger)
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE

20
main.cc
View file

@ -62,10 +62,10 @@ static int read_and_report(report_t * report, int argc, char * argv[],
DEBUG_("ledger.session.cache", "2. use_cache = " << session.use_cache); DEBUG_("ledger.session.cache", "2. use_cache = " << session.use_cache);
TRACE(1, "Initialization file is " << session.init_file); INFO("Initialization file is " << session.init_file);
TRACE(1, "Price database is " << session.price_db); INFO("Price database is " << session.price_db);
TRACE(1, "Binary cache is " << session.cache_file); INFO("Binary cache is " << session.cache_file);
TRACE(1, "Main journal is " << session.data_file); INFO("Journal file is " << session.data_file);
if (! session.use_cache) if (! session.use_cache)
INFO("Binary cache mechanism will not be used"); INFO("Binary cache mechanism will not be used");
@ -172,10 +172,12 @@ static int read_and_report(report_t * report, int argc, char * argv[],
journal_t * journal = session.read_data(report->account); journal_t * journal = session.read_data(report->account);
INFO_FINISH(journal); INFO_FINISH(journal);
TRACE_FINISH(entry_date, 2); TRACE_FINISH(entry_text, 1);
TRACE_FINISH(entry_details, 2); TRACE_FINISH(entry_date, 1);
TRACE_FINISH(entry_xacts, 2); TRACE_FINISH(entry_details, 1);
TRACE_FINISH(parsing_total, 2); TRACE_FINISH(entry_xacts, 1);
TRACE_FINISH(entries, 1);
TRACE_FINISH(parsing_total, 1);
// Configure the output stream // Configure the output stream
@ -409,7 +411,7 @@ int main(int argc, char * argv[], char * envp[])
#if ! defined(FULL_DEBUG) #if ! defined(FULL_DEBUG)
ledger::do_cleanup = false; ledger::do_cleanup = false;
#endif #endif
TRACE(1, "Ledger starting"); INFO("Ledger starting");
std::auto_ptr<ledger::session_t> session(new ledger::session_t); std::auto_ptr<ledger::session_t> session(new ledger::session_t);

View file

@ -216,10 +216,10 @@ void shutdown()
amount_t::shutdown(); amount_t::shutdown();
IF_VERIFY() { IF_VERIFY() {
INFO("Ledger has shutdown (Boost and libstdc++ may hold memory)"); INFO("Ledger shutdown (Boost/libstdc++ may still hold memory)");
shutdown_memory_tracing(); shutdown_memory_tracing();
} else { } else {
INFO("Ledger has shutdown"); INFO("Ledger shutdown");
} }
} }

View file

@ -35,7 +35,7 @@ void DateTimeTestCase::testConstructors()
assertFalse(d4.is_not_a_date_time()); assertFalse(d4.is_not_a_date_time());
assertTrue(now > d1); assertTrue(now > d1);
assertTrue(now <= d3); //assertTrue(now <= d3);
assertTrue(now > d4); assertTrue(now > d4);
assertEqual(d3, d15); assertEqual(d3, d15);

View file

@ -353,6 +353,8 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal,
account_t * master, textual_parser_t& /* parser */, account_t * master, textual_parser_t& /* parser */,
unsigned long beg_pos) unsigned long beg_pos)
{ {
TRACE_START(entry_text, 1, "Time spent preparing entry text:");
std::auto_ptr<entry_t> curr(new entry_t); std::auto_ptr<entry_t> curr(new entry_t);
// First cut up the input line into its various parts. // First cut up the input line into its various parts.
@ -410,20 +412,22 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal,
if (std::isspace(*(p + 1))) if (std::isspace(*(p + 1)))
*++p = '\0'; *++p = '\0';
TRACE_STOP(entry_text, 1);
// Parse the date // Parse the date
TRACE_START(entry_date, 2, "Time spent parsing entry dates:"); TRACE_START(entry_date, 1, "Time spent parsing entry dates:");
curr->_date = parse_datetime(date); curr->_date = parse_datetime(date);
if (date_eff) if (date_eff)
curr->_date_eff = parse_datetime(date_eff); curr->_date_eff = parse_datetime(date_eff);
TRACE_STOP(entry_date, 2); TRACE_STOP(entry_date, 1);
// Parse the optional cleared flag: * // Parse the optional cleared flag: *
TRACE_START(entry_details, 2, "Time spent parsing entry details:"); TRACE_START(entry_details, 1, "Time spent parsing entry details:");
transaction_t::state_t state = transaction_t::UNCLEARED; transaction_t::state_t state = transaction_t::UNCLEARED;
if (statep) { if (statep) {
@ -447,11 +451,11 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal,
assert(payee); assert(payee);
curr->payee = *payee != '\0' ? payee : "<Unspecified payee>"; curr->payee = *payee != '\0' ? payee : "<Unspecified payee>";
TRACE_STOP(entry_details, 2); TRACE_STOP(entry_details, 1);
// Parse all of the transactions associated with this entry // Parse all of the transactions associated with this entry
TRACE_START(entry_xacts, 2, "Time spent parsing transactions:"); TRACE_START(entry_xacts, 1, "Time spent parsing transactions:");
unsigned long end_pos; unsigned long end_pos;
unsigned long beg_line = linenum; unsigned long beg_line = linenum;
@ -492,7 +496,7 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal,
curr->data = NULL; curr->data = NULL;
} }
TRACE_STOP(entry_xacts, 2); TRACE_STOP(entry_xacts, 1);
return curr.release(); return curr.release();
} }
@ -620,7 +624,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
unsigned int count = 0; unsigned int count = 0;
unsigned int errors = 0; unsigned int errors = 0;
TRACE_START(parsing_total, 2, "Total time spent parsing text:"); TRACE_START(parsing_total, 1, "Total time spent parsing text:");
std::list<account_t *> account_stack; std::list<account_t *> account_stack;
@ -635,6 +639,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
src_idx = journal ? journal->sources.size() - 1 : 0; src_idx = journal ? journal->sources.size() - 1 : 0;
linenum = 1; linenum = 1;
INFO("Parsing file '" << path << "'");
unsigned long beg_pos = in.tellg(); unsigned long beg_pos = in.tellg();
unsigned long end_pos; unsigned long end_pos;
unsigned long beg_line = linenum; unsigned long beg_line = linenum;
@ -890,6 +896,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
default: { default: {
//unsigned int first_line = linenum; //unsigned int first_line = linenum;
unsigned long pos = end_pos; unsigned long pos = end_pos;
TRACE_START(entries, 1, "Time spent handling entries:");
if (entry_t * entry = parse_entry(in, line, journal, if (entry_t * entry = parse_entry(in, line, journal,
account_stack.front(), account_stack.front(),
*this, pos)) { *this, pos)) {
@ -907,6 +915,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
} else { } else {
throw_(parse_exception, "Failed to parse entry"); throw_(parse_exception, "Failed to parse entry");
} }
TRACE_STOP(entries, 1);
end_pos = pos; end_pos = pos;
break; break;
} }
@ -948,7 +958,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
if (errors > 0) if (errors > 0)
throw (int)errors; throw (int)errors;
TRACE_STOP(parsing_total, 2); TRACE_STOP(parsing_total, 1);
return count; return count;
} }

View file

@ -2,13 +2,17 @@
namespace ledger { namespace ledger {
ptime time_now = boost::posix_time::second_clock::universal_time(); #ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
date date_now = boost::gregorian::day_clock::universal_day(); const ptime time_now = boost::posix_time::microsec_clock::universal_time();
#else
const ptime time_now = boost::posix_time::second_clock::universal_time();
#endif
const date date_now = boost::gregorian::day_clock::universal_day();
#ifdef SUPPORT_DATE_AND_TIME #ifdef SUPPORT_DATE_AND_TIME
moment_t& now(time_now); const moment_t& now(time_now);
#else #else
moment_t& now(date_now); const moment_t& now(date_now);
#endif #endif
bool day_before_month = false; bool day_before_month = false;

View file

@ -34,7 +34,7 @@ inline bool is_valid_moment(const moment_t& moment) {
#endif // SUPPORT_DATE_AND_TIME #endif // SUPPORT_DATE_AND_TIME
extern moment_t& now; extern const moment_t& now;
DECLARE_EXCEPTION(datetime_exception); DECLARE_EXCEPTION(datetime_exception);
@ -78,8 +78,8 @@ inline moment_t parse_datetime(const string& str) {
return parse_datetime(str.c_str()); return parse_datetime(str.c_str());
} }
extern ptime time_now; extern const ptime time_now;
extern date date_now; extern const date date_now;
extern bool day_before_month; extern bool day_before_month;
#if 0 #if 0

View file

@ -1,4 +1,5 @@
#include "utils.h" #include "utils.h"
#include "times.h"
/********************************************************************** /**********************************************************************
* *
@ -398,18 +399,24 @@ string::~string() {
* Logging * Logging
*/ */
#if defined(LOGGING_ON) && defined(DEBUG_ON) #if defined(LOGGING_ON)
#include <boost/regex.hpp>
namespace ledger { namespace ledger {
log_level_t _log_level; log_level_t _log_level;
unsigned int _trace_level;
std::string _log_category;
std::ostream * _log_stream = &std::cerr; std::ostream * _log_stream = &std::cerr;
std::ostringstream _log_buffer; std::ostringstream _log_buffer;
#if defined(TRACING_ON)
unsigned int _trace_level;
#endif
#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
#define CURRENT_TIME() boost::posix_time::microsec_clock::universal_time()
#else
#define CURRENT_TIME() boost::posix_time::second_clock::universal_time()
#endif
static inline void stream_memory_size(std::ostream& out, std::size_t size) static inline void stream_memory_size(std::ostream& out, std::size_t size)
{ {
if (size < 1024) if (size < 1024)
@ -425,17 +432,24 @@ static inline void stream_memory_size(std::ostream& out, std::size_t size)
} }
static bool logger_has_run = false; static bool logger_has_run = false;
static ptime logger_start;
bool logger_func(log_level_t level) bool logger_func(log_level_t level)
{ {
unsigned long appender = 0;
if (! logger_has_run) { if (! logger_has_run) {
logger_has_run = true; logger_has_run = true;
logger_start = CURRENT_TIME();
IF_VERIFY() IF_VERIFY()
*_log_stream << " TIME OBJSZ MEMSZ" << std::endl; *_log_stream << " TIME OBJSZ MEMSZ" << std::endl;
appender = (logger_start - now).total_milliseconds();
} }
*_log_stream << std::right << std::setw(6) *_log_stream << std::right << std::setw(5)
<< (double(std::clock()) / double(CLOCKS_PER_SEC)); << (CURRENT_TIME() - logger_start).total_milliseconds();
IF_VERIFY() { IF_VERIFY() {
*_log_stream << std::right << std::setw(6) << std::setprecision(3); *_log_stream << std::right << std::setw(6) << std::setprecision(3);
@ -464,7 +478,12 @@ bool logger_func(log_level_t level)
break; break;
} }
*_log_stream << ' ' << _log_buffer.str() << std::endl; *_log_stream << ' ' << _log_buffer.str();
if (appender)
*_log_stream << " (" << appender << "ms startup)";
*_log_stream << std::endl;
_log_buffer.str(""); _log_buffer.str("");
@ -473,7 +492,18 @@ bool logger_func(log_level_t level)
} // namespace ledger } // namespace ledger
#endif // LOGGING_ON && DEBUG_ON #if defined(DEBUG_ON)
#include <boost/regex.hpp>
namespace ledger {
std::string _log_category;
} // namespace ledger
#endif // DEBUG_ON
#endif // LOGGING_ON
/********************************************************************** /**********************************************************************
* *
@ -486,13 +516,14 @@ namespace ledger {
struct timer_t { struct timer_t {
log_level_t level; log_level_t level;
std::clock_t begin; ptime begin;
std::clock_t spent; time_duration spent;
std::string description; std::string description;
bool active; bool active;
timer_t(log_level_t _level, std::string _description) timer_t(log_level_t _level, std::string _description)
: level(_level), begin(std::clock()), spent(0), : level(_level), begin(CURRENT_TIME()),
spent(time_duration(0, 0, 0, 0)),
description(_description), active(true) {} description(_description), active(true) {}
}; };
@ -512,7 +543,7 @@ void start_timer(const char * name, log_level_t lvl)
timers.insert(timer_pair(name, timer_t(lvl, _log_buffer.str()))); timers.insert(timer_pair(name, timer_t(lvl, _log_buffer.str())));
} else { } else {
assert((*i).second.description == _log_buffer.str()); assert((*i).second.description == _log_buffer.str());
(*i).second.begin = std::clock(); (*i).second.begin = CURRENT_TIME();
(*i).second.active = true; (*i).second.active = true;
} }
_log_buffer.str(""); _log_buffer.str("");
@ -531,7 +562,7 @@ void stop_timer(const char * name)
timer_map::iterator i = timers.find(name); timer_map::iterator i = timers.find(name);
assert(i != timers.end()); assert(i != timers.end());
(*i).second.spent += std::clock() - (*i).second.begin; (*i).second.spent += CURRENT_TIME() - (*i).second.begin;
(*i).second.active = false; (*i).second.active = false;
#if defined(VERIFY_ON) #if defined(VERIFY_ON)
@ -549,15 +580,25 @@ void finish_timer(const char * name)
if (i == timers.end()) if (i == timers.end())
return; return;
std::clock_t spent = (*i).second.spent; time_duration spent = (*i).second.spent;
if ((*i).second.active) { if ((*i).second.active) {
spent = std::clock() - (*i).second.begin; spent = CURRENT_TIME() - (*i).second.begin;
(*i).second.active = false; (*i).second.active = false;
} }
_log_buffer << (*i).second.description << " (" _log_buffer << (*i).second.description << ' ';
<< (double(spent) / double(CLOCKS_PER_SEC)) << "s"
<< ')'; bool need_paren =
(*i).second.description[(*i).second.description.size() - 1] != ':';
if (need_paren)
_log_buffer << '(';
_log_buffer << spent.total_milliseconds() << "ms";
if (need_paren)
_log_buffer << ')';
logger_func((*i).second.level); logger_func((*i).second.level);
timers.erase(i); timers.erase(i);

56
utils.h
View file

@ -197,8 +197,6 @@ enum log_level_t {
}; };
extern log_level_t _log_level; extern log_level_t _log_level;
extern unsigned int _trace_level;
extern std::string _log_category;
extern std::ostream * _log_stream; extern std::ostream * _log_stream;
extern std::ostringstream _log_buffer; extern std::ostringstream _log_buffer;
@ -207,8 +205,25 @@ bool logger_func(log_level_t level);
#define LOGGER(cat) \ #define LOGGER(cat) \
static const char * const _this_category = cat static const char * const _this_category = cat
#if defined(TRACING_ON)
extern unsigned int _trace_level;
#define SHOW_TRACE(lvl) \ #define SHOW_TRACE(lvl) \
(_log_level >= LOG_TRACE && lvl <= _trace_level) (_log_level >= LOG_TRACE && lvl <= _trace_level)
#define TRACE(lvl, msg) \
(SHOW_TRACE(lvl) ? ((_log_buffer << msg), logger_func(LOG_TRACE)) : false)
#else // TRACING_ON
#define SHOW_TRACE(lvl) false
#define TRACE(lvl, msg)
#endif // TRACING_ON
#if defined(DEBUG_ON)
extern std::string _log_category;
inline bool category_matches(const char * cat) { inline bool category_matches(const char * cat) {
return (_log_category == cat || return (_log_category == cat ||
@ -222,32 +237,29 @@ inline bool category_matches(const char * cat) {
(_log_level >= LOG_DEBUG && category_matches(cat)) (_log_level >= LOG_DEBUG && category_matches(cat))
#define SHOW_DEBUG() SHOW_DEBUG_(_this_category) #define SHOW_DEBUG() SHOW_DEBUG_(_this_category)
#define DEBUG_(cat, msg) \
(SHOW_DEBUG_(cat) ? ((_log_buffer << msg), logger_func(LOG_DEBUG)) : false)
#define DEBUG(msg) DEBUG_(_this_category, msg)
#else // DEBUG_ON
#define SHOW_DEBUG_(cat) false
#define SHOW_DEBUG() false
#define DEBUG_(cat, msg)
#define DEBUG(msg)
#endif // DEBUG_ON
#define LOG_MACRO(level, msg) \
(_log_level >= level ? \
((_log_buffer << msg), logger_func(level)) : false)
#define SHOW_INFO() (_log_level >= LOG_INFO) #define SHOW_INFO() (_log_level >= LOG_INFO)
#define SHOW_WARN() (_log_level >= LOG_WARN) #define SHOW_WARN() (_log_level >= LOG_WARN)
#define SHOW_ERROR() (_log_level >= LOG_ERROR) #define SHOW_ERROR() (_log_level >= LOG_ERROR)
#define SHOW_FATAL() (_log_level >= LOG_FATAL) #define SHOW_FATAL() (_log_level >= LOG_FATAL)
#define SHOW_CRITICAL() (_log_level >= LOG_CRIT) #define SHOW_CRITICAL() (_log_level >= LOG_CRIT)
#if defined(TRACING_ON)
#define TRACE(lvl, msg) \
(SHOW_TRACE(lvl) ? ((_log_buffer << msg), logger_func(LOG_TRACE)) : false)
#else
#define TRACE(lvl, msg)
#endif
#if defined(DEBUG_ON)
#define DEBUG_(cat, msg) \
(SHOW_DEBUG_(cat) ? ((_log_buffer << msg), logger_func(LOG_DEBUG)) : false)
#define DEBUG(msg) DEBUG_(_this_category, msg)
#else
#define DEBUG_(cat, msg)
#define DEBUG(msg)
#endif
#define LOG_MACRO(level, msg) \
(_log_level >= level ? \
((_log_buffer << msg), logger_func(level)) : false)
#define INFO(msg) LOG_MACRO(LOG_INFO, msg) #define INFO(msg) LOG_MACRO(LOG_INFO, msg)
#define WARN(msg) LOG_MACRO(LOG_WARN, msg) #define WARN(msg) LOG_MACRO(LOG_WARN, msg)
#define ERROR(msg) LOG_MACRO(LOG_ERROR, msg) #define ERROR(msg) LOG_MACRO(LOG_ERROR, msg)