diff options
Diffstat (limited to 'src/report.cc')
-rw-r--r-- | src/report.cc | 825 |
1 files changed, 429 insertions, 396 deletions
diff --git a/src/report.cc b/src/report.cc index 4302187e..e98596a3 100644 --- a/src/report.cc +++ b/src/report.cc @@ -47,6 +47,7 @@ #include "convert.h" #include "xml.h" #include "emacs.h" +#include "org.h" namespace ledger { @@ -76,7 +77,7 @@ void report_t::normalize_options(const string& verb) } item_t::use_effective_date = (HANDLED(effective) && - ! HANDLED(actual_dates)); + ! HANDLED(actual_dates)); commodity_pool_t::current_pool->keep_base = HANDLED(base); commodity_pool_t::current_pool->get_quotes = session.HANDLED(download); @@ -96,7 +97,7 @@ void report_t::normalize_options(const string& verb) set_datetime_format(HANDLER(datetime_format_).str().c_str()); if (HANDLED(start_of_week_)) { if (optional<date_time::weekdays> weekday = - string_to_day_of_week(HANDLER(start_of_week_).str())) + string_to_day_of_week(HANDLER(start_of_week_).str())) start_of_week = *weekday; } @@ -106,24 +107,24 @@ void report_t::normalize_options(const string& verb) if (! HANDLED(meta_width_)) { string::size_type i = HANDLER(meta_).str().find(':'); if (i != string::npos) { - HANDLED(meta_width_).on_with - (string("?normalize"), - lexical_cast<long>(string(HANDLER(meta_).str(), i + 1))); - HANDLED(meta_).on(string("?normalize"), - string(HANDLER(meta_).str(), 0, i)); + HANDLED(meta_width_).on_with + (string("?normalize"), + lexical_cast<long>(string(HANDLER(meta_).str(), i + 1))); + HANDLED(meta_).on(string("?normalize"), + string(HANDLER(meta_).str(), 0, i)); } } if (HANDLED(meta_width_)) { HANDLER(prepend_format_).on - (string("?normalize"), - string("%(justify(truncated(tag(\"") + - HANDLER(meta_).str() + "\"), " + - HANDLED(meta_width_).value.to_string() + " - 1), " + - HANDLED(meta_width_).value.to_string() + "))"); + (string("?normalize"), + string("%(justify(truncated(tag(\"") + + HANDLER(meta_).str() + "\"), " + + HANDLED(meta_width_).value.to_string() + " - 1), " + + HANDLED(meta_width_).value.to_string() + "))"); meta_width = HANDLED(meta_width_).value.to_long(); } else { HANDLER(prepend_format_).on(string("?normalize"), string("%(tag(\"") + - HANDLER(meta_).str() + "\"))"); + HANDLER(meta_).str() + "\"))"); } } if (! HANDLED(prepend_width_)) @@ -137,14 +138,6 @@ void report_t::normalize_options(const string& verb) HANDLER(equity).on_only(string("?normalize")); } - if (verb == "print") - HANDLER(limit_).on(string("?normalize"), "actual"); - - if (! HANDLED(empty)) - HANDLER(display_).on(string("?normalize"), - string("(post?(display_amount|account=\"") + - _("<Revalued>") + "\"):display_total)"); - if (verb[0] != 'b' && verb[0] != 'r') HANDLER(base).on_only(string("?normalize")); @@ -153,26 +146,8 @@ void report_t::normalize_options(const string& verb) // using -b or -e). Then, if no _duration_ was specified (such as monthly), // then ignore the period since the begin/end are the only interesting // details. - if (HANDLED(period_)) { - date_interval_t interval(HANDLER(period_).str()); - - optional<date_t> begin = interval.begin(session.current_year); - optional<date_t> end = interval.end(session.current_year); - - if (! HANDLED(begin_) && begin) { - string predicate = "date>=[" + to_iso_extended_string(*begin) + "]"; - HANDLER(limit_).on(string("?normalize"), predicate); - } - if (! HANDLED(end_) && end) { - string predicate = "date<[" + to_iso_extended_string(*end) + "]"; - HANDLER(limit_).on(string("?normalize"), predicate); - } - - if (! interval.duration) - HANDLER(period_).off(); - else if (! HANDLED(sort_all_)) - HANDLER(sort_xacts_).on_only(string("?normalize")); - } + if (HANDLED(period_)) + normalize_period(); // If -j or -J were specified, set the appropriate format string now so as // to avoid option ordering issues were we to have done it during the @@ -191,7 +166,7 @@ void report_t::normalize_options(const string& verb) if (HANDLED(exchange_) && HANDLER(exchange_).str().find('=') != string::npos) { value_t(0L).exchange_commodities(HANDLER(exchange_).str(), true, - terminus); + terminus); } long cols = 0; @@ -210,22 +185,22 @@ void report_t::normalize_options(const string& verb) if (! HANDLER(date_width_).specified) HANDLER(date_width_) - .on_with(none, static_cast<long>(format_date(CURRENT_DATE(), - FMT_PRINTED).length())); + .on_with(none, static_cast<long>(format_date(CURRENT_DATE(), + FMT_PRINTED).length())); long date_width = HANDLER(date_width_).value.to_long(); long payee_width = (HANDLER(payee_width_).specified ? - HANDLER(payee_width_).value.to_long() : - int(double(cols) * 0.263157)); + HANDLER(payee_width_).value.to_long() : + int(double(cols) * 0.263157)); long account_width = (HANDLER(account_width_).specified ? - HANDLER(account_width_).value.to_long() : - int(double(cols) * 0.302631)); + HANDLER(account_width_).value.to_long() : + int(double(cols) * 0.302631)); long amount_width = (HANDLER(amount_width_).specified ? - HANDLER(amount_width_).value.to_long() : - int(double(cols) * 0.157894)); + HANDLER(amount_width_).value.to_long() : + int(double(cols) * 0.157894)); long total_width = (HANDLER(total_width_).specified ? - HANDLER(total_width_).value.to_long() : - amount_width); + HANDLER(total_width_).value.to_long() : + amount_width); DEBUG("auto.columns", "date_width = " << date_width); DEBUG("auto.columns", "payee_width = " << payee_width); @@ -234,16 +209,16 @@ void report_t::normalize_options(const string& verb) DEBUG("auto.columns", "total_width = " << total_width); if (! HANDLER(date_width_).specified && - ! HANDLER(payee_width_).specified && - ! HANDLER(account_width_).specified && - ! HANDLER(amount_width_).specified && - ! HANDLER(total_width_).specified) { + ! HANDLER(payee_width_).specified && + ! HANDLER(account_width_).specified && + ! HANDLER(amount_width_).specified && + ! HANDLER(total_width_).specified) { long total = (4 /* the spaces between */ + date_width + payee_width + - account_width + amount_width + total_width); + account_width + amount_width + total_width); if (total > cols) { - DEBUG("auto.columns", "adjusting account down"); - account_width -= total - cols; - DEBUG("auto.columns", "account_width now = " << account_width); + DEBUG("auto.columns", "adjusting account down"); + account_width -= total - cols; + DEBUG("auto.columns", "account_width now = " << account_width); } } @@ -262,24 +237,57 @@ void report_t::normalize_options(const string& verb) } } +void report_t::normalize_period() +{ + date_interval_t interval(HANDLER(period_).str()); + + optional<date_t> begin = interval.begin(); + optional<date_t> end = interval.end(); + + if (! HANDLED(begin_) && begin) { + string predicate = "date>=[" + to_iso_extended_string(*begin) + "]"; + HANDLER(limit_).on(string("?normalize"), predicate); + } + if (! HANDLED(end_) && end) { + string predicate = "date<[" + to_iso_extended_string(*end) + "]"; + HANDLER(limit_).on(string("?normalize"), predicate); + } + + if (! interval.duration) + HANDLER(period_).off(); + else if (! HANDLED(sort_all_)) + HANDLER(sort_xacts_).on_only(string("?normalize")); +} + void report_t::parse_query_args(const value_t& args, const string& whence) { query_t query(args, what_to_keep()); - if (query) { - HANDLER(limit_).on(whence, query.text()); - DEBUG("report.predicate", - "Predicate = " << HANDLER(limit_).str()); + if (query.has_query(query_t::QUERY_LIMIT)) { + HANDLER(limit_).on(whence, query.get_query(query_t::QUERY_LIMIT)); + DEBUG("report.predicate", "Limit predicate = " << HANDLER(limit_).str()); } - if (query.tokens_remaining()) { - query.parse_again(); - if (query) { - HANDLER(display_).on(whence, query.text()); + if (query.has_query(query_t::QUERY_ONLY)) { + HANDLER(only_).on(whence, query.get_query(query_t::QUERY_ONLY)); + DEBUG("report.predicate", "Only predicate = " << HANDLER(only_).str()); + } - DEBUG("report.predicate", - "Display predicate = " << HANDLER(display_).str()); - } + if (query.has_query(query_t::QUERY_SHOW)) { + HANDLER(display_).on(whence, query.get_query(query_t::QUERY_SHOW)); + DEBUG("report.predicate", "Display predicate = " << HANDLER(display_).str()); + } + + if (query.has_query(query_t::QUERY_BOLD)) { + HANDLER(bold_if_).set_expr(whence, query.get_query(query_t::QUERY_BOLD)); + DEBUG("report.predicate", "Bolding predicate = " << HANDLER(bold_if_).str()); + } + + if (query.has_query(query_t::QUERY_FOR)) { + HANDLER(period_).on(whence, query.get_query(query_t::QUERY_FOR)); + DEBUG("report.predicate", "Report period = " << HANDLER(period_).str()); + + normalize_period(); // it needs normalization } } @@ -287,7 +295,7 @@ namespace { struct posts_flusher { post_handler_ptr handler; - report_t& report; + report_t& report; posts_flusher(post_handler_ptr _handler, report_t& _report) : handler(_handler), report(_report) {} @@ -318,8 +326,6 @@ void report_t::posts_report(post_handler_ptr handler) void report_t::generate_report(post_handler_ptr handler) { - HANDLER(limit_).on(string("#generate"), "actual"); - handler = chain_handlers(handler, *this); generate_posts_iterator walker @@ -345,7 +351,7 @@ namespace { struct accounts_title_printer { acct_handler_ptr handler; - report_t& report; + report_t& report; accounts_title_printer(acct_handler_ptr _handler, report_t& _report) : handler(_handler), report(_report) {} @@ -353,9 +359,9 @@ namespace { void operator()(const value_t& val) { if (! report.HANDLED(no_titles)) { - std::ostringstream buf; - val.print(buf); - handler->title(buf.str()); + std::ostringstream buf; + val.print(buf); + handler->title(buf.str()); } } }; @@ -363,7 +369,7 @@ namespace { struct accounts_flusher { acct_handler_ptr handler; - report_t& report; + report_t& report; accounts_flusher(acct_handler_ptr _handler, report_t& _report) : handler(_handler), report(_report) {} @@ -378,23 +384,23 @@ namespace { scoped_ptr<accounts_iterator> iter; if (! report.HANDLED(sort_)) { - iter.reset(new basic_accounts_iterator(*report.session.journal->master)); + iter.reset(new basic_accounts_iterator(*report.session.journal->master)); } else { - expr_t sort_expr(report.HANDLER(sort_).str()); - sort_expr.set_context(&report); - iter.reset(new sorted_accounts_iterator(*report.session.journal->master, - sort_expr, report.HANDLED(flat))); + expr_t sort_expr(report.HANDLER(sort_).str()); + sort_expr.set_context(&report); + iter.reset(new sorted_accounts_iterator(*report.session.journal->master, + sort_expr, report.HANDLED(flat))); } if (report.HANDLED(display_)) { - DEBUG("report.predicate", - "Display predicate = " << report.HANDLER(display_).str()); - pass_down_accounts(handler, *iter.get(), - predicate_t(report.HANDLER(display_).str(), - report.what_to_keep()), - report); + DEBUG("report.predicate", + "Display predicate = " << report.HANDLER(display_).str()); + pass_down_accounts(handler, *iter.get(), + predicate_t(report.HANDLER(display_).str(), + report.what_to_keep()), + report); } else { - pass_down_accounts(handler, *iter.get()); + pass_down_accounts(handler, *iter.get()); } report.session.journal->clear_xdata(); @@ -406,7 +412,7 @@ void report_t::accounts_report(acct_handler_ptr handler) { post_handler_ptr chain = chain_post_handlers(post_handler_ptr(new ignore_posts), *this, - /* for_accounts_report= */ true); + /* for_accounts_report= */ true); if (HANDLED(group_by_)) { std::auto_ptr<post_splitter> splitter(new post_splitter(chain, *this, HANDLER(group_by_).expr)); @@ -438,6 +444,37 @@ void report_t::commodities_report(post_handler_ptr handler) session.journal->clear_xdata(); } +value_t report_t::display_value(const value_t& val) +{ + value_t temp(val.strip_annotations(what_to_keep())); + if (HANDLED(base)) + return temp; + else + return temp.unreduced(); +} + +namespace { + value_t top_amount(const value_t& val) + { + switch (val.type()) { + case value_t::BALANCE: + return (*val.as_balance().amounts.begin()).second; + + case value_t::SEQUENCE: { + return top_amount(*val.as_sequence().begin()); + } + + default: + return val; + } + } +} + +value_t report_t::fn_top_amount(call_scope_t& args) +{ + return top_amount(args[0]); +} + value_t report_t::fn_amount_expr(call_scope_t& scope) { return HANDLER(amount_).expr.calc(scope); @@ -458,44 +495,45 @@ value_t report_t::fn_display_total(call_scope_t& scope) return HANDLER(display_total_).expr.calc(scope); } -value_t report_t::fn_market(call_scope_t& scope) +value_t report_t::fn_should_bold(call_scope_t& scope) +{ + if (HANDLED(bold_if_)) + return HANDLER(bold_if_).expr.calc(scope); + else + return false; +} + +value_t report_t::fn_market(call_scope_t& args) { - interactive_t args(scope, "a&ts"); - - value_t result; - optional<datetime_t> moment = (args.has(1) ? - args.get<datetime_t>(1) : - optional<datetime_t>()); - if (args.has(2)) - result = args.value_at(0).exchange_commodities(args.get<string>(2), - /* add_prices= */ false, - moment); + optional<datetime_t> moment = (args.has<datetime_t>(1) ? + args.get<datetime_t>(1) : + optional<datetime_t>()); + value_t result; + if (args.has<string>(2)) + result = args[0].exchange_commodities(args.get<string>(2), + /* add_prices= */ false, moment); else - result = args.value_at(0).value(true, moment); + result = args[0].value(moment); if (! result.is_null()) return result; - return args.value_at(0); + return args[0]; } -value_t report_t::fn_get_at(call_scope_t& scope) +value_t report_t::fn_get_at(call_scope_t& args) { - interactive_t args(scope, "Sl"); - - DEBUG("report.get_at", "get_at[0] = " << args.value_at(0)); - DEBUG("report.get_at", "get_at[1] = " << args.value_at(1)); - - if (args.get<long>(1) == 0) { - if (! args.value_at(0).is_sequence()) - return args.value_at(0); + std::size_t index = static_cast<std::size_t>(args.get<long>(1)); + if (index == 0) { + if (! args[0].is_sequence()) + return args[0]; } else { - if (! args.value_at(0).is_sequence()) + if (! args[0].is_sequence()) throw_(std::runtime_error, - _("Attempting to get argument at index %1 from %2") - << args.get<long>(1) << args.value_at(0).label()); + _("Attempting to get argument at index %1 from %2") + << index << args[0].label()); } - return args.get<const value_t::sequence_t&>(0)[args.get<long>(1)]; + return args[0].as_sequence()[index]; } value_t report_t::fn_is_seq(call_scope_t& scope) @@ -510,7 +548,7 @@ value_t report_t::fn_strip(call_scope_t& args) value_t report_t::fn_trim(call_scope_t& args) { - string temp(args.value().to_string()); + string temp(args.value().to_string()); scoped_array<char> buf(new char[temp.length() + 1]); std::strcpy(buf.get(), temp.c_str()); @@ -534,32 +572,25 @@ value_t report_t::fn_trim(call_scope_t& args) } } -value_t report_t::fn_print(call_scope_t& args) +value_t report_t::fn_format(call_scope_t& args) { - std::ostream& out(output_stream); - bool first = true; - for (call_scope_t::iterator i = args.begin(); i != args.end(); i++) { - if (first) - first = false; - else - out << ' '; - (*i).print(out); - } - return true; + format_t format(args.get<string>(0)); + std::ostringstream out; + out << format(args); + return string_value(out.str()); } -value_t report_t::scrub(value_t val) +value_t report_t::fn_print(call_scope_t& args) { - value_t temp(val.strip_annotations(what_to_keep())); - if (HANDLED(base)) - return temp; - else - return temp.unreduced(); + for (std::size_t i = 0; i < args.size(); i++) + args[i].print(output_stream); + static_cast<std::ostream&>(output_stream) << std::endl; + return true; } value_t report_t::fn_scrub(call_scope_t& args) { - return scrub(args.value()); + return display_value(args.value()); } value_t report_t::fn_rounded(call_scope_t& args) @@ -572,52 +603,52 @@ value_t report_t::fn_unrounded(call_scope_t& args) return args.value().unrounded(); } -value_t report_t::fn_quantity(call_scope_t& scope) +value_t report_t::fn_quantity(call_scope_t& args) { - interactive_t args(scope, "a"); return args.get<amount_t>(0).number(); } -value_t report_t::fn_floor(call_scope_t& scope) +value_t report_t::fn_floor(call_scope_t& args) { - interactive_t args(scope, "v"); - return args.value_at(0).floored(); + return args[0].floored(); } -value_t report_t::fn_abs(call_scope_t& scope) +value_t report_t::fn_abs(call_scope_t& args) { - interactive_t args(scope, "v"); - return args.value_at(0).abs(); + return args[0].abs(); } -value_t report_t::fn_truncated(call_scope_t& scope) +value_t report_t::fn_truncated(call_scope_t& args) { - interactive_t args(scope, "v&ll"); return string_value(format_t::truncate - (args.get<string>(0), - args.has(1) && args.get<int>(1) > 0 ? args.get<int>(1) : 0, - args.has(2) ? args.get<int>(2) : 0)); + (args.get<string>(0), + args.has<int>(1) && + args.get<int>(1) > 0 ? args.get<int>(1) : 0, + args.has<int>(2) ? args.get<int>(2) : 0)); } -value_t report_t::fn_justify(call_scope_t& scope) +value_t report_t::fn_justify(call_scope_t& args) { - interactive_t args(scope, "vl&lbb"); + uint_least8_t flags(AMOUNT_PRINT_ELIDE_COMMODITY_QUOTES); + + if (args.has<bool>(3) && args.get<bool>(3)) + flags |= AMOUNT_PRINT_RIGHT_JUSTIFY; + if (args.has<bool>(4) && args.get<bool>(4)) + flags |= AMOUNT_PRINT_COLORIZE; + std::ostringstream out; - args.value_at(0) - .print(out, args.get<int>(1), - args.has(2) ? args.get<int>(2) : -1, - args.has(3) ? args.get<bool>(3) : false, - args.has(4) ? args.get<bool>(4) : false); + args[0].print(out, args.get<int>(1), + args.has<int>(2) ? args.get<int>(2) : -1, flags); + return string_value(out.str()); } -value_t report_t::fn_quoted(call_scope_t& scope) +value_t report_t::fn_quoted(call_scope_t& args) { - interactive_t args(scope, "v"); std::ostringstream out; out << '"'; - foreach (const char ch, args.value_at(0).to_string()) { + foreach (const char ch, args.get<string>(0)) { if (ch == '"') out << "\\\""; else @@ -628,9 +659,8 @@ value_t report_t::fn_quoted(call_scope_t& scope) return string_value(out.str()); } -value_t report_t::fn_join(call_scope_t& scope) +value_t report_t::fn_join(call_scope_t& args) { - interactive_t args(scope, "s"); std::ostringstream out; foreach (const char ch, args.get<string>(0)) { @@ -642,149 +672,130 @@ value_t report_t::fn_join(call_scope_t& scope) return string_value(out.str()); } -value_t report_t::fn_format_date(call_scope_t& scope) +value_t report_t::fn_format_date(call_scope_t& args) { - interactive_t args(scope, "d&s"); - if (args.has(1)) + if (args.has<string>(1)) return string_value(format_date(args.get<date_t>(0), FMT_CUSTOM, - args.get<string>(1).c_str())); + args.get<string>(1).c_str())); else return string_value(format_date(args.get<date_t>(0), FMT_PRINTED)); } -value_t report_t::fn_ansify_if(call_scope_t& scope) +value_t report_t::fn_ansify_if(call_scope_t& args) { - interactive_t args(scope, "v&s"); - - if (args.has(1)) { + if (args.has<string>(1)) { string color = args.get<string>(1); std::ostringstream buf; - if (color == "black") buf << "\033[30m"; - else if (color == "red") buf << "\033[31m"; - else if (color == "green") buf << "\033[32m"; - else if (color == "yellow") buf << "\033[33m"; - else if (color == "blue") buf << "\033[34m"; + if (color == "black") buf << "\033[30m"; + else if (color == "red") buf << "\033[31m"; + else if (color == "green") buf << "\033[32m"; + else if (color == "yellow") buf << "\033[33m"; + else if (color == "blue") buf << "\033[34m"; else if (color == "magenta") buf << "\033[35m"; - else if (color == "cyan") buf << "\033[36m"; - else if (color == "white") buf << "\033[37m"; - else if (color == "bold") buf << "\033[1m"; + else if (color == "cyan") buf << "\033[36m"; + else if (color == "white") buf << "\033[37m"; + else if (color == "bold") buf << "\033[1m"; else if (color == "underline") buf << "\033[4m"; - else if (color == "blink") buf << "\033[5m"; - buf << args.value_at(0); + else if (color == "blink") buf << "\033[5m"; + buf << args[0]; buf << "\033[0m"; return string_value(buf.str()); - } else { - return args.value_at(0); } + return args[0]; } -value_t report_t::fn_percent(call_scope_t& scope) +value_t report_t::fn_percent(call_scope_t& args) { - interactive_t args(scope, "aa"); return (amount_t("100.00%") * - (args.get<amount_t>(0) / args.get<amount_t>(1)).number()); + (args.get<amount_t>(0) / args.get<amount_t>(1)).number()); } -value_t report_t::fn_price(call_scope_t& scope) +value_t report_t::fn_price(call_scope_t& args) { - interactive_t args(scope, "v"); - return args.value_at(0).price(); + return args[0].price(); } -value_t report_t::fn_lot_date(call_scope_t& scope) +value_t report_t::fn_commodity(call_scope_t& args) { - interactive_t args(scope, "v"); - if (args.value_at(0).has_annotation()) { - const annotation_t& details(args.value_at(0).annotation()); + return string_value(args.get<amount_t>(0).commodity().symbol()); +} + +value_t report_t::fn_lot_date(call_scope_t& args) +{ + if (args[0].has_annotation()) { + const annotation_t& details(args[0].annotation()); if (details.date) return *details.date; } return NULL_VALUE; } -value_t report_t::fn_lot_price(call_scope_t& scope) +value_t report_t::fn_lot_price(call_scope_t& args) { - interactive_t args(scope, "v"); - if (args.value_at(0).has_annotation()) { - const annotation_t& details(args.value_at(0).annotation()); + if (args[0].has_annotation()) { + const annotation_t& details(args[0].annotation()); if (details.price) return *details.price; } return NULL_VALUE; } -value_t report_t::fn_lot_tag(call_scope_t& scope) +value_t report_t::fn_lot_tag(call_scope_t& args) { - interactive_t args(scope, "v"); - if (args.value_at(0).has_annotation()) { - const annotation_t& details(args.value_at(0).annotation()); + if (args[0].has_annotation()) { + const annotation_t& details(args[0].annotation()); if (details.tag) return string_value(*details.tag); } return NULL_VALUE; } -value_t report_t::fn_to_boolean(call_scope_t& scope) +value_t report_t::fn_to_boolean(call_scope_t& args) { - interactive_t args(scope, "v"); - args.value_at(0).in_place_cast(value_t::BOOLEAN); - return args.value_at(0); + return args.get<bool>(0); } -value_t report_t::fn_to_int(call_scope_t& scope) +value_t report_t::fn_to_int(call_scope_t& args) { - interactive_t args(scope, "v"); - args.value_at(0).in_place_cast(value_t::INTEGER); - return args.value_at(0); + // This method is not called fn_to_long, because that would be + // confusing to users who don't care about the distinction between + // integer and long. + return args.get<long>(0); } -value_t report_t::fn_to_datetime(call_scope_t& scope) +value_t report_t::fn_to_datetime(call_scope_t& args) { - interactive_t args(scope, "v"); - args.value_at(0).in_place_cast(value_t::DATETIME); - return args.value_at(0); + return args.get<datetime_t>(0); } -value_t report_t::fn_to_date(call_scope_t& scope) +value_t report_t::fn_to_date(call_scope_t& args) { - interactive_t args(scope, "v"); - args.value_at(0).in_place_cast(value_t::DATE); - return args.value_at(0); + return args.get<date_t>(0); } -value_t report_t::fn_to_amount(call_scope_t& scope) +value_t report_t::fn_to_amount(call_scope_t& args) { - interactive_t args(scope, "v"); - args.value_at(0).in_place_cast(value_t::AMOUNT); - return args.value_at(0); + return args.get<amount_t>(0); } -value_t report_t::fn_to_balance(call_scope_t& scope) +value_t report_t::fn_to_balance(call_scope_t& args) { - interactive_t args(scope, "v"); - args.value_at(0).in_place_cast(value_t::BALANCE); - return args.value_at(0); + return args.get<balance_t>(0); } -value_t report_t::fn_to_string(call_scope_t& scope) +value_t report_t::fn_to_string(call_scope_t& args) { - interactive_t args(scope, "v"); - args.value_at(0).in_place_cast(value_t::STRING); - return args.value_at(0); + return string_value(args.get<string>(0)); } -value_t report_t::fn_to_mask(call_scope_t& scope) +value_t report_t::fn_to_mask(call_scope_t& args) { - interactive_t args(scope, "v"); - args.value_at(0).in_place_cast(value_t::MASK); - return args.value_at(0); + return args.get<mask_t>(0); } -value_t report_t::fn_to_sequence(call_scope_t& scope) +value_t report_t::fn_to_sequence(call_scope_t& args) { - interactive_t args(scope, "v"); - args.value_at(0).in_place_cast(value_t::SEQUENCE); - return args.value_at(0); + return args[0].to_sequence(); } namespace { @@ -836,21 +847,19 @@ value_t report_t::reload_command(call_scope_t&) return true; } -value_t report_t::echo_command(call_scope_t& scope) +value_t report_t::echo_command(call_scope_t& args) { - interactive_t args(scope, "s"); std::ostream& out(output_stream); out << args.get<string>(0) << std::endl; return true; } -value_t report_t::pricemap_command(call_scope_t& scope) +value_t report_t::pricemap_command(call_scope_t& args) { - interactive_t args(scope, "&s"); std::ostream& out(output_stream); commodity_pool_t::current_pool->print_pricemap - (out, what_to_keep(), args.has(0) ? + (out, what_to_keep(), args.has<string>(0) ? optional<datetime_t>(datetime_t(parse_date(args.get<string>(0)))) : none); return true; @@ -944,6 +953,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT(base); else OPT_ALT(basis, cost); else OPT_(begin_); + else OPT(bold_if_); else OPT(budget); else OPT(by_payee); break; @@ -992,12 +1002,14 @@ option_t<report_t> * report_t::lookup_option(const char * p) OPT(gain); else OPT(group_by_); else OPT(group_title_format_); + else OPT(generated); break; case 'h': OPT(head_); break; case 'i': OPT(invert); + else OPT(inject_); break; case 'j': OPT_CH(amount_data); @@ -1045,7 +1057,6 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT(payee_width_); else OPT(prepend_format_); else OPT(prepend_width_); - else OPT(print_virtual); break; case 'q': OPT(quantity); @@ -1084,7 +1095,6 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT(unrealized_gains_); else OPT(unrealized_losses_); else OPT(unround); - else OPT(unsorted); break; case 'w': OPT(weekly); @@ -1099,13 +1109,13 @@ option_t<report_t> * report_t::lookup_option(const char * p) } void report_t::define(const symbol_t::kind_t kind, const string& name, - expr_t::ptr_op_t def) + expr_t::ptr_op_t def) { session.define(kind, name, def); } expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, - const string& name) + const string& name) { if (expr_t::ptr_op_t def = session.lookup(kind, name)) return def; @@ -1119,203 +1129,216 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, switch (*p) { case 'd': case 'm': - return MAKE_FUNCTOR(report_t::fn_now); + return MAKE_FUNCTOR(report_t::fn_now); case 'P': - return MAKE_FUNCTOR(report_t::fn_market); + return MAKE_FUNCTOR(report_t::fn_market); case 't': - return MAKE_FUNCTOR(report_t::fn_display_amount); + return MAKE_FUNCTOR(report_t::fn_display_amount); case 'T': - return MAKE_FUNCTOR(report_t::fn_display_total); + return MAKE_FUNCTOR(report_t::fn_display_total); case 'U': - return MAKE_FUNCTOR(report_t::fn_abs); + return MAKE_FUNCTOR(report_t::fn_abs); case 'S': - return MAKE_FUNCTOR(report_t::fn_strip); + return MAKE_FUNCTOR(report_t::fn_strip); case 'i': - throw_(std::runtime_error, - _("The i value expression variable is no longer supported")); + throw_(std::runtime_error, + _("The i value expression variable is no longer supported")); case 'A': - throw_(std::runtime_error, - _("The A value expression variable is no longer supported")); + throw_(std::runtime_error, + _("The A value expression variable is no longer supported")); case 'v': case 'V': - throw_(std::runtime_error, - _("The V and v value expression variables are no longer supported")); + throw_(std::runtime_error, + _("The V and v value expression variables are no longer supported")); case 'I': case 'B': - throw_(std::runtime_error, - _("The I and B value expression variables are no longer supported")); + throw_(std::runtime_error, + _("The I and B value expression variables are no longer supported")); case 'g': case 'G': - throw_(std::runtime_error, - _("The G and g value expression variables are no longer supported")); + throw_(std::runtime_error, + _("The G and g value expression variables are no longer supported")); default: - return NULL; + return NULL; } } switch (*p) { case 'a': if (is_eq(p, "amount_expr")) - return MAKE_FUNCTOR(report_t::fn_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); + return MAKE_FUNCTOR(report_t::fn_ansify_if); else if (is_eq(p, "abs")) - return MAKE_FUNCTOR(report_t::fn_abs); + return MAKE_FUNCTOR(report_t::fn_abs); break; case 'b': if (is_eq(p, "black")) - return WRAP_FUNCTOR(fn_black); + return WRAP_FUNCTOR(fn_black); else if (is_eq(p, "blink")) - return WRAP_FUNCTOR(fn_blink); + return WRAP_FUNCTOR(fn_blink); else if (is_eq(p, "blue")) - return WRAP_FUNCTOR(fn_blue); + return WRAP_FUNCTOR(fn_blue); else if (is_eq(p, "bold")) - return WRAP_FUNCTOR(fn_bold); + return WRAP_FUNCTOR(fn_bold); break; case 'c': if (is_eq(p, "cyan")) - return WRAP_FUNCTOR(fn_cyan); + return WRAP_FUNCTOR(fn_cyan); + else if (is_eq(p, "commodity")) + return MAKE_FUNCTOR(report_t::fn_commodity); break; case 'd': if (is_eq(p, "display_amount")) - return MAKE_FUNCTOR(report_t::fn_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); + return MAKE_FUNCTOR(report_t::fn_display_total); else if (is_eq(p, "date")) - return MAKE_FUNCTOR(report_t::fn_now); + return MAKE_FUNCTOR(report_t::fn_now); break; case 'f': if (is_eq(p, "format_date")) - return MAKE_FUNCTOR(report_t::fn_format_date); + return MAKE_FUNCTOR(report_t::fn_format_date); + else if (is_eq(p, "format")) + return MAKE_FUNCTOR(report_t::fn_format); else if (is_eq(p, "floor")) - return MAKE_FUNCTOR(report_t::fn_floor); + return MAKE_FUNCTOR(report_t::fn_floor); break; case 'g': if (is_eq(p, "get_at")) - return MAKE_FUNCTOR(report_t::fn_get_at); + return MAKE_FUNCTOR(report_t::fn_get_at); else if (is_eq(p, "green")) - return WRAP_FUNCTOR(fn_green); + return WRAP_FUNCTOR(fn_green); break; case 'i': if (is_eq(p, "is_seq")) - return MAKE_FUNCTOR(report_t::fn_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); + return MAKE_FUNCTOR(report_t::fn_justify); else if (is_eq(p, "join")) - return MAKE_FUNCTOR(report_t::fn_join); + return MAKE_FUNCTOR(report_t::fn_join); break; case 'm': if (is_eq(p, "market")) - return MAKE_FUNCTOR(report_t::fn_market); + return MAKE_FUNCTOR(report_t::fn_market); else if (is_eq(p, "magenta")) - return WRAP_FUNCTOR(fn_magenta); + return WRAP_FUNCTOR(fn_magenta); break; case 'n': if (is_eq(p, "null")) - return WRAP_FUNCTOR(fn_null); + return WRAP_FUNCTOR(fn_null); else if (is_eq(p, "now")) - return MAKE_FUNCTOR(report_t::fn_now); + return MAKE_FUNCTOR(report_t::fn_now); break; case 'o': if (is_eq(p, "options")) - return MAKE_FUNCTOR(report_t::fn_options); + return MAKE_FUNCTOR(report_t::fn_options); break; case 'p': if (is_eq(p, "post")) - return WRAP_FUNCTOR(fn_false); + return WRAP_FUNCTOR(fn_false); else if (is_eq(p, "percent")) - return MAKE_FUNCTOR(report_t::fn_percent); + return MAKE_FUNCTOR(report_t::fn_percent); else if (is_eq(p, "price")) - return MAKE_FUNCTOR(report_t::fn_price); + return MAKE_FUNCTOR(report_t::fn_price); else if (is_eq(p, "print")) - return MAKE_FUNCTOR(report_t::fn_print); + return MAKE_FUNCTOR(report_t::fn_print); break; case 'q': if (is_eq(p, "quoted")) - return MAKE_FUNCTOR(report_t::fn_quoted); + return MAKE_FUNCTOR(report_t::fn_quoted); else if (is_eq(p, "quantity")) - return MAKE_FUNCTOR(report_t::fn_quantity); + return MAKE_FUNCTOR(report_t::fn_quantity); break; case 'r': if (is_eq(p, "rounded")) - return MAKE_FUNCTOR(report_t::fn_rounded); + return MAKE_FUNCTOR(report_t::fn_rounded); else if (is_eq(p, "red")) - return WRAP_FUNCTOR(fn_red); + return WRAP_FUNCTOR(fn_red); break; case 's': if (is_eq(p, "scrub")) - return MAKE_FUNCTOR(report_t::fn_scrub); + return MAKE_FUNCTOR(report_t::fn_scrub); else if (is_eq(p, "strip")) - return MAKE_FUNCTOR(report_t::fn_strip); + return MAKE_FUNCTOR(report_t::fn_strip); + else if (is_eq(p, "should_bold")) + return MAKE_FUNCTOR(report_t::fn_should_bold); break; case 't': if (is_eq(p, "truncated")) - return MAKE_FUNCTOR(report_t::fn_truncated); + return MAKE_FUNCTOR(report_t::fn_truncated); else if (is_eq(p, "total_expr")) - return MAKE_FUNCTOR(report_t::fn_total_expr); + return MAKE_FUNCTOR(report_t::fn_total_expr); else if (is_eq(p, "today")) - return MAKE_FUNCTOR(report_t::fn_today); + return MAKE_FUNCTOR(report_t::fn_today); else if (is_eq(p, "t")) - return MAKE_FUNCTOR(report_t::fn_display_amount); + return MAKE_FUNCTOR(report_t::fn_display_amount); else if (is_eq(p, "trim")) - return MAKE_FUNCTOR(report_t::fn_trim); + return MAKE_FUNCTOR(report_t::fn_trim); + else if (is_eq(p, "top_amount")) + return MAKE_FUNCTOR(report_t::fn_top_amount); else if (is_eq(p, "to_boolean")) - return MAKE_FUNCTOR(report_t::fn_to_boolean); + return MAKE_FUNCTOR(report_t::fn_to_boolean); else if (is_eq(p, "to_int")) - return MAKE_FUNCTOR(report_t::fn_to_int); + return MAKE_FUNCTOR(report_t::fn_to_int); else if (is_eq(p, "to_datetime")) - return MAKE_FUNCTOR(report_t::fn_to_datetime); + return MAKE_FUNCTOR(report_t::fn_to_datetime); else if (is_eq(p, "to_date")) - return MAKE_FUNCTOR(report_t::fn_to_date); + return MAKE_FUNCTOR(report_t::fn_to_date); else if (is_eq(p, "to_amount")) - return MAKE_FUNCTOR(report_t::fn_to_amount); + return MAKE_FUNCTOR(report_t::fn_to_amount); else if (is_eq(p, "to_balance")) - return MAKE_FUNCTOR(report_t::fn_to_balance); + return MAKE_FUNCTOR(report_t::fn_to_balance); else if (is_eq(p, "to_string")) - return MAKE_FUNCTOR(report_t::fn_to_string); + return MAKE_FUNCTOR(report_t::fn_to_string); else if (is_eq(p, "to_mask")) - return MAKE_FUNCTOR(report_t::fn_to_mask); + return MAKE_FUNCTOR(report_t::fn_to_mask); else if (is_eq(p, "to_sequence")) - return MAKE_FUNCTOR(report_t::fn_to_sequence); + return MAKE_FUNCTOR(report_t::fn_to_sequence); break; case 'T': if (is_eq(p, "T")) - return MAKE_FUNCTOR(report_t::fn_display_total); + return MAKE_FUNCTOR(report_t::fn_display_total); break; case 'u': if (is_eq(p, "underline")) - return WRAP_FUNCTOR(fn_underline); + return WRAP_FUNCTOR(fn_underline); else if (is_eq(p, "unrounded")) - return MAKE_FUNCTOR(report_t::fn_unrounded); + return MAKE_FUNCTOR(report_t::fn_unrounded); + break; + + case 'v': + if (is_eq(p, "value_date")) + return MAKE_FUNCTOR(report_t::fn_now); break; case 'w': if (is_eq(p, "white")) - return WRAP_FUNCTOR(fn_white); + return WRAP_FUNCTOR(fn_white); break; case 'y': if (is_eq(p, "yellow")) - return WRAP_FUNCTOR(fn_yellow); + return WRAP_FUNCTOR(fn_yellow); break; } @@ -1333,135 +1356,146 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, switch (*p) { case 'a': if (is_eq(p, "accounts")) { - return WRAP_FUNCTOR(reporter<>(new report_accounts(*this), *this, - "#accounts")); + return WRAP_FUNCTOR(reporter<>(new report_accounts(*this), *this, + "#accounts")); } break; 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_)), - maybe_format(HANDLER(prepend_format_)), - HANDLER(prepend_width_).value.to_long()), - *this, "#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_)), + maybe_format(HANDLER(prepend_format_)), + HANDLER(prepend_width_).value.to_long()), + *this, "#balance")); } else if (is_eq(p, "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_)), - maybe_format(HANDLER(prepend_format_)), - HANDLER(prepend_width_).value.to_long()), - *this, "#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_)), + maybe_format(HANDLER(prepend_format_)), + HANDLER(prepend_width_).value.to_long()), + *this, "#budget")); } break; case 'c': if (is_eq(p, "csv")) { - return WRAP_FUNCTOR - (reporter<> - (new format_posts(*this, report_format(HANDLER(csv_format_)), - maybe_format(HANDLER(prepend_format_)), - HANDLER(prepend_width_).value.to_long()), - *this, "#csv")); + return WRAP_FUNCTOR + (reporter<> + (new format_posts(*this, report_format(HANDLER(csv_format_)), + maybe_format(HANDLER(prepend_format_)), + HANDLER(prepend_width_).value.to_long()), + *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_)), - maybe_format(HANDLER(prepend_format_)), - HANDLER(prepend_width_).value.to_long()), - *this, "#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_)), + maybe_format(HANDLER(prepend_format_)), + HANDLER(prepend_width_).value.to_long()), + *this, "#cleared")); } else if (is_eq(p, "convert")) { - return WRAP_FUNCTOR(convert_command); + return WRAP_FUNCTOR(convert_command); } else if (is_eq(p, "commodities")) { - return WRAP_FUNCTOR(reporter<>(new report_commodities(*this), *this, - "#commodities")); + return WRAP_FUNCTOR(reporter<>(new report_commodities(*this), *this, + "#commodities")); } break; case 'e': if (is_eq(p, "equity")) { - HANDLER(print_virtual).on_only(string("#equity")); - return WRAP_FUNCTOR(reporter<>(new print_xacts(*this), *this, "#equity")); + HANDLER(generated).on_only(string("#equity")); + return WRAP_FUNCTOR(reporter<>(new print_xacts(*this), *this, "#equity")); } else if (is_eq(p, "entry")) { - return WRAP_FUNCTOR(xact_command); + return WRAP_FUNCTOR(xact_command); } else if (is_eq(p, "emacs")) { - return WRAP_FUNCTOR - (reporter<>(new format_emacs_posts(output_stream), *this, "#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); + return MAKE_FUNCTOR(report_t::echo_command); + } + break; + + case 'o': + if (is_eq(p, "org")) { + return WRAP_FUNCTOR + (reporter<> + (new posts_to_org_table(*this, maybe_format(HANDLER(prepend_format_))), + *this, "#org")); } break; case 'p': if (*(p + 1) == '\0' || is_eq(p, "print")) { - return WRAP_FUNCTOR - (reporter<>(new print_xacts(*this, HANDLED(raw)), *this, "#print")); + return WRAP_FUNCTOR + (reporter<>(new print_xacts(*this, 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_)), - maybe_format(HANDLER(prepend_format_)), - HANDLER(prepend_width_).value.to_long()), - *this, "#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_)), + maybe_format(HANDLER(prepend_format_)), + HANDLER(prepend_width_).value.to_long()), + *this, "#prices")); } else if (is_eq(p, "pricedb")) { - return expr_t::op_t::wrap_functor - (reporter<post_t, post_handler_ptr, &report_t::commodities_report> - (new format_posts(*this, report_format(HANDLER(pricedb_format_)), - maybe_format(HANDLER(prepend_format_)), - HANDLER(prepend_width_).value.to_long()), - *this, "#pricedb")); + return expr_t::op_t::wrap_functor + (reporter<post_t, post_handler_ptr, &report_t::commodities_report> + (new format_posts(*this, report_format(HANDLER(pricedb_format_)), + maybe_format(HANDLER(prepend_format_)), + HANDLER(prepend_width_).value.to_long()), + *this, "#pricedb")); } else if (is_eq(p, "pricemap")) { - return MAKE_FUNCTOR(report_t::pricemap_command); + return MAKE_FUNCTOR(report_t::pricemap_command); } else if (is_eq(p, "payees")) { - return WRAP_FUNCTOR(reporter<>(new report_payees(*this), *this, - "#payees")); + return WRAP_FUNCTOR(reporter<>(new report_payees(*this), *this, + "#payees")); } 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_)), - maybe_format(HANDLER(prepend_format_)), - HANDLER(prepend_width_).value.to_long()), - *this, "#register")); + return WRAP_FUNCTOR + (reporter<> + (new format_posts(*this, report_format(HANDLER(register_format_)), + maybe_format(HANDLER(prepend_format_)), + HANDLER(prepend_width_).value.to_long()), + *this, "#register")); } else if (is_eq(p, "reload")) { - return MAKE_FUNCTOR(report_t::reload_command); + return MAKE_FUNCTOR(report_t::reload_command); } break; case 's': if (is_eq(p, "stats") || is_eq(p, "stat")) - return WRAP_FUNCTOR(report_statistics); + return WRAP_FUNCTOR(report_statistics); + else if (is_eq(p, "source")) + return WRAP_FUNCTOR(source_command); break; case 'x': if (is_eq(p, "xact")) - return WRAP_FUNCTOR(xact_command); + return WRAP_FUNCTOR(xact_command); else if (is_eq(p, "xml")) - return WRAP_FUNCTOR(reporter<>(new format_xml(*this), *this, "#xml")); + return WRAP_FUNCTOR(reporter<>(new format_xml(*this), *this, "#xml")); break; } break; @@ -1470,39 +1504,38 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, switch (*p) { case 'a': if (is_eq(p, "args")) - return WRAP_FUNCTOR(query_command); + return WRAP_FUNCTOR(query_command); break; case 'e': if (is_eq(p, "eval")) - return WRAP_FUNCTOR(eval_command); + return WRAP_FUNCTOR(eval_command); else if (is_eq(p, "expr")) - return WRAP_FUNCTOR(parse_command); + return WRAP_FUNCTOR(parse_command); break; case 'f': if (is_eq(p, "format")) - return WRAP_FUNCTOR(format_command); + return WRAP_FUNCTOR(format_command); break; case 'g': if (is_eq(p, "generate")) { - HANDLER(print_virtual).on_only(string("#generate")); - return expr_t::op_t::wrap_functor - (reporter<post_t, post_handler_ptr, &report_t::generate_report> - (new print_xacts(*this), *this, "#generate")); + return expr_t::op_t::wrap_functor + (reporter<post_t, post_handler_ptr, &report_t::generate_report> + (new print_xacts(*this), *this, "#generate")); } break; case 'p': if (is_eq(p, "parse")) - return WRAP_FUNCTOR(parse_command); + return WRAP_FUNCTOR(parse_command); else if (is_eq(p, "period")) - return WRAP_FUNCTOR(period_command); + return WRAP_FUNCTOR(period_command); break; case 'q': if (is_eq(p, "query")) - return WRAP_FUNCTOR(query_command); + return WRAP_FUNCTOR(query_command); break; case 't': if (is_eq(p, "template")) - return WRAP_FUNCTOR(template_command); + return WRAP_FUNCTOR(template_command); break; } break; |