diff options
author | John Wiegley <johnw@newartisans.com> | 2009-10-27 07:15:41 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-10-27 08:30:39 -0400 |
commit | 0fdb900c9975b97b43fe85c2691a9d5e69006fab (patch) | |
tree | 833ced95e5bd15a2bce802cd474f3c0fd93a88f7 /src | |
parent | f20b6a3b9edc2ace7b85eb4c961d57f69d98ea09 (diff) | |
download | fork-ledger-0fdb900c9975b97b43fe85c2691a9d5e69006fab.tar.gz fork-ledger-0fdb900c9975b97b43fe85c2691a9d5e69006fab.tar.bz2 fork-ledger-0fdb900c9975b97b43fe85c2691a9d5e69006fab.zip |
Redid the way temporaries are handled in filtering
Diffstat (limited to 'src')
-rw-r--r-- | src/account.cc | 35 | ||||
-rw-r--r-- | src/account.h | 35 | ||||
-rw-r--r-- | src/filters.cc | 111 | ||||
-rw-r--r-- | src/filters.h | 92 | ||||
-rw-r--r-- | src/output.cc | 6 | ||||
-rw-r--r-- | src/temps.cc | 124 | ||||
-rw-r--r-- | src/temps.h | 84 | ||||
-rw-r--r-- | src/textual.cc | 6 | ||||
-rw-r--r-- | src/xact.cc | 2 |
9 files changed, 323 insertions, 172 deletions
diff --git a/src/account.cc b/src/account.cc index c2628134..4301b5d5 100644 --- a/src/account.cc +++ b/src/account.cc @@ -110,6 +110,14 @@ account_t * account_t::find_account_re(const string& regexp) return find_account_re_(this, mask_t(regexp)); } +bool account_t::remove_post(post_t * post) +{ + assert(! posts.empty()); + posts.remove(post); + post->account = NULL; + return true; +} + string account_t::fullname() const { if (! _fullname.empty()) { @@ -140,7 +148,7 @@ string account_t::partial_name(bool flat) const if (! flat) { std::size_t count = acct->children_with_flags(ACCOUNT_EXT_TO_DISPLAY); assert(count > 0); - if (count > 1 || acct->has_flags(ACCOUNT_EXT_TO_DISPLAY)) + if (count > 1 || acct->has_xflags(ACCOUNT_EXT_TO_DISPLAY)) break; } pname = acct->name + ":" + pname; @@ -206,7 +214,7 @@ namespace { acct = acct->parent) { std::size_t count = acct->children_with_flags(ACCOUNT_EXT_TO_DISPLAY); assert(count > 0); - if (count > 1 || acct->has_flags(ACCOUNT_EXT_TO_DISPLAY)) + if (count > 1 || acct->has_xflags(ACCOUNT_EXT_TO_DISPLAY)) depth++; } @@ -310,7 +318,7 @@ std::size_t account_t::children_with_flags(xdata_t::flags_t flags) const bool grandchildren_visited = false; foreach (const accounts_map::value_type& pair, accounts) { - if (pair.second->has_flags(flags) || + if (pair.second->has_xflags(flags) || pair.second->children_with_flags(flags)) count++; } @@ -362,21 +370,22 @@ account_t::xdata_t::details_t::operator+=(const details_t& other) value_t account_t::self_total(const optional<expr_t&>& expr) const { if (xdata_ && xdata_->has_flags(ACCOUNT_EXT_VISITED)) { - if (! xdata_) xdata_ = xdata_t(); - - posts_deque::const_iterator i = - posts.begin() + xdata_->self_details.last_size; + posts_list::const_iterator i; + if (xdata_->self_details.last_post) + i = *xdata_->self_details.last_post; + else + i = posts.begin(); for (; i != posts.end(); i++) { - if ((*i)->xdata().has_flags(POST_EXT_VISITED) && - ! (*i)->xdata().has_flags(POST_EXT_CONSIDERED)) { - (*i)->add_to_value(xdata_->self_details.total, expr); - (*i)->xdata().add_flags(POST_EXT_CONSIDERED); + if ((*i)->xdata().has_flags(POST_EXT_VISITED)) { + if (! (*i)->xdata().has_flags(POST_EXT_CONSIDERED)) { + (*i)->add_to_value(xdata_->self_details.total, expr); + (*i)->xdata().add_flags(POST_EXT_CONSIDERED); + } } + xdata_->self_details.last_post = i; } - xdata_->self_details.last_size = posts.size(); - return xdata_->self_details.total; } else { return NULL_VALUE; diff --git a/src/account.h b/src/account.h index d860d955..428f6c63 100644 --- a/src/account.h +++ b/src/account.h @@ -55,7 +55,7 @@ class account_t; class xact_t; class post_t; -typedef std::deque<post_t *> posts_deque; +typedef std::list<post_t *> posts_list; typedef std::map<const string, account_t *> accounts_map; /** @@ -63,35 +63,37 @@ typedef std::map<const string, account_t *> accounts_map; * * Long. */ -class account_t : public scope_t +class account_t : public supports_flags<>, public scope_t { - public: +#define ACCOUNT_NORMAL 0x00 // no flags at all, a basic account +#define ACCOUNT_KNOWN 0x01 +#define ACCOUNT_TEMP 0x02 // account is a temporary object + +public: account_t * parent; string name; optional<string> note; unsigned short depth; accounts_map accounts; - posts_deque posts; - bool known; + posts_list posts; mutable string _fullname; account_t(account_t * _parent = NULL, const string& _name = "", const optional<string>& _note = none) - : scope_t(), parent(_parent), name(_name), note(_note), - depth(static_cast<unsigned short>(parent ? parent->depth + 1 : 0)), - known(false) { + : supports_flags<>(), scope_t(), parent(_parent), + name(_name), note(_note), + depth(static_cast<unsigned short>(parent ? parent->depth + 1 : 0)) { TRACE_CTOR(account_t, "account_t *, const string&, const string&"); } account_t(const account_t& other) - : scope_t(), + : supports_flags<>(other.flags()), scope_t(), parent(other.parent), name(other.name), note(other.note), depth(other.depth), - accounts(other.accounts), - known(other.known) { + accounts(other.accounts) { TRACE_CTOR(account_t, "copy"); } ~account_t(); @@ -116,6 +118,7 @@ class account_t : public scope_t void add_post(post_t * post) { posts.push_back(post); } + bool remove_post(post_t * post); virtual expr_t::ptr_op_t lookup(const string& name); @@ -152,12 +155,12 @@ class account_t : public scope_t date_t latest_post; date_t latest_cleared_post; - std::size_t last_size; - std::set<path> filenames; std::set<string> accounts_referenced; std::set<string> payees_referenced; + optional<posts_list::const_iterator> last_post; + details_t() : calculated(false), gathered(false), @@ -167,9 +170,7 @@ class account_t : public scope_t posts_cleared_count(0), posts_last_7_count(0), posts_last_30_count(0), - posts_this_month_count(0), - - last_size(0) {} + posts_this_month_count(0) {} details_t& operator+=(const details_t& other); @@ -227,7 +228,7 @@ class account_t : public scope_t const xdata_t::details_t& self_details(bool gather_all = true) const; const xdata_t::details_t& family_details(bool gather_all = true) const; - bool has_flags(xdata_t::flags_t flags) const { + bool has_xflags(xdata_t::flags_t flags) const { return xdata_ && xdata_->has_flags(flags); } std::size_t children_with_flags(xdata_t::flags_t flags) const; diff --git a/src/filters.cc b/src/filters.cc index 112e95ac..3667c213 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -140,11 +140,11 @@ void anonymize_posts::operator()(post_t& post) bool copy_xact_details = false; if (last_xact != post.xact) { - xact_temps.push_back(*post.xact); + temps.copy_xact(*post.xact); last_xact = post.xact; copy_xact_details = true; } - xact_t& xact = xact_temps.back(); + xact_t& xact = temps.last_xact(); if (copy_xact_details) { xact.copy_details(*post.xact); @@ -157,10 +157,6 @@ void anonymize_posts::operator()(post_t& post) xact.note = none; } - post_temps.push_back(post); - post_t& temp = post_temps.back(); - temp.xact = &xact; - std::list<string> account_names; account_t * new_account = NULL; @@ -183,14 +179,8 @@ void anonymize_posts::operator()(post_t& post) foreach (const string& name, account_names) new_account = new_account->find_account(name); - temp.copy_details(post); - - temp.account = new_account; - temp.note = none; - temp.add_flags(ITEM_TEMP); - - temp.account->add_post(&temp); - xact.add_post(&temp); + post_t& temp = temps.copy_post(post, xact, new_account); + temp.note = none; (*handler)(temp); } @@ -228,19 +218,14 @@ namespace { void handle_value(const value_t& value, account_t * account, xact_t * xact, - std::list<post_t>& temps, + temporaries_t& temps, item_handler<post_t>& handler, const date_t& date = date_t(), const value_t& total = value_t(), const bool direct_amount = false, const optional<post_functor_t>& functor = none) { - temps.push_back(post_t(account)); - post_t& post(temps.back()); - post.xact = xact; - post.add_flags(ITEM_TEMP); - post.account->add_post(&post); - xact->add_post(&post); + post_t& post = temps.create_post(*xact, account); // If the account for this post is all virtual, then report the post as // such. This allows subtotal reports to show "(Account)" for accounts @@ -327,14 +312,13 @@ void collapse_posts::report_subtotal() earliest_date = reported; } - xact_temps.push_back(xact_t()); - xact_t& xact = xact_temps.back(); + xact_t& xact = temps.create_xact(); xact.payee = last_xact->payee; xact._date = (is_valid(earliest_date) ? earliest_date : last_xact->_date); DEBUG("filter.collapse", "Pseudo-xact date = " << *xact._date); - handle_value(subtotal, &totals_account, &xact, post_temps, *handler); + handle_value(subtotal, &totals_account, &xact, temps, *handler); } component_posts.clear(); @@ -429,12 +413,11 @@ void changed_value_posts::output_revaluation(post_t * post, const date_t& date) DEBUG("filter.changed_value", "output_revaluation(strip(diff)) = " << diff.strip_annotations(report.what_to_keep())); - xact_temps.push_back(xact_t()); - xact_t& xact = xact_temps.back(); + xact_t& xact = temps.create_xact(); xact.payee = _("Commodities revalued"); xact._date = is_valid(date) ? date : post->date(); - handle_value(diff, &revalued_account, &xact, post_temps, *handler, + handle_value(diff, &revalued_account, &xact, temps, *handler, *xact._date, repriced_total, false, optional<post_functor_t> (bind(&changed_value_posts::output_rounding, this, _1))); @@ -467,13 +450,12 @@ void changed_value_posts::output_rounding(post_t * post) DEBUG("filter.changed_value.rounding", "rounding.diff = " << diff); - xact_temps.push_back(xact_t()); - xact_t& xact = xact_temps.back(); + xact_t& xact = temps.create_xact(); xact.payee = _("Commodity rounding"); xact._date = post->date(); - handle_value(diff, &rounding_account, &xact, post_temps, - *handler, *xact._date, precise_display_total, true); + handle_value(diff, &rounding_account, &xact, temps, *handler, + *xact._date, precise_display_total, true); } } } @@ -528,13 +510,12 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, out_date << "- " << format_date(*range_finish); } - xact_temps.push_back(xact_t()); - xact_t& xact = xact_temps.back(); + xact_t& xact = temps.create_xact(); xact.payee = out_date.str(); xact._date = *range_start; foreach (values_map::value_type& pair, values) - handle_value(pair.second.value, pair.second.account, &xact, post_temps, + handle_value(pair.second.value, pair.second.account, &xact, temps, *handler); values.clear(); @@ -598,16 +579,12 @@ void interval_posts::operator()(post_t& post) // Generate a null posting, so the intervening periods can be // seen when -E is used, or if the calculated amount ends up being // non-zero - xact_temps.push_back(xact_t()); - xact_t& null_xact = xact_temps.back(); - null_xact.add_flags(ITEM_TEMP); + xact_t& null_xact = temps.create_xact(); null_xact._date = last_interval.inclusive_end(); - post_temps.push_back(post_t(&empty_account)); - post_t& null_post = post_temps.back(); - null_post.add_flags(ITEM_TEMP | POST_CALCULATED); + post_t& null_post = temps.create_post(null_xact, &empty_account); + null_post.add_flags(POST_CALCULATED); null_post.amount = 0L; - null_xact.add_post(&null_post); last_post = &null_post; subtotal_posts::operator()(null_post); @@ -639,14 +616,13 @@ void posts_as_equity::report_subtotal() } component_posts.clear(); - xact_temps.push_back(xact_t()); - xact_t& xact = xact_temps.back(); + xact_t& xact = temps.create_xact(); xact.payee = _("Opening Balances"); xact._date = finish; value_t total = 0L; foreach (values_map::value_type& pair, values) { - handle_value(pair.second.value, pair.second.account, &xact, post_temps, + handle_value(pair.second.value, pair.second.account, &xact, temps, *handler); total += pair.second.value; } @@ -655,21 +631,13 @@ void posts_as_equity::report_subtotal() if (total.is_balance()) { foreach (balance_t::amounts_map::value_type pair, total.as_balance().amounts) { - post_temps.push_back(post_t(balance_account)); - post_t& balance_post = post_temps.back(); - balance_post.add_flags(ITEM_TEMP); + post_t& balance_post = temps.create_post(xact, balance_account); balance_post.amount = - pair.second; - balance_post.account->add_post(&balance_post); - xact.add_post(&balance_post); (*handler)(balance_post); } } else { - post_temps.push_back(post_t(balance_account)); - post_t& balance_post = post_temps.back(); - balance_post.add_flags(ITEM_TEMP); + post_t& balance_post = temps.create_post(xact, balance_account); balance_post.amount = - total.to_amount(); - balance_post.account->add_post(&balance_post); - xact.add_post(&balance_post); (*handler)(balance_post); } } @@ -705,17 +673,11 @@ void by_payee_posts::operator()(post_t& post) void transfer_details::operator()(post_t& post) { - xact_temps.push_back(*post.xact); - xact_t& xact = xact_temps.back(); + xact_t& xact = temps.copy_xact(*post.xact); xact._date = post.date(); - post_temps.push_back(post); - post_t& temp = post_temps.back(); - temp.xact = &xact; + post_t& temp = temps.copy_post(post, xact); temp.set_state(post.state()); - temp.add_flags(ITEM_TEMP); - temp.account->add_post(&temp); - xact.add_post(&temp); bind_scope_t bound_scope(scope, temp); @@ -725,6 +687,7 @@ void transfer_details::operator()(post_t& post) break; case SET_ACCOUNT: temp.account = master->find_account(expr.calc(bound_scope).to_string()); + temp.account->add_post(&temp); break; default: assert(false); @@ -782,18 +745,12 @@ void budget_posts::report_budget_items(const date_t& date) DEBUG("ledger.walk.budget", "Reporting budget for " << post.reported_account()->fullname()); - xact_temps.push_back(xact_t()); - xact_t& xact = xact_temps.back(); + xact_t& xact = temps.create_xact(); xact.payee = _("Budget transaction"); xact._date = begin; - post_temps.push_back(post); - post_t& temp = post_temps.back(); - temp.xact = &xact; - temp.add_flags(ITEM_TEMP); + post_t& temp = temps.copy_post(post, xact); temp.amount.in_place_negate(); - temp.account->add_post(&temp); - xact.add_post(&temp); ++pair.first; begin = *pair.first.start; @@ -816,8 +773,8 @@ void budget_posts::operator()(post_t& post) acct = acct->parent) { if (acct == (*pair.second).reported_account()) { post_in_budget = true; - // Report the post as if it had occurred in the parent - // account. + // Report the post as if it had occurred in the parent account. + // jww (2009-10-27): What about calling add_post here? if (post.reported_account() != acct) post.xdata().account = acct; goto handle; @@ -873,17 +830,11 @@ void forecast_posts::flush() post_t& post = *(*least).second; - xact_temps.push_back(xact_t()); - xact_t& xact = xact_temps.back(); + xact_t& xact = temps.create_xact(); xact.payee = _("Forecast transaction"); xact._date = begin; - post_temps.push_back(post); - post_t& temp = post_temps.back(); - temp.xact = &xact; - temp.add_flags(ITEM_TEMP); - temp.account->add_post(&temp); - xact.add_post(&temp); + post_t& temp = temps.copy_post(post, xact); date_t next = *(*least).first.next; ++(*least).first; diff --git a/src/filters.h b/src/filters.h index a03d3160..23a06482 100644 --- a/src/filters.h +++ b/src/filters.h @@ -50,6 +50,7 @@ #include "xact.h" #include "post.h" #include "account.h" +#include "temps.h" namespace ledger { @@ -279,11 +280,6 @@ public: } }; -inline void clear_xacts_posts(std::list<xact_t>& xacts_list) { - foreach (xact_t& xact, xacts_list) - xact.posts.clear(); -} - /** * @brief Brief * @@ -291,8 +287,7 @@ inline void clear_xacts_posts(std::list<xact_t>& xacts_list) { */ class anonymize_posts : public item_handler<post_t> { - std::list<xact_t> xact_temps; - std::list<post_t> post_temps; + temporaries_t temps; xact_t * last_xact; @@ -305,7 +300,6 @@ public: } virtual ~anonymize_posts() { TRACE_DTOR(anonymize_posts); - clear_xacts_posts(xact_temps); } virtual void operator()(post_t& post); @@ -346,18 +340,16 @@ public: */ class collapse_posts : public item_handler<post_t> { - expr_t& amount_expr; - item_predicate display_predicate; - item_predicate only_predicate; - value_t subtotal; - std::size_t count; - xact_t * last_xact; - post_t * last_post; - account_t totals_account; - bool only_collapse_if_zero; - - std::list<xact_t> xact_temps; - std::list<post_t> post_temps; + expr_t& amount_expr; + item_predicate display_predicate; + item_predicate only_predicate; + value_t subtotal; + std::size_t count; + xact_t * last_xact; + post_t * last_post; + temporaries_t temps; + account_t& totals_account; + bool only_collapse_if_zero; std::list<post_t *> component_posts; collapse_posts(); @@ -372,13 +364,12 @@ public: display_predicate(_display_predicate), only_predicate(_only_predicate), count(0), last_xact(NULL), last_post(NULL), - totals_account(NULL, _("<Total>")), + totals_account(temps.create_account(_("<Total>"))), only_collapse_if_zero(_only_collapse_if_zero) { TRACE_CTOR(collapse_posts, "post_handler_ptr"); } virtual ~collapse_posts() { TRACE_DTOR(collapse_posts); - clear_xacts_posts(xact_temps); } virtual void flush() { @@ -432,19 +423,17 @@ class changed_value_posts : public item_handler<post_t> // This filter requires that calc_posts be used at some point // later in the chain. - expr_t display_amount_expr; - expr_t total_expr; - expr_t display_total_expr; - report_t& report; - bool changed_values_only; - post_t * last_post; - value_t last_total; - value_t last_display_total; - account_t revalued_account; - account_t rounding_account; - - std::list<xact_t> xact_temps; - std::list<post_t> post_temps; + expr_t display_amount_expr; + expr_t total_expr; + expr_t display_total_expr; + report_t& report; + bool changed_values_only; + post_t * last_post; + value_t last_total; + value_t last_display_total; + temporaries_t temps; + account_t& revalued_account; + account_t& rounding_account; changed_value_posts(); @@ -459,14 +448,13 @@ public: display_amount_expr(_display_amount_expr), total_expr(_total_expr), display_total_expr(_display_total_expr), report(_report), changed_values_only(_changed_values_only), last_post(NULL), - revalued_account(NULL, _("<Revalued>")), - rounding_account(NULL, _("<Rounding>")){ + revalued_account(temps.create_account(_("<Revalued>"))), + rounding_account(temps.create_account(_("<Rounding>"))) { TRACE_CTOR(changed_value_posts, "post_handler_ptr, const expr_t&, const expr_t&, report_t&, bool"); } virtual ~changed_value_posts() { TRACE_DTOR(changed_value_posts); - clear_xacts_posts(xact_temps); } virtual void flush(); @@ -517,8 +505,7 @@ protected: expr_t& amount_expr; values_map values; optional<string> date_format; - std::list<xact_t> xact_temps; - std::list<post_t> post_temps; + temporaries_t temps; std::list<post_t *> component_posts; public: @@ -531,7 +518,6 @@ public: } virtual ~subtotal_posts() { TRACE_DTOR(subtotal_posts); - clear_xacts_posts(xact_temps); } void report_subtotal(const char * spec_fmt = NULL, @@ -555,7 +541,7 @@ class interval_posts : public subtotal_posts date_interval_t interval; date_interval_t last_interval; post_t * last_post; - account_t empty_account; + account_t& empty_account; bool exact_periods; bool generate_empty_posts; @@ -569,11 +555,11 @@ public: bool _exact_periods = false, bool _generate_empty_posts = false) : subtotal_posts(_handler, amount_expr), interval(_interval), - last_post(NULL), empty_account(NULL, _("<None>")), + last_post(NULL), empty_account(temps.create_account(_("<None>"))), exact_periods(_exact_periods), generate_empty_posts(_generate_empty_posts) { TRACE_CTOR(interval_posts, - "post_handler_ptr, expr_t&, interval_t, account_t *, bool, bool"); + "post_handler_ptr, expr_t&, date_interval_t, bool, bool"); } virtual ~interval_posts() throw() { TRACE_DTOR(interval_posts); @@ -594,7 +580,7 @@ public: class posts_as_equity : public subtotal_posts { post_t * last_post; - account_t equity_account; + account_t& equity_account; account_t * balance_account; posts_as_equity(); @@ -602,7 +588,7 @@ class posts_as_equity : public subtotal_posts public: posts_as_equity(post_handler_ptr _handler, expr_t& amount_expr) : subtotal_posts(_handler, amount_expr), - equity_account(NULL, _("Equity")) { + equity_account(temps.create_account(_("Equity"))) { TRACE_CTOR(posts_as_equity, "post_handler_ptr, expr_t&"); balance_account = equity_account.find_account(_("Opening Balances")); } @@ -653,11 +639,10 @@ class by_payee_posts : public item_handler<post_t> */ class transfer_details : public item_handler<post_t> { - std::list<xact_t> xact_temps; - std::list<post_t> post_temps; - account_t * master; - expr_t expr; - scope_t& scope; + account_t * master; + expr_t expr; + scope_t& scope; + temporaries_t temps; transfer_details(); @@ -679,7 +664,6 @@ public: } virtual ~transfer_details() { TRACE_DTOR(transfer_details); - clear_xacts_posts(xact_temps); } virtual void operator()(post_t& post); @@ -725,8 +709,7 @@ protected: typedef std::list<pending_posts_pair> pending_posts_list; pending_posts_list pending_posts; - std::list<xact_t> xact_temps; - std::list<post_t> post_temps; + temporaries_t temps; public: generate_posts(post_handler_ptr handler) @@ -736,7 +719,6 @@ public: virtual ~generate_posts() { TRACE_DTOR(generate_posts); - clear_xacts_posts(xact_temps); } void add_period_xacts(period_xacts_list& period_xacts); diff --git a/src/output.cc b/src/output.cc index a0c2581b..b1a8cb1b 100644 --- a/src/output.cc +++ b/src/output.cc @@ -169,7 +169,7 @@ format_accounts::mark_accounts(account_t& account, const bool flat) #if defined(DEBUG_ON) DEBUG("account.display", "Considering account: " << account.fullname()); - if (account.has_flags(ACCOUNT_EXT_VISITED)) + if (account.has_xflags(ACCOUNT_EXT_VISITED)) DEBUG("account.display", " it was visited itself"); DEBUG("account.display", " it has " << visited << " visited children"); DEBUG("account.display", @@ -177,11 +177,11 @@ format_accounts::mark_accounts(account_t& account, const bool flat) #endif if (account.parent && - (account.has_flags(ACCOUNT_EXT_VISITED) || (! flat && visited > 0))) { + (account.has_xflags(ACCOUNT_EXT_VISITED) || (! flat && visited > 0))) { bind_scope_t bound_scope(report, account); if ((! flat && to_display > 1) || ((flat || to_display != 1 || - account.has_flags(ACCOUNT_EXT_VISITED)) && + account.has_xflags(ACCOUNT_EXT_VISITED)) && disp_pred(bound_scope))) { account.xdata().add_flags(ACCOUNT_EXT_TO_DISPLAY); DEBUG("account.display", "Marking account as TO_DISPLAY"); diff --git a/src/temps.cc b/src/temps.cc new file mode 100644 index 00000000..a9ecc2a1 --- /dev/null +++ b/src/temps.cc @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2003-2009, 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 <system.hh> + +#include "temps.h" + +namespace ledger { + +temporaries_t::~temporaries_t() +{ + if (post_temps) { + foreach (post_t& post, *post_temps) { + if (! post.xact->has_flags(ITEM_TEMP)) + post.xact->remove_post(&post); + + if (! post.account->has_flags(ACCOUNT_TEMP)) + post.account->remove_post(&post); + } + } +} + +xact_t& temporaries_t::copy_xact(xact_t& origin) +{ + if (! xact_temps) + xact_temps = std::list<xact_t>(); + + xact_temps->push_back(origin); + xact_t& temp(xact_temps->back()); + + temp.add_flags(ITEM_TEMP); + return temp; +} + +xact_t& temporaries_t::create_xact() +{ + if (! xact_temps) + xact_temps = std::list<xact_t>(); + + xact_temps->push_back(xact_t()); + xact_t& temp(xact_temps->back()); + + temp.add_flags(ITEM_TEMP); + return temp; +} + +post_t& temporaries_t::copy_post(post_t& origin, xact_t& xact, + account_t * account) +{ + if (! post_temps) + post_temps = std::list<post_t>(); + + post_temps->push_back(origin); + post_t& temp(post_temps->back()); + + if (account) + temp.account = account; + temp.add_flags(ITEM_TEMP); + + temp.account->add_post(&temp); + xact.add_post(&temp); + + return temp; +} + +post_t& temporaries_t::create_post(xact_t& xact, account_t * account) +{ + if (! post_temps) + post_temps = std::list<post_t>(); + + post_temps->push_back(post_t(account)); + post_t& temp(post_temps->back()); + + temp.account = account; + temp.add_flags(ITEM_TEMP); + + temp.account->add_post(&temp); + xact.add_post(&temp); + + return temp; +} + +account_t& temporaries_t::create_account(const string& name, + account_t * parent) +{ + if (! acct_temps) + acct_temps = std::list<account_t>(); + + acct_temps->push_back(account_t(parent, name)); + account_t& temp(acct_temps->back()); + + temp.add_flags(ACCOUNT_TEMP); + return temp; +} + +} // namespace ledger diff --git a/src/temps.h b/src/temps.h new file mode 100644 index 00000000..acd9cbd7 --- /dev/null +++ b/src/temps.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2003-2009, 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. + */ + +/** + * @addtogroup report + */ + +/** + * @file temps.h + * @author John Wiegley + * + * @ingroup report + * + * @brief Brief + * + * Long. + */ +#ifndef _TEMPS_H +#define _TEMPS_H + +#include "xact.h" +#include "post.h" +#include "account.h" + +namespace ledger { + +class temporaries_t +{ + optional<std::list<xact_t> > xact_temps; + optional<std::list<post_t> > post_temps; + optional<std::list<account_t> > acct_temps; + +public: + ~temporaries_t(); + + xact_t& copy_xact(xact_t& origin); + xact_t& create_xact(); + xact_t& last_xact() { + return xact_temps->back(); + } + post_t& copy_post(post_t& origin, xact_t& xact, + account_t * account = NULL); + post_t& create_post(xact_t& xact, account_t * account); + post_t& last_post() { + return post_temps->back(); + } + account_t& create_account(const string& name, + account_t * parent = NULL); + account_t& last_account() { + return acct_temps->back(); + } +}; + +} // namespace ledger + +#endif // _TEMPS_H diff --git a/src/textual.cc b/src/textual.cc index 56c67ef3..09cd8360 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -446,7 +446,7 @@ void instance_t::default_commodity_directive(char * line) void instance_t::default_account_directive(char * line) { journal.basket = account_stack.front()->find_account(skip_ws(line + 1)); - journal.basket->known = true; + journal.basket->add_flags(ACCOUNT_KNOWN); } void instance_t::price_conversion_directive(char * line) @@ -845,11 +845,11 @@ post_t * instance_t::parse_post(char * line, if (! post->account) post->account = account->find_account(name); - if (honor_strict && strict && ! post->account->known) { + if (honor_strict && strict && ! post->account->has_flags(ACCOUNT_KNOWN)) { if (post->_state == item_t::UNCLEARED) warning_(_("\"%1\", line %2: Unknown account '%3'") << pathname << linenum << post->account->fullname()); - post->account->known = true; + post->account->add_flags(ACCOUNT_KNOWN); } // Parse the optional amount diff --git a/src/xact.cc b/src/xact.cc index 13faedba..f459b4a2 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -65,7 +65,7 @@ void xact_base_t::add_post(post_t * post) bool xact_base_t::remove_post(post_t * post) { posts.remove(post); - post->xact = NULL; + post->xact = NULL; return true; } |