summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/chain.cc4
-rw-r--r--src/filters.h12
-rw-r--r--src/global.cc1
-rw-r--r--src/global.h1
-rw-r--r--src/op.cc17
-rw-r--r--src/report.h82
-rw-r--r--src/scope.cc3
-rw-r--r--src/scope.h5
-rw-r--r--test/baseline/opt-deviation.test2
-rw-r--r--test/baseline/opt-unround.test2
10 files changed, 65 insertions, 64 deletions
diff --git a/src/chain.cc b/src/chain.cc
index 400b8f26..f8f0aeff 100644
--- a/src/chain.cc
+++ b/src/chain.cc
@@ -118,6 +118,10 @@ post_handler_ptr chain_post_handlers(post_handler_ptr base_handler,
expr_t& expr(report.HANDLER(amount_).expr);
expr.set_context(&report);
+ report.HANDLER(total_).expr.set_context(&report);
+ report.HANDLER(display_amount_).expr.set_context(&report);
+ report.HANDLER(display_total_).expr.set_context(&report);
+
if (! for_accounts_report) {
// Make sure only forecast postings which match are allowed through
if (report.HANDLED(forecast_while_)) {
diff --git a/src/filters.h b/src/filters.h
index 22f2d2cb..7be3acb9 100644
--- a/src/filters.h
+++ b/src/filters.h
@@ -65,14 +65,14 @@ protected:
value_to_posts_map posts_map;
post_handler_ptr post_chain;
report_t& report;
- expr_t group_by_expr;
+ expr_t& group_by_expr;
custom_flusher_t preflush_func;
optional<custom_flusher_t> postflush_func;
public:
post_splitter(post_handler_ptr _post_chain,
report_t& _report,
- expr_t _group_by_expr)
+ expr_t& _group_by_expr)
: post_chain(_post_chain), report(_report),
group_by_expr(_group_by_expr) {
TRACE_CTOR(post_splitter, "scope_t&, post_handler_ptr, expr_t");
@@ -521,8 +521,8 @@ class display_filter_posts : public item_handler<post_t>
// later in the chain.
report_t& report;
- expr_t display_amount_expr;
- expr_t display_total_expr;
+ expr_t& display_amount_expr;
+ expr_t& display_total_expr;
bool show_rounding;
value_t last_display_total;
temporaries_t temps;
@@ -569,8 +569,8 @@ class changed_value_posts : public item_handler<post_t>
// later in the chain.
report_t& report;
- expr_t total_expr;
- expr_t display_total_expr;
+ expr_t& total_expr;
+ expr_t& display_total_expr;
bool changed_values_only;
bool for_accounts_report;
bool show_unrealized;
diff --git a/src/global.cc b/src/global.cc
index 5b7bb1c1..cc14c99e 100644
--- a/src/global.cc
+++ b/src/global.cc
@@ -70,6 +70,7 @@ global_scope_t::global_scope_t(char ** envp)
// generated.
report_stack.push_front(new report_t(*session_ptr));
scope_t::default_scope = &report();
+ scope_t::empty_scope = &empty_scope;
// Read the user's options, in the following order:
//
diff --git a/src/global.h b/src/global.h
index ce0534b0..7429b1f5 100644
--- a/src/global.h
+++ b/src/global.h
@@ -50,6 +50,7 @@ class global_scope_t : public noncopyable, public scope_t
{
shared_ptr<session_t> session_ptr;
ptr_list<report_t> report_stack;
+ empty_scope_t empty_scope;
public:
global_scope_t(char ** envp);
diff --git a/src/op.cc b/src/op.cc
index a8b71468..a5db1690 100644
--- a/src/op.cc
+++ b/src/op.cc
@@ -89,8 +89,9 @@ namespace {
expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth,
scope_t * param_scope)
{
- scope_t * scope_ptr = &scope;
- expr_t::ptr_op_t result;
+ scope_t * scope_ptr = &scope;
+ unique_ptr<scope_t> bound_scope;
+ expr_t::ptr_op_t result;
#if defined(DEBUG_ON)
if (SHOW_DEBUG("expr.compile")) {
@@ -129,9 +130,10 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth,
}
}
else if (is_scope()) {
- shared_ptr<scope_t> subscope(new symbol_scope_t(scope));
+ shared_ptr<scope_t> subscope(new symbol_scope_t(*scope_t::empty_scope));
set_scope(subscope);
- scope_ptr = subscope.get();
+ bound_scope.reset(new bind_scope_t(*scope_ptr, *subscope.get()));
+ scope_ptr = bound_scope.get();
}
else if (kind < TERMINALS) {
result = this;
@@ -153,8 +155,8 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth,
node->set_left(left()->right());
node->set_right(right());
- empty_scope_t empty_scope;
- symbol_scope_t params(param_scope ? *param_scope : empty_scope);
+ symbol_scope_t params(param_scope ?
+ *param_scope : *scope_t::empty_scope);
for (ptr_op_t sym = node->left();
sym;
sym = sym->has_right() ? sym->right() : NULL) {
@@ -330,8 +332,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
call_scope_t& call_args(find_scope<call_scope_t>(scope, true));
std::size_t args_count(call_args.size());
std::size_t args_index(0);
- empty_scope_t empty_scope;
- symbol_scope_t args_scope(empty_scope);
+ symbol_scope_t args_scope(*scope_t::empty_scope);
for (ptr_op_t sym = left();
sym;
diff --git a/src/report.h b/src/report.h
index 9541da43..f50bdc28 100644
--- a/src/report.h
+++ b/src/report.h
@@ -366,12 +366,9 @@ public:
OPTION__
(report_t, amount_, // -t
- expr_t expr;
- CTOR(report_t, amount_) {
- set_expr(none, "amount");
- }
+ DECL1(report_t, amount_, merged_expr_t, expr, ("amount_expr", "amount")) {}
void set_expr(const optional<string>& whence, const string& str) {
- expr = str;
+ expr.append(str);
on(whence, str);
}
DO_(args) {
@@ -384,7 +381,7 @@ public:
OPTION_(report_t, average, DO() { // -A
parent->HANDLER(display_total_)
- .set_expr(string("--average"), "count>0?(total_expr/count):0");
+ .set_expr(string("--average"), "count>0?(display_total/count):0");
});
OPTION__(report_t, balance_format_, CTOR(report_t, balance_format_) {
@@ -405,7 +402,7 @@ public:
OPTION_(report_t, basis, DO() { // -B
parent->HANDLER(revalued).on_only(string("--basis"));
- parent->HANDLER(amount_).set_expr(string("--basis"), "rounded(cost)");
+ parent->HANDLER(amount_).expr.set_base_expr("rounded(cost)");
});
OPTION_(report_t, begin_, DO_(args) { // -b
@@ -438,20 +435,20 @@ public:
OPTION__(report_t, budget_format_, CTOR(report_t, budget_format_) {
on(none,
- "%(justify(scrub(get_at(total_expr, 0)), 12, -1, true, color))"
- " %(justify(-scrub(get_at(total_expr, 1)), 12, "
+ "%(justify(scrub(get_at(display_total, 0)), 12, -1, true, color))"
+ " %(justify(-scrub(get_at(display_total, 1)), 12, "
" 12 + 1 + 12, true, color))"
- " %(justify(scrub(get_at(total_expr, 1) + "
- " get_at(total_expr, 0)), 12, "
+ " %(justify(scrub(get_at(display_total, 1) + "
+ " get_at(display_total, 0)), 12, "
" 12 + 1 + 12 + 1 + 12, true, color))"
" %(ansify_if("
- " justify((get_at(total_expr, 1) ? "
- " (100% * scrub(get_at(total_expr, 0))) / "
- " -scrub(get_at(total_expr, 1)) : 0), "
+ " justify((get_at(display_total, 1) ? "
+ " (100% * scrub(get_at(display_total, 0))) / "
+ " -scrub(get_at(display_total, 1)) : 0), "
" 5, -1, true, false),"
- " magenta if (color and get_at(total_expr, 1) and "
- " (abs(quantity(scrub(get_at(total_expr, 0))) / "
- " quantity(scrub(get_at(total_expr, 1)))) >= 1))))"
+ " magenta if (color and get_at(display_total, 1) and "
+ " (abs(quantity(scrub(get_at(display_total, 0))) / "
+ " quantity(scrub(get_at(display_total, 1)))) >= 1))))"
" %(!options.flat ? depth_spacer : \"\")"
"%-(ansify_if(partial_account(options.flat), blue if color))\n"
"%/%$1 %$2 %$3 %$4\n%/"
@@ -467,8 +464,8 @@ public:
OPTION__(report_t, cleared_format_, CTOR(report_t, cleared_format_) {
on(none,
- "%(justify(scrub(get_at(total_expr, 0)), 16, 16 + prepend_width, "
- " true, color)) %(justify(scrub(get_at(total_expr, 1)), 18, "
+ "%(justify(scrub(get_at(display_total, 0)), 16, 16 + prepend_width, "
+ " true, color)) %(justify(scrub(get_at(display_total, 1)), 18, "
" 36 + prepend_width, true, color))"
" %(latest_cleared ? format_date(latest_cleared) : \" \")"
" %(!options.flat ? depth_spacer : \"\")"
@@ -524,7 +521,7 @@ public:
OPTION_(report_t, deviation, DO() {
parent->HANDLER(display_total_)
- .set_expr(string("--deviation"), "amount_expr-total_expr/count");
+ .set_expr(string("--deviation"), "display_amount-display_total");
});
OPTION__
@@ -541,12 +538,10 @@ public:
OPTION__
(report_t, display_amount_,
- expr_t expr;
- CTOR(report_t, display_amount_) {
- set_expr(none, "amount_expr");
- }
+ DECL1(report_t, display_amount_, merged_expr_t, expr,
+ ("display_amount", "amount_expr")) {}
void set_expr(const optional<string>& whence, const string& str) {
- expr = str;
+ expr.append(str);
on(whence, str);
}
DO_(args) {
@@ -555,12 +550,10 @@ public:
OPTION__
(report_t, display_total_,
- expr_t expr;
- CTOR(report_t, display_total_) {
- set_expr(none, "total_expr");
- }
+ DECL1(report_t, display_total_, merged_expr_t, expr,
+ ("display_total", "total_expr")) {}
void set_expr(const optional<string>& whence, const string& str) {
- expr = str;
+ expr.append(str);
on(whence, str);
}
DO_(args) {
@@ -608,7 +601,10 @@ public:
OPTION_(report_t, gain, DO() { // -G
parent->HANDLER(revalued).on_only(string("--gain"));
- parent->HANDLER(amount_).set_expr(string("--gain"), "(amount, cost)");
+
+ parent->HANDLER(amount_).expr.set_base_expr("(amount, cost)");
+ parent->HANDLER(total_).expr.set_base_expr("total");
+
// Since we are displaying the amounts of revalued postings, they
// will end up being composite totals, and hence a pair of pairs.
parent->HANDLER(display_amount_)
@@ -676,10 +672,10 @@ public:
parent->HANDLER(revalued).on_only(string("--market"));
parent->HANDLER(display_amount_)
.set_expr(string("--market"),
- "market(amount_expr, value_date, exchange)");
+ "market(display_amount, value_date, exchange)");
parent->HANDLER(display_total_)
.set_expr(string("--market"),
- "market(total_expr, value_date, exchange)");
+ "market(display_total, value_date, exchange)");
});
OPTION(report_t, meta_);
@@ -802,10 +798,7 @@ public:
});
OPTION_(report_t, price, DO() { // -I
- parent->HANDLER(display_amount_)
- .set_expr(string("--price"), "price(amount_expr)");
- parent->HANDLER(display_total_)
- .set_expr(string("--price"), "price(total_expr)");
+ parent->HANDLER(amount_).expr.set_base_expr("price");
});
OPTION__(report_t, prices_format_, CTOR(report_t, prices_format_) {
@@ -823,8 +816,8 @@ public:
OPTION_(report_t, quantity, DO() { // -O
parent->HANDLER(revalued).off();
- parent->HANDLER(amount_).set_expr(string("--quantity"), "amount");
- parent->HANDLER(total_).set_expr(string("--quantity"), "total");
+ parent->HANDLER(amount_).expr.set_base_expr("amount");
+ parent->HANDLER(total_).expr.set_base_expr("total");
});
OPTION_(report_t, quarterly, DO() {
@@ -919,12 +912,9 @@ public:
OPTION__
(report_t, total_, // -T
- expr_t expr;
- CTOR(report_t, total_) {
- set_expr(none, "total");
- }
+ DECL1(report_t, total_, merged_expr_t, expr, ("total_expr", "total")) {}
void set_expr(const optional<string>& whence, const string& str) {
- expr = str;
+ expr.append(str);
on(whence, str);
}
DO_(args) {
@@ -961,9 +951,9 @@ public:
OPTION(report_t, unrealized_losses_);
OPTION_(report_t, unround, DO() {
- parent->HANDLER(display_amount_)
+ parent->HANDLER(amount_)
.set_expr(string("--unround"), "unrounded(amount_expr)");
- parent->HANDLER(display_total_)
+ parent->HANDLER(total_)
.set_expr(string("--unround"), "unrounded(total_expr)");
});
diff --git a/src/scope.cc b/src/scope.cc
index 160a97c9..00327159 100644
--- a/src/scope.cc
+++ b/src/scope.cc
@@ -35,7 +35,8 @@
namespace ledger {
-scope_t * scope_t::default_scope = NULL;
+scope_t * scope_t::default_scope = NULL;
+empty_scope_t * scope_t::empty_scope = NULL;
void symbol_scope_t::define(const symbol_t::kind_t kind,
const string& name, expr_t::ptr_op_t def)
diff --git a/src/scope.h b/src/scope.h
index 75dc2c0f..31ef61cb 100644
--- a/src/scope.h
+++ b/src/scope.h
@@ -99,10 +99,13 @@ private:
#endif // HAVE_BOOST_SERIALIZATION
};
+class empty_scope_t;
+
class scope_t
{
public:
- static scope_t * default_scope;
+ static scope_t * default_scope;
+ static empty_scope_t * empty_scope;
explicit scope_t() {
TRACE_CTOR(scope_t, "");
diff --git a/test/baseline/opt-deviation.test b/test/baseline/opt-deviation.test
index df216b9c..a677ff6e 100644
--- a/test/baseline/opt-deviation.test
+++ b/test/baseline/opt-deviation.test
@@ -190,7 +190,7 @@
Expenses:Books $120.00
Assets:Cash
-test reg --deviation books
+test reg -A --deviation books
08-Jan-01 January Expenses:Books $10.00 0
08-Jan-31 End of January Expenses:Books $10.00 0
08-Feb-01 February Expenses:Books $20.00 $6.67
diff --git a/test/baseline/opt-unround.test b/test/baseline/opt-unround.test
index cef212ae..755bb62c 100644
--- a/test/baseline/opt-unround.test
+++ b/test/baseline/opt-unround.test
@@ -82,7 +82,7 @@
Expenses:Travel:Passport $127.00
Assets:Checking
-test bal --unround --percent
+test bal --percent --unround
100.00% Assets:Checking
100.00% Expenses:Travel
92.14958953% Airfare