summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--csv.cc7
-rw-r--r--emacs.cc8
-rw-r--r--entry.h6
-rw-r--r--journal.h4
-rw-r--r--mask.h12
-rw-r--r--op.cc28
-rw-r--r--parser.cc1
-rw-r--r--parser.h10
-rw-r--r--qif.cc18
-rw-r--r--reconcile.cc4
-rw-r--r--report.cc8
-rw-r--r--textual.cc2
-rw-r--r--token.cc17
-rw-r--r--token.h6
-rw-r--r--walk.cc167
-rw-r--r--walk.h223
-rw-r--r--xact.cc98
-rw-r--r--xact.h140
-rw-r--r--xml.cc15
19 files changed, 387 insertions, 387 deletions
diff --git a/csv.cc b/csv.cc
index 7c8a92e0..e61e04a6 100644
--- a/csv.cc
+++ b/csv.cc
@@ -19,9 +19,8 @@ namespace {
void format_csv_xacts::operator()(xact_t& xact)
{
- if (! xact_has_xdata(xact) ||
- ! (xact_xdata_(xact).dflags & XACT_DISPLAYED)) {
-
+ if (! xact.has_xdata() ||
+ ! xact.xdata().has_flags(XACT_EXT_DISPLAYED)) {
{
format_t fmt("%D");
std::ostringstream str;
@@ -111,7 +110,7 @@ void format_csv_xacts::operator()(xact_t& xact)
}
out << '\n';
- xact_xdata(xact).dflags |= XACT_DISPLAYED;
+ xact.xdata().add_flags(XACT_EXT_DISPLAYED);
}
}
diff --git a/emacs.cc b/emacs.cc
index 688e59af..0b1f1860 100644
--- a/emacs.cc
+++ b/emacs.cc
@@ -33,8 +33,8 @@ void format_emacs_xacts::write_entry(entry_t& entry)
void format_emacs_xacts::operator()(xact_t& xact)
{
- if (! xact_has_xdata(xact) ||
- ! (xact_xdata_(xact).dflags & XACT_DISPLAYED)) {
+ if (! xact.has_xdata() ||
+ ! xact.xdata().has_flags(XACT_EXT_DISPLAYED)) {
if (! last_entry) {
out << "((";
write_entry(*xact.entry);
@@ -48,7 +48,7 @@ void format_emacs_xacts::operator()(xact_t& xact)
}
out << " (" << (static_cast<unsigned long>(xact.beg_line) + 1) << " ";
- out << "\"" << xact_account(xact)->fullname() << "\" \""
+ out << "\"" << xact.reported_account()->fullname() << "\" \""
<< xact.amount << "\"";
switch (xact.state) {
@@ -71,7 +71,7 @@ void format_emacs_xacts::operator()(xact_t& xact)
last_entry = xact.entry;
- xact_xdata(xact).dflags |= XACT_DISPLAYED;
+ xact.xdata().add_flags(XACT_EXT_DISPLAYED);
}
}
diff --git a/entry.h b/entry.h
index fdc9fbee..2834942f 100644
--- a/entry.h
+++ b/entry.h
@@ -39,8 +39,6 @@ namespace ledger {
class journal_t;
-typedef std::list<xact_t *> xacts_list;
-
class entry_base_t : public supports_flags<>
{
public:
@@ -232,6 +230,10 @@ inline bool auto_entry_finalizer_t::operator()(entry_t& entry, bool post) {
return true;
}
+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;
+
} // namespace ledger
#endif // _ENTRY_H
diff --git a/journal.h b/journal.h
index df17764d..293439bb 100644
--- a/journal.h
+++ b/journal.h
@@ -43,10 +43,6 @@ typedef std::list<path> paths_list;
class session_t;
class account_t;
-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;
-
class journal_t : public noncopyable
{
public:
diff --git a/mask.h b/mask.h
index 8213a346..538316be 100644
--- a/mask.h
+++ b/mask.h
@@ -36,25 +36,17 @@
namespace ledger {
-class mask_t : public supports_flags<>
+class mask_t
{
mask_t();
public:
-#define MASK_SHORT_ACCOUNT 0x01
-#define MASK_CODE 0x02
-#define MASK_COMMODITY 0x04
-#define MASK_PAYEE 0x08
-#define MASK_NOTE 0x10
-#define MASK_ACCOUNT 0x20
-
bool exclude;
boost::regex expr;
explicit mask_t(const string& pattern);
- mask_t(const mask_t& m)
- : supports_flags<>(), exclude(m.exclude), expr(m.expr) {
+ mask_t(const mask_t& m) : exclude(m.exclude), expr(m.expr) {
TRACE_CTOR(mask_t, "copy");
}
~mask_t() throw() {
diff --git a/op.cc b/op.cc
index 4f2fe880..15ba749a 100644
--- a/op.cc
+++ b/op.cc
@@ -647,34 +647,6 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope)
}
return this;
- case MASK: {
- ptr_op_t match = new op_t(op_t::O_MATCH);
- match->set_right(this);
-
- // jww (2008-08-02): Coupling!
- ptr_op_t ident = new op_t(op_t::IDENT);
- switch (as_mask().flags()) {
- case MASK_SHORT_ACCOUNT:
- ident->set_ident("account_base");
- break;
- case MASK_CODE:
- ident->set_ident("code");
- break;
- case MASK_PAYEE:
- ident->set_ident("payee");
- break;
- case MASK_NOTE:
- ident->set_ident("note");
- break;
- case MASK_ACCOUNT:
- ident->set_ident("account");
- break;
- }
- match->set_left(ident->compile(scope));
-
- return match;
- }
-
default:
break;
}
diff --git a/parser.cc b/parser.cc
index cada6c5e..4795c8f7 100644
--- a/parser.cc
+++ b/parser.cc
@@ -50,7 +50,6 @@ expr_t::parser_t::parse_value_term(std::istream& in,
case token_t::MASK:
node = new op_t(op_t::MASK);
node->set_mask(tok.value.as_string());
- node->as_mask_lval().add_flags(tok.flags());
break;
case token_t::IDENT: {
diff --git a/parser.h b/parser.h
index 6b68c41b..294d28ff 100644
--- a/parser.h
+++ b/parser.h
@@ -46,10 +46,14 @@ class expr_t::parser_t : public noncopyable
#define EXPR_PARSE_NO_ASSIGN 0x08
#define EXPR_PARSE_NO_DATES 0x10
+public:
+ typedef uint_least8_t flags_t;
+
+private:
mutable token_t lookahead;
mutable bool use_lookahead;
- token_t& next_token(std::istream& in, token_t::flags_t tflags) const
+ token_t& next_token(std::istream& in, flags_t tflags) const
{
if (use_lookahead)
use_lookahead = false;
@@ -69,10 +73,6 @@ class expr_t::parser_t : public noncopyable
use_lookahead = true;
}
-public:
- typedef uint_least8_t flags_t;
-
-private:
ptr_op_t parse_value_term(std::istream& in, const flags_t flags) const;
ptr_op_t parse_unary_expr(std::istream& in, const flags_t flags) const;
ptr_op_t parse_mul_expr(std::istream& in, const flags_t flags) const;
diff --git a/qif.cc b/qif.cc
index 643db562..7bd19335 100644
--- a/qif.cc
+++ b/qif.cc
@@ -34,21 +34,21 @@ bool qif_parser_t::test(std::istream& in) const
}
unsigned int qif_parser_t::parse(std::istream& in,
- session_t& session,
- journal_t& journal,
+ session_t& session,
+ journal_t& journal,
account_t * master,
const path * original_file)
{
std::auto_ptr<entry_t> entry;
std::auto_ptr<amount_t> amount;
- xact_t * xact;
- unsigned int count = 0;
- account_t * misc = NULL;
- commodity_t * def_commodity = NULL;
- bool saw_splits = false;
- bool saw_category = false;
- xact_t * total = NULL;
+ xact_t * xact;
+ unsigned int count = 0;
+ account_t * misc = NULL;
+ commodity_t * def_commodity = NULL;
+ bool saw_splits = false;
+ bool saw_category = false;
+ xact_t * total = NULL;
entry.reset(new entry_t);
xact = new xact_t(master);
diff --git a/reconcile.cc b/reconcile.cc
index 12b66c8c..92068227 100644
--- a/reconcile.cc
+++ b/reconcile.cc
@@ -3,8 +3,8 @@
namespace ledger {
-#define xact_next(x) reinterpret_cast<xact_t *>(xact_xdata(*x).ptr)
-#define xact_next_ptr(x) reinterpret_cast<xact_t **>(&xact_xdata(*x).ptr)
+#define xact_next(x) reinterpret_cast<xact_t *>(x->xdata().ptr)
+#define xact_next_ptr(x) reinterpret_cast<xact_t **>(&x->xdata().ptr)
static bool search_for_balance(amount_t& amount,
xact_t ** prev, xact_t * next)
diff --git a/report.cc b/report.cc
index cfd2f1cd..80ad6f98 100644
--- a/report.cc
+++ b/report.cc
@@ -476,8 +476,8 @@ format_xacts::format_xacts(std::ostream& _output_stream,
void format_xacts::operator()(xact_t& xact)
{
- if (! xact_has_xdata(xact) ||
- ! (xact_xdata_(xact).dflags & XACT_DISPLAYED)) {
+ if (! xact.has_xdata() ||
+ ! xact.xdata().has_flags(XACT_EXT_DISPLAYED)) {
if (last_entry != xact.entry) {
first_line_format.format(output_stream, xact);
last_entry = xact.entry;
@@ -489,7 +489,7 @@ void format_xacts::operator()(xact_t& xact)
next_lines_format.format(output_stream, xact);
}
- xact_xdata(xact).dflags |= XACT_DISPLAYED;
+ xact.xdata().add_flags(XACT_EXT_DISPLAYED);
last_xact = &xact;
}
}
@@ -515,7 +515,7 @@ void format_entries::format_last_entry()
void format_entries::operator()(xact_t& xact)
{
- xact_xdata(xact).dflags |= XACT_TO_DISPLAY;
+ xact.xdata().add_flags(XACT_EXT_TO_DISPLAY);
if (last_entry && xact.entry != last_entry)
format_last_entry();
diff --git a/textual.cc b/textual.cc
index f9499e6e..3412f755 100644
--- a/textual.cc
+++ b/textual.cc
@@ -1079,7 +1079,7 @@ void write_textual_journal(journal_t& journal,
if (base) {
foreach (xact_t * xact, base->xacts) {
if (! xact->has_flags(XACT_AUTO)) {
- xact_xdata(*xact).dflags |= XACT_TO_DISPLAY;
+ xact->xdata().add_flags(XACT_EXT_TO_DISPLAY);
(*formatter)(*xact);
}
}
diff --git a/token.cc b/token.cc
index 2cb21d0d..deafdb40 100644
--- a/token.cc
+++ b/token.cc
@@ -53,8 +53,6 @@ void expr_t::token_t::parse_ident(std::istream& in)
kind = IDENT;
length = 0;
- clear_flags();
-
char buf[256];
READ_INTO_(in, buf, 255, c, length,
std::isalnum(c) || c == '_' || c == '.' || c == '-');
@@ -122,7 +120,7 @@ void expr_t::token_t::parse_ident(std::istream& in)
value.set_string(buf);
}
-void expr_t::token_t::next(std::istream& in, const unsigned int pflags)
+void expr_t::token_t::next(std::istream& in, const uint_least8_t pflags)
{
if (in.eof()) {
kind = TOK_EOF;
@@ -284,19 +282,6 @@ void expr_t::token_t::next(std::istream& in, const unsigned int pflags)
in.get(c);
length++;
- if (short_account_mask)
- set_flags(MASK_SHORT_ACCOUNT);
- else if (code_mask)
- set_flags(MASK_CODE);
- else if (commodity_mask)
- set_flags(MASK_COMMODITY);
- else if (payee_mask)
- set_flags(MASK_PAYEE);
- else if (note_mask)
- set_flags(MASK_NOTE);
- else
- set_flags(MASK_ACCOUNT);
-
kind = MASK;
value.set_string(buf);
break;
diff --git a/token.h b/token.h
index 73833a2a..04ca39c1 100644
--- a/token.h
+++ b/token.h
@@ -36,7 +36,7 @@
namespace ledger {
-struct expr_t::token_t : public noncopyable, public supports_flags<>
+struct expr_t::token_t : public noncopyable
{
enum kind_t {
VALUE, // any kind of literal value
@@ -79,7 +79,7 @@ struct expr_t::token_t : public noncopyable, public supports_flags<>
value_t value;
std::size_t length;
- explicit token_t() : supports_flags<>(), kind(UNKNOWN), length(0) {
+ explicit token_t() : kind(UNKNOWN), length(0) {
TRACE_CTOR(token_t, "");
}
~token_t() throw() {
@@ -104,7 +104,7 @@ struct expr_t::token_t : public noncopyable, public supports_flags<>
}
void parse_ident(std::istream& in);
- void next(std::istream& in, unsigned int flags);
+ void next(std::istream& in, const uint_least8_t flags);
void rewind(std::istream& in);
void unexpected();
diff --git a/walk.cc b/walk.cc
index c082fc3a..067e057d 100644
--- a/walk.cc
+++ b/walk.cc
@@ -8,24 +8,23 @@
namespace ledger {
template <>
-bool compare_items<xact_t>::operator()(const xact_t * left,
- const xact_t * right)
+bool compare_items<xact_t>::operator()(xact_t * left, xact_t * right)
{
assert(left);
assert(right);
- xact_xdata_t& lxdata(xact_xdata(*left));
- if (! (lxdata.dflags & XACT_SORT_CALC)) {
- lxdata.sort_value = sort_order.calc(const_cast<xact_t&>(*left));
+ xact_t::xdata_t& lxdata(left->xdata());
+ if (! lxdata.has_flags(XACT_EXT_SORT_CALC)) {
+ lxdata.sort_value = sort_order.calc(*left);
lxdata.sort_value.reduce();
- lxdata.dflags |= XACT_SORT_CALC;
+ lxdata.add_flags(XACT_EXT_SORT_CALC);
}
- xact_xdata_t& rxdata(xact_xdata(*right));
- if (! (rxdata.dflags & XACT_SORT_CALC)) {
- rxdata.sort_value = sort_order.calc(const_cast<xact_t&>(*right));
+ xact_t::xdata_t& rxdata(right->xdata());
+ if (! rxdata.has_flags(XACT_EXT_SORT_CALC)) {
+ rxdata.sort_value = sort_order.calc(*right);
rxdata.sort_value.reduce();
- rxdata.dflags |= XACT_SORT_CALC;
+ rxdata.add_flags(XACT_EXT_SORT_CALC);
}
DEBUG("ledger.walk.compare_items_xact",
@@ -36,27 +35,6 @@ bool compare_items<xact_t>::operator()(const xact_t * left,
return lxdata.sort_value < rxdata.sort_value;
}
-xact_xdata_t& xact_xdata(const xact_t& xact)
-{
- if (! xact.data)
- xact.data = new xact_xdata_t();
- return *static_cast<xact_xdata_t *>(xact.data);
-}
-
-void add_xact_to(const xact_t& xact, value_t& value)
-{
- if (xact_has_xdata(xact) &&
- xact_xdata_(xact).dflags & XACT_COMPOUND) {
- value += xact_xdata_(xact).value;
- }
- else if (xact.cost || (! value.is_null() && ! value.is_realzero())) {
- value.add(xact.amount, xact.cost);
- }
- else {
- value = xact.amount;
- }
-}
-
void entries_iterator::reset(session_t& session)
{
journals_i = session.journals.begin();
@@ -157,11 +135,11 @@ void truncate_entries::flush()
void set_account_value::operator()(xact_t& xact)
{
- account_t * acct = xact_account(xact);
+ account_t * acct = xact.reported_account();
assert(acct);
account_xdata_t& xdata = account_xdata(*acct);
- add_xact_to(xact, xdata.value);
+ xact.add_to_value(xdata.value);
xdata.count++;
if (xact.has_flags(XACT_VIRTUAL))
@@ -176,7 +154,7 @@ void sort_xacts::post_accumulated_xacts()
compare_items<xact_t>(sort_order));
foreach (xact_t * xact, xacts) {
- xact_xdata(*xact).dflags &= ~XACT_SORT_CALC;
+ xact->xdata().drop_flags(XACT_EXT_SORT_CALC);
item_handler<xact_t>::operator()(*xact);
}
@@ -186,26 +164,24 @@ void sort_xacts::post_accumulated_xacts()
void calc_xacts::operator()(xact_t& xact)
{
try {
+ xact_t::xdata_t& xdata(xact.xdata());
+
+ if (last_xact && last_xact->has_xdata()) {
+ if (xdata.total.is_null())
+ xdata.total = last_xact->xdata().total;
+ else
+ xdata.total += last_xact->xdata().total;
+ xdata.index = last_xact->xdata().index + 1;
+ } else {
+ xdata.index = 0;
+ }
- xact_xdata_t& xdata(xact_xdata(xact));
-
- if (last_xact && xact_has_xdata(*last_xact)) {
- if (xdata.total.is_null())
- xdata.total = xact_xdata_(*last_xact).total;
- else
- xdata.total += xact_xdata_(*last_xact).total;
- xdata.index = xact_xdata_(*last_xact).index + 1;
- } else {
- xdata.index = 0;
- }
-
- if (! (xdata.dflags & XACT_NO_TOTAL))
- add_xact_to(xact, xdata.total);
-
- item_handler<xact_t>::operator()(xact);
+ if (! xdata.has_flags(XACT_EXT_NO_TOTAL))
+ xact.add_to_value(xdata.total);
- last_xact = &xact;
+ item_handler<xact_t>::operator()(xact);
+ last_xact = &xact;
}
catch (const std::exception& err) {
add_error_context("Calculating transaction at");
@@ -218,9 +194,9 @@ void calc_xacts::operator()(xact_t& xact)
void invert_xacts::operator()(xact_t& xact)
{
- if (xact_has_xdata(xact) &&
- xact_xdata_(xact).dflags & XACT_COMPOUND) {
- xact_xdata_(xact).value.negate();
+ if (xact.has_xdata() &&
+ xact.xdata().has_flags(XACT_EXT_COMPOUND)) {
+ xact.xdata().value.negate();
} else {
xact.amount.negate();
if (xact.cost)
@@ -251,7 +227,7 @@ void handle_value(const value_t& value,
// temporary, do so now.
if (component_xacts)
- xact_xdata(xact).copy_component_xacts(*component_xacts);
+ xact.xdata().copy_component_xacts(*component_xacts);
// If the account for this xact is all virtual, then report
// the xact as such. This allows subtotal reports to show
@@ -264,7 +240,7 @@ void handle_value(const value_t& value,
xact.add_flags(XACT_BALANCE);
}
- xact_xdata_t& xdata(xact_xdata(xact));
+ xact_t::xdata_t& xdata(xact.xdata());
if (is_valid(date))
xdata.date = date;
@@ -286,7 +262,7 @@ void handle_value(const value_t& value,
case value_t::BALANCE:
case value_t::BALANCE_PAIR:
xdata.value = temp;
- flags |= XACT_COMPOUND;
+ flags |= XACT_EXT_COMPOUND;
break;
default:
@@ -295,7 +271,7 @@ void handle_value(const value_t& value,
}
if (flags)
- xdata.dflags |= flags;
+ xdata.add_flags(flags);
handler(xact);
}
@@ -330,7 +306,7 @@ void collapse_xacts::operator()(xact_t& xact)
if (last_entry && last_entry != xact.entry && count > 0)
report_subtotal();
- add_xact_to(xact, subtotal);
+ xact.add_to_value(subtotal);
count++;
last_entry = xact.entry;
@@ -343,12 +319,12 @@ void related_xacts::flush()
foreach (xact_t * xact, xacts) {
if (xact->entry) {
foreach (xact_t * r_xact, xact->entry->xacts) {
- xact_xdata_t& xdata = xact_xdata(*r_xact);
- if (! (xdata.dflags & XACT_HANDLED) &&
- (! (xdata.dflags & XACT_RECEIVED) ?
+ xact_t::xdata_t& xdata(r_xact->xdata());
+ if (! xdata.has_flags(XACT_EXT_HANDLED) &&
+ (! xdata.has_flags(XACT_EXT_RECEIVED) ?
! r_xact->has_flags(XACT_AUTO | XACT_VIRTUAL) :
also_matching)) {
- xdata.dflags |= XACT_HANDLED;
+ xdata.add_flags(XACT_EXT_HANDLED);
item_handler<xact_t>::operator()(*r_xact);
}
}
@@ -356,10 +332,10 @@ void related_xacts::flush()
// This code should only be reachable from the "output"
// command, since that is the only command which attempts to
// output auto or period entries.
- xact_xdata_t& xdata = xact_xdata(*xact);
- if (! (xdata.dflags & XACT_HANDLED) &&
+ xact_t::xdata_t& xdata(xact->xdata());
+ if (! xdata.has_flags(XACT_EXT_HANDLED) &&
! xact->has_flags(XACT_AUTO)) {
- xdata.dflags |= XACT_HANDLED;
+ xdata.add_flags(XACT_EXT_HANDLED);
item_handler<xact_t>::operator()(*xact);
}
}
@@ -373,7 +349,7 @@ void changed_value_xacts::output_diff(const date_t& date)
{
value_t cur_bal;
- xact_xdata(*last_xact).date = date;
+ last_xact->xdata().date = date;
#if 0
compute_total(cur_bal, details_t(*last_xact));
#endif
@@ -381,7 +357,7 @@ void changed_value_xacts::output_diff(const date_t& date)
#if 0
// jww (2008-04-24): What does this do?
- xact_xdata(*last_xact).date = 0;
+ last_xact->xdata().date = 0;
#endif
if (value_t diff = cur_bal - last_balance) {
@@ -390,24 +366,18 @@ void changed_value_xacts::output_diff(const date_t& date)
entry.payee = "Commodities revalued";
entry._date = date;
- handle_value(diff, NULL, &entry, XACT_NO_TOTAL, xact_temps,
+ handle_value(diff, NULL, &entry, XACT_EXT_NO_TOTAL, xact_temps,
*handler);
}
}
void changed_value_xacts::operator()(xact_t& xact)
{
- if (last_xact) {
- date_t date;
- if (xact_has_xdata(*last_xact))
- date = xact_xdata_(*last_xact).date;
- else
- date = xact.date();
- output_diff(date);
- }
+ if (last_xact)
+ output_diff(last_xact->reported_date());
if (changed_values_only)
- xact_xdata(xact).dflags |= XACT_DISPLAYED;
+ xact.xdata().add_flags(XACT_EXT_DISPLAYED);
item_handler<xact_t>::operator()(xact);
@@ -422,9 +392,13 @@ void changed_value_xacts::operator()(xact_t& xact)
void component_xacts::operator()(xact_t& xact)
{
if (handler && pred(xact)) {
- if (xact_has_xdata(xact) &&
- xact_xdata_(xact).have_component_xacts())
- xact_xdata_(xact).walk_component_xacts(*handler);
+ if (xact.has_xdata() &&
+ xact.xdata().has_component_xacts())
+#if 0
+ xact.xdata().walk_component_xacts(*handler);
+#else
+ ;
+#endif
else
(*handler)(xact);
}
@@ -460,13 +434,13 @@ void subtotal_xacts::operator()(xact_t& xact)
if (! is_valid(finish) || xact.date() > finish)
finish = xact.date();
- account_t * acct = xact_account(xact);
+ account_t * acct = xact.reported_account();
assert(acct);
values_map::iterator i = values.find(acct->fullname());
if (i == values.end()) {
value_t temp;
- add_xact_to(xact, temp);
+ xact.add_to_value(temp);
std::pair<values_map::iterator, bool> result
= values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp)));
assert(result.second);
@@ -474,7 +448,7 @@ void subtotal_xacts::operator()(xact_t& xact)
if (remember_components)
(*result.first).second.components.push_back(&xact);
} else {
- add_xact_to(xact, (*i).second.value);
+ xact.add_to_value((*i).second.value);
if (remember_components)
(*i).second.components.push_back(&xact);
@@ -485,9 +459,9 @@ void subtotal_xacts::operator()(xact_t& xact)
// that contain only virtual xacts.
if (! xact.has_flags(XACT_VIRTUAL))
- account_xdata(*xact_account(xact)).dflags |= ACCOUNT_HAS_NON_VIRTUALS;
+ account_xdata(*xact.reported_account()).dflags |= ACCOUNT_HAS_NON_VIRTUALS;
else if (! xact.has_flags(XACT_BALANCE))
- account_xdata(*xact_account(xact)).dflags |= ACCOUNT_HAS_UNB_VIRTUALS;
+ account_xdata(*xact.reported_account()).dflags |= ACCOUNT_HAS_UNB_VIRTUALS;
}
void interval_xacts::report_subtotal(const date_t& date)
@@ -675,7 +649,7 @@ void budget_xacts::report_budget_items(const date_t& date)
xact_t& xact = *pair.second;
DEBUG("ledger.walk.budget", "Reporting budget for "
- << xact_account(xact)->fullname());
+ << xact.reported_account()->fullname());
entry_temps.push_back(entry_t());
entry_t& entry = entry_temps.back();
@@ -704,15 +678,15 @@ void budget_xacts::operator()(xact_t& xact)
bool xact_in_budget = false;
foreach (pending_xacts_list::value_type& pair, pending_xacts)
- for (account_t * acct = xact_account(xact);
+ for (account_t * acct = xact.reported_account();
acct;
acct = acct->parent) {
- if (acct == xact_account(*pair.second)) {
+ if (acct == (*pair.second).reported_account()) {
xact_in_budget = true;
// Report the xact as if it had occurred in the parent
// account.
- if (xact_account(xact) != acct)
- xact_xdata(xact).account = acct;
+ if (xact.reported_account() != acct)
+ xact.xdata().account = acct;
goto handle;
}
}
@@ -782,8 +756,8 @@ void forecast_xacts::flush()
item_handler<xact_t>::operator()(temp);
- if (xact_has_xdata(temp) &&
- xact_xdata_(temp).dflags & XACT_MATCHES) {
+ if (temp.has_xdata() &&
+ temp.xdata().has_flags(XACT_EXT_MATCHES)) {
if (! pred(temp))
break;
last = temp.date();
@@ -808,21 +782,20 @@ void forecast_xacts::flush()
}
template <>
-bool compare_items<account_t>::operator()(const account_t * left,
- const account_t * right)
+bool compare_items<account_t>::operator()(account_t * left, account_t * right)
{
assert(left);
assert(right);
account_xdata_t& lxdata(account_xdata(*left));
if (! (lxdata.dflags & ACCOUNT_SORT_CALC)) {
- lxdata.sort_value = sort_order.calc(const_cast<account_t&>(*left));
+ lxdata.sort_value = sort_order.calc(*left);
lxdata.dflags |= ACCOUNT_SORT_CALC;
}
account_xdata_t& rxdata(account_xdata(*right));
if (! (rxdata.dflags & ACCOUNT_SORT_CALC)) {
- rxdata.sort_value = sort_order.calc(const_cast<account_t&>(*right));
+ rxdata.sort_value = sort_order.calc(*right);
rxdata.dflags |= ACCOUNT_SORT_CALC;
}
diff --git a/walk.h b/walk.h
index b3bf3098..1d449b2c 100644
--- a/walk.h
+++ b/walk.h
@@ -2,6 +2,7 @@
#define _WALK_H
#include "journal.h"
+#include "entry.h"
#include "account.h"
namespace ledger {
@@ -34,123 +35,6 @@ public:
typedef shared_ptr<item_handler<xact_t> > xact_handler_ptr;
-template <typename T>
-class compare_items
-{
- expr_t sort_order;
-
- compare_items();
-
-public:
- compare_items(const compare_items& other) : sort_order(other.sort_order) {
- TRACE_CTOR(compare_items, "copy");
- }
- compare_items(const expr_t& _sort_order) : sort_order(_sort_order) {
- TRACE_CTOR(compare_items, "const value_expr&");
- }
- ~compare_items() throw() {
- TRACE_DTOR(compare_items);
- }
- bool operator()(const T * left, const T * right);
-};
-
-template <typename T>
-bool compare_items<T>::operator()(const T * left, const T * right)
-{
- assert(left);
- assert(right);
- return sort_order.calc(*left) < sort_order.calc(*right);
-}
-
-template <>
-bool compare_items<xact_t>::operator()(const xact_t * left,
- const xact_t * right);
-template <>
-bool compare_items<account_t>::operator()(const account_t * left,
- const account_t * right);
-
-//////////////////////////////////////////////////////////////////////
-//
-// Xact handlers
-//
-
-#define XACT_RECEIVED 0x0001
-#define XACT_HANDLED 0x0002
-#define XACT_TO_DISPLAY 0x0004
-#define XACT_DISPLAYED 0x0008
-#define XACT_NO_TOTAL 0x0010
-#define XACT_SORT_CALC 0x0020
-#define XACT_COMPOUND 0x0040
-#define XACT_MATCHES 0x0080
-
-struct xact_xdata_t : public noncopyable
-{
- value_t total;
- value_t sort_value;
- value_t value;
- unsigned int index;
- unsigned short dflags;
- date_t date;
- account_t * account;
- void * ptr;
- xacts_list * component_xacts;
-
- xact_xdata_t()
- : index(0), dflags(0),
- account(NULL), ptr(NULL), component_xacts(NULL) {
- TRACE_CTOR(xact_xdata_t, "");
- }
- ~xact_xdata_t() {
- TRACE_DTOR(xact_xdata_t);
- if (component_xacts)
- checked_delete(component_xacts);
- }
-
- void remember_xact(xact_t& xact) {
- if (! component_xacts)
- component_xacts = new xacts_list;
- component_xacts->push_back(&xact);
- }
-
- bool have_component_xacts() const {
- return component_xacts != NULL && ! component_xacts->empty();
- }
-
- void copy_component_xacts(xacts_list& xacts) {
- foreach (xact_t * xact, xacts)
- remember_xact(*xact);
- }
-
- void walk_component_xacts(item_handler<xact_t>& handler) const {
- foreach (xact_t * xact, *component_xacts)
- handler(*xact);
- }
-};
-
-inline bool xact_has_xdata(const xact_t& xact) {
- return xact.data != NULL;
-}
-
-inline xact_xdata_t& xact_xdata_(const xact_t& xact) {
- return *static_cast<xact_xdata_t *>(xact.data);
-}
-
-xact_xdata_t& xact_xdata(const xact_t& xact);
-void add_xact_to(const xact_t& xact, value_t& value);
-
-inline account_t * xact_account(xact_t& xact) {
- if (xact.data) {
- account_t * account = xact_xdata(xact).account;
- if (account)
- return account;
- }
- return xact.account;
-}
-
-inline const account_t * xact_account(const xact_t& xact) {
- return xact_account(const_cast<xact_t&>(xact));
-}
-
//////////////////////////////////////////////////////////////////////
class entries_iterator : public noncopyable
@@ -226,7 +110,7 @@ public:
class session_xacts_iterator : public xacts_iterator
{
- entries_iterator entries;
+ entries_iterator entries;
entry_xacts_iterator xacts;
public:
@@ -258,10 +142,7 @@ class clear_xact_xdata : public item_handler<xact_t>
{
public:
virtual void operator()(xact_t& xact) {
- if (xact.data) {
- checked_delete(static_cast<xact_xdata_t *>(xact.data));
- xact.data = NULL;
- }
+ xact.clear_xdata();
}
};
@@ -270,11 +151,11 @@ class pass_down_xacts : public item_handler<xact_t>
pass_down_xacts();
public:
- pass_down_xacts(xact_handler_ptr handler,
- xacts_iterator& iter)
- : item_handler<xact_t>(handler) {
- TRACE_CTOR(pass_down_xacts,
- "xact_handler_ptr, xacts_iterator");
+ pass_down_xacts(xact_handler_ptr handler, xacts_iterator& iter)
+ : item_handler<xact_t>(handler)
+ {
+ TRACE_CTOR(pass_down_xacts, "xact_handler_ptr, xacts_iterator");
+
for (xact_t * xact = iter(); xact; xact = iter())
item_handler<xact_t>::operator()(*xact);
}
@@ -284,6 +165,25 @@ public:
}
};
+class push_to_xacts_list : public item_handler<xact_t>
+{
+ push_to_xacts_list();
+
+public:
+ xacts_list& xacts;
+
+ push_to_xacts_list(xacts_list& _xacts) : xacts(_xacts) {
+ TRACE_CTOR(push_to_xacts_list, "xacts_list&");
+ }
+ virtual ~push_to_xacts_list() {
+ TRACE_DTOR(push_to_xacts_list);
+ }
+
+ virtual void operator()(xact_t& xact) {
+ xacts.push_back(&xact);
+ }
+};
+
class truncate_entries : public item_handler<xact_t>
{
int head_count;
@@ -306,6 +206,9 @@ public:
virtual void flush();
virtual void operator()(xact_t& xact) {
+ if (tail_count == 0 && head_count > 0 &&
+ xacts.size() >= static_cast<unsigned int>(head_count))
+ return;
xacts.push_back(&xact);
}
};
@@ -319,26 +222,6 @@ public:
virtual void operator()(xact_t& xact);
};
-class push_to_xacts_list : public item_handler<xact_t>
-{
- push_to_xacts_list();
-
-public:
- xacts_list& xact_list;
-
- push_to_xacts_list(xacts_list& _xact_list)
- : xact_list(_xact_list) {
- TRACE_CTOR(push_to_xacts_list, "xacts_list&");
- }
- virtual ~push_to_xacts_list() {
- TRACE_DTOR(push_to_xacts_list);
- }
-
- virtual void operator()(xact_t& xact) {
- xact_list.push_back(&xact);
- }
-};
-
class sort_xacts : public item_handler<xact_t>
{
typedef std::deque<xact_t *> xacts_deque;
@@ -444,7 +327,7 @@ public:
virtual void operator()(xact_t& xact) {
if (pred(xact)) {
- xact_xdata(xact).dflags |= XACT_MATCHES;
+ xact.xdata().add_flags(XACT_EXT_MATCHES);
(*handler)(xact);
}
}
@@ -567,7 +450,7 @@ public:
virtual void flush();
virtual void operator()(xact_t& xact) {
- xact_xdata(xact).dflags |= XACT_RECEIVED;
+ xact.xdata().add_flags(XACT_EXT_RECEIVED);
xacts.push_back(&xact);
}
};
@@ -577,12 +460,12 @@ class changed_value_xacts : public item_handler<xact_t>
// This filter requires that calc_xacts be used at some point
// later in the chain.
- bool changed_values_only;
+ bool changed_values_only;
xact_t * last_xact;
- value_t last_balance;
+ value_t last_balance;
- std::list<entry_t> entry_temps;
- std::list<xact_t> xact_temps;
+ std::list<entry_t> entry_temps;
+ std::list<xact_t> xact_temps;
changed_value_xacts();
@@ -1045,6 +928,40 @@ public:
virtual journal_t * operator()();
};
+template <typename T>
+class compare_items
+{
+ expr_t sort_order;
+
+ compare_items();
+
+public:
+ compare_items(const compare_items& other) : sort_order(other.sort_order) {
+ TRACE_CTOR(compare_items, "copy");
+ }
+ compare_items(const expr_t& _sort_order) : sort_order(_sort_order) {
+ TRACE_CTOR(compare_items, "const value_expr&");
+ }
+ ~compare_items() throw() {
+ TRACE_DTOR(compare_items);
+ }
+ bool operator()(T * left, T * right);
+};
+
+template <typename T>
+bool compare_items<T>::operator()(T * left, T * right)
+{
+ assert(left);
+ assert(right);
+ return sort_order.calc(*left) < sort_order.calc(*right);
+}
+
+template <>
+bool compare_items<xact_t>::operator()(xact_t * left, xact_t * right);
+template <>
+bool compare_items<account_t>::operator()(account_t * left,
+ account_t * right);
+
} // namespace ledger
#endif // _WALK_H
diff --git a/xact.cc b/xact.cc
index 8c9014f4..c6f76ebe 100644
--- a/xact.cc
+++ b/xact.cc
@@ -58,18 +58,39 @@ date_t xact_t::effective_date() const
}
namespace {
- value_t get_amount(xact_t& xact)
- {
- return xact.amount;
+ value_t get_state(xact_t& xact) {
+ return long(xact.state);
+ }
+
+ value_t state_uncleared(call_scope_t&) {
+ return 0L;
+ }
+
+ value_t state_cleared(call_scope_t&) {
+ return 1L;
}
- value_t get_date(xact_t& xact)
- {
+ value_t state_pending(call_scope_t&) {
+ return 2L;
+ }
+
+ value_t get_date(xact_t& xact) {
return xact.date();
}
- value_t get_account(call_scope_t& scope)
- {
+ value_t get_amount(xact_t& xact) {
+ return xact.amount;
+ }
+
+ value_t get_cost(xact_t& xact) {
+ return xact.cost ? *xact.cost : xact.amount;
+ }
+
+ value_t get_note(xact_t& xact) {
+ return string_value(xact.note ? *xact.note : ":NOTELESS:");
+ }
+
+ value_t get_account(call_scope_t& scope) {
xact_t& xact(downcast<xact_t>(*scope.parent));
long width = 0;
@@ -78,7 +99,7 @@ namespace {
// jww (2008-08-02): Accept a width here so that we can abbreviate the
// string.
- string name = xact.account->fullname();
+ string name = xact.reported_account()->fullname();
if (width > 2)
name = format_t::truncate(name, width - 2, true);
@@ -92,10 +113,33 @@ namespace {
return string_value(name);
}
- value_t get_account_base(xact_t& xact)
- {
- assert(false);
- return NULL_VALUE;
+ value_t get_account_base(xact_t& xact) {
+ return string_value(xact.reported_account()->name);
+ }
+
+ value_t get_beg_pos(xact_t& xact) {
+ return long(xact.beg_pos);
+ }
+
+ value_t get_beg_line(xact_t& xact) {
+ return long(xact.beg_line);
+ }
+
+ value_t get_end_pos(xact_t& xact) {
+ return long(xact.end_pos);
+ }
+
+ value_t get_end_line(xact_t& xact) {
+ return long(xact.end_line);
+ }
+
+ // xdata_t members...
+
+ value_t get_total(xact_t& xact) {
+ if (xact.xdata_)
+ return xact.xdata_->total;
+ else
+ return xact.amount;
}
template <value_t (*Func)(xact_t&)>
@@ -115,16 +159,33 @@ expr_t::ptr_op_t xact_t::lookup(const string& name)
else if (name == "account_base")
return WRAP_FUNCTOR(get_wrapper<&get_account_base>);
break;
+
+ case 'c':
+ if (name == "cleared")
+ return expr_t::op_t::wrap_value(0L);
+ break;
+
case 'd':
if (name[1] == '\0' || name == "date")
return WRAP_FUNCTOR(get_wrapper<&get_date>);
break;
+
case 'f':
if (name.find("fmt_") == 0) {
if (name == "fmt_A")
return WRAP_FUNCTOR(get_account);
}
break;
+
+ case 'p':
+ if (name == "pending")
+ return expr_t::op_t::wrap_value(2L);
+ break;
+
+ case 'u':
+ if (name == "uncleared")
+ return expr_t::op_t::wrap_value(1L);
+ break;
}
return entry->lookup(name);
}
@@ -187,4 +248,17 @@ xact_context::xact_context(const xact_t& _xact, const string& desc) throw()
}
#endif
+void xact_t::add_to_value(value_t& value)
+{
+ if (xdata_ && xdata_->has_flags(XACT_EXT_COMPOUND)) {
+ value += xdata_->value;
+ }
+ else if (cost || (! value.is_null() && ! value.is_realzero())) {
+ value.add(amount, cost);
+ }
+ else {
+ value = amount;
+ }
+}
+
} // namespace ledger
diff --git a/xact.h b/xact.h
index d843bd11..5a3aa32f 100644
--- a/xact.h
+++ b/xact.h
@@ -37,7 +37,15 @@
namespace ledger {
-// These flags persist with the object
+class entry_t;
+class account_t;
+
+class xact_t;
+typedef std::list<xact_t *> xacts_list;
+
+class xact_t : public supports_flags<>, public scope_t
+{
+public:
#define XACT_NORMAL 0x0000 // no flags at all, a basic transaction
#define XACT_VIRTUAL 0x0001 // the account was specified with (parens)
#define XACT_BALANCE 0x0002 // the account was specified with [brackets]
@@ -47,47 +55,42 @@ namespace ledger {
#define XACT_GENERATED 0x0020 // transaction was not found in a journal
#define XACT_TEMP 0x0040 // transaction is a temporary object
-class entry_t;
-class account_t;
-
-class xact_t : public supports_flags<>, public scope_t
-{
- public:
enum state_t { UNCLEARED, CLEARED, PENDING };
entry_t * entry;
- state_t state;
account_t * account;
+ state_t state;
+
optional<date_t> _date;
optional<date_t> _date_eff;
+ optional<string> note;
+
amount_t amount;
optional<expr_t> amount_expr;
optional<amount_t> cost;
optional<expr_t> cost_expr;
- optional<string> note;
+
istream_pos_type beg_pos;
unsigned long beg_line;
istream_pos_type end_pos;
unsigned long end_line;
- mutable void * data;
- static bool use_effective_date;
+ static bool use_effective_date;
xact_t(account_t * _account = NULL,
- flags_t _flags = XACT_NORMAL)
- : supports_flags<>(_flags), entry(NULL),
- state(UNCLEARED), account(_account),
- beg_pos(0), beg_line(0), end_pos(0), end_line(0), data(NULL)
+ flags_t _flags = XACT_NORMAL)
+ : supports_flags<>(_flags), entry(NULL), account(_account),
+ state(UNCLEARED), beg_pos(0), beg_line(0), end_pos(0), end_line(0)
{
TRACE_CTOR(xact_t, "account_t *, flags_t");
}
xact_t(account_t * _account,
- const amount_t& _amount,
- flags_t _flags = XACT_NORMAL,
- const optional<string>& _note = none)
- : supports_flags<>(_flags), entry(NULL), state(UNCLEARED),
- account(_account), amount(_amount), note(_note),
- beg_pos(0), beg_line(0), end_pos(0), end_line(0), data(NULL)
+ const amount_t& _amount,
+ flags_t _flags = XACT_NORMAL,
+ const optional<string>& _note = none)
+ : supports_flags<>(_flags), entry(NULL), account(_account),
+ state(UNCLEARED), note(_note), amount(_amount),
+ beg_pos(0), beg_line(0), end_pos(0), end_line(0)
{
TRACE_CTOR(xact_t,
"account_t *, const amount_t&, flags_t, const string&");
@@ -96,18 +99,18 @@ class xact_t : public supports_flags<>, public scope_t
: supports_flags<>(xact),
scope_t(),
entry(xact.entry),
- state(xact.state),
account(xact.account),
+ state(xact.state),
_date(xact._date),
_date_eff(xact._date_eff),
+ note(xact.note),
amount(xact.amount),
cost(xact.cost),
- note(xact.note),
beg_pos(xact.beg_pos),
beg_line(xact.beg_line),
end_pos(xact.end_pos),
end_line(xact.end_line),
- data(xact.data) // jww (2008-07-19): What are the copy semantics?
+ xdata_(xact.xdata_) // jww (2008-07-19): What are the copy semantics?
{
TRACE_CTOR(xact_t, "copy");
}
@@ -129,6 +132,95 @@ class xact_t : public supports_flags<>, public scope_t
virtual expr_t::ptr_op_t lookup(const string& name);
bool valid() const;
+
+ struct xdata_t : public supports_flags<>
+ {
+#define XACT_EXT_RECEIVED 0x01
+#define XACT_EXT_HANDLED 0x02
+#define XACT_EXT_TO_DISPLAY 0x04
+#define XACT_EXT_DISPLAYED 0x08
+#define XACT_EXT_NO_TOTAL 0x10
+#define XACT_EXT_SORT_CALC 0x20
+#define XACT_EXT_COMPOUND 0x40
+#define XACT_EXT_MATCHES 0x80
+
+ value_t total;
+ value_t sort_value;
+ value_t value;
+ unsigned int index;
+ date_t date;
+ account_t * account;
+ void * ptr;
+
+ optional<xacts_list> component_xacts;
+
+ xdata_t() : supports_flags<>(), index(0), account(NULL), ptr(NULL) {
+ TRACE_CTOR(xdata_t, "");
+ }
+ ~xdata_t() throw() {
+ TRACE_DTOR(xdata_t);
+ }
+
+ void remember_xact(xact_t& xact) {
+ if (! component_xacts)
+ component_xacts = xacts_list();
+ component_xacts->push_back(&xact);
+ }
+
+ bool has_component_xacts() const {
+ return component_xacts && ! component_xacts->empty();
+ }
+
+ void copy_component_xacts(xacts_list& xacts) {
+ foreach (xact_t * xact, xacts)
+ remember_xact(*xact);
+ }
+
+#if 0
+ void walk_component_xacts(item_handler<xact_t>& handler) const {
+ foreach (xact_t * xact, *component_xacts)
+ handler(*xact);
+ }
+#endif
+ };
+
+ // This variable holds a pointer to "extended data" which is usually
+ // produced only during reporting, and only for the transaction set being
+ // reported. It's a memory-saving measure to delay allocation until the
+ // last possible moment.
+ mutable optional<xdata_t> xdata_;
+
+ bool has_xdata() const {
+ return xdata_;
+ }
+ void clear_xdata() {
+ xdata_ = none;
+ }
+ xdata_t& xdata() {
+ if (! xdata_)
+ xdata_ = xdata_t();
+ return *xdata_;
+ }
+
+ void add_to_value(value_t& value);
+
+ date_t reported_date() const {
+ if (xdata_ && is_valid(xdata_->date))
+ return xdata_->date;
+ return
+ date();
+ }
+
+ account_t * reported_account() {
+ if (xdata_)
+ if (account_t * acct = xdata_->account)
+ return acct;
+ return account;
+ }
+
+ const account_t * reported_account() const {
+ return const_cast<xact_t *>(this)->reported_account();
+ }
};
} // namespace ledger
diff --git a/xml.cc b/xml.cc
index ebafd65b..c71aaa97 100644
--- a/xml.cc
+++ b/xml.cc
@@ -381,9 +381,9 @@ void format_xml_entries::format_last_entry()
}
bool first = true;
- foreach (const xact_t * xact, last_entry->xacts) {
- if (xact_has_xdata(*xact) &&
- xact_xdata_(*xact).dflags & XACT_TO_DISPLAY) {
+ foreach (xact_t * xact, last_entry->xacts) {
+ if (xact->has_xdata() &&
+ xact->xdata().has_flags(XACT_EXT_TO_DISPLAY)) {
if (first) {
output_stream << " <en:xacts>\n";
first = false;
@@ -427,9 +427,8 @@ void format_xml_entries::format_last_entry()
}
output_stream << " <tr:amount>\n";
- if (xact_xdata_(*xact).dflags & XACT_COMPOUND)
- xml_write_value(output_stream,
- xact_xdata_(*xact).value, 10);
+ if (xact->xdata().has_flags(XACT_EXT_COMPOUND))
+ xml_write_value(output_stream, xact->xdata().value, 10);
else
xml_write_value(output_stream, value_t(xact->amount), 10);
output_stream << " </tr:amount>\n";
@@ -448,13 +447,13 @@ void format_xml_entries::format_last_entry()
if (show_totals) {
output_stream << " <total>\n";
- xml_write_value(output_stream, xact_xdata_(*xact).total, 10);
+ xml_write_value(output_stream, xact->xdata().total, 10);
output_stream << " </total>\n";
}
output_stream << " </xact>\n";
- xact_xdata_(*xact).dflags |= XACT_DISPLAYED;
+ xact->xdata().add_flags(XACT_EXT_DISPLAYED);
}
}