Decreased memory usage considerably

This commit is contained in:
John Wiegley 2007-04-20 23:49:18 +00:00
parent b84f676946
commit c30f520900
22 changed files with 340 additions and 363 deletions

View file

@ -67,17 +67,17 @@ class amount_t::bigint_t
unsigned int index; unsigned int index;
bigint_t() : prec(0), flags(0), ref(1), index(0) { bigint_t() : prec(0), flags(0), ref(1), index(0) {
TRACE_CTOR("bigint_t()"); TRACE_CTOR(bigint_t, "");
mpz_init(val); mpz_init(val);
} }
bigint_t(mpz_t _val) : prec(0), flags(0), ref(1), index(0) { bigint_t(mpz_t _val) : prec(0), flags(0), ref(1), index(0) {
TRACE_CTOR("bigint_t(mpz_t)"); TRACE_CTOR(bigint_t, "mpz_t");
mpz_init_set(val, _val); mpz_init_set(val, _val);
} }
bigint_t(const bigint_t& other) bigint_t(const bigint_t& other)
: prec(other.prec), flags(other.flags & BIGINT_KEEP_PREC), : prec(other.prec), flags(other.flags & BIGINT_KEEP_PREC),
ref(1), index(0) { ref(1), index(0) {
TRACE_CTOR("bigint_t(copy)"); TRACE_CTOR(bigint_t, "copy");
mpz_init_set(val, other.val); mpz_init_set(val, other.val);
} }
~bigint_t(); ~bigint_t();
@ -97,7 +97,7 @@ static mpz_t divisor;
static amount_t::bigint_t * true_value = NULL; static amount_t::bigint_t * true_value = NULL;
inline amount_t::bigint_t::~bigint_t() { inline amount_t::bigint_t::~bigint_t() {
TRACE_DTOR("bigint_t"); TRACE_DTOR(bigint_t);
assert(ref == 0 || (! do_cleanup && this == true_value)); assert(ref == 0 || (! do_cleanup && this == true_value));
mpz_clear(val); mpz_clear(val);
} }
@ -219,7 +219,7 @@ static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec)
amount_t::amount_t(const long val) amount_t::amount_t(const long val)
{ {
TRACE_CTOR("amount_t(const long)"); TRACE_CTOR(amount_t, "const long");
if (val != 0) { if (val != 0) {
quantity = new bigint_t; quantity = new bigint_t;
mpz_set_si(MPZ(quantity), val); mpz_set_si(MPZ(quantity), val);
@ -231,7 +231,7 @@ amount_t::amount_t(const long val)
amount_t::amount_t(const unsigned long val) amount_t::amount_t(const unsigned long val)
{ {
TRACE_CTOR("amount_t(const unsigned long)"); TRACE_CTOR(amount_t, "const unsigned long");
if (val != 0) { if (val != 0) {
quantity = new bigint_t; quantity = new bigint_t;
mpz_set_ui(MPZ(quantity), val); mpz_set_ui(MPZ(quantity), val);
@ -329,7 +329,7 @@ namespace {
amount_t::amount_t(const double val) amount_t::amount_t(const double val)
{ {
TRACE_CTOR("amount_t(const double)"); TRACE_CTOR(amount_t, "const double");
quantity = new bigint_t; quantity = new bigint_t;
quantity->prec = convert_double(MPZ(quantity), val); quantity->prec = convert_double(MPZ(quantity), val);
commodity_ = NULL; commodity_ = NULL;

View file

@ -48,7 +48,7 @@
#define _AMOUNT_H #define _AMOUNT_H
#include <map> #include <map>
#include <deque> #include <vector>
#include <stack> #include <stack>
#include <string> #include <string>
#include <cctype> #include <cctype>
@ -107,21 +107,21 @@ class amount_t
public: public:
// constructors // constructors
amount_t() : quantity(NULL), commodity_(NULL) { amount_t() : quantity(NULL), commodity_(NULL) {
TRACE_CTOR("amount_t()"); TRACE_CTOR(amount_t, "");
} }
amount_t(const amount_t& amt) : quantity(NULL) { amount_t(const amount_t& amt) : quantity(NULL) {
TRACE_CTOR("amount_t(copy)"); TRACE_CTOR(amount_t, "copy");
if (amt.quantity) if (amt.quantity)
_copy(amt); _copy(amt);
else else
commodity_ = NULL; commodity_ = NULL;
} }
amount_t(const string& val) : quantity(NULL) { amount_t(const string& val) : quantity(NULL) {
TRACE_CTOR("amount_t(const string&)"); TRACE_CTOR(amount_t, "const string&");
parse(val); parse(val);
} }
amount_t(const char * val) : quantity(NULL) { amount_t(const char * val) : quantity(NULL) {
TRACE_CTOR("amount_t(const char *)"); TRACE_CTOR(amount_t, "const char *");
parse(val); parse(val);
} }
amount_t(const long val); amount_t(const long val);
@ -130,7 +130,7 @@ class amount_t
// destructor // destructor
~amount_t() { ~amount_t() {
TRACE_DTOR("amount_t"); TRACE_DTOR(amount_t);
if (quantity) if (quantity)
_release(); _release();
} }
@ -499,11 +499,11 @@ class commodity_base_t
commodity_base_t() commodity_base_t()
: precision(0), flags(COMMODITY_STYLE_DEFAULTS), : precision(0), flags(COMMODITY_STYLE_DEFAULTS),
smaller(NULL), larger(NULL), history(NULL) { smaller(NULL), larger(NULL), history(NULL) {
TRACE_CTOR("commodity_base_t()"); TRACE_CTOR(commodity_base_t, "");
} }
commodity_base_t(const commodity_base_t&) { commodity_base_t(const commodity_base_t&) {
TRACE_CTOR("commodity_base_t(copy)"); TRACE_CTOR(commodity_base_t, "copy");
assert(0); assert(0);
} }
@ -512,11 +512,11 @@ class commodity_base_t
unsigned int _flags = COMMODITY_STYLE_DEFAULTS) unsigned int _flags = COMMODITY_STYLE_DEFAULTS)
: precision(_precision), flags(_flags), : precision(_precision), flags(_flags),
smaller(NULL), larger(NULL), symbol(_symbol), history(NULL) { smaller(NULL), larger(NULL), symbol(_symbol), history(NULL) {
TRACE_CTOR("commodity_base_t(const string&, unsigned int, unsigned int)"); TRACE_CTOR(commodity_base_t, "const string&, unsigned int, unsigned int");
} }
~commodity_base_t() { ~commodity_base_t() {
TRACE_DTOR("commodity_base_t"); TRACE_DTOR(commodity_base_t);
if (history) delete history; if (history) delete history;
if (smaller) delete smaller; if (smaller) delete smaller;
if (larger) delete larger; if (larger) delete larger;
@ -555,7 +555,7 @@ class commodity_base_t
typedef std::map<const string, commodity_t *> commodities_map; typedef std::map<const string, commodity_t *> commodities_map;
typedef std::pair<const string, commodity_t *> commodities_pair; typedef std::pair<const string, commodity_t *> commodities_pair;
typedef std::deque<commodity_t *> commodities_array; typedef std::vector<commodity_t *> commodities_array;
class commodity_t class commodity_t
{ {
@ -590,15 +590,15 @@ class commodity_t
public: public:
explicit commodity_t() : base(NULL), annotated(false) { explicit commodity_t() : base(NULL), annotated(false) {
TRACE_CTOR("commodity_t()"); TRACE_CTOR(commodity_t, "");
} }
commodity_t(const commodity_t& o) commodity_t(const commodity_t& o)
: ident(o.ident), base(o.base), : ident(o.ident), base(o.base),
qualified_symbol(o.qualified_symbol), annotated(o.annotated) { qualified_symbol(o.qualified_symbol), annotated(o.annotated) {
TRACE_CTOR("commodity_t(copy)"); TRACE_CTOR(commodity_t, "copy");
} }
virtual ~commodity_t() { virtual ~commodity_t() {
TRACE_DTOR("commodity_t"); TRACE_DTOR(commodity_t);
} }
operator bool() const { operator bool() const {
@ -703,11 +703,11 @@ class annotated_commodity_t : public commodity_t
string tag; string tag;
explicit annotated_commodity_t() { explicit annotated_commodity_t() {
TRACE_CTOR("annotated_commodity_t()"); TRACE_CTOR(annotated_commodity_t, "");
annotated = true; annotated = true;
} }
virtual ~annotated_commodity_t() { virtual ~annotated_commodity_t() {
TRACE_DTOR("annotated_commodity_t"); TRACE_DTOR(annotated_commodity_t);
} }
virtual bool operator==(const commodity_t& comm) const; virtual bool operator==(const commodity_t& comm) const;

View file

@ -1,7 +1,7 @@
#include "balance.h" #include "balance.h"
#include "util.h" #include "util.h"
#include <deque> #include <vector>
#include <algorithm> #include <algorithm>
namespace ledger { namespace ledger {
@ -115,8 +115,8 @@ void balance_t::write(std::ostream& out,
out << std::right << (*i).second; out << std::right << (*i).second;
} }
} else { } else {
typedef std::deque<const amount_t *> amounts_deque; typedef std::vector<const amount_t *> amounts_array;
amounts_deque sorted; amounts_array sorted;
for (amounts_map::const_iterator i = amounts.begin(); for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end(); i != amounts.end();
@ -127,7 +127,7 @@ void balance_t::write(std::ostream& out,
std::stable_sort(sorted.begin(), sorted.end(), std::stable_sort(sorted.begin(), sorted.end(),
compare_amount_commodities()); compare_amount_commodities());
for (amounts_deque::const_iterator i = sorted.begin(); for (amounts_array::const_iterator i = sorted.begin();
i != sorted.end(); i != sorted.end();
i++) { i++) {
int width; int width;

View file

@ -24,23 +24,23 @@ class balance_t
// constructors // constructors
balance_t() { balance_t() {
TRACE_CTOR("balance_t()"); TRACE_CTOR(balance_t, "");
} }
balance_t(const balance_t& bal) { balance_t(const balance_t& bal) {
TRACE_CTOR("balance_t(copy)"); TRACE_CTOR(balance_t, "copy");
for (amounts_map::const_iterator i = bal.amounts.begin(); for (amounts_map::const_iterator i = bal.amounts.begin();
i != bal.amounts.end(); i != bal.amounts.end();
i++) i++)
*this += (*i).second; *this += (*i).second;
} }
balance_t(const amount_t& amt) { balance_t(const amount_t& amt) {
TRACE_CTOR("balance_t(const amount_t&)"); TRACE_CTOR(balance_t, "const amount_t&");
if (! amt.realzero()) if (! amt.realzero())
amounts.insert(amounts_pair(&amt.commodity(), amt)); amounts.insert(amounts_pair(&amt.commodity(), amt));
} }
template <typename T> template <typename T>
balance_t(T val) { balance_t(T val) {
TRACE_CTOR("balance_t(T)"); TRACE_CTOR(balance_t, "T");
amount_t amt(val); amount_t amt(val);
if (! amt.realzero()) if (! amt.realzero())
amounts.insert(amounts_pair(&amt.commodity(), amt)); amounts.insert(amounts_pair(&amt.commodity(), amt));
@ -502,30 +502,30 @@ class balance_pair_t
// constructors // constructors
balance_pair_t() : cost(NULL) { balance_pair_t() : cost(NULL) {
TRACE_CTOR("balance_pair_t()"); TRACE_CTOR(balance_pair_t, "");
} }
balance_pair_t(const balance_pair_t& bal_pair) balance_pair_t(const balance_pair_t& bal_pair)
: quantity(bal_pair.quantity), cost(NULL) { : quantity(bal_pair.quantity), cost(NULL) {
TRACE_CTOR("balance_pair_t(copy)"); TRACE_CTOR(balance_pair_t, "copy");
if (bal_pair.cost) if (bal_pair.cost)
cost = new balance_t(*bal_pair.cost); cost = new balance_t(*bal_pair.cost);
} }
balance_pair_t(const balance_t& _quantity) balance_pair_t(const balance_t& _quantity)
: quantity(_quantity), cost(NULL) { : quantity(_quantity), cost(NULL) {
TRACE_CTOR("balance_pair_t(const balance_t&)"); TRACE_CTOR(balance_pair_t, "const balance_t&");
} }
balance_pair_t(const amount_t& _quantity) balance_pair_t(const amount_t& _quantity)
: quantity(_quantity), cost(NULL) { : quantity(_quantity), cost(NULL) {
TRACE_CTOR("balance_pair_t(const amount_t&)"); TRACE_CTOR(balance_pair_t, "const amount_t&");
} }
template <typename T> template <typename T>
balance_pair_t(T val) : quantity(val), cost(NULL) { balance_pair_t(T val) : quantity(val), cost(NULL) {
TRACE_CTOR("balance_pair_t(T)"); TRACE_CTOR(balance_pair_t, "T");
} }
// destructor // destructor
~balance_pair_t() { ~balance_pair_t() {
TRACE_DTOR("balance_pair_t"); TRACE_DTOR(balance_pair_t);
if (cost) delete cost; if (cost) delete cost;
} }

View file

@ -8,88 +8,43 @@
#include <unistd.h> // for the `write' method #include <unistd.h> // for the `write' method
int offset = 0; int new_calls = 0;
int new_size = 0;
std::map<void *, int> ptrs;
#define PRINT_INC(x) { \
char buf[128]; \
std::sprintf(buf, "%d: %p: %s", ++offset, ptr, x); \
write(1, buf, std::strlen(buf)); \
}
#define PRINT_DEC(x) { \
char buf[128]; \
std::sprintf(buf, "%d: %p: %s", --offset, ptr, x); \
write(1, buf, std::strlen(buf)); \
}
void * operator new(std::size_t size) throw (std::bad_alloc) { void * operator new(std::size_t size) throw (std::bad_alloc) {
void * ptr = std::malloc(size); void * ptr = std::malloc(size);
#if 0 // jww (2007-04-19): these don't work with boost::regex new_calls++;
if (DEBUG("debug.alloc")) { new_size += size;
PRINT_INC("void * operator new(std::size_t size) throw (std::bad_alloc)\n");
}
#endif
return ptr; return ptr;
} }
void * operator new[](std::size_t size) throw (std::bad_alloc) { void * operator new[](std::size_t size) throw (std::bad_alloc) {
void * ptr = std::malloc(size); void * ptr = std::malloc(size);
#if 0 new_calls++;
if (DEBUG("debug.alloc")) { new_size += size;
PRINT_INC("void * operator new[](std::size_t) throw (std::bad_alloc)\n");
}
#endif
return ptr; return ptr;
} }
void * operator new(std::size_t size, const std::nothrow_t&) throw() { void * operator new(std::size_t size, const std::nothrow_t&) throw() {
void * ptr = std::malloc(size); void * ptr = std::malloc(size);
#if 0 new_calls++;
if (DEBUG("debug.alloc")) { new_size += size;
PRINT_INC("void * operator new(std::size_t size, const std::nothrow_t&) throw()\n");
}
#endif
return ptr; return ptr;
} }
void * operator new[](std::size_t size, const std::nothrow_t&) throw() { void * operator new[](std::size_t size, const std::nothrow_t&) throw() {
void * ptr = std::malloc(size); void * ptr = std::malloc(size);
#if 0 new_calls++;
if (DEBUG("debug.alloc")) { new_size += size;
PRINT_INC("void * operator new[](std::size_t size, const std::nothrow_t&) throw()\n");
}
#endif
return ptr; return ptr;
} }
void operator delete(void * ptr) throw() { void operator delete(void * ptr) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete(void * ptr) throw()\n");
}
#endif
std::free(ptr); std::free(ptr);
} }
void operator delete[](void * ptr) throw() { void operator delete[](void * ptr) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete[](void * ptr) throw()\n");
}
#endif
std::free(ptr); std::free(ptr);
} }
void operator delete(void * ptr, const std::nothrow_t&) throw() { void operator delete(void * ptr, const std::nothrow_t&) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete(void * ptr, const std::nothrow_t&) throw()\n");
}
#endif
std::free(ptr); std::free(ptr);
} }
void operator delete[](void * ptr, const std::nothrow_t&) throw() { void operator delete[](void * ptr, const std::nothrow_t&) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete[](void * ptr, const std::nothrow_t&) throw()\n");
}
#endif
std::free(ptr); std::free(ptr);
} }
@ -97,13 +52,20 @@ std::ostream * _debug_stream = &std::cerr;
bool _free_debug_stream = false; bool _free_debug_stream = false;
boost::regex _debug_regex; boost::regex _debug_regex;
bool _set_debug_regex = false; bool _set_debug_regex = false;
bool _debug_regex_on = false;
bool _debug_active(const char * const cls) { bool _debug_active(const char * const cls) {
if (! _set_debug_regex) { if (! _set_debug_regex) {
_debug_regex = std::getenv("DEBUG_CLASS"); const char * user_class = std::getenv("DEBUG_CLASS");
if (user_class) {
_debug_regex = user_class;
_debug_regex_on = true;
}
_set_debug_regex = true; _set_debug_regex = true;
} }
return boost::regex_match(cls, _debug_regex); if (_debug_regex_on)
return boost::regex_match(cls, _debug_regex);
return false;
} }
static struct init_streams { static struct init_streams {

View file

@ -142,7 +142,7 @@ void operator delete[](void*, const std::nothrow_t&) throw();
#define CONFIRM(x) #define CONFIRM(x)
#ifndef TRACE_CTOR #ifndef TRACE_CTOR
#define TRACE_CTOR(cls) #define TRACE_CTOR(cls, args)
#define TRACE_DTOR(cls) #define TRACE_DTOR(cls)
#define TRACE(cat, msg) #define TRACE(cat, msg)
#define TRACE_PUSH(cat, msg) #define TRACE_PUSH(cat, msg)
@ -154,7 +154,7 @@ void operator delete[](void*, const std::nothrow_t&) throw();
#define CONFIRM(x) #define CONFIRM(x)
#ifndef TRACE_CTOR #ifndef TRACE_CTOR
#define TRACE_CTOR(cls) #define TRACE_CTOR(cls, args)
#define TRACE_DTOR(cls) #define TRACE_DTOR(cls)
#define TRACE(cat, msg) #define TRACE(cat, msg)
#define TRACE_PUSH(cat, msg) #define TRACE_PUSH(cat, msg)

View file

@ -28,11 +28,11 @@ class format_t
element_t() element_t()
: align_left(false), min_width(-1), max_width(-1), : align_left(false), min_width(-1), max_width(-1),
kind(UNKNOWN), chars(NULL) { kind(UNKNOWN), chars(NULL) {
TRACE_CTOR("element_t()"); TRACE_CTOR(element_t, "");
} }
~element_t() { ~element_t() {
TRACE_DTOR("element_t"); TRACE_DTOR(element_t);
switch (kind) { switch (kind) {
case TEXT: case TEXT:
@ -68,10 +68,10 @@ class format_t
public: public:
format_t() { format_t() {
TRACE_CTOR("format_t()"); TRACE_CTOR(format_t, "");
} }
format_t(const string& fmt) { format_t(const string& fmt) {
TRACE_CTOR("format_t(const string&)"); TRACE_CTOR(format_t, "const string&");
parse(fmt); parse(fmt);
} }
@ -84,7 +84,7 @@ class format_t
} }
virtual ~format_t() { virtual ~format_t() {
TRACE_DTOR("format_t"); TRACE_DTOR(format_t);
clear_elements(); clear_elements();
} }

View file

@ -18,7 +18,7 @@ bool transaction_t::use_effective_date = false;
transaction_t::~transaction_t() transaction_t::~transaction_t()
{ {
TRACE_DTOR("transaction_t"); TRACE_DTOR(transaction_t);
if (cost) delete cost; if (cost) delete cost;
} }
@ -274,7 +274,7 @@ entry_t::entry_t(const entry_t& e)
: entry_base_t(e), _date(e._date), _date_eff(e._date_eff), : entry_base_t(e), _date(e._date), _date_eff(e._date_eff),
code(e.code), payee(e.payee), data(NULL) code(e.code), payee(e.payee), data(NULL)
{ {
TRACE_CTOR("entry_t(copy)"); TRACE_CTOR(entry_t, "copy");
for (transactions_list::const_iterator i = transactions.begin(); for (transactions_list::const_iterator i = transactions.begin();
i != transactions.end(); i != transactions.end();
i++) i++)
@ -366,7 +366,7 @@ void auto_entry_t::extend_entry(entry_base_t& entry, bool post)
account_t::~account_t() account_t::~account_t()
{ {
TRACE_DTOR("account_t"); TRACE_DTOR(account_t);
for (accounts_map::iterator i = accounts.begin(); for (accounts_map::iterator i = accounts.begin();
i != accounts.end(); i != accounts.end();
@ -493,7 +493,7 @@ bool account_t::valid() const
journal_t::~journal_t() journal_t::~journal_t()
{ {
TRACE_DTOR("journal_t"); TRACE_DTOR(journal_t);
assert(master); assert(master);
delete master; delete master;

View file

@ -46,7 +46,7 @@ class transaction_t
: entry(NULL), account(_account), cost(NULL), : entry(NULL), account(_account), cost(NULL),
state(UNCLEARED), flags(TRANSACTION_NORMAL), state(UNCLEARED), flags(TRANSACTION_NORMAL),
beg_pos(0), beg_line(0), end_pos(0), end_line(0), data(NULL) { beg_pos(0), beg_line(0), end_pos(0), end_line(0), data(NULL) {
TRACE_CTOR("transaction_t(account_t *)"); TRACE_CTOR(transaction_t, "account_t *");
} }
transaction_t(account_t * _account, transaction_t(account_t * _account,
const amount_t& _amount, const amount_t& _amount,
@ -56,14 +56,14 @@ class transaction_t
state(UNCLEARED), flags(_flags), state(UNCLEARED), flags(_flags),
note(_note), beg_pos(0), beg_line(0), end_pos(0), end_line(0), note(_note), beg_pos(0), beg_line(0), end_pos(0), end_line(0),
data(NULL) { data(NULL) {
TRACE_CTOR("transaction_t(account_t *, const amount_t&, unsigned int, const string&)"); TRACE_CTOR(transaction_t, "account_t *, const amount_t&, unsigned int, const string&");
} }
transaction_t(const transaction_t& xact) transaction_t(const transaction_t& xact)
: entry(xact.entry), account(xact.account), amount(xact.amount), : entry(xact.entry), account(xact.account), amount(xact.amount),
cost(xact.cost ? new amount_t(*xact.cost) : NULL), cost(xact.cost ? new amount_t(*xact.cost) : NULL),
state(xact.state), flags(xact.flags), note(xact.note), state(xact.state), flags(xact.flags), note(xact.note),
beg_pos(0), beg_line(0), end_pos(0), end_line(0), data(NULL) { beg_pos(0), beg_line(0), end_pos(0), end_line(0), data(NULL) {
TRACE_CTOR("transaction_t(copy)"); TRACE_CTOR(transaction_t, "copy");
} }
~transaction_t(); ~transaction_t();
@ -112,19 +112,19 @@ class entry_base_t
entry_base_t() : journal(NULL), entry_base_t() : journal(NULL),
beg_pos(0), beg_line(0), end_pos(0), end_line(0) { beg_pos(0), beg_line(0), end_pos(0), end_line(0) {
TRACE_CTOR("entry_base_t()"); TRACE_CTOR(entry_base_t, "");
} }
entry_base_t(const entry_base_t& e) : journal(NULL), entry_base_t(const entry_base_t& e) : journal(NULL),
beg_pos(0), beg_line(0), end_pos(0), end_line(0) beg_pos(0), beg_line(0), end_pos(0), end_line(0)
{ {
TRACE_CTOR("entry_base_t(copy)"); TRACE_CTOR(entry_base_t, "copy");
for (transactions_list::const_iterator i = e.transactions.begin(); for (transactions_list::const_iterator i = e.transactions.begin();
i != e.transactions.end(); i != e.transactions.end();
i++) i++)
transactions.push_back(new transaction_t(**i)); transactions.push_back(new transaction_t(**i));
} }
virtual ~entry_base_t() { virtual ~entry_base_t() {
TRACE_DTOR("entry_base_t"); TRACE_DTOR(entry_base_t);
for (transactions_list::iterator i = transactions.begin(); for (transactions_list::iterator i = transactions.begin();
i != transactions.end(); i != transactions.end();
i++) i++)
@ -159,12 +159,12 @@ class entry_t : public entry_base_t
mutable void * data; mutable void * data;
entry_t() : data(NULL) { entry_t() : data(NULL) {
TRACE_CTOR("entry_t()"); TRACE_CTOR(entry_t, "");
} }
entry_t(const entry_t& e); entry_t(const entry_t& e);
virtual ~entry_t() { virtual ~entry_t() {
TRACE_DTOR("entry_t"); TRACE_DTOR(entry_t);
} }
moment_t actual_date() const { moment_t actual_date() const {
@ -224,15 +224,15 @@ public:
xml::xpath_t predicate; xml::xpath_t predicate;
auto_entry_t() { auto_entry_t() {
TRACE_CTOR("auto_entry_t()"); TRACE_CTOR(auto_entry_t, "");
} }
auto_entry_t(const string& _predicate) auto_entry_t(const string& _predicate)
: predicate(_predicate) { : predicate(_predicate) {
TRACE_CTOR("auto_entry_t(const string&)"); TRACE_CTOR(auto_entry_t, "const string&");
} }
virtual ~auto_entry_t() { virtual ~auto_entry_t() {
TRACE_DTOR("auto_entry_t"); TRACE_DTOR(auto_entry_t);
} }
virtual void extend_entry(entry_base_t& entry, bool post); virtual void extend_entry(entry_base_t& entry, bool post);
@ -255,19 +255,19 @@ class period_entry_t : public entry_base_t
string period_string; string period_string;
period_entry_t() { period_entry_t() {
TRACE_CTOR("period_entry_t()"); TRACE_CTOR(period_entry_t, "");
} }
period_entry_t(const string& _period) period_entry_t(const string& _period)
: period(_period), period_string(_period) { : period(_period), period_string(_period) {
TRACE_CTOR("period_entry_t(const string&)"); TRACE_CTOR(period_entry_t, "const string&");
} }
period_entry_t(const period_entry_t& e) period_entry_t(const period_entry_t& e)
: entry_base_t(e), period(e.period), period_string(e.period_string) { : entry_base_t(e), period(e.period), period_string(e.period_string) {
TRACE_CTOR("period_entry_t(copy)"); TRACE_CTOR(period_entry_t, "copy");
} }
virtual ~period_entry_t() { virtual ~period_entry_t() {
TRACE_DTOR("period_entry_t"); TRACE_DTOR(period_entry_t);
} }
virtual bool valid() const { virtual bool valid() const {
@ -300,7 +300,7 @@ class account_t
const string& _note = "") const string& _note = "")
: parent(_parent), name(_name), note(_note), : parent(_parent), name(_name), note(_note),
depth(parent ? parent->depth + 1 : 0), data(NULL), ident(0) { depth(parent ? parent->depth + 1 : 0), data(NULL), ident(0) {
TRACE_CTOR("account_t(account_t *, const string&, const string&)"); TRACE_CTOR(account_t, "account_t *, const string&, const string&");
} }
~account_t(); ~account_t();
@ -407,7 +407,7 @@ class journal_t
journal_t(session_t * _session) journal_t(session_t * _session)
: session(_session), basket(NULL), : session(_session), basket(NULL),
item_pool(NULL), item_pool_end(NULL), document(NULL) { item_pool(NULL), item_pool_end(NULL), document(NULL) {
TRACE_CTOR("journal_t()"); TRACE_CTOR(journal_t, "");
master = new account_t(NULL, ""); master = new account_t(NULL, "");
master->journal = this; master->journal = this;
} }

View file

@ -396,6 +396,11 @@ static int read_and_report(report_t * report, int argc, char * argv[],
return 0; return 0;
} }
#ifdef DEBUG_ENABLED
extern int new_calls;
extern int new_size;
#endif
int main(int argc, char * argv[], char * envp[]) int main(int argc, char * argv[], char * envp[])
{ {
int status = 1; int status = 1;
@ -429,7 +434,7 @@ int main(int argc, char * argv[], char * envp[])
#if DEBUG_LEVEL >= BETA #if DEBUG_LEVEL >= BETA
DEBUG_IF("ledger.trace.memory") { DEBUG_IF("ledger.trace.memory") {
ledger::trace_mode = true; ledger::trace_class_mode = true;
} }
#endif #endif
@ -490,6 +495,8 @@ int main(int argc, char * argv[], char * envp[])
#if DEBUG_LEVEL >= BETA #if DEBUG_LEVEL >= BETA
DEBUG_IF("ledger.trace.memory") { DEBUG_IF("ledger.trace.memory") {
report_memory(std::cerr); report_memory(std::cerr);
std::cerr << "Total calls to new: " << new_calls << std::endl
<< "Total memory new'd: " << new_size << std::endl;
} }
ledger::tracing_active = false; ledger::tracing_active = false;
#endif #endif

View file

@ -6,7 +6,7 @@ namespace ledger {
report_t::~report_t() report_t::~report_t()
{ {
TRACE_DTOR("report_t"); TRACE_DTOR(report_t);
for (std::list<transform_t *>::const_iterator i = transforms.begin(); for (std::list<transform_t *>::const_iterator i = transforms.begin();
i != transforms.end(); i != transforms.end();
i++) i++)

View file

@ -40,7 +40,7 @@ class report_t : public xml::xpath_t::scope_t
session(_session), session(_session),
last_transform(NULL) last_transform(NULL)
{ {
TRACE_CTOR("report_t(session_t *)"); TRACE_CTOR(report_t, "session_t *");
eval("t=total,TOT=0,T()=(TOT=TOT+t,TOT)"); eval("t=total,TOT=0,T()=(TOT=TOT+t,TOT)");
} }

View file

@ -226,7 +226,8 @@ void export_session()
.def_readwrite("cache_dirty", &session_t::cache_dirty) .def_readwrite("cache_dirty", &session_t::cache_dirty)
.def_readwrite("debug_mode", &session_t::debug_mode) .def_readwrite("debug_mode", &session_t::debug_mode)
.def_readwrite("verbose_mode", &session_t::verbose_mode) .def_readwrite("verbose_mode", &session_t::verbose_mode)
.def_readwrite("trace_mode", &session_t::trace_mode) .def_readwrite("trace_alloc_mode", &session_t::trace_alloc_mode)
.def_readwrite("trace_class_mode", &session_t::trace_class_mode)
.def_readwrite("journals", &session_t::journals) .def_readwrite("journals", &session_t::journals)
; ;

View file

@ -35,7 +35,8 @@ class session_t : public xml::xpath_t::scope_t
bool cache_dirty; bool cache_dirty;
bool debug_mode; bool debug_mode;
bool verbose_mode; bool verbose_mode;
bool trace_mode; bool trace_alloc_mode;
bool trace_class_mode;
moment_t now; moment_t now;
@ -89,7 +90,8 @@ class session_t : public xml::xpath_t::scope_t
cache_dirty(false), cache_dirty(false),
debug_mode(false), debug_mode(false),
verbose_mode(false), verbose_mode(false),
trace_mode(false), trace_alloc_mode(false),
trace_class_mode(false),
now(now), now(now),
@ -98,11 +100,11 @@ class session_t : public xml::xpath_t::scope_t
ansi_codes(false), ansi_codes(false),
ansi_invert(false) { ansi_invert(false) {
TRACE_CTOR("session_t(xml::xpath_t::scope_t *)"); TRACE_CTOR(session_t, "xml::xpath_t::scope_t *");
} }
virtual ~session_t() { virtual ~session_t() {
TRACE_DTOR("session_t"); TRACE_DTOR(session_t);
for (std::list<journal_t *>::iterator i = journals.begin(); for (std::list<journal_t *>::iterator i = journals.begin();
i != journals.end(); i != journals.end();

188
trace.cc
View file

@ -6,7 +6,8 @@
namespace ledger { namespace ledger {
bool trace_mode; bool trace_alloc_mode;
bool trace_class_mode;
void trace(const string& cat, const string& str) void trace(const string& cat, const string& str)
{ {
@ -37,94 +38,99 @@ object_count_map live_count;
bool tracing_active = false; bool tracing_active = false;
bool trace_ctor(void * ptr, const char * name) inline void add_to_count_map(object_count_map& the_map,
const char * name, std::size_t size)
{
object_count_map::iterator k = the_map.find(name);
if (k != the_map.end()) {
(*k).second.first++;
(*k).second.second += size;
} else {
std::pair<object_count_map::iterator, bool> result =
the_map.insert(object_count_pair(name, count_size_pair(1, size)));
assert(result.second);
}
}
inline void report_count_map(std::ostream& out, object_count_map& the_map)
{
for (object_count_map::iterator i = the_map.begin();
i != the_map.end();
i++)
out << " " << std::right << std::setw(12) << (*i).second.first
<< " " << std::right << std::setw(12) << (*i).second.second
<< " " << std::left << (*i).first
<< std::endl;
}
bool trace_ctor(void * ptr, const char * cls_name, const char * args,
std::size_t cls_size)
{ {
if (! tracing_active) if (! tracing_active)
return true; return true;
DEBUG_PRINT("ledger.trace.debug", "trace_ctor " << ptr << " " << name); if (trace_class_mode && cls_name[0] == '_')
return true;
if (trace_alloc_mode && cls_name[0] != '_')
return true;
const char * pos = std::strchr(name, '('); static char name[1024];
static char cls_name[1024]; std::strcpy(name, cls_name);
std::strncpy(cls_name, name, pos - name); std::strcat(name, "(");
cls_name[pos - name] = '\0'; std::strcat(name, args);
std::strcat(name, ")");
DEBUG_PRINT("ledger.trace.debug",
"trace_ctor " << ptr << " " << name);
live_objects.insert(live_objects_pair(ptr, cls_name)); live_objects.insert(live_objects_pair(ptr, cls_name));
object_count_map::iterator i = ctor_count.find(name); add_to_count_map(ctor_count, name, cls_size);
if (i != ctor_count.end()) { add_to_count_map(object_count, cls_name, cls_size);
(*i).second++; add_to_count_map(object_count, "__ALL__", cls_size);
} else { add_to_count_map(live_count, cls_name, cls_size);
std::pair<object_count_map::iterator, bool> result
= ctor_count.insert(object_count_pair(name, 1));
if (! result.second) {
tracing_active = false;
return false;
}
}
object_count_map::iterator j = object_count.find(cls_name);
if (j != object_count.end()) {
(*j).second++;
} else {
std::pair<object_count_map::iterator, bool> result
= object_count.insert(object_count_pair(cls_name, 1));
if (! result.second) {
tracing_active = false;
return false;
}
}
object_count_map::iterator k = live_count.find(cls_name);
if (k != live_count.end()) {
(*k).second++;
} else {
std::pair<object_count_map::iterator, bool> result
= live_count.insert(object_count_pair(cls_name, 1));
if (! result.second) {
tracing_active = false;
return false;
}
}
return true; return true;
} }
bool trace_dtor(void * ptr, const char * name) bool trace_dtor(void * ptr, const char * cls_name, std::size_t cls_size)
{ {
if (! tracing_active) if (! tracing_active)
return true; return true;
DEBUG_PRINT("ledger.trace.debug", "trace_dtor " << ptr << " " << name); if (trace_class_mode && cls_name[0] == '_')
return true;
if (trace_alloc_mode && cls_name[0] != '_')
return true;
DEBUG_PRINT("ledger.trace.debug", "trace_dtor " << ptr << " " << cls_name);
live_objects_map::iterator i = live_objects.find(ptr); live_objects_map::iterator i = live_objects.find(ptr);
if (i == live_objects.end()) { if (i == live_objects.end()) {
std::cerr << "Destruction of unknown object " << name << " " << ptr std::cerr << "Destruction of unknown object of type " << cls_name
<< std::endl;; << " " << ptr << std::endl;
tracing_active = false; assert(0);
return false; return false;
} }
const char * cls_name = name;
int ptr_count = live_objects.count(ptr); int ptr_count = live_objects.count(ptr);
for (int x = 0; x < ptr_count; x++) { for (int x = 0; x < ptr_count; x++, i++) {
if ((*i).second == cls_name) { if ((*i).second == cls_name) {
live_objects.erase(i); live_objects.erase(i);
break; break;
} else {
i++;
} }
} }
object_count_map::iterator k = live_count.find(name); object_count_map::iterator k = live_count.find(cls_name);
if (k == live_count.end()) { if (k == live_count.end()) {
std::cerr << "Destruction of unregistered class " << name std::cerr << "Destruction of unregistered class " << cls_name
<< std::endl;; << std::endl;;
tracing_active = false; assert(0);
return false; return false;
} }
if (--(*k).second == 0)
(*k).second.second -= cls_size;
if (--(*k).second.first == 0)
live_count.erase(k); live_count.erase(k);
return true; return true;
@ -132,91 +138,67 @@ bool trace_dtor(void * ptr, const char * name)
void report_memory(std::ostream& out) void report_memory(std::ostream& out)
{ {
if (live_count.size() > 0) if (live_count.size() > 0) {
out << "Live object counts:" << std::endl; out << "Live object counts:" << std::endl;
report_count_map(out, live_count);
for (object_count_map::iterator i = live_count.begin();
i != live_count.end();
i++) {
out << " ";
out << std::right;
out.width(7);
out << (*i).second << " " << (*i).first << std::endl;
} }
DEBUG_IF("ledger.trace.verbose") { if (live_objects.size() > 0) {
if (live_objects.size() > 0) out << "Live objects:" << std::endl;
out << "Live objects:" << std::endl;
for (live_objects_map::iterator i = live_objects.begin(); for (live_objects_map::iterator i = live_objects.begin();
i != live_objects.end(); i != live_objects.end();
i++) { i++)
out << " "; out << " " << std::right << std::setw(7) << (*i).first
out << std::right; << " " << std::left << (*i).second
out.width(7); << std::endl;
out << (*i).first << " " << (*i).second << std::endl;
}
} }
if (object_count.size() > 0) if (object_count.size() > 0) {
out << "Object counts:" << std::endl; out << "Object counts:" << std::endl;
report_count_map(out, object_count);
for (object_count_map::iterator i = object_count.begin();
i != object_count.end();
i++) {
out << " ";
out << std::right;
out.width(7);
out << (*i).second << " " << (*i).first << std::endl;
} }
if (ctor_count.size() > 0) if (ctor_count.size() > 0) {
out << "Constructor counts:" << std::endl; out << "Constructor counts:" << std::endl;
report_count_map(out, ctor_count);
for (object_count_map::iterator i = ctor_count.begin();
i != ctor_count.end();
i++) {
out << " ";
out << std::right;
out.width(7);
out << (*i).second << " " << (*i).first << std::endl;
} }
} }
#if DEBUG_LEVEL >= 4 #if DEBUG_LEVEL >= 4
string::string() : std::string() { string::string() : std::string() {
TRACE_CTOR("string()"); TRACE_CTOR(string, "");
} }
string::string(const string& str) : std::string(str) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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) { 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() { string::~string() {
TRACE_DTOR("string"); TRACE_DTOR(string);
} }
#endif #endif

44
trace.h
View file

@ -8,7 +8,8 @@ namespace ledger {
class timing_t; class timing_t;
extern bool trace_mode; extern bool trace_alloc_mode;
extern bool trace_class_mode;
#if DEBUG_LEVEL >= 4 #if DEBUG_LEVEL >= 4
class string; class string;
@ -17,43 +18,50 @@ typedef std::string string;
#endif #endif
void trace(const string& cat, const string& str); void trace(const string& cat, const string& str);
void trace_push(const string& cat, const string& str, void trace_push(const string& cat, const string& str, timing_t& timer);
timing_t& timer); void trace_pop(const string& cat, const string& str, timing_t& timer);
void trace_pop(const string& cat, const string& str,
timing_t& timer);
#ifndef TRACE #ifndef TRACE
#define TRACE(cat, msg) if (trace_mode) trace(#cat, msg) #define TRACE(cat, msg) if (trace_class_mode) trace(#cat, msg)
#define TRACE_(cat, msg) if (trace_mode) trace(#cat, msg) #define TRACE_(cat, msg) if (trace_class_mode) trace(#cat, msg)
#define TRACE_PUSH(cat, msg) \ #define TRACE_PUSH(cat, msg) \
timing_t timer_ ## cat(#cat); \ timing_t timer_ ## cat(#cat); \
if (trace_mode) trace_push(#cat, msg, timer_ ## cat) if (trace_class_mode) trace_push(#cat, msg, timer_ ## cat)
#define TRACE_POP(cat, msg) \ #define TRACE_POP(cat, msg) \
if (trace_mode) trace_pop(#cat, msg, timer_ ## cat) if (trace_class_mode) trace_pop(#cat, msg, timer_ ## cat)
#endif #endif
typedef std::multimap<void *, std::string> live_objects_map; typedef std::multimap<void *, std::string> live_objects_map;
typedef std::pair<void *, std::string> live_objects_pair; typedef std::pair<void *, std::string> live_objects_pair;
typedef std::map<std::string, int> object_count_map; typedef std::pair<unsigned int, std::size_t> count_size_pair;
typedef std::pair<std::string, int> object_count_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 live_objects_map live_objects;
extern object_count_map live_count;
extern object_count_map ctor_count; extern object_count_map ctor_count;
extern object_count_map object_count; extern object_count_map object_count;
extern object_count_map live_count;
extern bool tracing_active; extern bool tracing_active;
bool trace_ctor(void * ptr, const char * name); bool trace_ctor(void * ptr, const char * cls_name, const char * args,
bool trace_dtor(void * ptr, const char * name); 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); void report_memory(std::ostream& out);
#if 0
#ifndef TRACE_CTOR #ifndef TRACE_CTOR
#define TRACE_CTOR(cls) CONFIRM(ledger::trace_ctor(this, cls)) #define TRACE_CTOR(cls, args) \
#define TRACE_DTOR(cls) CONFIRM(ledger::trace_dtor(this, cls)) 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 #endif
#if DEBUG_LEVEL >= 4 #if DEBUG_LEVEL >= 4

View file

@ -4,7 +4,7 @@
#include "xpath.h" #include "xpath.h"
#include <list> #include <list>
#include <deque> #include <vector>
namespace ledger { namespace ledger {

40
value.h
View file

@ -5,7 +5,9 @@
#include "balance.h" #include "balance.h"
#include "error.h" #include "error.h"
#include <deque> #include "linked_list.h" // code by Donovan Rebbechi
#include <vector>
#include <exception> #include <exception>
namespace ledger { namespace ledger {
@ -26,7 +28,7 @@ namespace xml {
class value_t class value_t
{ {
public: public:
typedef std::deque<value_t> sequence_t; typedef std::vector<value_t> sequence_t;
char data[sizeof(balance_pair_t)]; char data[sizeof(balance_pair_t)];
@ -44,42 +46,42 @@ class value_t
} type; } type;
value_t() { value_t() {
TRACE_CTOR("value_t()"); TRACE_CTOR(value_t, "");
*((long *) data) = 0; *((long *) data) = 0;
type = INTEGER; type = INTEGER;
} }
value_t(const value_t& val) : type(INTEGER) { value_t(const value_t& val) : type(INTEGER) {
TRACE_CTOR("value_t(copy)"); TRACE_CTOR(value_t, "copy");
*this = val; *this = val;
} }
value_t(const bool val) { value_t(const bool val) {
TRACE_CTOR("value_t(const bool)"); TRACE_CTOR(value_t, "const bool");
*((bool *) data) = val; *((bool *) data) = val;
type = BOOLEAN; type = BOOLEAN;
} }
value_t(const long val) { value_t(const long val) {
TRACE_CTOR("value_t(const long)"); TRACE_CTOR(value_t, "const long");
*((long *) data) = val; *((long *) data) = val;
type = INTEGER; type = INTEGER;
} }
value_t(const moment_t val) { value_t(const moment_t val) {
TRACE_CTOR("value_t(const moment_t)"); TRACE_CTOR(value_t, "const moment_t");
*((moment_t *) data) = val; *((moment_t *) data) = val;
type = DATETIME; type = DATETIME;
} }
value_t(const unsigned long val) { value_t(const unsigned long val) {
TRACE_CTOR("value_t(const unsigned long)"); TRACE_CTOR(value_t, "const unsigned long");
new((amount_t *) data) amount_t(val); new((amount_t *) data) amount_t(val);
type = AMOUNT; type = AMOUNT;
} }
value_t(const double val) { value_t(const double val) {
TRACE_CTOR("value_t(const double)"); TRACE_CTOR(value_t, "const double");
new((amount_t *) data) amount_t(val); new((amount_t *) data) amount_t(val);
type = AMOUNT; type = AMOUNT;
} }
value_t(const string& val, bool literal = false) { value_t(const string& val, bool literal = false) {
TRACE_CTOR("value_t(const string&, bool)"); TRACE_CTOR(value_t, "const string&, bool");
if (literal) { if (literal) {
type = INTEGER; type = INTEGER;
set_string(val); set_string(val);
@ -89,38 +91,38 @@ class value_t
} }
} }
value_t(const char * val) { value_t(const char * val) {
TRACE_CTOR("value_t(const char *)"); TRACE_CTOR(value_t, "const char *");
new((amount_t *) data) amount_t(val); new((amount_t *) data) amount_t(val);
type = AMOUNT; type = AMOUNT;
} }
value_t(const amount_t& val) { value_t(const amount_t& val) {
TRACE_CTOR("value_t(const amount_t&)"); TRACE_CTOR(value_t, "const amount_t&");
new((amount_t *)data) amount_t(val); new((amount_t *)data) amount_t(val);
type = AMOUNT; type = AMOUNT;
} }
value_t(const balance_t& val) : type(INTEGER) { value_t(const balance_t& val) : type(INTEGER) {
TRACE_CTOR("value_t(const balance_t&)"); TRACE_CTOR(value_t, "const balance_t&");
*this = val; *this = val;
} }
value_t(const balance_pair_t& val) : type(INTEGER) { value_t(const balance_pair_t& val) : type(INTEGER) {
TRACE_CTOR("value_t(const balance_pair_t&)"); TRACE_CTOR(value_t, "const balance_pair_t&");
*this = val; *this = val;
} }
value_t(xml::node_t * xml_node) : type(INTEGER) { // gets set in = value_t(xml::node_t * xml_node) : type(INTEGER) { // gets set in =
TRACE_CTOR("value_t(xml::node_t *)"); TRACE_CTOR(value_t, "xml::node_t *");
*this = xml_node; *this = xml_node;
} }
value_t(void * item) : type(INTEGER) { // gets set in = value_t(void * item) : type(INTEGER) { // gets set in =
TRACE_CTOR("value_t(void *)"); TRACE_CTOR(value_t, "void *");
*this = item; *this = item;
} }
value_t(sequence_t * seq) : type(INTEGER) { // gets set in = value_t(sequence_t * seq) : type(INTEGER) { // gets set in =
TRACE_CTOR("value_t(sequence_t *)"); TRACE_CTOR(value_t, "sequence_t *");
*this = seq; *this = seq;
} }
~value_t() { ~value_t() {
TRACE_DTOR("value_t"); TRACE_DTOR(value_t);
destroy(); destroy();
} }
@ -276,7 +278,7 @@ class value_t
bool to_boolean() const; bool to_boolean() const;
long to_integer() const; long to_integer() const;
moment_t to_datetime() const; moment_t to_datetime() const;
amount_t to_amount() const; amount_t to_amount() const;
balance_t to_balance() const; balance_t to_balance() const;
balance_pair_t to_balance_pair() const; balance_pair_t to_balance_pair() const;

37
xml.cc
View file

@ -11,21 +11,21 @@ namespace xml {
document_t::document_t(node_t * _top, const char ** _builtins, document_t::document_t(node_t * _top, const char ** _builtins,
const int _builtins_size) const int _builtins_size)
: builtins(_builtins), builtins_size(_builtins_size), : builtins(_builtins), builtins_size(_builtins_size), stub(this),
top(_top ? _top : new terminal_node_t(this)) { top(_top ? _top : &stub) {
TRACE_CTOR("xml::document_t(node_t *, const char **, const int)"); TRACE_CTOR(xml::document_t, "node_t *, const char **, const int");
} }
document_t::~document_t() document_t::~document_t()
{ {
TRACE_DTOR("xml::document_t"); TRACE_DTOR(xml::document_t);
if (top) if (top && top != &stub)
delete top; delete top;
} }
void document_t::set_top(node_t * _top) void document_t::set_top(node_t * _top)
{ {
if (top) if (top && top != &stub)
delete top; delete top;
top = _top; top = _top;
} }
@ -117,7 +117,7 @@ node_t::node_t(document_t * _document, parent_node_t * _parent,
: name_id(0), parent(_parent), next(NULL), prev(NULL), : name_id(0), parent(_parent), next(NULL), prev(NULL),
flags(_flags), info(NULL), attrs(NULL) flags(_flags), info(NULL), attrs(NULL)
{ {
TRACE_CTOR("node_t(document_t *, node_t *)"); TRACE_CTOR(node_t, "document_t *, node_t *");
document = _document; document = _document;
if (document && ! document->top) if (document && ! document->top)
document->set_top(this); document->set_top(this);
@ -147,6 +147,29 @@ void node_t::extract()
prev = NULL; prev = NULL;
} }
const char * node_t::name() const
{
return document->lookup_name(name_id);
}
int node_t::set_name(const char * _name)
{
name_id = document->register_name(_name);
return name_id;
}
node_t * node_t::lookup_child(const char * _name)
{
int id = document->lookup_name_id(_name);
return lookup_child(id);
}
node_t * node_t::lookup_child(const string& _name)
{
int id = document->lookup_name_id(_name);
return lookup_child(id);
}
void parent_node_t::clear() void parent_node_t::clear()
{ {
node_t * child = _children; node_t * child = _children;

130
xml.h
View file

@ -21,44 +21,6 @@ class journal_t;
namespace xml { namespace xml {
class node_t;
class document_t
{
const char ** builtins;
const int builtins_size;
typedef std::deque<string> names_array;
names_array names;
typedef std::map<string, int> names_map;
typedef std::pair<string, int> names_pair;
names_map names_index;
public:
node_t * top;
// Ids 0-9 are reserved. 10-999 are for "builtin" names. 1000+ are
// for dynamically registered names.
enum special_names_t {
CURRENT, PARENT, ROOT, ALL
};
document_t(node_t * _top = NULL, const char ** _builtins = NULL,
const int _builtins_size = 0);
~document_t();
void set_top(node_t * _top);
int register_name(const string& name);
int lookup_name_id(const string& name) const;
const char * lookup_name(int id) const;
void write(std::ostream& out) const;
};
#define XML_NODE_IS_PARENT 0x1 #define XML_NODE_IS_PARENT 0x1
class conversion_error : public error { class conversion_error : public error {
@ -70,6 +32,7 @@ class conversion_error : public error {
}; };
class parent_node_t; class parent_node_t;
class document_t;
class node_t class node_t
{ {
@ -95,7 +58,7 @@ public:
unsigned int _flags = 0); unsigned int _flags = 0);
virtual ~node_t() { virtual ~node_t() {
TRACE_DTOR("node_t"); TRACE_DTOR(node_t);
if (parent) extract(); if (parent) extract();
if (attrs) delete attrs; if (attrs) delete attrs;
} }
@ -107,13 +70,8 @@ public:
return NULL; return NULL;
} }
const char * name() const { const char * name() const;
return document->lookup_name(name_id); int set_name(const char * _name);
}
int set_name(const char * _name) {
name_id = document->register_name(_name);
return name_id;
}
int set_name(int _name_id) { int set_name(int _name_id) {
name_id = _name_id; name_id = _name_id;
return name_id; return name_id;
@ -135,14 +93,8 @@ public:
return NULL; return NULL;
} }
node_t * lookup_child(const char * _name) { node_t * lookup_child(const char * _name);
int id = document->lookup_name_id(_name); node_t * lookup_child(const string& _name);
return lookup_child(id);
}
node_t * lookup_child(const string& _name) {
int id = document->lookup_name_id(_name);
return lookup_child(id);
}
virtual node_t * lookup_child(int /* _name_id */) { virtual node_t * lookup_child(int /* _name_id */) {
return NULL; return NULL;
} }
@ -168,10 +120,10 @@ public:
: node_t(_document, _parent, XML_NODE_IS_PARENT), : node_t(_document, _parent, XML_NODE_IS_PARENT),
_children(NULL), _last_child(NULL) _children(NULL), _last_child(NULL)
{ {
TRACE_CTOR("parent_node_t(document_t *, parent_node_t *)"); TRACE_CTOR(parent_node_t, "document_t *, parent_node_t *");
} }
virtual ~parent_node_t() { virtual ~parent_node_t() {
TRACE_DTOR("parent_node_t"); TRACE_DTOR(parent_node_t);
if (_children) clear(); if (_children) clear();
} }
@ -201,10 +153,10 @@ public:
terminal_node_t(document_t * _document, parent_node_t * _parent = NULL) terminal_node_t(document_t * _document, parent_node_t * _parent = NULL)
: node_t(_document, _parent) : node_t(_document, _parent)
{ {
TRACE_CTOR("terminal_node_t(document_t *, parent_node_t *)"); TRACE_CTOR(terminal_node_t, "document_t *, parent_node_t *");
} }
virtual ~terminal_node_t() { virtual ~terminal_node_t() {
TRACE_DTOR("terminal_node_t"); TRACE_DTOR(terminal_node_t);
} }
virtual const char * text() const { virtual const char * text() const {
@ -228,6 +180,44 @@ private:
terminal_node_t& operator=(const node_t&); terminal_node_t& operator=(const node_t&);
}; };
class document_t
{
const char ** builtins;
const int builtins_size;
typedef std::vector<string> names_array;
names_array names;
typedef std::map<string, int> names_map;
typedef std::pair<string, int> names_pair;
names_map names_index;
terminal_node_t stub;
public:
node_t * top;
// Ids 0-9 are reserved. 10-999 are for "builtin" names. 1000+ are
// for dynamically registered names.
enum special_names_t {
CURRENT, PARENT, ROOT, ALL
};
document_t(node_t * _top = NULL, const char ** _builtins = NULL,
const int _builtins_size = 0);
~document_t();
void set_top(node_t * _top);
int register_name(const string& name);
int lookup_name_id(const string& name) const;
const char * lookup_name(int id) const;
void write(std::ostream& out) const;
};
#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE) #if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
class parser_t class parser_t
@ -271,11 +261,11 @@ public:
commodity_t * _commodity, commodity_t * _commodity,
parent_node_t * _parent = NULL) parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), commodity(_commodity) { : parent_node_t(_document, _parent), commodity(_commodity) {
TRACE_CTOR("commodity_node_t(document_t *, commodity_t *, parent_node_t *)"); TRACE_CTOR(commodity_node_t, "document_t *, commodity_t *, parent_node_t *");
set_name("commodity"); set_name("commodity");
} }
virtual ~commodity_node_t() { virtual ~commodity_node_t() {
TRACE_DTOR("commodity_node_t"); TRACE_DTOR(commodity_node_t);
} }
virtual node_t * children() const; virtual node_t * children() const;
@ -290,11 +280,11 @@ public:
amount_t * _amount, amount_t * _amount,
parent_node_t * _parent = NULL) parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), amount(_amount) { : parent_node_t(_document, _parent), amount(_amount) {
TRACE_CTOR("amount_node_t(document_t *, amount_t *, parent_node_t *)"); TRACE_CTOR(amount_node_t, "document_t *, amount_t *, parent_node_t *");
set_name("amount"); set_name("amount");
} }
virtual ~amount_node_t() { virtual ~amount_node_t() {
TRACE_DTOR("amount_node_t"); TRACE_DTOR(amount_node_t);
} }
virtual node_t * children() const; virtual node_t * children() const;
@ -317,12 +307,12 @@ public:
parent_node_t * _parent = NULL) parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), payee_virtual_node(NULL), : parent_node_t(_document, _parent), payee_virtual_node(NULL),
transaction(_transaction) { transaction(_transaction) {
TRACE_CTOR("transaction_node_t(document_t *, transaction_t *, parent_node_t *)"); TRACE_CTOR(transaction_node_t, "document_t *, transaction_t *, parent_node_t *");
set_name("transaction"); set_name("transaction");
payee_id = document->register_name("payee"); payee_id = document->register_name("payee");
} }
virtual ~transaction_node_t() { virtual ~transaction_node_t() {
TRACE_DTOR("transaction_node_t"); TRACE_DTOR(transaction_node_t);
if (payee_virtual_node) if (payee_virtual_node)
delete payee_virtual_node; delete payee_virtual_node;
} }
@ -340,11 +330,11 @@ public:
entry_node_t(document_t * _document, entry_t * _entry, entry_node_t(document_t * _document, entry_t * _entry,
parent_node_t * _parent = NULL) parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), entry(_entry) { : parent_node_t(_document, _parent), entry(_entry) {
TRACE_CTOR("entry_node_t(document_t *, entry_t *, parent_node_t *)"); TRACE_CTOR(entry_node_t, "document_t *, entry_t *, parent_node_t *");
set_name("entry"); set_name("entry");
} }
virtual ~entry_node_t() { virtual ~entry_node_t() {
TRACE_DTOR("entry_node_t"); TRACE_DTOR(entry_node_t);
} }
virtual node_t * children() const; virtual node_t * children() const;
@ -358,11 +348,11 @@ public:
account_node_t(document_t * _document, account_t * _account, account_node_t(document_t * _document, account_t * _account,
parent_node_t * _parent = NULL) parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), account(_account) { : parent_node_t(_document, _parent), account(_account) {
TRACE_CTOR("account_node_t(document_t *, account_t *, parent_node_t *)"); TRACE_CTOR(account_node_t, "document_t *, account_t *, parent_node_t *");
set_name("account"); set_name("account");
} }
virtual ~account_node_t() { virtual ~account_node_t() {
TRACE_DTOR("account_node_t"); TRACE_DTOR(account_node_t);
} }
virtual node_t * children() const; virtual node_t * children() const;
@ -376,11 +366,11 @@ public:
journal_node_t(document_t * _document, journal_t * _journal, journal_node_t(document_t * _document, journal_t * _journal,
parent_node_t * _parent = NULL) parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), journal(_journal) { : parent_node_t(_document, _parent), journal(_journal) {
TRACE_CTOR("journal_node_t(document_t *, journal_t *, parent_node_t *)"); TRACE_CTOR(journal_node_t, "document_t *, journal_t *, parent_node_t *");
set_name("journal"); set_name("journal");
} }
virtual ~journal_node_t() { virtual ~journal_node_t() {
TRACE_DTOR("journal_node_t"); TRACE_DTOR(journal_node_t);
} }
virtual node_t * children() const; virtual node_t * children() const;

View file

@ -546,7 +546,7 @@ bool xpath_t::function_scope_t::resolve(const string& name,
xpath_t::op_t::~op_t() xpath_t::op_t::~op_t()
{ {
TRACE_DTOR("xpath_t::op_t"); TRACE_DTOR(xpath_t::op_t);
DEBUG_PRINT("ledger.xpath.memory", "Destroying " << this); DEBUG_PRINT("ledger.xpath.memory", "Destroying " << this);
assert(refc == 0); assert(refc == 0);

28
xpath.h
View file

@ -189,11 +189,11 @@ public:
scope_t(scope_t * _parent = NULL, kind_t _kind = NORMAL) scope_t(scope_t * _parent = NULL, kind_t _kind = NORMAL)
: parent(_parent), kind(_kind) { : parent(_parent), kind(_kind) {
TRACE_CTOR("xpath_t::scope_t(scope *, kind_t)"); TRACE_CTOR(xpath_t::scope_t, "scope *, kind_t");
} }
virtual ~scope_t() { virtual ~scope_t() {
TRACE_DTOR("xpath_t::scope_t"); TRACE_DTOR(xpath_t::scope_t);
for (symbol_map::iterator i = symbols.begin(); for (symbol_map::iterator i = symbols.begin();
i != symbols.end(); i != symbols.end();
i++) i++)
@ -296,17 +296,17 @@ private:
unsigned int length; unsigned int length;
token_t() : kind(UNKNOWN), length(0) { token_t() : kind(UNKNOWN), length(0) {
TRACE_CTOR("xpath_t::token_t()"); TRACE_CTOR(xpath_t::token_t, "");
} }
token_t(const token_t& other) { token_t(const token_t& other) {
assert(0); assert(0);
TRACE_CTOR("xpath_t::token_t(copy)"); TRACE_CTOR(xpath_t::token_t, "copy");
*this = other; *this = other;
} }
~token_t() { ~token_t() {
TRACE_DTOR("xpath_t::token_t"); TRACE_DTOR(xpath_t::token_t);
} }
token_t& operator=(const token_t& other) { token_t& operator=(const token_t& other) {
@ -421,7 +421,7 @@ public:
op_t(const kind_t _kind) op_t(const kind_t _kind)
: kind(_kind), refc(0), left(NULL), right(NULL) { : kind(_kind), refc(0), left(NULL), right(NULL) {
TRACE_CTOR("xpath_t::op_t(const kind_t)"); TRACE_CTOR(xpath_t::op_t, "const kind_t");
} }
op_t(const op_t&); op_t(const op_t&);
~op_t(); ~op_t();
@ -618,31 +618,31 @@ public:
unsigned short flags; // flags used to parse `expr' unsigned short flags; // flags used to parse `expr'
xpath_t() : ptr(NULL), use_lookahead(false), flags(0) { xpath_t() : ptr(NULL), use_lookahead(false), flags(0) {
TRACE_CTOR("xpath_t"); TRACE_CTOR(xpath_t, "");
} }
xpath_t(op_t * _ptr) : ptr(_ptr), use_lookahead(false) { xpath_t(op_t * _ptr) : ptr(_ptr), use_lookahead(false) {
TRACE_CTOR("xpath_t(op_t *)"); TRACE_CTOR(xpath_t, "op_t *");
} }
xpath_t(const string& _expr, xpath_t(const string& _expr,
unsigned short _flags = XPATH_PARSE_RELAXED) unsigned short _flags = XPATH_PARSE_RELAXED)
: ptr(NULL), use_lookahead(false), flags(0) { : ptr(NULL), use_lookahead(false), flags(0) {
TRACE_CTOR("xpath_t(const string&, unsigned short)"); TRACE_CTOR(xpath_t, "const string&, unsigned short");
if (! _expr.empty()) if (! _expr.empty())
parse(_expr, _flags); parse(_expr, _flags);
} }
xpath_t(std::istream& in, unsigned short _flags = XPATH_PARSE_RELAXED) xpath_t(std::istream& in, unsigned short _flags = XPATH_PARSE_RELAXED)
: ptr(NULL), use_lookahead(false), flags(0) { : ptr(NULL), use_lookahead(false), flags(0) {
TRACE_CTOR("xpath_t(std::istream&, unsigned short)"); TRACE_CTOR(xpath_t, "std::istream&, unsigned short");
parse(in, _flags); parse(in, _flags);
} }
xpath_t(const xpath_t& other) xpath_t(const xpath_t& other)
: ptr(other.ptr ? other.ptr->acquire() : NULL), : ptr(other.ptr ? other.ptr->acquire() : NULL),
use_lookahead(false), expr(other.expr), flags(other.flags) { use_lookahead(false), expr(other.expr), flags(other.flags) {
TRACE_CTOR("xpath_t(copy)"); TRACE_CTOR(xpath_t, "copy");
} }
virtual ~xpath_t() { virtual ~xpath_t() {
TRACE_DTOR("xpath_t"); TRACE_DTOR(xpath_t);
reset(NULL); reset(NULL);
} }
@ -700,8 +700,8 @@ public:
void compile(document_t * document, scope_t * scope = NULL) { void compile(document_t * document, scope_t * scope = NULL) {
if (! document) { if (! document) {
std::auto_ptr<document_t> tdoc(new xml::document_t); document_t tdoc;
compile(tdoc->top, scope); compile(tdoc.top, scope);
} else { } else {
compile(document->top, scope); compile(document->top, scope);
} }