summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2007-04-27 10:08:05 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 03:38:31 -0400
commit4716975cb18795e4a953fc705cf0b7c74d6a1c95 (patch)
tree4e22788779337c306aa9b83282e7a67c52b6004c
parent9039e728b2015b54dc87da52f450c27683303392 (diff)
downloadfork-ledger-4716975cb18795e4a953fc705cf0b7c74d6a1c95.tar.gz
fork-ledger-4716975cb18795e4a953fc705cf0b7c74d6a1c95.tar.bz2
fork-ledger-4716975cb18795e4a953fc705cf0b7c74d6a1c95.zip
More work done toward rearranging the utility code.
-rw-r--r--Makefile.am15
-rw-r--r--context.h28
-rw-r--r--debug.cc95
-rw-r--r--debug.h166
-rw-r--r--error.h77
-rw-r--r--timing.h61
-rw-r--r--trace.h130
-rw-r--r--util.h23
-rw-r--r--utils.cc (renamed from trace.cc)163
-rw-r--r--utils.h363
10 files changed, 552 insertions, 569 deletions
diff --git a/Makefile.am b/Makefile.am
index d1efe736..13ec77c2 100644
--- a/Makefile.am
+++ b/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 \
diff --git a/context.h b/context.h
new file mode 100644
index 00000000..3851d073
--- /dev/null
+++ b/context.h
@@ -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
diff --git a/debug.cc b/debug.cc
deleted file mode 100644
index 680e426c..00000000
--- a/debug.cc
+++ /dev/null
@@ -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
diff --git a/debug.h b/debug.h
deleted file mode 100644
index f0987b3f..00000000
--- a/debug.h
+++ /dev/null
@@ -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
diff --git a/error.h b/error.h
index c174eea0..93116054 100644
--- a/error.h
+++ b/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) {
diff --git a/timing.h b/timing.h
deleted file mode 100644
index 51a3e7c4..00000000
--- a/timing.h
+++ /dev/null
@@ -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
diff --git a/trace.h b/trace.h
deleted file mode 100644
index 3763ca77..00000000
--- a/trace.h
+++ /dev/null
@@ -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
diff --git a/util.h b/util.h
index 53dc720e..5965a5ed 100644
--- a/util.h
+++ b/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) {
diff --git a/trace.cc b/utils.cc
index f11e3bad..2183e96c 100644
--- a/trace.cc
+++ b/utils.cc
@@ -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
diff --git a/utils.h b/utils.h
index 4ff8a006..b8e1e3b1 100644
--- a/utils.h
+++ b/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