More work done toward rearranging the utility code.
This commit is contained in:
parent
9039e728b2
commit
4716975cb1
10 changed files with 552 additions and 569 deletions
15
Makefile.am
15
Makefile.am
|
|
@ -31,8 +31,9 @@ libledger_la_CPPFLAGS = -I$(top_builddir)/gdtoa
|
|||
libledger_la_LDFLAGS = -release 3.0
|
||||
|
||||
libledger_la_SOURCES = \
|
||||
amount.cc \
|
||||
utils.cc \
|
||||
times.cc \
|
||||
amount.cc \
|
||||
quotes.cc \
|
||||
balance.cc \
|
||||
value.cc \
|
||||
|
|
@ -40,8 +41,6 @@ libledger_la_SOURCES = \
|
|||
xpath.cc \
|
||||
mask.cc \
|
||||
format.cc \
|
||||
util.cc \
|
||||
trace.cc \
|
||||
\
|
||||
session.cc \
|
||||
journal.cc \
|
||||
|
|
@ -55,7 +54,6 @@ libledger_la_SOURCES = \
|
|||
transform.cc \
|
||||
\
|
||||
register.cc \
|
||||
\
|
||||
csv.cc \
|
||||
derive.cc \
|
||||
emacs.cc \
|
||||
|
|
@ -74,8 +72,7 @@ libledger_la_CPPFLAGS += -DHAVE_LIBOFX=1
|
|||
libledger_la_SOURCES += ofx.cc
|
||||
endif
|
||||
if DEBUG
|
||||
libledger_la_CPPFLAGS += -DDEBUG_LEVEL=4
|
||||
libledger_la_SOURCES += debug.cc
|
||||
libledger_la_CPPFLAGS += -DFULL_DEBUG
|
||||
endif
|
||||
if HAVE_BOOST_PYTHON
|
||||
libledger_la_CPPFLAGS += -DUSE_BOOST_PYTHON=1
|
||||
|
|
@ -107,8 +104,8 @@ pkginclude_HEADERS = \
|
|||
times.h \
|
||||
balance.h \
|
||||
binary.h \
|
||||
context.h \
|
||||
csv.h \
|
||||
debug.h \
|
||||
derive.h \
|
||||
emacs.h \
|
||||
error.h \
|
||||
|
|
@ -131,10 +128,8 @@ pkginclude_HEADERS = \
|
|||
session.h \
|
||||
system.hh \
|
||||
textual.h \
|
||||
timing.h \
|
||||
trace.h \
|
||||
transform.h \
|
||||
util.h \
|
||||
utils.h \
|
||||
value.h \
|
||||
xml.h \
|
||||
xmlparse.h \
|
||||
|
|
|
|||
28
context.h
Normal file
28
context.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _CONTEXT_H
|
||||
#define _CONTEXT_H
|
||||
|
||||
namespace ledger {
|
||||
|
||||
class context
|
||||
{
|
||||
public:
|
||||
string context; // ex: 'While parsing file "%R" at line %L'
|
||||
|
||||
string resource; // ex: ledger.dat
|
||||
long linenum_beg; // ex: 1010
|
||||
long linenum_end; // ex: 1010
|
||||
long colnum_beg; // ex: 8
|
||||
long colnum_end; // ex: 8
|
||||
long position_beg;
|
||||
long position_end;
|
||||
|
||||
string text; // ex: (The multi-line text of an entry)
|
||||
long linenum_beg_off; // ex: 2 / -1 means start at beginning
|
||||
long linenum_end_off; // ex: 2 / -1 means start at beginning
|
||||
long colnum_beg_off; // ex: 8 / -1 means start
|
||||
long colnum_end_off; // ex: 8 / -1 means start
|
||||
};
|
||||
|
||||
} // namespace ledger
|
||||
|
||||
#endif // _CONTEXT_H
|
||||
95
debug.cc
95
debug.cc
|
|
@ -1,95 +0,0 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
int new_calls = 0;
|
||||
unsigned long new_size = 0;
|
||||
|
||||
void * operator new(std::size_t size) throw (std::bad_alloc) {
|
||||
void * ptr = std::malloc(size);
|
||||
new_calls++;
|
||||
new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void * operator new[](std::size_t size) throw (std::bad_alloc) {
|
||||
void * ptr = std::malloc(size);
|
||||
new_calls++;
|
||||
new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void * operator new(std::size_t size, const std::nothrow_t&) throw() {
|
||||
void * ptr = std::malloc(size);
|
||||
new_calls++;
|
||||
new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void * operator new[](std::size_t size, const std::nothrow_t&) throw() {
|
||||
void * ptr = std::malloc(size);
|
||||
new_calls++;
|
||||
new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void operator delete(void * ptr) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete[](void * ptr) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete(void * ptr, const std::nothrow_t&) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete[](void * ptr, const std::nothrow_t&) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
|
||||
std::ostream * _debug_stream = &std::cerr;
|
||||
bool _free_debug_stream = false;
|
||||
boost::regex _debug_regex;
|
||||
bool _set_debug_regex = false;
|
||||
bool _debug_regex_on = false;
|
||||
|
||||
bool _debug_active(const char * const cls) {
|
||||
if (! _set_debug_regex) {
|
||||
const char * user_class = std::getenv("DEBUG_CLASS");
|
||||
if (user_class) {
|
||||
_debug_regex = user_class;
|
||||
_debug_regex_on = true;
|
||||
}
|
||||
_set_debug_regex = true;
|
||||
}
|
||||
if (_debug_regex_on)
|
||||
return boost::regex_match(cls, _debug_regex);
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct init_streams {
|
||||
init_streams() {
|
||||
// If debugging is enabled and DEBUG_FILE is set, all debugging
|
||||
// output goes to that file.
|
||||
if (const char * p = std::getenv("DEBUG_FILE")) {
|
||||
_debug_stream = new std::ofstream(p);
|
||||
_free_debug_stream = true;
|
||||
}
|
||||
}
|
||||
~init_streams() {
|
||||
if (_free_debug_stream && _debug_stream) {
|
||||
delete _debug_stream;
|
||||
_debug_stream = NULL;
|
||||
}
|
||||
}
|
||||
} _debug_init;
|
||||
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
#if DEBUG_LEVEL >= BETA
|
||||
|
||||
void debug_assert(const ledger::string& reason,
|
||||
const ledger::string& file,
|
||||
unsigned long line)
|
||||
{
|
||||
throw new ledger::fatal_assert(reason, new ledger::file_context(file, line));
|
||||
}
|
||||
|
||||
#endif
|
||||
166
debug.h
166
debug.h
|
|
@ -1,166 +0,0 @@
|
|||
#ifndef _DEBUG_H
|
||||
#define _DEBUG_H
|
||||
|
||||
#define DEVELOPER 4
|
||||
#define ALPHA 3
|
||||
#define BETA 2
|
||||
#define RELEASE 1
|
||||
#define NO_SEATBELT 0
|
||||
|
||||
#ifndef DEBUG_LEVEL
|
||||
#define DEBUG_LEVEL NO_SEATBELT
|
||||
#endif
|
||||
|
||||
#if DEBUG_LEVEL >= RELEASE
|
||||
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
|
||||
#if DEBUG_LEVEL >= BETA
|
||||
|
||||
void debug_assert(const ledger::string& reason,
|
||||
const ledger::string& file,
|
||||
unsigned long line);
|
||||
|
||||
#define assert(x) \
|
||||
if (! (x)) \
|
||||
debug_assert(#x, __FILE__, __LINE__)
|
||||
|
||||
#else
|
||||
|
||||
#define assert(x) \
|
||||
if (! (x)) \
|
||||
throw new fatal_assert(#x, new file_context(__FILE__, __LINE__))
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
#define assert(x)
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// General debugging facilities
|
||||
//
|
||||
// - In developer level, all checking and debugging facilities are
|
||||
// active.
|
||||
//
|
||||
// - Alpha level does not include performance degrading
|
||||
// VALIDATE calls.
|
||||
//
|
||||
// - Beta level is like Alpha, but does not include debugging
|
||||
// facilities.
|
||||
//
|
||||
// - Release level does not include CONFIRM checks, but does include
|
||||
// assert calls.
|
||||
//
|
||||
// - Running with no seatbelt disables all checking except for normal
|
||||
// syntax and semantic error checking.
|
||||
|
||||
#if DEBUG_LEVEL >= ALPHA
|
||||
|
||||
#define DEBUG_ENABLED
|
||||
|
||||
extern std::ostream * _debug_stream;
|
||||
extern bool _free_debug_stream;
|
||||
|
||||
bool _debug_active(const char * const cls);
|
||||
|
||||
#define DEBUG_CLASS(cls) static const char * const _debug_cls = (cls)
|
||||
|
||||
#define DEBUG(cls) (_debug_active(cls))
|
||||
#define DEBUG_() DEBUG(_debug_cls)
|
||||
|
||||
#define DEBUG_IF(cls) if (_debug_active(cls))
|
||||
#define DEBUG_IF_() if (_debug_active(_debug_cls))
|
||||
|
||||
#define DEBUG_PRINT(cls, x) \
|
||||
if (_debug_stream && _debug_active(cls)) { \
|
||||
*_debug_stream << x << std::endl; \
|
||||
}
|
||||
#define DEBUG_PRINT_(x) DEBUG_PRINT(_debug_cls, x)
|
||||
|
||||
#define DEBUG_PRINT_TIME(cls, x) { \
|
||||
DEBUG_PRINT(cls, #x << " is " << x); \
|
||||
}
|
||||
|
||||
#define DEBUG_PRINT_TIME_(x) DEBUG_PRINT_TIME(_debug_cls, x)
|
||||
|
||||
#define CONFIRM(x) assert(x)
|
||||
|
||||
#if DEBUG_LEVEL == DEVELOPER
|
||||
#define VALIDATE(x) assert(x)
|
||||
#else
|
||||
#define VALIDATE(x)
|
||||
#endif
|
||||
|
||||
extern int new_calls;
|
||||
extern unsigned long new_size;
|
||||
|
||||
#if 0
|
||||
void * operator new(std::size_t) throw (std::bad_alloc);
|
||||
void * operator new[](std::size_t) throw (std::bad_alloc);
|
||||
void operator delete(void*) throw();
|
||||
void operator delete[](void*) throw();
|
||||
void * operator new(std::size_t, const std::nothrow_t&) throw();
|
||||
void * operator new[](std::size_t, const std::nothrow_t&) throw();
|
||||
void operator delete(void*, const std::nothrow_t&) throw();
|
||||
void operator delete[](void*, const std::nothrow_t&) throw();
|
||||
#endif
|
||||
|
||||
#else // DEBUG_LEVEL
|
||||
|
||||
#define DEBUG_CLASS(cls)
|
||||
#define DEBUG(cls) 0
|
||||
#define DEBUG_() 0
|
||||
#define DEBUG_IF(cls)
|
||||
#define DEBUG_IF_()
|
||||
#define DEBUG_PRINT(cls, x)
|
||||
#define DEBUG_PRINT_(x)
|
||||
#define DEBUG_PRINT_TIME(cls, x)
|
||||
#define DEBUG_PRINT_TIME_(x)
|
||||
|
||||
#define VALIDATE(x)
|
||||
|
||||
#if DEBUG_LEVEL == NO_SEATBELT
|
||||
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
#define assert(x)
|
||||
#define CONFIRM(x)
|
||||
|
||||
#ifndef TRACE_CTOR
|
||||
#define TRACE_CTOR(cls, args)
|
||||
#define TRACE_DTOR(cls)
|
||||
#define TRACE(cat, msg)
|
||||
#define TRACE_PUSH(cat, msg)
|
||||
#define TRACE_POP(cat, msg)
|
||||
#endif
|
||||
|
||||
#elif DEBUG_LEVEL == RELEASE
|
||||
|
||||
#define CONFIRM(x)
|
||||
|
||||
#ifndef TRACE_CTOR
|
||||
#define TRACE_CTOR(cls, args)
|
||||
#define TRACE_DTOR(cls)
|
||||
#define TRACE(cat, msg)
|
||||
#define TRACE_PUSH(cat, msg)
|
||||
#define TRACE_POP(cat, msg)
|
||||
#endif
|
||||
|
||||
#elif DEBUG_LEVEL >= BETA
|
||||
|
||||
#define CONFIRM(x) assert(x)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DEBUG_LEVEL
|
||||
|
||||
#endif // _DEBUG_H
|
||||
77
error.h
77
error.h
|
|
@ -1,8 +1,43 @@
|
|||
#ifndef _ERROR_H
|
||||
#define _ERROR_H
|
||||
|
||||
#import "context.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
class exception : public std::exception
|
||||
{
|
||||
protected:
|
||||
string reason;
|
||||
|
||||
public:
|
||||
std::list<context> context_stack;
|
||||
|
||||
exception(const string& _reason,
|
||||
const context& immediate_ctxt) throw()
|
||||
: reason(_reason) {
|
||||
push(immediate_ctxt);
|
||||
}
|
||||
|
||||
void push(const context& intermediate_ctxt) throw() {
|
||||
context_stack.push_front(intermediate_ctxt);
|
||||
}
|
||||
|
||||
void write(std::ostream& out) const throw() {
|
||||
for (std::list<context>::const_iterator
|
||||
i = context.begin();
|
||||
i != context.end();
|
||||
i++)
|
||||
(*i).write(out);
|
||||
}
|
||||
|
||||
const char * what() const throw() {
|
||||
return reason.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
class error_context
|
||||
{
|
||||
public:
|
||||
|
|
@ -57,46 +92,6 @@ class line_context : public error_context {
|
|||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class str_exception : public std::exception {
|
||||
protected:
|
||||
string reason;
|
||||
public:
|
||||
std::list<error_context *> context;
|
||||
|
||||
str_exception(const string& _reason,
|
||||
error_context * ctxt = NULL) throw()
|
||||
: reason(_reason) {
|
||||
if (ctxt)
|
||||
context.push_back(ctxt);
|
||||
}
|
||||
|
||||
virtual ~str_exception() throw() {
|
||||
for (std::list<error_context *>::iterator i = context.begin();
|
||||
i != context.end();
|
||||
i++)
|
||||
delete *i;
|
||||
}
|
||||
|
||||
virtual void reveal_context(std::ostream& out,
|
||||
const string& kind) const throw() {
|
||||
for (std::list<error_context *>::const_reverse_iterator i =
|
||||
context.rbegin();
|
||||
i != context.rend();
|
||||
i++) {
|
||||
std::list<error_context *>::const_reverse_iterator x = i;
|
||||
if (++x == context.rend())
|
||||
out << kind << ": ";
|
||||
(*i)->describe(out);
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char* what() const throw() {
|
||||
return reason.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
class error : public str_exception {
|
||||
public:
|
||||
error(const string& _reason, error_context * _ctxt = NULL) throw()
|
||||
|
|
@ -118,6 +113,8 @@ class fatal_assert : public fatal {
|
|||
virtual ~fatal_assert() throw() {}
|
||||
};
|
||||
|
||||
#endif // 0
|
||||
|
||||
inline void unexpected(char c, char wanted)
|
||||
{
|
||||
if ((unsigned char) c == 0xff) {
|
||||
|
|
|
|||
61
timing.h
61
timing.h
|
|
@ -1,61 +0,0 @@
|
|||
#ifndef _TIMING_H
|
||||
#define _TIMING_H
|
||||
|
||||
namespace ledger {
|
||||
|
||||
class timing_t
|
||||
{
|
||||
public:
|
||||
std::clock_t begin;
|
||||
std::clock_t cumulative;
|
||||
string file;
|
||||
unsigned long line;
|
||||
string symbol;
|
||||
string category;
|
||||
|
||||
timing_t(const string& _symbol, const string& _category)
|
||||
: begin(0), cumulative(0), symbol(_symbol), category(_category) {}
|
||||
|
||||
timing_t(const string& _symbol)
|
||||
: begin(0), cumulative(0), symbol(_symbol) {}
|
||||
|
||||
~timing_t() {
|
||||
string cls = "timing.results.";
|
||||
cls += symbol;
|
||||
#if 0
|
||||
// jww (2007-04-19): This crashes things nowadays
|
||||
DEBUG_PRINT(cls.c_str(), file << ":" << line << ": "
|
||||
<< category << " = "
|
||||
<< (double(cumulative) / double(CLOCKS_PER_SEC)) << "s");
|
||||
#endif
|
||||
}
|
||||
|
||||
void start(const string& _file, unsigned long _line) {
|
||||
file = _file;
|
||||
line = _line;
|
||||
begin = std::clock();
|
||||
}
|
||||
void start() {
|
||||
begin = std::clock();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
cumulative += std::clock() - begin;
|
||||
}
|
||||
};
|
||||
|
||||
#if 0 && DEBUG_LEVEL >= 4
|
||||
#define TIMER_DEF(sym, cat) static timing_t sym(#sym, cat);
|
||||
#define TIMER_DEF_(sym) static timing_t sym(#sym, #sym);
|
||||
#define TIMER_START(sym) sym.start(__FILE__, __LINE__);
|
||||
#define TIMER_STOP(sym) sym.stop();
|
||||
#else
|
||||
#define TIMER_DEF(sym, cat)
|
||||
#define TIMER_DEF_(sym)
|
||||
#define TIMER_START(sym)
|
||||
#define TIMER_STOP(sym)
|
||||
#endif
|
||||
|
||||
} // namespace ledger
|
||||
|
||||
#endif // _TIMING_H
|
||||
130
trace.h
130
trace.h
|
|
@ -1,130 +0,0 @@
|
|||
#ifndef _TRACE_H
|
||||
#define _TRACE_H
|
||||
|
||||
namespace ledger {
|
||||
|
||||
class timing_t;
|
||||
|
||||
extern bool trace_alloc_mode;
|
||||
extern bool trace_class_mode;
|
||||
|
||||
#if 0 && DEBUG_LEVEL >= 4 && ! defined(USE_BOOST_PYTHON)
|
||||
class string;
|
||||
#else
|
||||
typedef std::string string;
|
||||
#endif
|
||||
|
||||
void trace(const string& cat, const string& str);
|
||||
void trace_push(const string& cat, const string& str, timing_t& timer);
|
||||
void trace_pop(const string& cat, const string& str, timing_t& timer);
|
||||
|
||||
#ifndef TRACE
|
||||
#define TRACE(cat, msg) if (trace_class_mode) trace(#cat, msg)
|
||||
#define TRACE_(cat, msg) if (trace_class_mode) trace(#cat, msg)
|
||||
|
||||
#define TRACE_PUSH(cat, msg) \
|
||||
timing_t timer_ ## cat(#cat); \
|
||||
if (trace_class_mode) trace_push(#cat, msg, timer_ ## cat)
|
||||
|
||||
#define TRACE_POP(cat, msg) \
|
||||
if (trace_class_mode) trace_pop(#cat, msg, timer_ ## cat)
|
||||
#endif
|
||||
|
||||
typedef std::multimap<void *, std::string> live_objects_map;
|
||||
typedef std::pair<void *, std::string> live_objects_pair;
|
||||
typedef std::pair<unsigned int, std::size_t> count_size_pair;
|
||||
typedef std::map<std::string, count_size_pair> object_count_map;
|
||||
typedef std::pair<std::string, count_size_pair> object_count_pair;
|
||||
|
||||
extern live_objects_map live_objects;
|
||||
extern object_count_map live_count;
|
||||
extern object_count_map ctor_count;
|
||||
extern object_count_map object_count;
|
||||
|
||||
extern bool tracing_active;
|
||||
|
||||
bool trace_ctor(void * ptr, const char * cls_name, const char * args,
|
||||
std::size_t cls_size);
|
||||
bool trace_dtor(void * ptr, const char * cls_name, std::size_t cls_size);
|
||||
|
||||
void report_memory(std::ostream& out);
|
||||
|
||||
#if 1
|
||||
#ifndef TRACE_CTOR
|
||||
#define TRACE_CTOR(cls, args) \
|
||||
CONFIRM(ledger::trace_ctor(this, #cls, args, sizeof(cls)))
|
||||
#define TRACE_DTOR(cls) \
|
||||
CONFIRM(ledger::trace_dtor(this, #cls, sizeof(cls)))
|
||||
#endif
|
||||
#else
|
||||
#define TRACE_CTOR(cls, args)
|
||||
#define TRACE_DTOR(cls)
|
||||
#endif
|
||||
|
||||
#if 0 && DEBUG_LEVEL >= 4 && ! defined(USE_BOOST_PYTHON)
|
||||
|
||||
class string : public std::string
|
||||
{
|
||||
public:
|
||||
string();
|
||||
string(const string& str);
|
||||
string(const std::string& str);
|
||||
string(const int len, char x);
|
||||
string(const char * str);
|
||||
string(const char * str, const char * end);
|
||||
string(const string& str, int x);
|
||||
string(const string& str, int x, int y);
|
||||
string(const char * str, int x);
|
||||
string(const char * str, int x, int y);
|
||||
~string();
|
||||
};
|
||||
|
||||
inline string operator+(const string& __lhs, const string& __rhs)
|
||||
{
|
||||
string __str(__lhs);
|
||||
__str.append(__rhs);
|
||||
return __str;
|
||||
}
|
||||
|
||||
string operator+(const char* __lhs, const string& __rhs);
|
||||
string operator+(char __lhs, const string& __rhs);
|
||||
|
||||
inline string operator+(const string& __lhs, const char* __rhs)
|
||||
{
|
||||
string __str(__lhs);
|
||||
__str.append(__rhs);
|
||||
return __str;
|
||||
}
|
||||
|
||||
inline string operator+(const string& __lhs, char __rhs)
|
||||
{
|
||||
typedef string __string_type;
|
||||
typedef string::size_type __size_type;
|
||||
__string_type __str(__lhs);
|
||||
__str.append(__size_type(1), __rhs);
|
||||
return __str;
|
||||
}
|
||||
|
||||
inline bool operator==(const string& __lhs, const string& __rhs)
|
||||
{ return __lhs.compare(__rhs) == 0; }
|
||||
|
||||
inline bool operator==(const char* __lhs, const string& __rhs)
|
||||
{ return __rhs.compare(__lhs) == 0; }
|
||||
|
||||
inline bool operator==(const string& __lhs, const char* __rhs)
|
||||
{ return __lhs.compare(__rhs) == 0; }
|
||||
|
||||
inline bool operator!=(const string& __lhs, const string& __rhs)
|
||||
{ return __rhs.compare(__lhs) != 0; }
|
||||
|
||||
inline bool operator!=(const char* __lhs, const string& __rhs)
|
||||
{ return __rhs.compare(__lhs) != 0; }
|
||||
|
||||
inline bool operator!=(const string& __lhs, const char* __rhs)
|
||||
{ return __lhs.compare(__rhs) != 0; }
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace ledger
|
||||
|
||||
#endif // _TRACE_H
|
||||
23
util.h
23
util.h
|
|
@ -1,29 +1,6 @@
|
|||
#ifndef _UTIL_H
|
||||
#define _UTIL_H
|
||||
|
||||
#if defined __FreeBSD__ && __FreeBSD__ <=4
|
||||
// FreeBSD has a broken isspace macro, so dont use it
|
||||
#undef isspace(c)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUG__) && __GNUG__ < 3
|
||||
namespace std {
|
||||
inline ostream & right (ostream & i) {
|
||||
i.setf(i.right, i.adjustfield);
|
||||
return i;
|
||||
}
|
||||
inline ostream & left (ostream & i) {
|
||||
i.setf(i.left, i.adjustfield);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
typedef unsigned long istream_pos_type;
|
||||
typedef unsigned long ostream_pos_type;
|
||||
#else
|
||||
typedef std::istream::pos_type istream_pos_type;
|
||||
typedef std::ostream::pos_type ostream_pos_type;
|
||||
#endif
|
||||
|
||||
namespace ledger {
|
||||
|
||||
inline char * skip_ws(char * ptr) {
|
||||
|
|
|
|||
|
|
@ -1,31 +1,60 @@
|
|||
#include "utils.h"
|
||||
#include "times.h"
|
||||
|
||||
namespace ledger {
|
||||
namespace ledger
|
||||
|
||||
bool trace_alloc_mode;
|
||||
bool trace_class_mode;
|
||||
#if defined(ASSERTS_ON)
|
||||
|
||||
void trace(const string& cat, const string& str)
|
||||
void debug_assert(const ledger::string& reason,
|
||||
const ledger::string& func,
|
||||
const ledger::string& file,
|
||||
unsigned long line)
|
||||
{
|
||||
std::cerr << boost::posix_time::to_simple_string(now) << " "
|
||||
<< cat << ": " << str << std::endl;
|
||||
throw fatal(reason, context());
|
||||
}
|
||||
|
||||
void trace_push(const string& cat, const string& str,
|
||||
timing_t& timer)
|
||||
{
|
||||
timer.start();
|
||||
trace(cat, str);
|
||||
}
|
||||
#endif
|
||||
|
||||
void trace_pop(const string& cat, const string& str,
|
||||
timing_t& timer)
|
||||
{
|
||||
timer.stop();
|
||||
std::ostringstream out;
|
||||
out << str << ": " << (double(timer.cumulative) / double(CLOCKS_PER_SEC)) << "s";
|
||||
trace(cat, out.str());
|
||||
#if defined(VERIFY_ON)
|
||||
|
||||
int new_calls = 0;
|
||||
unsigned long new_size = 0;
|
||||
|
||||
void * operator new(std::size_t size) throw (std::bad_alloc) {
|
||||
void * ptr = std::malloc(size);
|
||||
new_calls++;
|
||||
new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void * operator new[](std::size_t size) throw (std::bad_alloc) {
|
||||
void * ptr = std::malloc(size);
|
||||
new_calls++;
|
||||
new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void * operator new(std::size_t size, const std::nothrow_t&) throw() {
|
||||
void * ptr = std::malloc(size);
|
||||
new_calls++;
|
||||
new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void * operator new[](std::size_t size, const std::nothrow_t&) throw() {
|
||||
void * ptr = std::malloc(size);
|
||||
new_calls++;
|
||||
new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void operator delete(void * ptr) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete[](void * ptr) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete(void * ptr, const std::nothrow_t&) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete[](void * ptr, const std::nothrow_t&) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
|
||||
live_objects_map live_objects;
|
||||
|
|
@ -33,8 +62,6 @@ object_count_map ctor_count;
|
|||
object_count_map object_count;
|
||||
object_count_map live_count;
|
||||
|
||||
bool tracing_active = false;
|
||||
|
||||
inline void add_to_count_map(object_count_map& the_map,
|
||||
const char * name, std::size_t size)
|
||||
{
|
||||
|
|
@ -63,9 +90,6 @@ inline void report_count_map(std::ostream& out, object_count_map& the_map)
|
|||
bool trace_ctor(void * ptr, const char * cls_name, const char * args,
|
||||
std::size_t cls_size)
|
||||
{
|
||||
if (! tracing_active)
|
||||
return true;
|
||||
|
||||
if (trace_class_mode && cls_name[0] == '_')
|
||||
return true;
|
||||
if (trace_alloc_mode && cls_name[0] != '_')
|
||||
|
|
@ -92,9 +116,6 @@ bool trace_ctor(void * ptr, const char * cls_name, const char * args,
|
|||
|
||||
bool trace_dtor(void * ptr, const char * cls_name, std::size_t cls_size)
|
||||
{
|
||||
if (! tracing_active)
|
||||
return true;
|
||||
|
||||
if (trace_class_mode && cls_name[0] == '_')
|
||||
return true;
|
||||
if (trace_alloc_mode && cls_name[0] != '_')
|
||||
|
|
@ -162,42 +183,106 @@ void report_memory(std::ostream& out)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0 && DEBUG_LEVEL >= 4 && ! defined(USE_BOOST_PYTHON)
|
||||
#if ! defined(USE_BOOST_PYTHON)
|
||||
|
||||
string::string() : std::string() {
|
||||
TRACE_CTOR(string, "");
|
||||
trace_ctor(string, "");
|
||||
}
|
||||
string::string(const string& str) : std::string(str) {
|
||||
TRACE_CTOR(string, "const string&");
|
||||
trace_ctor(string, "const string&");
|
||||
}
|
||||
string::string(const std::string& str) : std::string(str) {
|
||||
TRACE_CTOR(string, "const std::string&");
|
||||
trace_ctor(string, "const std::string&");
|
||||
}
|
||||
string::string(const int len, char x) : std::string(len, x) {
|
||||
TRACE_CTOR(string, "const int, char");
|
||||
trace_ctor(string, "const int, char");
|
||||
}
|
||||
string::string(const char * str) : std::string(str) {
|
||||
TRACE_CTOR(string, "const char *");
|
||||
trace_ctor(string, "const char *");
|
||||
}
|
||||
string::string(const char * str, const char * end) : std::string(str, end) {
|
||||
TRACE_CTOR(string, "const char *, const char *");
|
||||
trace_ctor(string, "const char *, const char *");
|
||||
}
|
||||
string::string(const string& str, int x) : std::string(str, x) {
|
||||
TRACE_CTOR(string, "const string&, int");
|
||||
trace_ctor(string, "const string&, int");
|
||||
}
|
||||
string::string(const string& str, int x, int y) : std::string(str, x, y) {
|
||||
TRACE_CTOR(string, "const string&, int, int");
|
||||
trace_ctor(string, "const string&, int, int");
|
||||
}
|
||||
string::string(const char * str, int x) : std::string(str, x) {
|
||||
TRACE_CTOR(string, "const char *, int");
|
||||
trace_ctor(string, "const char *, int");
|
||||
}
|
||||
string::string(const char * str, int x, int y) : std::string(str, x, y) {
|
||||
TRACE_CTOR(string, "const char *, int, int");
|
||||
trace_ctor(string, "const char *, int, int");
|
||||
}
|
||||
string::~string() {
|
||||
TRACE_DTOR(string);
|
||||
trace_dtor(string);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // VERIFY_ON
|
||||
|
||||
#if defined(TIMERS_ON)
|
||||
|
||||
void start_timer(const char * name)
|
||||
{
|
||||
begin = std::clock();
|
||||
}
|
||||
|
||||
void stop_timer(const char * name)
|
||||
{
|
||||
cumulative += std::clock() - begin;
|
||||
}
|
||||
|
||||
void finish_timer(const char * name)
|
||||
{
|
||||
DEBUG_PRINT(cls.c_str(), file << ":" << line << ": "
|
||||
<< category << " = "
|
||||
<< (double(cumulative) / double(CLOCKS_PER_SEC)) << "s");
|
||||
}
|
||||
|
||||
#endif // TIMERS_ON
|
||||
|
||||
#if defined(LOGGING_ON) && defined(DEBUG_ON)
|
||||
|
||||
std::ostream * _debug_stream = &std::cerr;
|
||||
bool _free_debug_stream = false;
|
||||
boost::regex _debug_regex;
|
||||
bool _set_debug_regex = false;
|
||||
bool _debug_regex_on = false;
|
||||
|
||||
bool _debug_active(const char * const cls) {
|
||||
if (! _set_debug_regex) {
|
||||
const char * user_class = std::getenv("DEBUG_CLASS");
|
||||
if (user_class) {
|
||||
_debug_regex = user_class;
|
||||
_debug_regex_on = true;
|
||||
}
|
||||
_set_debug_regex = true;
|
||||
}
|
||||
if (_debug_regex_on)
|
||||
return boost::regex_match(cls, _debug_regex);
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct init_streams {
|
||||
init_streams() {
|
||||
// If debugging is enabled and DEBUG_FILE is set, all debugging
|
||||
// output goes to that file.
|
||||
if (const char * p = std::getenv("DEBUG_FILE")) {
|
||||
_debug_stream = new std::ofstream(p);
|
||||
_free_debug_stream = true;
|
||||
}
|
||||
}
|
||||
~init_streams() {
|
||||
if (_free_debug_stream && _debug_stream) {
|
||||
delete _debug_stream;
|
||||
_debug_stream = NULL;
|
||||
}
|
||||
}
|
||||
} _debug_init;
|
||||
|
||||
#endif // LOGGING_ON && DEBUG_ON
|
||||
|
||||
} // namespace ledger
|
||||
363
utils.h
363
utils.h
|
|
@ -3,6 +3,26 @@
|
|||
|
||||
#include <system.hh>
|
||||
|
||||
#if defined __FreeBSD__ && __FreeBSD__ <=4
|
||||
// FreeBSD has a broken isspace macro, so don't use it
|
||||
#undef isspace(c)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUG__) && __GNUG__ < 3
|
||||
namespace std {
|
||||
inline ostream & right (ostream & i) {
|
||||
i.setf(i.right, i.adjustfield);
|
||||
return i;
|
||||
}
|
||||
inline ostream & left (ostream & i) {
|
||||
i.setf(i.left, i.adjustfield);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace ledger {
|
||||
|
||||
// jww (2007-04-23): Need to clean up the following include files. I
|
||||
// want to following services:
|
||||
//
|
||||
|
|
@ -15,10 +35,343 @@
|
|||
// verification (optionally on, like debugging but silent)
|
||||
// memory tracing and debugging (and watching for threshholds)
|
||||
|
||||
#include "trace.h"
|
||||
#include "debug.h"
|
||||
#include "timing.h"
|
||||
#include "error.h"
|
||||
#include "util.h"
|
||||
#import "error.h"
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Default values
|
||||
*/
|
||||
|
||||
#if defined(FULL_DEBUG)
|
||||
#define VERIFY_ON 1
|
||||
#define TRACING_ON 1
|
||||
#define DEBUG_ON 1
|
||||
#define TIMERS_ON 1
|
||||
#elif defined(NO_DEBUG)
|
||||
#define NO_ASSERTS 1
|
||||
#define NO_LOGGING 1
|
||||
#else
|
||||
#define TIMERS_ON 1
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Assertions
|
||||
*/
|
||||
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
|
||||
#if ! defined(NO_ASSERTS)
|
||||
#define ASSERTS_ON 1
|
||||
#endif
|
||||
#if defined(ASSERTS_ON)
|
||||
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
void debug_assert(const ledger::string& reason,
|
||||
const ledger::string& func,
|
||||
const ledger::string& file,
|
||||
unsigned long line);
|
||||
|
||||
#define assert(x) \
|
||||
((x) ? ((void)0) : debug_assert(#x, BOOST_CURRENT_FUNCTION, \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
#endif // ASSERTS_ON
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Verification (basically, very slow asserts)
|
||||
*/
|
||||
|
||||
#if defined(VERIFY_ON)
|
||||
|
||||
extern bool verify_enabled;
|
||||
|
||||
#define verify(x) (verify_enabled ? assert(x) : ((void)0))
|
||||
|
||||
extern int new_calls;
|
||||
extern unsigned long new_size;
|
||||
|
||||
void * operator new(std::size_t) throw(std::bad_alloc);
|
||||
void * operator new[](std::size_t) throw(std::bad_alloc);
|
||||
void operator delete(void*) throw();
|
||||
void operator delete[](void*) throw();
|
||||
void * operator new(std::size_t, const std::nothrow_t&) throw();
|
||||
void * operator new[](std::size_t, const std::nothrow_t&) throw();
|
||||
void operator delete(void*, const std::nothrow_t&) throw();
|
||||
void operator delete[](void*, const std::nothrow_t&) throw();
|
||||
|
||||
typedef std::multimap<void *, std::string> live_objects_map;
|
||||
typedef std::pair<void *, std::string> live_objects_pair;
|
||||
typedef std::pair<unsigned int, std::size_t> count_size_pair;
|
||||
typedef std::map<std::string, count_size_pair> object_count_map;
|
||||
typedef std::pair<std::string, count_size_pair> object_count_pair;
|
||||
|
||||
extern live_objects_map live_objects;
|
||||
extern object_count_map live_count;
|
||||
extern object_count_map ctor_count;
|
||||
extern object_count_map object_count;
|
||||
|
||||
bool trace_ctor(void * ptr, const char * cls_name, const char * args,
|
||||
std::size_t cls_size);
|
||||
bool trace_dtor(void * ptr, const char * cls_name, std::size_t cls_size);
|
||||
|
||||
#define trace_ctor(cls, args) \
|
||||
verify(trace_ctor(this, #cls, args, sizeof(cls)))
|
||||
#define trace_dtor(cls) \
|
||||
verify(trace_dtor(this, #cls, sizeof(cls)))
|
||||
|
||||
void report_memory(std::ostream& out);
|
||||
|
||||
#if ! defined(USE_BOOST_PYTHON)
|
||||
|
||||
class string : public std::string
|
||||
{
|
||||
public:
|
||||
string();
|
||||
string(const string& str);
|
||||
string(const std::string& str);
|
||||
string(const int len, char x);
|
||||
string(const char * str);
|
||||
string(const char * str, const char * end);
|
||||
string(const string& str, int x);
|
||||
string(const string& str, int x, int y);
|
||||
string(const char * str, int x);
|
||||
string(const char * str, int x, int y);
|
||||
~string();
|
||||
};
|
||||
|
||||
inline string operator+(const string& __lhs, const string& __rhs)
|
||||
{
|
||||
string __str(__lhs);
|
||||
__str.append(__rhs);
|
||||
return __str;
|
||||
}
|
||||
|
||||
string operator+(const char* __lhs, const string& __rhs);
|
||||
string operator+(char __lhs, const string& __rhs);
|
||||
|
||||
inline string operator+(const string& __lhs, const char* __rhs)
|
||||
{
|
||||
string __str(__lhs);
|
||||
__str.append(__rhs);
|
||||
return __str;
|
||||
}
|
||||
|
||||
inline string operator+(const string& __lhs, char __rhs)
|
||||
{
|
||||
typedef string __string_type;
|
||||
typedef string::size_type __size_type;
|
||||
__string_type __str(__lhs);
|
||||
__str.append(__size_type(1), __rhs);
|
||||
return __str;
|
||||
}
|
||||
|
||||
inline bool operator==(const string& __lhs, const string& __rhs)
|
||||
{ return __lhs.compare(__rhs) == 0; }
|
||||
|
||||
inline bool operator==(const char* __lhs, const string& __rhs)
|
||||
{ return __rhs.compare(__lhs) == 0; }
|
||||
|
||||
inline bool operator==(const string& __lhs, const char* __rhs)
|
||||
{ return __lhs.compare(__rhs) == 0; }
|
||||
|
||||
inline bool operator!=(const string& __lhs, const string& __rhs)
|
||||
{ return __rhs.compare(__lhs) != 0; }
|
||||
|
||||
inline bool operator!=(const char* __lhs, const string& __rhs)
|
||||
{ return __rhs.compare(__lhs) != 0; }
|
||||
|
||||
inline bool operator!=(const string& __lhs, const char* __rhs)
|
||||
{ return __lhs.compare(__rhs) != 0; }
|
||||
|
||||
#endif
|
||||
|
||||
#else // ! VERIFY_ON
|
||||
|
||||
#define verify(x)
|
||||
#define trace_ctor(cls, args)
|
||||
#define trace_dtor(cls)
|
||||
|
||||
#endif // VERIFY_ON
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Logging
|
||||
*/
|
||||
|
||||
#if ! defined(NO_LOGGING)
|
||||
#define LOGGING_ON 1
|
||||
#endif
|
||||
#if defined(LOGGING_ON)
|
||||
|
||||
// Logging
|
||||
|
||||
enum log_level_t {
|
||||
LOG_OFF = 0,
|
||||
LOG_CRIT,
|
||||
LOG_FATAL,
|
||||
LOG_ASSERT,
|
||||
LOG_ERROR,
|
||||
LOG_VERIFY,
|
||||
LOG_WARN,
|
||||
LOG_INFO,
|
||||
LOG_EXCEPT,
|
||||
LOG_DEBUG,
|
||||
LOG_TRACE,
|
||||
LOG_ALL
|
||||
};
|
||||
|
||||
extern log_level_t _log_level;
|
||||
extern unsigned int _trace_level;
|
||||
extern std::string _log_category;
|
||||
extern std::ostream * _log_stream;
|
||||
extern std::ostringstream _log_buffer;
|
||||
|
||||
#define category(cat) \
|
||||
static const char * const _this_category = (cat)
|
||||
|
||||
bool logger(log_level_t level);
|
||||
|
||||
#if defined(TRACING_ON)
|
||||
#define trace(lvl, msg) \
|
||||
(_log_level >= LOG_TRACE && lvl >= _trace_level ? \
|
||||
((_log_buffer << msg), logger(LOG_TRACE)) : false)
|
||||
#else
|
||||
#define trace(lvl, msg)
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_ON)
|
||||
#define debug_(cat, msg) \
|
||||
(_log_level >= LOG_DEBUG && \
|
||||
(_log_category == cat || \
|
||||
_log_category.find(cat ".") == 0) ? \
|
||||
((_log_buffer << msg), logger(LOG_DEBUG)) : false)
|
||||
#define debug(msg) debug_(_this_category, msg)
|
||||
#else
|
||||
#define debug_(cat, msg)
|
||||
#define debug(msg)
|
||||
#endif
|
||||
|
||||
#define info_(cat, msg) \
|
||||
(_log_level >= LOG_INFO && \
|
||||
(_log_category == cat || \
|
||||
_log_category.find(cat ".") == 0) ? \
|
||||
((_log_buffer << msg), logger(LOG_INFO)) : false)
|
||||
#define info(msg) info_(_this_category, msg)
|
||||
|
||||
#define log_macro(level, msg) \
|
||||
(_log_level >= level ? \
|
||||
((_log_buffer << msg), logger(level)) : false)
|
||||
|
||||
#define warn(msg) log_macro(LOG_WARN, msg)
|
||||
#define error(msg) log_macro(LOG_ERROR, msg)
|
||||
#define fatal(msg) log_macro(LOG_FATAL, msg)
|
||||
#define critical(msg) log_macro(LOG_CRIT, msg)
|
||||
|
||||
#else // ! LOGGING_ON
|
||||
|
||||
#define category(cat)
|
||||
#define trace(lvl, msg)
|
||||
#define debug(msg)
|
||||
#define debug_(cat, msg)
|
||||
#define info(msg)
|
||||
#define info_(cat, msg)
|
||||
#define warn(msg)
|
||||
#define error(msg)
|
||||
#define fatal(msg)
|
||||
#define critical(msg)
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Timers (allows log entries to specify cumulative time spent)
|
||||
*/
|
||||
|
||||
#if defined(LOGGING_ON) && defined(TIMERS_ON)
|
||||
|
||||
struct timer_t {
|
||||
std::clock_t count;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, timer_t> timing_map;
|
||||
typedef timing_map::value_type timing_pair;
|
||||
|
||||
void start_timer(const char * name);
|
||||
void stop_timer(const char * name);
|
||||
void finish_timer(const char * name);
|
||||
|
||||
#if defined(TRACING_ON)
|
||||
#define trace_start(name, lvl, msg) \
|
||||
(trace(lvl, msg) && start_timer(name))
|
||||
#define trace_stop(name) stop_timer(name)
|
||||
#define trace_finish(name) finish_timer(name)
|
||||
#else
|
||||
#define trace_start(name, lvl, msg)
|
||||
#define trace_stop(name)
|
||||
#define trace_finish(name)
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_ON)
|
||||
#define debug_start(name, msg) \
|
||||
(debug(msg) && start_timer(name))
|
||||
#define debug_start_(name, cat, msg) \
|
||||
(debug_(cat, msg) && start_timer(name))
|
||||
#define debug_stop(name) stop_timer(name)
|
||||
#define debug_finish(name) finish_timer(name)
|
||||
#else
|
||||
#define debug_start(name, msg)
|
||||
#define debug_start_(name, cat, msg)
|
||||
#define debug_stop(name)
|
||||
#define debug_finish(name)
|
||||
#endif
|
||||
|
||||
#define info_start(name, msg) \
|
||||
(info(msg) && start_timer(name))
|
||||
#define info_start_(name, cat, msg)
|
||||
#define info_stop(name) stop_timer(name)
|
||||
#define info_finish(name) finish_timer(name)
|
||||
|
||||
#else // ! (LOGGING_ON && TIMERS_ON)
|
||||
|
||||
#define trace_start(lvl, msg, name)
|
||||
#define trace_stop(name)
|
||||
#define trace_finish(name)
|
||||
|
||||
#define debug_start(name, msg)
|
||||
#define debug_start_(name, cat, msg)
|
||||
#define debug_stop(name)
|
||||
#define debug_finish(name)
|
||||
|
||||
#define info_start(name, msg)
|
||||
#define info_start_(name, cat, msg)
|
||||
#define info_stop(name)
|
||||
#define info_finish(name)
|
||||
|
||||
#endif // TIMERS_ON
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Debug macros
|
||||
*/
|
||||
|
||||
#if defined(DEBUG_ON)
|
||||
|
||||
#define if_debug_(cat) \
|
||||
if (_log_level >= LOG_DEBUG && \
|
||||
(_log_category == cat || \
|
||||
_log_category.find(cat ".") == 0))
|
||||
#define if_debug() if_debug_(_this_category)
|
||||
|
||||
#else // ! DEBUG_ON
|
||||
|
||||
#define if_debug(cat) if (false)
|
||||
|
||||
#endif // DEBUG_ON
|
||||
|
||||
// } namespace ledger
|
||||
|
||||
#endif // _UTILS_H
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue