diff options
Diffstat (limited to 'src/account.cc')
-rw-r--r-- | src/account.cc | 149 |
1 files changed, 87 insertions, 62 deletions
diff --git a/src/account.cc b/src/account.cc index 37ff83f3..3e0ad086 100644 --- a/src/account.cc +++ b/src/account.cc @@ -34,7 +34,6 @@ #include "account.h" #include "post.h" #include "xact.h" -#include "interactive.h" namespace ledger { @@ -44,14 +43,14 @@ account_t::~account_t() foreach (accounts_map::value_type& pair, accounts) { if (! pair.second->has_flags(ACCOUNT_TEMP) || - has_flags(ACCOUNT_TEMP)) { + has_flags(ACCOUNT_TEMP)) { checked_delete(pair.second); } } } account_t * account_t::find_account(const string& name, - const bool auto_create) + const bool auto_create) { accounts_map::const_iterator i = accounts.find(name); if (i != accounts.end()) @@ -111,7 +110,7 @@ namespace { foreach (accounts_map::value_type& pair, account->accounts) if (account_t * a = find_account_re_(pair.second, regexp)) - return a; + return a; return NULL; } @@ -122,6 +121,20 @@ account_t * account_t::find_account_re(const string& regexp) return find_account_re_(this, mask_t(regexp)); } +void account_t::add_post(post_t * post) +{ + posts.push_back(post); + + // Adding a new post changes the possible totals that may have been + // computed before. + if (xdata_) { + xdata_->self_details.gathered = false; + xdata_->self_details.calculated = false; + xdata_->family_details.gathered = false; + xdata_->family_details.calculated = false; + } +} + bool account_t::remove_post(post_t * post) { assert(! posts.empty()); @@ -135,13 +148,13 @@ string account_t::fullname() const if (! _fullname.empty()) { return _fullname; } else { - const account_t * first = this; - string fullname = name; + const account_t * first = this; + string fullname = name; while (first->parent) { first = first->parent; if (! first->name.empty()) - fullname = first->name + ":" + fullname; + fullname = first->name + ":" + fullname; } _fullname = fullname; @@ -161,7 +174,7 @@ string account_t::partial_name(bool flat) const std::size_t count = acct->children_with_flags(ACCOUNT_EXT_TO_DISPLAY); assert(count > 0); if (count > 1 || acct->has_xflags(ACCOUNT_EXT_TO_DISPLAY)) - break; + break; } pname = acct->name + ":" + pname; } @@ -175,15 +188,31 @@ std::ostream& operator<<(std::ostream& out, const account_t& account) } namespace { - value_t get_partial_name(call_scope_t& scope) + value_t get_partial_name(call_scope_t& args) { - in_context_t<account_t> env(scope, "&b"); - return string_value(env->partial_name(env.has(0) ? - env.get<bool>(0) : false)); - } - - value_t get_account(account_t& account) { // this gets the name - return string_value(account.fullname()); + return string_value(args.context<account_t>() + .partial_name(args.has<bool>(0) && + args.get<bool>(0))); + } + + value_t get_account(call_scope_t& args) { // this gets the name + account_t& account(args.context<account_t>()); + if (args.has<string>(0)) { + account_t * acct = account.parent; + for (; acct && acct->parent; acct = acct->parent) ; + if (args[0].is_string()) + return scope_value(acct->find_account(args.get<string>(0), false)); + else if (args[0].is_mask()) + return scope_value(acct->find_account_re(args.get<mask_t>(0).str())); + else + return NULL_VALUE; + } + else if (args.type_context() == value_t::SCOPE) { + return scope_value(&account); + } + else { + return string_value(account.fullname()); + } } value_t get_account_base(account_t& account) { @@ -230,12 +259,12 @@ namespace { { std::size_t depth = 0; for (const account_t * acct = account.parent; - acct && acct->parent; - acct = acct->parent) { + acct && acct->parent; + acct = acct->parent) { std::size_t count = acct->children_with_flags(ACCOUNT_EXT_TO_DISPLAY); assert(count > 0); if (count > 1 || acct->has_xflags(ACCOUNT_EXT_TO_DISPLAY)) - depth++; + depth++; } std::ostringstream out; @@ -251,47 +280,43 @@ namespace { } template <value_t (*Func)(account_t&)> - value_t get_wrapper(call_scope_t& scope) { - return (*Func)(find_scope<account_t>(scope)); + value_t get_wrapper(call_scope_t& args) { + return (*Func)(args.context<account_t>()); } value_t get_parent(account_t& account) { - return value_t(static_cast<scope_t *>(account.parent)); + return scope_value(account.parent); } - value_t fn_any(call_scope_t& scope) + value_t fn_any(call_scope_t& args) { - interactive_t args(scope, "X&X"); - - account_t& account(find_scope<account_t>(scope)); - expr_t& expr(args.get<expr_t&>(0)); + account_t& account(args.context<account_t>()); + expr_t::ptr_op_t expr(args.get<expr_t::ptr_op_t>(0)); foreach (post_t * p, account.posts) { - bind_scope_t bound_scope(scope, *p); - if (expr.calc(bound_scope).to_boolean()) - return true; + bind_scope_t bound_scope(args, *p); + if (expr->calc(bound_scope, args.locus, args.depth).to_boolean()) + return true; } return false; } - value_t fn_all(call_scope_t& scope) + value_t fn_all(call_scope_t& args) { - interactive_t args(scope, "X&X"); - - account_t& account(find_scope<account_t>(scope)); - expr_t& expr(args.get<expr_t&>(0)); + account_t& account(args.context<account_t>()); + expr_t::ptr_op_t expr(args.get<expr_t::ptr_op_t>(0)); foreach (post_t * p, account.posts) { - bind_scope_t bound_scope(scope, *p); - if (! expr.calc(bound_scope).to_boolean()) - return false; + bind_scope_t bound_scope(args, *p); + if (! expr->calc(bound_scope, args.locus, args.depth).to_boolean()) + return false; } return true; } } expr_t::ptr_op_t account_t::lookup(const symbol_t::kind_t kind, - const string& name) + const string& name) { if (kind != symbol_t::FUNCTION) return NULL; @@ -301,7 +326,7 @@ expr_t::ptr_op_t account_t::lookup(const symbol_t::kind_t kind, if (name[1] == '\0' || name == "amount") return WRAP_FUNCTOR(get_wrapper<&get_amount>); else if (name == "account") - return WRAP_FUNCTOR(get_wrapper<&get_account>); + return WRAP_FUNCTOR(&get_account); else if (name == "account_base") return WRAP_FUNCTOR(get_wrapper<&get_account_base>); else if (name == "addr") @@ -407,7 +432,7 @@ bool account_t::children_with_xdata() const { foreach (const accounts_map::value_type& pair, accounts) if (pair.second->has_xdata() || - pair.second->children_with_xdata()) + pair.second->children_with_xdata()) return true; return false; @@ -420,7 +445,7 @@ std::size_t account_t::children_with_flags(xdata_t::flags_t flags) const foreach (const accounts_map::value_type& pair, accounts) if (pair.second->has_xflags(flags) || - pair.second->children_with_flags(flags)) + pair.second->children_with_flags(flags)) count++; // Although no immediately children were visited, if any progeny at all were @@ -434,11 +459,11 @@ std::size_t account_t::children_with_flags(xdata_t::flags_t flags) const account_t::xdata_t::details_t& account_t::xdata_t::details_t::operator+=(const details_t& other) { - posts_count += other.posts_count; - posts_virtuals_count += other.posts_virtuals_count; - posts_cleared_count += other.posts_cleared_count; - posts_last_7_count += other.posts_last_7_count; - posts_last_30_count += other.posts_last_30_count; + posts_count += other.posts_count; + posts_virtuals_count += other.posts_virtuals_count; + posts_cleared_count += other.posts_cleared_count; + posts_last_7_count += other.posts_last_7_count; + posts_last_30_count += other.posts_last_30_count; posts_this_month_count += other.posts_this_month_count; if (! is_valid(earliest_post) || @@ -461,9 +486,9 @@ account_t::xdata_t::details_t::operator+=(const details_t& other) filenames.insert(other.filenames.begin(), other.filenames.end()); accounts_referenced.insert(other.accounts_referenced.begin(), - other.accounts_referenced.end()); + other.accounts_referenced.end()); payees_referenced.insert(other.payees_referenced.begin(), - other.payees_referenced.end()); + other.payees_referenced.end()); return *this; } @@ -487,10 +512,10 @@ value_t account_t::amount(const optional<expr_t&>& expr) const for (; i != posts.end(); i++) { 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); - } + 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; } @@ -502,10 +527,10 @@ value_t account_t::amount(const optional<expr_t&>& expr) const for (; i != xdata_->reported_posts.end(); i++) { 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); - } + 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_reported_post = i; } @@ -525,7 +550,7 @@ value_t account_t::total(const optional<expr_t&>& expr) const foreach (const accounts_map::value_type& pair, accounts) { temp = pair.second->total(expr); if (! temp.is_null()) - add_or_set_value(xdata_->family_details.total, temp); + add_or_set_value(xdata_->family_details.total, temp); } temp = amount(expr); @@ -562,7 +587,7 @@ account_t::family_details(bool gather_all) const } void account_t::xdata_t::details_t::update(post_t& post, - bool gather_all) + bool gather_all) { posts_count++; @@ -592,16 +617,16 @@ void account_t::xdata_t::details_t::update(post_t& post, posts_cleared_count++; if (! is_valid(earliest_cleared_post) || - post.date() < earliest_cleared_post) + post.date() < earliest_cleared_post) earliest_cleared_post = post.date(); if (! is_valid(latest_cleared_post) || - post.date() > latest_cleared_post) + post.date() > latest_cleared_post) latest_cleared_post = post.date(); } if (gather_all) { accounts_referenced.insert(post.account->fullname()); - payees_referenced.insert(post.xact->payee); + payees_referenced.insert(post.payee()); } } |