Made several of the filters more context aware

This resolves certain issues where value expressions were not being
looked up within their full context.
This commit is contained in:
John Wiegley 2009-02-15 23:00:16 -04:00
parent 14ffc2b31a
commit 8c2a70e197
5 changed files with 65 additions and 39 deletions

View file

@ -58,7 +58,8 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
if (report.HANDLED(display_)) if (report.HANDLED(display_))
handler.reset(new filter_xacts handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(display_).str(), (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 // calc_xacts computes the running total. When this appears will
// determine, for example, whether filtered xacts are included or excluded // 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_)) if (report.HANDLED(only_))
handler.reset(new filter_xacts handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(only_).str(), (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' // sort_xacts will sort all the xacts it sees, based on the `sort_order'
// value expression. // value expression.
@ -146,7 +148,8 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
"Report predicate expression = " << report.HANDLER(limit_).str()); "Report predicate expression = " << report.HANDLER(limit_).str());
handler.reset(new filter_xacts handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(limit_).str(), (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 // 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_)) if (report.HANDLED(limit_))
handler.reset(new filter_xacts handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(limit_).str(), (handler, item_predicate(report.HANDLER(limit_).str(),
report.what_to_keep()))); report.what_to_keep()),
report));
} }
else if (report.HANDLED(forecast_)) { else if (report.HANDLED(forecast_)) {
forecast_xacts * forecast_handler forecast_xacts * forecast_handler
= new forecast_xacts(handler, = new forecast_xacts(handler,
item_predicate(report.HANDLER(forecast_).str(), 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); forecast_handler->add_period_entries(report.session.journal->period_entries);
handler.reset(forecast_handler); handler.reset(forecast_handler);
@ -183,7 +188,8 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
if (report.HANDLED(limit_)) if (report.HANDLED(limit_))
handler.reset(new filter_xacts handler.reset(new filter_xacts
(handler, item_predicate(report.HANDLER(limit_).str(), (handler, item_predicate(report.HANDLER(limit_).str(),
report.what_to_keep()))); report.what_to_keep()),
report));
} }
if (report.HANDLED(comm_as_payee)) if (report.HANDLED(comm_as_payee))

View file

@ -764,7 +764,8 @@ void forecast_xacts::flush()
if (temp.has_xdata() && if (temp.has_xdata() &&
temp.xdata().has_flags(XACT_EXT_MATCHES)) { temp.xdata().has_flags(XACT_EXT_MATCHES)) {
if (! pred(temp)) bind_scope_t bound_scope(context, temp);
if (! pred(bound_scope))
break; break;
last = temp.date(); last = temp.date();
passed.clear(); passed.clear();
@ -789,15 +790,21 @@ void forecast_xacts::flush()
pass_down_accounts::pass_down_accounts(acct_handler_ptr handler, pass_down_accounts::pass_down_accounts(acct_handler_ptr handler,
accounts_iterator& iter, accounts_iterator& iter,
const optional<item_predicate>& predicate) const optional<item_predicate>& _pred,
: item_handler<account_t>(handler), pred(predicate) const optional<scope_t&>& _context)
: item_handler<account_t>(handler), pred(_pred), context(_context)
{ {
TRACE_CTOR(pass_down_accounts, TRACE_CTOR(pass_down_accounts, "acct_handler_ptr, accounts_iterator, ...");
"acct_handler_ptr, accounts_iterator");
for (account_t * account = iter(); account; account = iter()) for (account_t * account = iter(); account; account = iter()) {
if (! pred || (*pred)(*account)) if (! pred) {
item_handler<account_t>::operator()(*account); 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(); item_handler<account_t>::flush();
} }

View file

@ -273,22 +273,25 @@ public:
class filter_xacts : public item_handler<xact_t> class filter_xacts : public item_handler<xact_t>
{ {
item_predicate pred; item_predicate pred;
scope_t& context;
filter_xacts(); filter_xacts();
public: public:
filter_xacts(xact_handler_ptr handler, filter_xacts(xact_handler_ptr handler,
const item_predicate& predicate) const item_predicate& predicate,
: item_handler<xact_t>(handler), pred(predicate) { scope_t& _context)
: item_handler<xact_t>(handler), pred(predicate), context(_context) {
TRACE_CTOR(filter_xacts, TRACE_CTOR(filter_xacts,
"xact_handler_ptr, const item_predicate<xact_t>&"); "xact_handler_ptr, const item_predicate&, scope_t&");
} }
virtual ~filter_xacts() { virtual ~filter_xacts() {
TRACE_DTOR(filter_xacts); TRACE_DTOR(filter_xacts);
} }
virtual void operator()(xact_t& xact) { 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); xact.xdata().add_flags(XACT_EXT_MATCHES);
(*handler)(xact); (*handler)(xact);
} }
@ -775,13 +778,15 @@ public:
class forecast_xacts : public generate_xacts class forecast_xacts : public generate_xacts
{ {
item_predicate pred; item_predicate pred;
scope_t& context;
public: public:
forecast_xacts(xact_handler_ptr handler, forecast_xacts(xact_handler_ptr handler,
const item_predicate& predicate) const item_predicate& predicate,
: generate_xacts(handler), pred(predicate) { scope_t& _context)
: generate_xacts(handler), pred(predicate), context(_context) {
TRACE_CTOR(forecast_xacts, TRACE_CTOR(forecast_xacts,
"xact_handler_ptr, const item_predicate<xact_t>&"); "xact_handler_ptr, const item_predicate&, scope_t&");
} }
virtual ~forecast_xacts() throw() { virtual ~forecast_xacts() throw() {
TRACE_DTOR(forecast_xacts); TRACE_DTOR(forecast_xacts);
@ -822,11 +827,13 @@ class pass_down_accounts : public item_handler<account_t>
pass_down_accounts(); pass_down_accounts();
optional<item_predicate> pred; optional<item_predicate> pred;
optional<scope_t&> context;
public: public:
pass_down_accounts(acct_handler_ptr handler, pass_down_accounts(acct_handler_ptr handler,
accounts_iterator& iter, accounts_iterator& iter,
const optional<item_predicate>& predicate = none); const optional<item_predicate>& _pred = none,
const optional<scope_t&>& _context = none);
virtual ~pass_down_accounts() { virtual ~pass_down_accounts() {
TRACE_DTOR(pass_down_accounts); TRACE_DTOR(pass_down_accounts);

View file

@ -125,15 +125,20 @@ void report_t::accounts_report(acct_handler_ptr handler)
{ {
sum_all_accounts(); sum_all_accounts();
if (! HANDLED(sort_)) { scoped_ptr<accounts_iterator> iter;
basic_accounts_iterator walker(*session.master);
pass_down_accounts(handler, walker, if (! HANDLED(sort_))
item_predicate("total", what_to_keep())); iter.reset(new basic_accounts_iterator(*session.master));
} else { else
sorted_accounts_iterator walker(*session.master, HANDLER(sort_).str()); iter.reset(new sorted_accounts_iterator(*session.master,
pass_down_accounts(handler, walker, HANDLER(sort_).str()));
item_predicate("total", what_to_keep()));
} 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_xacts();
session.clean_accounts(); session.clean_accounts();
@ -266,13 +271,13 @@ namespace {
value_t operator()(call_scope_t& args) value_t operator()(call_scope_t& args)
{ {
if (args.value().size() > 0) if (args.value().size() > 0) {
report.HANDLER(limit_).append report.HANDLER(limit_).append
(args_to_predicate_expr(args.value().as_sequence().begin(), (args_to_predicate_expr(args.value().as_sequence().begin(),
args.value().as_sequence().end())); args.value().as_sequence().end()));
DEBUG("report.predicate",
DEBUG("report.predicate", "Predicate = " << report.HANDLER(limit_).str());
"Predicate = " << report.HANDLER(limit_).str()); }
(report.*report_method)(handler_ptr(handler)); (report.*report_method)(handler_ptr(handler));

View file

@ -250,8 +250,9 @@ public:
OPTION(report_t, code_as_payee); OPTION(report_t, code_as_payee);
OPTION_(report_t, collapse, DO() { // -n OPTION_(report_t, collapse, DO() { // -n
// Make sure that balance reports are collapsed too // Make sure that balance reports are collapsed too, but only apply it
parent->HANDLER(display_).append("depth<=1"); // to account entries
parent->HANDLER(display_).append("xact|depth<=1");
}); });
OPTION_(report_t, collapse_if_zero, DO() { OPTION_(report_t, collapse_if_zero, DO() {