diff options
author | John Wiegley <johnw@newartisans.com> | 2008-09-19 08:06:20 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-09-19 08:06:20 -0400 |
commit | fdc7a4e4c5423e79df4ad8905b5a67d45d2f85bc (patch) | |
tree | b7aa301f7d884315f00c42903778ea549e7833d7 | |
parent | 43ba0bb03807eea3fdcd4dd40fba10b00f823e24 (diff) | |
download | fork-ledger-fdc7a4e4c5423e79df4ad8905b5a67d45d2f85bc.tar.gz fork-ledger-fdc7a4e4c5423e79df4ad8905b5a67d45d2f85bc.tar.bz2 fork-ledger-fdc7a4e4c5423e79df4ad8905b5a67d45d2f85bc.zip |
Factored common parts of entry_t and xact_t into new item_t
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | src/account.cc | 7 | ||||
-rw-r--r-- | src/account.h | 7 | ||||
-rw-r--r-- | src/csv.cc | 23 | ||||
-rw-r--r-- | src/emacs.cc | 8 | ||||
-rw-r--r-- | src/entry.cc | 120 | ||||
-rw-r--r-- | src/entry.h | 48 | ||||
-rw-r--r-- | src/filters.cc | 28 | ||||
-rw-r--r-- | src/filters.h | 4 | ||||
-rw-r--r-- | src/gnucash.cc | 4 | ||||
-rw-r--r-- | src/item.cc | 141 | ||||
-rw-r--r-- | src/item.h | 135 | ||||
-rw-r--r-- | src/journal.cc | 21 | ||||
-rw-r--r-- | src/journal.h | 7 | ||||
-rw-r--r-- | src/ofx.cc | 3 | ||||
-rw-r--r-- | src/output.cc | 2 | ||||
-rw-r--r-- | src/qif.cc | 2 | ||||
-rw-r--r-- | src/reconcile.cc | 8 | ||||
-rw-r--r-- | src/session.cc | 4 | ||||
-rw-r--r-- | src/session.h | 2 | ||||
-rw-r--r-- | src/textual.cc | 32 | ||||
-rw-r--r-- | src/xact.cc | 153 | ||||
-rw-r--r-- | src/xact.h | 89 | ||||
-rw-r--r-- | src/xml.cc | 12 |
24 files changed, 445 insertions, 419 deletions
diff --git a/Makefile.am b/Makefile.am index fb1ea9f2..3d9701f7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -38,8 +38,9 @@ endif libledger_la_CPPFLAGS = $(libamounts_la_CPPFLAGS) libledger_la_LDFLAGS = -release 3.0.0 -libledger_la_SOURCES = \ +libledger_la_SOURCES = \ src/journal.cc \ + src/item.cc \ src/entry.cc \ src/xact.cc \ src/account.cc \ @@ -102,6 +103,7 @@ pkginclude_HEADERS = \ src/option.h \ \ src/journal.h \ + src/item.h \ src/entry.h \ src/xact.h \ src/account.h \ diff --git a/src/account.cc b/src/account.cc index f628817e..fc80a9d6 100644 --- a/src/account.cc +++ b/src/account.cc @@ -73,7 +73,7 @@ account_t * account_t::find_account(const string& name, if (! auto_create) return NULL; - account = new account_t(owner, this, first); + account = new account_t(this, first); std::pair<accounts_map::iterator, bool> result = accounts.insert(accounts_map::value_type(first, account)); assert(result.second); @@ -190,8 +190,7 @@ expr_t::ptr_op_t account_t::lookup(const string& name) break; } - assert(owner == session_t::current); - return owner->current_report->lookup(name); + return session_t::current->current_report->lookup(name); } bool account_t::valid() const @@ -234,7 +233,7 @@ void account_t::calculate_sums() } call_scope_t args(*this); - value_t amount(owner->current_report->get_amount_expr(args)); + value_t amount(session_t::current->current_report->get_amount_expr(args)); if (! amount.is_null()) { add_or_set_value(xd.total, amount); xd.total_count += xd.count; diff --git a/src/account.h b/src/account.h index 6bd11704..ff79e3be 100644 --- a/src/account.h +++ b/src/account.h @@ -47,7 +47,6 @@ class account_t : public scope_t public: typedef unsigned long ident_t; - session_t * owner; account_t * parent; string name; optional<string> note; @@ -58,17 +57,15 @@ class account_t : public scope_t mutable ident_t ident; mutable string _fullname; - account_t(session_t * _owner, - account_t * _parent = NULL, + account_t(account_t * _parent = NULL, const string& _name = "", const optional<string>& _note = none) - : scope_t(), owner(_owner), parent(_parent), name(_name), note(_note), + : scope_t(), parent(_parent), name(_name), note(_note), depth(parent ? parent->depth + 1 : 0), data(NULL), ident(0) { TRACE_CTOR(account_t, "account_t *, const string&, const string&"); } account_t(const account_t& other) : scope_t(), - owner(other.owner), parent(other.parent), name(other.name), note(other.note), @@ -102,28 +102,15 @@ void format_csv_xacts::operator()(xact_t& xact) } out << ','; - switch (xact.state) { - case xact_t::CLEARED: + switch (xact.state()) { + case item_t::CLEARED: write_escaped_string(out, "*"); break; - case xact_t::PENDING: + case item_t::PENDING: write_escaped_string(out, "!"); break; - default: { - xact_t::state_t state; - if (xact.entry->get_state(&state)) - switch (state) { - case xact_t::CLEARED: - write_escaped_string(out, "*"); - break; - case xact_t::PENDING: - write_escaped_string(out, "!"); - break; - default: - write_escaped_string(out, ""); - break; - } - } + default: + break; } out << ','; diff --git a/src/emacs.cc b/src/emacs.cc index cf787e75..dab9223f 100644 --- a/src/emacs.cc +++ b/src/emacs.cc @@ -45,7 +45,7 @@ void format_emacs_xacts::write_entry(entry_t& entry) out << (static_cast<unsigned long>(entry.beg_line) + 1) << " "; - tm when = gregorian::to_tm(entry.date()); + tm when = gregorian::to_tm(*entry.date()); std::time_t date = std::mktime(&when); // jww (2008-04-20): Is this GMT or local? out << "(" << (date / 65536) << " " << (date % 65536) << " 0) "; @@ -83,11 +83,11 @@ void format_emacs_xacts::operator()(xact_t& xact) out << "\"" << xact.reported_account()->fullname() << "\" \"" << xact.amount << "\""; - switch (xact.state) { - case xact_t::CLEARED: + switch (xact.state()) { + case item_t::CLEARED: out << " t"; break; - case xact_t::PENDING: + case item_t::PENDING: out << " pending"; break; default: diff --git a/src/entry.cc b/src/entry.cc index a66b8852..9f3af62e 100644 --- a/src/entry.cc +++ b/src/entry.cc @@ -38,8 +38,7 @@ namespace ledger { entry_base_t::entry_base_t(const entry_base_t& e) - : supports_flags<>(), journal(NULL), - beg_pos(0), beg_line(0), end_pos(0), end_line(0) + : item_t(), journal(NULL) { TRACE_CTOR(entry_base_t, "copy"); xacts.insert(xacts.end(), e.xacts.begin(), e.xacts.end()); @@ -53,8 +52,8 @@ entry_base_t::~entry_base_t() // If the transaction is a temporary, it will be destructed when the // temporary is. If it's from a binary cache, we can safely destruct it // but its memory will be deallocated with the cache. - if (! xact->has_flags(XACT_TEMP)) { - if (! xact->has_flags(XACT_IN_CACHE)) + if (! xact->has_flags(ITEM_TEMP)) { + if (! xact->has_flags(ITEM_IN_CACHE)) checked_delete(xact); else xact->~xact_t(); @@ -62,6 +61,20 @@ entry_base_t::~entry_base_t() } } +item_t::state_t entry_base_t::state() const +{ + bool first = true; + state_t result = UNCLEARED; + + foreach (xact_t * xact, xacts) { + if ((result == UNCLEARED && xact->_state != UNCLEARED) || + (result == PENDING && xact->_state == CLEARED)) + result = xact->_state; + } + + return result; +} + void entry_base_t::add_xact(xact_t * xact) { xacts.push_back(xact); @@ -133,8 +146,8 @@ bool entry_base_t::finalize() if (journal && journal->basket && xacts.size() == 1 && ! balance.is_null()) { // jww (2008-07-24): Need to make the rest of the code aware of what to do // when it sees a generated xact. - null_xact = new xact_t(journal->basket, XACT_GENERATED); - null_xact->state = (*xacts.begin())->state; + null_xact = new xact_t(journal->basket, ITEM_GENERATED); + null_xact->_state = (*xacts.begin())->_state; add_xact(null_xact); } @@ -170,7 +183,7 @@ bool entry_base_t::finalize() first = false; } else { add_xact(new xact_t(null_xact->account, pair.second.negate(), - XACT_GENERATED)); + ITEM_GENERATED)); } } } @@ -279,7 +292,7 @@ bool entry_base_t::finalize() amount_t basis_cost; amount_t ann_amount = commodity_t::exchange(x_amt, final_cost, basis_cost, xact->cost, none, - datetime_t(xact->actual_date(), + datetime_t(*xact->actual_date(), time_duration_t(0, 0, 0)), entry ? entry->code : optional<string>()); @@ -341,8 +354,7 @@ bool entry_base_t::finalize() } entry_t::entry_t(const entry_t& e) - : entry_base_t(e), scope_t(), _date(e._date), _date_eff(e._date_eff), - code(e.code), payee(e.payee) + : entry_base_t(e), code(e.code), payee(e.payee) { TRACE_CTOR(entry_t, "copy"); @@ -350,27 +362,6 @@ entry_t::entry_t(const entry_t& e) xact->entry = this; } -bool entry_t::get_state(xact_t::state_t * state) const -{ - bool first = true; - bool hetero = false; - - foreach (xact_t * xact, xacts) { - if (first || - xact->state == xact_t::CLEARED || - (xact->state == xact_t::PENDING && *state == xact_t::UNCLEARED)) { - *state = xact->state; - first = false; - } - else if (*state != xact->state) { - hetero = true; - break; - } - } - - return ! hetero; -} - void entry_t::add_xact(xact_t * xact) { xact->entry = this; @@ -378,26 +369,6 @@ void entry_t::add_xact(xact_t * xact) } namespace { - value_t get_date(entry_t& entry) { - return entry.date(); - } - - value_t get_status(entry_t& entry) { - xact_t::state_t status; - entry.get_state(&status); - return long(status); - } - value_t get_cleared(entry_t& entry) { - xact_t::state_t status; - entry.get_state(&status); - return status == xact_t::CLEARED; - } - value_t get_pending(entry_t& entry) { - xact_t::state_t status; - entry.get_state(&status); - return status == xact_t::PENDING; - } - value_t get_code(entry_t& entry) { if (entry.code) return string_value(*entry.code); @@ -421,49 +392,20 @@ expr_t::ptr_op_t entry_t::lookup(const string& name) case 'c': if (name == "code") return WRAP_FUNCTOR(get_wrapper<&get_code>); - else if (name == "cleared") - return WRAP_FUNCTOR(get_wrapper<&get_cleared>); - break; - - case 'd': - if (name[1] == '\0' || name == "date") - return WRAP_FUNCTOR(get_wrapper<&get_date>); break; case 'p': if (name[1] == '\0' || name == "payee") return WRAP_FUNCTOR(get_wrapper<&get_payee>); - else if (name == "pending") - return WRAP_FUNCTOR(get_wrapper<&get_pending>); - break; - - case 'u': - if (name == "uncleared") - return expr_t::op_t::wrap_value(1L); - break; - - case 'X': - if (name[1] == '\0') - return WRAP_FUNCTOR(get_wrapper<&get_cleared>); - break; - - case 'Y': - if (name[1] == '\0') - return WRAP_FUNCTOR(get_wrapper<&get_pending>); break; } - if (journal) { - assert(journal->owner == session_t::current); - return journal->owner->current_report->lookup(name); - } else { - return session_t::current->current_report->lookup(name); - } + return item_t::lookup(name); } bool entry_t::valid() const { - if (! is_valid(_date) || ! journal) { + if (! _date || ! journal) { DEBUG("ledger.validate", "entry_t: ! _date || ! journal"); return false; } @@ -514,19 +456,11 @@ void auto_entry_t::extend_entry(entry_base_t& entry, bool post) if (fullname == "$account" || fullname == "@account") account = initial_xact->account; - xact_t * new_xact - = new xact_t(account, amt, xact->flags() | XACT_AUTO); - // Copy over details so that the resulting xact is a mirror of // the automated entry's one. - new_xact->state = xact->state; - new_xact->_date = xact->_date; - new_xact->_date_eff = xact->_date_eff; - new_xact->note = xact->note; - new_xact->beg_pos = xact->beg_pos; - new_xact->beg_line = xact->beg_line; - new_xact->end_pos = xact->end_pos; - new_xact->end_line = xact->end_line; + xact_t * new_xact = new xact_t(account, amt); + new_xact->copy_details(*xact); + new_xact->add_flags(XACT_AUTO); entry.add_xact(new_xact); } diff --git a/src/entry.h b/src/entry.h index 2834942f..7d6623ae 100644 --- a/src/entry.h +++ b/src/entry.h @@ -39,35 +39,20 @@ namespace ledger { class journal_t; -class entry_base_t : public supports_flags<> +class entry_base_t : public item_t { public: -#define ENTRY_IN_CACHE 0x1 - - journal_t * journal; - string note; - unsigned long src_idx; - istream_pos_type beg_pos; - unsigned long beg_line; - istream_pos_type end_pos; - unsigned long end_line; - xacts_list xacts; - - entry_base_t() : journal(NULL), - beg_pos(0), beg_line(0), end_pos(0), end_line(0) - { + journal_t * journal; + xacts_list xacts; + + entry_base_t() : journal(NULL) { TRACE_CTOR(entry_base_t, ""); } entry_base_t(const entry_base_t& e); virtual ~entry_base_t(); - bool operator==(const entry_base_t& entry) { - return this == &entry; - } - bool operator!=(const entry_base_t& entry) { - return ! (*this == entry); - } + virtual state_t state() const; virtual void add_xact(xact_t * xact); virtual bool remove_xact(xact_t * xact); @@ -76,11 +61,9 @@ public: virtual bool valid() const = 0; }; -class entry_t : public entry_base_t, public scope_t +class entry_t : public entry_base_t { public: - date_t _date; - optional<date_t> _date_eff; optional<string> code; string payee; @@ -93,23 +76,6 @@ public: TRACE_DTOR(entry_t); } - date_t actual_date() const { - return _date; - } - date_t effective_date() const { - if (! _date_eff) - return _date; - return *_date_eff; - } - date_t date() const { - if (xact_t::use_effective_date) - return effective_date(); - else - return actual_date(); - } - - bool get_state(xact_t::state_t * state) const; - virtual void add_xact(xact_t * xact); virtual expr_t::ptr_op_t lookup(const string& name); diff --git a/src/filters.cc b/src/filters.cc index 9b5aded4..0205f68c 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -180,7 +180,7 @@ void handle_value(const value_t& value, temps.push_back(xact_t(account)); xact_t& xact(temps.back()); xact.entry = entry; - xact.add_flags(XACT_TEMP); + xact.add_flags(ITEM_TEMP); entry->add_xact(&xact); // If there are component xacts to associate with this @@ -390,9 +390,9 @@ void subtotal_xacts::report_subtotal(const char * spec_fmt) void subtotal_xacts::operator()(xact_t& xact) { if (! is_valid(start) || xact.date() < start) - start = xact.date(); + start = *xact.date(); if (! is_valid(finish) || xact.date() > finish) - finish = xact.date(); + finish = *xact.date(); account_t * acct = xact.reported_account(); assert(acct); @@ -432,7 +432,7 @@ void interval_xacts::report_subtotal(const date_t& date) if (is_valid(date)) finish = date - gregorian::days(1); else - finish = last_xact->date(); + finish = *last_xact->date(); subtotal_xacts::report_subtotal(); @@ -441,7 +441,7 @@ void interval_xacts::report_subtotal(const date_t& date) void interval_xacts::operator()(xact_t& xact) { - const date_t& date(xact.date()); + const date_t& date(*xact.date()); if ((is_valid(interval.begin) && date < interval.begin) || (is_valid(interval.end) && date >= interval.end)) @@ -512,7 +512,7 @@ void by_payee_xacts::operator()(xact_t& xact) } if (xact.date() > (*i).second->start) - (*i).second->start = xact.date(); + (*i).second->start = *xact.date(); (*(*i).second)(xact); } @@ -532,8 +532,8 @@ void set_comm_as_payee::operator()(xact_t& xact) xact_temps.push_back(xact); xact_t& temp = xact_temps.back(); temp.entry = &entry; - temp.state = xact.state; - temp.add_flags(XACT_TEMP); + temp.set_state(xact.state()); + temp.add_flags(ITEM_TEMP); entry.add_xact(&temp); @@ -554,8 +554,8 @@ void set_code_as_payee::operator()(xact_t& xact) xact_temps.push_back(xact); xact_t& temp = xact_temps.back(); temp.entry = &entry; - temp.state = xact.state; - temp.add_flags(XACT_TEMP); + temp.set_state(xact.state()); + temp.add_flags(ITEM_TEMP); entry.add_xact(&temp); @@ -619,7 +619,7 @@ void budget_xacts::report_budget_items(const date_t& date) xact_temps.push_back(xact); xact_t& temp = xact_temps.back(); temp.entry = &entry; - temp.add_flags(XACT_AUTO | XACT_TEMP); + temp.add_flags(XACT_AUTO | ITEM_TEMP); temp.amount.negate(); entry.add_xact(&temp); @@ -653,7 +653,7 @@ void budget_xacts::operator()(xact_t& xact) handle: if (xact_in_budget && flags & BUDGET_BUDGETED) { - report_budget_items(xact.date()); + report_budget_items(*xact.date()); item_handler<xact_t>::operator()(xact); } else if (! xact_in_budget && flags & BUDGET_UNBUDGETED) { @@ -706,7 +706,7 @@ void forecast_xacts::flush() xact_temps.push_back(xact); xact_t& temp = xact_temps.back(); temp.entry = &entry; - temp.add_flags(XACT_AUTO | XACT_TEMP); + temp.add_flags(XACT_AUTO | ITEM_TEMP); entry.add_xact(&temp); date_t next = (*least).first.increment(begin); @@ -720,7 +720,7 @@ void forecast_xacts::flush() temp.xdata().has_flags(XACT_EXT_MATCHES)) { if (! pred(temp)) break; - last = temp.date(); + last = *temp.date(); passed.clear(); } else { bool found = false; diff --git a/src/filters.h b/src/filters.h index 31c89b48..59c8f52c 100644 --- a/src/filters.h +++ b/src/filters.h @@ -290,7 +290,7 @@ public: collapse_xacts(xact_handler_ptr handler, session_t& session) : item_handler<xact_t>(handler), count(0), last_entry(NULL), last_xact(NULL), - totals_account(&session, NULL, "<Total>") { + totals_account(NULL, "<Total>") { TRACE_CTOR(collapse_xacts, "xact_handler_ptr"); } virtual ~collapse_xacts() { @@ -588,7 +588,7 @@ public: virtual void flush(); virtual void operator()(xact_t& xact) { - days_of_the_week[xact.date().day_of_week()].push_back(&xact); + days_of_the_week[xact.date()->day_of_week()].push_back(&xact); } }; diff --git a/src/gnucash.cc b/src/gnucash.cc index 6b9b5211..e2ee113a 100644 --- a/src/gnucash.cc +++ b/src/gnucash.cc @@ -89,7 +89,7 @@ static enum action_t { static void startElement(void *, const char *name, const char **) { if (std::strcmp(name, "gnc:account") == 0) { - curr_account = new account_t(master_account->owner, master_account); + curr_account = new account_t(master_account); } else if (std::strcmp(name, "act:name") == 0) action = ACCOUNT_NAME; @@ -193,7 +193,7 @@ static void endElement(void *, const char *name) value = curr_quant; } - xact->state = curr_state; + xact->set_state(curr_state); xact->amount = value; if (value != curr_value) xact->cost = curr_value; diff --git a/src/item.cc b/src/item.cc new file mode 100644 index 00000000..c6f77987 --- /dev/null +++ b/src/item.cc @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2003-2008, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "item.h" +#include "session.h" +#include "report.h" + +namespace ledger { + +bool item_t::use_effective_date = false; + +namespace { + value_t get_status(item_t& item) { + return long(item.state()); + } + value_t get_cleared(item_t& item) { + return item.state() == item_t::CLEARED; + } + value_t get_pending(item_t& item) { + return item.state() == item_t::PENDING; + } + + value_t get_date(item_t& item) { + if (optional<date_t> date = item.date()) + return *date; + else + return 0L; + } + + value_t get_note(item_t& item) { + return string_value(item.note ? *item.note : empty_string); + } + + value_t get_beg_pos(item_t& item) { + return long(item.beg_pos); + } + + value_t get_beg_line(item_t& item) { + return long(item.beg_line); + } + + value_t get_end_pos(item_t& item) { + return long(item.end_pos); + } + + value_t get_end_line(item_t& item) { + return long(item.end_line); + } + + template <value_t (*Func)(item_t&)> + value_t get_wrapper(call_scope_t& scope) { + return (*Func)(find_scope<item_t>(scope)); + } +} + +expr_t::ptr_op_t item_t::lookup(const string& name) +{ + switch (name[0]) { + case 'c': + if (name == "cleared") + return WRAP_FUNCTOR(get_wrapper<&get_cleared>); + break; + + case 'd': + if (name[1] == '\0' || name == "date") + return WRAP_FUNCTOR(get_wrapper<&get_date>); + break; + + case 'n': + if (name == "note") + return WRAP_FUNCTOR(get_wrapper<&get_note>); + break; + + case 'p': + if (name == "pending") + return WRAP_FUNCTOR(get_wrapper<&get_pending>); + break; + + case 's': + if (name == "status") + return WRAP_FUNCTOR(get_wrapper<&get_status>); + break; + + case 'u': + if (name == "uncleared") + return expr_t::op_t::wrap_value(1L); + break; + + case 'X': + if (name[1] == '\0') + return WRAP_FUNCTOR(get_wrapper<&get_cleared>); + break; + + case 'Y': + if (name[1] == '\0') + return WRAP_FUNCTOR(get_wrapper<&get_pending>); + break; + } + + return session_t::current->current_report->lookup(name); +} + +bool item_t::valid() const +{ + if (_state != UNCLEARED && _state != CLEARED && _state != PENDING) { + DEBUG("ledger.validate", "item_t: state is bad"); + return false; + } + + return true; +} + +} // namespace ledger diff --git a/src/item.h b/src/item.h new file mode 100644 index 00000000..74edf563 --- /dev/null +++ b/src/item.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2003-2008, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ITEM_H +#define _ITEM_H + +#include "utils.h" +#include "scope.h" + +namespace ledger { + +class entry_t; +class account_t; + +class item_t; +typedef std::list<item_t *> items_list; + +class item_t : public supports_flags<>, public scope_t +{ +public: +#define ITEM_NORMAL 0x0000 // no flags at all, a basic transaction +#define ITEM_IN_CACHE 0x0001 // transaction allocated by the binary cache +#define ITEM_GENERATED 0x0002 // transaction was not found in a journal +#define ITEM_TEMP 0x0004 // transaction is a temporary object + + enum state_t { UNCLEARED = 0, CLEARED, PENDING }; + + state_t _state; + + optional<date_t> _date; + optional<date_t> _date_eff; + optional<string> note; + + unsigned short src_idx; + istream_pos_type beg_pos; + unsigned long beg_line; + istream_pos_type end_pos; + unsigned long end_line; + + static bool use_effective_date; + + item_t(flags_t _flags = ITEM_NORMAL, const optional<string>& _note = none) + : supports_flags<>(_flags), _state(UNCLEARED), note(_note), + beg_pos(0), beg_line(0), end_pos(0), end_line(0) + { + TRACE_CTOR(item_t, "flags_t, const string&"); + } + item_t(const item_t& item) : supports_flags<>(), scope_t() + { + TRACE_CTOR(item_t, "copy"); + copy_details(item); + } + virtual ~item_t() { + TRACE_DTOR(item_t); + } + + void copy_details(const item_t& item) + { + set_flags(item.flags()); + set_state(item.state()); + + _date = item._date; + _date_eff = item._date_eff; + + note = item.note; + + beg_pos = item.beg_pos; + beg_line = item.beg_line; + end_pos = item.end_pos; + end_line = item.end_line; + } + + virtual bool operator==(const item_t& entry) { + return this == &entry; + } + virtual bool operator!=(const item_t& entry) { + return ! (*this == entry); + } + + virtual optional<date_t> actual_date() const { + return _date; + } + virtual optional<date_t> effective_date() const { + return _date_eff; + } + optional<date_t> date() const { + if (use_effective_date && _date_eff) + return effective_date(); + else + return actual_date(); + } + + void set_state(state_t new_state) { + _state = new_state; + } + virtual state_t state() const { + return _state; + } + + virtual expr_t::ptr_op_t lookup(const string& name); + + bool valid() const; +}; + +} // namespace ledger + +#endif // _ITEM_H diff --git a/src/journal.cc b/src/journal.cc index 7d95d72f..c5a9e9fc 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -36,11 +36,10 @@ namespace ledger { const string version = PACKAGE_VERSION; -journal_t::journal_t(session_t * _owner) - : owner(_owner), basket(NULL) +journal_t::journal_t() : basket(NULL) { TRACE_CTOR(journal_t, ""); - master = owner->master.get(); + master = session_t::current->master.get(); } journal_t::~journal_t() @@ -51,19 +50,19 @@ journal_t::~journal_t() // accounts they refer to, because all accounts are about to // be deleted. foreach (entry_t * entry, entries) - if (! entry->has_flags(ENTRY_IN_CACHE)) + if (! entry->has_flags(ITEM_IN_CACHE)) checked_delete(entry); else entry->~entry_t(); foreach (auto_entry_t * entry, auto_entries) - if (! entry->has_flags(ENTRY_IN_CACHE)) + if (! entry->has_flags(ITEM_IN_CACHE)) checked_delete(entry); else entry->~auto_entry_t(); foreach (period_entry_t * entry, period_entries) - if (! entry->has_flags(ENTRY_IN_CACHE)) + if (! entry->has_flags(ITEM_IN_CACHE)) checked_delete(entry); else entry->~period_entry_t(); @@ -71,22 +70,22 @@ journal_t::~journal_t() void journal_t::add_account(account_t * acct) { - owner->add_account(acct); + session_t::current->add_account(acct); } bool journal_t::remove_account(account_t * acct) { - return owner->remove_account(acct); + return session_t::current->remove_account(acct); } account_t * journal_t::find_account(const string& name, bool auto_create) { - return owner->find_account(name, auto_create); + return session_t::current->find_account(name, auto_create); } account_t * journal_t::find_account_re(const string& regexp) { - return owner->find_account_re(regexp); + return session_t::current->find_account_re(regexp); } bool journal_t::add_entry(entry_t * entry) @@ -105,7 +104,7 @@ bool journal_t::add_entry(entry_t * entry) foreach (const xact_t * xact, entry->xacts) if (xact->cost) { assert(xact->amount); - xact->amount.commodity().add_price(datetime_t(entry->date(), + xact->amount.commodity().add_price(datetime_t(*entry->date(), time_duration_t(0, 0, 0)), *xact->cost / xact->amount.number()); } diff --git a/src/journal.h b/src/journal.h index 293439bb..487b0841 100644 --- a/src/journal.h +++ b/src/journal.h @@ -46,7 +46,6 @@ class account_t; class journal_t : public noncopyable { public: - session_t * owner; account_t * master; account_t * basket; entries_list entries; @@ -58,11 +57,11 @@ public: hooks_t<entry_finalizer_t, entry_t> entry_finalize_hooks; - journal_t(session_t * _owner); + journal_t(); ~journal_t(); - // These four methods are delegated to 'owner', since all accounts processed - // are gathered together at the session level. + // These four methods are delegated to the current session, since all + // accounts processed are gathered together at the session level. void add_account(account_t * acct); bool remove_account(account_t * acct); account_t * find_account(const string& name, bool auto_create = true); @@ -61,8 +61,7 @@ int ofx_proc_account_cb(struct OfxAccountData data, void *) return -1; DEBUG("ledger.ofx.parse", "account " << data.account_name); - account_t * account = new account_t(master_account->owner, master_account, - data.account_name); + account_t * account = new account_t(master_account, data.account_name); curr_journal->add_account(account); ofx_accounts.insert(accounts_pair(data.account_id, account)); diff --git a/src/output.cc b/src/output.cc index 4ddcffb5..3db202cd 100644 --- a/src/output.cc +++ b/src/output.cc @@ -253,7 +253,7 @@ format_equity::format_equity(report_t& _report, const string& _format) void format_equity::flush() { - account_t summary(&report.session, NULL, "Equity:Opening Balances"); + account_t summary(NULL, "Equity:Opening Balances"); account_t::xdata_t& xdata(summary.xdata()); std::ostream& out(*report.output_stream); @@ -166,7 +166,7 @@ unsigned int qif_parser_t::parse(std::istream& in, c = in.peek(); if (c == '*' || c == 'X') { in.get(c); - xact->state = xact_t::CLEARED; + xact->set_state(item_t::CLEARED); } break; diff --git a/src/reconcile.cc b/src/reconcile.cc index aca1732e..0294d93e 100644 --- a/src/reconcile.cc +++ b/src/reconcile.cc @@ -72,12 +72,12 @@ void reconcile_xacts::flush() foreach (xact_t * xact, xacts) { if (! is_valid(cutoff) || xact->date() < cutoff) { - switch (xact->state) { - case xact_t::CLEARED: + switch (xact->state()) { + case item_t::CLEARED: cleared_balance += xact->amount; break; - case xact_t::UNCLEARED: - case xact_t::PENDING: + case item_t::UNCLEARED: + case item_t::PENDING: pending_balance += xact->amount; *last_ptr = xact; last_ptr = xact_next_ptr(xact); diff --git a/src/session.cc b/src/session.cc index 6bcca89a..be7256a5 100644 --- a/src/session.cc +++ b/src/session.cc @@ -113,7 +113,7 @@ session_t::session_t() ansi_codes(false), ansi_invert(false), - master(new account_t(this, NULL, "")) + master(new account_t(NULL, "")) { TRACE_CTOR(session_t, ""); } @@ -161,7 +161,7 @@ void session_t::read_init() ifstream init(*init_file); - journal_t temp(this); + journal_t temp; if (read_journal(temp, *init_file) > 0 || temp.auto_entries.size() > 0 || temp.period_entries.size() > 0) diff --git a/src/session.h b/src/session.h index a8c3fb4c..b45923d9 100644 --- a/src/session.h +++ b/src/session.h @@ -96,7 +96,7 @@ public: virtual ~session_t(); journal_t * create_journal() { - journal_t * journal = new journal_t(this); + journal_t * journal = new journal_t; journals.push_back(journal); return journal; } diff --git a/src/textual.cc b/src/textual.cc index e167467f..a0efd4ef 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -127,14 +127,14 @@ xact_t * parse_xact(char * line, account_t * account, entry_t * entry = NULL) char p = peek_next_nonws(in); switch (p) { case '*': - xact->state = xact_t::CLEARED; + xact->set_state(item_t::CLEARED); in.get(p); p = peek_next_nonws(in); DEBUG("ledger.textual.parse", "line " << linenum << ": " << "Parsed the CLEARED flag"); break; case '!': - xact->state = xact_t::PENDING; + xact->set_state(item_t::PENDING); in.get(p); p = peek_next_nonws(in); DEBUG("ledger.textual.parse", "line " << linenum << ": " << @@ -160,15 +160,17 @@ xact_t * parse_xact(char * line, account_t * account, entry_t * entry = NULL) char * b = &line[long(account_beg)]; char * e = &line[long(account_end)]; + if ((*b == '[' && *(e - 1) == ']') || (*b == '(' && *(e - 1) == ')')) { xact->add_flags(XACT_VIRTUAL); - DEBUG("ledger.textual.parse", "line " << linenum << ": " << - "Parsed a virtual account name"); + DEBUG("ledger.textual.parse", + "line " << linenum << ": " << "Parsed a virtual account name"); + if (*b == '[') { xact->add_flags(XACT_BALANCE); - DEBUG("ledger.textual.parse", "line " << linenum << ": " << - "Parsed a balanced virtual account name"); + DEBUG("ledger.textual.parse", + "line " << linenum << ": " << "Transaction must balance"); } b++; e--; } @@ -374,7 +376,7 @@ xact_t * parse_xact(char * line, account_t * account, entry_t * entry = NULL) diff -= xact->amount; if (! diff.is_zero()) { xact_t * temp = new xact_t(xact->account, diff, - XACT_GENERATED | XACT_CALCULATED); + ITEM_GENERATED | XACT_CALCULATED); entry->add_xact(temp); DEBUG("ledger.textual.parse", "line " << linenum << ": " << @@ -496,15 +498,15 @@ entry_t * parse_entry(std::istream& in, char * line, account_t * master, // Parse the optional cleared flag: * - xact_t::state_t state = xact_t::UNCLEARED; + item_t::state_t state = item_t::UNCLEARED; if (next) { switch (*next) { case '*': - state = xact_t::CLEARED; + state = item_t::CLEARED; next = skip_ws(++next); break; case '!': - state = xact_t::PENDING; + state = item_t::PENDING; next = skip_ws(++next); break; } @@ -556,14 +558,13 @@ entry_t * parse_entry(std::istream& in, char * line, account_t * master, } if (xact_t * xact = parse_xact(line, master, curr.get())) { - if (state != xact_t::UNCLEARED && - xact->state == xact_t::UNCLEARED) - xact->state = state; + xact->set_state(state); xact->beg_pos = beg_pos; xact->beg_line = beg_line; xact->end_pos = end_pos; xact->end_line = linenum; + pos = end_pos; curr->add_xact(xact); @@ -674,9 +675,8 @@ static void clock_out_from_timelog(std::list<time_entry_t>& time_entries, amt.parse(buf); assert(amt.valid()); - xact_t * xact - = new xact_t(event.account, amt, XACT_VIRTUAL); - xact->state = xact_t::CLEARED; + xact_t * xact = new xact_t(event.account, amt, XACT_VIRTUAL); + xact->set_state(item_t::CLEARED); curr->add_xact(xact); if (! journal.add_entry(curr.get())) diff --git a/src/xact.cc b/src/xact.cc index 556a0776..66c08f5b 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -36,48 +36,32 @@ namespace ledger { -bool xact_t::use_effective_date = false; - -xact_t::~xact_t() +optional<date_t> xact_t::actual_date() const { - TRACE_DTOR(xact_t); + optional<date_t> date = item_t::actual_date(); + if (! date && entry) + return entry->actual_date(); + return date; } -date_t xact_t::actual_date() const +optional<date_t> xact_t::effective_date() const { - if (! _date && entry) - return entry->actual_date(); - return *_date; + optional<date_t> date = item_t::effective_date(); + if (! date && entry) + return entry->effective_date(); + return date; } -date_t xact_t::effective_date() const +item_t::state_t xact_t::state() const { - if (! _date_eff && entry) - return entry->effective_date(); - return *_date_eff; + state_t entry_state = entry->state(); + if ((_state == UNCLEARED && entry_state != UNCLEARED) || + (_state == PENDING && entry_state == CLEARED)) + return entry_state; + return _state; } namespace { - 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 state_pending(call_scope_t&) { - return 2L; - } - - value_t get_date(xact_t& xact) { - return xact.date(); - } - value_t get_code(xact_t& xact) { if (xact.entry->code) return string_value(*xact.entry->code); @@ -85,22 +69,6 @@ namespace { return string_value(empty_string); } - value_t get_status(xact_t& xact) { - xact_t::state_t status; - xact.entry->get_state(&status); - return long(status); - } - value_t get_cleared(xact_t& xact) { - xact_t::state_t status; - xact.entry->get_state(&status); - return status == xact_t::CLEARED; - } - value_t get_pending(xact_t& xact) { - xact_t::state_t status; - xact.entry->get_state(&status); - return status == xact_t::PENDING; - } - value_t get_payee(xact_t& xact) { return string_value(xact.entry->payee); } @@ -125,10 +93,6 @@ namespace { return xact.cost ? *xact.cost : xact.amount; } - value_t get_note(xact_t& xact) { - return string_value(xact.note ? *xact.note : empty_string); - } - value_t get_account(call_scope_t& scope) { xact_t& xact(downcast<xact_t>(*scope.parent)); @@ -153,22 +117,6 @@ namespace { 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); - } - template <value_t (*Func)(xact_t&)> value_t get_wrapper(call_scope_t& scope) { return (*Func)(find_scope<xact_t>(scope)); @@ -188,68 +136,29 @@ expr_t::ptr_op_t xact_t::lookup(const string& name) break; case 'c': - if (name == "cleared") - return WRAP_FUNCTOR(get_wrapper<&get_cleared>); - else if (name == "code") + if (name == "code") return WRAP_FUNCTOR(get_wrapper<&get_code>); break; - case 'd': - if (name[1] == '\0' || name == "date") - return WRAP_FUNCTOR(get_wrapper<&get_date>); - break; - - case 'f': - if (name.find("fmt_") == 0) { - switch (name[4]) { - case 'A': - return WRAP_FUNCTOR(get_account); - case 'D': - return WRAP_FUNCTOR(get_wrapper<&get_date>); - case 'P': - return WRAP_FUNCTOR(get_wrapper<&get_payee>); - } - } - break; - - case 'n': - if (name == "note") - return WRAP_FUNCTOR(get_wrapper<&get_note>); - break; - case 'p': - if (name == "pending") - return WRAP_FUNCTOR(get_wrapper<&get_pending>); - else if (name == "payee") + if (name == "payee") return WRAP_FUNCTOR(get_wrapper<&get_payee>); break; - case 's': - if (name == "status") - return WRAP_FUNCTOR(get_wrapper<&get_status>); - break; - case 't': if (name[1] == '\0' || name == "total") return WRAP_FUNCTOR(get_wrapper<&get_total>); break; - - case 'u': - if (name == "uncleared") - return expr_t::op_t::wrap_value(1L); - break; - - case 'X': - if (name[1] == '\0') - return WRAP_FUNCTOR(get_wrapper<&get_cleared>); - break; - - case 'Y': - if (name[1] == '\0') - return WRAP_FUNCTOR(get_wrapper<&get_pending>); - break; } + +#if 0 + // jww (2008-09-19): I don't think we can lookup in entry, because + // that means the functor returned would be expecting an entry to be + // passed to it, rather than a transaction. return entry->lookup(name); +#else + return item_t::lookup(name); +#endif } bool xact_t::valid() const @@ -259,11 +168,6 @@ bool xact_t::valid() const return false; } - if (state != UNCLEARED && state != CLEARED && state != PENDING) { - DEBUG("ledger.validate", "xact_t: state is bad"); - return false; - } - xacts_list::const_iterator i = std::find(entry->xacts.begin(), entry->xacts.end(), this); @@ -287,11 +191,6 @@ bool xact_t::valid() const return false; } - if (flags() & ~0x003f) { - DEBUG("ledger.validate", "xact_t: flags are bad"); - return false; - } - return true; } @@ -32,8 +32,7 @@ #ifndef _XACT_H #define _XACT_H -#include "utils.h" -#include "scope.h" +#include "item.h" namespace ledger { @@ -43,90 +42,59 @@ class account_t; class xact_t; typedef std::list<xact_t *> xacts_list; -class xact_t : public supports_flags<>, public scope_t +class xact_t : public item_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] -#define XACT_AUTO 0x0004 // transaction created by automated entry -#define XACT_IN_CACHE 0x0008 // transaction allocated by the binary cache -#define XACT_CALCULATED 0x0010 // transaction's amount was auto-calculated -#define XACT_GENERATED 0x0020 // transaction was not found in a journal -#define XACT_TEMP 0x0040 // transaction is a temporary object - - enum state_t { UNCLEARED = 0, CLEARED, PENDING }; - - entry_t * entry; - account_t * account; - state_t state; +#define XACT_VIRTUAL 0x0100 // the account was specified with (parens) +#define XACT_BALANCE 0x0200 // the account was specified with [brackets] +#define XACT_AUTO 0x0400 // transaction created by automated entry +#define XACT_CALCULATED 0x0800 // transaction's amount was auto-calculated - optional<date_t> _date; - optional<date_t> _date_eff; - optional<string> note; + entry_t * entry; // only set for xacts of regular entries + account_t * account; - amount_t amount; + amount_t amount; // can be null until finalization optional<expr_t> amount_expr; optional<amount_t> cost; optional<expr_t> cost_expr; optional<amount_t> assigned_amount; optional<expr_t> assigned_amount_expr; - istream_pos_type beg_pos; - unsigned long beg_line; - istream_pos_type end_pos; - unsigned long end_line; - - static bool use_effective_date; - xact_t(account_t * _account = 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) + flags_t _flags = ITEM_NORMAL) + : item_t(_flags), + entry(NULL), account(_account) { TRACE_CTOR(xact_t, "account_t *, flags_t"); } - xact_t(account_t * _account, - const amount_t& _amount, - flags_t _flags = XACT_NORMAL, + xact_t(account_t * _account, + const amount_t& _amount, + flags_t _flags = ITEM_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) + : item_t(_flags, _note), + entry(NULL), account(_account), amount(_amount) { - TRACE_CTOR(xact_t, - "account_t *, const amount_t&, flags_t, const string&"); + TRACE_CTOR(xact_t, "account_t *, const amount_t&, flags_t, const optional<string>&"); } xact_t(const xact_t& xact) - : supports_flags<>(xact), - scope_t(), + : item_t(xact), entry(xact.entry), account(xact.account), - state(xact.state), - _date(xact._date), - _date_eff(xact._date_eff), - note(xact.note), amount(xact.amount), cost(xact.cost), - beg_pos(xact.beg_pos), - beg_line(xact.beg_line), - end_pos(xact.end_pos), - end_line(xact.end_line), xdata_(xact.xdata_) // jww (2008-07-19): What are the copy semantics? { TRACE_CTOR(xact_t, "copy"); } - ~xact_t(); - - date_t actual_date() const; - date_t effective_date() const; - date_t date() const { - if (use_effective_date) - return effective_date(); - else - return actual_date(); + ~xact_t() { + TRACE_DTOR(xact_t); } + virtual optional<date_t> actual_date() const; + virtual optional<date_t> effective_date() const; + + virtual state_t state() const; + bool must_balance() const { return ! has_flags(XACT_VIRTUAL) || has_flags(XACT_BALANCE); } @@ -221,8 +189,7 @@ public: date_t reported_date() const { if (xdata_ && is_valid(xdata_->date)) return xdata_->date; - return - date(); + return *date(); } account_t * reported_account() { @@ -235,6 +202,8 @@ public: const account_t * reported_account() const { return const_cast<xact_t *>(this)->reported_account(); } + + friend class entry_t; }; } // namespace ledger @@ -64,8 +64,8 @@ static void startElement(void *userData, const char *name, const char **attrs) else if (std::strcmp(name, "xact") == 0) { assert(curr_entry); curr_entry->add_xact(new xact_t); - if (curr_state != xact_t::UNCLEARED) - curr_entry->xacts.back()->state = curr_state; + if (curr_state != item_t::UNCLEARED) + curr_entry->xacts.back()->set_state(curr_state); } else if (std::strcmp(name, "commodity") == 0) { if (string(attrs[0]) == "flags") @@ -122,10 +122,10 @@ static void endElement(void *userData, const char *name) curr_entry->xacts.back()->account = curr_journal->find_account(data); } else if (std::strcmp(name, "tr:cleared") == 0) { - curr_entry->xacts.back()->state = xact_t::CLEARED; + curr_entry->xacts.back()->set_state(item_t::CLEARED); } else if (std::strcmp(name, "tr:pending") == 0) { - curr_entry->xacts.back()->state = xact_t::PENDING; + curr_entry->xacts.back()->set_state(item_t::PENDING); } else if (std::strcmp(name, "tr:virtual") == 0) { curr_entry->xacts.back()->add_flags(XACT_VIRTUAL); @@ -437,9 +437,9 @@ void format_xml_entries::format_last_entry() << "</tr:date_eff>\n"; #endif - if (xact->state == xact_t::CLEARED) + if (xact->state() == item_t::CLEARED) out << " <tr:cleared/>\n"; - else if (xact->state == xact_t::PENDING) + else if (xact->state() == xact_t::PENDING) out << " <tr:pending/>\n"; if (xact->has_flags(XACT_VIRTUAL)) |