Added new debug option --options

This reports which options are in place before invoking a command, and
where exactly each option value came from.
This commit is contained in:
John Wiegley 2009-06-02 19:14:46 +01:00
parent e2092d07d8
commit c79fd9e72d
10 changed files with 392 additions and 167 deletions

View file

@ -423,7 +423,8 @@ value_t xact_command(call_scope_t& args)
xact_template_t tmpl = args_to_xact_template(begin, end); xact_template_t tmpl = args_to_xact_template(begin, end);
std::auto_ptr<xact_t> new_xact(derive_xact_from_template(tmpl, report)); std::auto_ptr<xact_t> new_xact(derive_xact_from_template(tmpl, report));
report.HANDLER(limit_).on("actual"); // jww (2009-02-27): make this more general // jww (2009-02-27): make this more general
report.HANDLER(limit_).on(string("#xact"), "actual");
report.xact_report(post_handler_ptr report.xact_report(post_handler_ptr
(new format_posts(report, (new format_posts(report,

View file

@ -204,6 +204,13 @@ void global_scope_t::execute_command(strings_list args, bool at_repl)
optional<path>(path(report().HANDLER(pager_).str())) : optional<path>(path(report().HANDLER(pager_).str())) :
optional<path>()); optional<path>());
// Now that the output stream is initialized, report the options that will
// participate in this report, if the user specified --options
if (HANDLED(options)) {
report_options(report(), report().output_stream);
}
// Create an argument scope containing the report command's arguments, and // Create an argument scope containing the report command's arguments, and
// then invoke the command. The bound scope causes lookups to happen // then invoke the command. The bound scope causes lookups to happen
// first in the global scope, and then in the report scope. // first in the global scope, and then in the report scope.
@ -239,6 +246,29 @@ int global_scope_t::execute_command_wrapper(strings_list args, bool at_repl)
return status; return status;
} }
void global_scope_t::report_options(report_t& report, std::ostream& out)
{
out << "<=============================================================================>"
<< std::endl;
out << "[Global scope options]" << std::endl;
HANDLER(args_only).report(out);
HANDLER(debug_).report(out);
HANDLER(init_file_).report(out);
HANDLER(script_).report(out);
HANDLER(trace_).report(out);
HANDLER(verbose).report(out);
HANDLER(verify).report(out);
out << std::endl << "[Session scope options]" << std::endl;
report.session.report_options(out);
out << std::endl << "[Report scope options]" << std::endl;
report.report_options(out);
out << "<=============================================================================>"
<< std::endl;
}
option_t<global_scope_t> * global_scope_t::lookup_option(const char * p) option_t<global_scope_t> * global_scope_t::lookup_option(const char * p)
{ {
switch (*p) { switch (*p) {
@ -260,6 +290,9 @@ option_t<global_scope_t> * global_scope_t::lookup_option(const char * p)
case 'i': case 'i':
OPT(init_file_); OPT(init_file_);
break; break;
case 'o':
OPT(options);
break;
case 's': case 's':
OPT(script_); OPT(script_);
break; break;
@ -287,13 +320,13 @@ expr_t::ptr_op_t global_scope_t::lookup(const string& name)
break; break;
case 'p': case 'p':
if (WANT_PRECMD()) { p += PRECMD_PREFIX_LEN; if (WANT_PRECMD()) { const char * q = p + PRECMD_PREFIX_LEN;
switch (*p) { switch (*q) {
case 'p': case 'p':
if (is_eq(p, "push")) if (is_eq(q, "push"))
MAKE_FUNCTOR(global_scope_t::push_command); return MAKE_FUNCTOR(global_scope_t::push_command);
else if (is_eq(p, "pop")) else if (is_eq(q, "pop"))
MAKE_FUNCTOR(global_scope_t::pop_command); return MAKE_FUNCTOR(global_scope_t::pop_command);
break; break;
} }
} }
@ -316,18 +349,18 @@ void global_scope_t::read_environment_settings(char * envp[])
if (const char * p = std::getenv("LEDGER")) { if (const char * p = std::getenv("LEDGER")) {
if (! std::getenv("LEDGER_FILE")) if (! std::getenv("LEDGER_FILE"))
process_option("file", report(), p, "LEDGER"); process_option("environ", "file", report(), p, "LEDGER");
} }
if (const char * p = std::getenv("LEDGER_INIT")) { if (const char * p = std::getenv("LEDGER_INIT")) {
if (! std::getenv("LEDGER_INIT_FILE")) if (! std::getenv("LEDGER_INIT_FILE"))
process_option("init-file", report(), p, "LEDGER_INIT"); process_option("environ", "init-file", report(), p, "LEDGER_INIT");
} }
if (const char * p = std::getenv("PRICE_HIST")) { if (const char * p = std::getenv("PRICE_HIST")) {
if (! std::getenv("LEDGER_PRICEDB")) if (! std::getenv("LEDGER_PRICEDB"))
process_option("price-db", report(), p, "PRICE_HIST"); process_option("environ", "price-db", report(), p, "PRICE_HIST");
} }
if (const char * p = std::getenv("PRICE_EXP")) if (const char * p = std::getenv("PRICE_EXP"))
process_option("price-exp", report(), p, "PRICE_EXP"); process_option("environ", "price-exp", report(), p, "PRICE_EXP");
#endif #endif
TRACE_FINISH(environment, 1); TRACE_FINISH(environment, 1);
@ -397,29 +430,29 @@ void global_scope_t::normalize_report_options(const string& verb)
// I might be able to do it with command objects, like register_t, which // I might be able to do it with command objects, like register_t, which
// each know how to adjust the report based on its current option settings. // each know how to adjust the report based on its current option settings.
if (verb == "print" || verb == "xact" || verb == "dump") { if (verb == "print" || verb == "xact" || verb == "dump") {
rep.HANDLER(related).on_only(); rep.HANDLER(related).on_only(string("?normalize"));
rep.HANDLER(related_all).on_only(); rep.HANDLER(related_all).on_only(string("?normalize"));
} }
else if (verb == "equity") { else if (verb == "equity") {
rep.HANDLER(equity).on_only(); rep.HANDLER(equity).on_only(string("?normalize"));
} }
else if (rep.HANDLED(related)) { else if (rep.HANDLED(related)) {
if (verb[0] == 'r') { if (verb[0] == 'r') {
rep.HANDLER(invert).on_only(); rep.HANDLER(invert).on_only(string("?normalize"));
} else { } else {
rep.HANDLER(subtotal).on_only(); rep.HANDLER(subtotal).on_only(string("?normalize"));
rep.HANDLER(related_all).on_only(); rep.HANDLER(related_all).on_only(string("?normalize"));
} }
} }
if (! rep.HANDLED(empty)) if (! rep.HANDLED(empty))
rep.HANDLER(display_).on("amount|(!post&total)"); rep.HANDLER(display_).on(string("?normalize"), "amount|(!post&total)");
if (verb[0] != 'b' && verb[0] != 'r') if (verb[0] != 'b' && verb[0] != 'r')
rep.HANDLER(base).on_only(); rep.HANDLER(base).on_only(string("?normalize"));
if (rep.HANDLED(period_) && ! rep.HANDLED(sort_all_)) if (rep.HANDLED(period_) && ! rep.HANDLED(sort_all_))
rep.HANDLER(sort_xacts_).on_only(); rep.HANDLER(sort_xacts_).on_only(string("?normalize"));
long cols = 0; long cols = 0;
if (rep.HANDLED(columns_)) if (rep.HANDLED(columns_))
@ -465,15 +498,15 @@ void global_scope_t::normalize_report_options(const string& verb)
} }
if (! rep.HANDLER(date_width_).specified) if (! rep.HANDLER(date_width_).specified)
rep.HANDLER(date_width_).on_with(date_width); rep.HANDLER(date_width_).on_with(string("?normalize"), date_width);
if (! rep.HANDLER(payee_width_).specified) if (! rep.HANDLER(payee_width_).specified)
rep.HANDLER(payee_width_).on_with(payee_width); rep.HANDLER(payee_width_).on_with(string("?normalize"), payee_width);
if (! rep.HANDLER(account_width_).specified) if (! rep.HANDLER(account_width_).specified)
rep.HANDLER(account_width_).on_with(account_width); rep.HANDLER(account_width_).on_with(string("?normalize"), account_width);
if (! rep.HANDLER(amount_width_).specified) if (! rep.HANDLER(amount_width_).specified)
rep.HANDLER(amount_width_).on_with(amount_width); rep.HANDLER(amount_width_).on_with(string("?normalize"), amount_width);
if (! rep.HANDLER(total_width_).specified) if (! rep.HANDLER(total_width_).specified)
rep.HANDLER(total_width_).on_with(total_width); rep.HANDLER(total_width_).on_with(string("?normalize"), total_width);
} }
} }

View file

@ -113,6 +113,8 @@ See LICENSE file included with the distribution for details and disclaimer.");
out << std::endl; out << std::endl;
} }
void report_options(report_t& report, std::ostream& out);
option_t<global_scope_t> * lookup_option(const char * p); option_t<global_scope_t> * lookup_option(const char * p);
virtual expr_t::ptr_op_t lookup(const string& name); virtual expr_t::ptr_op_t lookup(const string& name);
@ -133,11 +135,12 @@ See LICENSE file included with the distribution for details and disclaimer.");
CTOR(global_scope_t, init_file_) { CTOR(global_scope_t, init_file_) {
if (const char * home_var = std::getenv("HOME")) if (const char * home_var = std::getenv("HOME"))
on((path(home_var) / ".ledgerrc").string()); on(none, (path(home_var) / ".ledgerrc").string());
else else
on(path("./.ledgerrc").string()); on(none, path("./.ledgerrc").string());
}); });
OPTION(global_scope_t, options);
OPTION(global_scope_t, script_); OPTION(global_scope_t, script_);
OPTION(global_scope_t, trace_); OPTION(global_scope_t, trace_);
OPTION(global_scope_t, verbose); OPTION(global_scope_t, verbose);

View file

@ -76,11 +76,13 @@ namespace {
return op_bool_tuple(scope.lookup(buf), false); return op_bool_tuple(scope.lookup(buf), false);
} }
void process_option(const function_t& opt, scope_t& scope, void process_option(const string& whence, const function_t& opt,
const char * arg, const string& name) scope_t& scope, const char * arg, const string& name)
{ {
try { try {
call_scope_t args(scope); call_scope_t args(scope);
args.push_back(string_value(whence));
if (arg) if (arg)
args.push_back(string_value(arg)); args.push_back(string_value(arg));
@ -97,12 +99,12 @@ namespace {
} }
} }
void process_option(const string& name, scope_t& scope, void process_option(const string& whence, const string& name, scope_t& scope,
const char * arg, const string& varname) const char * arg, const string& varname)
{ {
op_bool_tuple opt(find_option(scope, name)); op_bool_tuple opt(find_option(scope, name));
if (opt.first) if (opt.first)
process_option(opt.first->as_function(), scope, arg, varname); process_option(whence, opt.first->as_function(), scope, arg, varname);
} }
void process_environment(const char ** envp, const string& tag, void process_environment(const char ** envp, const string& tag,
@ -129,7 +131,7 @@ void process_environment(const char ** envp, const string& tag,
try { try {
string value = string(*p, q - *p); string value = string(*p, q - *p);
if (! value.empty()) if (! value.empty())
process_option(string(buf), scope, q + 1, value); process_option(string("$") + buf, string(buf), scope, q + 1, value);
} }
catch (const std::exception& err) { catch (const std::exception& err) {
add_error_context(_("While parsing environment variable option '%1':") add_error_context(_("While parsing environment variable option '%1':")
@ -201,7 +203,8 @@ strings_list process_arguments(strings_list args, scope_t& scope)
if (value == NULL) if (value == NULL)
throw_(option_error, _("Missing option argument for --%1") << name); throw_(option_error, _("Missing option argument for --%1") << name);
} }
process_option(opt.first->as_function(), scope, value, process_option(string("--") + name,
opt.first->as_function(), scope, value,
string("--") + name); string("--") + name);
} }
else if ((*i)[1] == '\0') { else if ((*i)[1] == '\0') {
@ -230,7 +233,8 @@ strings_list process_arguments(strings_list args, scope_t& scope)
throw_(option_error, throw_(option_error,
_("Missing option argument for -%1") << o.ch); _("Missing option argument for -%1") << o.ch);
} }
process_option(o.op->as_function(), scope, value, string("-") + o.ch); process_option(string("-") + o.ch, o.op->as_function(), scope, value,
string("-") + o.ch);
} }
} }
} }

View file

@ -60,6 +60,7 @@ protected:
std::size_t name_len; std::size_t name_len;
const char ch; const char ch;
bool handled; bool handled;
optional<string> source;
option_t& operator=(const option_t&); option_t& operator=(const option_t&);
@ -90,6 +91,18 @@ public:
TRACE_DTOR(option_t); TRACE_DTOR(option_t);
} }
void report(std::ostream& out) const {
if (handled && source) {
if (wants_arg) {
out << desc() << " => ";
value.dump(out);
} else {
out << desc();
}
out << " <" << *source << ">" << std::endl;
}
}
string desc() const { string desc() const {
std::ostringstream out; std::ostringstream out;
out << "--"; out << "--";
@ -117,31 +130,42 @@ public:
return value.as_string_lval(); return value.as_string_lval();
} }
void on_only() { string str() const {
assert(handled);
if (! value)
throw_(std::runtime_error, _("No argument provided for %1") << desc());
return value.as_string();
}
void on_only(const optional<string>& whence) {
handled = true; handled = true;
source = whence;
} }
void on(const string& str) { void on(const optional<string>& whence, const string& str) {
on_with(string_value(str)); on_with(whence, string_value(str));
} }
virtual void on_with(const value_t& val) { virtual void on_with(const optional<string>& whence,
const value_t& val) {
handled = true; handled = true;
value = val; value = val;
source = whence;
} }
void off() { void off() {
handled = false; handled = false;
value = value_t(); value = value_t();
source = none;
} }
virtual void handler_thunk(call_scope_t&) {} virtual void handler_thunk(call_scope_t&) {}
virtual void handler(call_scope_t& args) { virtual void handler(call_scope_t& args) {
if (wants_arg) { if (wants_arg) {
if (args.empty()) if (args.empty() || args.size() == 1)
throw_(std::runtime_error, _("No argument provided for %1") << desc()); throw_(std::runtime_error, _("No argument provided for %1") << desc());
on_with(args[0]); on_with(args[0].as_string(), args[1]);
} else { } else {
on_only(); on_only(args[0].as_string());
} }
handler_thunk(args); handler_thunk(args);
@ -270,7 +294,7 @@ inline bool is_eq(const char * p, const char * n) {
#define WANT_DIR() \ #define WANT_DIR() \
(std::strncmp(p, DIR_PREFIX, DIR_PREFIX_LEN) == 0) (std::strncmp(p, DIR_PREFIX, DIR_PREFIX_LEN) == 0)
void process_option(const string& name, scope_t& scope, void process_option(const string& whence, const string& name, scope_t& scope,
const char * arg, const string& varname); const char * arg, const string& varname);
void process_environment(const char ** envp, const string& tag, void process_environment(const char ** envp, const string& tag,

View file

@ -55,12 +55,15 @@ void report_t::posts_report(post_handler_ptr handler)
void report_t::generate_report(post_handler_ptr handler) void report_t::generate_report(post_handler_ptr handler)
{ {
HANDLER(limit_).on("actual"); // jww (2009-02-27): make this more general // jww (2009-02-27): make this more general
HANDLER(limit_).on(string("#generate"), "actual");
generate_posts_iterator walker generate_posts_iterator walker
(session, HANDLED(seed_) ? (session, HANDLED(seed_) ?
static_cast<unsigned int>(HANDLER(seed_).value.to_long()) : 0, static_cast<unsigned int>(HANDLER(seed_).value.to_long()) : 0,
HANDLED(head_) ? HANDLED(head_) ?
static_cast<unsigned int>(HANDLER(head_).value.to_long()) : 50); static_cast<unsigned int>(HANDLER(head_).value.to_long()) : 50);
pass_down_posts(chain_post_handlers(*this, handler), walker); pass_down_posts(chain_post_handlers(*this, handler), walker);
} }
@ -349,10 +352,12 @@ namespace {
shared_ptr<item_handler<Type> > handler; shared_ptr<item_handler<Type> > handler;
report_t& report; report_t& report;
string whence;
public: public:
reporter(item_handler<Type> * _handler, report_t& _report) reporter(item_handler<Type> * _handler, report_t& _report,
: handler(_handler), report(_report) {} const string& _whence)
: handler(_handler), report(_report), whence(_whence) {}
value_t operator()(call_scope_t& args) value_t operator()(call_scope_t& args)
{ {
@ -365,7 +370,7 @@ namespace {
string limit = args_to_predicate_expr(begin, end); string limit = args_to_predicate_expr(begin, end);
if (! limit.empty()) if (! limit.empty())
report.HANDLER(limit_).on(limit); report.HANDLER(limit_).on(whence, limit);
DEBUG("report.predicate", DEBUG("report.predicate",
"Predicate = " << report.HANDLER(limit_).str()); "Predicate = " << report.HANDLER(limit_).str());
@ -375,7 +380,7 @@ namespace {
display = args_to_predicate_expr(begin, end); display = args_to_predicate_expr(begin, end);
if (! display.empty()) if (! display.empty())
report.HANDLER(display_).on(display); report.HANDLER(display_).on(whence, display);
DEBUG("report.predicate", DEBUG("report.predicate",
"Display predicate = " << report.HANDLER(display_).str()); "Display predicate = " << report.HANDLER(display_).str());
@ -675,7 +680,7 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
return expr_t::op_t::wrap_functor return expr_t::op_t::wrap_functor
(reporter<account_t, acct_handler_ptr, &report_t::accounts_report> (reporter<account_t, acct_handler_ptr, &report_t::accounts_report>
(new format_accounts(*this, report_format(HANDLER(balance_format_))), (new format_accounts(*this, report_format(HANDLER(balance_format_))),
*this)); *this, "#balance"));
break; break;
case 'c': case 'c':
@ -683,7 +688,7 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
return WRAP_FUNCTOR return WRAP_FUNCTOR
(reporter<> (reporter<>
(new format_posts(*this, report_format(HANDLER(csv_format_))), (new format_posts(*this, report_format(HANDLER(csv_format_))),
*this)); *this, "#csv"));
break; break;
case 'e': case 'e':
@ -691,12 +696,12 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
return WRAP_FUNCTOR return WRAP_FUNCTOR
(reporter<> (reporter<>
(new format_posts(*this, report_format(HANDLER(print_format_))), (new format_posts(*this, report_format(HANDLER(print_format_))),
*this)); *this, "#equity"));
else if (is_eq(q, "xact") || is_eq(q, "entry")) else if (is_eq(q, "xact") || is_eq(q, "entry"))
return WRAP_FUNCTOR(xact_command); return WRAP_FUNCTOR(xact_command);
else if (is_eq(q, "emacs")) else if (is_eq(q, "emacs"))
return WRAP_FUNCTOR return WRAP_FUNCTOR
(reporter<>(new format_emacs_posts(output_stream), *this)); (reporter<>(new format_emacs_posts(output_stream), *this, "#emacs"));
break; break;
case 'p': case 'p':
@ -704,17 +709,17 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
return WRAP_FUNCTOR return WRAP_FUNCTOR
(reporter<> (reporter<>
(new format_posts(*this, report_format(HANDLER(print_format_)), (new format_posts(*this, report_format(HANDLER(print_format_)),
HANDLED(raw)), *this)); HANDLED(raw)), *this, "#print"));
else if (is_eq(q, "prices")) else if (is_eq(q, "prices"))
return expr_t::op_t::wrap_functor return expr_t::op_t::wrap_functor
(reporter<post_t, post_handler_ptr, &report_t::commodities_report> (reporter<post_t, post_handler_ptr, &report_t::commodities_report>
(new format_posts(*this, report_format(HANDLER(prices_format_))), (new format_posts(*this, report_format(HANDLER(prices_format_))),
*this)); *this, "#prices"));
else if (is_eq(q, "pricesdb")) else if (is_eq(q, "pricesdb"))
return expr_t::op_t::wrap_functor return expr_t::op_t::wrap_functor
(reporter<post_t, post_handler_ptr, &report_t::commodities_report> (reporter<post_t, post_handler_ptr, &report_t::commodities_report>
(new format_posts(*this, report_format(HANDLER(pricesdb_format_))), (new format_posts(*this, report_format(HANDLER(pricesdb_format_))),
*this)); *this, "#pricesdb"));
else if (is_eq(q, "python") && maybe_import("ledger.interp")) else if (is_eq(q, "python") && maybe_import("ledger.interp"))
return session.lookup(string(CMD_PREFIX) + "python"); return session.lookup(string(CMD_PREFIX) + "python");
break; break;
@ -724,7 +729,7 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
return WRAP_FUNCTOR return WRAP_FUNCTOR
(reporter<> (reporter<>
(new format_posts(*this, report_format(HANDLER(register_format_))), (new format_posts(*this, report_format(HANDLER(register_format_))),
*this)); *this, "#register"));
else if (is_eq(q, "reload")) else if (is_eq(q, "reload"))
return MAKE_FUNCTOR(report_t::reload_command); return MAKE_FUNCTOR(report_t::reload_command);
break; break;
@ -815,7 +820,7 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
return expr_t::op_t::wrap_functor return expr_t::op_t::wrap_functor
(reporter<post_t, post_handler_ptr, &report_t::generate_report> (reporter<post_t, post_handler_ptr, &report_t::generate_report>
(new format_posts(*this, report_format(HANDLER(print_format_)), (new format_posts(*this, report_format(HANDLER(print_format_)),
false), *this)); false), *this, "#generate"));
case 'h': case 'h':
if (is_eq(q, "hello") && maybe_import("ledger.hello")) if (is_eq(q, "hello") && maybe_import("ledger.hello"))
return session.lookup(string(PRECMD_PREFIX) + "hello"); return session.lookup(string(PRECMD_PREFIX) + "hello");

View file

@ -176,6 +176,113 @@ public:
bool maybe_import(const string& module); bool maybe_import(const string& module);
void report_options(std::ostream& out)
{
HANDLER(abbrev_len_).report(out);
HANDLER(account_).report(out);
HANDLER(actual).report(out);
HANDLER(add_budget).report(out);
HANDLER(amount_).report(out);
HANDLER(amount_data).report(out);
HANDLER(anon).report(out);
HANDLER(average).report(out);
HANDLER(balance_format_).report(out);
HANDLER(base).report(out);
HANDLER(basis).report(out);
HANDLER(begin_).report(out);
HANDLER(budget).report(out);
HANDLER(by_payee).report(out);
HANDLER(cleared).report(out);
HANDLER(code_as_payee).report(out);
HANDLER(comm_as_payee).report(out);
HANDLER(code_as_account).report(out);
HANDLER(comm_as_account).report(out);
HANDLER(color).report(out);
HANDLER(collapse).report(out);
HANDLER(collapse_if_zero).report(out);
HANDLER(columns_).report(out);
HANDLER(csv_format_).report(out);
HANDLER(current).report(out);
HANDLER(daily).report(out);
HANDLER(date_format_).report(out);
HANDLER(depth_).report(out);
HANDLER(deviation).report(out);
HANDLER(display_).report(out);
HANDLER(display_amount_).report(out);
HANDLER(display_total_).report(out);
HANDLER(dow).report(out);
HANDLER(effective).report(out);
HANDLER(empty).report(out);
HANDLER(end_).report(out);
HANDLER(equity).report(out);
HANDLER(exact).report(out);
HANDLER(exchange_).report(out);
HANDLER(flat).report(out);
HANDLER(forecast_while_).report(out);
HANDLER(format_).report(out);
HANDLER(gain).report(out);
HANDLER(head_).report(out);
HANDLER(invert).report(out);
HANDLER(limit_).report(out);
HANDLER(lot_dates).report(out);
HANDLER(lot_prices).report(out);
HANDLER(lot_tags).report(out);
HANDLER(lots).report(out);
HANDLER(lots_actual).report(out);
HANDLER(market).report(out);
HANDLER(monthly).report(out);
HANDLER(no_total).report(out);
HANDLER(only_).report(out);
HANDLER(output_).report(out);
HANDLER(pager_).report(out);
HANDLER(payee_as_account).report(out);
HANDLER(pending).report(out);
HANDLER(percentage).report(out);
HANDLER(period_).report(out);
HANDLER(period_sort_).report(out);
HANDLER(plot_amount_format_).report(out);
HANDLER(plot_total_format_).report(out);
HANDLER(price).report(out);
HANDLER(price_exp_).report(out);
HANDLER(prices_format_).report(out);
HANDLER(pricesdb_format_).report(out);
HANDLER(print_format_).report(out);
HANDLER(quantity).report(out);
HANDLER(quarterly).report(out);
HANDLER(raw).report(out);
HANDLER(real).report(out);
HANDLER(register_format_).report(out);
HANDLER(related).report(out);
HANDLER(related_all).report(out);
HANDLER(revalued).report(out);
HANDLER(revalued_only).report(out);
HANDLER(revalued_total_).report(out);
HANDLER(seed_).report(out);
HANDLER(set_account_).report(out);
HANDLER(set_payee_).report(out);
HANDLER(set_price_).report(out);
HANDLER(sort_).report(out);
HANDLER(sort_all_).report(out);
HANDLER(sort_xacts_).report(out);
HANDLER(start_of_week_).report(out);
HANDLER(subtotal).report(out);
HANDLER(tail_).report(out);
HANDLER(total_).report(out);
HANDLER(total_data).report(out);
HANDLER(truncate_).report(out);
HANDLER(unbudgeted).report(out);
HANDLER(uncleared).report(out);
HANDLER(unround).report(out);
HANDLER(weekly).report(out);
HANDLER(wide).report(out);
HANDLER(yearly).report(out);
HANDLER(date_width_).report(out);
HANDLER(payee_width_).report(out);
HANDLER(account_width_).report(out);
HANDLER(amount_width_).report(out);
HANDLER(total_width_).report(out);
}
option_t<report_t> * lookup_option(const char * p); option_t<report_t> * lookup_option(const char * p);
virtual void define(const string& name, expr_t::ptr_op_t def); virtual void define(const string& name, expr_t::ptr_op_t def);
@ -187,11 +294,11 @@ public:
*/ */
OPTION__(report_t, abbrev_len_, OPTION__(report_t, abbrev_len_,
CTOR(report_t, abbrev_len_) { on_with(2L); }); CTOR(report_t, abbrev_len_) { on_with(none, 2L); });
OPTION(report_t, account_); OPTION(report_t, account_);
OPTION_(report_t, actual, DO() { // -L OPTION_(report_t, actual, DO() { // -L
parent->HANDLER(limit_).on("actual"); parent->HANDLER(limit_).on(string("--actual"), "actual");
}); });
OPTION_(report_t, add_budget, DO() { OPTION_(report_t, add_budget, DO() {
@ -202,28 +309,31 @@ public:
(report_t, amount_, // -t (report_t, amount_, // -t
expr_t expr; expr_t expr;
CTOR(report_t, amount_) { CTOR(report_t, amount_) {
set_expr("amount"); set_expr(none, "amount");
} }
void set_expr(const string& str) { void set_expr(const optional<string>& whence, const string& str) {
expr = str; expr = str;
on(str); on(whence, str);
} }
DO_(args) { DO_(args) {
set_expr(args[0].to_string()); set_expr(args[0].to_string(), args[1].to_string());
}); });
OPTION_(report_t, amount_data, DO() { // -j OPTION_(report_t, amount_data, DO() { // -j
parent->HANDLER(format_).on_with(parent->HANDLER(plot_amount_format_).value); parent->HANDLER(format_)
.on_with(none, parent->HANDLER(plot_amount_format_).value);
}); });
OPTION(report_t, anon); OPTION(report_t, anon);
OPTION_(report_t, average, DO() { // -A OPTION_(report_t, average, DO() { // -A
parent->HANDLER(display_total_).set_expr("total_expr/count"); parent->HANDLER(display_total_).set_expr(string("--average"),
"total_expr/count");
}); });
OPTION__(report_t, balance_format_, CTOR(report_t, balance_format_) { OPTION__(report_t, balance_format_, CTOR(report_t, balance_format_) {
on("%(ansify_if(justify(scrub(display_total), 20, -1, true), " on(none,
"%(ansify_if(justify(scrub(display_total), 20, -1, true), "
" red if color & scrub(display_total) < 0))" " red if color & scrub(display_total) < 0))"
" %(!options.flat ? depth_spacer : \"\")" " %(!options.flat ? depth_spacer : \"\")"
"%-(ansify_if(partial_account(options.flat), blue if color))\n%/" "%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
@ -235,20 +345,20 @@ public:
OPTION(report_t, base); OPTION(report_t, base);
OPTION_(report_t, basis, DO() { // -B OPTION_(report_t, basis, DO() { // -B
parent->HANDLER(revalued).on_only(); parent->HANDLER(revalued).on_only(string("--basis"));
parent->HANDLER(amount_).set_expr("rounded(cost)"); parent->HANDLER(amount_).set_expr(string("--basis"), "rounded(cost)");
}); });
OPTION_(report_t, begin_, DO_(args) { // -b OPTION_(report_t, begin_, DO_(args) { // -b
date_interval_t interval(args[0].to_string()); date_interval_t interval(args[1].to_string());
if (! interval.start) if (! interval.start)
throw_(std::invalid_argument, throw_(std::invalid_argument,
_("Could not determine beginning of period '%1'") _("Could not determine beginning of period '%1'")
<< args[0].to_string()); << args[1].to_string());
string predicate = string predicate =
"date>=[" + to_iso_extended_string(*interval.start) + "]"; "date>=[" + to_iso_extended_string(*interval.start) + "]";
parent->HANDLER(limit_).on(predicate); parent->HANDLER(limit_).on(string("--begin"), predicate);
}); });
OPTION_(report_t, budget, DO() { OPTION_(report_t, budget, DO() {
@ -258,7 +368,7 @@ public:
OPTION(report_t, by_payee); // -P OPTION(report_t, by_payee); // -P
OPTION_(report_t, cleared, DO() { // -C OPTION_(report_t, cleared, DO() { // -C
parent->HANDLER(limit_).on("cleared"); parent->HANDLER(limit_).on(string("--cleared"), "cleared");
}); });
OPTION(report_t, code_as_payee); OPTION(report_t, code_as_payee);
@ -270,17 +380,18 @@ public:
OPTION_(report_t, collapse, DO() { // -n OPTION_(report_t, collapse, DO() { // -n
// Make sure that balance reports are collapsed too, but only apply it // Make sure that balance reports are collapsed too, but only apply it
// to account xacts // to account xacts
parent->HANDLER(display_).on("post|depth<=1"); parent->HANDLER(display_).on(string("--collapse"), "post|depth<=1");
}); });
OPTION_(report_t, collapse_if_zero, DO() { OPTION_(report_t, collapse_if_zero, DO() {
parent->HANDLER(collapse).on_only(); parent->HANDLER(collapse).on_only(string("--collapse-if-zero"));
}); });
OPTION(report_t, columns_); OPTION(report_t, columns_);
OPTION__(report_t, csv_format_, CTOR(report_t, csv_format_) { OPTION__(report_t, csv_format_, CTOR(report_t, csv_format_) {
on("%(quoted(date))," on(none,
"%(quoted(date)),"
"%(quoted(payee))," "%(quoted(payee)),"
"%(quoted(account))," "%(quoted(account)),"
"%(quoted(scrub(display_amount)))," "%(quoted(scrub(display_amount))),"
@ -290,35 +401,38 @@ public:
}); });
OPTION_(report_t, current, DO() { // -c OPTION_(report_t, current, DO() { // -c
parent->HANDLER(limit_).on("date<=today"); parent->HANDLER(limit_).on(string("--current"), "date<=today");
}); });
OPTION_(report_t, daily, DO() { OPTION_(report_t, daily, DO() {
parent->HANDLER(period_).on("daily"); parent->HANDLER(period_).on(string("--daily"), "daily");
}); });
OPTION__(report_t, date_format_, // -y OPTION__(report_t, date_format_, // -y
CTOR(report_t, date_format_) { CTOR(report_t, date_format_) {
on("%y-%b-%d"); on(none, "%y-%b-%d");
}); });
OPTION_(report_t, depth_, DO_(scope) { OPTION_(report_t, depth_, DO_(scope) {
interactive_t args(scope, "l"); interactive_t args(scope, "sl");
parent->HANDLER(display_).on(string("depth<=") + args.get<string>(0)); parent->HANDLER(display_).on(string("--depth"),
string("depth<=") + args.get<string>(1));
}); });
OPTION_(report_t, deviation, DO() { // -D OPTION_(report_t, deviation, DO() { // -D
parent->HANDLER(display_total_).set_expr("amount_expr-total_expr/count"); parent->HANDLER(display_total_).set_expr(string("--deviation"),
"amount_expr-total_expr/count");
}); });
OPTION__ OPTION__
(report_t, display_, // -d (report_t, display_, // -d
CTOR(report_t, display_) {} CTOR(report_t, display_) {}
virtual void on_with(const value_t& text) { virtual void on_with(const optional<string>& whence, const value_t& text) {
if (! handled) if (! handled)
option_t<report_t>::on_with(text); option_t<report_t>::on_with(whence, text);
else else
option_t<report_t>::on_with(string_value(string("(") + str() + ")&(" + option_t<report_t>::on_with(whence,
string_value(string("(") + str() + ")&(" +
text.as_string() + ")")); text.as_string() + ")"));
}); });
@ -326,28 +440,28 @@ public:
(report_t, display_amount_, (report_t, display_amount_,
expr_t expr; expr_t expr;
CTOR(report_t, display_amount_) { CTOR(report_t, display_amount_) {
set_expr("amount_expr"); set_expr(none, "amount_expr");
} }
void set_expr(const string& str) { void set_expr(const optional<string>& whence, const string& str) {
expr = str; expr = str;
on(str); on(whence, str);
} }
DO_(args) { DO_(args) {
set_expr(args[0].to_string()); set_expr(args[0].to_string(), args[1].to_string());
}); });
OPTION__ OPTION__
(report_t, display_total_, (report_t, display_total_,
expr_t expr; expr_t expr;
CTOR(report_t, display_total_) { CTOR(report_t, display_total_) {
set_expr("total_expr"); set_expr(none, "total_expr");
} }
void set_expr(const string& str) { void set_expr(const optional<string>& whence, const string& str) {
expr = str; expr = str;
on(str); on(whence, str);
} }
DO_(args) { DO_(args) {
set_expr(args[0].to_string()); set_expr(args[0].to_string(), args[1].to_string());
}); });
OPTION(report_t, dow); OPTION(report_t, dow);
@ -355,15 +469,15 @@ public:
OPTION(report_t, empty); // -E OPTION(report_t, empty); // -E
OPTION_(report_t, end_, DO_(args) { // -e OPTION_(report_t, end_, DO_(args) { // -e
date_interval_t interval(args[0].to_string()); date_interval_t interval(args[1].to_string());
if (! interval.start) if (! interval.start)
throw_(std::invalid_argument, throw_(std::invalid_argument,
_("Could not determine end of period '%1'") _("Could not determine end of period '%1'")
<< args[0].to_string()); << args[1].to_string());
string predicate = string predicate =
"date<[" + to_iso_extended_string(*interval.start) + "]"; "date<[" + to_iso_extended_string(*interval.start) + "]";
parent->HANDLER(limit_).on(predicate); parent->HANDLER(limit_).on(string("--end"), predicate);
#if 0 #if 0
terminus = interval.begin; terminus = interval.begin;
#endif #endif
@ -373,8 +487,9 @@ public:
OPTION(report_t, exact); OPTION(report_t, exact);
OPTION_(report_t, exchange_, DO_(args) { // -X OPTION_(report_t, exchange_, DO_(args) { // -X
on_with(args[0]); on_with(args[0].as_string(), args[1]);
call_scope_t no_args(*parent); call_scope_t no_args(*parent);
no_args.push_back(args[0]);
parent->HANDLER(market).parent = parent; parent->HANDLER(market).parent = parent;
parent->HANDLER(market).handler(no_args); parent->HANDLER(market).handler(no_args);
}); });
@ -384,21 +499,24 @@ public:
OPTION(report_t, format_); // -F OPTION(report_t, format_); // -F
OPTION_(report_t, gain, DO() { // -G OPTION_(report_t, gain, DO() { // -G
parent->HANDLER(revalued).on_only(); parent->HANDLER(revalued).on_only(string("--gain"));
parent->HANDLER(amount_).set_expr("(amount, cost)"); parent->HANDLER(amount_).set_expr(string("--gain"), "(amount, cost)");
// Since we are displaying the amounts of revalued postings, they // Since we are displaying the amounts of revalued postings, they
// will end up being composite totals, and hence a pair of pairs. // will end up being composite totals, and hence a pair of pairs.
parent->HANDLER(display_amount_) parent->HANDLER(display_amount_)
.set_expr("use_direct_amount ? amount :" .set_expr(string("--gain"),
"use_direct_amount ? amount :"
" (is_seq(get_at(amount_expr, 0)) ?" " (is_seq(get_at(amount_expr, 0)) ?"
" get_at(get_at(amount_expr, 0), 0) :" " get_at(get_at(amount_expr, 0), 0) :"
" market(get_at(amount_expr, 0), date, exchange)" " market(get_at(amount_expr, 0), date, exchange)"
" - get_at(amount_expr, 1))"); " - get_at(amount_expr, 1))");
parent->HANDLER(revalued_total_) parent->HANDLER(revalued_total_)
.set_expr("(market(get_at(total_expr, 0), date, exchange), " .set_expr(string("--gain"),
"(market(get_at(total_expr, 0), date, exchange), "
"get_at(total_expr, 1))"); "get_at(total_expr, 1))");
parent->HANDLER(display_total_) parent->HANDLER(display_total_)
.set_expr("use_direct_amount ? total_expr :" .set_expr(string("--gain"),
"use_direct_amount ? total_expr :"
" market(get_at(total_expr, 0), date, exchange)" " market(get_at(total_expr, 0), date, exchange)"
" - get_at(total_expr, 1)"); " - get_at(total_expr, 1)");
}); });
@ -406,17 +524,18 @@ public:
OPTION(report_t, head_); OPTION(report_t, head_);
OPTION_(report_t, invert, DO() { OPTION_(report_t, invert, DO() {
parent->HANDLER(amount_).set_expr("-amount"); parent->HANDLER(amount_).set_expr(string("--invert"), "-amount");
}); });
OPTION__ OPTION__
(report_t, limit_, // -l (report_t, limit_, // -l
CTOR(report_t, limit_) {} CTOR(report_t, limit_) {}
virtual void on_with(const value_t& text) { virtual void on_with(const optional<string>& whence, const value_t& text) {
if (! handled) if (! handled)
option_t<report_t>::on_with(text); option_t<report_t>::on_with(whence, text);
else else
option_t<report_t>::on_with(string_value(string("(") + str() + ")&(" + option_t<report_t>::on_with(whence,
string_value(string("(") + str() + ")&(" +
text.as_string() + ")")); text.as_string() + ")"));
}); });
@ -427,15 +546,15 @@ public:
OPTION(report_t, lots_actual); OPTION(report_t, lots_actual);
OPTION_(report_t, market, DO() { // -V OPTION_(report_t, market, DO() { // -V
parent->HANDLER(revalued).on_only(); parent->HANDLER(revalued).on_only(string("--market"));
parent->HANDLER(display_amount_) parent->HANDLER(display_amount_)
.set_expr("market(amount_expr, date, exchange)"); .set_expr(string("--market"), "market(amount_expr, date, exchange)");
parent->HANDLER(display_total_) parent->HANDLER(display_total_)
.set_expr("market(total_expr, date, exchange)"); .set_expr(string("--market"), "market(total_expr, date, exchange)");
}); });
OPTION_(report_t, monthly, DO() { // -M OPTION_(report_t, monthly, DO() { // -M
parent->HANDLER(period_).on("monthly"); parent->HANDLER(period_).on(string("--monthly"), "monthly");
}); });
OPTION(report_t, no_total); OPTION(report_t, no_total);
@ -443,11 +562,12 @@ public:
OPTION__ OPTION__
(report_t, only_, (report_t, only_,
CTOR(report_t, only_) {} CTOR(report_t, only_) {}
virtual void on_with(const value_t& text) { virtual void on_with(const optional<string>& whence, const value_t& text) {
if (! handled) if (! handled)
option_t<report_t>::on_with(text); option_t<report_t>::on_with(whence, text);
else else
option_t<report_t>::on_with(string_value(string("(") + str() + ")&(" + option_t<report_t>::on_with(whence,
string_value(string("(") + str() + ")&(" +
text.as_string() + ")")); text.as_string() + ")"));
}); });
@ -456,7 +576,7 @@ public:
OPTION(report_t, payee_as_account); OPTION(report_t, payee_as_account);
OPTION_(report_t, pending, DO() { // -C OPTION_(report_t, pending, DO() { // -C
parent->HANDLER(limit_).on("pending"); parent->HANDLER(limit_).on(string("--pending"), "pending");
}); });
OPTION(report_t, percentage); // -% OPTION(report_t, percentage); // -%
@ -464,40 +584,46 @@ public:
OPTION__ OPTION__
(report_t, period_, // -p (report_t, period_, // -p
CTOR(report_t, period_) {} CTOR(report_t, period_) {}
virtual void on_with(const value_t& text) { virtual void on_with(const optional<string>& whence, const value_t& text) {
if (! handled) if (! handled)
option_t<report_t>::on_with(text); option_t<report_t>::on_with(whence, text);
else else
option_t<report_t>::on_with(string_value(text.as_string() + " " + str())); option_t<report_t>::on_with(whence,
string_value(text.as_string() + " " + str()));
}); });
OPTION(report_t, period_sort_); OPTION(report_t, period_sort_);
OPTION__(report_t, plot_amount_format_, CTOR(report_t, plot_amount_format_) { OPTION__(report_t, plot_amount_format_, CTOR(report_t, plot_amount_format_) {
on("%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_amount)))\n"); on(none,
"%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_amount)))\n");
}); });
OPTION__(report_t, plot_total_format_, CTOR(report_t, plot_total_format_) { OPTION__(report_t, plot_total_format_, CTOR(report_t, plot_total_format_) {
on("%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_total)))\n"); on(none,
"%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_total)))\n");
}); });
OPTION_(report_t, price, DO() { // -I OPTION_(report_t, price, DO() { // -I
parent->HANDLER(revalued).off(); parent->HANDLER(revalued).off();
parent->HANDLER(amount_).set_expr("price"); parent->HANDLER(amount_).set_expr(string("--price"), "price");
}); });
OPTION(report_t, price_exp_); // -Z OPTION(report_t, price_exp_); // -Z
OPTION__(report_t, prices_format_, CTOR(report_t, prices_format_) { OPTION__(report_t, prices_format_, CTOR(report_t, prices_format_) {
on("%-.9(date) %-8(account) %12(scrub(display_amount))\n"); on(none,
"%-.9(date) %-8(account) %12(scrub(display_amount))\n");
}); });
OPTION__(report_t, pricesdb_format_, CTOR(report_t, pricesdb_format_) { OPTION__(report_t, pricesdb_format_, CTOR(report_t, pricesdb_format_) {
on("P %[%Y/%m/%d %H:%M:%S] %A %t\n"); on(none,
"P %[%Y/%m/%d %H:%M:%S] %A %t\n");
}); });
OPTION__(report_t, print_format_, CTOR(report_t, print_format_) { OPTION__(report_t, print_format_, CTOR(report_t, print_format_) {
on("%(format_date(xact.date, \"%Y/%m/%d\"))" on(none,
"%(format_date(xact.date, \"%Y/%m/%d\"))"
"%(!effective & xact.effective_date ?" "%(!effective & xact.effective_date ?"
" \"=\" + format_date(xact.effective_date, \"%Y/%m/%d\") : \"\")" " \"=\" + format_date(xact.effective_date, \"%Y/%m/%d\") : \"\")"
"%(xact.cleared ? \" *\" : (xact.pending ? \" !\" : \"\"))" "%(xact.cleared ? \" *\" : (xact.pending ? \" !\" : \"\"))"
@ -521,22 +647,23 @@ public:
OPTION_(report_t, quantity, DO() { // -O OPTION_(report_t, quantity, DO() { // -O
parent->HANDLER(revalued).off(); parent->HANDLER(revalued).off();
parent->HANDLER(amount_).set_expr("amount"); parent->HANDLER(amount_).set_expr(string("--quantity"), "amount");
parent->HANDLER(total_).set_expr("total"); parent->HANDLER(total_).set_expr(string("--quantity"), "total");
}); });
OPTION_(report_t, quarterly, DO() { OPTION_(report_t, quarterly, DO() {
parent->HANDLER(period_).on("quarterly"); parent->HANDLER(period_).on(string("--quarterly"), "quarterly");
}); });
OPTION(report_t, raw); OPTION(report_t, raw);
OPTION_(report_t, real, DO() { // -R OPTION_(report_t, real, DO() { // -R
parent->HANDLER(limit_).on("real"); parent->HANDLER(limit_).on(string("--real"), "real");
}); });
OPTION__(report_t, register_format_, CTOR(report_t, register_format_) { OPTION__(report_t, register_format_, CTOR(report_t, register_format_) {
on("%(ansify_if(justify(date, date_width), green if color & date > today))" on(none,
"%(ansify_if(justify(date, date_width), green if color & date > today))"
" %(ansify_if(justify(truncated(payee, payee_width), payee_width), " " %(ansify_if(justify(truncated(payee, payee_width), payee_width), "
" bold if color & !cleared))" " bold if color & !cleared))"
" %(ansify_if(justify(truncated(account, account_width, abbrev_len), " " %(ansify_if(justify(truncated(account, account_width, abbrev_len), "
@ -567,12 +694,12 @@ public:
(report_t, revalued_total_, (report_t, revalued_total_,
expr_t expr; expr_t expr;
CTOR(report_t, revalued_total_) {} CTOR(report_t, revalued_total_) {}
void set_expr(const string& str) { void set_expr(const optional<string>& whence, const string& str) {
expr = str; expr = str;
on(str); on(whence, str);
} }
DO_(args) { DO_(args) {
set_expr(args[0].to_string()); set_expr(args[0].to_string(), args[1].to_string());
}); });
OPTION(report_t, seed_); OPTION(report_t, seed_);
@ -581,18 +708,18 @@ public:
OPTION(report_t, set_price_); OPTION(report_t, set_price_);
OPTION_(report_t, sort_, DO_(args) { // -S OPTION_(report_t, sort_, DO_(args) { // -S
on_with(args[0]); on_with(args[0].as_string(), args[1]);
parent->HANDLER(sort_xacts_).off(); parent->HANDLER(sort_xacts_).off();
parent->HANDLER(sort_all_).off(); parent->HANDLER(sort_all_).off();
}); });
OPTION_(report_t, sort_all_, DO_(args) { OPTION_(report_t, sort_all_, DO_(args) {
parent->HANDLER(sort_).on_with(args[0]); parent->HANDLER(sort_).on_with(string("--sort-all"), args[1]);
parent->HANDLER(sort_xacts_).off(); parent->HANDLER(sort_xacts_).off();
}); });
OPTION_(report_t, sort_xacts_, DO_(args) { OPTION_(report_t, sort_xacts_, DO_(args) {
parent->HANDLER(sort_).on_with(args[0]); parent->HANDLER(sort_).on_with(string("--sort-xacts"), args[1]);
parent->HANDLER(sort_all_).off(); parent->HANDLER(sort_all_).off();
}); });
@ -604,23 +731,24 @@ public:
(report_t, total_, // -T (report_t, total_, // -T
expr_t expr; expr_t expr;
CTOR(report_t, total_) { CTOR(report_t, total_) {
set_expr("total"); set_expr(none, "total");
} }
void set_expr(const string& str) { void set_expr(const optional<string>& whence, const string& str) {
expr = str; expr = str;
on(str); on(whence, str);
} }
DO_(args) { DO_(args) {
set_expr(args[0].to_string()); set_expr(args[0].to_string(), args[1].to_string());
}); });
OPTION_(report_t, total_data, DO() { // -J OPTION_(report_t, total_data, DO() { // -J
parent->HANDLER(format_).on_with(parent->HANDLER(plot_total_format_).value); parent->HANDLER(format_).on_with(string("--total-data"),
parent->HANDLER(plot_total_format_).value);
}); });
OPTION_(report_t, truncate_, DO() { OPTION_(report_t, truncate_, DO() {
#if 0 #if 0
string style(args[0].to_string()); string style(args[1].to_string());
if (style == "leading") if (style == "leading")
format_t::elision_style = format_t::TRUNCATE_LEADING; format_t::elision_style = format_t::TRUNCATE_LEADING;
else if (style == "middle") else if (style == "middle")
@ -637,54 +765,70 @@ public:
}); });
OPTION_(report_t, uncleared, DO() { // -U OPTION_(report_t, uncleared, DO() { // -U
parent->HANDLER(limit_).on("uncleared|pending"); parent->HANDLER(limit_).on(string("--uncleared"), "uncleared|pending");
}); });
OPTION_(report_t, unround, DO() { OPTION_(report_t, unround, DO() {
parent->HANDLER(amount_).set_expr("unrounded(amount)"); parent->HANDLER(amount_).set_expr(string("--uncleared"),
"unrounded(amount)");
}); });
OPTION_(report_t, weekly, DO() { // -W OPTION_(report_t, weekly, DO() { // -W
parent->HANDLER(period_).on("weekly"); parent->HANDLER(period_).on(string("--weekly"), "weekly");
}); });
OPTION_(report_t, wide, DO() { // -w OPTION_(report_t, wide, DO() { // -w
parent->HANDLER(date_width_).on_with(9L); parent->HANDLER(date_width_).on_with(string("--wide"), 9L);
parent->HANDLER(date_width_).specified = true; parent->HANDLER(date_width_).specified = true;
parent->HANDLER(payee_width_).on_with(35L); parent->HANDLER(payee_width_).on_with(string("--wide"), 35L);
parent->HANDLER(payee_width_).specified = true; parent->HANDLER(payee_width_).specified = true;
parent->HANDLER(account_width_).on_with(39L); parent->HANDLER(account_width_).on_with(string("--wide"), 39L);
parent->HANDLER(account_width_).specified = true; parent->HANDLER(account_width_).specified = true;
parent->HANDLER(amount_width_).on_with(22L); parent->HANDLER(amount_width_).on_with(string("--wide"), 22L);
parent->HANDLER(amount_width_).specified = true; parent->HANDLER(amount_width_).specified = true;
parent->HANDLER(total_width_).on_with(22L); parent->HANDLER(total_width_).on_with(string("--wide"), 22L);
parent->HANDLER(total_width_).specified = true; parent->HANDLER(total_width_).specified = true;
}); });
OPTION_(report_t, yearly, DO() { // -Y OPTION_(report_t, yearly, DO() { // -Y
parent->HANDLER(period_).on("yearly"); parent->HANDLER(period_).on(string("--yearly"), "yearly");
}); });
OPTION__(report_t, date_width_, OPTION__(report_t, date_width_,
bool specified; bool specified;
CTOR(report_t, date_width_) { on_with(9L); specified = false; } CTOR(report_t, date_width_) {
DO_(args) { value = args[0].to_long(); specified = true; }); on_with(none, 9L);
specified = false;
}
DO_(args) { value = args[1].to_long(); specified = true; });
OPTION__(report_t, payee_width_, OPTION__(report_t, payee_width_,
bool specified; bool specified;
CTOR(report_t, payee_width_) { on_with(20L); specified = false; } CTOR(report_t, payee_width_) {
DO_(args) { value = args[0].to_long(); specified = true; }); on_with(none, 20L);
specified = false;
}
DO_(args) { value = args[1].to_long(); specified = true; });
OPTION__(report_t, account_width_, OPTION__(report_t, account_width_,
bool specified; bool specified;
CTOR(report_t, account_width_) { on_with(23L); specified = false; } CTOR(report_t, account_width_) {
DO_(args) { value = args[0].to_long(); specified = true; }); on_with(none, 23L);
specified = false;
}
DO_(args) { value = args[1].to_long(); specified = true; });
OPTION__(report_t, amount_width_, OPTION__(report_t, amount_width_,
bool specified; bool specified;
CTOR(report_t, amount_width_) { on_with(12L); specified = false; } CTOR(report_t, amount_width_) {
DO_(args) { value = args[0].to_long(); specified = true; }); on_with(none, 12L);
specified = false;
}
DO_(args) { value = args[1].to_long(); specified = true; });
OPTION__(report_t, total_width_, OPTION__(report_t, total_width_,
bool specified; bool specified;
CTOR(report_t, total_width_) { on_with(12L); specified = false; } CTOR(report_t, total_width_) {
DO_(args) { value = args[0].to_long(); specified = true; }); on_with(none, 12L);
specified = false;
}
DO_(args) { value = args[1].to_long(); specified = true; });
}; };
} // namespace ledger } // namespace ledger

View file

@ -71,9 +71,9 @@ session_t::session_t()
TRACE_CTOR(session_t, ""); TRACE_CTOR(session_t, "");
if (const char * home_var = std::getenv("HOME")) if (const char * home_var = std::getenv("HOME"))
HANDLER(price_db_).on((path(home_var) / ".pricedb").string()); HANDLER(price_db_).on(none, (path(home_var) / ".pricedb").string());
else else
HANDLER(price_db_).on(path("./.pricedb").string()); HANDLER(price_db_).on(none, path("./.pricedb").string());
// Add time commodity conversions, so that timelog's may be parsed // Add time commodity conversions, so that timelog's may be parsed
// in terms of seconds, but reported as minutes or hours. // in terms of seconds, but reported as minutes or hours.

View file

@ -108,6 +108,17 @@ public:
return CURRENT_DATE(); return CURRENT_DATE();
} }
void report_options(std::ostream& out)
{
HANDLER(account_).report(out);
HANDLER(download).report(out);
HANDLER(leeway_).report(out);
HANDLER(file_).report(out);
HANDLER(input_date_format_).report(out);
HANDLER(price_db_).report(out);
HANDLER(strict).report(out);
}
option_t<session_t> * lookup_option(const char * p); option_t<session_t> * lookup_option(const char * p);
virtual expr_t::ptr_op_t lookup(const string& name); virtual expr_t::ptr_op_t lookup(const string& name);
@ -123,7 +134,7 @@ public:
(session_t, leeway_, (session_t, leeway_,
CTOR(session_t, leeway_) { value = 24L * 3600L; } CTOR(session_t, leeway_) { value = 24L * 3600L; }
DO_(args) { DO_(args) {
value = args[0].to_long() * 60L; value = args[1].to_long() * 60L;
}); });
OPTION__ OPTION__
@ -131,12 +142,12 @@ public:
std::list<path> data_files; std::list<path> data_files;
CTOR(session_t, file_) {} CTOR(session_t, file_) {}
DO_(args) { DO_(args) {
assert(args.size() == 1); assert(args.size() == 2);
if (parent->flush_on_next_data_file) { if (parent->flush_on_next_data_file) {
data_files.clear(); data_files.clear();
parent->flush_on_next_data_file = false; parent->flush_on_next_data_file = false;
} }
data_files.push_back(args[0].as_string()); data_files.push_back(args[1].as_string());
}); });
OPTION(session_t, input_date_format_); OPTION(session_t, input_date_format_);

View file

@ -535,7 +535,7 @@ void instance_t::option_directive(char * line)
if (p) if (p)
*p++ = '\0'; *p++ = '\0';
} }
process_option(line + 2, session_scope, p, line); process_option(pathname.string(), line + 2, session_scope, p, line);
} }
void instance_t::automated_xact_directive(char * line) void instance_t::automated_xact_directive(char * line)