summaryrefslogtreecommitdiff
path: root/src/report.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/report.cc')
-rw-r--r--src/report.cc562
1 files changed, 287 insertions, 275 deletions
diff --git a/src/report.cc b/src/report.cc
index fe482a2e..883b324a 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -464,8 +464,8 @@ value_t report_t::echo_command(call_scope_t& scope)
bool report_t::maybe_import(const string& module)
{
- if (lookup(string(OPT_PREFIX) + "import_")) {
- expr_t(string(OPT_PREFIX) + "import_(\"" + module + "\")").calc(*this);
+ if (lookup(symbol_t::OPTION, "import_")) {
+ expr_t(string("import_(\"") + module + "\")").calc(*this);
return true;
}
return false;
@@ -707,304 +707,316 @@ option_t<report_t> * report_t::lookup_option(const char * p)
return NULL;
}
-void report_t::define(const string& name, expr_t::ptr_op_t def)
+void report_t::define(const symbol_t::kind_t kind, const string& name,
+ expr_t::ptr_op_t def)
{
- session.define(name, def);
+ session.define(kind, name, def);
}
-expr_t::ptr_op_t report_t::lookup(const string& name)
+expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
+ const string& name)
{
- if (expr_t::ptr_op_t def = session.lookup(name))
+ if (expr_t::ptr_op_t def = session.lookup(kind, name))
return def;
const char * p = name.c_str();
- switch (*p) {
- case 'a':
- if (is_eq(p, "amount_expr"))
- return MAKE_FUNCTOR(report_t::fn_amount_expr);
- else if (is_eq(p, "ansify_if"))
- return MAKE_FUNCTOR(report_t::fn_ansify_if);
- else if (is_eq(p, "abs"))
- return MAKE_FUNCTOR(report_t::fn_abs);
- break;
-
- case 'b':
- if (is_eq(p, "black"))
- return WRAP_FUNCTOR(fn_black);
- else if (is_eq(p, "blink"))
- return WRAP_FUNCTOR(fn_blink);
- else if (is_eq(p, "blue"))
- return WRAP_FUNCTOR(fn_blue);
- else if (is_eq(p, "bold"))
- return WRAP_FUNCTOR(fn_bold);
- break;
-
- case 'c':
- if (WANT_CMD()) { const char * q = p + CMD_PREFIX_LEN;
- switch (*q) {
- case 'b':
- if (*(q + 1) == '\0' || is_eq(q, "bal") || is_eq(q, "balance")) {
- return expr_t::op_t::wrap_functor
- (reporter<account_t, acct_handler_ptr, &report_t::accounts_report>
- (new format_accounts(*this, report_format(HANDLER(balance_format_))),
- *this, "#balance"));
- }
- else if (is_eq(q, "budget")) {
- HANDLER(amount_).set_expr(string("#budget"), "(amount, 0)");
-
- budget_flags |= BUDGET_WRAP_VALUES;
- if (! (budget_flags & ~BUDGET_WRAP_VALUES))
- budget_flags |= BUDGET_BUDGETED;
- return expr_t::op_t::wrap_functor
- (reporter<account_t, acct_handler_ptr, &report_t::accounts_report>
- (new format_accounts(*this, report_format(HANDLER(budget_format_))),
- *this, "#budget"));
- }
- break;
-
- case 'c':
- if (is_eq(q, "csv")) {
- return WRAP_FUNCTOR
- (reporter<>
- (new format_posts(*this, report_format(HANDLER(csv_format_))),
- *this, "#csv"));
- }
- else if (is_eq(q, "cleared")) {
- HANDLER(amount_).set_expr(string("#cleared"),
- "(amount, cleared ? amount : 0)");
-
- return expr_t::op_t::wrap_functor
- (reporter<account_t, acct_handler_ptr, &report_t::accounts_report>
- (new format_accounts(*this, report_format(HANDLER(cleared_format_))),
- *this, "#cleared"));
- }
- break;
-
- case 'e':
- if (is_eq(q, "equity"))
- return WRAP_FUNCTOR
- (reporter<>
- (new format_posts(*this, report_format(HANDLER(print_format_))),
- *this, "#equity"));
- else if (is_eq(q, "entry"))
- return WRAP_FUNCTOR(xact_command);
- else if (is_eq(q, "emacs"))
- return WRAP_FUNCTOR
- (reporter<>(new format_emacs_posts(output_stream), *this, "#emacs"));
- else if (is_eq(q, "echo"))
- return MAKE_FUNCTOR(report_t::echo_command);
- break;
-
- case 'p':
- if (*(q + 1) == '\0' || is_eq(q, "print"))
- return WRAP_FUNCTOR
- (reporter<>
- (new format_posts(*this, report_format(HANDLER(print_format_)),
- HANDLED(raw)), *this, "#print"));
- else if (is_eq(q, "prices"))
- return expr_t::op_t::wrap_functor
- (reporter<post_t, post_handler_ptr, &report_t::commodities_report>
- (new format_posts(*this, report_format(HANDLER(prices_format_))),
- *this, "#prices"));
- else if (is_eq(q, "pricesdb"))
- return expr_t::op_t::wrap_functor
- (reporter<post_t, post_handler_ptr, &report_t::commodities_report>
- (new format_posts(*this, report_format(HANDLER(pricesdb_format_))),
- *this, "#pricesdb"));
- else if (is_eq(q, "python") && maybe_import("ledger.interp"))
- return session.lookup(string(CMD_PREFIX) + "python");
- break;
-
- case 'r':
- if (*(q + 1) == '\0' || is_eq(q, "reg") || is_eq(q, "register"))
- return WRAP_FUNCTOR
- (reporter<>
- (new format_posts(*this, report_format(HANDLER(register_format_))),
- *this, "#register"));
- else if (is_eq(q, "reload"))
- return MAKE_FUNCTOR(report_t::reload_command);
- break;
-
- case 's':
- if (is_eq(q, "stats") || is_eq(q, "stat"))
- return WRAP_FUNCTOR(report_statistics);
- else
- if (is_eq(q, "server") && maybe_import("ledger.server"))
- return session.lookup(string(CMD_PREFIX) + "server");
- break;
-
- case 'x':
- if (is_eq(q, "xact"))
- return WRAP_FUNCTOR(xact_command);
- break;
- }
+ switch (kind) {
+ case symbol_t::FUNCTION:
+ switch (*p) {
+ case 'a':
+ if (is_eq(p, "amount_expr"))
+ return MAKE_FUNCTOR(report_t::fn_amount_expr);
+ else if (is_eq(p, "ansify_if"))
+ return MAKE_FUNCTOR(report_t::fn_ansify_if);
+ else if (is_eq(p, "abs"))
+ return MAKE_FUNCTOR(report_t::fn_abs);
+ break;
+
+ case 'b':
+ if (is_eq(p, "black"))
+ return WRAP_FUNCTOR(fn_black);
+ else if (is_eq(p, "blink"))
+ return WRAP_FUNCTOR(fn_blink);
+ else if (is_eq(p, "blue"))
+ return WRAP_FUNCTOR(fn_blue);
+ else if (is_eq(p, "bold"))
+ return WRAP_FUNCTOR(fn_bold);
+ break;
+
+ case 'c':
+ if (is_eq(p, "cyan"))
+ return WRAP_FUNCTOR(fn_cyan);
+ break;
+
+ case 'd':
+ if (is_eq(p, "display_amount"))
+ return MAKE_FUNCTOR(report_t::fn_display_amount);
+ else if (is_eq(p, "display_total"))
+ return MAKE_FUNCTOR(report_t::fn_display_total);
+ else if (is_eq(p, "date"))
+ return MAKE_FUNCTOR(report_t::fn_now);
+ break;
+
+ case 'f':
+ if (is_eq(p, "format_date"))
+ return MAKE_FUNCTOR(report_t::fn_format_date);
+ break;
+
+ case 'g':
+ if (is_eq(p, "get_at"))
+ return MAKE_FUNCTOR(report_t::fn_get_at);
+ else if (is_eq(p, "green"))
+ return WRAP_FUNCTOR(fn_green);
+ break;
+
+ case 'i':
+ if (is_eq(p, "is_seq"))
+ return MAKE_FUNCTOR(report_t::fn_is_seq);
+ break;
+
+ case 'j':
+ if (is_eq(p, "justify"))
+ return MAKE_FUNCTOR(report_t::fn_justify);
+ else if (is_eq(p, "join"))
+ return MAKE_FUNCTOR(report_t::fn_join);
+ break;
+
+ case 'm':
+ if (is_eq(p, "market"))
+ return MAKE_FUNCTOR(report_t::fn_market);
+ else if (is_eq(p, "magenta"))
+ return WRAP_FUNCTOR(fn_magenta);
+ break;
+
+ case 'n':
+ if (is_eq(p, "null"))
+ return WRAP_FUNCTOR(fn_null);
+ else if (is_eq(p, "now"))
+ return MAKE_FUNCTOR(report_t::fn_now);
+ break;
+
+ case 'o':
+ if (is_eq(p, "options"))
+ return MAKE_FUNCTOR(report_t::fn_options);
+ break;
+
+ case 'p':
+ if (is_eq(p, "post"))
+ return WRAP_FUNCTOR(fn_false);
+ else if (is_eq(p, "percent"))
+ return MAKE_FUNCTOR(report_t::fn_percent);
+ else if (is_eq(p, "price"))
+ return MAKE_FUNCTOR(report_t::fn_price);
+ break;
+
+ case 'q':
+ if (is_eq(p, "quoted"))
+ return MAKE_FUNCTOR(report_t::fn_quoted);
+ else if (is_eq(p, "quantity"))
+ return MAKE_FUNCTOR(report_t::fn_quantity);
+ break;
+
+ case 'r':
+ if (is_eq(p, "rounded"))
+ return MAKE_FUNCTOR(report_t::fn_rounded);
+ else if (is_eq(p, "red"))
+ return WRAP_FUNCTOR(fn_red);
+ break;
+
+ case 's':
+ if (is_eq(p, "scrub"))
+ return MAKE_FUNCTOR(report_t::fn_scrub);
+ else if (is_eq(p, "strip"))
+ return MAKE_FUNCTOR(report_t::fn_strip);
+ break;
+
+ case 't':
+ if (is_eq(p, "truncated"))
+ return MAKE_FUNCTOR(report_t::fn_truncated);
+ else if (is_eq(p, "total_expr"))
+ return MAKE_FUNCTOR(report_t::fn_total_expr);
+ else if (is_eq(p, "today"))
+ return MAKE_FUNCTOR(report_t::fn_today);
+ else if (is_eq(p, "t"))
+ return MAKE_FUNCTOR(report_t::fn_display_amount);
+ break;
+
+ case 'T':
+ if (is_eq(p, "T"))
+ return MAKE_FUNCTOR(report_t::fn_display_total);
+ break;
+
+ case 'u':
+ if (is_eq(p, "underline"))
+ return WRAP_FUNCTOR(fn_underline);
+ else if (is_eq(p, "unrounded"))
+ return MAKE_FUNCTOR(report_t::fn_unrounded);
+ break;
+
+ case 'w':
+ if (is_eq(p, "white"))
+ return WRAP_FUNCTOR(fn_white);
+ break;
+
+ case 'y':
+ if (is_eq(p, "yellow"))
+ return WRAP_FUNCTOR(fn_yellow);
+ break;
}
- else if (is_eq(p, "cyan"))
- return WRAP_FUNCTOR(fn_cyan);
- break;
- case 'd':
- if (is_eq(p, "display_amount"))
- return MAKE_FUNCTOR(report_t::fn_display_amount);
- else if (is_eq(p, "display_total"))
- return MAKE_FUNCTOR(report_t::fn_display_total);
- else if (is_eq(p, "date"))
- return MAKE_FUNCTOR(report_t::fn_now);
+ // Check if they are trying to access an option's setting or value.
+ if (option_t<report_t> * handler = lookup_option(p))
+ return MAKE_OPT_FUNCTOR(report_t, handler);
break;
- case 'f':
- if (is_eq(p, "format_date"))
- return MAKE_FUNCTOR(report_t::fn_format_date);
- break;
-
- case 'g':
- if (is_eq(p, "get_at"))
- return MAKE_FUNCTOR(report_t::fn_get_at);
- else if (is_eq(p, "green"))
- return WRAP_FUNCTOR(fn_green);
+ case symbol_t::OPTION:
+ if (option_t<report_t> * handler = lookup_option(p))
+ return MAKE_OPT_HANDLER(report_t, handler);
break;
- case 'i':
- if (is_eq(p, "is_seq"))
- return MAKE_FUNCTOR(report_t::fn_is_seq);
- break;
-
- case 'j':
- if (is_eq(p, "justify"))
- return MAKE_FUNCTOR(report_t::fn_justify);
- else if (is_eq(p, "join"))
- return MAKE_FUNCTOR(report_t::fn_join);
- break;
-
- case 'm':
- if (is_eq(p, "market"))
- return MAKE_FUNCTOR(report_t::fn_market);
- else if (is_eq(p, "magenta"))
- return WRAP_FUNCTOR(fn_magenta);
- break;
-
- case 'n':
- if (is_eq(p, "null"))
- return WRAP_FUNCTOR(fn_null);
- else if (is_eq(p, "now"))
- return MAKE_FUNCTOR(report_t::fn_now);
- break;
+ case symbol_t::COMMAND:
+ switch (*p) {
+ case 'b':
+ if (*(p + 1) == '\0' || is_eq(p, "bal") || is_eq(p, "balance")) {
+ return expr_t::op_t::wrap_functor
+ (reporter<account_t, acct_handler_ptr, &report_t::accounts_report>
+ (new format_accounts(*this, report_format(HANDLER(balance_format_))),
+ *this, "#balance"));
+ }
+ else if (is_eq(p, "budget")) {
+ HANDLER(amount_).set_expr(string("#budget"), "(amount, 0)");
- case 'o':
- if (WANT_OPT()) { const char * q = p + OPT_PREFIX_LEN;
- if (option_t<report_t> * handler = lookup_option(q))
- return MAKE_OPT_HANDLER(report_t, handler);
- }
- else if (is_eq(p, "options")) {
- return MAKE_FUNCTOR(report_t::fn_options);
- }
- break;
+ budget_flags |= BUDGET_WRAP_VALUES;
+ if (! (budget_flags & ~BUDGET_WRAP_VALUES))
+ budget_flags |= BUDGET_BUDGETED;
- case 'p':
- if (WANT_PRECMD()) { const char * q = p + PRECMD_PREFIX_LEN;
- switch (*q) {
- case 'a':
- if (is_eq(q, "args"))
- return WRAP_FUNCTOR(args_command);
- break;
- case 'e':
- if (is_eq(q, "eval"))
- return WRAP_FUNCTOR(eval_command);
- break;
- case 'f':
- if (is_eq(q, "format"))
- return WRAP_FUNCTOR(format_command);
- break;
- case 'g':
- if (is_eq(q, "generate"))
- return expr_t::op_t::wrap_functor
- (reporter<post_t, post_handler_ptr, &report_t::generate_report>
- (new format_posts(*this, report_format(HANDLER(print_format_)),
- false), *this, "#generate"));
- case 'h':
- if (is_eq(q, "hello") && maybe_import("ledger.hello"))
- return session.lookup(string(PRECMD_PREFIX) + "hello");
- break;
- case 'p':
- if (is_eq(q, "parse"))
- return WRAP_FUNCTOR(parse_command);
- else if (is_eq(q, "period"))
- return WRAP_FUNCTOR(period_command);
- break;
- case 't':
- if (is_eq(q, "template"))
- return WRAP_FUNCTOR(template_command);
- break;
+ return expr_t::op_t::wrap_functor
+ (reporter<account_t, acct_handler_ptr, &report_t::accounts_report>
+ (new format_accounts(*this, report_format(HANDLER(budget_format_))),
+ *this, "#budget"));
+ }
+ break;
+
+ case 'c':
+ if (is_eq(p, "csv")) {
+ return WRAP_FUNCTOR
+ (reporter<>
+ (new format_posts(*this, report_format(HANDLER(csv_format_))),
+ *this, "#csv"));
+ }
+ else if (is_eq(p, "cleared")) {
+ HANDLER(amount_).set_expr(string("#cleared"),
+ "(amount, cleared ? amount : 0)");
+
+ return expr_t::op_t::wrap_functor
+ (reporter<account_t, acct_handler_ptr, &report_t::accounts_report>
+ (new format_accounts(*this, report_format(HANDLER(cleared_format_))),
+ *this, "#cleared"));
}
+ break;
+
+ case 'e':
+ if (is_eq(p, "equity"))
+ return WRAP_FUNCTOR
+ (reporter<>
+ (new format_posts(*this, report_format(HANDLER(print_format_))),
+ *this, "#equity"));
+ else if (is_eq(p, "entry"))
+ return WRAP_FUNCTOR(xact_command);
+ else if (is_eq(p, "emacs"))
+ return WRAP_FUNCTOR
+ (reporter<>(new format_emacs_posts(output_stream), *this, "#emacs"));
+ else if (is_eq(p, "echo"))
+ return MAKE_FUNCTOR(report_t::echo_command);
+ break;
+
+ case 'p':
+ if (*(p + 1) == '\0' || is_eq(p, "print"))
+ return WRAP_FUNCTOR
+ (reporter<>
+ (new format_posts(*this, report_format(HANDLER(print_format_)),
+ HANDLED(raw)), *this, "#print"));
+ else if (is_eq(p, "prices"))
+ return expr_t::op_t::wrap_functor
+ (reporter<post_t, post_handler_ptr, &report_t::commodities_report>
+ (new format_posts(*this, report_format(HANDLER(prices_format_))),
+ *this, "#prices"));
+ else if (is_eq(p, "pricesdb"))
+ return expr_t::op_t::wrap_functor
+ (reporter<post_t, post_handler_ptr, &report_t::commodities_report>
+ (new format_posts(*this, report_format(HANDLER(pricesdb_format_))),
+ *this, "#pricesdb"));
+ else if (is_eq(p, "python") && maybe_import("ledger.interp"))
+ return session.lookup(symbol_t::COMMAND, "python");
+ break;
+
+ case 'r':
+ if (*(p + 1) == '\0' || is_eq(p, "reg") || is_eq(p, "register"))
+ return WRAP_FUNCTOR
+ (reporter<>
+ (new format_posts(*this, report_format(HANDLER(register_format_))),
+ *this, "#register"));
+ else if (is_eq(p, "reload"))
+ return MAKE_FUNCTOR(report_t::reload_command);
+ break;
+
+ case 's':
+ if (is_eq(p, "stats") || is_eq(p, "stat"))
+ return WRAP_FUNCTOR(report_statistics);
+ else
+ if (is_eq(p, "server") && maybe_import("ledger.server"))
+ return session.lookup(symbol_t::COMMAND, "server");
+ break;
+
+ case 'x':
+ if (is_eq(p, "xact"))
+ return WRAP_FUNCTOR(xact_command);
+ break;
}
- else if (is_eq(p, "post"))
- return WRAP_FUNCTOR(fn_false);
- else if (is_eq(p, "percent"))
- return MAKE_FUNCTOR(report_t::fn_percent);
- else if (is_eq(p, "price"))
- return MAKE_FUNCTOR(report_t::fn_price);
- break;
-
- case 'q':
- if (is_eq(p, "quoted"))
- return MAKE_FUNCTOR(report_t::fn_quoted);
- else if (is_eq(p, "quantity"))
- return MAKE_FUNCTOR(report_t::fn_quantity);
- break;
-
- case 'r':
- if (is_eq(p, "rounded"))
- return MAKE_FUNCTOR(report_t::fn_rounded);
- else if (is_eq(p, "red"))
- return WRAP_FUNCTOR(fn_red);
- break;
-
- case 's':
- if (is_eq(p, "scrub"))
- return MAKE_FUNCTOR(report_t::fn_scrub);
- else if (is_eq(p, "strip"))
- return MAKE_FUNCTOR(report_t::fn_strip);
- break;
-
- case 't':
- if (is_eq(p, "truncated"))
- return MAKE_FUNCTOR(report_t::fn_truncated);
- else if (is_eq(p, "total_expr"))
- return MAKE_FUNCTOR(report_t::fn_total_expr);
- else if (is_eq(p, "today"))
- return MAKE_FUNCTOR(report_t::fn_today);
- else if (is_eq(p, "t"))
- return MAKE_FUNCTOR(report_t::fn_display_amount);
- break;
-
- case 'T':
- if (is_eq(p, "T"))
- return MAKE_FUNCTOR(report_t::fn_display_total);
break;
- case 'u':
- if (is_eq(p, "underline"))
- return WRAP_FUNCTOR(fn_underline);
- else if (is_eq(p, "unrounded"))
- return MAKE_FUNCTOR(report_t::fn_unrounded);
- break;
-
- case 'w':
- if (is_eq(p, "white"))
- return WRAP_FUNCTOR(fn_white);
+ case symbol_t::PRECOMMAND:
+ switch (*p) {
+ case 'a':
+ if (is_eq(p, "args"))
+ return WRAP_FUNCTOR(args_command);
+ break;
+ case 'e':
+ if (is_eq(p, "eval"))
+ return WRAP_FUNCTOR(eval_command);
+ break;
+ case 'f':
+ if (is_eq(p, "format"))
+ return WRAP_FUNCTOR(format_command);
+ break;
+ case 'g':
+ if (is_eq(p, "generate"))
+ return expr_t::op_t::wrap_functor
+ (reporter<post_t, post_handler_ptr, &report_t::generate_report>
+ (new format_posts(*this, report_format(HANDLER(print_format_)),
+ false), *this, "#generate"));
+ case 'h':
+ if (is_eq(p, "hello") && maybe_import("ledger.hello"))
+ return session.lookup(symbol_t::PRECOMMAND, "hello");
+ break;
+ case 'p':
+ if (is_eq(p, "parse"))
+ return WRAP_FUNCTOR(parse_command);
+ else if (is_eq(p, "period"))
+ return WRAP_FUNCTOR(period_command);
+ break;
+ case 't':
+ if (is_eq(p, "template"))
+ return WRAP_FUNCTOR(template_command);
+ break;
+ }
break;
- case 'y':
- if (is_eq(p, "yellow"))
- return WRAP_FUNCTOR(fn_yellow);
+ default:
break;
}
- // Check if they are trying to access an option's setting or value.
- if (option_t<report_t> * handler = lookup_option(p))
- return MAKE_OPT_FUNCTOR(report_t, handler);
-
return NULL;
}