From 15bf3ed39ed24bc55abc624757a1a943ebabb085 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 12 Jun 2010 21:31:55 -0400 Subject: account(NAME) function can lookup account objects For example, just the word "account" returns the name of the current posting's account, but account("Expenses:Food") returns the actual account object, so that it's total may be accessed. --- src/account.cc | 21 ++++++++++++++++++--- src/post.cc | 17 ++++++++++++++++- src/session.cc | 27 +++++++++++++++++++++++++-- src/session.h | 2 ++ 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/account.cc b/src/account.cc index 4170a4d2..710cabe1 100644 --- a/src/account.cc +++ b/src/account.cc @@ -182,8 +182,23 @@ namespace { env.get(0) : false)); } - value_t get_account(account_t& account) { // this gets the name - return string_value(account.fullname()); + value_t get_account(call_scope_t& scope) { // this gets the name + interactive_t args(scope, "&v"); + account_t& account(find_scope(scope)); + if (args.has(0)) { + account_t * acct = account.parent; + for (; acct && acct->parent; acct = acct->parent) ; + if (scope[0].is_string()) + return value_t(static_cast + (acct->find_account(args.get(0), false))); + else if (scope[0].is_mask()) + return value_t(static_cast + (acct->find_account_re(args.get(0).str()))); + else + return NULL_VALUE; + } else { + return string_value(account.fullname()); + } } value_t get_account_base(account_t& account) { @@ -301,7 +316,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") diff --git a/src/post.cc b/src/post.cc index fa8bab4f..dd489cba 100644 --- a/src/post.cc +++ b/src/post.cc @@ -318,7 +318,22 @@ namespace { value_t get_account(call_scope_t& scope) { - return account_name(scope); + interactive_t args(scope, "&v"); + account_t& account(*find_scope(scope).account); + if (args.has(0)) { + account_t * acct = account.parent; + for (; acct && acct->parent; acct = acct->parent) ; + if (scope[0].is_string()) + return value_t(static_cast + (acct->find_account(args.get(0), false))); + else if (scope[0].is_mask()) + return value_t(static_cast + (acct->find_account_re(args.get(0).str()))); + else + return NULL_VALUE; + } else { + return account_name(scope); + } } value_t get_account_id(post_t& post) { diff --git a/src/session.cc b/src/session.cc index 8adfef38..34cda5ef 100644 --- a/src/session.cc +++ b/src/session.cc @@ -182,6 +182,19 @@ void session_t::close_journal_files() amount_t::initialize(); } +value_t session_t::fn_account(call_scope_t& scope) +{ + interactive_t args(scope, "v"); + if (scope[0].is_string()) + return value_t(static_cast + (journal->find_account(args.get(0), false))); + else if (scope[0].is_mask()) + return value_t(static_cast + (journal->find_account_re(args.get(0).str()))); + else + return NULL_VALUE; +} + option_t * session_t::lookup_option(const char * p) { switch (*p) { @@ -224,15 +237,25 @@ option_t * session_t::lookup_option(const char * p) expr_t::ptr_op_t session_t::lookup(const symbol_t::kind_t kind, const string& name) { + const char * p = name.c_str(); + switch (kind) { case symbol_t::FUNCTION: + switch (*p) { + case 'a': + if (is_eq(p, "account")) + return MAKE_FUNCTOR(session_t::fn_account); + break; + default: + break; + } // Check if they are trying to access an option's setting or value. - if (option_t * handler = lookup_option(name.c_str())) + if (option_t * handler = lookup_option(p)) return MAKE_OPT_FUNCTOR(session_t, handler); break; case symbol_t::OPTION: - if (option_t * handler = lookup_option(name.c_str())) + if (option_t * handler = lookup_option(p)) return MAKE_OPT_HANDLER(session_t, handler); break; diff --git a/src/session.h b/src/session.h index 4968f1b8..5130e3fb 100644 --- a/src/session.h +++ b/src/session.h @@ -75,6 +75,8 @@ public: void read_journal_files(); void close_journal_files(); + value_t fn_account(call_scope_t& scope); + void report_options(std::ostream& out) { HANDLER(cache_).report(out); -- cgit v1.2.3