diff options
author | John Wiegley <johnw@newartisans.com> | 2007-04-20 02:14:53 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 03:38:28 -0400 |
commit | b84f676946941df6f7e8476d77d1db0cbe7736c5 (patch) | |
tree | 9ee7c7a2d3b7496b38ad127519210adfeced2241 | |
parent | 539370ff1b37772e9f11439f652ffd3583beeedb (diff) | |
download | fork-ledger-b84f676946941df6f7e8476d77d1db0cbe7736c5.tar.gz fork-ledger-b84f676946941df6f7e8476d77d1db0cbe7736c5.tar.bz2 fork-ledger-b84f676946941df6f7e8476d77d1db0cbe7736c5.zip |
Did some optimization and memory cleanup
-rw-r--r-- | Makefile.am | 8 | ||||
-rw-r--r-- | Makefile.in | 57 | ||||
-rwxr-xr-x | acprep | 8 | ||||
-rw-r--r-- | amount.cc | 163 | ||||
-rw-r--r-- | amount.h | 114 | ||||
-rw-r--r-- | balance.h | 2 | ||||
-rw-r--r-- | binary.cc | 36 | ||||
-rw-r--r-- | binary.h | 20 | ||||
-rw-r--r-- | debug.cc | 18 | ||||
-rw-r--r-- | debug.h | 23 | ||||
-rw-r--r-- | derive.cc | 6 | ||||
-rw-r--r-- | docs/sample.dat | 6 | ||||
-rw-r--r-- | error.h | 42 | ||||
-rw-r--r-- | format.cc | 27 | ||||
-rw-r--r-- | format.h | 14 | ||||
-rw-r--r-- | gnucash.cc | 38 | ||||
-rw-r--r-- | gnucash.h | 14 | ||||
-rw-r--r-- | journal.cc | 39 | ||||
-rw-r--r-- | journal.h | 84 | ||||
-rw-r--r-- | main.cc | 129 | ||||
-rw-r--r-- | mask.cc | 6 | ||||
-rw-r--r-- | mask.h | 10 | ||||
-rw-r--r-- | ofx.cc | 12 | ||||
-rw-r--r-- | ofx.h | 2 | ||||
-rw-r--r-- | option.cc | 101 | ||||
-rw-r--r-- | option.h | 8 | ||||
-rw-r--r-- | parser.cc | 2 | ||||
-rw-r--r-- | parser.h | 4 | ||||
-rw-r--r-- | py_amount.cc | 6 | ||||
-rw-r--r-- | py_eval.cc | 18 | ||||
-rw-r--r-- | py_eval.h | 12 | ||||
-rw-r--r-- | qif.cc | 6 | ||||
-rw-r--r-- | qif.h | 2 | ||||
-rw-r--r-- | quotes.cc | 9 | ||||
-rw-r--r-- | quotes.h | 4 | ||||
-rw-r--r-- | report.cc | 11 | ||||
-rw-r--r-- | report.h | 31 | ||||
-rw-r--r-- | session.cc | 26 | ||||
-rw-r--r-- | session.h | 51 | ||||
-rw-r--r-- | tests/corelib/numerics/BasicAmount.cc | 21 | ||||
-rw-r--r-- | tests/corelib/numerics/Commodity.cc | 8 | ||||
-rw-r--r-- | tests/corelib/numerics/CommodityAmount.cc | 147 | ||||
-rw-r--r-- | textual.cc | 134 | ||||
-rw-r--r-- | textual.h | 10 | ||||
-rw-r--r-- | times.cc | 2 | ||||
-rw-r--r-- | times.h | 20 | ||||
-rw-r--r-- | timing.h | 31 | ||||
-rw-r--r-- | trace.cc | 68 | ||||
-rw-r--r-- | trace.h | 90 | ||||
-rw-r--r-- | transform.h | 4 | ||||
-rw-r--r-- | util.cc | 40 | ||||
-rw-r--r-- | util.h | 17 | ||||
-rw-r--r-- | value.cc | 116 | ||||
-rw-r--r-- | value.h | 24 | ||||
-rw-r--r-- | xml.cc | 24 | ||||
-rw-r--r-- | xml.h | 36 | ||||
-rw-r--r-- | xmlparse.cc | 22 | ||||
-rw-r--r-- | xmlparse.h | 2 | ||||
-rw-r--r-- | xpath.cc | 117 | ||||
-rw-r--r-- | xpath.h | 83 |
60 files changed, 1232 insertions, 953 deletions
diff --git a/Makefile.am b/Makefile.am index 79363110..3e1c7fee 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,6 +20,11 @@ endif AM_YFLAGS = -d AM_LFLAGS = -o $(LEX_OUTPUT_ROOT).c +WARNFLAGS = -Wall -Wextra -Wfloat-equal -Wno-endif-labels +WARNFLAGS += -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion +WARNFLAGS += -Wconversion -Wshorten-64-to-32 -Wsign-compare +WARNFLAGS += -Wmissing-field-initializers -pedantic-errors + libledger_la_CXXFLAGS = $(WARNFLAGS) -I$(top_builddir)/gdtoa libledger_la_SOURCES = \ amount.cc \ @@ -34,6 +39,7 @@ libledger_la_SOURCES = \ mask.cc \ format.cc \ util.cc \ + trace.cc \ \ session.cc \ journal.cc \ @@ -67,7 +73,7 @@ libledger_la_SOURCES += ofx.cc endif if DEBUG libledger_la_CXXFLAGS += -DDEBUG_LEVEL=4 -libledger_la_SOURCES += debug.cc trace.cc +libledger_la_SOURCES += debug.cc endif if HAVE_BOOST_PYTHON libledger_la_CXXFLAGS += -DUSE_BOOST_PYTHON=1 diff --git a/Makefile.in b/Makefile.in index 60b15a6e..8a955fc2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -43,7 +43,7 @@ host_triplet = @host@ @HAVE_LIBOFX_TRUE@am__append_6 = -DHAVE_LIBOFX=1 @HAVE_LIBOFX_TRUE@am__append_7 = ofx.cc @DEBUG_TRUE@am__append_8 = -DDEBUG_LEVEL=4 -@DEBUG_TRUE@am__append_9 = debug.cc trace.cc +@DEBUG_TRUE@am__append_9 = debug.cc @HAVE_BOOST_PYTHON_TRUE@am__append_10 = -DUSE_BOOST_PYTHON=1 @DEBUG_TRUE@am__append_11 = -DDEBUG_LEVEL=4 bin_PROGRAMS = ledger$(EXEEXT) @@ -68,8 +68,8 @@ subdir = . DIST_COMMON = README $(am__configure_deps) $(pkginclude_HEADERS) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/acconf.h.in $(top_srcdir)/configure AUTHORS COPYING \ - ChangeLog INSTALL NEWS compile config.guess config.sub depcomp \ - elisp-comp install-sh ltmain.sh missing parsetime.cc \ + ChangeLog INSTALL NEWS TODO compile config.guess config.sub \ + depcomp elisp-comp install-sh ltmain.sh missing parsetime.cc \ parsetime.h scantime.cc texinfo.tex ylwrap ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in @@ -94,30 +94,29 @@ LTLIBRARIES = $(lib_LTLIBRARIES) libledger_la_LIBADD = am__libledger_la_SOURCES_DIST = amount.cc times.cc parsetime.yy \ scantime.ll quotes.cc balance.cc value.cc xml.cc xpath.cc \ - mask.cc format.cc util.cc session.cc journal.cc parser.cc \ - textual.cc binary.cc xmlparse.cc qif.cc report.cc transform.cc \ - register.cc csv.cc derive.cc emacs.cc reconcile.cc gnucash.cc \ - ofx.cc debug.cc trace.cc + mask.cc format.cc util.cc trace.cc session.cc journal.cc \ + parser.cc textual.cc binary.cc xmlparse.cc qif.cc report.cc \ + transform.cc register.cc csv.cc derive.cc emacs.cc \ + reconcile.cc gnucash.cc ofx.cc debug.cc @HAVE_EXPAT_TRUE@am__objects_1 = libledger_la-gnucash.lo @HAVE_XMLPARSE_TRUE@am__objects_2 = libledger_la-gnucash.lo @HAVE_LIBOFX_TRUE@am__objects_3 = libledger_la-ofx.lo -@DEBUG_TRUE@am__objects_4 = libledger_la-debug.lo \ -@DEBUG_TRUE@ libledger_la-trace.lo +@DEBUG_TRUE@am__objects_4 = libledger_la-debug.lo am_libledger_la_OBJECTS = libledger_la-amount.lo libledger_la-times.lo \ libledger_la-parsetime.lo libledger_la-scantime.lo \ libledger_la-quotes.lo libledger_la-balance.lo \ libledger_la-value.lo libledger_la-xml.lo \ libledger_la-xpath.lo libledger_la-mask.lo \ libledger_la-format.lo libledger_la-util.lo \ - libledger_la-session.lo libledger_la-journal.lo \ - libledger_la-parser.lo libledger_la-textual.lo \ - libledger_la-binary.lo libledger_la-xmlparse.lo \ - libledger_la-qif.lo libledger_la-report.lo \ - libledger_la-transform.lo libledger_la-register.lo \ - libledger_la-csv.lo libledger_la-derive.lo \ - libledger_la-emacs.lo libledger_la-reconcile.lo \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) + libledger_la-trace.lo libledger_la-session.lo \ + libledger_la-journal.lo libledger_la-parser.lo \ + libledger_la-textual.lo libledger_la-binary.lo \ + libledger_la-xmlparse.lo libledger_la-qif.lo \ + libledger_la-report.lo libledger_la-transform.lo \ + libledger_la-register.lo libledger_la-csv.lo \ + libledger_la-derive.lo libledger_la-emacs.lo \ + libledger_la-reconcile.lo $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) libledger_la_OBJECTS = $(am_libledger_la_OBJECTS) libledger_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(libledger_la_CXXFLAGS) \ @@ -368,13 +367,17 @@ EXTRA_DIST = docs tests ledger.pdf ledger.info lib_LTLIBRARIES = libledger.la $(am__append_1) AM_YFLAGS = -d AM_LFLAGS = -o $(LEX_OUTPUT_ROOT).c +WARNFLAGS = -Wall -Wextra -Wfloat-equal -Wno-endif-labels -Wcast-qual \ + -Wcast-align -Wwrite-strings -Wconversion -Wconversion \ + -Wshorten-64-to-32 -Wsign-compare -Wmissing-field-initializers \ + -pedantic-errors libledger_la_CXXFLAGS = $(WARNFLAGS) -I$(top_builddir)/gdtoa \ $(am__append_2) $(am__append_4) $(am__append_6) \ $(am__append_8) $(am__append_10) libledger_la_SOURCES = amount.cc times.cc parsetime.yy scantime.ll \ quotes.cc balance.cc value.cc xml.cc xpath.cc mask.cc \ - format.cc util.cc session.cc journal.cc parser.cc textual.cc \ - binary.cc xmlparse.cc qif.cc report.cc transform.cc \ + format.cc util.cc trace.cc session.cc journal.cc parser.cc \ + textual.cc binary.cc xmlparse.cc qif.cc report.cc transform.cc \ register.cc csv.cc derive.cc emacs.cc reconcile.cc \ $(am__append_3) $(am__append_5) $(am__append_7) \ $(am__append_9) @@ -748,6 +751,13 @@ libledger_la-util.lo: util.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-util.lo `test -f 'util.cc' || echo '$(srcdir)/'`util.cc +libledger_la-trace.lo: trace.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-trace.lo -MD -MP -MF $(DEPDIR)/libledger_la-trace.Tpo -c -o libledger_la-trace.lo `test -f 'trace.cc' || echo '$(srcdir)/'`trace.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-trace.Tpo $(DEPDIR)/libledger_la-trace.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='trace.cc' object='libledger_la-trace.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-trace.lo `test -f 'trace.cc' || echo '$(srcdir)/'`trace.cc + libledger_la-session.lo: session.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-session.lo -MD -MP -MF $(DEPDIR)/libledger_la-session.Tpo -c -o libledger_la-session.lo `test -f 'session.cc' || echo '$(srcdir)/'`session.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-session.Tpo $(DEPDIR)/libledger_la-session.Plo @@ -867,13 +877,6 @@ libledger_la-debug.lo: debug.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-debug.lo `test -f 'debug.cc' || echo '$(srcdir)/'`debug.cc -libledger_la-trace.lo: trace.cc -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-trace.lo -MD -MP -MF $(DEPDIR)/libledger_la-trace.Tpo -c -o libledger_la-trace.lo `test -f 'trace.cc' || echo '$(srcdir)/'`trace.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-trace.Tpo $(DEPDIR)/libledger_la-trace.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='trace.cc' object='libledger_la-trace.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-trace.lo `test -f 'trace.cc' || echo '$(srcdir)/'`trace.cc - libpyledger_la-py_eval.lo: py_eval.cc @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpyledger_la_CXXFLAGS) $(CXXFLAGS) -MT libpyledger_la-py_eval.lo -MD -MP -MF $(DEPDIR)/libpyledger_la-py_eval.Tpo -c -o libpyledger_la-py_eval.lo `test -f 'py_eval.cc' || echo '$(srcdir)/'`py_eval.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libpyledger_la-py_eval.Tpo $(DEPDIR)/libpyledger_la-py_eval.Plo @@ -45,12 +45,6 @@ else CXXFLAGS="" fi -WARNFLAGS="-Wall -Wextra -Wfloat-equal -Wno-endif-labels -Wshadow" -WARNFLAGS="$WARNFLAGS -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion" -WARNFLAGS="$WARNFLAGS -Wconversion -Wshorten-64-to-32 -Wsign-compare" -WARNFLAGS="$WARNFLAGS -Wmissing-field-initializers -Wmissing-noreturn" -WARNFLAGS="$WARNFLAGS -pedantic-errors" - # Building the command-line tool as a shared library is a luxury, # since there are no clients except a GUI tool which might use it (and # that is built again anyway by Xcode). @@ -100,4 +94,4 @@ fi "$HERE/configure" --srcdir="$HERE" \ EMACS="$HOME/bin/emacs" EMACSLOADPATH="$EMACSLOADPATH" \ CPPFLAGS="$INCDIRS" CXXFLAGS="$CXXFLAGS $local_cxxflags" \ - WARNFLAGS="$WARNFLAGS" LDFLAGS="$LIBDIRS" $SWITCHES "$@" + LDFLAGS="$LIBDIRS" $SWITCHES "$@" @@ -94,11 +94,11 @@ static mpz_t temp; // these are the global temp variables static mpz_t divisor; #endif -static amount_t::bigint_t true_value; +static amount_t::bigint_t * true_value = NULL; inline amount_t::bigint_t::~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); } @@ -114,55 +114,62 @@ commodity_t * commodity_t::null_commodity; commodity_t * commodity_t::default_commodity = NULL; #endif -static struct _init_amounts +void amount_t::initialize() { - _init_amounts() { - mpz_init(temp); - mpz_init(divisor); + mpz_init(temp); + mpz_init(divisor); - mpz_set_ui(true_value.val, 1); + true_value = new amount_t::bigint_t; + mpz_set_ui(true_value->val, 1); - commodity_base_t::updater = NULL; - commodity_t::null_commodity = commodity_t::create(""); - commodity_t::default_commodity = NULL; + commodity_base_t::updater = NULL; - commodity_t::null_commodity->add_flags(COMMODITY_STYLE_NOMARKET | - COMMODITY_STYLE_BUILTIN); + commodity_t::default_commodity = NULL; + commodity_t::null_commodity = commodity_t::create(""); + commodity_t::null_commodity->add_flags(COMMODITY_STYLE_NOMARKET | + COMMODITY_STYLE_BUILTIN); - // Add time commodity conversions, so that timelog's may be parsed - // in terms of seconds, but reported as minutes or hours. - commodity_t * commodity; + // Add time commodity conversions, so that timelog's may be parsed + // in terms of seconds, but reported as minutes or hours. + commodity_t * commodity = commodity_t::create("s"); + commodity->add_flags(COMMODITY_STYLE_NOMARKET | COMMODITY_STYLE_BUILTIN); - commodity = commodity_t::create("s"); - commodity->add_flags(COMMODITY_STYLE_NOMARKET | COMMODITY_STYLE_BUILTIN); + parse_conversion("1.0m", "60s"); + parse_conversion("1.0h", "60m"); +} + +void amount_t::shutdown() +{ + mpz_clear(temp); + mpz_clear(divisor); - parse_conversion("1.0m", "60s"); - parse_conversion("1.0h", "60m"); + if (commodity_base_t::updater) { + delete commodity_base_t::updater; + commodity_base_t::updater = NULL; } - ~_init_amounts() { - if (! do_cleanup) - return; + for (base_commodities_map::iterator i = commodity_base_t::commodities.begin(); + i != commodity_base_t::commodities.end(); + i++) + delete (*i).second; - mpz_clear(temp); - mpz_clear(divisor); + for (commodities_map::iterator i = commodity_t::commodities.begin(); + i != commodity_t::commodities.end(); + i++) + delete (*i).second; - if (commodity_base_t::updater) { - delete commodity_base_t::updater; - commodity_base_t::updater = NULL; - } + commodity_base_t::commodities.clear(); + commodity_t::commodities.clear(); + commodity_t::commodities_by_ident.clear(); - for (commodities_map::iterator i = commodity_t::commodities.begin(); - i != commodity_t::commodities.end(); - i++) - delete (*i).second; + commodity_t::null_commodity = NULL; + commodity_t::default_commodity = NULL; - commodity_t::commodities.clear(); - commodity_t::commodities_by_ident.clear(); - - true_value.ref--; - } -} _init_obj; + true_value->ref--; + assert(true_value->ref == 0); + delete true_value; + true_value = NULL; +} static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec) { @@ -380,7 +387,7 @@ void amount_t::_copy(const amount_t& amt) commodity_ = amt.commodity_; } -amount_t& amount_t::operator=(const std::string& val) +amount_t& amount_t::operator=(const string& val) { std::istringstream str(val); parse(str); @@ -389,7 +396,7 @@ amount_t& amount_t::operator=(const std::string& val) amount_t& amount_t::operator=(const char * val) { - std::string valstr(val); + string valstr(val); std::istringstream str(valstr); parse(str); return *this; @@ -479,7 +486,7 @@ amount_t& amount_t::operator+=(const amount_t& amt) { if (commodity() != amt.commodity()) { throw new amount_error - (std::string("Adding amounts with different commodities: ") + + (string("Adding amounts with different commodities: ") + (has_commodity() ? commodity_->qualified_symbol : "NONE") + " != " + (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE")); } @@ -514,7 +521,7 @@ amount_t& amount_t::operator-=(const amount_t& amt) { if (commodity() != amt.commodity()) throw new amount_error - (std::string("Subtracting amounts with different commodities: ") + + (string("Subtracting amounts with different commodities: ") + (has_commodity() ? commodity_->qualified_symbol : "NONE") + " != " + (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE")); @@ -551,7 +558,7 @@ amount_t& amount_t::operator*=(const amount_t& amt) if (has_commodity() && amt.has_commodity() && commodity() != amt.commodity()) { throw new amount_error - (std::string("Multiplying amounts with different commodities: ") + + (string("Multiplying amounts with different commodities: ") + (has_commodity() ? commodity_->qualified_symbol : "NONE") + " != " + (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE")); } @@ -591,7 +598,7 @@ amount_t& amount_t::operator/=(const amount_t& amt) if (has_commodity() && amt.has_commodity() && commodity() != amt.commodity()) { throw new amount_error - (std::string("Dividing amounts with different commodities: ") + + (string("Dividing amounts with different commodities: ") + (has_commodity() ? commodity_->qualified_symbol : "NONE") + " != " + (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE")); } @@ -664,7 +671,7 @@ int amount_t::compare(const amount_t& amt) const if (has_commodity() && amt.commodity() && commodity() != amt.commodity()) throw new amount_error - (std::string("Cannot compare amounts with different commodities: ") + + (string("Cannot compare amounts with different commodities: ") + commodity().symbol() + " and " + amt.commodity().symbol()); if (quantity->prec == amt.quantity->prec) { @@ -982,7 +989,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, std::free(p); } else { - std::list<std::string> strs; + std::list<string> strs; char buf[4]; for (int powers = 0; true; powers += 3) { @@ -1001,7 +1008,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, bool printed = false; - for (std::list<std::string>::reverse_iterator i = strs.rbegin(); + for (std::list<string>::reverse_iterator i = strs.rbegin(); i != strs.rend(); i++) { if (printed) { @@ -1023,20 +1030,20 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, final << p; std::free(p); - const std::string& str(final.str()); + const string& str(final.str()); int i, len = str.length(); const char * q = str.c_str(); for (i = len; i > 0; i--) if (q[i - 1] != '0') break; - std::string ender; + string ender; if (i == len) ender = str; else if (i < comm.precision()) - ender = std::string(str, 0, comm.precision()); + ender = string(str, 0, comm.precision()); else - ender = std::string(str, 0, i); + ender = string(str, 0, i); if (! ender.empty()) { out << ((comm.flags() & COMMODITY_STYLE_EUROPEAN) ? ',' : '.'); @@ -1073,7 +1080,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, return; } -static void parse_quantity(std::istream& in, std::string& value) +static void parse_quantity(std::istream& in, string& value) { char buf[256]; char c = peek_next_nonws(in); @@ -1114,7 +1121,7 @@ int invalid_chars[256] = { /* f0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -static void parse_commodity(std::istream& in, std::string& symbol) +static void parse_commodity(std::istream& in, string& symbol) { char buf[256]; char c = peek_next_nonws(in); @@ -1132,7 +1139,7 @@ static void parse_commodity(std::istream& in, std::string& symbol) } bool parse_annotations(std::istream& in, amount_t& price, - moment_t& date, std::string& tag) + moment_t& date, string& tag) { bool has_date = false; @@ -1209,12 +1216,12 @@ void amount_t::parse(std::istream& in, unsigned char flags) // [-]NUM[ ]SYM [@ AMOUNT] // SYM[ ][-]NUM [@ AMOUNT] - std::string symbol; - std::string quant; + string symbol; + string quant; amount_t tprice; moment_t tdate; bool had_date = false; - std::string tag; + string tag; unsigned int comm_flags = COMMODITY_STYLE_DEFAULTS; bool negative = false; @@ -1283,10 +1290,10 @@ void amount_t::parse(std::istream& in, unsigned char flags) // Determine the precision of the amount, based on the usage of // comma or period. - std::string::size_type last_comma = quant.rfind(','); - std::string::size_type last_period = quant.rfind('.'); + string::size_type last_comma = quant.rfind(','); + string::size_type last_period = quant.rfind('.'); - if (last_comma != std::string::npos && last_period != std::string::npos) { + if (last_comma != string::npos && last_period != string::npos) { comm_flags |= COMMODITY_STYLE_THOUSANDS; if (last_comma > last_period) { comm_flags |= COMMODITY_STYLE_EUROPEAN; @@ -1295,11 +1302,11 @@ void amount_t::parse(std::istream& in, unsigned char flags) quantity->prec = quant.length() - last_period - 1; } } - else if (last_comma != std::string::npos && + else if (last_comma != string::npos && commodity().flags() & COMMODITY_STYLE_EUROPEAN) { quantity->prec = quant.length() - last_comma - 1; } - else if (last_period != std::string::npos && + else if (last_period != string::npos && ! (commodity().flags() & COMMODITY_STYLE_EUROPEAN)) { quantity->prec = quant.length() - last_period - 1; } @@ -1321,7 +1328,7 @@ void amount_t::parse(std::istream& in, unsigned char flags) // Now we have the final number. Remove commas and periods, if // necessary. - if (last_comma != std::string::npos || last_period != std::string::npos) { + if (last_comma != string::npos || last_period != string::npos) { int len = quant.length(); char * buf = new char[len + 1]; const char * p = quant.c_str(); @@ -1355,8 +1362,8 @@ void amount_t::in_place_reduce() } } -void parse_conversion(const std::string& larger_str, - const std::string& smaller_str) +void parse_conversion(const string& larger_str, + const string& smaller_str) { amount_t larger, smaller; @@ -1553,7 +1560,7 @@ bool amount_t::valid() const void amount_t::annotate_commodity(const amount_t& tprice, const moment_t& tdate, - const std::string& tag) + const string& tag) { const commodity_t * this_base; annotated_commodity_t * this_ann = NULL; @@ -1676,7 +1683,7 @@ bool commodity_base_t::remove_price(const moment_t& date) return false; } -commodity_base_t * commodity_base_t::create(const std::string& symbol) +commodity_base_t * commodity_base_t::create(const string& symbol) { commodity_base_t * commodity = new commodity_base_t(symbol); @@ -1689,7 +1696,7 @@ commodity_base_t * commodity_base_t::create(const std::string& symbol) return commodity; } -bool commodity_t::needs_quotes(const std::string& symbol) +bool commodity_t::needs_quotes(const string& symbol) { for (const char * p = symbol.c_str(); *p; p++) if (std::isspace(*p) || std::isdigit(*p) || *p == '-' || *p == '.') @@ -1719,7 +1726,7 @@ bool commodity_t::valid() const return true; } -commodity_t * commodity_t::create(const std::string& symbol) +commodity_t * commodity_t::create(const string& symbol) { std::auto_ptr<commodity_t> commodity(new commodity_t); @@ -1753,7 +1760,7 @@ commodity_t * commodity_t::create(const std::string& symbol) return commodity.release(); } -commodity_t * commodity_t::find_or_create(const std::string& symbol) +commodity_t * commodity_t::find_or_create(const string& symbol) { DEBUG_PRINT("amounts.commodities", "Find-or-create commodity " << symbol); @@ -1763,7 +1770,7 @@ commodity_t * commodity_t::find_or_create(const std::string& symbol) return create(symbol); } -commodity_t * commodity_t::find(const std::string& symbol) +commodity_t * commodity_t::find(const string& symbol) { DEBUG_PRINT("amounts.commodities", "Find commodity " << symbol); @@ -1844,7 +1851,7 @@ void annotated_commodity_t::write_annotations(std::ostream& out, const amount_t& price, const moment_t& date, - const std::string& tag) + const string& tag) { if (price) out << " {" << price << '}'; @@ -1860,8 +1867,8 @@ commodity_t * annotated_commodity_t::create(const commodity_t& comm, const amount_t& price, const moment_t& date, - const std::string& tag, - const std::string& mapping_key) + const string& tag, + const string& mapping_key) { std::auto_ptr<annotated_commodity_t> commodity(new annotated_commodity_t); @@ -1898,10 +1905,10 @@ annotated_commodity_t::create(const commodity_t& comm, } namespace { - std::string make_qualified_name(const commodity_t& comm, + string make_qualified_name(const commodity_t& comm, const amount_t& price, const moment_t& date, - const std::string& tag) + const string& tag) { if (price < 0) throw new amount_error("A commodity's price may not be negative"); @@ -1927,9 +1934,9 @@ commodity_t * annotated_commodity_t::find_or_create(const commodity_t& comm, const amount_t& price, const moment_t& date, - const std::string& tag) + const string& tag) { - std::string name = make_qualified_name(comm, price, date, tag); + string name = make_qualified_name(comm, price, date, tag); commodity_t * ann_comm = commodity_t::find(name); if (ann_comm) { @@ -58,7 +58,6 @@ #include <exception> #include "times.h" -#include "debug.h" #include "error.h" namespace ledger { @@ -85,6 +84,9 @@ class amount_t public: class bigint_t; + static void initialize(); + static void shutdown(); + static bool keep_price; static bool keep_date; static bool keep_tag; @@ -114,8 +116,8 @@ class amount_t else commodity_ = NULL; } - amount_t(const std::string& val) : quantity(NULL) { - TRACE_CTOR("amount_t(const std::string&)"); + amount_t(const string& val) : quantity(NULL) { + TRACE_CTOR("amount_t(const string&)"); parse(val); } amount_t(const char * val) : quantity(NULL) { @@ -146,7 +148,7 @@ class amount_t } void annotate_commodity(const amount_t& price, const moment_t& date = moment_t(), - const std::string& tag = ""); + const string& tag = ""); amount_t strip_annotations(const bool _keep_price = keep_price, const bool _keep_date = keep_date, const bool _keep_tag = keep_tag) const; @@ -162,7 +164,7 @@ class amount_t // assignment operator amount_t& operator=(const amount_t& amt); - amount_t& operator=(const std::string& val); + amount_t& operator=(const string& val); amount_t& operator=(const char * val); amount_t& operator=(const long val); amount_t& operator=(const unsigned long val); @@ -263,16 +265,16 @@ class amount_t operator bool() const { return ! zero(); } - operator std::string() const { + operator string() const { return to_string(); } operator long() const; operator double() const; - std::string to_string() const; - std::string to_fullstring() const; - std::string quantity_string() const; + string to_string() const; + string to_fullstring() const; + string quantity_string() const; // comparisons between amounts int compare(const amount_t& amt) const; @@ -341,7 +343,7 @@ class amount_t bool valid() const; - static amount_t exact(const std::string& value); + static amount_t exact(const string& value); // This function is special, and exists only to support a custom // optimization in binary.cc (which offers a significant enough gain @@ -351,7 +353,7 @@ class amount_t char * item_pool_end); friend bool parse_annotations(std::istream& in, amount_t& price, - moment_t& date, std::string& tag); + moment_t& date, string& tag); // Streaming interface @@ -367,7 +369,7 @@ class amount_t void print(std::ostream& out, bool omit_commodity = false, bool full_precision = false) const; void parse(std::istream& in, unsigned char flags = 0); - void parse(const std::string& str, unsigned char flags = 0) { + void parse(const string& str, unsigned char flags = 0) { std::istringstream stream(str); parse(stream, flags); } @@ -383,25 +385,25 @@ class amount_t void read_quantity(char *& data); }; -inline amount_t amount_t::exact(const std::string& value) { +inline amount_t amount_t::exact(const string& value) { amount_t temp; temp.parse(value, AMOUNT_PARSE_NO_MIGRATE); return temp; } -inline std::string amount_t::to_string() const { +inline string amount_t::to_string() const { std::ostringstream bufstream; print(bufstream); return bufstream.str(); } -inline std::string amount_t::to_fullstring() const { +inline string amount_t::to_fullstring() const { std::ostringstream bufstream; print(bufstream, false, true); return bufstream.str(); } -inline std::string amount_t::quantity_string() const { +inline string amount_t::quantity_string() const { std::ostringstream bufstream; print(bufstream, true); return bufstream.str(); @@ -475,8 +477,8 @@ typedef std::pair<const moment_t, amount_t> history_pair; class commodity_base_t; -typedef std::map<const std::string, commodity_base_t *> base_commodities_map; -typedef std::pair<const std::string, commodity_base_t *> base_commodities_pair; +typedef std::map<const string, commodity_base_t *> base_commodities_map; +typedef std::pair<const string, commodity_base_t *> base_commodities_pair; class commodity_base_t { @@ -487,8 +489,8 @@ class commodity_base_t typedef unsigned long ident_t; ident_t ident; - std::string name; - std::string note; + string name; + string note; unsigned char precision; unsigned char flags; amount_t * smaller; @@ -496,24 +498,34 @@ class commodity_base_t commodity_base_t() : precision(0), flags(COMMODITY_STYLE_DEFAULTS), - smaller(NULL), larger(NULL), history(NULL) {} + smaller(NULL), larger(NULL), history(NULL) { + TRACE_CTOR("commodity_base_t()"); + } + + commodity_base_t(const commodity_base_t&) { + TRACE_CTOR("commodity_base_t(copy)"); + assert(0); + } - commodity_base_t(const std::string& _symbol, + commodity_base_t(const string& _symbol, unsigned int _precision = 0, unsigned int _flags = COMMODITY_STYLE_DEFAULTS) : 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)"); + } ~commodity_base_t() { + TRACE_DTOR("commodity_base_t"); if (history) delete history; if (smaller) delete smaller; if (larger) delete larger; } static base_commodities_map commodities; - static commodity_base_t * create(const std::string& symbol); + static commodity_base_t * create(const string& symbol); - std::string symbol; + string symbol; struct history_t { history_map prices; @@ -540,8 +552,8 @@ class commodity_base_t static updater_t * updater; }; -typedef std::map<const std::string, commodity_t *> commodities_map; -typedef std::pair<const std::string, commodity_t *> commodities_pair; +typedef std::map<const string, commodity_t *> commodities_map; +typedef std::pair<const string, commodity_t *> commodities_pair; typedef std::deque<commodity_t *> commodities_array; @@ -558,13 +570,13 @@ class commodity_t static commodity_t * null_commodity; static commodity_t * default_commodity; - static commodity_t * create(const std::string& symbol); - static commodity_t * find(const std::string& name); - static commodity_t * find_or_create(const std::string& symbol); + static commodity_t * create(const string& symbol); + static commodity_t * find(const string& name); + static commodity_t * find_or_create(const string& symbol); - static bool needs_quotes(const std::string& symbol); + static bool needs_quotes(const string& symbol); - static void make_alias(const std::string& symbol, + static void make_alias(const string& symbol, commodity_t * commodity); // These are specific to each commodity reference @@ -573,13 +585,18 @@ class commodity_t ident_t ident; commodity_base_t * base; - std::string qualified_symbol; + string qualified_symbol; bool annotated; public: explicit commodity_t() : base(NULL), annotated(false) { TRACE_CTOR("commodity_t()"); } + commodity_t(const commodity_t& o) + : ident(o.ident), base(o.base), + qualified_symbol(o.qualified_symbol), annotated(o.annotated) { + TRACE_CTOR("commodity_t(copy)"); + } virtual ~commodity_t() { TRACE_DTOR("commodity_t"); } @@ -596,10 +613,10 @@ class commodity_t return ! (*this == comm); } - std::string base_symbol() const { + string base_symbol() const { return base->symbol; } - std::string symbol() const { + string symbol() const { return qualified_symbol; } @@ -607,17 +624,17 @@ class commodity_t out << symbol(); } - std::string name() const { + string name() const { return base->name; } - void set_name(const std::string& arg) { + void set_name(const string& arg) { base->name = arg; } - std::string note() const { + string note() const { return base->note; } - void set_note(const std::string& arg) { + void set_note(const string& arg) { base->note = arg; } @@ -683,12 +700,15 @@ class annotated_commodity_t : public commodity_t amount_t price; moment_t date; - std::string tag; + string tag; explicit annotated_commodity_t() { TRACE_CTOR("annotated_commodity_t()"); annotated = true; } + virtual ~annotated_commodity_t() { + TRACE_DTOR("annotated_commodity_t"); + } virtual bool operator==(const commodity_t& comm) const; @@ -699,19 +719,19 @@ class annotated_commodity_t : public commodity_t static void write_annotations(std::ostream& out, const amount_t& price, const moment_t& date, - const std::string& tag); + const string& tag); private: static commodity_t * create(const commodity_t& comm, const amount_t& price, const moment_t& date, - const std::string& tag, - const std::string& mapping_key); + const string& tag, + const string& mapping_key); static commodity_t * find_or_create(const commodity_t& comm, const amount_t& price, const moment_t& date, - const std::string& tag); + const string& tag); friend class amount_t; }; @@ -737,13 +757,13 @@ inline commodity_t& amount_t::commodity() const { } -void parse_conversion(const std::string& larger_str, - const std::string& smaller_str); +void parse_conversion(const string& larger_str, + const string& smaller_str); class amount_error : public error { public: - amount_error(const std::string& _reason) throw() : error(_reason) {} + amount_error(const string& _reason) throw() : error(_reason) {} virtual ~amount_error() throw() {} }; @@ -874,7 +874,7 @@ class balance_pair_t return ((! cost || cost->realzero()) && quantity.realzero()); } - balance_pair_t in_place_abs() { + void in_place_abs() { quantity = quantity.abs(); if (cost) *cost = cost->abs(); @@ -49,7 +49,7 @@ void read_binary_bool(char *& data, bool& num) read_binary_guard(data, 0x2006); } -void read_binary_string(std::istream& in, std::string& str) +void read_binary_string(std::istream& in, string& str) { read_binary_guard(in, 0x3001); @@ -76,7 +76,7 @@ void read_binary_string(std::istream& in, std::string& str) read_binary_guard(in, 0x3002); } -void read_binary_string(char *& data, std::string& str) +void read_binary_string(char *& data, string& str) { read_binary_guard(data, 0x3001); @@ -85,11 +85,11 @@ void read_binary_string(char *& data, std::string& str) if (len == 0xff) { unsigned short slen; read_binary_number_nocheck(data, slen); - str = std::string(data, slen); + str = string(data, slen); data += slen; } else if (len) { - str = std::string(data, len); + str = string(data, len); data += len; } else { @@ -99,7 +99,7 @@ void read_binary_string(char *& data, std::string& str) read_binary_guard(data, 0x3002); } -void read_binary_string(char *& data, std::string * str) +void read_binary_string(char *& data, string * str) { read_binary_guard(data, 0x3001); @@ -108,15 +108,15 @@ void read_binary_string(char *& data, std::string * str) if (len == 0xff) { unsigned short slen; read_binary_number_nocheck(data, slen); - new(str) std::string(data, slen); + new(str) string(data, slen); data += slen; } else if (len) { - new(str) std::string(data, len); + new(str) string(data, len); data += len; } else { - new(str) std::string(""); + new(str) string(""); } read_binary_guard(data, 0x3002); @@ -152,7 +152,7 @@ inline void read_binary_mask(char *& data, mask_t *& mask) { bool exclude; read_binary_number(data, exclude); - std::string pattern; + string pattern; read_binary_string(data, pattern); mask = new mask_t(pattern); @@ -170,7 +170,7 @@ inline void read_binary_transaction(char *& data, transaction_t * xact) read_binary_amount(data, xact->amount); } else if (flag == 1) { - std::string expr; + string expr; read_binary_string(data, expr); xact->amount_expr = expr; @@ -244,7 +244,7 @@ inline void read_binary_auto_entry(char *& data, auto_entry_t * entry, bool ignore; read_binary_entry_base(data, entry, xact_pool, ignore); - std::string pred_str; + string pred_str; read_binary_string(data, &pred_str); entry->predicate.parse(pred_str); } @@ -397,7 +397,7 @@ account_t * read_binary_account(char *& data, journal_t * journal, unsigned int read_binary_journal(std::istream& in, journal_t * journal, account_t * master, - const std::string& original_file) + const string& original_file) { account_index = base_commodity_index = @@ -411,7 +411,7 @@ unsigned int read_binary_journal(std::istream& in, count = read_binary_number<unsigned short>(in); i < count; i++) { - std::string path = read_binary_string(in); + string path = read_binary_string(in); std::time_t old_mtime; read_binary_number(in, old_mtime); struct stat info; @@ -496,7 +496,7 @@ unsigned int read_binary_journal(std::istream& in, // expression passed to an option, we'll just override the // flags, but keep the commodity pointer intact. if (c == commodity_base_t::commodities.end()) - throw new error(std::string("Failed to read base commodity from cache: ") + + throw new error(string("Failed to read base commodity from cache: ") + commodity->symbol); (*c).second->name = commodity->name; @@ -520,7 +520,7 @@ unsigned int read_binary_journal(std::istream& in, for (commodity_t::ident_t i = 0; i < c_count; i++) { commodity_t * commodity; - std::string mapping_key; + string mapping_key; if (! read_binary_bool(data)) { commodity = read_binary_commodity(data); @@ -537,7 +537,7 @@ unsigned int read_binary_journal(std::istream& in, commodities_map::iterator c = commodity_t::commodities.find(mapping_key); if (c == commodity_t::commodities.end()) - throw new error(std::string("Failed to read commodity from cache: ") + + throw new error(string("Failed to read commodity from cache: ") + commodity->symbol()); *(commodities_next - 1) = (*c).second; @@ -611,7 +611,7 @@ bool binary_parser_t::test(std::istream& in) const unsigned int binary_parser_t::parse(std::istream& in, journal_t * journal, account_t * master, - const std::string * original_file) + const string * original_file) { #if 0 return read_binary_journal(in, journal, master, @@ -629,7 +629,7 @@ void write_binary_bool(std::ostream& out, bool num) write_binary_guard(out, 0x2006); } -void write_binary_string(std::ostream& out, const std::string& str) +void write_binary_string(std::ostream& out, const string& str) { write_binary_guard(out, 0x3001); @@ -6,6 +6,8 @@ #include "parser.h" #endif +#include "util.h" + #include <string> #include <iostream> @@ -20,7 +22,7 @@ class binary_parser_t : public parser_t virtual unsigned int parse(std::istream& in, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL); + const string * original_file = NULL); }; #endif @@ -173,18 +175,18 @@ inline T read_binary_long(char *& data) { return num; } -void read_binary_string(std::istream& in, std::string& str); -void read_binary_string(char *& data, std::string& str); -void read_binary_string(char *& data, std::string * str); +void read_binary_string(std::istream& in, string& str); +void read_binary_string(char *& data, string& str); +void read_binary_string(char *& data, string * str); -inline std::string read_binary_string(std::istream& in) { - std::string temp; +inline string read_binary_string(std::istream& in) { + string temp; read_binary_string(in, temp); return temp; } -inline std::string read_binary_string(char *& data) { - std::string temp; +inline string read_binary_string(char *& data) { + string temp; read_binary_string(data, temp); return temp; } @@ -245,7 +247,7 @@ void write_binary_long(std::ostream& out, T num) write_binary_guard(out, 0x2002); } -void write_binary_string(std::ostream& out, const std::string& str); +void write_binary_string(std::ostream& out, const string& str); @@ -1,4 +1,5 @@ #include "debug.h" +#include "error.h" #ifdef DEBUG_ENABLED @@ -94,12 +95,15 @@ void operator delete[](void * ptr, const std::nothrow_t&) throw() { std::ostream * _debug_stream = &std::cerr; bool _free_debug_stream = false; +boost::regex _debug_regex; +bool _set_debug_regex = false; bool _debug_active(const char * const cls) { - if (char * debug = std::getenv("DEBUG_CLASS")) { - return boost::regex_match(cls, boost::regex(debug)); + if (! _set_debug_regex) { + _debug_regex = std::getenv("DEBUG_CLASS"); + _set_debug_regex = true; } - return false; + return boost::regex_match(cls, _debug_regex); } static struct init_streams { @@ -125,11 +129,11 @@ static struct init_streams { #include <string> -void debug_assert(const std::string& reason, - const std::string& file, - unsigned long line) +void debug_assert(const ledger::string& reason, + const ledger::string& file, + unsigned long line) { - throw new fatal_assert(reason, new file_context(file, line)); + throw new ledger::fatal_assert(reason, new ledger::file_context(file, line)); } #endif @@ -11,29 +11,38 @@ #define DEBUG_LEVEL NO_SEATBELT #endif +#include "trace.h" + #if DEBUG_LEVEL >= RELEASE -#include "error.h" #ifdef assert #undef assert #endif + #if DEBUG_LEVEL >= BETA -void debug_assert(const std::string& reason, - const std::string& file, - unsigned long line); + +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 ////////////////////////////////////////////////////////////////////// @@ -99,8 +108,6 @@ bool _debug_active(const char * const cls); #define VALIDATE(x) #endif -#include "trace.h" - #if 0 void * operator new(std::size_t) throw (std::bad_alloc); void * operator new[](std::size_t) throw (std::bad_alloc); @@ -134,21 +141,25 @@ void operator delete[](void*, const std::nothrow_t&) throw(); #define assert(x) #define CONFIRM(x) +#ifndef TRACE_CTOR #define TRACE_CTOR(cls) #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) #define TRACE_DTOR(cls) #define TRACE(cat, msg) #define TRACE_PUSH(cat, msg) #define TRACE_POP(cat, msg) +#endif #elif DEBUG_LEVEL >= BETA @@ -6,8 +6,8 @@ namespace ledger { -void derive_command::operator()(value_t& result, - xml::xpath_t::scope_t * locals) +void derive_command::operator() + (value_t& result, xml::xpath_t::scope_t * locals) { #if 0 std::ostream& out = *get_ptr<std::ostream>(locals, 0); @@ -118,7 +118,7 @@ void derive_command::operator()(value_t& result, } else { while (i != args.end()) { - std::string& re_pat(*i++); + string& re_pat(*i++); account_t * acct = NULL; amount_t * amt = NULL; diff --git a/docs/sample.dat b/docs/sample.dat index 7010b2e5..4856a6e2 100644 --- a/docs/sample.dat +++ b/docs/sample.dat @@ -1,9 +1,9 @@ ;= acct =~ /^Expenses:Books/ ; (Liabilities:Taxes) -0.10 -~ Monthly - Assets:Bank:Checking $500.00 - Income:Salary +;~ Monthly +; Assets:Bank:Checking $500.00 +; Income:Salary 2004/05/01 * (22:15) Checking balance Assets:Bank:Checking $1,000.00 @@ -7,12 +7,16 @@ #include <sstream> #include <list> +#include "debug.h" + +namespace ledger { + class error_context { public: - std::string desc; + string desc; - error_context(const std::string& _desc) throw() : desc(_desc) {} + error_context(const string& _desc) throw() : desc(_desc) {} virtual ~error_context() throw() {} virtual void describe(std::ostream& out) const throw() { if (! desc.empty()) @@ -23,11 +27,11 @@ class error_context class file_context : public error_context { protected: - std::string file; + string file; unsigned long line; public: - file_context(const std::string& _file, unsigned long _line, - const std::string& _desc = "") throw() + file_context(const string& _file, unsigned long _line, + const string& _desc = "") throw() : error_context(_desc), file(_file), line(_line) {} virtual ~file_context() throw() {} @@ -41,11 +45,11 @@ class file_context : public error_context class line_context : public error_context { public: - std::string line; + string line; long pos; - line_context(const std::string& _line, long _pos, - const std::string& _desc = "") throw() + line_context(const string& _line, long _pos, + const string& _desc = "") throw() : error_context(_desc), line(_line), pos(_pos) {} virtual ~line_context() throw() {} @@ -65,11 +69,11 @@ class line_context : public error_context { class str_exception : public std::exception { protected: - std::string reason; + string reason; public: std::list<error_context *> context; - str_exception(const std::string& _reason, + str_exception(const string& _reason, error_context * ctxt = NULL) throw() : reason(_reason) { if (ctxt) @@ -84,7 +88,7 @@ class str_exception : public std::exception { } virtual void reveal_context(std::ostream& out, - const std::string& kind) const throw() { + const string& kind) const throw() { for (std::list<error_context *>::const_reverse_iterator i = context.rbegin(); i != context.rend(); @@ -103,22 +107,22 @@ class str_exception : public std::exception { class error : public str_exception { public: - error(const std::string& _reason, error_context * _ctxt = NULL) throw() + error(const string& _reason, error_context * _ctxt = NULL) throw() : str_exception(_reason, _ctxt) {} virtual ~error() throw() {} }; class fatal : public str_exception { public: - fatal(const std::string& _reason, error_context * _ctxt = NULL) throw() + fatal(const string& _reason, error_context * _ctxt = NULL) throw() : str_exception(_reason, _ctxt) {} virtual ~fatal() throw() {} }; class fatal_assert : public fatal { public: - fatal_assert(const std::string& _reason, error_context * _ctxt = NULL) throw() - : fatal(std::string("assertion failed '") + _reason + "'", _ctxt) {} + fatal_assert(const string& _reason, error_context * _ctxt = NULL) throw() + : fatal(string("assertion failed '") + _reason + "'", _ctxt) {} virtual ~fatal_assert() throw() {} }; @@ -126,16 +130,18 @@ inline void unexpected(char c, char wanted) { if ((unsigned char) c == 0xff) { if (wanted) - throw new error(std::string("Missing '") + wanted + "'"); + throw new error(string("Missing '") + wanted + "'"); else throw new error("Unexpected end of input"); } else { if (wanted) - throw new error(std::string("Invalid char '") + c + + throw new error(string("Invalid char '") + c + "' (wanted '" + wanted + "')"); else - throw new error(std::string("Invalid char '") + c + "'"); + throw new error(string("Invalid char '") + c + "'"); } } +} // namespace ledger + #endif // _ERROR_H @@ -11,7 +11,7 @@ namespace ledger { -void format_t::parse(const std::string& fmt) +void format_t::parse(const string& fmt) { element_t * current = NULL; @@ -56,7 +56,7 @@ void format_t::parse(const std::string& fmt) if (q != buf) { current->kind = element_t::TEXT; - current->chars = new std::string(buf, q); + current->chars = new string(buf, q); q = buf; current = new element_t; @@ -115,16 +115,16 @@ void format_t::parse(const std::string& fmt) p++; } if (*p != close) - throw new format_error(std::string("Missing '") + close + "'"); + throw new format_error(string("Missing '") + close + "'"); if (open == '{') { assert(! current->xpath); current->kind = element_t::XPATH; - current->xpath = new xml::xpath_t(std::string(b, p)); + current->xpath = new xml::xpath_t(string(b, p)); } else { assert(! current->format); current->kind = element_t::GROUP; - current->format = new format_t(std::string(b, p)); + current->format = new format_t(string(b, p)); } break; } @@ -132,18 +132,17 @@ void format_t::parse(const std::string& fmt) default: assert(! current->xpath); current->kind = element_t::XPATH; - current->xpath = new xml::xpath_t(std::string(p, p + 1)); + current->xpath = new xml::xpath_t(string(p, p + 1)); break; } } - END: if (q != buf) { current = new element_t; elements.push_back(current); current->kind = element_t::TEXT; - current->chars = new std::string(buf, q); + current->chars = new string(buf, q); } } @@ -161,6 +160,8 @@ void format_t::compile(xml::node_t * context) assert((*i)->format); (*i)->format->compile(context); break; + default: + break; } } @@ -175,7 +176,7 @@ int format_t::element_formatter_t::operator() } if (elem->min_width != -1 && elem->min_width > column) { - out_str << std::string(elem->min_width - column, ' '); + out_str << string(elem->min_width - column, ' '); column = elem->min_width; } return column; @@ -203,8 +204,8 @@ int format_t::element_formatter_t::operator() else assert(0); - std::string temp = out.str(); - for (std::string::const_iterator i = temp.begin(); + string temp = out.str(); + for (string::const_iterator i = temp.begin(); i != temp.end(); i++) if (*i == '\n' || *i == '\r') @@ -215,7 +216,7 @@ int format_t::element_formatter_t::operator() int virtual_width = column - start_column; if (elem->min_width != -1 && virtual_width < elem->min_width) { - out_str << temp << std::string(' ', elem->min_width - virtual_width); + out_str << temp << string(' ', elem->min_width - virtual_width); } else if (elem->max_width != -1 && virtual_width > elem->max_width) { temp.erase(temp.length() - (virtual_width - elem->max_width)); @@ -252,7 +253,7 @@ using namespace ledger; void export_format() { class_< format_t > ("Format") - .def(init<std::string>()) + .def(init<string>()) .def("parse", &format_t::parse) .def("format", &format_t::format) ; @@ -20,7 +20,7 @@ class format_t enum kind_t { UNKNOWN, TEXT, COLUMN, XPATH, GROUP } kind; union { - std::string * chars; + string * chars; xml::xpath_t * xpath; format_t * format; }; @@ -60,7 +60,7 @@ class format_t xml::node_t * context, int column) const; }; - std::string format_string; + string format_string; std::list<element_t *> elements; private: @@ -70,8 +70,8 @@ class format_t format_t() { TRACE_CTOR("format_t()"); } - format_t(const std::string& fmt) { - TRACE_CTOR("format_t(const std::string&)"); + format_t(const string& fmt) { + TRACE_CTOR("format_t(const string&)"); parse(fmt); } @@ -88,9 +88,9 @@ class format_t clear_elements(); } - void parse(const std::string& fmt); + void parse(const string& fmt); - void compile(const std::string& fmt, xml::node_t * context = NULL) { + void compile(const string& fmt, xml::node_t * context = NULL) { parse(fmt); compile(context); } @@ -107,7 +107,7 @@ class format_t class format_error : public error { public: - format_error(const std::string& reason, error_context * ctxt = NULL) throw() + format_error(const string& reason, error_context * ctxt = NULL) throw() : error(reason, ctxt) {} virtual ~format_error() throw() {} }; @@ -2,7 +2,7 @@ namespace ledger { -void startElement(void *userData, const char *name, const char **atts) +void startElement(void *userData, const char *name, const char ** /* attrs */) { gnucash_parser_t * parser = static_cast<gnucash_parser_t *>(userData); @@ -139,14 +139,14 @@ void endElement(void *userData, const char *name) parser->action = gnucash_parser_t::NO_ACTION; } -amount_t gnucash_parser_t::convert_number(const std::string& number, +amount_t gnucash_parser_t::convert_number(const string& number, int * precision) { const char * num = number.c_str(); if (char * p = std::strchr(num, '/')) { - std::string numer_str(num, p - num); - std::string denom_str(p + 1); + string numer_str(num, p - num); + string denom_str(p + 1); amount_t amt(numer_str); amount_t den(denom_str); @@ -171,15 +171,15 @@ void dataHandler(void *userData, const char *s, int len) switch (parser->action) { case gnucash_parser_t::ACCOUNT_NAME: - parser->curr_account->name = std::string(s, len); + parser->curr_account->name = string(s, len); break; case gnucash_parser_t::ACCOUNT_ID: - parser->curr_account_id = std::string(s, len); + parser->curr_account_id = string(s, len); break; case gnucash_parser_t::ACCOUNT_PARENT: { - accounts_map::iterator i = parser->accounts_by_id.find(std::string(s, len)); + accounts_map::iterator i = parser->accounts_by_id.find(string(s, len)); assert(i != parser->accounts_by_id.end()); parser->curr_account->parent = (*i).second; parser->curr_account->depth = parser->curr_account->parent->depth + 1; @@ -188,7 +188,7 @@ void dataHandler(void *userData, const char *s, int len) } case gnucash_parser_t::COMM_SYM: { - std::string symbol(s, len); + string symbol(s, len); if (symbol == "USD") symbol = "$"; parser->curr_comm = commodity_t::find_or_create(symbol); @@ -207,7 +207,7 @@ void dataHandler(void *userData, const char *s, int len) } case gnucash_parser_t::COMM_NAME: - parser->curr_comm->set_name(std::string(s, len)); + parser->curr_comm->set_name(string(s, len)); break; case gnucash_parser_t::COMM_PREC: @@ -215,15 +215,15 @@ void dataHandler(void *userData, const char *s, int len) break; case gnucash_parser_t::ENTRY_NUM: - parser->curr_entry->code = std::string(s, len); + parser->curr_entry->code = string(s, len); break; case gnucash_parser_t::ENTRY_DATE: - parser->curr_entry->_date = parse_datetime(std::string(s, len)); + parser->curr_entry->_date = parse_datetime(string(s, len)); break; case gnucash_parser_t::ENTRY_DESC: - parser->curr_entry->payee = std::string(s, len); + parser->curr_entry->payee = string(s, len); break; case gnucash_parser_t::XACT_STATE: @@ -238,7 +238,7 @@ void dataHandler(void *userData, const char *s, int len) case gnucash_parser_t::XACT_VALUE: { int precision; assert(parser->entry_comm); - parser->curr_value = parser->convert_number(std::string(s, len), &precision); + parser->curr_value = parser->convert_number(string(s, len), &precision); parser->curr_value.set_commodity(*parser->entry_comm); if (precision > parser->entry_comm->precision()) @@ -247,27 +247,27 @@ void dataHandler(void *userData, const char *s, int len) } case gnucash_parser_t::XACT_QUANTITY: - parser->curr_quant = parser->convert_number(std::string(s, len)); + parser->curr_quant = parser->convert_number(string(s, len)); break; case gnucash_parser_t::XACT_ACCOUNT: { transaction_t * xact = parser->curr_entry->transactions.back(); accounts_map::iterator i = - parser->accounts_by_id.find(std::string(s, len)); + parser->accounts_by_id.find(string(s, len)); if (i != parser->accounts_by_id.end()) { xact->account = (*i).second; } else { xact->account = parser->curr_journal->find_account("<Unknown>"); - parser->have_error = (std::string("Could not find account ") + - std::string(s, len)); + parser->have_error = (string("Could not find account ") + + string(s, len)); } break; } case gnucash_parser_t::XACT_NOTE: - parser->curr_entry->transactions.back()->note = std::string(s, len); + parser->curr_entry->transactions.back()->note = string(s, len); break; case gnucash_parser_t::NO_ACTION: @@ -294,7 +294,7 @@ bool gnucash_parser_t::test(std::istream& in) const unsigned int gnucash_parser_t::parse(std::istream& in, journal_t * journal, account_t * master, - const std::string * original_file) + const string * original_file) { char buf[BUFSIZ]; @@ -23,8 +23,8 @@ namespace ledger { struct gnucash_parser_t : public parser_t { - typedef std::map<const std::string, account_t *> accounts_map; - typedef std::pair<const std::string, account_t *> accounts_pair; + typedef std::map<const string, account_t *> accounts_map; + typedef std::pair<const string, account_t *> accounts_pair; typedef std::map<account_t *, commodity_t *> account_comm_map; typedef std::pair<account_t *, commodity_t *> account_comm_pair; @@ -32,7 +32,7 @@ struct gnucash_parser_t : public parser_t journal_t * curr_journal; account_t * master_account; account_t * curr_account; - std::string curr_account_id; + string curr_account_id; entry_t * curr_entry; commodity_t * entry_comm; commodity_t * curr_comm; @@ -42,12 +42,12 @@ struct gnucash_parser_t : public parser_t accounts_map accounts_by_id; account_comm_map account_comms; unsigned int count; - std::string have_error; + string have_error; std::istream * instreamp; unsigned int offset; XML_Parser parser; - std::string path; + string path; unsigned int src_idx; istream_pos_type beg_pos; unsigned long beg_line; @@ -80,9 +80,9 @@ struct gnucash_parser_t : public parser_t virtual unsigned int parse(std::istream& in, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL); + const string * original_file = NULL); - amount_t convert_number(const std::string& number, int * precision = NULL); + amount_t convert_number(const string& number, int * precision = NULL); }; } // namespace ledger @@ -12,7 +12,7 @@ namespace ledger { -const std::string version = PACKAGE_VERSION; +const string version = PACKAGE_VERSION; bool transaction_t::use_effective_date = false; @@ -351,7 +351,7 @@ void auto_entry_t::extend_entry(entry_base_t& entry, bool post) } account_t * account = (*t)->account; - std::string fullname = account->fullname(); + string fullname = account->fullname(); assert(! fullname.empty()); if (fullname == "$account" || fullname == "@account") account = (*i)->account; @@ -374,7 +374,7 @@ account_t::~account_t() delete (*i).second; } -account_t * account_t::find_account(const std::string& name, +account_t * account_t::find_account(const string& name, const bool auto_create) { accounts_map::const_iterator i = accounts.find(name); @@ -383,11 +383,11 @@ account_t * account_t::find_account(const std::string& name, char buf[256]; - std::string::size_type sep = name.find(':'); - assert(sep < 256|| sep == std::string::npos); + string::size_type sep = name.find(':'); + assert(sep < 256|| sep == string::npos); const char * first, * rest; - if (sep == std::string::npos) { + if (sep == string::npos) { first = name.c_str(); rest = NULL; } else { @@ -436,18 +436,18 @@ account_t * find_account_re_(account_t * account, const mask_t& regexp) return NULL; } -account_t * journal_t::find_account_re(const std::string& regexp) +account_t * journal_t::find_account_re(const string& regexp) { return find_account_re_(master, mask_t(regexp)); } -std::string account_t::fullname() const +string account_t::fullname() const { if (! _fullname.empty()) { return _fullname; } else { const account_t * first = this; - std::string fullname = name; + string fullname = name; while (first->parent) { first = first->parent; @@ -498,6 +498,9 @@ journal_t::~journal_t() assert(master); delete master; + if (document) + delete document; + // Don't bother unhooking each entry's transactions from the // accounts they refer to, because all accounts are about to // be deleted. @@ -600,9 +603,9 @@ bool journal_t::valid() const } void print_entry(std::ostream& out, const entry_base_t& entry_base, - const std::string& prefix) + const string& prefix) { - std::string print_format; + string print_format; if (dynamic_cast<const entry_t *>(&entry_base)) { print_format = (prefix + "%D %X%C%P\n" + @@ -644,11 +647,11 @@ void entry_context::describe(std::ostream& out) const throw() } xact_context::xact_context(const ledger::transaction_t& _xact, - const std::string& desc) throw() - : xact(_xact), file_context("", 0, desc) + const string& desc) throw() + : file_context("", 0, desc), xact(_xact) { const ledger::strings_list& sources(xact.entry->journal->sources); - int x = 0; + unsigned int x = 0; for (ledger::strings_list::const_iterator i = sources.begin(); i != sources.end(); i++, x++) @@ -787,12 +790,12 @@ void py_account_set_data(account_t& account, PyObject * obj) account.data = obj; } -account_t * py_find_account_1(journal_t& journal, const std::string& name) +account_t * py_find_account_1(journal_t& journal, const string& name) { return journal.find_account(name); } -account_t * py_find_account_2(journal_t& journal, const std::string& name, +account_t * py_find_account_2(journal_t& journal, const string& name, const bool auto_create) { return journal.find_account(name, auto_create); @@ -891,7 +894,7 @@ void export_journal() class_< transaction_t > ("Transaction") .def(init<optional<account_t *> >()) - .def(init<account_t *, amount_t, optional<unsigned int, const std::string&> >()) + .def(init<account_t *, amount_t, optional<unsigned int, const string&> >()) .def(self == self) .def(self != self) @@ -930,7 +933,7 @@ void export_journal() class_< account_t > ("Account", - init<optional<account_t *, std::string, std::string> >() + init<optional<account_t *, string, string> >() [with_custodian_and_ward<1, 2>()]) .def(self == self) .def(self != self) @@ -23,16 +23,16 @@ class transaction_t enum state_t { UNCLEARED, CLEARED, PENDING }; entry_t * entry; - moment_t _date; - moment_t _date_eff; + moment_t _date; + moment_t _date_eff; account_t * account; amount_t amount; - std::string amount_expr; + string amount_expr; amount_t * cost; - std::string cost_expr; + string cost_expr; state_t state; unsigned short flags; - std::string note; + string note; istream_pos_type beg_pos; unsigned long beg_line; istream_pos_type end_pos; @@ -51,12 +51,12 @@ class transaction_t transaction_t(account_t * _account, const amount_t& _amount, unsigned int _flags = TRANSACTION_NORMAL, - const std::string& _note = "") + const string& _note = "") : entry(NULL), account(_account), amount(_amount), cost(NULL), state(UNCLEARED), flags(_flags), note(_note), beg_pos(0), beg_line(0), end_pos(0), end_line(0), data(NULL) { - TRACE_CTOR("transaction_t(account_t *, const amount_t&, unsigned int, const std::string&)"); + TRACE_CTOR("transaction_t(account_t *, const amount_t&, unsigned int, const string&)"); } transaction_t(const transaction_t& xact) : entry(xact.entry), account(xact.account), amount(xact.amount), @@ -91,7 +91,7 @@ class xact_context : public file_context { const transaction_t& xact; xact_context(const transaction_t& _xact, - const std::string& desc = "") throw(); + const string& desc = "") throw(); virtual ~xact_context() throw() {} }; @@ -151,10 +151,10 @@ class entry_base_t class entry_t : public entry_base_t { public: - moment_t _date; - moment_t _date_eff; - std::string code; - std::string payee; + moment_t _date; + moment_t _date_eff; + string code; + string payee; mutable void * data; @@ -195,14 +195,14 @@ struct entry_finalizer_t { }; void print_entry(std::ostream& out, const entry_base_t& entry, - const std::string& prefix = ""); + const string& prefix = ""); class entry_context : public error_context { public: const entry_base_t& entry; entry_context(const entry_base_t& _entry, - const std::string& _desc = "") throw() + const string& _desc = "") throw() : error_context(_desc), entry(_entry) {} virtual ~entry_context() throw() {} @@ -211,7 +211,7 @@ class entry_context : public error_context { class balance_error : public error { public: - balance_error(const std::string& _reason, + balance_error(const string& _reason, error_context * _ctxt = NULL) throw() : error(_reason, _ctxt) {} virtual ~balance_error() throw() {} @@ -226,9 +226,9 @@ public: auto_entry_t() { TRACE_CTOR("auto_entry_t()"); } - auto_entry_t(const std::string& _predicate) + auto_entry_t(const string& _predicate) : predicate(_predicate) { - TRACE_CTOR("auto_entry_t(const std::string&)"); + TRACE_CTOR("auto_entry_t(const string&)"); } virtual ~auto_entry_t() { @@ -241,8 +241,6 @@ public: } }; -class journal_t; - struct auto_entry_finalizer_t : public entry_finalizer_t { journal_t * journal; auto_entry_finalizer_t(journal_t * _journal) : journal(_journal) {} @@ -254,14 +252,14 @@ class period_entry_t : public entry_base_t { public: interval_t period; - std::string period_string; + string period_string; period_entry_t() { TRACE_CTOR("period_entry_t()"); } - period_entry_t(const std::string& _period) + period_entry_t(const string& _period) : period(_period), period_string(_period) { - TRACE_CTOR("period_entry_t(const std::string&)"); + TRACE_CTOR("period_entry_t(const string&)"); } period_entry_t(const period_entry_t& e) : entry_base_t(e), period(e.period), period_string(e.period_string) { @@ -278,8 +276,8 @@ class period_entry_t : public entry_base_t }; -typedef std::map<const std::string, account_t *> accounts_map; -typedef std::pair<const std::string, account_t *> accounts_pair; +typedef std::map<const string, account_t *> accounts_map; +typedef std::pair<const string, account_t *> accounts_pair; class account_t { @@ -288,21 +286,21 @@ class account_t journal_t * journal; account_t * parent; - std::string name; - std::string note; + string name; + string note; unsigned short depth; accounts_map accounts; - mutable void * data; - mutable ident_t ident; - mutable std::string _fullname; + mutable void * data; + mutable ident_t ident; + mutable string _fullname; - account_t(account_t * _parent = NULL, - const std::string& _name = "", - const std::string& _note = "") + account_t(account_t * _parent = NULL, + const string& _name = "", + const string& _note = "") : parent(_parent), name(_name), note(_note), depth(parent ? parent->depth + 1 : 0), data(NULL), ident(0) { - TRACE_CTOR("account_t(account_t *, const std::string&, const std::string&)"); + TRACE_CTOR("account_t(account_t *, const string&, const string&)"); } ~account_t(); @@ -313,7 +311,7 @@ class account_t return ! (*this == account); } - std::string fullname() const; + string fullname() const; void add_account(account_t * acct) { accounts.insert(accounts_pair(acct->name, acct)); @@ -325,9 +323,9 @@ class account_t return n > 0; } - account_t * find_account(const std::string& name, bool auto_create = true); + account_t * find_account(const string& name, bool auto_create = true); - operator std::string() const { + operator string() const { return fullname(); } @@ -377,7 +375,7 @@ bool run_hooks(std::list<T>& list, Data& item, bool post) { typedef std::list<entry_t *> entries_list; typedef std::list<auto_entry_t *> auto_entries_list; typedef std::list<period_entry_t *> period_entries_list; -typedef std::list<std::string> strings_list; +typedef std::list<string> strings_list; class session_t; @@ -389,7 +387,7 @@ class journal_t account_t * basket; entries_list entries; strings_list sources; - std::string price_db; + string price_db; char * item_pool; char * item_pool_end; @@ -402,15 +400,13 @@ class journal_t auto_entries_list auto_entries; period_entries_list period_entries; - mutable void * data; mutable accounts_map accounts_cache; std::list<entry_finalizer_t *> entry_finalize_hooks; journal_t(session_t * _session) : session(_session), basket(NULL), - item_pool(NULL), item_pool_end(NULL), - document(NULL), data(NULL) { + item_pool(NULL), item_pool_end(NULL), document(NULL) { TRACE_CTOR("journal_t()"); master = new account_t(NULL, ""); master->journal = this; @@ -433,7 +429,7 @@ class journal_t acct->journal = NULL; } - account_t * find_account(const std::string& name, bool auto_create = true) { + account_t * find_account(const string& name, bool auto_create = true) { accounts_map::iterator c = accounts_cache.find(name); if (c != accounts_cache.end()) return (*c).second; @@ -443,7 +439,7 @@ class journal_t account->journal = this; return account; } - account_t * find_account_re(const std::string& regexp); + account_t * find_account_re(const string& regexp); bool add_entry(entry_t * entry); bool remove_entry(entry_t * entry); @@ -471,7 +467,7 @@ inline bool auto_entry_finalizer_t::operator()(entry_t& entry, bool post) { return true; } -extern const std::string version; +extern const string version; } // namespace ledger @@ -10,6 +10,7 @@ #include <cstring> #include "option.h" +#include "timing.h" #include "acconf.h" #ifdef HAVE_UNIX_PIPES @@ -43,7 +44,7 @@ static int read_and_report(report_t * report, int argc, char * argv[], // Handle the command-line arguments - std::list<std::string> args; + std::list<string> args; process_arguments(argc - 1, argv + 1, false, report, args); if (args.empty()) { @@ -68,7 +69,7 @@ static int read_and_report(report_t * report, int argc, char * argv[], process_environment(const_cast<const char **>(envp), "LEDGER_", report); const char * p = std::getenv("HOME"); - std::string home = p ? p : ""; + string home = p ? p : ""; if (session.init_file.empty()) session.init_file = home + "/.ledgerrc"; @@ -83,23 +84,23 @@ static int read_and_report(report_t * report, int argc, char * argv[], DEBUG_PRINT("ledger.session.cache", "2. use_cache = " << session.use_cache); - TRACE(main, std::string("Initialization file is ") + session.init_file); - TRACE(main, std::string("Price database is ") + session.price_db); - TRACE(main, std::string("Binary cache is ") + session.cache_file); - TRACE(main, std::string("Main journal is ") + session.data_file); + TRACE(main, string("Initialization file is ") + session.init_file); + TRACE(main, string("Price database is ") + session.price_db); + TRACE(main, string("Binary cache is ") + session.cache_file); + TRACE(main, string("Main journal is ") + session.data_file); - TRACE(main, std::string("Based on option settings, binary cache ") + + TRACE(main, string("Based on option settings, binary cache ") + (session.use_cache ? "WILL " : "will NOT ") + "be used"); // Read the command word and create a command object based on it - std::string verb = *arg++; + string verb = *arg++; - xml::xpath_t::functor_t * command = NULL; + std::auto_ptr<xml::xpath_t::functor_t> command; if (verb == "register" || verb == "reg" || verb == "r") { #if 1 - command = new register_command; + command.reset(new register_command); #else command = new format_command ("register", either_or(report->format_string, @@ -147,7 +148,7 @@ static int read_and_report(report_t * report, int argc, char * argv[], command = new emacs_command; #endif else if (verb == "xml") - command = new xml_command; + command.reset(new xml_command); else if (verb == "expr") ; else if (verb == "xpath") @@ -174,11 +175,14 @@ static int read_and_report(report_t * report, int argc, char * argv[], char buf[128]; std::strcpy(buf, "command_"); std::strcat(buf, verb.c_str()); + + // jww (2007-04-19): This is an error, since command is an + // auto_ptr! if (xml::xpath_t::op_t * def = report->lookup(buf)) - command = def->functor_obj(); + command.reset(def->functor_obj()); - if (! command) - throw new error(std::string("Unrecognized command '") + verb + "'"); + if (! command.get()) + throw new error(string("Unrecognized command '") + verb + "'"); } // Parse the initialization file, which can only be textual; then @@ -278,26 +282,11 @@ static int read_and_report(report_t * report, int argc, char * argv[], return 0; } - // Cleanup memory -- if this is a beta or development build. - -#if DEBUG_LEVEL >= BETA - { TRACE_PUSH(cleanup, "Cleaning up allocated memory"); - -#ifdef USE_BOOST_PYTHON - shutdown_ledger_for_python(); -#endif - - if (! report->output_file.empty()) - delete out; - - TRACE_POP(cleanup, "Finished cleaning"); } -#endif - // Create the an argument scope containing the report command's // arguments, and then invoke the command. - xml::xpath_t::scope_t * locals = - new xml::xpath_t::scope_t(report, xml::xpath_t::scope_t::ARGUMENT); + std::auto_ptr<xml::xpath_t::scope_t> locals + (new xml::xpath_t::scope_t(report, xml::xpath_t::scope_t::ARGUMENT)); locals->args = new value_t::sequence_t; locals->args.push_back(out); @@ -309,7 +298,7 @@ static int read_and_report(report_t * report, int argc, char * argv[], i++) locals->args.push_back(*i); } else { - std::string regexps[4]; + string regexps[4]; // Treat the remaining command-line arguments as regular // expressions, used for refining report results. @@ -337,38 +326,29 @@ static int read_and_report(report_t * report, int argc, char * argv[], if (! regexps[3].empty()) report->transforms.push_front (new remove_transform - (std::string("//entry[payee =~ /(") + regexps[3] + ")/]")); + (string("//entry[payee =~ /(") + regexps[3] + ")/]")); if (! regexps[2].empty()) report->transforms.push_front (new select_transform - (std::string("//entry[payee =~ /(") + regexps[2] + ")/]")); + (string("//entry[payee =~ /(") + regexps[2] + ")/]")); if (! regexps[1].empty()) report->transforms.push_front (new remove_transform - (std::string("//xact[account =~ /(") + regexps[1] + ")/]")); + (string("//xact[account =~ /(") + regexps[1] + ")/]")); if (! regexps[0].empty()) report->transforms.push_front (new select_transform - (std::string("//xact[account =~ /(") + regexps[0] + ")/]")); + (string("//xact[account =~ /(") + regexps[0] + ")/]")); #endif } - xml::document_t * xml_doc = new xml::document_t; - xml::journal_node_t * journal_node = new xml::journal_node_t(xml_doc, journal); - - xml_doc->set_top(journal_node); - - assert(xml_doc->top == journal_node); - assert(journal_node->document == xml_doc); - assert(journal_node->document->top == journal_node); - - report->apply_transforms(xml_doc); + report->apply_transforms(journal->document); value_t temp; - (*command)(temp, locals); + (*command)(temp, locals.get()); // Write out the binary cache, if need be @@ -384,6 +364,21 @@ static int read_and_report(report_t * report, int argc, char * argv[], TRACE_POP(binary_cache, "Finished writing"); } + // Cleanup memory -- if this is a beta or development build. + +#if DEBUG_LEVEL >= BETA + { TRACE_PUSH(cleanup, "Cleaning up allocated memory"); + +#ifdef USE_BOOST_PYTHON + shutdown_ledger_for_python(); +#endif + + if (! report->output_file.empty()) + delete out; + + TRACE_POP(cleanup, "Finished cleaning"); } +#endif + // If the user specified a pager, wait for it to exit now #ifdef HAVE_UNIX_PIPES @@ -403,6 +398,8 @@ static int read_and_report(report_t * report, int argc, char * argv[], int main(int argc, char * argv[], char * envp[]) { + int status = 1; + try { std::ios::sync_with_stdio(false); @@ -413,6 +410,8 @@ int main(int argc, char * argv[], char * envp[]) #endif TRACE_PUSH(main, "Ledger starting"); + ledger::amount_t::initialize(); + std::auto_ptr<ledger::session_t> session(new ledger::session_t); #if 0 @@ -428,25 +427,25 @@ int main(int argc, char * argv[], char * envp[]) session->register_parser(new qif_parser_t); session->register_parser(new textual_parser_t); +#if DEBUG_LEVEL >= BETA + DEBUG_IF("ledger.trace.memory") { + ledger::trace_mode = true; + } +#endif + std::auto_ptr<ledger::report_t> report(new ledger::report_t(session.get())); - int status = read_and_report(report.get(), argc, argv, envp); + status = read_and_report(report.get(), argc, argv, envp); if (! ledger::do_cleanup) { report.release(); session.release(); + ledger::xml::xpath_t::lookahead.clear(); + } else { + ledger::amount_t::shutdown(); } TRACE_POP(main, "Ledger done"); - -#if DEBUG_LEVEL >= BETA - DEBUG_IF("ledger.trace.memory") { - report_memory(std::cout); - } - ledger::tracing_active = false; -#endif - - return status; } catch (error * err) { std::cout.flush(); @@ -460,7 +459,6 @@ int main(int argc, char * argv[], char * envp[]) #if DEBUG_LEVEL >= BETA ledger::tracing_active = false; #endif - return 1; } catch (fatal * err) { std::cout.flush(); @@ -474,7 +472,6 @@ int main(int argc, char * argv[], char * envp[]) #if DEBUG_LEVEL >= BETA ledger::tracing_active = false; #endif - return 1; } catch (const std::exception& err) { std::cout.flush(); @@ -482,14 +479,22 @@ int main(int argc, char * argv[], char * envp[]) #if DEBUG_LEVEL >= BETA ledger::tracing_active = false; #endif - return 1; } - catch (int status) { + catch (int _status) { #if DEBUG_LEVEL >= BETA ledger::tracing_active = false; #endif - return status; + status = _status; } + +#if DEBUG_LEVEL >= BETA + DEBUG_IF("ledger.trace.memory") { + report_memory(std::cerr); + } + ledger::tracing_active = false; +#endif + + return status; } // main.cc ends here. @@ -4,7 +4,9 @@ #include <cstdlib> -mask_t::mask_t(const std::string& pat) : exclude(false) +namespace ledger { + +mask_t::mask_t(const string& pat) : exclude(false) { const char * p = pat.c_str(); @@ -22,3 +24,5 @@ mask_t::mask_t(const std::string& pat) : exclude(false) expr.assign(p); } + +} // namespace ledger @@ -8,24 +8,28 @@ #include <boost/regex.hpp> +namespace ledger { + class mask_t { public: bool exclude; boost::regex expr; - explicit mask_t(const std::string& pattern); + explicit mask_t(const string& pattern); mask_t(const mask_t& m) : exclude(m.exclude), expr(m.expr) {} - bool match(const std::string& str) const { + bool match(const string& str) const { return boost::regex_match(str, expr) && ! exclude; } }; class mask_error : public error { public: - mask_error(const std::string& _reason) throw() : error(_reason) {} + mask_error(const string& _reason) throw() : error(_reason) {} virtual ~mask_error() throw() {} }; +} // namespace ledger + #endif // _MASK_H @@ -9,11 +9,11 @@ namespace ledger { -typedef std::map<const std::string, account_t *> accounts_map; -typedef std::pair<const std::string, account_t *> accounts_pair; +typedef std::map<const string, account_t *> accounts_map; +typedef std::pair<const string, account_t *> accounts_pair; -typedef std::map<const std::string, commodity_t *> commodities_map; -typedef std::pair<const std::string, commodity_t *> commodities_pair; +typedef std::map<const string, commodity_t *> commodities_map; +typedef std::pair<const string, commodity_t *> commodities_pair; journal_t * curr_journal; accounts_map ofx_accounts; @@ -130,7 +130,7 @@ int ofx_proc_security_cb(struct OfxSecurityData data, void * security_data) if (! data.unique_id_valid) return -1; - std::string symbol; + string symbol; if (data.ticker_valid) symbol = data.ticker; else if (data.currency_valid) @@ -198,7 +198,7 @@ bool ofx_parser_t::test(std::istream& in) const unsigned int ofx_parser_t::parse(std::istream& in, journal_t * journal, account_t * master, - const std::string * original_file) + const string * original_file) { if (! original_file) return 0; @@ -13,7 +13,7 @@ class ofx_parser_t : public parser_t virtual unsigned int parse(std::istream& in, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL); + const string * original_file = NULL); }; } // namespace ledger @@ -15,15 +15,15 @@ #if 0 #ifdef USE_BOOST_PYTHON -static ledger::option_t * find_option(const std::string& name); +static ledger::option_t * find_option(const string& name); #endif #endif namespace ledger { namespace { - xml::xpath_t::functor_t * find_option(xml::xpath_t::scope_t * scope, - const std::string& name) + xml::xpath_t::op_t * find_option(xml::xpath_t::scope_t * scope, + const string& name) { char buf[128]; std::strcpy(buf, "option_"); @@ -36,13 +36,10 @@ namespace { } *p = '\0'; - if (xml::xpath_t::op_t * def = scope->lookup(buf)) - return def->functor_obj(); - else - return NULL; + return scope->lookup(buf); } - xml::xpath_t::functor_t * find_option(xml::xpath_t::scope_t * scope, + xml::xpath_t::op_t * find_option(xml::xpath_t::scope_t * scope, const char letter) { char buf[9]; @@ -50,49 +47,50 @@ namespace { buf[7] = letter; buf[8] = '\0'; - if (xml::xpath_t::op_t * def = scope->lookup(buf)) - return def->functor_obj(); - else - return NULL; + return scope->lookup(buf); } void process_option(xml::xpath_t::functor_t * opt, xml::xpath_t::scope_t * scope, const char * arg) { try { - xml::xpath_t::scope_t * args = NULL; + std::auto_ptr<xml::xpath_t::scope_t> args; if (arg) { - args = new xml::xpath_t::scope_t(scope, xml::xpath_t::scope_t::ARGUMENT); + args.reset(new xml::xpath_t::scope_t(scope, xml::xpath_t::scope_t::ARGUMENT)); args->args.set_string(arg); } value_t temp; - (*opt)(temp, args); + (*opt)(temp, args.get()); } catch (error * err) { #if 0 err->context.push_back (new error_context - (std::string("While parsing option '--") + opt->long_opt + + (string("While parsing option '--") + opt->long_opt + "'" + (opt->short_opt != '\0' ? - (std::string(" (-") + opt->short_opt + "):") : ":"))); + (string(" (-") + opt->short_opt + "):") : ":"))); #endif throw err; } } } -bool process_option(const std::string& name, xml::xpath_t::scope_t * scope, +bool process_option(const string& name, xml::xpath_t::scope_t * scope, const char * arg) { - if (xml::xpath_t::functor_t * opt = find_option(scope, name)) { - process_option(opt, scope, arg); - return true; + std::auto_ptr<xml::xpath_t::op_t> opt(find_option(scope, name)); + if (opt.get()) { + xml::xpath_t::functor_t * def = opt->functor_obj(); + if (def) { + process_option(def, scope, arg); + return true; + } } return false; } -void process_environment(const char ** envp, const std::string& tag, +void process_environment(const char ** envp, const string& tag, xml::xpath_t::scope_t * scope) { const char * tag_p = tag.c_str(); @@ -120,7 +118,7 @@ void process_environment(const char ** envp, const std::string& tag, catch (error * err) { err->context.push_back (new error_context - (std::string("While parsing environment variable option '") + + (string("While parsing environment variable option '") + *p + "':")); throw err; } @@ -130,7 +128,7 @@ void process_environment(const char ** envp, const std::string& tag, void process_arguments(int argc, char ** argv, const bool anywhere, xml::xpath_t::scope_t * scope, - std::list<std::string>& args) + std::list<string>& args) { for (char ** i = argv; *i; i++) { if ((*i)[0] != '-') { @@ -157,48 +155,63 @@ void process_arguments(int argc, char ** argv, const bool anywhere, value = p; } - xml::xpath_t::functor_t * opt = find_option(scope, name); - if (! opt) - throw new option_error(std::string("illegal option --") + name); + std::auto_ptr<xml::xpath_t::op_t> opt(find_option(scope, name)); + if (! opt.get()) + throw new option_error(string("illegal option --") + name); - if (opt->wants_args && value == NULL) { + xml::xpath_t::functor_t * def = opt->functor_obj(); + if (! def) + throw new option_error(string("illegal option --") + name); + + if (def->wants_args && value == NULL) { value = *++i; if (value == NULL) - throw new option_error(std::string("missing option argument for --") + + throw new option_error(string("missing option argument for --") + name); } - process_option(opt, scope, value); + process_option(def, scope, value); } else if ((*i)[1] == '\0') { - throw new option_error(std::string("illegal option -")); + throw new option_error(string("illegal option -")); } else { - std::list<xml::xpath_t::functor_t *> option_queue; + std::list<xml::xpath_t::op_t *> option_queue; int x = 1; for (char c = (*i)[x]; c != '\0'; x++, c = (*i)[x]) { - xml::xpath_t::functor_t * opt = find_option(scope, c); + xml::xpath_t::op_t * opt = find_option(scope, c); if (! opt) - throw new option_error(std::string("illegal option -") + c); + throw new option_error(string("illegal option -") + c); + + xml::xpath_t::functor_t * def = opt->functor_obj(); + if (! def) + throw new option_error(string("illegal option -") + c); + option_queue.push_back(opt); } - for (std::list<xml::xpath_t::functor_t *>::iterator + for (std::list<xml::xpath_t::op_t *>::iterator o = option_queue.begin(); o != option_queue.end(); o++) { char * value = NULL; - if ((*o)->wants_args) { + + xml::xpath_t::functor_t * def = (*o)->functor_obj(); + assert(def); + + if (def->wants_args) { value = *++i; if (value == NULL) - throw new option_error(std::string("missing option argument for -") + + throw new option_error(string("missing option argument for -") + #if 0 - (*o)->short_opt); + def->short_opt); #else '?'); #endif } - process_option(*o, scope, value); + process_option(def, scope, value); + + delete *o; } } @@ -224,7 +237,7 @@ struct py_option_t : public option_t PyObject * self; py_option_t(PyObject * self_, - const std::string& long_opt, + const string& long_opt, const bool wants_arg) : self(self_), option_t(long_opt, wants_arg) {} @@ -245,12 +258,12 @@ struct py_option_t : public option_t BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(option_select_overloads, py_option_t::select, 1, 2) -typedef std::map<const std::string, object> options_map; -typedef std::pair<const std::string, object> options_pair; +typedef std::map<const string, object> options_map; +typedef std::pair<const string, object> options_pair; options_map options; -static option_t * find_option(const std::string& name) +static option_t * find_option(const string& name) { options_map::const_iterator i = options.find(name); if (i != options.end()) @@ -267,7 +280,7 @@ void shutdown_option() void export_option() { class_< option_t, py_option_t, boost::noncopyable > - ("Option", init<const std::string&, bool>()) + ("Option", init<const string&, bool>()) .def_readonly("long_opt", &py_option_t::long_opt) .def_readonly("short_opt", &py_option_t::short_opt) .def_readonly("wants_arg", &py_option_t::wants_arg) @@ -11,19 +11,19 @@ namespace ledger { -bool process_option(const std::string& name, xml::xpath_t::scope_t * scope, +bool process_option(const string& name, xml::xpath_t::scope_t * scope, const char * arg = NULL); -void process_environment(const char ** envp, const std::string& tag, +void process_environment(const char ** envp, const string& tag, xml::xpath_t::scope_t * scope); void process_arguments(int argc, char ** argv, const bool anywhere, xml::xpath_t::scope_t * scope, - std::list<std::string>& args); + std::list<string>& args); class option_error : public error { public: - option_error(const std::string& reason) throw() : error(reason) {} + option_error(const string& reason) throw() : error(reason) {} virtual ~option_error() throw() {} }; @@ -21,7 +21,7 @@ struct py_parser_t : public parser_t virtual repitem_t * parse(std::istream& in, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL) { + const string * original_file = NULL) { return call_method<unsigned int>(self, "parse", in, journal, master, original_file); } @@ -21,12 +21,12 @@ class parser_t virtual unsigned int parse(std::istream& in, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL) = 0; + const string * original_file = NULL) = 0; }; class parse_error : public error { public: - parse_error(const std::string& _reason, + parse_error(const string& _reason, error_context * _ctxt = NULL) throw() : error(_reason, _ctxt) {} virtual ~parse_error() throw() {} diff --git a/py_amount.cc b/py_amount.cc index eb0a4dd4..6a6ca499 100644 --- a/py_amount.cc +++ b/py_amount.cc @@ -13,11 +13,11 @@ int py_amount_quantity(amount_t& amount) return std::atol(quant.str().c_str()); } -void py_parse_1(amount_t& amount, const std::string& str, +void py_parse_1(amount_t& amount, const string& str, unsigned char flags) { amount.parse(str, flags); } -void py_parse_2(amount_t& amount, const std::string& str) { +void py_parse_2(amount_t& amount, const string& str) { amount.parse(str); } @@ -42,7 +42,7 @@ struct commodity_updater_wrap : public commodity_base_t::updater_t } }; -commodity_t * py_find_commodity(const std::string& symbol) +commodity_t * py_find_commodity(const string& symbol) { return commodity_t::find(symbol); } @@ -50,7 +50,7 @@ struct python_run { object result; python_run(python_interpreter_t * intepreter, - const std::string& str, int input_mode) + const string& str, int input_mode) : result(handle<>(borrowed(PyRun_String(str.c_str(), input_mode, intepreter->nspace.ptr(), intepreter->nspace.ptr())))) {} @@ -68,14 +68,14 @@ python_interpreter_t::python_interpreter_t(xml::xpath_t::scope_t * parent) detail::init_module("ledger", &initialize_ledger_for_python); } -object python_interpreter_t::import(const std::string& str) +object python_interpreter_t::import(const string& str) { assert(Py_IsInitialized()); try { PyObject * mod = PyImport_Import(PyString_FromString(str.c_str())); if (! mod) - throw error(std::string("Failed to import Python module ") + str); + throw error(string("Failed to import Python module ") + str); object newmod(handle<>(borrowed(mod))); @@ -84,20 +84,20 @@ object python_interpreter_t::import(const std::string& str) dict m_nspace(handle<>(borrowed(PyModule_GetDict(mod)))); nspace.update(m_nspace); #else - nspace[std::string(PyModule_GetName(mod))] = newmod; + nspace[string(PyModule_GetName(mod))] = newmod; #endif return newmod; } catch (const error_already_set&) { PyErr_Print(); - throw error(std::string("Importing Python module ") + str); + throw error(string("Importing Python module ") + str); } } object python_interpreter_t::eval(std::istream& in, py_eval_mode_t mode) { bool first = true; - std::string buffer; + string buffer; buffer.reserve(4096); while (! in.eof()) { @@ -128,7 +128,7 @@ object python_interpreter_t::eval(std::istream& in, py_eval_mode_t mode) } } -object python_interpreter_t::eval(const std::string& str, py_eval_mode_t mode) +object python_interpreter_t::eval(const string& str, py_eval_mode_t mode) { try { int input_mode; @@ -170,7 +170,7 @@ void python_interpreter_t::functor_t::operator()(value_t& result, else if (PyObject * err = PyErr_Occurred()) { PyErr_Print(); throw new xml::xpath_t::calc_error - (std::string("While calling Python function '") + name() + "'"); + (string("While calling Python function '") + name() + "'"); } else { assert(0); } @@ -182,7 +182,7 @@ void python_interpreter_t::functor_t::operator()(value_t& result, catch (const error_already_set&) { PyErr_Print(); throw new xml::xpath_t::calc_error - (std::string("While calling Python function '") + name() + "'"); + (string("While calling Python function '") + name() + "'"); } } @@ -29,7 +29,7 @@ class python_interpreter_t : public xml::xpath_t::scope_t Py_Finalize(); } - object import(const std::string& name); + object import(const string& name); enum py_eval_mode_t { PY_EVAL_EXPR, @@ -38,9 +38,9 @@ class python_interpreter_t : public xml::xpath_t::scope_t }; object eval(std::istream& in, py_eval_mode_t mode = PY_EVAL_EXPR); - object eval(const std::string& str, py_eval_mode_t mode = PY_EVAL_EXPR); + object eval(const string& str, py_eval_mode_t mode = PY_EVAL_EXPR); object eval(const char * c_str, py_eval_mode_t mode = PY_EVAL_EXPR) { - std::string str(c_str); + string str(c_str); return eval(str, mode); } @@ -48,18 +48,18 @@ class python_interpreter_t : public xml::xpath_t::scope_t protected: object func; public: - functor_t(const std::string& name, object _func) + functor_t(const string& name, object _func) : xml::xpath_t::functor_t(name), func(_func) {} virtual void operator()(value_t& result, xml::xpath_t::scope_t * locals); }; - virtual void define(const std::string& name, xml::xpath_t::op_t * def) { + virtual void define(const string& name, xml::xpath_t::op_t * def) { // Pass any definitions up to our parent parent->define(name, def); } - virtual xml::xpath_t::op_t * lookup(const std::string& name) { + virtual xml::xpath_t::op_t * lookup(const string& name) { object func = eval(name); if (! func) return parent ? parent->lookup(name) : NULL; @@ -11,7 +11,7 @@ namespace ledger { #define MAX_LINE 1024 static char line[MAX_LINE + 1]; -static std::string path; +static string path; static unsigned int src_idx; static unsigned int linenum; @@ -40,7 +40,7 @@ bool qif_parser_t::test(std::istream& in) const unsigned int qif_parser_t::parse(std::istream& in, journal_t * journal, account_t * master, - const std::string *) + const string *) { std::auto_ptr<entry_t> entry; std::auto_ptr<amount_t> amount; @@ -95,7 +95,7 @@ unsigned int qif_parser_t::parse(std::istream& in, std::strcmp(line, "Type:Cat") == 0 || std::strcmp(line, "Type:Class") == 0 || std::strcmp(line, "Type:Memorized") == 0) - throw new parse_error(std::string("QIF files of type ") + line + + throw new parse_error(string("QIF files of type ") + line + " are not supported."); break; @@ -13,7 +13,7 @@ class qif_parser_t : public parser_t virtual unsigned int parse(std::istream& in, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL); + const string * original_file = NULL); }; } // namespace ledger @@ -32,8 +32,6 @@ void quotes_by_script::operator()(commodity_base_t& commodity, (price && moment > date && (moment - date) <= pricing_leeway)) return; - using namespace std; - DEBUG_PRINT_("downloading quote for symbol " << commodity.symbol); char buf[256]; @@ -65,9 +63,10 @@ void quotes_by_script::operator()(commodity_base_t& commodity, if (price && ! price_db.empty()) { #if defined(__GNUG__) && __GNUG__ < 3 - ofstream database(price_db.c_str(), ios::out | ios::app); + std::ofstream database(price_db.c_str(), ios::out | ios::app); #else - ofstream database(price_db.c_str(), ios_base::out | ios_base::app); + std::ofstream database(price_db.c_str(), + std::ios_base::out | std::ios_base::app); #endif #if 0 // jww (2007-04-18): Need to convert to local time and print @@ -77,7 +76,7 @@ void quotes_by_script::operator()(commodity_base_t& commodity, #endif } } else { - throw new error(std::string("Failed to download price for '") + + throw new error(string("Failed to download price for '") + commodity.symbol + "' (command: \"getquote " + commodity.symbol + "\")"); } @@ -7,12 +7,12 @@ namespace ledger { class quotes_by_script : public commodity_base_t::updater_t { - std::string price_db; + string price_db; time_duration pricing_leeway; bool& cache_dirty; public: - quotes_by_script(std::string _price_db, + quotes_by_script(string _price_db, time_duration _pricing_leeway, bool& _cache_dirty) : price_db(_price_db), pricing_leeway(_pricing_leeway), @@ -6,6 +6,7 @@ namespace ledger { report_t::~report_t() { + TRACE_DTOR("report_t"); for (std::list<transform_t *>::const_iterator i = transforms.begin(); i != transforms.end(); i++) @@ -25,7 +26,7 @@ void report_t::abbrev(value_t& result, xml::xpath_t::scope_t * locals) if (locals->args.size() < 2) throw new error("usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])"); - std::string str = locals->args[0].to_string(); + string str = locals->args[0].to_string(); long wid = locals->args[1]; elision_style_t style = session->elision_style; @@ -39,14 +40,14 @@ void report_t::abbrev(value_t& result, xml::xpath_t::scope_t * locals) result.set_string(abbreviate(str, wid, style, true, (int)abbrev_len)); } -void report_t::ftime(value_t& result, xml::xpath_t::scope_t * locals) +void report_t::ftime(value_t&, xml::xpath_t::scope_t * locals) { if (locals->args.size() < 1) throw new error("usage: ftime(DATE [, DATE_FORMAT])"); moment_t date = locals->args[0].to_datetime(); - std::string date_format; + string date_format; if (locals->args.size() == 2) date_format = locals->args[1].to_string(); #if 0 @@ -58,7 +59,7 @@ void report_t::ftime(value_t& result, xml::xpath_t::scope_t * locals) #endif } -bool report_t::resolve(const std::string& name, value_t& result, +bool report_t::resolve(const string& name, value_t& result, xml::xpath_t::scope_t * locals) { const char * p = name.c_str(); @@ -81,7 +82,7 @@ bool report_t::resolve(const std::string& name, value_t& result, return xml::xpath_t::scope_t::resolve(name, result, locals); } -xml::xpath_t::op_t * report_t::lookup(const std::string& name) +xml::xpath_t::op_t * report_t::lookup(const string& name) { const char * p = name.c_str(); switch (*p) { @@ -9,21 +9,21 @@ namespace ledger { -typedef std::list<std::string> strings_list; +typedef std::list<string> strings_list; class report_t : public xml::xpath_t::scope_t { public: - std::string output_file; - std::string format_string; - std::string amount_expr; - std::string total_expr; - std::string date_output_format; + string output_file; + string format_string; + string amount_expr; + string total_expr; + string date_output_format; unsigned long budget_flags; - std::string account; - std::string pager; + string account; + string pager; bool show_totals; bool raw_mode; @@ -40,6 +40,7 @@ class report_t : public xml::xpath_t::scope_t session(_session), last_transform(NULL) { + TRACE_CTOR("report_t(session_t *)"); eval("t=total,TOT=0,T()=(TOT=TOT+t,TOT)"); } @@ -58,7 +59,7 @@ class report_t : public xml::xpath_t::scope_t // Config options // - void eval(const std::string& expr) { + void eval(const string& expr) { xml::xpath_t(expr).compile((xml::document_t *)NULL, this); } void option_eval(value_t&, xml::xpath_t::scope_t * locals) { @@ -66,10 +67,10 @@ class report_t : public xml::xpath_t::scope_t } void option_amount(value_t&, xml::xpath_t::scope_t * locals) { - eval(std::string("t=") + locals->args[0].to_string()); + eval(string("t=") + locals->args[0].to_string()); } void option_total(value_t&, xml::xpath_t::scope_t * locals) { - eval(std::string("T()=") + locals->args[0].to_string()); + eval(string("T()=") + locals->args[0].to_string()); } void option_format(value_t&, xml::xpath_t::scope_t * locals) { @@ -96,7 +97,7 @@ class report_t : public xml::xpath_t::scope_t transforms.push_back(new select_transform(locals->args[0].to_string())); } void option_limit(value_t&, xml::xpath_t::scope_t * locals) { - std::string expr = (std::string("//xact[") + + string expr = (string("//xact[") + locals->args[0].to_string() + "]"); transforms.push_back(new select_transform(expr)); } @@ -130,12 +131,12 @@ class report_t : public xml::xpath_t::scope_t // Scope members // - virtual bool resolve(const std::string& name, value_t& result, + virtual bool resolve(const string& name, value_t& result, xml::xpath_t::scope_t * locals); - virtual xml::xpath_t::op_t * lookup(const std::string& name); + virtual xml::xpath_t::op_t * lookup(const string& name); }; -std::string abbrev(const std::string& str, unsigned int width, +string abbrev(const string& str, unsigned int width, const bool is_account); } // namespace ledger @@ -1,4 +1,6 @@ #include "session.h" +#include "debug.h" +#include "timing.h" #include <fstream> @@ -7,15 +9,11 @@ namespace ledger { unsigned int session_t::read_journal(std::istream& in, journal_t * journal, account_t * master, - const std::string * original_file) + const string * original_file) { if (! master) master = journal->master; -#if 0 - journal->data = repitem_t::wrap(journal); -#endif - for (std::list<parser_t *>::iterator i = parsers.begin(); i != parsers.end(); i++) @@ -25,15 +23,15 @@ unsigned int session_t::read_journal(std::istream& in, return 0; } -unsigned int session_t::read_journal(const std::string& path, +unsigned int session_t::read_journal(const string& path, journal_t * journal, account_t * master, - const std::string * original_file) + const string * original_file) { journal->sources.push_back(path); if (access(path.c_str(), R_OK) == -1) - throw new error(std::string("Cannot read file '") + path + "'"); + throw new error(string("Cannot read file '") + path + "'"); if (! original_file) original_file = &path; @@ -48,20 +46,20 @@ void session_t::read_init() return; if (access(init_file.c_str(), R_OK) == -1) - throw new error(std::string("Cannot read init file '") + init_file + "'"); + throw new error(string("Cannot read init file '") + init_file + "'"); std::ifstream init(init_file.c_str()); // jww (2006-09-15): Read initialization options here! } -journal_t * session_t::read_data(const std::string& master_account) +journal_t * session_t::read_data(const string& master_account) { TRACE_PUSH(parser, "Parsing journal file"); journal_t * journal = new_journal(); journal->document = new xml::document_t; - journal->document->top = xml::wrap_node(journal->document, journal); + journal->document->set_top(xml::wrap_node(journal->document, journal)); unsigned int entry_count = 0; @@ -76,7 +74,7 @@ journal_t * session_t::read_data(const std::string& master_account) if (access(cache_file.c_str(), R_OK) != -1) { std::ifstream stream(cache_file.c_str()); - std::string price_db_orig = journal->price_db; + string price_db_orig = journal->price_db; journal->price_db = price_db; entry_count += read_journal(stream, journal, NULL, &data_file); @@ -129,7 +127,7 @@ journal_t * session_t::read_data(const std::string& master_account) return journal; } -bool session_t::resolve(const std::string& name, value_t& result, +bool session_t::resolve(const string& name, value_t& result, xml::xpath_t::scope_t * locals) { const char * p = name.c_str(); @@ -166,7 +164,7 @@ bool session_t::resolve(const std::string& name, value_t& result, return xml::xpath_t::scope_t::resolve(name, result, locals); } -xml::xpath_t::op_t * session_t::lookup(const std::string& name) +xml::xpath_t::op_t * session_t::lookup(const string& name) { const char * p = name.c_str(); switch (*p) { @@ -11,22 +11,22 @@ namespace ledger { class session_t : public xml::xpath_t::scope_t { public: - std::string init_file; - std::string data_file; - std::string cache_file; - std::string price_db; - - std::string register_format; - std::string wide_register_format; - std::string print_format; - std::string balance_format; - std::string equity_format; - std::string plot_amount_format; - std::string plot_total_format; - std::string write_hdr_format; - std::string write_xact_format; - std::string prices_format; - std::string pricesdb_format; + string init_file; + string data_file; + string cache_file; + string price_db; + + string register_format; + string wide_register_format; + string print_format; + string balance_format; + string equity_format; + string plot_amount_format; + string plot_total_format; + string write_hdr_format; + string write_xact_format; + string prices_format; + string pricesdb_format; unsigned long pricing_leeway; @@ -67,6 +67,7 @@ class session_t : public xml::xpath_t::scope_t balance_format ("%(/%(//%20t %{\" \" * rdepth}%{rname}\n))--------------------\n%20t\n"), equity_format + ("%((/)%{ftime(now, date_format)} %-.20{\"Opening Balance\"}\n%((.//account[value != 0]) %-34{fullname} %12{value}\n)\n)"), plot_amount_format ("%D %(@S(@t))\n"), @@ -96,9 +97,13 @@ class session_t : public xml::xpath_t::scope_t abbrev_length(2), ansi_codes(false), - ansi_invert(false) {} + ansi_invert(false) { + TRACE_CTOR("session_t(xml::xpath_t::scope_t *)"); + } virtual ~session_t() { + TRACE_DTOR("session_t"); + for (std::list<journal_t *>::iterator i = journals.begin(); i != journals.end(); i++) @@ -123,16 +128,16 @@ class session_t : public xml::xpath_t::scope_t unsigned int read_journal(std::istream& in, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL); + const string * original_file = NULL); - unsigned int read_journal(const std::string& path, + unsigned int read_journal(const string& path, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL); + const string * original_file = NULL); void read_init(); - journal_t * read_data(const std::string& master_account = ""); + journal_t * read_data(const string& master_account = ""); void register_parser(parser_t * parser) { parsers.push_back(parser); @@ -154,9 +159,9 @@ class session_t : public xml::xpath_t::scope_t // Scope members // - virtual bool resolve(const std::string& name, value_t& result, + virtual bool resolve(const string& name, value_t& result, xml::xpath_t::scope_t * locals = NULL); - virtual xml::xpath_t::op_t * lookup(const std::string& name); + virtual xml::xpath_t::op_t * lookup(const string& name); // // Option handlers diff --git a/tests/corelib/numerics/BasicAmount.cc b/tests/corelib/numerics/BasicAmount.cc index 972dcbcc..143b8c38 100644 --- a/tests/corelib/numerics/BasicAmount.cc +++ b/tests/corelib/numerics/BasicAmount.cc @@ -5,8 +5,13 @@ using namespace ledger; CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BasicAmountTestCase, "numerics"); -void BasicAmountTestCase::setUp() {} -void BasicAmountTestCase::tearDown() {} +void BasicAmountTestCase::setUp() { + amount_t::initialize(); +} +void BasicAmountTestCase::tearDown() { + amount_t::shutdown(); + assert(live_count.size() == 0); +} void BasicAmountTestCase::testConstructors() { @@ -89,8 +94,8 @@ void BasicAmountTestCase::testAssignment() amount_t x3 = 123.456; amount_t x5 = "123456"; amount_t x6 = "123.456"; - amount_t x7 = std::string("123456"); - amount_t x8 = std::string("123.456"); + amount_t x7 = string("123456"); + amount_t x8 = string("123.456"); amount_t x9 = x3; amount_t x10 = amount_t(x6); @@ -416,8 +421,8 @@ void BasicAmountTestCase::testIntegerConversion() assertEqual(true, bool(x1)); assertEqual(123456L, long(x1)); assertEqual(123456.0, double(x1)); - assertEqual(std::string("123456"), x1.to_string()); - assertEqual(std::string("123456"), x1.quantity_string()); + assertEqual(string("123456"), x1.to_string()); + assertEqual(string("123456"), x1.quantity_string()); CPPUNIT_ASSERT(x1.valid()); } @@ -429,8 +434,8 @@ void BasicAmountTestCase::testFractionalConversion() assertEqual(true, bool(x1)); assertEqual(1234L, long(x1)); assertEqual(1234.56, double(x1)); - assertEqual(std::string("1234.56"), x1.to_string()); - assertEqual(std::string("1234.56"), x1.quantity_string()); + assertEqual(string("1234.56"), x1.to_string()); + assertEqual(string("1234.56"), x1.quantity_string()); CPPUNIT_ASSERT(x1.valid()); } diff --git a/tests/corelib/numerics/Commodity.cc b/tests/corelib/numerics/Commodity.cc index a2dbb58d..f74f671c 100644 --- a/tests/corelib/numerics/Commodity.cc +++ b/tests/corelib/numerics/Commodity.cc @@ -5,8 +5,12 @@ using namespace ledger; CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CommodityTestCase, "numerics"); -void CommodityTestCase::setUp() {} -void CommodityTestCase::tearDown() {} +void CommodityTestCase::setUp() { + amount_t::initialize(); +} +void CommodityTestCase::tearDown() { + amount_t::shutdown(); +} void CommodityTestCase::testPriceHistory() { diff --git a/tests/corelib/numerics/CommodityAmount.cc b/tests/corelib/numerics/CommodityAmount.cc index 860e7b1c..9e27dba3 100644 --- a/tests/corelib/numerics/CommodityAmount.cc +++ b/tests/corelib/numerics/CommodityAmount.cc @@ -9,6 +9,8 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CommodityAmountTestCase, "numerics"); void CommodityAmountTestCase::setUp() { + amount_t::initialize(); + // Cause the display precision for dollars to be initialized to 2. amount_t x1("$1.00"); assertTrue(x1); @@ -18,6 +20,7 @@ void CommodityAmountTestCase::setUp() void CommodityAmountTestCase::tearDown() { amount_t::full_strings = false; + amount_t::shutdown(); } void CommodityAmountTestCase::testConstructors() @@ -44,16 +47,16 @@ void CommodityAmountTestCase::testConstructors() assertEqual(amount_t("123.45€"), x9); assertEqual(amount_t("-123.45€"), x10); - assertEqual(std::string("$123.45"), x1.to_string()); - assertEqual(std::string("$-123.45"), x2.to_string()); - assertEqual(std::string("$-123.45"), x3.to_string()); - assertEqual(std::string("DM 123.45"), x4.to_string()); - assertEqual(std::string("DM -123.45"), x5.to_string()); - assertEqual(std::string("DM -123.45"), x6.to_string()); - assertEqual(std::string("123.45 euro"), x7.to_string()); - assertEqual(std::string("-123.45 euro"), x8.to_string()); - assertEqual(std::string("123.45€"), x9.to_string()); - assertEqual(std::string("-123.45€"), x10.to_string()); + assertEqual(string("$123.45"), x1.to_string()); + assertEqual(string("$-123.45"), x2.to_string()); + assertEqual(string("$-123.45"), x3.to_string()); + assertEqual(string("DM 123.45"), x4.to_string()); + assertEqual(string("DM -123.45"), x5.to_string()); + assertEqual(string("DM -123.45"), x6.to_string()); + assertEqual(string("123.45 euro"), x7.to_string()); + assertEqual(string("-123.45 euro"), x8.to_string()); + assertEqual(string("123.45€"), x9.to_string()); + assertEqual(string("-123.45€"), x10.to_string()); assertValid(x1); assertValid(x2); @@ -95,16 +98,16 @@ void CommodityAmountTestCase::testNegation() assertEqual(amount_t("$123.45"), x2.negate()); assertEqual(amount_t("$123.45"), x3.negate()); - assertEqual(std::string("$-123.45"), (- x1).to_string()); - assertEqual(std::string("$123.45"), (- x2).to_string()); - assertEqual(std::string("$123.45"), (- x3).to_string()); - assertEqual(std::string("DM -123.45"), (- x4).to_string()); - assertEqual(std::string("DM 123.45"), (- x5).to_string()); - assertEqual(std::string("DM 123.45"), (- x6).to_string()); - assertEqual(std::string("-123.45 euro"), (- x7).to_string()); - assertEqual(std::string("123.45 euro"), (- x8).to_string()); - assertEqual(std::string("-123.45€"), (- x9).to_string()); - assertEqual(std::string("123.45€"), (- x10).to_string()); + assertEqual(string("$-123.45"), (- x1).to_string()); + assertEqual(string("$123.45"), (- x2).to_string()); + assertEqual(string("$123.45"), (- x3).to_string()); + assertEqual(string("DM -123.45"), (- x4).to_string()); + assertEqual(string("DM 123.45"), (- x5).to_string()); + assertEqual(string("DM 123.45"), (- x6).to_string()); + assertEqual(string("-123.45 euro"), (- x7).to_string()); + assertEqual(string("123.45 euro"), (- x8).to_string()); + assertEqual(string("-123.45€"), (- x9).to_string()); + assertEqual(string("123.45€"), (- x10).to_string()); assertEqual(amount_t("$-123.45"), x1.negate()); assertEqual(amount_t("$123.45"), x2.negate()); @@ -146,16 +149,16 @@ void CommodityAmountTestCase::testAssignment() assertEqual(amount_t("123.45€"), x9); assertEqual(amount_t("-123.45€"), x10); - assertEqual(std::string("$123.45"), x1.to_string()); - assertEqual(std::string("$-123.45"), x2.to_string()); - assertEqual(std::string("$-123.45"), x3.to_string()); - assertEqual(std::string("DM 123.45"), x4.to_string()); - assertEqual(std::string("DM -123.45"), x5.to_string()); - assertEqual(std::string("DM -123.45"), x6.to_string()); - assertEqual(std::string("123.45 euro"), x7.to_string()); - assertEqual(std::string("-123.45 euro"), x8.to_string()); - assertEqual(std::string("123.45€"), x9.to_string()); - assertEqual(std::string("-123.45€"), x10.to_string()); + assertEqual(string("$123.45"), x1.to_string()); + assertEqual(string("$-123.45"), x2.to_string()); + assertEqual(string("$-123.45"), x3.to_string()); + assertEqual(string("DM 123.45"), x4.to_string()); + assertEqual(string("DM -123.45"), x5.to_string()); + assertEqual(string("DM -123.45"), x6.to_string()); + assertEqual(string("123.45 euro"), x7.to_string()); + assertEqual(string("-123.45 euro"), x8.to_string()); + assertEqual(string("123.45€"), x9.to_string()); + assertEqual(string("-123.45€"), x10.to_string()); assertValid(x1); assertValid(x2); @@ -229,8 +232,8 @@ void CommodityAmountTestCase::testAddition() assertEqual(internalAmount("$246.906789"), x1 + x2); // Converting to string drops internal precision - assertEqual(std::string("$246.90"), (x1 + x1).to_string()); - assertEqual(std::string("$246.91"), (x1 + x2).to_string()); + assertEqual(string("$246.90"), (x1 + x1).to_string()); + assertEqual(string("$246.91"), (x1 + x2).to_string()); assertThrow(x1 + x0, amount_error *); assertThrow(x1 + x3, amount_error *); @@ -244,9 +247,9 @@ void CommodityAmountTestCase::testAddition() assertEqual(amount_t("246.90 euro"), x4 + x4); assertEqual(amount_t("246.90€"), x5 + x5); - assertEqual(std::string("DM 246.90"), (x3 + x3).to_string()); - assertEqual(std::string("246.90 euro"), (x4 + x4).to_string()); - assertEqual(std::string("246.90€"), (x5 + x5).to_string()); + assertEqual(string("DM 246.90"), (x3 + x3).to_string()); + assertEqual(string("246.90 euro"), (x4 + x4).to_string()); + assertEqual(string("246.90€"), (x5 + x5).to_string()); x1 += amount_t("$456.45"); assertEqual(amount_t("$579.90"), x1); @@ -287,8 +290,8 @@ void CommodityAmountTestCase::testSubtraction() // Converting to string drops internal precision. If an amount is // zero, it drops the commodity as well. - assertEqual(std::string("$0.00"), (x1 - x1).to_string()); - assertEqual(std::string("$-0.01"), (x1 - x2).to_string()); + assertEqual(string("$0.00"), (x1 - x1).to_string()); + assertEqual(string("$-0.01"), (x1 - x2).to_string()); assertThrow(x1 - x0, amount_error *); assertThrow(x1 - x3, amount_error *); @@ -308,15 +311,15 @@ void CommodityAmountTestCase::testSubtraction() assertEqual(amount_t("23.45€"), x5 - amount_t("100.00€")); assertEqual(amount_t("-23.45€"), amount_t("100.00€") - x5); - assertEqual(std::string("DM 0.00"), (x3 - x3).to_string()); - assertEqual(std::string("DM 23.45"), (x3 - amount_t("DM 100.00")).to_string()); - assertEqual(std::string("DM -23.45"), (amount_t("DM 100.00") - x3).to_string()); - assertEqual(std::string("0.00 euro"), (x4 - x4).to_string()); - assertEqual(std::string("23.45 euro"), (x4 - amount_t("100.00 euro")).to_string()); - assertEqual(std::string("-23.45 euro"), (amount_t("100.00 euro") - x4).to_string()); - assertEqual(std::string("0.00€"), (x5 - x5).to_string()); - assertEqual(std::string("23.45€"), (x5 - amount_t("100.00€")).to_string()); - assertEqual(std::string("-23.45€"), (amount_t("100.00€") - x5).to_string()); + assertEqual(string("DM 0.00"), (x3 - x3).to_string()); + assertEqual(string("DM 23.45"), (x3 - amount_t("DM 100.00")).to_string()); + assertEqual(string("DM -23.45"), (amount_t("DM 100.00") - x3).to_string()); + assertEqual(string("0.00 euro"), (x4 - x4).to_string()); + assertEqual(string("23.45 euro"), (x4 - amount_t("100.00 euro")).to_string()); + assertEqual(string("-23.45 euro"), (amount_t("100.00 euro") - x4).to_string()); + assertEqual(string("0.00€"), (x5 - x5).to_string()); + assertEqual(string("23.45€"), (x5 - amount_t("100.00€")).to_string()); + assertEqual(string("-23.45€"), (amount_t("100.00€") - x5).to_string()); x1 -= amount_t("$456.45"); assertEqual(amount_t("$-333.00"), x1); @@ -329,12 +332,12 @@ void CommodityAmountTestCase::testSubtraction() amount_t x8(internalAmount("$2354974984698.98459845984598")); assertEqual(internalAmount("$123454434148472090.138858329277476789"), x7 - x8); - assertEqual(std::string("$123454434148472090.138858329277476789"), (x7 - x8).to_string()); - assertEqual(std::string("$123454434148472090.14"), + assertEqual(string("$123454434148472090.138858329277476789"), (x7 - x8).to_string()); + assertEqual(string("$123454434148472090.14"), (amount_t("$1.00") * (x7 - x8)).to_string()); assertEqual(internalAmount("$-123454434148472090.138858329277476789"), x8 - x7); - assertEqual(std::string("$-123454434148472090.138858329277476789"), (x8 - x7).to_string()); - assertEqual(std::string("$-123454434148472090.14"), + assertEqual(string("$-123454434148472090.138858329277476789"), (x8 - x7).to_string()); + assertEqual(string("$-123454434148472090.14"), (amount_t("$1.00") * (x8 - x7)).to_string()); assertValid(x1); @@ -363,16 +366,16 @@ void CommodityAmountTestCase::testMultiplication() assertEqual(- x1, x1 * -1L); assertEqual(- x1, -1L * x1); assertEqual(internalAmount("$56198.124"), x1 * y1); - assertEqual(std::string("$56198.12"), (x1 * y1).to_string()); + assertEqual(string("$56198.12"), (x1 * y1).to_string()); assertEqual(internalAmount("$56198.124"), y1 * x1); - assertEqual(std::string("$56198.12"), (y1 * x1).to_string()); + assertEqual(string("$56198.12"), (y1 * x1).to_string()); // Internal amounts retain their precision, even when being // converted to strings assertEqual(internalAmount("$15199.99986168"), x1 * x2); assertEqual(internalAmount("$15199.99986168"), x2 * x1); - assertEqual(std::string("$15200.00"), (x1 * x2).to_string()); - assertEqual(std::string("$15199.99986168"), (x2 * x1).to_string()); + assertEqual(string("$15200.00"), (x1 * x2).to_string()); + assertEqual(string("$15199.99986168"), (x2 * x1).to_string()); assertThrow(x1 * x3, amount_error *); assertThrow(x1 * x4, amount_error *); @@ -380,13 +383,13 @@ void CommodityAmountTestCase::testMultiplication() x1 *= amount_t("123.12"); assertEqual(internalAmount("$15158.5344"), x1); - assertEqual(std::string("$15158.53"), x1.to_string()); + assertEqual(string("$15158.53"), x1.to_string()); x1 *= 123.12; assertEqual(internalAmount("$1866318.755328"), x1); - assertEqual(std::string("$1866318.76"), x1.to_string()); + assertEqual(string("$1866318.76"), x1.to_string()); x1 *= 123L; assertEqual(internalAmount("$229557206.905344"), x1); - assertEqual(std::string("$229557206.91"), x1.to_string()); + assertEqual(string("$229557206.91"), x1.to_string()); amount_t x7(internalAmount("$123456789123456789.123456789123456789")); @@ -417,16 +420,16 @@ void CommodityAmountTestCase::testDivision() assertEqual(- x1, x1 / -1L); assertEqual(internalAmount("$-0.00812216"), -1L / x1); assertEqual(internalAmount("$0.26973382"), x1 / y1); - assertEqual(std::string("$0.27"), (x1 / y1).to_string()); + assertEqual(string("$0.27"), (x1 / y1).to_string()); assertEqual(internalAmount("$3.70735867"), y1 / x1); - assertEqual(std::string("$3.71"), (y1 / x1).to_string()); + assertEqual(string("$3.71"), (y1 / x1).to_string()); // Internal amounts retain their precision, even when being // converted to strings assertEqual(internalAmount("$0.99727201"), x1 / x2); assertEqual(internalAmount("$1.00273545321637426901"), x2 / x1); - assertEqual(std::string("$1.00"), (x1 / x2).to_string()); - assertEqual(std::string("$1.00273545321637426901"), (x2 / x1).to_string()); + assertEqual(string("$1.00"), (x1 / x2).to_string()); + assertEqual(string("$1.00273545321637426901"), (x2 / x1).to_string()); assertThrow(x1 / x3, amount_error *); assertThrow(x1 / x4, amount_error *); @@ -434,13 +437,13 @@ void CommodityAmountTestCase::testDivision() x1 /= amount_t("123.12"); assertEqual(internalAmount("$1.00"), x1); - assertEqual(std::string("$1.00"), x1.to_string()); + assertEqual(string("$1.00"), x1.to_string()); x1 /= 123.12; assertEqual(internalAmount("$0.00812216"), x1); - assertEqual(std::string("$0.01"), x1.to_string()); + assertEqual(string("$0.01"), x1.to_string()); x1 /= 123L; assertEqual(internalAmount("$0.00006603"), x1); - assertEqual(std::string("$0.00"), x1.to_string()); + assertEqual(string("$0.00"), x1.to_string()); amount_t x6(internalAmount("$237235987235987.98723987235978")); amount_t x7(internalAmount("$123456789123456789.123456789123456789")); @@ -467,8 +470,8 @@ void CommodityAmountTestCase::testConversion() assertEqual(true, bool(x1)); assertEqual(1234L, long(x1)); assertEqual(1234.56, double(x1)); - assertEqual(std::string("$1234.56"), x1.to_string()); - assertEqual(std::string("1234.56"), x1.quantity_string()); + assertEqual(string("$1234.56"), x1.to_string()); + assertEqual(string("1234.56"), x1.quantity_string()); assertValid(x1); } @@ -520,9 +523,9 @@ void CommodityAmountTestCase::testRound() x5 *= 100.12; assertEqual(internalAmount("$12359.814"), x5); - assertEqual(std::string("$12359.81"), x5.to_string()); - assertEqual(std::string("$12359.814"), x5.to_fullstring()); - assertEqual(std::string("$12359.814"), x5.unround().to_string()); + assertEqual(string("$12359.81"), x5.to_string()); + assertEqual(string("$12359.814"), x5.to_fullstring()); + assertEqual(string("$12359.814"), x5.unround().to_string()); assertValid(x1); assertValid(x2); @@ -540,17 +543,17 @@ void CommodityAmountTestCase::testDisplayRound() assertNotEqual(amount_t("$0.16"), x1); assertEqual(internalAmount("$0.1615"), x1); - assertEqual(std::string("$0.16"), x1.to_string()); + assertEqual(string("$0.16"), x1.to_string()); assertEqual(amount_t("$0.10"), x2); assertNotEqual(internalAmount("$0.101"), x2); - assertEqual(std::string("$0.10"), x2.to_string()); + assertEqual(string("$0.10"), x2.to_string()); x1 *= 7L; assertNotEqual(amount_t("$1.13"), x1); assertEqual(internalAmount("$1.1305"), x1); - assertEqual(std::string("$1.13"), x1.to_string()); + assertEqual(string("$1.13"), x1.to_string()); } void CommodityAmountTestCase::testTruth() @@ -21,18 +21,18 @@ namespace ledger { #define MAX_LINE 1024 -static std::string path; +static string path; static unsigned int linenum; static unsigned int src_idx; static accounts_map account_aliases; -static std::list<std::pair<std::string, int> > include_stack; +static std::list<std::pair<string, int> > include_stack; #ifdef TIMELOG_SUPPORT struct time_entry_t { moment_t checkin; account_t * account; - std::string desc; + string desc; }; std::list<time_entry_t> time_entries; #endif @@ -60,7 +60,7 @@ inline char * next_element(char * buf, bool variable = false) } static inline void -parse_amount_expr(std::istream& in, journal_t * journal, +parse_amount_expr(std::istream& in, journal_t *, transaction_t& xact, amount_t& amount, unsigned short flags = 0) { @@ -93,12 +93,10 @@ transaction_t * parse_transaction(char * line, std::auto_ptr<transaction_t> xact(new transaction_t(NULL)); std::istringstream in(line); - std::string err_desc; + string err_desc; try { xact->entry = entry; // this might be NULL - if (xact->entry) - xact->data = xml::wrap_node(journal->document, xact.get(), xact->entry->data); // Parse the state flag @@ -150,7 +148,7 @@ transaction_t * parse_transaction(char * line, b++; e--; } - std::string name(b, e - b); + string name(b, e - b); DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " << "Parsed account name " << name); if (account_aliases.size() > 0) { @@ -174,10 +172,37 @@ transaction_t * parse_transaction(char * line, // jww (2006-09-15): Make sure it doesn't gobble up the upcoming @ symbol unsigned long beg = (long)in.tellg(); - parse_amount_expr(in, journal, *xact, xact->amount, - XPATH_PARSE_NO_REDUCE); - unsigned long end = (long)in.tellg(); - xact->amount_expr = std::string(line, beg, end - beg); + + xact->amount.parse(in, AMOUNT_PARSE_NO_REDUCE); + + if (! in.eof() && (p = peek_next_nonws(in)) != '@' && + p != ';' && ! in.eof()) { + in.seekg(beg, std::ios::beg); + + if (xact->entry) { + // Create a report item for this entry, so the transaction + // below may refer to it + + if (! xact->entry->data) + xact->entry->data = xml::wrap_node(journal->document, xact->entry, + journal->document->top); + + xact->data = xml::wrap_node(journal->document, xact.get(), + xact->entry->data); + } + + parse_amount_expr(in, journal, *xact, xact->amount, + XPATH_PARSE_NO_REDUCE); + + if (xact->entry) { + delete static_cast<xml::transaction_node_t *>(xact->data); + xact->data = NULL; + } + + unsigned long end = (long)in.tellg(); + + xact->amount_expr = string(line, beg, end - beg); + } } catch (error * err) { err_desc = "While parsing transaction amount:"; @@ -207,17 +232,16 @@ transaction_t * parse_transaction(char * line, try { unsigned long beg = (long)in.tellg(); - parse_amount_expr(in, journal, *xact, *xact->cost, - XPATH_PARSE_NO_MIGRATE); + xact->cost->parse(in); unsigned long end = (long)in.tellg(); if (per_unit) - xact->cost_expr = (std::string("@") + - std::string(line, beg, end - beg)); + xact->cost_expr = (string("@") + + string(line, beg, end - beg)); else - xact->cost_expr = (std::string("@@") + - std::string(line, beg, end - beg)); + xact->cost_expr = (string("@@") + + string(line, beg, end - beg)); } catch (error * err) { err_desc = "While parsing transaction cost:"; @@ -245,11 +269,14 @@ transaction_t * parse_transaction(char * line, "Per-unit cost is " << per_unit_cost); DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " << "Annotated amount is " << xact->amount); + DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " << + "Bare amount is " << xact->amount.number()); } } } xact->amount.in_place_reduce(); + DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " << "Reduced amount is " << xact->amount); @@ -297,12 +324,12 @@ transaction_t * parse_transaction(char * line, } } -bool parse_transactions(std::istream& in, - journal_t * journal, - account_t * account, - entry_base_t& entry, - const std::string& kind, - unsigned long beg_pos) +bool parse_transactions(std::istream& in, + journal_t * journal, + account_t * account, + entry_base_t& entry, + const string& /* kind */, + unsigned long beg_pos) { static char line[MAX_LINE + 1]; bool added = false; @@ -329,14 +356,14 @@ bool parse_transactions(std::istream& in, } namespace { - TIMER_DEF(parsing_total, "total parsing time"); - TIMER_DEF(entry_xacts, "parsing transactions"); - TIMER_DEF(entry_details, "parsing entry details"); - TIMER_DEF(entry_date, "parsing entry date"); + TIMER_DEF(parsing_total, "total parsing time") + TIMER_DEF(entry_xacts, "parsing transactions") + TIMER_DEF(entry_details, "parsing entry details") + TIMER_DEF(entry_date, "parsing entry date") } entry_t * parse_entry(std::istream& in, char * line, journal_t * journal, - account_t * master, textual_parser_t& parser, + account_t * master, textual_parser_t& /* parser */, unsigned long beg_pos) { std::auto_ptr<entry_t> curr(new entry_t); @@ -348,7 +375,7 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal, TIMER_START(entry_date); - std::string word; + string word; line_in >> word; curr->_date = parse_datetime(word); @@ -397,11 +424,6 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal, TIMER_STOP(entry_details); - // Create a report item for this entry, so the transaction below may - // refer to it - - curr->data = xml::wrap_node(journal->document, curr.get(), journal->data); - // Parse all of the transactions associated with this entry TIMER_START(entry_xacts); @@ -442,6 +464,11 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal, break; } + if (curr->data) { + delete static_cast<xml::entry_node_t *>(curr->data); + curr->data = NULL; + } + TIMER_STOP(entry_xacts); return curr.release(); @@ -455,13 +482,13 @@ struct push_var { ~push_var() { var = prev; } }; -static inline void parse_symbol(char *& p, std::string& symbol) +static inline void parse_symbol(char *& p, string& symbol) { if (*p == '"') { char * q = std::strchr(p + 1, '"'); if (! q) throw new parse_error("Quoted commodity symbol lacks closing quote"); - symbol = std::string(p + 1, 0, q - p - 1); + symbol = string(p + 1, 0, q - p - 1); p = q + 2; } else { char * q = next_element(p); @@ -545,7 +572,7 @@ static void clock_out_from_timelog(const moment_t& when, ("Timelog check-out date less than corresponding check-in"); char buf[32]; - std::sprintf(buf, "%lds", (curr->_date - event.checkin).total_seconds()); + std::sprintf(buf, "%lds", (long)(curr->_date - event.checkin).total_seconds()); amount_t amt; amt.parse(buf); @@ -563,7 +590,7 @@ static void clock_out_from_timelog(const moment_t& when, unsigned int textual_parser_t::parse(std::istream& in, journal_t * journal, account_t * master, - const std::string * original_file) + const string * original_file) { static bool added_auto_entry_hook = false; static char line[MAX_LINE + 1]; @@ -613,7 +640,7 @@ unsigned int textual_parser_t::parse(std::istream& in, #ifdef TIMELOG_SUPPORT case 'i': case 'I': { - std::string date(line, 2, 19); + string date(line, 2, 19); char * p = skip_ws(line + 22); char * n = next_element(p, true); @@ -640,7 +667,7 @@ unsigned int textual_parser_t::parse(std::istream& in, if (time_entries.empty()) { throw new parse_error("Timelog check-out event without a check-in"); } else { - std::string date(line, 2, 19); + string date(line, 2, 19); char * p = skip_ws(line + 22); char * n = next_element(p, true); @@ -675,7 +702,7 @@ unsigned int textual_parser_t::parse(std::istream& in, char * date_field_ptr = skip_ws(line + 1); char * time_field_ptr = next_element(date_field_ptr); if (! time_field_ptr) break; - std::string date_field = date_field_ptr; + string date_field = date_field_ptr; char * symbol_and_price; moment_t datetime; @@ -689,7 +716,7 @@ unsigned int textual_parser_t::parse(std::istream& in, datetime = parse_datetime(date_field); } - std::string symbol; + string symbol; parse_symbol(symbol_and_price, symbol); amount_t price(symbol_and_price); @@ -700,7 +727,7 @@ unsigned int textual_parser_t::parse(std::istream& in, case 'N': { // don't download prices char * p = skip_ws(line + 1); - std::string symbol; + string symbol; parse_symbol(p, symbol); if (commodity_t * commodity = commodity_t::find_or_create(symbol)) @@ -747,7 +774,7 @@ unsigned int textual_parser_t::parse(std::istream& in, case '~': { // period entry period_entry_t * pe = new period_entry_t(skip_ws(line + 1)); if (! pe->period) - throw new parse_error(std::string("Parsing time period '") + skip_ws(line + 1) + "'"); + throw new parse_error(string("Parsing time period '") + skip_ws(line + 1) + "'"); if (parse_transactions(in, journal, account_stack.front(), *pe, "period", end_pos)) { @@ -769,9 +796,9 @@ unsigned int textual_parser_t::parse(std::istream& in, case '@': case '!': { // directive char * p = next_element(line); - std::string word(line + 1); + string word(line + 1); if (word == "include") { - push_var<std::string> save_path(path); + push_var<string> save_path(path); push_var<unsigned int> save_src_idx(src_idx); push_var<unsigned long> save_beg_pos(beg_pos); push_var<unsigned long> save_end_pos(end_pos); @@ -779,18 +806,18 @@ unsigned int textual_parser_t::parse(std::istream& in, path = p; if (path[0] != '/' && path[0] != '\\' && path[0] != '~') { - std::string::size_type pos = save_path.prev.rfind('/'); - if (pos == std::string::npos) + string::size_type pos = save_path.prev.rfind('/'); + if (pos == string::npos) pos = save_path.prev.rfind('\\'); - if (pos != std::string::npos) - path = std::string(save_path.prev, 0, pos + 1) + path; + if (pos != string::npos) + path = string(save_path.prev, 0, pos + 1) + path; } path = resolve_path(path); DEBUG_PRINT("ledger.textual.include", "line " << linenum << ": " << "Including path '" << path << "'"); - include_stack.push_back(std::pair<std::string, int> + include_stack.push_back(std::pair<string, int> (journal->sources.back(), linenum - 1)); count += journal->session->read_journal(path, journal, account_stack.front()); @@ -861,7 +888,7 @@ unsigned int textual_parser_t::parse(std::istream& in, } } catch (error * err) { - for (std::list<std::pair<std::string, int> >::reverse_iterator i = + for (std::list<std::pair<string, int> >::reverse_iterator i = include_stack.rbegin(); i != include_stack.rend(); i++) @@ -880,7 +907,6 @@ unsigned int textual_parser_t::parse(std::istream& in, beg_pos = end_pos; } - done: if (! time_entries.empty()) { for (std::list<time_entry_t>::iterator i = time_entries.begin(); i != time_entries.end(); @@ -13,20 +13,20 @@ class textual_parser_t : public parser_t virtual unsigned int parse(std::istream& in, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL); + const string * original_file = NULL); }; #if 0 -void write_textual_journal(journal_t& journal, std::string path, +void write_textual_journal(journal_t& journal, string path, item_handler<transaction_t>& formatter, - const std::string& write_hdr_format, + const string& write_hdr_format, std::ostream& out); #endif class include_context : public file_context { public: - include_context(const std::string& file, unsigned long line, - const std::string& desc = "") throw() + include_context(const string& file, unsigned long line, + const string& desc = "") throw() : file_context(file, line, desc) {} virtual ~include_context() throw() {} @@ -31,7 +31,7 @@ moment_t parse_datetime(std::istream& in) #if 0 return parse_abs_datetime(in); #else - std::string word; + string word; if (! in.good() || in.eof()) return moment_t(); @@ -45,7 +45,7 @@ extern moment_t& now; class datetime_error : public error { public: - datetime_error(const std::string& _reason) throw() : error(_reason) {} + datetime_error(const string& _reason) throw() : error(_reason) {} virtual ~datetime_error() throw() {} }; @@ -53,16 +53,16 @@ class interval_t { public: interval_t() {} - interval_t(const std::string& desc) {} + interval_t(const string&) {} operator bool() const { return false; } - void start(const moment_t& moment) {} - moment_t next() const {} + void start(const moment_t&) {} + moment_t next() const { return moment_t(); } - void parse(std::istream& in) {} + void parse(std::istream&) {} }; #if 0 @@ -73,19 +73,19 @@ inline moment_t ptime_local_to_utc(const moment_t& when) { // jww (2007-04-18): I need to make a general parsing function // instead, and then make these into private methods. -inline moment_t ptime_from_local_date_string(const std::string& date_string) { +inline moment_t ptime_from_local_date_string(const string& date_string) { return ptime_local_to_utc(moment_t(boost::gregorian::from_string(date_string), time_duration())); } -inline moment_t ptime_from_local_time_string(const std::string& time_string) { +inline moment_t ptime_from_local_time_string(const string& time_string) { return ptime_local_to_utc(boost::posix_time::time_from_string(time_string)); } #endif moment_t parse_datetime(std::istream& in); -inline moment_t parse_datetime(const std::string& str) { +inline moment_t parse_datetime(const string& str) { std::istringstream instr(str); return parse_datetime(instr); } @@ -97,11 +97,11 @@ extern bool day_before_month; struct intorchar { int ival; - std::string sval; + string sval; intorchar() : ival(-1) {} intorchar(int val) : ival(val) {} - intorchar(const std::string& val) : ival(-1), sval(val) {} + intorchar(const string& val) : ival(-1), sval(val) {} intorchar(const intorchar& o) : ival(o.ival), sval(o.sval) {} }; @@ -1,10 +1,10 @@ #ifndef _TIMING_H #define _TIMING_H -#include "debug.h" - #include <ctime> +#include "trace.h" + namespace ledger { class timing_t @@ -12,26 +12,29 @@ class timing_t public: std::clock_t begin; std::clock_t cumulative; - std::string file; + string file; unsigned long line; - std::string symbol; - std::string category; + string symbol; + string category; - timing_t(const std::string& _symbol, const std::string& _category) + timing_t(const string& _symbol, const string& _category) : begin(0), cumulative(0), symbol(_symbol), category(_category) {} - timing_t(const std::string& _symbol) + timing_t(const string& _symbol) : begin(0), cumulative(0), symbol(_symbol) {} ~timing_t() { - std::string cls = "timing.results."; + 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 std::string& _file, unsigned long _line) { + void start(const string& _file, unsigned long _line) { file = _file; line = _line; begin = std::clock(); @@ -45,11 +48,11 @@ class timing_t } }; -#ifdef DEBUG_ENABLED -#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() +#if 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) @@ -1,4 +1,6 @@ #include "trace.h" +#include "debug.h" +#include "timing.h" #include "times.h" #include "acconf.h" @@ -6,21 +8,20 @@ namespace ledger { bool trace_mode; -void trace(const std::string& cat, const std::string& str) +void trace(const string& cat, const string& str) { - char buf[32]; std::cerr << boost::posix_time::to_simple_string(now) << " " << cat << ": " << str << std::endl; } -void trace_push(const std::string& cat, const std::string& str, +void trace_push(const string& cat, const string& str, timing_t& timer) { timer.start(); trace(cat, str); } -void trace_pop(const std::string& cat, const std::string& str, +void trace_pop(const string& cat, const string& str, timing_t& timer) { timer.stop(); @@ -36,15 +37,17 @@ object_count_map live_count; bool tracing_active = false; -bool trace_ctor(void * ptr, const std::string& name) +bool trace_ctor(void * ptr, const char * name) { if (! tracing_active) return true; DEBUG_PRINT("ledger.trace.debug", "trace_ctor " << ptr << " " << name); - std::string::size_type pos = name.find_first_of('('); - std::string cls_name(name, 0, pos); + const char * pos = std::strchr(name, '('); + static char cls_name[1024]; + std::strncpy(cls_name, name, pos - name); + cls_name[pos - name] = '\0'; live_objects.insert(live_objects_pair(ptr, cls_name)); @@ -87,7 +90,7 @@ bool trace_ctor(void * ptr, const std::string& name) return true; } -bool trace_dtor(void * ptr, const std::string& name) +bool trace_dtor(void * ptr, const char * name) { if (! tracing_active) return true; @@ -102,8 +105,7 @@ bool trace_dtor(void * ptr, const std::string& name) return false; } - std::string::size_type pos = name.find_first_of('('); - std::string cls_name(name, 0, pos); + const char * cls_name = name; int ptr_count = live_objects.count(ptr); for (int x = 0; x < ptr_count; x++) { @@ -138,7 +140,7 @@ void report_memory(std::ostream& out) i++) { out << " "; out << std::right; - out.width(5); + out.width(7); out << (*i).second << " " << (*i).first << std::endl; } @@ -151,7 +153,7 @@ void report_memory(std::ostream& out) i++) { out << " "; out << std::right; - out.width(5); + out.width(7); out << (*i).first << " " << (*i).second << std::endl; } } @@ -164,7 +166,7 @@ void report_memory(std::ostream& out) i++) { out << " "; out << std::right; - out.width(5); + out.width(7); out << (*i).second << " " << (*i).first << std::endl; } @@ -176,9 +178,47 @@ void report_memory(std::ostream& out) i++) { out << " "; out << std::right; - out.width(5); + out.width(7); out << (*i).second << " " << (*i).first << std::endl; } } +#if DEBUG_LEVEL >= 4 + +string::string() : std::string() { + TRACE_CTOR("string()"); +} +string::string(const string& str) : std::string(str) { + TRACE_CTOR("string(const string&)"); +} +string::string(const std::string& str) : std::string(str) { + TRACE_CTOR("string(const std::string&)"); +} +string::string(const int len, char x) : std::string(len, x) { + TRACE_CTOR("string(const int, char)"); +} +string::string(const char * str) : std::string(str) { + TRACE_CTOR("string(const char *)"); +} +string::string(const char * str, const char * end) : std::string(str, end) { + TRACE_CTOR("string(const char *, const char *)"); +} +string::string(const string& str, int x) : std::string(str, x) { + 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)"); +} +string::string(const char * str, int x) : std::string(str, x) { + 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)"); +} +string::~string() { + TRACE_DTOR("string"); +} + +#endif + } // namespace ledger @@ -1,21 +1,28 @@ #ifndef _TRACE_H #define _TRACE_H -#include "timing.h" - #include <string> #include <map> namespace ledger { +class timing_t; + extern bool trace_mode; -void trace(const std::string& cat, const std::string& str); -void trace_push(const std::string& cat, const std::string& str, +#if DEBUG_LEVEL >= 4 +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 std::string& cat, const std::string& str, +void trace_pop(const string& cat, const string& str, timing_t& timer); +#ifndef TRACE #define TRACE(cat, msg) if (trace_mode) trace(#cat, msg) #define TRACE_(cat, msg) if (trace_mode) trace(#cat, msg) @@ -25,9 +32,10 @@ void trace_pop(const std::string& cat, const std::string& str, #define TRACE_POP(cat, msg) \ if (trace_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<void *, std::string> live_objects_pair; typedef std::map<std::string, int> object_count_map; typedef std::pair<std::string, int> object_count_pair; @@ -38,13 +46,79 @@ extern object_count_map live_count; extern bool tracing_active; -bool trace_ctor(void * ptr, const std::string& name); -bool trace_dtor(void * ptr, const std::string& name); +bool trace_ctor(void * ptr, const char * name); +bool trace_dtor(void * ptr, const char * name); void report_memory(std::ostream& out); +#ifndef TRACE_CTOR #define TRACE_CTOR(cls) CONFIRM(ledger::trace_ctor(this, cls)) #define TRACE_DTOR(cls) CONFIRM(ledger::trace_dtor(this, cls)) +#endif + +#if DEBUG_LEVEL >= 4 + +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 diff --git a/transform.h b/transform.h index 74e770b2..e98c53a3 100644 --- a/transform.h +++ b/transform.h @@ -113,7 +113,7 @@ class select_transform : public transform_t xml::xpath_t xpath; public: - select_transform(const std::string& selection_path) { + select_transform(const string& selection_path) { xpath.parse(selection_path); } virtual ~select_transform() { @@ -127,7 +127,7 @@ class select_transform : public transform_t class remove_transform : public select_transform { public: - remove_transform(const std::string& selection_path) + remove_transform(const string& selection_path) : select_transform(selection_path) {} virtual void execute(xml::document_t * document); @@ -15,13 +15,15 @@ #include <pwd.h> #endif -std::string expand_path(const std::string& path) +namespace ledger { + +string expand_path(const string& path) { if (path.length() == 0 || path[0] != '~') return path; const char * pfx = NULL; - std::string::size_type pos = path.find_first_of('/'); + string::size_type pos = path.find_first_of('/'); if (path.length() == 1 || pos == 1) { pfx = std::getenv("HOME"); @@ -36,8 +38,8 @@ std::string expand_path(const std::string& path) } #ifdef HAVE_GETPWNAM else { - std::string user(path, 1, pos == std::string::npos ? - std::string::npos : pos - 1); + string user(path, 1, pos == string::npos ? + string::npos : pos - 1); struct passwd * pw = getpwnam(user.c_str()); if (pw) pfx = pw->pw_dir; @@ -49,9 +51,9 @@ std::string expand_path(const std::string& path) if (! pfx) return path; - std::string result(pfx); + string result(pfx); - if (pos == std::string::npos) + if (pos == string::npos) return result; if (result.length() == 0 || result[result.length() - 1] != '/') @@ -62,14 +64,14 @@ std::string expand_path(const std::string& path) return result; } -std::string resolve_path(const std::string& path) +string resolve_path(const string& path) { if (path[0] == '~') return expand_path(path); return path; } -std::string abbreviate(const std::string& str, unsigned int width, +string abbreviate(const string& str, unsigned int width, elision_style_t elision_style, const bool is_account, int abbrev_length) { @@ -101,28 +103,28 @@ std::string abbreviate(const std::string& str, unsigned int width, case ABBREVIATE: if (is_account) { - std::list<std::string> parts; - std::string::size_type beg = 0; - for (std::string::size_type pos = str.find(':'); - pos != std::string::npos; + std::list<string> parts; + string::size_type beg = 0; + for (string::size_type pos = str.find(':'); + pos != string::npos; beg = pos + 1, pos = str.find(':', beg)) - parts.push_back(std::string(str, beg, pos - beg)); - parts.push_back(std::string(str, beg)); + parts.push_back(string(str, beg, pos - beg)); + parts.push_back(string(str, beg)); - std::string result; + string result; unsigned int newlen = len; - for (std::list<std::string>::iterator i = parts.begin(); + for (std::list<string>::iterator i = parts.begin(); i != parts.end(); i++) { // Don't contract the last element - std::list<std::string>::iterator x = i; + std::list<string>::iterator x = i; if (++x == parts.end()) { result += *i; break; } if (newlen > width) { - result += std::string(*i, 0, abbrev_length); + result += string(*i, 0, abbrev_length); result += ":"; newlen -= (*i).length() - abbrev_length; } else { @@ -155,3 +157,5 @@ std::string abbreviate(const std::string& str, unsigned int width, return buf; } + +} // namespace ledger @@ -3,6 +3,8 @@ #include <iostream> +#include "trace.h" + #if defined __FreeBSD__ && __FreeBSD__ <=4 // FreeBSD has a broken isspace macro, so dont use it #undef isspace(c) @@ -26,6 +28,8 @@ 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) { while (*ptr == ' ' || *ptr == '\t' || *ptr == '\n') ptr++; @@ -79,7 +83,7 @@ inline char peek_next_nonws(std::istream& in) { *_p = '\0'; \ } -std::string resolve_path(const std::string& path); +ledger::string resolve_path(const ledger::string& path); #ifdef HAVE_REALPATH extern "C" char *realpath(const char *, char resolved_path[]); @@ -92,12 +96,13 @@ enum elision_style_t { ABBREVIATE }; -std::string abbreviate(const std::string& str, unsigned int width, - elision_style_t elision_style = TRUNCATE_TRAILING, - const bool is_account = false, int abbrev_length = 2); +ledger::string abbreviate(const ledger::string& str, unsigned int width, + elision_style_t elision_style = TRUNCATE_TRAILING, + const bool is_account = false, int abbrev_length = 2); static inline const -std::string& either_or(const std::string& first, const std::string& second) +ledger::string& either_or(const ledger::string& first, + const ledger::string& second) { if (first.empty()) return second; @@ -105,4 +110,6 @@ std::string& either_or(const std::string& first, const std::string& second) return first; } +} // namespace ledger + #endif // _UTIL_H @@ -71,10 +71,10 @@ balance_pair_t value_t::to_balance_pair() const } } -std::string value_t::to_string() const +string value_t::to_string() const { if (type == STRING) { - return **(std::string **) data; + return **(string **) data; } else { std::ostringstream out; out << *this; @@ -119,7 +119,7 @@ void value_t::destroy() ((balance_pair_t *)data)->~balance_pair_t(); break; case STRING: - delete *(std::string **) data; + delete *(string **) data; break; case SEQUENCE: delete *(sequence_t **) data; @@ -187,7 +187,7 @@ value_t& value_t::operator=(const value_t& val) return *this; } else if (type == STRING && val.type == STRING) { - **(std::string **) data = **(std::string **) val.data; + **(string **) data = **(string **) val.data; return *this; } else if (type == SEQUENCE && val.type == SEQUENCE) { @@ -223,7 +223,7 @@ value_t& value_t::operator=(const value_t& val) break; case STRING: - *(std::string **) data = new std::string(**(std::string **) val.data); + *(string **) data = new string(**(string **) val.data); break; case XML_NODE: @@ -407,7 +407,7 @@ value_t& value_t::operator+=(const value_t& val) case BALANCE_PAIR: throw new value_error("Cannot add a balance pair to a string"); case STRING: - **(std::string **) data += **(std::string **) val.data; + **(string **) data += **(string **) val.data; break; default: assert(0); @@ -708,19 +708,19 @@ value_t& value_t::operator*=(const value_t& val) case STRING: switch (val.type) { case INTEGER: { - std::string temp; + string temp; for (long i = 0; i < *(long *) val.data; i++) - temp += **(std::string **) data; - **(std::string **) data = temp; + temp += **(string **) data; + **(string **) data = temp; break; } case AMOUNT: { - std::string temp; + string temp; value_t num(val); num.in_place_cast(INTEGER); for (long i = 0; i < *(long *) num.data; i++) - temp += **(std::string **) data; - **(std::string **) data = temp; + temp += **(string **) data; + **(string **) data = temp; break; } case BALANCE: @@ -885,7 +885,7 @@ value_t::operator bool() const case BALANCE_PAIR: return *(balance_pair_t *) data; case STRING: - return ! (**((std::string **) data)).empty(); + return ! (**((string **) data)).empty(); case XML_NODE: return (*(xml::node_t **) data)->to_value().to_boolean(); case POINTER: @@ -1002,7 +1002,7 @@ value_t::operator double() const } template <> -value_t::operator std::string() const +value_t::operator string() const { switch (type) { case BOOLEAN: @@ -1016,7 +1016,7 @@ value_t::operator std::string() const return temp; } case STRING: - return **(std::string **) data; + return **(string **) data; case XML_NODE: return (*(xml::node_t **) data)->to_value().to_string(); @@ -1284,8 +1284,8 @@ bool value_t::operator OP(const value_t& val) \ throw new value_error("Cannot compare a string to a balance pair"); \ \ case STRING: \ - return (**((std::string **) data) OP \ - **((std::string **) val.data)); \ + return (**((string **) data) OP \ + **((string **) val.data)); \ \ case XML_NODE: \ return *this OP (*(xml::node_t **) data)->to_value(); \ @@ -1396,7 +1396,7 @@ void value_t::in_place_cast(type_t cast_type) case BALANCE_PAIR: throw new value_error("Cannot convert a boolean to a balance pair"); case STRING: - *(std::string **) data = new std::string(*((bool *) data) ? "true" : "false"); + *(string **) data = new string(*((bool *) data) ? "true" : "false"); break; case XML_NODE: throw new value_error("Cannot convert a boolean to an XML node"); @@ -1433,7 +1433,7 @@ void value_t::in_place_cast(type_t cast_type) case STRING: { char buf[32]; std::sprintf(buf, "%ld", *(long *) data); - *(std::string **) data = new std::string(buf); + *(string **) data = new string(buf); break; } case XML_NODE: @@ -1513,7 +1513,7 @@ void value_t::in_place_cast(type_t cast_type) std::ostringstream out; out << *(amount_t *) data; destroy(); - *(std::string **) data = new std::string(out.str()); + *(string **) data = new string(out.str()); break; } case XML_NODE: @@ -1636,11 +1636,11 @@ void value_t::in_place_cast(type_t cast_type) case STRING: switch (cast_type) { case BOOLEAN: { - if (**(std::string **) data == "true") { + if (**(string **) data == "true") { destroy(); *(bool *) data = true; } - else if (**(std::string **) data == "false") { + else if (**(string **) data == "false") { destroy(); *(bool *) data = false; } @@ -1650,8 +1650,8 @@ void value_t::in_place_cast(type_t cast_type) break; } case INTEGER: { - int l = (*(std::string **) data)->length(); - const char * p = (*(std::string **) data)->c_str(); + int l = (*(string **) data)->length(); + const char * p = (*(string **) data)->c_str(); bool alldigits = true; for (int i = 0; i < l; i++) if (! std::isdigit(p[i])) { @@ -1659,7 +1659,7 @@ void value_t::in_place_cast(type_t cast_type) break; } if (alldigits) { - long temp = std::atol((*(std::string **) data)->c_str()); + long temp = std::atol((*(string **) data)->c_str()); destroy(); *(long *) data = temp; } else { @@ -1672,7 +1672,7 @@ void value_t::in_place_cast(type_t cast_type) throw new value_error("Cannot convert a string to a date/time"); case AMOUNT: { - amount_t temp = **(std::string **) data; + amount_t temp = **(string **) data; destroy(); new((amount_t *)data) amount_t(temp); break; @@ -1925,7 +1925,7 @@ value_t value_t::round() const case DATETIME: throw new value_error("Cannot round a date/time"); case INTEGER: - break; + return *this; case AMOUNT: return ((amount_t *) data)->round(); case BALANCE: @@ -1941,18 +1941,19 @@ value_t value_t::round() const case SEQUENCE: throw new value_error("Cannot round a sequence"); } + assert(0); + return value_t(); } value_t value_t::unround() const { - value_t temp; switch (type) { case BOOLEAN: throw new value_error("Cannot un-round a boolean"); case DATETIME: throw new value_error("Cannot un-round a date/time"); case INTEGER: - break; + return *this; case AMOUNT: return ((amount_t *) data)->unround(); case BALANCE: @@ -1968,7 +1969,8 @@ value_t value_t::unround() const case SEQUENCE: throw new value_error("Cannot un-round a sequence"); } - return temp; + assert(0); + return value_t(); } value_t value_t::price() const @@ -2221,7 +2223,7 @@ std::ostream& operator<<(std::ostream& out, const value_t& val) out << *(balance_pair_t *) val.data; break; case value_t::STRING: - out << **(std::string **) val.data; + out << **(string **) val.data; break; case value_t::XML_NODE: if ((*(xml::node_t **) val.data)->flags & XML_NODE_IS_PARENT) @@ -2258,7 +2260,7 @@ std::ostream& operator<<(std::ostream& out, const value_t& val) } value_context::value_context(const value_t& _bal, - const std::string& _desc) throw() + const string& _desc) throw() : error_context(_desc), bal(new value_t(_bal)) {} value_context::~value_context() throw() @@ -2412,20 +2414,20 @@ void export_value() .def(init<balance_pair_t>()) .def(init<balance_t>()) .def(init<amount_t>()) - .def(init<std::string>()) + .def(init<string>()) .def(init<double>()) .def(init<long>()) .def(initmoment_t()) .def(self + self) - .def(self + other<std::string>()) + .def(self + other<string>()) .def(self + other<balance_pair_t>()) .def(self + other<balance_t>()) .def(self + other<amount_t>()) .def(self + long()) .def(self + double()) - .def(other<std::string>() + self) + .def(other<string>() + self) .def(other<balance_pair_t>() + self) .def(other<balance_t>() + self) .def(other<amount_t>() + self) @@ -2433,14 +2435,14 @@ void export_value() .def(double() + self) .def(self - self) - .def(self - other<std::string>()) + .def(self - other<string>()) .def(self - other<balance_pair_t>()) .def(self - other<balance_t>()) .def(self - other<amount_t>()) .def(self - long()) .def(self - double()) - .def(other<std::string>() - self) + .def(other<string>() - self) .def(other<balance_pair_t>() - self) .def(other<balance_t>() - self) .def(other<amount_t>() - self) @@ -2448,14 +2450,14 @@ void export_value() .def(double() - self) .def(self * self) - .def(self * other<std::string>()) + .def(self * other<string>()) .def(self * other<balance_pair_t>()) .def(self * other<balance_t>()) .def(self * other<amount_t>()) .def(self * long()) .def(self * double()) - .def(other<std::string>() * self) + .def(other<string>() * self) .def(other<balance_pair_t>() * self) .def(other<balance_t>() * self) .def(other<amount_t>() * self) @@ -2463,14 +2465,14 @@ void export_value() .def(double() * self) .def(self / self) - .def(self / other<std::string>()) + .def(self / other<string>()) .def(self / other<balance_pair_t>()) .def(self / other<balance_t>()) .def(self / other<amount_t>()) .def(self / long()) .def(self / double()) - .def(other<std::string>() / self) + .def(other<string>() / self) .def(other<balance_pair_t>() / self) .def(other<balance_t>() / self) .def(other<amount_t>() / self) @@ -2480,7 +2482,7 @@ void export_value() .def(- self) .def(self += self) - .def(self += other<std::string>()) + .def(self += other<string>()) .def(self += other<balance_pair_t>()) .def(self += other<balance_t>()) .def(self += other<amount_t>()) @@ -2488,7 +2490,7 @@ void export_value() .def(self += double()) .def(self -= self) - .def(self -= other<std::string>()) + .def(self -= other<string>()) .def(self -= other<balance_pair_t>()) .def(self -= other<balance_t>()) .def(self -= other<amount_t>()) @@ -2496,7 +2498,7 @@ void export_value() .def(self -= double()) .def(self *= self) - .def(self *= other<std::string>()) + .def(self *= other<string>()) .def(self *= other<balance_pair_t>()) .def(self *= other<balance_t>()) .def(self *= other<amount_t>()) @@ -2504,7 +2506,7 @@ void export_value() .def(self *= double()) .def(self /= self) - .def(self /= other<std::string>()) + .def(self /= other<string>()) .def(self /= other<balance_pair_t>()) .def(self /= other<balance_t>()) .def(self /= other<amount_t>()) @@ -2512,7 +2514,7 @@ void export_value() .def(self /= double()) .def(self < self) - .def(self < other<std::string>()) + .def(self < other<string>()) .def(self < other<balance_pair_t>()) .def(self < other<balance_t>()) .def(self < other<amount_t>()) @@ -2520,7 +2522,7 @@ void export_value() .def(self < othermoment_t()) .def(self < double()) - .def(other<std::string>() < self) + .def(other<string>() < self) .def(other<balance_pair_t>() < self) .def(other<balance_t>() < self) .def(other<amount_t>() < self) @@ -2529,7 +2531,7 @@ void export_value() .def(double() < self) .def(self <= self) - .def(self <= other<std::string>()) + .def(self <= other<string>()) .def(self <= other<balance_pair_t>()) .def(self <= other<balance_t>()) .def(self <= other<amount_t>()) @@ -2537,7 +2539,7 @@ void export_value() .def(self <= othermoment_t()) .def(self <= double()) - .def(other<std::string>() <= self) + .def(other<string>() <= self) .def(other<balance_pair_t>() <= self) .def(other<balance_t>() <= self) .def(other<amount_t>() <= self) @@ -2546,7 +2548,7 @@ void export_value() .def(double() <= self) .def(self > self) - .def(self > other<std::string>()) + .def(self > other<string>()) .def(self > other<balance_pair_t>()) .def(self > other<balance_t>()) .def(self > other<amount_t>()) @@ -2554,7 +2556,7 @@ void export_value() .def(self > othermoment_t()) .def(self > double()) - .def(other<std::string>() > self) + .def(other<string>() > self) .def(other<balance_pair_t>() > self) .def(other<balance_t>() > self) .def(other<amount_t>() > self) @@ -2563,7 +2565,7 @@ void export_value() .def(double() > self) .def(self >= self) - .def(self >= other<std::string>()) + .def(self >= other<string>()) .def(self >= other<balance_pair_t>()) .def(self >= other<balance_t>()) .def(self >= other<amount_t>()) @@ -2571,7 +2573,7 @@ void export_value() .def(self >= othermoment_t()) .def(self >= double()) - .def(other<std::string>() >= self) + .def(other<string>() >= self) .def(other<balance_pair_t>() >= self) .def(other<balance_t>() >= self) .def(other<amount_t>() >= self) @@ -2580,7 +2582,7 @@ void export_value() .def(double() >= self) .def(self == self) - .def(self == other<std::string>()) + .def(self == other<string>()) .def(self == other<balance_pair_t>()) .def(self == other<balance_t>()) .def(self == other<amount_t>()) @@ -2588,7 +2590,7 @@ void export_value() .def(self == othermoment_t()) .def(self == double()) - .def(other<std::string>() == self) + .def(other<string>() == self) .def(other<balance_pair_t>() == self) .def(other<balance_t>() == self) .def(other<amount_t>() == self) @@ -2597,7 +2599,7 @@ void export_value() .def(double() == self) .def(self != self) - .def(self != other<std::string>()) + .def(self != other<string>()) .def(self != other<balance_pair_t>()) .def(self != other<balance_t>()) .def(self != other<amount_t>()) @@ -2605,7 +2607,7 @@ void export_value() .def(self != othermoment_t()) .def(self != double()) - .def(other<std::string>() != self) + .def(other<string>() != self) .def(other<balance_pair_t>() != self) .def(other<balance_t>() != self) .def(other<amount_t>() != self) @@ -78,8 +78,8 @@ class value_t new((amount_t *) data) amount_t(val); type = AMOUNT; } - value_t(const std::string& val, bool literal = false) { - TRACE_CTOR("value_t(const std::string&, bool)"); + value_t(const string& val, bool literal = false) { + TRACE_CTOR("value_t(const string&, bool)"); if (literal) { type = INTEGER; set_string(val); @@ -158,7 +158,7 @@ class value_t value_t& operator=(const double val) { return *this = amount_t(val); } - value_t& operator=(const std::string& val) { + value_t& operator=(const string& val) { return *this = amount_t(val); } value_t& operator=(const char * val) { @@ -263,13 +263,13 @@ class value_t } } - value_t& set_string(const std::string& str = "") { + value_t& set_string(const string& str = "") { if (type != STRING) { destroy(); - *(std::string **) data = new std::string(str); + *(string **) data = new string(str); type = STRING; } else { - **(std::string **) data = str; + **(string **) data = str; } return *this; } @@ -280,7 +280,7 @@ class value_t amount_t to_amount() const; balance_t to_balance() const; balance_pair_t to_balance_pair() const; - std::string to_string() const; + string to_string() const; xml::node_t * to_xml_node() const; void * to_pointer() const; sequence_t * to_sequence() const; @@ -425,7 +425,7 @@ class value_t case BALANCE_PAIR: return ((balance_pair_t *) data)->realzero(); case STRING: - return ((std::string *) data)->empty(); + return ((string *) data)->empty(); case XML_NODE: case POINTER: case SEQUENCE: @@ -540,7 +540,7 @@ value_t::operator T() const case BALANCE: return *(balance_t *) data; case STRING: - return **(std::string **) data; + return **(string **) data; case XML_NODE: return *(xml::node_t **) data; case POINTER: @@ -560,7 +560,7 @@ template <> value_t::operator bool() const; template <> value_t::operator long() const; template <> value_t::operator moment_t() const; template <> value_t::operator double() const; -template <> value_t::operator std::string() const; +template <> value_t::operator string() const; std::ostream& operator<<(std::ostream& out, const value_t& val); @@ -569,7 +569,7 @@ class value_context : public error_context value_t * bal; public: value_context(const value_t& _bal, - const std::string& desc = "") throw(); + const string& desc = "") throw(); virtual ~value_context() throw(); virtual void describe(std::ostream& out) const throw(); @@ -577,7 +577,7 @@ class value_context : public error_context class value_error : public error { public: - value_error(const std::string& _reason, + value_error(const string& _reason, error_context * _ctxt = NULL) throw() : error(_reason, _ctxt) {} virtual ~value_error() throw() {} @@ -12,7 +12,16 @@ namespace xml { document_t::document_t(node_t * _top, const char ** _builtins, const int _builtins_size) : builtins(_builtins), builtins_size(_builtins_size), - top(new terminal_node_t(this)) {} + top(_top ? _top : new terminal_node_t(this)) { + TRACE_CTOR("xml::document_t(node_t *, const char **, const int)"); +} + +document_t::~document_t() +{ + TRACE_DTOR("xml::document_t"); + if (top) + delete top; +} void document_t::set_top(node_t * _top) { @@ -21,7 +30,7 @@ void document_t::set_top(node_t * _top) top = _top; } -int document_t::register_name(const std::string& name) +int document_t::register_name(const string& name) { int index = lookup_name_id(name); if (index != -1) @@ -39,7 +48,7 @@ int document_t::register_name(const std::string& name) return index + 1000; } -int document_t::lookup_name_id(const std::string& name) const +int document_t::lookup_name_id(const string& name) const { if (builtins) { int first = 0; @@ -110,7 +119,7 @@ node_t::node_t(document_t * _document, parent_node_t * _parent, { TRACE_CTOR("node_t(document_t *, node_t *)"); document = _document; - if (! document->top) + if (document && ! document->top) document->set_top(this); if (parent) parent->add_child(this); @@ -269,7 +278,7 @@ static void dataHandler(void *userData, const char *s, int len) { parser_t * parser = static_cast<parser_t *>(userData); - DEBUG_PRINT("xml.parse", "dataHandler(" << std::string(s, len) << ")"); + DEBUG_PRINT("xml.parse", "dataHandler(" << string(s, len) << ")"); bool all_whitespace = true; for (int i = 0; i < len; i++) { @@ -285,7 +294,7 @@ static void dataHandler(void *userData, const char *s, int len) if (! all_whitespace) { terminal_node_t * node = create_node<terminal_node_t>(parser); - node->set_text(std::string(s, len)); + node->set_text(string(s, len)); parser->handled_data = true; if (parser->node_stack.empty()) { @@ -389,6 +398,7 @@ node_t * transaction_node_t::lookup_child(int _name_id) payee_virtual_node->set_text(transaction->entry->payee); return payee_virtual_node; } + return NULL; } value_t transaction_node_t::to_value() const @@ -468,7 +478,7 @@ node_t * journal_node_t::children() const #endif // defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE) -void output_xml_string(std::ostream& out, const std::string& str) +void output_xml_string(std::ostream& out, const string& str) { for (const char * s = str.c_str(); *s; s++) { switch (*s) { @@ -28,12 +28,12 @@ class document_t const char ** builtins; const int builtins_size; - typedef std::deque<std::string> names_array; + typedef std::deque<string> names_array; names_array names; - typedef std::map<std::string, int> names_map; - typedef std::pair<std::string, int> names_pair; + typedef std::map<string, int> names_map; + typedef std::pair<string, int> names_pair; names_map names_index; @@ -48,11 +48,12 @@ class document_t 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 std::string& name); - int lookup_name_id(const std::string& name) const; + 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; @@ -62,7 +63,7 @@ class document_t class conversion_error : public error { public: - conversion_error(const std::string& _reason, + conversion_error(const string& _reason, error_context * _ctxt = NULL) throw() : error(_reason, _ctxt) {} virtual ~conversion_error() throw() {} @@ -85,8 +86,8 @@ public: unsigned int flags; void * info; - typedef std::map<std::string, std::string> attrs_map; - typedef std::pair<std::string, std::string> attrs_pair; + typedef std::map<string, string> attrs_map; + typedef std::pair<string, string> attrs_pair; attrs_map * attrs; @@ -138,11 +139,11 @@ public: int id = document->lookup_name_id(_name); return lookup_child(id); } - node_t * lookup_child(const std::string& _name) { + 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; } @@ -194,7 +195,7 @@ private: class terminal_node_t : public node_t { - std::string data; + string data; public: terminal_node_t(document_t * _document, parent_node_t * _parent = NULL) @@ -202,6 +203,9 @@ public: { TRACE_CTOR("terminal_node_t(document_t *, parent_node_t *)"); } + virtual ~terminal_node_t() { + TRACE_DTOR("terminal_node_t"); + } virtual const char * text() const { return data.c_str(); @@ -209,7 +213,7 @@ public: virtual void set_text(const char * _data) { data = _data; } - virtual void set_text(const std::string& _data) { + virtual void set_text(const string& _data) { data = _data; } @@ -231,7 +235,7 @@ class parser_t public: document_t * document; XML_Parser parser; - std::string have_error; + string have_error; const char * pending; node_t::attrs_map * pending_attrs; bool handled_data; @@ -250,7 +254,7 @@ class parser_t class parse_error : public error { public: - parse_error(const std::string& _reason, + parse_error(const string& _reason, error_context * _ctxt = NULL) throw() : error(_reason, _ctxt) {} virtual ~parse_error() throw() {} @@ -311,8 +315,8 @@ public: transaction_node_t(document_t * _document, transaction_t * _transaction, parent_node_t * _parent = NULL) - : parent_node_t(_document, _parent), transaction(_transaction), - payee_virtual_node(NULL) { + : parent_node_t(_document, _parent), payee_virtual_node(NULL), + transaction(_transaction) { TRACE_CTOR("transaction_node_t(document_t *, transaction_t *, parent_node_t *)"); set_name("transaction"); payee_id = document->register_name("payee"); diff --git a/xmlparse.cc b/xmlparse.cc index daf3b15b..6841b3fa 100644 --- a/xmlparse.cc +++ b/xmlparse.cc @@ -21,13 +21,13 @@ static unsigned int count; static journal_t * curr_journal; static entry_t * curr_entry; static commodity_t * curr_comm; -static std::string comm_flags; +static string comm_flags; static transaction_t::state_t curr_state; -static std::string data; +static string data; static bool ignore; -static std::string have_error; +static string have_error; static void startElement(void *userData, const char *name, const char **attrs) { @@ -46,7 +46,7 @@ static void startElement(void *userData, const char *name, const char **attrs) curr_entry->transactions.back()->state = curr_state; } else if (std::strcmp(name, "commodity") == 0) { - if (std::string(attrs[0]) == "flags") + if (string(attrs[0]) == "flags") comm_flags = attrs[1]; } else if (std::strcmp(name, "total") == 0) { @@ -117,7 +117,7 @@ static void endElement(void *userData, const char *name) assert(curr_comm); curr_comm->add_flags(COMMODITY_STYLE_SUFFIXED); if (! comm_flags.empty()) { - for (std::string::size_type i = 0, l = comm_flags.length(); i < l; i++) { + for (string::size_type i = 0, l = comm_flags.length(); i < l; i++) { switch (comm_flags[i]) { case 'P': curr_comm->drop_flags(COMMODITY_STYLE_SUFFIXED); break; case 'S': curr_comm->add_flags(COMMODITY_STYLE_SEPARATED); break; @@ -144,8 +144,8 @@ static void endElement(void *userData, const char *name) else if (std::strcmp(name, "quantity") == 0) { curr_entry->transactions.back()->amount.parse(data); if (curr_comm) { - std::string::size_type i = data.find('.'); - if (i != std::string::npos) { + string::size_type i = data.find('.'); + if (i != string::npos) { int precision = data.length() - i - 1; if (precision > curr_comm->precision()) curr_comm->set_precision(precision); @@ -162,7 +162,7 @@ static void endElement(void *userData, const char *name) static void dataHandler(void *userData, const char *s, int len) { if (! ignore) - data = std::string(s, len); + data = string(s, len); } bool xml_parser_t::test(std::istream& in) const @@ -191,7 +191,7 @@ bool xml_parser_t::test(std::istream& in) const unsigned int xml_parser_t::parse(std::istream& in, journal_t * journal, account_t * master, - const std::string * original_file) + const string * original_file) { char buf[BUFSIZ]; @@ -342,7 +342,7 @@ void xml_write_value(std::ostream& out, const value_t& value, out << "</value>\n"; } -void output_xml_string(std::ostream& out, const std::string& str) +void output_xml_string(std::ostream& out, const string& str) { for (const char * s = str.c_str(); *s; s++) { switch (*s) { @@ -419,7 +419,7 @@ void format_xml_entries::format_last_entry() output_stream << " <tr:generated/>\n"; if ((*i)->account) { - std::string name = (*i)->account->fullname(); + string name = (*i)->account->fullname(); if (name == "<Total>") name = "[TOTAL]"; else if (name == "<Unknown>") @@ -15,7 +15,7 @@ class xml_parser_t : public parser_t virtual unsigned int parse(std::istream& in, journal_t * journal, account_t * master = NULL, - const std::string * original_file = NULL); + const string * original_file = NULL); }; #endif @@ -1,9 +1,11 @@ #include "xpath.h" #include "debug.h" #include "util.h" +#if 0 #ifdef USE_BOOST_PYTHON #include "py_eval.h" #endif +#endif #include <fstream> namespace ledger { @@ -379,7 +381,11 @@ void xpath_t::token_t::next(std::istream& in, unsigned short flags) catch (amount_error * err) { // If the amount had no commodity, it must be an unambiguous // variable reference + + // jww (2007-04-19): There must be a more efficient way to do this! if (std::strcmp(err->what(), "No quantity specified for amount") == 0) { + delete err; + in.clear(); in.seekg(pos, std::ios::beg); @@ -408,13 +414,13 @@ void xpath_t::token_t::unexpected() case TOK_EOF: throw new parse_error("Unexpected end of expression"); case IDENT: - throw new parse_error(std::string("Unexpected symbol '") + + throw new parse_error(string("Unexpected symbol '") + value.to_string() + "'"); case VALUE: - throw new parse_error(std::string("Unexpected value '") + + throw new parse_error(string("Unexpected value '") + value.to_string() + "'"); default: - throw new parse_error(std::string("Unexpected operator '") + symbol + "'"); + throw new parse_error(string("Unexpected operator '") + symbol + "'"); } } @@ -422,15 +428,15 @@ void xpath_t::token_t::unexpected(char c, char wanted) { if ((unsigned char) c == 0xff) { if (wanted) - throw new parse_error(std::string("Missing '") + wanted + "'"); + throw new parse_error(string("Missing '") + wanted + "'"); else throw new parse_error("Unexpected end"); } else { if (wanted) - throw new parse_error(std::string("Invalid char '") + c + + throw new parse_error(string("Invalid char '") + c + "' (wanted '" + wanted + "')"); else - throw new parse_error(std::string("Invalid char '") + c + "'"); + throw new parse_error(string("Invalid char '") + c + "'"); } } @@ -443,17 +449,12 @@ xpath_t::op_t * xpath_t::wrap_value(const value_t& val) xpath_t::op_t * xpath_t::wrap_sequence(value_t::sequence_t * val) { - if (val->size() == 0) { + if (val->size() == 0) return wrap_value(false); - } - else if (val->size() == 1) { + else if (val->size() == 1) return wrap_value(val->front()); - } - else { - xpath_t::op_t * temp = new xpath_t::op_t(xpath_t::op_t::VALUE); - temp->valuep = new value_t(val); - return temp; - } + else + return wrap_value(val); } xpath_t::op_t * xpath_t::wrap_functor(functor_t * fobj) @@ -464,7 +465,7 @@ xpath_t::op_t * xpath_t::wrap_functor(functor_t * fobj) } #if 0 -xpath_t::op_t * xpath_t::wrap_mask(const std::string& pattern) +xpath_t::op_t * xpath_t::wrap_mask(const string& pattern) { xpath_t::op_t * temp = new xpath_t::op_t(xpath_t::op_t::MASK); temp->mask = new mask_t(pattern); @@ -472,7 +473,7 @@ xpath_t::op_t * xpath_t::wrap_mask(const std::string& pattern) } #endif -void xpath_t::scope_t::define(const std::string& name, op_t * def) +void xpath_t::scope_t::define(const string& name, op_t * def) { DEBUG_PRINT("ledger.xpath.syms", "Defining '" << name << "' = " << def); @@ -487,14 +488,14 @@ void xpath_t::scope_t::define(const std::string& name, op_t * def) std::pair<symbol_map::iterator, bool> result2 = symbols.insert(symbol_pair(name, def)); if (! result2.second) - throw new compile_error(std::string("Redefinition of '") + + throw new compile_error(string("Redefinition of '") + name + "' in same scope"); } def->acquire(); } xpath_t::op_t * -xpath_t::scope_t::lookup(const std::string& name) +xpath_t::scope_t::lookup(const string& name) { symbol_map::const_iterator i = symbols.find(name); if (i != symbols.end()) @@ -504,11 +505,11 @@ xpath_t::scope_t::lookup(const std::string& name) return NULL; } -void xpath_t::scope_t::define(const std::string& name, functor_t * def) { +void xpath_t::scope_t::define(const string& name, functor_t * def) { define(name, wrap_functor(def)); } -bool xpath_t::function_scope_t::resolve(const std::string& name, +bool xpath_t::function_scope_t::resolve(const string& name, value_t& result, scope_t * locals) { @@ -606,8 +607,8 @@ void xpath_t::op_t::get_value(value_t& result) const std::ostringstream buf; write(buf); throw new calc_error - (std::string("Cannot determine value of expression symbol '") + - buf.str() + "'"); + (string("Cannot determine value of expression symbol '") + + string(buf.str()) + "'"); } } } @@ -640,7 +641,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const lambda->functor = new python_functor_t(python_eval(buf)); eval->set_left(lambda); op_t * sym = new op_t(op_t::SYMBOL); - sym->name = new std::string("__ptr"); + sym->name = new string("__ptr"); eval->set_right(sym); node.reset(eval); @@ -653,13 +654,13 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const #endif /* USE_BOOST_PYTHON */ #endif - std::string ident = tok.value.to_string(); + string ident = tok.value.to_string(); if (std::isdigit(ident[0])) { node.reset(new op_t(op_t::ARG_INDEX)); node->arg_index = std::atol(ident.c_str()); } else { node.reset(new op_t(op_t::NODE_NAME)); - node->name = new std::string(ident); + node->name = new string(ident); } // An identifier followed by ( represents a function call @@ -689,7 +690,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const throw parse_error("@ symbol must be followed by attribute name"); node.reset(new op_t(op_t::ATTR_NAME)); - node->name = new std::string(tok.value.to_string()); + node->name = new string(tok.value.to_string()); break; #if 0 @@ -699,7 +700,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const throw parse_error("$ symbol must be followed by variable name"); node.reset(new op_t(op_t::VAR_NAME)); - node->name = new std::string(tok.value.to_string()); + node->name = new string(tok.value.to_string()); break; #endif @@ -724,7 +725,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const case token_t::LPAREN: node.reset(parse_value_expr(in, tflags | XPATH_PARSE_PARTIAL)); if (! node.get()) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); tok = next_token(in, tflags); if (tok.kind != token_t::RPAREN) @@ -819,7 +820,7 @@ xpath_t::parse_unary_expr(std::istream& in, unsigned short tflags) const case token_t::EXCLAM: { std::auto_ptr<op_t> texpr(parse_path_expr(in, tflags)); if (! texpr.get()) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); // A very quick optimization if (texpr->kind == op_t::VALUE) { @@ -835,7 +836,7 @@ xpath_t::parse_unary_expr(std::istream& in, unsigned short tflags) const case token_t::MINUS: { std::auto_ptr<op_t> texpr(parse_path_expr(in, tflags)); if (! texpr.get()) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); // A very quick optimization if (texpr->kind == op_t::VALUE) { @@ -852,7 +853,7 @@ xpath_t::parse_unary_expr(std::istream& in, unsigned short tflags) const case token_t::PERCENT: { std::auto_ptr<op_t> texpr(parse_path_expr(in, tflags)); if (! texpr.get()) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); // A very quick optimization if (texpr->kind == op_t::VALUE) { @@ -889,7 +890,7 @@ xpath_t::parse_union_expr(std::istream& in, unsigned short tflags) const node->set_left(prev.release()); node->set_right(parse_union_expr(in, tflags)); if (! node->right) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); } else { push_token(tok); @@ -912,7 +913,7 @@ xpath_t::parse_mul_expr(std::istream& in, unsigned short tflags) const node->set_left(prev.release()); node->set_right(parse_mul_expr(in, tflags)); if (! node->right) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); tok = next_token(in, tflags); @@ -938,7 +939,7 @@ xpath_t::parse_add_expr(std::istream& in, unsigned short tflags) const node->set_left(prev.release()); node->set_right(parse_add_expr(in, tflags)); if (! node->right) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); tok = next_token(in, tflags); @@ -1008,10 +1009,10 @@ xpath_t::parse_logic_expr(std::istream& in, unsigned short tflags) const if (! node->right) { if (tok.kind == token_t::PLUS) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); else - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); } } @@ -1033,7 +1034,7 @@ xpath_t::parse_and_expr(std::istream& in, unsigned short tflags) const node->set_left(prev.release()); node->set_right(parse_and_expr(in, tflags)); if (! node->right) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); } else { push_token(tok); @@ -1055,7 +1056,7 @@ xpath_t::parse_or_expr(std::istream& in, unsigned short tflags) const node->set_left(prev.release()); node->set_right(parse_or_expr(in, tflags)); if (! node->right) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); } else { push_token(tok); @@ -1078,14 +1079,14 @@ xpath_t::parse_querycolon_expr(std::istream& in, unsigned short tflags) const node->set_right(new op_t(op_t::O_COLON)); node->right->set_left(parse_querycolon_expr(in, tflags)); if (! node->right) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); tok = next_token(in, tflags); if (tok.kind != token_t::COLON) tok.unexpected(); // jww (2006-09-09): wanted : node->right->set_right(parse_querycolon_expr(in, tflags)); if (! node->right) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); } else { push_token(tok); @@ -1107,7 +1108,7 @@ xpath_t::parse_value_expr(std::istream& in, unsigned short tflags) const node->set_left(prev.release()); node->set_right(parse_value_expr(in, tflags)); if (! node->right) - throw new parse_error(std::string(tok.symbol) + + throw new parse_error(string(tok.symbol) + " operator not followed by argument"); tok = next_token(in, tflags); } @@ -1120,7 +1121,7 @@ xpath_t::parse_value_expr(std::istream& in, unsigned short tflags) const } } else if (! (tflags & XPATH_PARSE_PARTIAL)) { - throw new parse_error(std::string("Failed to parse value expression")); + throw new parse_error(string("Failed to parse value expression")); } return node.release(); @@ -1755,7 +1756,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, return func->compile(context, call_args.get(), resolve); } else { - throw new calc_error(std::string("Unknown function name '") + + throw new calc_error(string("Unknown function name '") + *left->name + "'"); } } @@ -1906,10 +1907,10 @@ void xpath_t::calc(value_t& result, node_t * node, scope_t * scope) const } } -xpath_t::context::context(const xpath_t& _xpath, - const op_t * _err_node, - const std::string& desc) throw() - : xpath(_xpath), err_node(_err_node), error_context(desc) +xpath_t::context::context(const xpath_t& _xpath, + const op_t * _err_node, + const string& desc) throw() + : error_context(desc), xpath(_xpath), err_node(_err_node) { _err_node->acquire(); } @@ -1939,7 +1940,7 @@ void xpath_t::context::describe(std::ostream& out) const throw() out << std::endl; if (found) { out << " "; - for (int i = 0; i < end - start; i++) { + for (unsigned int i = 0; i < end - start; i++) { if (i >= begin - start) out << "^"; else @@ -1963,7 +1964,7 @@ bool xpath_t::op_t::write(std::ostream& out, found = true; } - std::string symbol; + string symbol; switch (kind) { case VALUE: @@ -1992,6 +1993,16 @@ bool xpath_t::op_t::write(std::ostream& out, case value_t::STRING: out << '"' << *valuep << '"'; break; + + case value_t::XML_NODE: + out << '<' << valuep << '>'; + break; + case value_t::POINTER: + out << '&' << valuep; + break; + case value_t::SEQUENCE: + out << '~' << valuep << '~'; + break; } break; @@ -2406,7 +2417,7 @@ value_t py_calc(xpath_t::op_t& xpath_t, const T& item) return result; } -xpath_t::op_t * py_parse_xpath_t_1(const std::string& str) +xpath_t::op_t * py_parse_xpath_t_1(const string& str) { return parse_xpath_t(str); } @@ -2449,12 +2460,12 @@ void export_xpath() return_value_policy<manage_new_object>()); class_< item_predicate<transaction_t> > - ("TransactionPredicate", init<std::string>()) + ("TransactionPredicate", init<string>()) .def("__call__", &item_predicate<transaction_t>::operator()) ; class_< item_predicate<account_t> > - ("AccountPredicate", init<std::string>()) + ("AccountPredicate", init<string>()) .def("__call__", &item_predicate<account_t>::operator()) ; @@ -20,7 +20,7 @@ public: class parse_error : public error { public: - parse_error(const std::string& _reason, + parse_error(const string& _reason, error_context * _ctxt = NULL) throw() : error(_reason, _ctxt) {} virtual ~parse_error() throw() {} @@ -28,7 +28,7 @@ public: class compile_error : public error { public: - compile_error(const std::string& _reason, + compile_error(const string& _reason, error_context * _ctxt = NULL) throw() : error(_reason, _ctxt) {} virtual ~compile_error() throw() {} @@ -36,7 +36,7 @@ public: class calc_error : public error { public: - calc_error(const std::string& _reason, + calc_error(const string& _reason, error_context * _ctxt = NULL) throw() : error(_reason, _ctxt) {} virtual ~calc_error() throw() {} @@ -49,7 +49,7 @@ public: context(const xpath_t& _xpath, const op_t * _err_node, - const std::string& desc = "") throw(); + const string& desc = "") throw(); virtual ~context() throw(); virtual void describe(std::ostream& out) const throw(); @@ -60,16 +60,16 @@ public: class functor_t { protected: - std::string fname; + string fname; public: bool wants_args; - functor_t(const std::string& _fname, bool _wants_args = false) + functor_t(const string& _fname, bool _wants_args = false) : fname(_fname), wants_args(_wants_args) {} virtual ~functor_t() {} virtual void operator()(value_t& result, scope_t * locals) = 0; - virtual std::string name() const { return fname; } + virtual string name() const { return fname; } }; template <typename T, typename U> @@ -78,7 +78,7 @@ public: T * ptr; U T::*dptr; - member_functor_t(const std::string& _name, T * _ptr, U T::*_dptr) + member_functor_t(const string& _name, T * _ptr, U T::*_dptr) : functor_t(_name, false), ptr(_ptr), dptr(_dptr) {} virtual void operator()(value_t& result, scope_t * locals) { @@ -89,12 +89,12 @@ public: }; template <typename T> - class member_functor_t<T, std::string> : public functor_t { + class member_functor_t<T, string> : public functor_t { public: T * ptr; - std::string T::*dptr; + string T::*dptr; - member_functor_t(const std::string& _name, T * _ptr, std::string T::*_dptr) + member_functor_t(const string& _name, T * _ptr, string T::*_dptr) : functor_t(_name, false), ptr(_ptr), dptr(_dptr) {} virtual void operator()(value_t& result, scope_t * locals) { @@ -110,7 +110,7 @@ public: T * ptr; void (T::*mptr)(value_t& result); - memfun_functor_t(const std::string& _name, T * _ptr, + memfun_functor_t(const string& _name, T * _ptr, void (T::*_mptr)(value_t& result)) : functor_t(_name, false), ptr(_ptr), mptr(_mptr) {} @@ -129,7 +129,7 @@ public: T * ptr; void (T::*mptr)(value_t& result, scope_t * locals); - memfun_args_functor_t(const std::string& _name, T * _ptr, + memfun_args_functor_t(const string& _name, T * _ptr, void (T::*_mptr)(value_t& result, scope_t * locals)) : functor_t(_name, true), ptr(_ptr), mptr(_mptr) {} @@ -144,25 +144,25 @@ public: static op_t * wrap_sequence(value_t::sequence_t * val); static op_t * wrap_functor(functor_t * fobj); #if 0 - static op_t * wrap_mask(const std::string& pattern); + static op_t * wrap_mask(const string& pattern); #endif template <typename T, typename U> static op_t * - make_functor(const std::string& name = "<data>", T * ptr, U T::*mptr) { + make_functor(const string& name = "<data>", T * ptr, U T::*mptr) { return wrap_functor(new member_functor_t<T, U>(name, ptr, mptr)); } template <typename T> static op_t * - make_functor(const std::string& fname = "<func>", T * ptr, + make_functor(const string& fname = "<func>", T * ptr, void (T::*mptr)(value_t& result)) { return wrap_functor(new memfun_functor_t<T>(fname, ptr, mptr)); } template <typename T> static op_t * - make_functor(const std::string& fname = "<func>", T * ptr, + make_functor(const string& fname = "<func>", T * ptr, void (T::*mptr)(value_t& result, scope_t * locals)) { return wrap_functor(new memfun_args_functor_t<T>(fname, ptr, mptr)); } @@ -173,8 +173,8 @@ public: public: class scope_t { - typedef std::map<const std::string, op_t *> symbol_map; - typedef std::pair<const std::string, op_t *> symbol_pair; + typedef std::map<const string, op_t *> symbol_map; + typedef std::pair<const string, op_t *> symbol_pair; symbol_map symbols; @@ -201,16 +201,16 @@ public: } public: - virtual void define(const std::string& name, op_t * def); - virtual bool resolve(const std::string& name, value_t& result, + virtual void define(const string& name, op_t * def); + virtual bool resolve(const string& name, value_t& result, scope_t * locals = NULL) { if (parent) return parent->resolve(name, result, locals); return false; } - virtual op_t * lookup(const std::string& name); + virtual op_t * lookup(const string& name); - void define(const std::string& name, functor_t * def); + void define(const string& name, functor_t * def); friend struct op_t; }; @@ -227,7 +227,7 @@ public: : scope_t(_parent, STATIC), sequence(_sequence), value(_value), index(_index) {} - virtual bool resolve(const std::string& name, value_t& result, + virtual bool resolve(const string& name, value_t& result, scope_t * locals = NULL); }; @@ -319,6 +319,7 @@ private: void clear() { kind = UNKNOWN; length = 0; + value = 0L; symbol[0] = '\0'; symbol[1] = '\0'; @@ -408,7 +409,7 @@ public: union { value_t * valuep; // used by constant VALUE - std::string * name; // used by constant SYMBOL + string * name; // used by constant SYMBOL unsigned int arg_index; // used by ARG_INDEX and O_ARG functor_t * functor; // used by terminal FUNCTOR unsigned int name_id; // used by NODE_NAME and ATTR_NAME @@ -582,7 +583,7 @@ public: op_t * parse_expr(std::istream& in, unsigned short flags = XPATH_PARSE_RELAXED) const; - op_t * parse_expr(const std::string& str, + op_t * parse_expr(const string& str, unsigned short tflags = XPATH_PARSE_RELAXED) const { std::istringstream stream(str); @@ -599,7 +600,7 @@ public: op_t * parse_expr(const char * p, unsigned short tflags = XPATH_PARSE_RELAXED) const { - return parse_expr(std::string(p), tflags); + return parse_expr(string(p), tflags); } bool write(std::ostream& out, @@ -613,7 +614,7 @@ public: } public: - std::string expr; + string expr; unsigned short flags; // flags used to parse `expr' xpath_t() : ptr(NULL), use_lookahead(false), flags(0) { @@ -623,10 +624,10 @@ public: TRACE_CTOR("xpath_t(op_t *)"); } - xpath_t(const std::string& _expr, + xpath_t(const string& _expr, unsigned short _flags = XPATH_PARSE_RELAXED) : ptr(NULL), use_lookahead(false), flags(0) { - TRACE_CTOR("xpath_t(const std::string&, unsigned short)"); + TRACE_CTOR("xpath_t(const string&, unsigned short)"); if (! _expr.empty()) parse(_expr, _flags); } @@ -642,11 +643,10 @@ public: } virtual ~xpath_t() { TRACE_DTOR("xpath_t"); - if (ptr) - ptr->release(); + reset(NULL); } - xpath_t& operator=(const std::string& _expr) { + xpath_t& operator=(const string& _expr) { parse(_expr); return *this; } @@ -666,11 +666,11 @@ public: operator bool() const throw() { return ptr != NULL; } - operator std::string() const throw() { + operator string() const throw() { return expr; } - void parse(const std::string& _expr, unsigned short _flags = XPATH_PARSE_RELAXED) { + void parse(const string& _expr, unsigned short _flags = XPATH_PARSE_RELAXED) { expr = _expr; flags = _flags; op_t * tmp = parse_expr(_expr, _flags); @@ -685,7 +685,7 @@ public: reset(tmp ? tmp->acquire() : NULL); } - void compile(const std::string& _expr, scope_t * scope = NULL, + void compile(const string& _expr, scope_t * scope = NULL, unsigned short _flags = XPATH_PARSE_RELAXED) { parse(_expr, _flags); // jww (2006-09-24): fix @@ -699,9 +699,12 @@ public: } void compile(document_t * document, scope_t * scope = NULL) { - if (! document) - document = new xml::document_t; - compile(document->top, scope); + if (! document) { + std::auto_ptr<document_t> tdoc(new xml::document_t); + compile(tdoc->top, scope); + } else { + compile(document->top, scope); + } } void compile(node_t * top_node, scope_t * scope = NULL) { if (ptr) { @@ -731,7 +734,7 @@ public: return temp; } - static value_t eval(const std::string& _expr, document_t * document, + static value_t eval(const string& _expr, document_t * document, scope_t * scope = NULL) { xpath_t temp(_expr); return temp.calc(document, scope); |