summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-02-15 23:00:16 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-02-15 23:00:16 -0400
commit8c2a70e1979377660ab0b88d0161b4b7f5be62f0 (patch)
treeb7e9a20e9802b90da1d674ee3d356ceb42ec2e84 /src
parent14ffc2b31a38a7fdd25bd93fe21d17132b16062a (diff)
downloadfork-ledger-8c2a70e1979377660ab0b88d0161b4b7f5be62f0.tar.gz
fork-ledger-8c2a70e1979377660ab0b88d0161b4b7f5be62f0.tar.bz2
fork-ledger-8c2a70e1979377660ab0b88d0161b4b7f5be62f0.zip
Made several of the filters more context aware
This resolves certain issues where value expressions were not being looked up within their full context.
Diffstat (limited to 'src')
-rw-r--r--src/chain.cc18
-rw-r--r--src/filters.cc21
-rw-r--r--src/filters.h27
-rw-r--r--src/report.cc33
-rw-r--r--src/report.h5
5 files changed, 65 insertions, 39 deletions
diff --git a/src/chain.cc b/src/chain.cc
index 62aac7b0..dae72db1 100644
--- a/src/chain.cc
+++ b/src/chain.cc
@@ -58,7 +58,8 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
if (report.HANDLED(display_))
handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(display_).str(),
- report.what_to_keep())));
+ report.what_to_keep()),
+ report));
// calc_xacts computes the running total. When this appears will
// determine, for example, whether filtered xacts are included or excluded
@@ -71,7 +72,8 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
if (report.HANDLED(only_))
handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(only_).str(),
- report.what_to_keep())));
+ report.what_to_keep()),
+ report));
// sort_xacts will sort all the xacts it sees, based on the `sort_order'
// value expression.
@@ -146,7 +148,8 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
"Report predicate expression = " << report.HANDLER(limit_).str());
handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(limit_).str(),
- report.what_to_keep())));
+ report.what_to_keep()),
+ report));
}
// budget_xacts takes a set of xacts from a data file and uses them to
@@ -169,13 +172,15 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
if (report.HANDLED(limit_))
handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(limit_).str(),
- report.what_to_keep())));
+ report.what_to_keep()),
+ report));
}
else if (report.HANDLED(forecast_)) {
forecast_xacts * forecast_handler
= new forecast_xacts(handler,
item_predicate(report.HANDLER(forecast_).str(),
- report.what_to_keep()));
+ report.what_to_keep()),
+ report);
forecast_handler->add_period_entries(report.session.journal->period_entries);
handler.reset(forecast_handler);
@@ -183,7 +188,8 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
if (report.HANDLED(limit_))
handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(limit_).str(),
- report.what_to_keep())));
+ report.what_to_keep()),
+ report));
}
if (report.HANDLED(comm_as_payee))
diff --git a/src/filters.cc b/src/filters.cc
index 118e8c5e..c3007f01 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -764,7 +764,8 @@ void forecast_xacts::flush()
if (temp.has_xdata() &&
temp.xdata().has_flags(XACT_EXT_MATCHES)) {
- if (! pred(temp))
+ bind_scope_t bound_scope(context, temp);
+ if (! pred(bound_scope))
break;
last = temp.date();
passed.clear();
@@ -789,15 +790,21 @@ void forecast_xacts::flush()
pass_down_accounts::pass_down_accounts(acct_handler_ptr handler,
accounts_iterator& iter,
- const optional<item_predicate>& predicate)
- : item_handler<account_t>(handler), pred(predicate)
+ const optional<item_predicate>& _pred,
+ const optional<scope_t&>& _context)
+ : item_handler<account_t>(handler), pred(_pred), context(_context)
{
- TRACE_CTOR(pass_down_accounts,
- "acct_handler_ptr, accounts_iterator");
+ TRACE_CTOR(pass_down_accounts, "acct_handler_ptr, accounts_iterator, ...");
- for (account_t * account = iter(); account; account = iter())
- if (! pred || (*pred)(*account))
+ for (account_t * account = iter(); account; account = iter()) {
+ if (! pred) {
item_handler<account_t>::operator()(*account);
+ } else {
+ bind_scope_t bound_scope(*context, *account);
+ if ((*pred)(bound_scope))
+ item_handler<account_t>::operator()(*account);
+ }
+ }
item_handler<account_t>::flush();
}
diff --git a/src/filters.h b/src/filters.h
index a16f5665..62a1a3dc 100644
--- a/src/filters.h
+++ b/src/filters.h
@@ -273,22 +273,25 @@ public:
class filter_xacts : public item_handler<xact_t>
{
item_predicate pred;
+ scope_t& context;
filter_xacts();
public:
filter_xacts(xact_handler_ptr handler,
- const item_predicate& predicate)
- : item_handler<xact_t>(handler), pred(predicate) {
+ const item_predicate& predicate,
+ scope_t& _context)
+ : item_handler<xact_t>(handler), pred(predicate), context(_context) {
TRACE_CTOR(filter_xacts,
- "xact_handler_ptr, const item_predicate<xact_t>&");
+ "xact_handler_ptr, const item_predicate&, scope_t&");
}
virtual ~filter_xacts() {
TRACE_DTOR(filter_xacts);
}
virtual void operator()(xact_t& xact) {
- if (pred(xact)) {
+ bind_scope_t bound_scope(context, xact);
+ if (pred(bound_scope)) {
xact.xdata().add_flags(XACT_EXT_MATCHES);
(*handler)(xact);
}
@@ -775,13 +778,15 @@ public:
class forecast_xacts : public generate_xacts
{
item_predicate pred;
+ scope_t& context;
public:
forecast_xacts(xact_handler_ptr handler,
- const item_predicate& predicate)
- : generate_xacts(handler), pred(predicate) {
+ const item_predicate& predicate,
+ scope_t& _context)
+ : generate_xacts(handler), pred(predicate), context(_context) {
TRACE_CTOR(forecast_xacts,
- "xact_handler_ptr, const item_predicate<xact_t>&");
+ "xact_handler_ptr, const item_predicate&, scope_t&");
}
virtual ~forecast_xacts() throw() {
TRACE_DTOR(forecast_xacts);
@@ -822,11 +827,13 @@ class pass_down_accounts : public item_handler<account_t>
pass_down_accounts();
optional<item_predicate> pred;
+ optional<scope_t&> context;
public:
- pass_down_accounts(acct_handler_ptr handler,
- accounts_iterator& iter,
- const optional<item_predicate>& predicate = none);
+ pass_down_accounts(acct_handler_ptr handler,
+ accounts_iterator& iter,
+ const optional<item_predicate>& _pred = none,
+ const optional<scope_t&>& _context = none);
virtual ~pass_down_accounts() {
TRACE_DTOR(pass_down_accounts);
diff --git a/src/report.cc b/src/report.cc
index 343f0110..837a1fb4 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -125,16 +125,21 @@ void report_t::accounts_report(acct_handler_ptr handler)
{
sum_all_accounts();
- if (! HANDLED(sort_)) {
- basic_accounts_iterator walker(*session.master);
- pass_down_accounts(handler, walker,
- item_predicate("total", what_to_keep()));
- } else {
- sorted_accounts_iterator walker(*session.master, HANDLER(sort_).str());
- pass_down_accounts(handler, walker,
- item_predicate("total", what_to_keep()));
- }
-
+ scoped_ptr<accounts_iterator> iter;
+
+ if (! HANDLED(sort_))
+ iter.reset(new basic_accounts_iterator(*session.master));
+ else
+ iter.reset(new sorted_accounts_iterator(*session.master,
+ HANDLER(sort_).str()));
+
+ if (HANDLED(display_))
+ pass_down_accounts(handler, *iter.get(),
+ item_predicate(HANDLER(display_).str(), what_to_keep()),
+ *this);
+ else
+ pass_down_accounts(handler, *iter.get());
+
session.clean_xacts();
session.clean_accounts();
}
@@ -266,13 +271,13 @@ namespace {
value_t operator()(call_scope_t& args)
{
- if (args.value().size() > 0)
+ if (args.value().size() > 0) {
report.HANDLER(limit_).append
(args_to_predicate_expr(args.value().as_sequence().begin(),
args.value().as_sequence().end()));
-
- DEBUG("report.predicate",
- "Predicate = " << report.HANDLER(limit_).str());
+ DEBUG("report.predicate",
+ "Predicate = " << report.HANDLER(limit_).str());
+ }
(report.*report_method)(handler_ptr(handler));
diff --git a/src/report.h b/src/report.h
index cb89f965..809d0f5b 100644
--- a/src/report.h
+++ b/src/report.h
@@ -250,8 +250,9 @@ public:
OPTION(report_t, code_as_payee);
OPTION_(report_t, collapse, DO() { // -n
- // Make sure that balance reports are collapsed too
- parent->HANDLER(display_).append("depth<=1");
+ // Make sure that balance reports are collapsed too, but only apply it
+ // to account entries
+ parent->HANDLER(display_).append("xact|depth<=1");
});
OPTION_(report_t, collapse_if_zero, DO() {