summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2004-08-29 23:32:29 -0400
committerJohn Wiegley <johnw@newartisans.com>2004-08-29 23:32:29 -0400
commit63367e3aac062a7b55a3ba5c36a6c7fffbb6e2cc (patch)
tree6af161c7d0a7ca78a26f8b1f1f57426acddf9be9
parent2d62f7b633bdaa39c650bb67425514cf1e66a4dd (diff)
downloadfork-ledger-63367e3aac062a7b55a3ba5c36a6c7fffbb6e2cc.tar.gz
fork-ledger-63367e3aac062a7b55a3ba5c36a6c7fffbb6e2cc.tar.bz2
fork-ledger-63367e3aac062a7b55a3ba5c36a6c7fffbb6e2cc.zip
the amount/balance/value logic is now a library, completely separate from ledger
-rw-r--r--Makefile.am42
-rwxr-xr-xacprep2
-rw-r--r--amount.cc203
-rw-r--r--amount.h69
-rw-r--r--autoxact.cc2
-rw-r--r--balance.cc105
-rw-r--r--balance.h91
-rw-r--r--binary.cc29
-rw-r--r--binary.h5
-rw-r--r--error.h6
-rw-r--r--format.cc31
-rw-r--r--format.h52
-rw-r--r--journal.cc18
-rw-r--r--ledger.h61
-rw-r--r--main.cc27
-rw-r--r--python.cc7
-rwxr-xr-xsetup.py6
-rw-r--r--valexpr.cc3
-rw-r--r--valexpr.h25
-rw-r--r--value.cc79
-rw-r--r--value.h37
-rw-r--r--walk.cc136
-rw-r--r--walk.h113
23 files changed, 613 insertions, 536 deletions
diff --git a/Makefile.am b/Makefile.am
index 4b3d0ab0..191017d2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,11 @@
-lib_LTLIBRARIES = libledger.la
-libledger_la_SOURCES = amount.cc autoxact.cc balance.cc binary.cc config.cc \
- datetime.cc format.cc journal.cc option.cc parser.cc qif.cc quotes.cc \
- textual.cc valexpr.cc value.cc walk.cc
+lib_LTLIBRARIES = libamounts.la
+libamounts_la_SOURCES = amount.cc balance.cc value.cc
+libamounts_la_LDFLAGS = -version-info 2:0
+
+lib_LTLIBRARIES += libledger.la
+libledger_la_SOURCES = autoxact.cc binary.cc config.cc datetime.cc \
+ format.cc journal.cc option.cc parser.cc qif.cc quotes.cc \
+ textual.cc valexpr.cc walk.cc
if READ_GNUCASH
libledger_la_SOURCES += gnucash.cc
endif
@@ -18,12 +22,13 @@ if DEBUG
ledger_CXXFLAGS = -DDEBUG_LEVEL=4
endif
ledger_SOURCES = main.cc
-ledger_LDADD = $(LIBOBJS) libledger.la
+ledger_LDADD = $(LIBOBJS) libamounts.la libledger.la
nobase_include_HEADERS = \
amount.h \
- autoxact.h \
balance.h \
+ value.h \
+ autoxact.h \
binary.h \
config.h \
datetime.h \
@@ -38,7 +43,6 @@ nobase_include_HEADERS = \
quotes.h \
textual.h \
valexpr.h \
- value.h \
walk.h
info_TEXINFOS = ledger.texi
@@ -47,10 +51,14 @@ info_TEXINFOS = ledger.texi
if HAVE_PYTHON
if HAVE_BOOST_PYTHON
-noinst_LIBRARIES = libledger_bpy.a
-libledger_bpy_a_SOURCES = amount.cc autoxact.cc balance.cc binary.cc config.cc \
- datetime.cc format.cc journal.cc option.cc parser.cc qif.cc quotes.cc \
- textual.cc valexpr.cc value.cc walk.cc
+noinst_LIBRARIES = libamounts_bpy.a
+libamounts_bpy_a_SOURCES = amount.cc balance.cc value.cc
+libamounts_bpy_a_CXXFLAGS = -DUSE_BOOST_PYTHON=1
+
+noinst_LIBRARIES += libledger_bpy.a
+libledger_bpy_a_SOURCES = autoxact.cc binary.cc config.cc datetime.cc \
+ format.cc journal.cc option.cc parser.cc qif.cc quotes.cc \
+ textual.cc valexpr.cc walk.cc
libledger_bpy_a_CXXFLAGS = -DUSE_BOOST_PYTHON=1
if READ_GNUCASH
libledger_bpy_a_SOURCES += gnucash.cc
@@ -60,13 +68,17 @@ libledger_bpy_a_CXXFLAGS += -DDEBUG_LEVEL=4
libledger_bpy_a_SOURCES += debug.cc
endif
-bin_PROGRAMS += ledger.so
+bin_PROGRAMS += amounts.so ledger.so
+
+amounts.so: pyamounts.cc libamounts_bpy.a
+ CFLAGS="$(CPPFLAGS) -L." python setup_amounts.py build --build-lib=.
-ledger.so: python.cc libledger_bpy.a
- CFLAGS="$(CPPFLAGS) -L." python setup.py build --build-lib=.
+ledger.so: pyledger.cc libamounts_bpy.a libledger_bpy.a
+ CFLAGS="$(CPPFLAGS) -L." python setup_ledger.py build --build-lib=.
install-exec-hook:
- CFLAGS="$(CPPFLAGS) -L." python setup.py install --prefix=$(DESTDIR)
+ CFLAGS="$(CPPFLAGS) -L." python setup_amounts.py install --prefix=$(DESTDIR)
+ CFLAGS="$(CPPFLAGS) -L." python setup_ledger.py install --prefix=$(DESTDIR)
endif
endif
diff --git a/acprep b/acprep
index 191636d3..ba5706bb 100755
--- a/acprep
+++ b/acprep
@@ -1,6 +1,6 @@
#!/bin/sh
-libtoolize --automake -fc
+libtoolize --automake -f -c
aclocal
autoheader
touch AUTHORS ChangeLog
diff --git a/amount.cc b/amount.cc
index c4293aee..1e7c6d5c 100644
--- a/amount.cc
+++ b/amount.cc
@@ -1,10 +1,8 @@
#include "amount.h"
-#include "binary.h"
-#include "error.h"
#include "util.h"
#include <sstream>
-#include <cstring>
+#include <deque>
#include "gmp.h"
@@ -21,23 +19,17 @@ class amount_t::bigint_t {
unsigned int index;
bigint_t() : prec(0), flags(0), ref(1), index(0) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t::bigint_t");
mpz_init(val);
}
bigint_t(mpz_t _val) : prec(0), flags(0), ref(1), index(0) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t::bigint_t");
mpz_init_set(val, _val);
}
bigint_t(const bigint_t& other)
: prec(other.prec), flags(0), ref(1), index(0) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t::bigint_t");
mpz_init_set(val, other.val);
}
~bigint_t() {
- DEBUG_PRINT("ledger.memory.dtors", "dtor amount_t::bigint_t");
-#if DEBUG_LEVEL >= BETA
assert(ref == 0);
-#endif
mpz_clear(val);
}
};
@@ -56,7 +48,12 @@ commodity_t::updater_t * commodity_t::updater = NULL;
commodities_map commodity_t::commodities;
commodity_t * commodity_t::null_commodity;
-void initialize_amounts()
+static struct _init_amounts {
+ _init_amounts();
+ ~_init_amounts();
+} _init_obj;
+
+_init_amounts::_init_amounts()
{
mpz_init(temp);
mpz_init(divisor);
@@ -67,6 +64,26 @@ void initialize_amounts()
commodity_t::null_commodity = commodity_t::find_commodity("", true);
}
+_init_amounts::~_init_amounts()
+{
+ mpz_clear(divisor);
+ mpz_clear(temp);
+
+ if (commodity_t::updater) {
+ delete commodity_t::updater;
+ commodity_t::updater = NULL;
+ }
+
+ for (commodities_map::iterator i = commodity_t::commodities.begin();
+ i != commodity_t::commodities.end();
+ i++)
+ delete (*i).second;
+
+ commodity_t::commodities.clear();
+
+ true_value.ref--;
+}
+
void clean_commodity_history(char * item_pool, char * item_pool_end)
{
for (commodities_map::iterator i = commodity_t::commodities.begin();
@@ -94,26 +111,6 @@ void clean_commodity_history(char * item_pool, char * item_pool_end)
}
}
-void shutdown_amounts()
-{
- mpz_clear(divisor);
- mpz_clear(temp);
-
- if (commodity_t::updater) {
- delete commodity_t::updater;
- commodity_t::updater = NULL;
- }
-
- for (commodities_map::iterator i = commodity_t::commodities.begin();
- i != commodity_t::commodities.end();
- i++)
- delete (*i).second;
-
- commodity_t::commodities.clear();
-
- true_value.ref--;
-}
-
static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec)
{
// Round `value', with an encoding precision of `value_prec', to a
@@ -162,21 +159,17 @@ static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec)
amount_t::amount_t(const bool value)
{
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
-
if (value) {
- quantity = &true_value;
+ quantity = &true_value;
quantity->ref++;
} else {
- quantity = NULL;
+ quantity = NULL;
}
commodity_ = NULL;
}
amount_t::amount_t(const int value)
{
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
-
if (value != 0) {
quantity = new bigint_t;
mpz_set_si(MPZ(quantity), value);
@@ -188,8 +181,6 @@ amount_t::amount_t(const int value)
amount_t::amount_t(const unsigned int value)
{
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
-
if (value != 0) {
quantity = new bigint_t;
mpz_set_ui(MPZ(quantity), value);
@@ -201,8 +192,6 @@ amount_t::amount_t(const unsigned int value)
amount_t::amount_t(const double value)
{
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
-
if (value != 0.0) {
quantity = new bigint_t;
mpz_set_d(MPZ(quantity), value);
@@ -668,7 +657,7 @@ std::ostream& operator<<(std::ostream& _out, const amount_t& amt)
std::free(p);
}
else {
- strings_list strs;
+ std::deque<std::string> strs;
char buf[4];
for (int powers = 0; true; powers += 3) {
@@ -687,7 +676,7 @@ std::ostream& operator<<(std::ostream& _out, const amount_t& amt)
bool printed = false;
- for (strings_list::reverse_iterator i = strs.rbegin();
+ for (std::deque<std::string>::reverse_iterator i = strs.rbegin();
i != strs.rend();
i++) {
if (printed) {
@@ -858,8 +847,81 @@ void amount_t::parse(const std::string& str)
}
+char * bigints;
+char * bigints_next;
+unsigned int bigints_index;
+unsigned int bigints_count;
+
+void amount_t::read_quantity(char *& data)
+{
+ char byte = *data++;;
+
+ if (byte == 0) {
+ quantity = NULL;
+ }
+ else if (byte == 1) {
+ quantity = new((bigint_t *)bigints_next) bigint_t;
+ bigints_next += sizeof(bigint_t);
+ quantity->flags |= BIGINT_BULK_ALLOC;
+
+ unsigned short len = *((unsigned short *) data);
+ data += sizeof(unsigned short);
+ mpz_import(MPZ(quantity), len / sizeof(short), 1, sizeof(short),
+ 0, 0, data);
+ data += len;
+
+ char negative = *data++;
+ if (negative)
+ mpz_neg(MPZ(quantity), MPZ(quantity));
+
+ quantity->prec = *((unsigned short *) data);
+ data += sizeof(unsigned short);
+ } else {
+ unsigned int index = *((unsigned int *) data);
+ data += sizeof(unsigned int);
+
+ quantity = (bigint_t *) (bigints + (index - 1) * sizeof(bigint_t));
+ quantity->ref++;
+ }
+}
+
static char buf[4096];
+void amount_t::read_quantity(std::istream& in)
+{
+ static std::deque<bigint_t *> _bigints;
+
+ char byte;
+ in.read(&byte, sizeof(byte));
+
+ if (byte == 0) {
+ quantity = NULL;
+ }
+ else if (byte == 1) {
+ quantity = new bigint_t;
+ _bigints.push_back(quantity);
+
+ unsigned short len;
+ in.read((char *)&len, sizeof(len));
+ assert(len < 4096);
+ in.read(buf, len);
+ mpz_import(MPZ(quantity), len / sizeof(short), 1, sizeof(short),
+ 0, 0, buf);
+
+ char negative;
+ in.read(&negative, sizeof(negative));
+ if (negative)
+ mpz_neg(MPZ(quantity), MPZ(quantity));
+
+ in.read((char *)&quantity->prec, sizeof(quantity->prec));
+ } else {
+ unsigned int index;
+ in.read((char *)&index, sizeof(index));
+ quantity = _bigints[index - 1];
+ quantity->ref++;
+ }
+}
+
void amount_t::write_quantity(std::ostream& out) const
{
char byte;
@@ -883,6 +945,7 @@ void amount_t::write_quantity(std::ostream& out) const
out.write((char *)&len, sizeof(len));
if (len) {
+ assert(len < 4096);
out.write(buf, len);
byte = mpz_sgn(MPZ(quantity)) < 0 ? 1 : 0;
@@ -901,38 +964,6 @@ void amount_t::write_quantity(std::ostream& out) const
}
}
-void amount_t::read_quantity(char *& data)
-{
- char byte = *data++;;
-
- if (byte == 0) {
- quantity = NULL;
- }
- else if (byte == 1) {
- quantity = new(bigints_next++) bigint_t;
- quantity->flags |= BIGINT_BULK_ALLOC;
-
- unsigned short len = *((unsigned short *) data);
- data += sizeof(unsigned short);
- mpz_import(MPZ(quantity), len / sizeof(short), 1, sizeof(short),
- 0, 0, data);
- data += len;
-
- char negative = *data++;
- if (negative)
- mpz_neg(MPZ(quantity), MPZ(quantity));
-
- quantity->prec = *((unsigned short *) data);
- data += sizeof(unsigned short);
- } else {
- unsigned int index = *((unsigned int *) data);
- data += sizeof(unsigned int);
-
- quantity = bigints + (index - 1);
- quantity->ref++;
- }
-}
-
bool amount_t::valid() const
{
if (quantity) {
@@ -1039,30 +1070,38 @@ void export_amount()
.def("commodity", &amount_t::commodity,
return_value_policy<reference_existing_object>())
.def("set_commodity", &amount_t::set_commodity)
+ .def("clear_commodity", &amount_t::clear_commodity)
.def(self += self)
+ .def(self += int())
.def(self + self)
+ .def(self + int())
.def(self -= self)
+ .def(self -= int())
.def(self - self)
+ .def(self - int())
.def(self *= self)
+ .def(self *= int())
.def(self * self)
+ .def(self * int())
.def(self /= self)
+ .def(self /= int())
.def(self / self)
-
- .def(self < int())
- .def(self <= int())
- .def(self > int())
- .def(self >= int())
- .def(self == int())
- .def(self != int())
+ .def(self / int())
+ .def(- self)
.def(self < self)
+ .def(self < int())
.def(self <= self)
+ .def(self <= int())
.def(self > self)
+ .def(self > int())
.def(self >= self)
+ .def(self >= int())
.def(self == self)
+ .def(self == int())
.def(self != self)
- .def(- self)
+ .def(self != int())
.def(! self)
.def(abs(self))
diff --git a/amount.h b/amount.h
index bf7457f0..d58bd6e6 100644
--- a/amount.h
+++ b/amount.h
@@ -6,8 +6,8 @@
#include <ctime>
#include <cctype>
#include <iostream>
-
-#include "debug.h"
+#include <cassert>
+#include <exception>
namespace ledger {
@@ -41,22 +41,17 @@ class amount_t
public:
// constructors
- amount_t() : quantity(NULL), commodity_(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
- }
+ amount_t() : quantity(NULL), commodity_(NULL) {}
amount_t(const amount_t& amt) : quantity(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
if (amt.quantity)
_copy(amt);
else
commodity_ = NULL;
}
amount_t(const std::string& value) : quantity(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
parse(value);
}
amount_t(const char * value) : quantity(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor amount_t");
parse(value);
}
amount_t(const bool value);
@@ -66,7 +61,6 @@ class amount_t
// destructor
~amount_t() {
- DEBUG_PRINT("ledger.memory.dtors", "dtor amount_t");
if (quantity)
_release();
}
@@ -75,6 +69,9 @@ class amount_t
void set_commodity(commodity_t& comm) {
commodity_ = &comm;
}
+ void clear_commodity() {
+ commodity_ = NULL;
+ }
// assignment operator
amount_t& operator=(const amount_t& amt);
@@ -94,6 +91,19 @@ class amount_t
amount_t& operator*=(const amount_t& amt);
amount_t& operator/=(const amount_t& amt);
+ amount_t& operator+=(const int value) {
+ return *this += amount_t(value);
+ }
+ amount_t& operator-=(const int value) {
+ return *this -= amount_t(value);
+ }
+ amount_t& operator*=(const int value) {
+ return *this *= amount_t(value);
+ }
+ amount_t& operator/=(const int value) {
+ return *this /= amount_t(value);
+ }
+
// simple arithmetic
amount_t operator+(const amount_t& amt) const {
amount_t temp = *this;
@@ -116,6 +126,27 @@ class amount_t
return temp;
}
+ amount_t operator+(const int value) const {
+ amount_t temp = *this;
+ temp += value;
+ return temp;
+ }
+ amount_t operator-(const int value) const {
+ amount_t temp = *this;
+ temp -= value;
+ return temp;
+ }
+ amount_t operator*(const int value) const {
+ amount_t temp = *this;
+ temp *= value;
+ return temp;
+ }
+ amount_t operator/(const int value) const {
+ amount_t temp = *this;
+ temp /= value;
+ return temp;
+ }
+
// unary negation
void negate();
amount_t negated() const {
@@ -172,6 +203,7 @@ class amount_t
void parse(const std::string& str);
void read_quantity(char *& data);
+ void read_quantity(std::istream& in);
void write_quantity(std::ostream& out) const;
bool valid() const;
@@ -285,14 +317,8 @@ class commodity_t
unsigned int _flags = COMMODITY_STYLE_DEFAULTS)
: symbol(_symbol), quote(false), precision(_precision),
flags(_flags), last_lookup(0) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor commodity_t");
check_symbol();
}
-#ifdef DEBUG_ENABLED
- ~commodity_t() {
- DEBUG_PRINT("ledger.memory.dtors", "dtor commodity_t");
- }
-#endif
operator bool() const {
return this != null_commodity;
@@ -346,7 +372,18 @@ inline commodity_t& amount_t::commodity() const {
return *commodity_t::null_commodity;
else
return *commodity_;
- }
+}
+
+class amount_error : public std::exception {
+ std::string reason;
+ public:
+ amount_error(const std::string& _reason) throw() : reason(_reason) {}
+ virtual ~amount_error() throw() {}
+
+ virtual const char* what() const throw() {
+ return reason.c_str();
+ }
+};
} // namespace ledger
diff --git a/autoxact.cc b/autoxact.cc
index 165ebede..d358daf3 100644
--- a/autoxact.cc
+++ b/autoxact.cc
@@ -10,7 +10,7 @@ void automated_transaction_t::extend_entry(entry_t * entry)
for (transactions_deque::iterator i = initial_xacts.begin();
i != initial_xacts.end();
i++)
- if (predicate(*i))
+ if (predicate(**i))
for (transactions_deque::iterator t = transactions.begin();
t != transactions.end();
t++) {
diff --git a/balance.cc b/balance.cc
index 69066f97..14ce1615 100644
--- a/balance.cc
+++ b/balance.cc
@@ -1,5 +1,4 @@
#include "balance.h"
-#include "ledger.h"
#include <deque>
@@ -84,40 +83,6 @@ void balance_t::write(std::ostream& out,
}
}
-balance_pair_t::balance_pair_t(const transaction_t& xact)
- : quantity(xact.amount), cost(NULL)
-{
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
- if (xact.cost)
- cost = new balance_t(*xact.cost);
-}
-
-balance_pair_t& balance_pair_t::operator+=(const transaction_t& xact)
-{
- if (xact.cost && ! cost)
- cost = new balance_t(quantity);
-
- quantity += xact.amount;
-
- if (cost)
- *cost += xact.cost ? *xact.cost : xact.amount;
-
- return *this;
-}
-
-balance_pair_t& balance_pair_t::operator-=(const transaction_t& xact)
-{
- if (xact.cost && ! cost)
- cost = new balance_t(quantity);
-
- quantity -= xact.amount;
-
- if (cost)
- *cost -= xact.cost ? *xact.cost : xact.amount;
-
- return *this;
-}
-
} // namespace ledger
#ifdef USE_BOOST_PYTHON
@@ -169,10 +134,11 @@ void export_balance()
.def(! self)
.def(abs(self))
- //.def(str(self))
+#if 0
+ .def(str(self))
+#endif
- .def("negate", &balance_t::negate,
- return_value_policy<reference_existing_object>())
+ .def("negate", &balance_t::negate)
.def("amount", &balance_t::amount)
.def("value", &balance_t::value)
.def("write", &balance_t::write)
@@ -180,6 +146,69 @@ void export_balance()
;
class_< balance_pair_t > ("BalancePair")
+ .def(init<balance_pair_t>())
+ .def(init<balance_t>())
+ .def(init<amount_t>())
+ .def(init<int>())
+ .def(init<unsigned int>())
+ .def(init<double>())
+
+ .def(self += self)
+ .def(self += other<balance_t>())
+ .def(self += other<amount_t>())
+ .def(self + self)
+ .def(self + other<balance_t>())
+ .def(self + other<amount_t>())
+ .def(self -= self)
+ .def(self -= other<balance_t>())
+ .def(self -= other<amount_t>())
+ .def(self - self)
+ .def(self - other<balance_t>())
+ .def(self - other<amount_t>())
+ .def(self *= self)
+ .def(self *= other<balance_t>())
+ .def(self *= other<amount_t>())
+ .def(self * self)
+ .def(self * other<balance_t>())
+ .def(self * other<amount_t>())
+ .def(self /= self)
+ .def(self /= other<balance_t>())
+ .def(self /= other<amount_t>())
+ .def(self / self)
+ .def(self / other<balance_t>())
+ .def(self / other<amount_t>())
+ .def(- self)
+
+ .def(self < self)
+ .def(self < other<balance_t>())
+ .def(self < other<amount_t>())
+ .def(self <= self)
+ .def(self <= other<balance_t>())
+ .def(self <= other<amount_t>())
+ .def(self > self)
+ .def(self > other<balance_t>())
+ .def(self > other<amount_t>())
+ .def(self >= self)
+ .def(self >= other<balance_t>())
+ .def(self >= other<amount_t>())
+ .def(self == self)
+ .def(self == other<balance_t>())
+ .def(self == other<amount_t>())
+ .def(self != self)
+ .def(self != other<balance_t>())
+ .def(self != other<amount_t>())
+ .def(! self)
+
+ .def(abs(self))
+#if 0
+ .def(str(self))
+#endif
+
+ .def("negate", &balance_pair_t::negate)
+ .def("amount", &balance_pair_t::amount)
+ .def("value", &balance_pair_t::value)
+ .def("write", &balance_pair_t::write)
+ .def("valid", &balance_pair_t::valid)
;
}
diff --git a/balance.h b/balance.h
index 2c2683f0..0740ea59 100644
--- a/balance.h
+++ b/balance.h
@@ -1,13 +1,12 @@
#ifndef _BALANCE_H
#define _BALANCE_H
+#include "amount.h"
+
#include <map>
#include <ctime>
#include <iostream>
-#include "amount.h"
-#include "error.h"
-
namespace ledger {
typedef std::map<const commodity_t *, amount_t> amounts_map;
@@ -28,47 +27,33 @@ class balance_t
}
// constructors
- balance_t() {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
- }
+ balance_t() {}
balance_t(const balance_t& bal) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
for (amounts_map::const_iterator i = bal.amounts.begin();
i != bal.amounts.end();
i++)
*this += (*i).second;
}
balance_t(const amount_t& amt) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
if (amt)
amounts.insert(amounts_pair(&amt.commodity(), amt));
}
balance_t(const int value) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
amount_t amt(value);
if (amt)
amounts.insert(amounts_pair(&amt.commodity(), amt));
}
balance_t(const unsigned int value) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
amount_t amt(value);
if (amt)
amounts.insert(amounts_pair(&amt.commodity(), amt));
}
balance_t(const double value) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_t");
amount_t amt(value);
if (amt)
amounts.insert(amounts_pair(&amt.commodity(), amt));
}
- // destructor
-#ifdef DEBUG_ENABLED
- ~balance_t() {
- DEBUG_PRINT("ledger.memory.dtors", "dtor balance_t");
- }
-#endif
-
// assignment operator
balance_t& operator=(const balance_t& bal) {
if (this != &bal) {
@@ -351,12 +336,11 @@ class balance_t
#endif
// unary negation
- balance_t& negate() {
+ void negate() {
for (amounts_map::iterator i = amounts.begin();
i != amounts.end();
i++)
(*i).second.negate();
- return *this;
}
balance_t negated() const {
balance_t temp = *this;
@@ -372,7 +356,8 @@ class balance_t
if (amounts.size() == 1)
return (*amounts.begin()).second;
else
- throw error("Cannot convert a balance with multiple commodities to an amount");
+ throw amount_error("Cannot convert a balance with "
+ "multiple commodities to an amount");
}
operator bool() const {
for (amounts_map::const_iterator i = amounts.begin();
@@ -404,60 +389,32 @@ inline balance_t abs(const balance_t& bal) {
return temp;
}
-#ifdef DEBUG_ENABLED
-inline std::ostream& operator<<(std::ostream& out, const balance_t& bal) {
- bal.write(out, 12);
- return out;
-}
-#endif
-
-class transaction_t;
-
class balance_pair_t
{
public:
balance_t quantity;
balance_t * cost;
- bool valid() const {
- return quantity.valid() && (! cost || cost->valid());
- }
-
// constructors
- balance_pair_t() : cost(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
- }
+ balance_pair_t() : cost(NULL) {}
balance_pair_t(const balance_pair_t& bal_pair)
: quantity(bal_pair.quantity), cost(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
if (bal_pair.cost)
cost = new balance_t(*bal_pair.cost);
}
balance_pair_t(const balance_t& _quantity)
- : quantity(_quantity), cost(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
- }
+ : quantity(_quantity), cost(NULL) {}
balance_pair_t(const amount_t& _quantity)
- : quantity(_quantity), cost(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
- }
+ : quantity(_quantity), cost(NULL) {}
balance_pair_t(const int value)
- : quantity(value), cost(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
- }
+ : quantity(value), cost(NULL) {}
balance_pair_t(const unsigned int value)
- : quantity(value), cost(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
- }
+ : quantity(value), cost(NULL) {}
balance_pair_t(const double value)
- : quantity(value), cost(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor balance_pair_t");
- }
- balance_pair_t(const transaction_t& xact);
+ : quantity(value), cost(NULL) {}
// destructor
~balance_pair_t() {
- DEBUG_PRINT("ledger.memory.dtors", "dtor balance_pair_t");
if (cost)
delete cost;
}
@@ -541,7 +498,6 @@ class balance_pair_t
*cost += amt;
return *this;
}
- balance_pair_t& operator+=(const transaction_t& xact);
balance_pair_t& operator-=(const balance_pair_t& bal_pair) {
if (bal_pair.cost && ! cost)
@@ -566,7 +522,6 @@ class balance_pair_t
*cost -= amt;
return *this;
}
- balance_pair_t& operator-=(const transaction_t& xact);
// simple arithmetic
balance_pair_t operator+(const balance_pair_t& bal_pair) const {
@@ -741,11 +696,10 @@ class balance_pair_t
}
// unary negation
- balance_pair_t& negate() {
+ void negate() {
quantity.negate();
if (cost)
cost->negate();
- return *this;
}
balance_pair_t negated() const {
balance_pair_t temp = *this;
@@ -767,7 +721,8 @@ class balance_pair_t
if (quantity.amounts.size() == 1)
return (*quantity.amounts.begin()).second;
else
- throw error("Cannot convert a balance pair with multiple commodities to an amount");
+ throw amount_error("Cannot convert a balance pair with "
+ "multiple commodities to an amount");
}
void abs() {
@@ -775,6 +730,22 @@ class balance_pair_t
if (cost)
cost->abs();
}
+
+ amount_t amount(const commodity_t& commodity) const {
+ return quantity.amount(commodity);
+ }
+ balance_t value(const std::time_t moment) const {
+ return quantity.value(moment);
+ }
+ void write(std::ostream& out,
+ const int first_width,
+ const int latter_width = -1) const {
+ quantity.write(out, first_width, latter_width);
+ }
+
+ bool valid() {
+ return quantity.valid() && (! cost || cost->valid());
+ }
};
inline balance_pair_t abs(const balance_pair_t& bal_pair) {
diff --git a/binary.cc b/binary.cc
index 0a712972..a64f21ff 100644
--- a/binary.cc
+++ b/binary.cc
@@ -8,21 +8,21 @@
namespace ledger {
-const unsigned long binary_magic_number = 0xFFEED765;
-static const unsigned long format_version = 0x0002001a;
+static unsigned long binary_magic_number = 0xFFEED765;
+static unsigned long format_version = 0x0002001a;
-static account_t ** accounts;
-static account_t ** accounts_next;
-static unsigned int account_index;
+static account_t ** accounts;
+static account_t ** accounts_next;
+static unsigned int account_index;
-static commodity_t ** commodities;
-static commodity_t ** commodities_next;
-static unsigned int commodity_index;
+static commodity_t ** commodities;
+static commodity_t ** commodities_next;
+static unsigned int commodity_index;
-amount_t::bigint_t * bigints;
-amount_t::bigint_t * bigints_next;
-unsigned int bigints_index;
-unsigned int bigints_count;
+extern char * bigints;
+extern char * bigints_next;
+extern unsigned int bigints_index;
+extern unsigned int bigints_count;
#if DEBUG_LEVEL >= ALPHA
#define read_binary_guard(in, id) { \
@@ -342,9 +342,8 @@ unsigned int read_binary_journal(std::istream& in,
transaction_t * xact_pool = (transaction_t *) (item_pool +
sizeof(entry_t) * count);
bigints_index = 0;
- bigints = bigints_next
- = (amount_t::bigint_t *) (item_pool + sizeof(entry_t) * count +
- sizeof(transaction_t) * xact_count);
+ bigints = bigints_next = (item_pool + sizeof(entry_t) * count +
+ sizeof(transaction_t) * xact_count);
// Read in the commodities
diff --git a/binary.h b/binary.h
index 40621e19..4487f25e 100644
--- a/binary.h
+++ b/binary.h
@@ -19,11 +19,6 @@ class binary_parser_t : public parser_t
const std::string * original_file = NULL);
};
-extern amount_t::bigint_t * bigints;
-extern amount_t::bigint_t * bigints_next;
-extern unsigned int bigints_index;
-extern unsigned int bigints_count;
-
void write_binary_journal(std::ostream& out,
journal_t * journal,
strings_list * files = NULL);
diff --git a/error.h b/error.h
index ca5663a9..d5107f6d 100644
--- a/error.h
+++ b/error.h
@@ -20,12 +20,6 @@ class error : public std::exception {
}
};
-class amount_error : public error {
- public:
- amount_error(const std::string& reason) throw() : error(reason) {}
- virtual ~amount_error() throw() {}
-};
-
class compute_error : public error {
public:
compute_error(const std::string& reason) throw() : error(reason) {}
diff --git a/format.cc b/format.cc
index fda47a14..d99f9824 100644
--- a/format.cc
+++ b/format.cc
@@ -33,18 +33,15 @@ std::string partial_account_name(const account_t * account)
return name;
}
-std::string format_t::date_format;
-value_expr_t * format_t::value_expr;
-value_expr_t * format_t::total_expr;
+std::string format_t::date_format = "%Y/%m/%d";
+value_expr_t * format_t::value_expr = NULL;
+value_expr_t * format_t::total_expr = NULL;
-void initialize_formats()
-{
- format_t::date_format = "%Y/%m/%d";
- format_t::value_expr = NULL;
- format_t::total_expr = NULL;
-}
+static struct _init_format {
+ ~_init_format();
+} _init_obj;
-void shutdown_formats()
+_init_format::~_init_format()
{
if (format_t::value_expr)
delete format_t::value_expr;
@@ -375,7 +372,7 @@ void format_t::format_elements(std::ostream& out,
}
}
-bool format_account::disp_subaccounts_p(const account_t * account,
+bool format_account::disp_subaccounts_p(const account_t& account,
const item_predicate<account_t>&
disp_pred,
const account_t *& to_show)
@@ -389,13 +386,13 @@ bool format_account::disp_subaccounts_p(const account_t * account,
to_show = NULL;
- for (accounts_map::const_iterator i = account->accounts.begin();
- i != account->accounts.end();
+ for (accounts_map::const_iterator i = account.accounts.begin();
+ i != account.accounts.end();
i++) {
- if (! disp_pred((*i).second))
+ if (! disp_pred(*(*i).second))
continue;
- format_t::compute_total(result, details_t((*i).second));
+ format_t::compute_total(result, details_t(*(*i).second));
if (! computed) {
format_t::compute_total(acct_total, details_t(account));
computed = true;
@@ -412,11 +409,11 @@ bool format_account::disp_subaccounts_p(const account_t * account,
return display;
}
-bool format_account::display_account(const account_t * account,
+bool format_account::display_account(const account_t& account,
const item_predicate<account_t>& disp_pred)
{
// Never display an account that has already been displayed.
- if (account->data && ACCT_DATA(account)->dflags & ACCOUNT_DISPLAYED)
+ if (account.data && ACCT_DATA_(account)->dflags & ACCOUNT_DISPLAYED)
return false;
// At this point, one of two possibilities exists: the account is a
diff --git a/format.h b/format.h
index c8047528..e6a10133 100644
--- a/format.h
+++ b/format.h
@@ -105,18 +105,18 @@ class format_transactions : public item_handler<transaction_t>
output_stream.flush();
}
- virtual void operator()(transaction_t * xact) {
- if (! xact->data ||
- ! (XACT_DATA(xact)->dflags & TRANSACTION_DISPLAYED)) {
- if (last_entry != xact->entry) {
+ virtual void operator()(transaction_t& xact) {
+ if (! xact.data ||
+ ! (XACT_DATA_(xact)->dflags & TRANSACTION_DISPLAYED)) {
+ if (last_entry != xact.entry) {
first_line_format.format_elements(output_stream, details_t(xact));
- last_entry = xact->entry;
+ last_entry = xact.entry;
} else {
next_lines_format.format_elements(output_stream, details_t(xact));
}
- if (! xact->data)
- xact->data = new transaction_data_t;
- XACT_DATA(xact)->dflags |= TRANSACTION_DISPLAYED;
+ if (! xact.data)
+ xact.data = new transaction_data_t;
+ XACT_DATA_(xact)->dflags |= TRANSACTION_DISPLAYED;
}
}
};
@@ -135,32 +135,32 @@ class format_account : public item_handler<account_t>
: output_stream(_output_stream), format(_format),
disp_pred(display_predicate) {}
- static bool disp_subaccounts_p(const account_t * account,
+ static bool disp_subaccounts_p(const account_t& account,
const item_predicate<account_t>& disp_pred,
const account_t *& to_show);
- static bool disp_subaccounts_p(const account_t * account) {
+ static bool disp_subaccounts_p(const account_t& account) {
const account_t * temp;
return disp_subaccounts_p(account, item_predicate<account_t>(NULL), temp);
}
- static bool display_account(const account_t * account,
+ static bool display_account(const account_t& account,
const item_predicate<account_t>& disp_pred);
virtual void flush() {
output_stream.flush();
}
- virtual void operator()(account_t * account) {
+ virtual void operator()(account_t& account) {
if (display_account(account, disp_pred)) {
- if (! account->parent) {
- if (! account->data)
- account->data = new account_data_t;
- ACCT_DATA(account)->dflags |= ACCOUNT_TO_DISPLAY;
+ if (! account.parent) {
+ if (! account.data)
+ account.data = new account_data_t;
+ ACCT_DATA_(account)->dflags |= ACCOUNT_TO_DISPLAY;
} else {
format.format_elements(output_stream, details_t(account));
- if (! account->data)
- account->data = new account_data_t;
- ACCT_DATA(account)->dflags |= ACCOUNT_DISPLAYED;
+ if (! account.data)
+ account.data = new account_data_t;
+ ACCT_DATA_(account)->dflags |= ACCOUNT_DISPLAYED;
}
}
}
@@ -188,7 +188,7 @@ class format_equity : public item_handler<account_t>
entry_t header_entry;
header_entry.payee = "Opening Balances";
header_entry.date = std::time(NULL);
- first_line_format.format_elements(output_stream, details_t(&header_entry));
+ first_line_format.format_elements(output_stream, details_t(header_entry));
}
virtual void flush() {
@@ -197,18 +197,18 @@ class format_equity : public item_handler<account_t>
summary.data = acct_data.get();
((account_data_t *) summary.data)->value = total;
((account_data_t *) summary.data)->value.negate();
- next_lines_format.format_elements(output_stream, details_t(&summary));
+ next_lines_format.format_elements(output_stream, details_t(summary));
output_stream.flush();
}
- virtual void operator()(account_t * account) {
+ virtual void operator()(account_t& account) {
if (format_account::display_account(account, disp_pred)) {
next_lines_format.format_elements(output_stream, details_t(account));
- if (! account->data)
- account->data = new account_data_t;
+ if (! account.data)
+ account.data = new account_data_t;
else
- total += ACCT_DATA(account)->value;
- ACCT_DATA(account)->dflags |= ACCOUNT_DISPLAYED;
+ total += ACCT_DATA_(account)->value;
+ ACCT_DATA_(account)->dflags |= ACCOUNT_DISPLAYED;
}
}
};
diff --git a/journal.cc b/journal.cc
index 2d8cc4bb..a4bf4401 100644
--- a/journal.cc
+++ b/journal.cc
@@ -418,24 +418,6 @@ bool journal_t::valid() const
return true;
}
-void initialize_amounts();
-void shutdown_amounts();
-
-void initialize_formats();
-void shutdown_formats();
-
-void initialize()
-{
- initialize_amounts();
- initialize_formats();
-}
-
-void shutdown()
-{
- shutdown_amounts();
- shutdown_formats();
-}
-
} // namespace ledger
#ifdef USE_BOOST_PYTHON
diff --git a/ledger.h b/ledger.h
index 8f56e950..e52a1e83 100644
--- a/ledger.h
+++ b/ledger.h
@@ -16,8 +16,9 @@
#include <ctime>
#include <iostream>
-#include "debug.h"
#include "amount.h"
+#include "value.h"
+#include "debug.h"
namespace ledger {
@@ -64,6 +65,61 @@ class transaction_t
bool valid() const;
};
+inline
+balance_pair_t& add_transaction_to(const transaction_t& xact,
+ balance_pair_t& bal_pair)
+{
+ if (xact.cost && ! bal_pair.cost)
+ bal_pair.cost = new balance_t(bal_pair.quantity);
+
+ bal_pair.quantity += xact.amount;
+
+ if (bal_pair.cost)
+ *bal_pair.cost += xact.cost ? *xact.cost : xact.amount;
+
+ return bal_pair;
+}
+
+inline
+value_t& add_transaction_to(const transaction_t& xact, value_t& value)
+{
+ switch (value.type) {
+ case value_t::BOOLEAN:
+ case value_t::INTEGER:
+ value.cast(value_t::AMOUNT);
+
+ case value_t::AMOUNT:
+ if (xact.cost) {
+ value.cast(value_t::BALANCE_PAIR);
+ return add_transaction_to(xact, value);
+ }
+ else if (((amount_t *) value.data)->commodity() !=
+ xact.amount.commodity()) {
+ value.cast(value_t::BALANCE);
+ return add_transaction_to(xact, value);
+ }
+ *((amount_t *) value.data) += xact.amount;
+ break;
+
+ case value_t::BALANCE:
+ if (xact.cost) {
+ value.cast(value_t::BALANCE_PAIR);
+ return add_transaction_to(xact, value);
+ }
+ *((balance_t *) value.data) += xact.amount;
+ break;
+
+ case value_t::BALANCE_PAIR:
+ add_transaction_to(xact, *((balance_pair_t *) value.data));
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ return value;
+}
typedef std::deque<transaction_t *> transactions_list;
@@ -211,9 +267,6 @@ class journal_t
extern const std::string version;
-void initialize();
-void shutdown();
-
} // namespace ledger
#endif // _LEDGER_H
diff --git a/main.cc b/main.cc
index f852564c..6ae0bb21 100644
--- a/main.cc
+++ b/main.cc
@@ -335,8 +335,8 @@ int parse_and_report(int argc, char * argv[], char * envp[])
if (command == "b") {
format_account acct_formatter(out, config.format,
config.display_predicate);
- sum_accounts(journal->master);
- walk_accounts(journal->master, acct_formatter, config.sort_order.get());
+ sum_accounts(*journal->master);
+ walk_accounts(*journal->master, acct_formatter, config.sort_order.get());
acct_formatter.flush();
if (journal->master->data) {
@@ -344,15 +344,15 @@ int parse_and_report(int argc, char * argv[], char * envp[])
if (ACCT_DATA(journal->master)->dflags & ACCOUNT_TO_DISPLAY) {
out << "--------------------\n";
- config.format.format_elements(out, details_t(journal->master));
+ config.format.format_elements(out, details_t(*journal->master));
}
}
}
else if (command == "E") {
format_equity acct_formatter(out, config.format, config.nformat,
config.display_predicate);
- sum_accounts(journal->master);
- walk_accounts(journal->master, acct_formatter, config.sort_order.get());
+ sum_accounts(*journal->master);
+ walk_accounts(*journal->master, acct_formatter, config.sort_order.get());
acct_formatter.flush();
}
@@ -363,7 +363,7 @@ int parse_and_report(int argc, char * argv[], char * envp[])
walk_entries(journal->entries, xact_cleanup);
clear_account_data acct_cleanup;
- walk_accounts(journal->master, acct_cleanup);
+ walk_accounts(*journal->master, acct_cleanup);
#endif
TIMER_STOP(report_gen);
@@ -384,25 +384,16 @@ int parse_and_report(int argc, char * argv[], char * envp[])
int main(int argc, char * argv[], char * envp[])
{
- int status = 0;
-
- initialize();
-
try {
- status = parse_and_report(argc, argv, envp);
+ return parse_and_report(argc, argv, envp);
}
catch (error& err) {
std::cerr << "Error: " << err.what() << std::endl;
- status = 1;
+ return 1;
}
catch (int& val) {
- status = val;
+ return val; // this acts like a std::setjmp
}
-
-#if DEBUG_LEVEL >= BETA
- shutdown();
-#endif
- return status;
}
// main.cc ends here.
diff --git a/python.cc b/python.cc
index 5ed9be31..d469c2f3 100644
--- a/python.cc
+++ b/python.cc
@@ -5,12 +5,6 @@ using namespace boost::python;
#include "ledger.h"
#include "acconf.h"
-static struct cleanup_ledger_t {
- ~cleanup_ledger_t() {
- ledger::shutdown();
- }
-} _cleanup_ledger;
-
void export_amount();
void export_balance();
void export_value();
@@ -37,5 +31,4 @@ BOOST_PYTHON_MODULE(ledger) {
export_gnucash();
#endif
export_option();
- ledger::initialize();
}
diff --git a/setup.py b/setup.py
index e447d35e..5452e0ee 100755
--- a/setup.py
+++ b/setup.py
@@ -10,6 +10,6 @@ setup(name = "Ledger",
url = "http://www.newartisans.com/johnw/",
ext_modules = [
Extension("ledger", ["python.cc"],
- define_macros = [('PYTHON_MODULE', None)],
- libraries = ["ledger_bpy", "boost_python", "gmp", "pcre",
- "xmlparse", "xmltok"])])
+ define_macros = [('PYTHON_MODULE', None)],
+ libraries = ["ledger_bpy", "boost_python", "gmp", "pcre",
+ "xmlparse", "xmltok"])])
diff --git a/valexpr.cc b/valexpr.cc
index 2618553e..7e2a6da0 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -218,9 +218,8 @@ void value_expr_t::compute(value_t& result, const details_t& details) const
// jww (2004-08-17): do something smarter here?
result.cast(value_t::AMOUNT);
}
- // jww (2004-08-29): maybe this should be strip_commodity?
if (result.type == value_t::AMOUNT)
- ((amount_t *) result.data)->set_commodity(*commodity_t::null_commodity);
+ ((amount_t *) result.data)->clear_commodity();
break;
}
diff --git a/valexpr.h b/valexpr.h
index f841cf95..91de7ed7 100644
--- a/valexpr.h
+++ b/valexpr.h
@@ -29,23 +29,12 @@ struct details_t
const transaction_t * xact;
const account_t * account;
- details_t(const entry_t * _entry)
- : entry(_entry), xact(NULL), account(NULL) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor details_t");
- }
- details_t(const transaction_t * _xact)
- : entry(_xact->entry), xact(_xact), account(_xact->account) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor details_t");
- }
- details_t(const account_t * _account)
- : entry(NULL), xact(NULL), account(_account) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor details_t");
- }
-#ifdef DEBUG_ENABLED
- ~details_t() {
- DEBUG_PRINT("ledger.memory.dtors", "dtor details_t");
- }
-#endif
+ details_t(const entry_t& _entry)
+ : entry(&_entry), xact(NULL), account(NULL) {}
+ details_t(const transaction_t& _xact)
+ : entry(_xact.entry), xact(&_xact), account(_xact.account) {}
+ details_t(const account_t& _account)
+ : entry(NULL), xact(NULL), account(&_account) {}
};
struct value_expr_t
@@ -190,7 +179,7 @@ class item_predicate
delete predicate;
}
- bool operator()(const T * item) const {
+ bool operator()(const T& item) const {
if (predicate) {
value_t result;
predicate->compute(result, details_t(item));
diff --git a/value.cc b/value.cc
index aa1e184e..a811c778 100644
--- a/value.cc
+++ b/value.cc
@@ -1,6 +1,4 @@
#include "value.h"
-#include "ledger.h"
-#include "error.h"
namespace ledger {
@@ -171,45 +169,6 @@ DEF_VALUE_OP(-=)
DEF_VALUE_OP(*=)
DEF_VALUE_OP(/=)
-value_t& value_t::operator +=(const transaction_t& xact)
-{
- switch (type) {
- case BOOLEAN:
- case INTEGER:
- cast(AMOUNT);
-
- case AMOUNT:
- if (xact.cost) {
- cast(BALANCE_PAIR);
- return *this += xact;
- }
- else if (((amount_t *) data)->commodity() != xact.amount.commodity()) {
- cast(BALANCE);
- return *this += xact;
- }
- *((amount_t *) data) += xact.amount;
- break;
-
- case BALANCE:
- if (xact.cost) {
- cast(BALANCE_PAIR);
- return *this += xact;
- }
- *((balance_t *) data) += xact.amount;
- break;
-
- case BALANCE_PAIR:
- *((balance_pair_t *) data) += xact;
- break;
-
- default:
- assert(0);
- break;
- }
-
- return *this;
-}
-
#define DEF_VALUE_CMP_OP(OP) \
bool value_t::operator OP(const value_t& value) \
{ \
@@ -435,7 +394,7 @@ void value_t::cast(type_t cast_type)
break;
}
case INTEGER:
- throw error("Cannot convert a balance to an integer");
+ throw value_error("Cannot convert a balance to an integer");
case AMOUNT: {
balance_t * temp = (balance_t *) data;
if (temp->amounts.size() == 1) {
@@ -443,7 +402,8 @@ void value_t::cast(type_t cast_type)
destroy();
new((amount_t *)data) amount_t(amt);
} else {
- throw error("Cannot convert a balance with multiple commodities to an amount");
+ throw value_error("Cannot convert a balance with "
+ "multiple commodities to an amount");
}
break;
}
@@ -471,7 +431,7 @@ void value_t::cast(type_t cast_type)
break;
}
case INTEGER:
- throw error("Cannot convert a balance pair to an integer");
+ throw value_error("Cannot convert a balance pair to an integer");
case AMOUNT: {
balance_t * temp = &((balance_pair_t *) data)->quantity;
@@ -480,7 +440,8 @@ void value_t::cast(type_t cast_type)
destroy();
new((amount_t *)data) amount_t(amt);
} else {
- throw error("Cannot convert a balance pair with multiple commodities to an amount");
+ throw value_error("Cannot convert a balance pair with "
+ "multiple commodities to an amount");
}
break;
}
@@ -592,6 +553,34 @@ using namespace ledger;
void export_value()
{
class_< value_t > ("Value")
+ .def(init<value_t>())
+ .def(init<balance_pair_t>())
+ .def(init<balance_t>())
+ .def(init<amount_t>())
+ .def(init<unsigned int>())
+ .def(init<bool>())
+
+ .def(self += self)
+ .def(self -= self)
+ .def(self *= self)
+ .def(self /= self)
+
+ .def(self < self)
+ .def(self <= self)
+ .def(self > self)
+ .def(self >= self)
+ .def(self == self)
+ .def(self != self)
+ .def(! self)
+
+#if 0
+ .def(abs(self))
+ .def(str(self))
+
+ .def("cast", &value_t::cast)
+#endif
+ .def("negate", &value_t::negate)
+ .def("cost", &value_t::cost)
;
}
diff --git a/value.h b/value.h
index b0687d64..34af0f73 100644
--- a/value.h
+++ b/value.h
@@ -3,7 +3,8 @@
#include "amount.h"
#include "balance.h"
-#include "debug.h"
+
+#include <exception>
namespace ledger {
@@ -16,8 +17,6 @@ namespace ledger {
// fact that logic chains only need boolean values to continue, no
// memory allocations need to take place at all.
-class transaction_t;
-
class value_t
{
public:
@@ -32,40 +31,32 @@ class value_t
} type;
value_t() {
- DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*((unsigned int *) data) = 0;
type = INTEGER;
}
value_t(const value_t& value) : type(INTEGER) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*this = value;
}
value_t(const bool value) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*((bool *) data) = value;
type = BOOLEAN;
}
value_t(const unsigned int value) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*((unsigned int *) data) = value;
type = INTEGER;
}
value_t(const amount_t& value) : type(INTEGER) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*this = value;
}
value_t(const balance_t& value) : type(INTEGER) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*this = value;
}
value_t(const balance_pair_t& value) : type(INTEGER) {
- DEBUG_PRINT("ledger.memory.ctors", "ctor value_t");
*this = value;
}
~value_t() {
- DEBUG_PRINT("ledger.memory.dtors", "dtor value_t");
destroy();
}
@@ -130,17 +121,14 @@ class value_t
value_t& operator*=(const value_t& value);
value_t& operator/=(const value_t& value);
- value_t& operator+=(const transaction_t& xact);
-
- bool operator==(const value_t& value);
- bool operator!=(const value_t& value) {
- return ! (*this == value);
- }
-
bool operator<(const value_t& value);
bool operator<=(const value_t& value);
bool operator>(const value_t& value);
bool operator>=(const value_t& value);
+ bool operator==(const value_t& value);
+ bool operator!=(const value_t& value) {
+ return ! (*this == value);
+ }
template <typename T>
operator T() const;
@@ -173,7 +161,18 @@ value_t::operator T() const
}
assert(0);
return 0;
- }
+}
+
+class value_error : public std::exception {
+ std::string reason;
+ public:
+ value_error(const std::string& _reason) throw() : reason(_reason) {}
+ virtual ~value_error() throw() {}
+
+ virtual const char* what() const throw() {
+ return reason.c_str();
+ }
+};
} // namespace ledger
diff --git a/walk.cc b/walk.cc
index 0fadd1e6..a8111597 100644
--- a/walk.cc
+++ b/walk.cc
@@ -11,43 +11,43 @@ void sort_transactions::flush()
for (std::deque<transaction_t *>::iterator i = transactions.begin();
i != transactions.end();
i++)
- (*handler)(*i);
+ (*handler)(**i);
transactions.clear();
item_handler<transaction_t>::flush();
}
-void calc_transactions::operator()(transaction_t * xact)
+void calc_transactions::operator()(transaction_t& xact)
{
- if (! xact->data)
- xact->data = new transaction_data_t;
+ if (! xact.data)
+ xact.data = new transaction_data_t;
if (last_xact && last_xact->data) {
- XACT_DATA(xact)->total += XACT_DATA(last_xact)->total;
- XACT_DATA(xact)->index = XACT_DATA(last_xact)->index + 1;
+ XACT_DATA_(xact)->total += XACT_DATA(last_xact)->total;
+ XACT_DATA_(xact)->index = XACT_DATA(last_xact)->index + 1;
} else {
- XACT_DATA(xact)->index = 0;
+ XACT_DATA_(xact)->index = 0;
}
if (inverted) {
- xact->amount.negate();
- if (xact->cost)
- xact->cost->negate();
+ xact.amount.negate();
+ if (xact.cost)
+ xact.cost->negate();
}
- if (! (XACT_DATA(xact)->dflags & TRANSACTION_NO_TOTAL))
- XACT_DATA(xact)->total += *xact;
+ if (! (XACT_DATA_(xact)->dflags & TRANSACTION_NO_TOTAL))
+ add_transaction_to(xact, XACT_DATA_(xact)->total);
(*handler)(xact);
if (inverted) {
- xact->amount.negate();
- if (xact->cost)
- xact->cost->negate();
+ xact.amount.negate();
+ if (xact.cost)
+ xact.cost->negate();
}
- last_xact = xact;
+ last_xact = &xact;
}
@@ -65,7 +65,7 @@ static void handle_value(const value_t& value, account_t * account,
transaction_t * xact = new transaction_t(account);
temps.push_back(xact);
- xact->entry = entry;
+ xact->entry = entry;
switch (value.type) {
case value_t::BOOLEAN:
xact->amount = *((bool *) value.data);
@@ -87,7 +87,7 @@ static void handle_value(const value_t& value, account_t * account,
XACT_DATA(xact)->dflags |= flags;
}
- (*handler)(xact);
+ (*handler)(*xact);
break;
}
@@ -114,7 +114,7 @@ static void handle_value(const value_t& value, account_t * account,
XACT_DATA(xact)->dflags |= flags;
}
- (*handler)(xact);
+ (*handler)(*xact);
}
break;
@@ -127,7 +127,7 @@ static void handle_value(const value_t& value, account_t * account,
void collapse_transactions::report_cumulative_subtotal()
{
if (count == 1) {
- (*handler)(last_xact);
+ (*handler)(*last_xact);
} else {
assert(count > 1);
@@ -135,7 +135,7 @@ void collapse_transactions::report_cumulative_subtotal()
totals_account->data = new account_data_t;
ACCT_DATA(totals_account)->total = subtotal;
value_t result;
- format_t::compute_total(result, details_t(totals_account));
+ format_t::compute_total(result, details_t(*totals_account));
handle_value(result, totals_account, last_entry, 0, xact_temps, handler);
}
@@ -143,44 +143,45 @@ void collapse_transactions::report_cumulative_subtotal()
count = 0;
}
-void changed_value_transactions::operator()(transaction_t * xact)
+void changed_value_transactions::output_diff(const std::time_t current)
{
- if (last_xact) {
- value_t prev_bal;
- value_t cur_bal;
- std::time_t current = xact ? xact->entry->date : std::time(NULL);
- std::time_t prev_date = last_xact->entry->date;
+ value_t prev_bal;
+ value_t cur_bal;
+ std::time_t prev_date = last_xact->entry->date;
- format_t::compute_total(prev_bal, details_t(last_xact));
+ format_t::compute_total(prev_bal, details_t(*last_xact));
- last_xact->entry->date = current;
- format_t::compute_total(cur_bal, details_t(last_xact));
- last_xact->entry->date = prev_date;
+ last_xact->entry->date = current;
+ format_t::compute_total(cur_bal, details_t(*last_xact));
+ last_xact->entry->date = prev_date;
- cur_bal -= prev_bal;
- if (cur_bal) {
- entry_t * entry = new entry_t;
- entry_temps.push_back(entry);
+ cur_bal -= prev_bal;
+ if (cur_bal) {
+ entry_t * entry = new entry_t;
+ entry_temps.push_back(entry);
- entry->payee = "Commodities revalued";
- entry->date = current;
+ entry->payee = "Commodities revalued";
+ entry->date = current;
- handle_value(cur_bal, NULL, entry, TRANSACTION_NO_TOTAL, xact_temps,
- handler);
- }
+ handle_value(cur_bal, NULL, entry, TRANSACTION_NO_TOTAL, xact_temps,
+ handler);
}
+}
- if (xact) {
- if (changed_values_only) {
- if (! xact->data)
- xact->data = new transaction_data_t;
- XACT_DATA(xact)->dflags |= TRANSACTION_DISPLAYED;
- }
+void changed_value_transactions::operator()(transaction_t& xact)
+{
+ if (last_xact)
+ output_diff(xact.entry->date);
- (*handler)(xact);
+ if (changed_values_only) {
+ if (! xact.data)
+ xact.data = new transaction_data_t;
+ XACT_DATA_(xact)->dflags |= TRANSACTION_DISPLAYED;
}
- last_xact = xact;
+ (*handler)(xact);
+
+ last_xact = &xact;
}
void subtotal_transactions::flush(const char * spec_fmt)
@@ -218,7 +219,7 @@ void subtotal_transactions::flush(const char * spec_fmt)
std::auto_ptr<transaction_data_t> xact_data(new transaction_data_t);
temp.data = xact_data.get();
((transaction_data_t *) temp.data)->total = (*i).second;
- format_t::compute_total(result, details_t(&temp));
+ format_t::compute_total(result, details_t(temp));
}
temp.data = NULL;
}
@@ -232,28 +233,31 @@ void subtotal_transactions::flush(const char * spec_fmt)
item_handler<transaction_t>::flush();
}
-void subtotal_transactions::operator()(transaction_t * xact)
+void subtotal_transactions::operator()(transaction_t& xact)
{
if (balances.size() == 0) {
- start = finish = xact->entry->date;
+ start = finish = xact.entry->date;
} else {
- if (std::difftime(xact->entry->date, start) < 0)
- start = xact->entry->date;
- if (std::difftime(xact->entry->date, finish) > 0)
- finish = xact->entry->date;
+ if (std::difftime(xact.entry->date, start) < 0)
+ start = xact.entry->date;
+ if (std::difftime(xact.entry->date, finish) > 0)
+ finish = xact.entry->date;
}
- balances_map::iterator i = balances.find(xact->account);
- if (i == balances.end())
- balances.insert(balances_pair(xact->account, *xact));
- else
- (*i).second += *xact;
+ balances_map::iterator i = balances.find(xact.account);
+ if (i == balances.end()) {
+ balance_pair_t temp;
+ add_transaction_to(xact, temp);
+ balances.insert(balances_pair(xact.account, temp));
+ } else {
+ add_transaction_to(xact, (*i).second);
+ }
}
-void interval_transactions::operator()(transaction_t * xact)
+void interval_transactions::operator()(transaction_t& xact)
{
std::time_t quant = interval.increment(begin);
- if (std::difftime(xact->entry->date, quant) > 0) {
+ if (std::difftime(xact.entry->date, quant) > 0) {
if (last_xact) {
start = begin;
finish = quant;
@@ -261,7 +265,7 @@ void interval_transactions::operator()(transaction_t * xact)
}
if (! interval.seconds) {
- struct std::tm * desc = std::localtime(&xact->entry->date);
+ struct std::tm * desc = std::localtime(&xact.entry->date);
if (interval.years)
desc->tm_mon = 0;
desc->tm_mday = 1;
@@ -272,7 +276,7 @@ void interval_transactions::operator()(transaction_t * xact)
}
std::time_t temp;
- while (std::difftime(xact->entry->date,
+ while (std::difftime(xact.entry->date,
temp = interval.increment(quant)) > 0)
quant = temp;
begin = quant;
@@ -280,7 +284,7 @@ void interval_transactions::operator()(transaction_t * xact)
subtotal_transactions::operator()(xact);
- last_xact = xact;
+ last_xact = &xact;
}
void dow_transactions::flush()
@@ -289,7 +293,7 @@ void dow_transactions::flush()
for (std::deque<transaction_t *>::iterator d = days_of_the_week[i].begin();
d != days_of_the_week[i].end();
d++)
- subtotal_transactions::operator()(*d);
+ subtotal_transactions::operator()(**d);
subtotal_transactions::flush("%As");
days_of_the_week[i].clear();
}
diff --git a/walk.h b/walk.h
index 7a8dc060..00296082 100644
--- a/walk.h
+++ b/walk.h
@@ -32,7 +32,7 @@ struct item_handler {
if (handler)
handler->flush();
}
- virtual void operator()(T * item) {
+ virtual void operator()(T& item) {
if (handler)
(*handler)(item);
}
@@ -55,8 +55,8 @@ class compare_items {
assert(left);
assert(right);
- sort_order->compute(left_result, details_t(left));
- sort_order->compute(right_result, details_t(right));
+ sort_order->compute(left_result, details_t(*left));
+ sort_order->compute(right_result, details_t(*right));
return left_result < right_result;
}
@@ -71,7 +71,7 @@ inline void walk_transactions(transactions_list::iterator begin,
transactions_list::iterator end,
item_handler<transaction_t>& handler) {
for (transactions_list::iterator i = begin; i != end; i++)
- handler(*i);
+ handler(**i);
}
inline void walk_transactions(transactions_list& deque,
@@ -114,6 +114,7 @@ struct transaction_data_t
};
#define XACT_DATA(xact) ((transaction_data_t *) ((xact)->data))
+#define XACT_DATA_(xact) ((transaction_data_t *) ((xact).data))
#define ACCOUNT_DISPLAYED 0x1
#define ACCOUNT_TO_DISPLAY 0x2
@@ -137,22 +138,23 @@ struct account_data_t
};
#define ACCT_DATA(acct) ((account_data_t *) ((acct)->data))
+#define ACCT_DATA_(acct) ((account_data_t *) ((acct).data))
//////////////////////////////////////////////////////////////////////
class ignore_transactions : public item_handler<transaction_t>
{
public:
- virtual void operator()(transaction_t * xact) {}
+ virtual void operator()(transaction_t& xact) {}
};
class clear_transaction_data : public item_handler<transaction_t>
{
public:
- virtual void operator()(transaction_t * xact) {
- if (xact->data) {
- delete (transaction_data_t *) xact->data;
- xact->data = NULL;
+ virtual void operator()(transaction_t& xact) {
+ if (xact.data) {
+ delete (transaction_data_t *) xact.data;
+ xact.data = NULL;
}
}
};
@@ -163,12 +165,12 @@ class set_account_value : public item_handler<transaction_t>
set_account_value(item_handler<transaction_t> * handler = NULL)
: item_handler<transaction_t>(handler) {}
- virtual void operator()(transaction_t * xact) {
- if (! ACCT_DATA(xact->account))
- xact->account->data = new account_data_t;
+ virtual void operator()(transaction_t& xact) {
+ if (! ACCT_DATA(xact.account))
+ xact.account->data = new account_data_t;
- ACCT_DATA(xact->account)->value += *xact;
- ACCT_DATA(xact->account)->subcount++;
+ add_transaction_to(xact, ACCT_DATA(xact.account)->value);
+ ACCT_DATA(xact.account)->subcount++;
if (handler)
(*handler)(xact);
@@ -187,8 +189,8 @@ class sort_transactions : public item_handler<transaction_t>
sort_order(_sort_order) {}
virtual void flush();
- virtual void operator()(transaction_t * xact) {
- transactions.push_back(xact);
+ virtual void operator()(transaction_t& xact) {
+ transactions.push_back(&xact);
}
};
@@ -201,7 +203,7 @@ class filter_transactions : public item_handler<transaction_t>
const std::string& predicate)
: item_handler<transaction_t>(handler), pred(predicate) {}
- virtual void operator()(transaction_t * xact) {
+ virtual void operator()(transaction_t& xact) {
if (pred(xact))
(*handler)(xact);
}
@@ -218,7 +220,7 @@ class calc_transactions : public item_handler<transaction_t>
: item_handler<transaction_t>(handler),
last_xact(NULL), inverted(_inverted) {}
- virtual void operator()(transaction_t * xact);
+ virtual void operator()(transaction_t& xact);
};
class collapse_transactions : public item_handler<transaction_t>
@@ -262,18 +264,18 @@ class collapse_transactions : public item_handler<transaction_t>
void report_cumulative_subtotal();
- virtual void operator()(transaction_t * xact) {
+ virtual void operator()(transaction_t& xact) {
// If we've reached a new entry, report on the subtotal
// accumulated thus far.
- if (last_entry && last_entry != xact->entry)
+ if (last_entry && last_entry != xact.entry)
report_cumulative_subtotal();
- subtotal += *xact;
+ add_transaction_to(xact, subtotal);
count++;
- last_entry = xact->entry;
- last_xact = xact;
+ last_entry = xact.entry;
+ last_xact = &xact;
}
};
@@ -311,11 +313,14 @@ class changed_value_transactions : public item_handler<transaction_t>
}
virtual void flush() {
- (*this)(NULL);
+ output_diff(std::time(NULL));
+ last_xact = NULL;
item_handler<transaction_t>::flush();
}
- virtual void operator()(transaction_t * xact);
+ void output_diff(const std::time_t current);
+
+ virtual void operator()(transaction_t& xact);
};
class subtotal_transactions : public item_handler<transaction_t>
@@ -356,7 +361,7 @@ class subtotal_transactions : public item_handler<transaction_t>
virtual void flush() {
flush(NULL);
}
- virtual void operator()(transaction_t * xact);
+ virtual void operator()(transaction_t& xact);
};
class interval_transactions : public subtotal_transactions
@@ -377,7 +382,7 @@ class interval_transactions : public subtotal_transactions
finish = interval.increment(begin);
}
- virtual void operator()(transaction_t * xact);
+ virtual void operator()(transaction_t& xact);
};
class dow_transactions : public subtotal_transactions
@@ -389,9 +394,9 @@ class dow_transactions : public subtotal_transactions
: subtotal_transactions(handler) {}
virtual void flush();
- virtual void operator()(transaction_t * xact) {
- struct std::tm * desc = std::localtime(&xact->entry->date);
- days_of_the_week[desc->tm_wday].push_back(xact);
+ virtual void operator()(transaction_t& xact) {
+ struct std::tm * desc = std::localtime(&xact.entry->date);
+ days_of_the_week[desc->tm_wday].push_back(&xact);
}
};
@@ -405,18 +410,18 @@ class related_transactions : public item_handler<transaction_t>
: item_handler<transaction_t>(handler),
also_matching(_also_matching) {}
- virtual void operator()(transaction_t * xact) {
- for (transactions_list::iterator i = xact->entry->transactions.begin();
- i != xact->entry->transactions.end();
+ virtual void operator()(transaction_t& xact) {
+ for (transactions_list::iterator i = xact.entry->transactions.begin();
+ i != xact.entry->transactions.end();
i++)
if ((! (*i)->data ||
! (XACT_DATA(*i)->dflags & TRANSACTION_HANDLED)) &&
- (*i == xact ? also_matching :
+ (*i == &xact ? also_matching :
! ((*i)->flags & TRANSACTION_AUTO))) {
if (! (*i)->data)
(*i)->data = new transaction_data_t;
XACT_DATA(*i)->dflags |= TRANSACTION_HANDLED;
- (*handler)(*i);
+ (*handler)(**i);
}
}
};
@@ -438,29 +443,29 @@ class clear_account_data : public item_handler<account_t>
}
};
-inline void sum_accounts(account_t * account) {
- if (! account->data)
- account->data = new account_data_t;
+inline void sum_accounts(account_t& account) {
+ if (! account.data)
+ account.data = new account_data_t;
- for (accounts_map::iterator i = account->accounts.begin();
- i != account->accounts.end();
+ for (accounts_map::iterator i = account.accounts.begin();
+ i != account.accounts.end();
i++) {
- sum_accounts((*i).second);
- ACCT_DATA(account)->total += ACCT_DATA((*i).second)->total;
- ACCT_DATA(account)->count += (ACCT_DATA((*i).second)->count +
+ sum_accounts(*(*i).second);
+ ACCT_DATA_(account)->total += ACCT_DATA((*i).second)->total;
+ ACCT_DATA_(account)->count += (ACCT_DATA((*i).second)->count +
ACCT_DATA((*i).second)->subcount);
}
- ACCT_DATA(account)->total += ACCT_DATA(account)->value;
- ACCT_DATA(account)->count += ACCT_DATA(account)->subcount;
+ ACCT_DATA_(account)->total += ACCT_DATA_(account)->value;
+ ACCT_DATA_(account)->count += ACCT_DATA_(account)->subcount;
}
typedef std::deque<account_t *> accounts_list;
-inline void sort_accounts(account_t * account,
+inline void sort_accounts(account_t& account,
const value_expr_t * sort_order,
- accounts_list& accounts) {
- for (accounts_map::iterator i = account->accounts.begin();
- i != account->accounts.end();
+ accounts_list& accounts) {
+ for (accounts_map::iterator i = account.accounts.begin();
+ i != account.accounts.end();
i++)
accounts.push_back((*i).second);
@@ -468,7 +473,7 @@ inline void sort_accounts(account_t * account,
compare_items<account_t>(sort_order));
}
-inline void walk_accounts(account_t * account,
+inline void walk_accounts(account_t& account,
item_handler<account_t>& handler,
const value_expr_t * sort_order = NULL) {
handler(account);
@@ -479,12 +484,12 @@ inline void walk_accounts(account_t * account,
for (accounts_list::const_iterator i = accounts.begin();
i != accounts.end();
i++)
- walk_accounts(*i, handler, sort_order);
+ walk_accounts(**i, handler, sort_order);
} else {
- for (accounts_map::const_iterator i = account->accounts.begin();
- i != account->accounts.end();
+ for (accounts_map::const_iterator i = account.accounts.begin();
+ i != account.accounts.end();
i++)
- walk_accounts((*i).second, handler);
+ walk_accounts(*(*i).second, handler);
}
}