Reworked the way that options are handled
This commit is contained in:
parent
ef478079e7
commit
59f5ebe2df
10 changed files with 468 additions and 539 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
.Dd March 7, 2012
|
.Dd March 9, 2012
|
||||||
.Dt ledger 1
|
.Dt ledger 1
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm ledger
|
.Nm ledger
|
||||||
|
|
@ -359,6 +359,7 @@ See
|
||||||
.It Fl \-meta-width Ar INT
|
.It Fl \-meta-width Ar INT
|
||||||
.It Fl \-monthly Pq Fl M
|
.It Fl \-monthly Pq Fl M
|
||||||
.It Fl \-no-color
|
.It Fl \-no-color
|
||||||
|
.It Fl \-no-pager
|
||||||
.It Fl \-no-rounding
|
.It Fl \-no-rounding
|
||||||
.It Fl \-no-titles
|
.It Fl \-no-titles
|
||||||
.It Fl \-no-total
|
.It Fl \-no-total
|
||||||
|
|
|
||||||
11
src/chain.cc
11
src/chain.cc
|
|
@ -88,10 +88,9 @@ post_handler_ptr chain_pre_post_handlers(post_handler_ptr base_handler,
|
||||||
predicate_t(report.HANDLER(forecast_while_).str(),
|
predicate_t(report.HANDLER(forecast_while_).str(),
|
||||||
report.what_to_keep()),
|
report.what_to_keep()),
|
||||||
report,
|
report,
|
||||||
report.HANDLED(forecast_years_) ?
|
(report.HANDLED(forecast_years_) ?
|
||||||
static_cast<std::size_t>
|
lexical_cast<std::size_t>
|
||||||
(report.HANDLER(forecast_years_).value.to_long()) :
|
(report.HANDLER(forecast_years_).value) : 5UL));
|
||||||
5UL);
|
|
||||||
forecast_handler->add_period_xacts(report.session.journal->period_xacts);
|
forecast_handler->add_period_xacts(report.session.journal->period_xacts);
|
||||||
handler.reset(forecast_handler);
|
handler.reset(forecast_handler);
|
||||||
|
|
||||||
|
|
@ -137,9 +136,9 @@ post_handler_ptr chain_post_handlers(post_handler_ptr base_handler,
|
||||||
handler.reset
|
handler.reset
|
||||||
(new truncate_xacts(handler,
|
(new truncate_xacts(handler,
|
||||||
report.HANDLED(head_) ?
|
report.HANDLED(head_) ?
|
||||||
report.HANDLER(head_).value.to_int() : 0,
|
lexical_cast<int>(report.HANDLER(head_).value) : 0,
|
||||||
report.HANDLED(tail_) ?
|
report.HANDLED(tail_) ?
|
||||||
report.HANDLER(tail_).value.to_int() : 0));
|
lexical_cast<int>(report.HANDLER(tail_).value) : 0));
|
||||||
|
|
||||||
// display_filter_posts adds virtual posts to the list to account
|
// display_filter_posts adds virtual posts to the list to account
|
||||||
// for changes in value of commodities, which otherwise would affect
|
// for changes in value of commodities, which otherwise would affect
|
||||||
|
|
|
||||||
|
|
@ -522,7 +522,7 @@ value_t xact_command(call_scope_t& args)
|
||||||
xact_t * new_xact = draft.insert(*report.session.journal.get());
|
xact_t * new_xact = draft.insert(*report.session.journal.get());
|
||||||
|
|
||||||
// Only consider actual postings for the "xact" command
|
// Only consider actual postings for the "xact" command
|
||||||
report.HANDLER(limit_).on(string("#xact"), "actual");
|
report.HANDLER(limit_).on("#xact", "actual");
|
||||||
|
|
||||||
if (new_xact)
|
if (new_xact)
|
||||||
report.xact_report(post_handler_ptr(new print_xacts(report)), *new_xact);
|
report.xact_report(post_handler_ptr(new print_xacts(report)), *new_xact);
|
||||||
|
|
|
||||||
79
src/option.h
79
src/option.h
|
|
@ -61,9 +61,9 @@ protected:
|
||||||
option_t& operator=(const option_t&);
|
option_t& operator=(const option_t&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
T * parent;
|
T * parent;
|
||||||
value_t value;
|
string value;
|
||||||
bool wants_arg;
|
bool wants_arg;
|
||||||
|
|
||||||
option_t(const char * _name, const char _ch = '\0')
|
option_t(const char * _name, const char _ch = '\0')
|
||||||
: name(_name), name_len(std::strlen(name)), ch(_ch),
|
: name(_name), name_len(std::strlen(name)), ch(_ch),
|
||||||
|
|
@ -94,7 +94,8 @@ public:
|
||||||
out << std::right << desc();
|
out << std::right << desc();
|
||||||
if (wants_arg) {
|
if (wants_arg) {
|
||||||
out << " = ";
|
out << " = ";
|
||||||
value.print(out, 42);
|
out.width(42);
|
||||||
|
out << value;
|
||||||
} else {
|
} else {
|
||||||
out.width(45);
|
out.width(45);
|
||||||
out << ' ';
|
out << ' ';
|
||||||
|
|
@ -123,43 +124,49 @@ public:
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
string& str() {
|
|
||||||
assert(handled);
|
|
||||||
if (! value)
|
|
||||||
throw_(std::runtime_error, _("No argument provided for %1") << desc());
|
|
||||||
return value.as_string_lval();
|
|
||||||
}
|
|
||||||
|
|
||||||
string str() const {
|
string str() const {
|
||||||
assert(handled);
|
assert(handled);
|
||||||
if (! value)
|
if (value.empty())
|
||||||
throw_(std::runtime_error, _("No argument provided for %1") << desc());
|
throw_(std::runtime_error, _("No argument provided for %1") << desc());
|
||||||
return value.as_string();
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_only(const optional<string>& whence) {
|
void on(const char * whence) {
|
||||||
|
on(string(whence));
|
||||||
|
}
|
||||||
|
void on(const optional<string>& whence) {
|
||||||
|
handler_thunk(whence);
|
||||||
|
|
||||||
handled = true;
|
handled = true;
|
||||||
source = whence;
|
source = whence;
|
||||||
}
|
}
|
||||||
void on(const optional<string>& whence, const string& str) {
|
|
||||||
on_with(whence, string_value(str));
|
void on(const char * whence, const string& str) {
|
||||||
|
on(string(whence), str);
|
||||||
}
|
}
|
||||||
virtual void on_with(const optional<string>& whence,
|
void on(const optional<string>& whence, const string& str) {
|
||||||
const value_t& val) {
|
string before = value;
|
||||||
|
|
||||||
|
handler_thunk(whence, str);
|
||||||
|
|
||||||
|
if (value == before)
|
||||||
|
value = str;
|
||||||
|
|
||||||
handled = true;
|
handled = true;
|
||||||
value = val;
|
|
||||||
source = whence;
|
source = whence;
|
||||||
}
|
}
|
||||||
|
|
||||||
void off() {
|
void off() {
|
||||||
handled = false;
|
handled = false;
|
||||||
value = value_t();
|
value = "";
|
||||||
source = none;
|
source = none;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void handler_thunk(call_scope_t&) {}
|
virtual void handler_thunk(const optional<string>& whence) {}
|
||||||
|
virtual void handler_thunk(const optional<string>& whence,
|
||||||
|
const string& str) {}
|
||||||
|
|
||||||
virtual void handler(call_scope_t& args) {
|
value_t handler(call_scope_t& args) {
|
||||||
if (wants_arg) {
|
if (wants_arg) {
|
||||||
if (args.size() < 2)
|
if (args.size() < 2)
|
||||||
throw_(std::runtime_error, _("No argument provided for %1") << desc());
|
throw_(std::runtime_error, _("No argument provided for %1") << desc());
|
||||||
|
|
@ -167,7 +174,7 @@ public:
|
||||||
throw_(std::runtime_error, _("To many arguments provided for %1") << desc());
|
throw_(std::runtime_error, _("To many arguments provided for %1") << desc());
|
||||||
else if (! args[0].is_string())
|
else if (! args[0].is_string())
|
||||||
throw_(std::runtime_error, _("Context argument for %1 not a string") << desc());
|
throw_(std::runtime_error, _("Context argument for %1 not a string") << desc());
|
||||||
on_with(args.get<string>(0), args[1]);
|
on(args.get<string>(0), args.get<string>(1));
|
||||||
}
|
}
|
||||||
else if (args.size() < 1) {
|
else if (args.size() < 1) {
|
||||||
throw_(std::runtime_error, _("No argument provided for %1") << desc());
|
throw_(std::runtime_error, _("No argument provided for %1") << desc());
|
||||||
|
|
@ -176,27 +183,18 @@ public:
|
||||||
throw_(std::runtime_error, _("Context argument for %1 not a string") << desc());
|
throw_(std::runtime_error, _("Context argument for %1 not a string") << desc());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
on_only(args.get<string>(0));
|
on(args.get<string>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
handler_thunk(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual value_t handler_wrapper(call_scope_t& args) {
|
|
||||||
handler(args);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual value_t operator()(call_scope_t& args) {
|
virtual value_t operator()(call_scope_t& args) {
|
||||||
if (! args.empty()) {
|
if (! args.empty()) {
|
||||||
args.push_front(string_value("?expr"));
|
args.push_front(string_value("?expr"));
|
||||||
return handler_wrapper(args);
|
return handler(args);
|
||||||
}
|
}
|
||||||
else if (wants_arg) {
|
else if (wants_arg) {
|
||||||
if (handled)
|
return string_value(value);
|
||||||
return value;
|
|
||||||
else
|
|
||||||
return NULL_VALUE;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return handled;
|
return handled;
|
||||||
|
|
@ -215,15 +213,16 @@ public:
|
||||||
vartype var ; \
|
vartype var ; \
|
||||||
name ## option_t() : option_t<type>(#name), var value
|
name ## option_t() : option_t<type>(#name), var value
|
||||||
|
|
||||||
#define DO() virtual void handler_thunk(call_scope_t&)
|
#define DO() virtual void handler_thunk(const optional<string>& whence)
|
||||||
#define DO_(var) virtual void handler_thunk(call_scope_t& var)
|
#define DO_(var) virtual void handler_thunk(const optional<string>& whence, \
|
||||||
|
const string& var)
|
||||||
|
|
||||||
#define END(name) name ## handler
|
#define END(name) name ## handler
|
||||||
|
|
||||||
#define COPY_OPT(name, other) name ## handler(other.name ## handler)
|
#define COPY_OPT(name, other) name ## handler(other.name ## handler)
|
||||||
|
|
||||||
#define MAKE_OPT_HANDLER(type, x) \
|
#define MAKE_OPT_HANDLER(type, x) \
|
||||||
expr_t::op_t::wrap_functor(bind(&option_t<type>::handler_wrapper, x, _1))
|
expr_t::op_t::wrap_functor(bind(&option_t<type>::handler, x, _1))
|
||||||
|
|
||||||
#define MAKE_OPT_FUNCTOR(type, x) \
|
#define MAKE_OPT_FUNCTOR(type, x) \
|
||||||
expr_t::op_t::wrap_functor(bind(&option_t<type>::operator(), x, _1))
|
expr_t::op_t::wrap_functor(bind(&option_t<type>::operator(), x, _1))
|
||||||
|
|
@ -284,6 +283,10 @@ inline bool is_eq(const char * p, const char * n) {
|
||||||
} \
|
} \
|
||||||
END(name)
|
END(name)
|
||||||
|
|
||||||
|
#define OTHER(name) \
|
||||||
|
parent->HANDLER(name).parent = parent; \
|
||||||
|
parent->HANDLER(name)
|
||||||
|
|
||||||
bool process_option(const string& whence, const string& name, scope_t& scope,
|
bool process_option(const string& whence, const string& name, scope_t& scope,
|
||||||
const char * arg, const string& varname);
|
const char * arg, const string& varname);
|
||||||
|
|
||||||
|
|
|
||||||
17
src/print.cc
17
src/print.cc
|
|
@ -133,7 +133,7 @@ namespace {
|
||||||
|
|
||||||
std::size_t columns =
|
std::size_t columns =
|
||||||
(report.HANDLED(columns_) ?
|
(report.HANDLED(columns_) ?
|
||||||
static_cast<std::size_t>(report.HANDLER(columns_).value.to_long()) : 80);
|
lexical_cast<std::size_t>(report.HANDLER(columns_).str()) : 80);
|
||||||
|
|
||||||
if (xact.note)
|
if (xact.note)
|
||||||
print_note(out, *xact.note, xact.has_flags(ITEM_NOTE_ON_NEXT_LINE),
|
print_note(out, *xact.note, xact.has_flags(ITEM_NOTE_ON_NEXT_LINE),
|
||||||
|
|
@ -191,8 +191,8 @@ namespace {
|
||||||
unistring name(pbuf.str());
|
unistring name(pbuf.str());
|
||||||
|
|
||||||
std::size_t account_width =
|
std::size_t account_width =
|
||||||
(report.HANDLER(account_width_).specified ?
|
(report.HANDLED(account_width_) ?
|
||||||
static_cast<std::size_t>(report.HANDLER(account_width_).value.to_long()) : 36);
|
lexical_cast<std::size_t>(report.HANDLER(account_width_).str()) : 36);
|
||||||
|
|
||||||
if (account_width < name.length())
|
if (account_width < name.length())
|
||||||
account_width = name.length();
|
account_width = name.length();
|
||||||
|
|
@ -218,13 +218,14 @@ namespace {
|
||||||
// first.
|
// first.
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int amount_width =
|
std::size_t amount_width =
|
||||||
(report.HANDLER(amount_width_).specified ?
|
(report.HANDLED(amount_width_) ?
|
||||||
report.HANDLER(amount_width_).value.to_int() : 12);
|
lexical_cast<std::size_t>(report.HANDLER(amount_width_).str()) :
|
||||||
|
12);
|
||||||
|
|
||||||
std::ostringstream amt_str;
|
std::ostringstream amt_str;
|
||||||
value_t(post->amount).print(amt_str, amount_width, -1,
|
value_t(post->amount).print(amt_str, static_cast<int>(amount_width),
|
||||||
AMOUNT_PRINT_RIGHT_JUSTIFY |
|
-1, AMOUNT_PRINT_RIGHT_JUSTIFY |
|
||||||
AMOUNT_PRINT_NO_COMPUTED_ANNOTATIONS);
|
AMOUNT_PRINT_NO_COMPUTED_ANNOTATIONS);
|
||||||
amt = amt_str.str();
|
amt = amt_str.str();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,8 +136,8 @@ public:
|
||||||
virtual expr_t::ptr_op_t lookup(const symbol_t::kind_t kind,
|
virtual expr_t::ptr_op_t lookup(const symbol_t::kind_t kind,
|
||||||
const string& name);
|
const string& name);
|
||||||
|
|
||||||
OPTION_(python_interpreter_t, import_, DO_(args) {
|
OPTION_(python_interpreter_t, import_, DO_(str) {
|
||||||
parent->import_option(args.get<string>(1));
|
parent->import_option(str);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
238
src/report.cc
238
src/report.cc
|
|
@ -59,7 +59,7 @@ void report_t::normalize_options(const string& verb)
|
||||||
#ifdef HAVE_ISATTY
|
#ifdef HAVE_ISATTY
|
||||||
if (! HANDLED(force_color)) {
|
if (! HANDLED(force_color)) {
|
||||||
if (! HANDLED(no_color) && isatty(STDOUT_FILENO))
|
if (! HANDLED(no_color) && isatty(STDOUT_FILENO))
|
||||||
HANDLER(color).on_only(string("?normalize"));
|
HANDLER(color).on("?normalize");
|
||||||
if (HANDLED(color) && ! isatty(STDOUT_FILENO))
|
if (HANDLED(color) && ! isatty(STDOUT_FILENO))
|
||||||
HANDLER(color).off();
|
HANDLER(color).off();
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +83,7 @@ void report_t::normalize_options(const string& verb)
|
||||||
|
|
||||||
if (session.HANDLED(price_exp_))
|
if (session.HANDLED(price_exp_))
|
||||||
commodity_pool_t::current_pool->quote_leeway =
|
commodity_pool_t::current_pool->quote_leeway =
|
||||||
session.HANDLER(price_exp_).value.as_long();
|
lexical_cast<long>(session.HANDLER(price_exp_).value) * 3600L;
|
||||||
|
|
||||||
if (session.HANDLED(price_db_))
|
if (session.HANDLED(price_db_))
|
||||||
commodity_pool_t::current_pool->price_db = session.HANDLER(price_db_).str();
|
commodity_pool_t::current_pool->price_db = session.HANDLER(price_db_).str();
|
||||||
|
|
@ -106,39 +106,35 @@ void report_t::normalize_options(const string& verb)
|
||||||
if (! HANDLED(meta_width_)) {
|
if (! HANDLED(meta_width_)) {
|
||||||
string::size_type i = HANDLER(meta_).str().find(':');
|
string::size_type i = HANDLER(meta_).str().find(':');
|
||||||
if (i != string::npos) {
|
if (i != string::npos) {
|
||||||
HANDLED(meta_width_).on_with
|
HANDLED(meta_width_).on("?normalize",
|
||||||
(string("?normalize"),
|
string(HANDLER(meta_).str(), i + 1));
|
||||||
lexical_cast<long>(string(HANDLER(meta_).str(), i + 1)));
|
HANDLED(meta_).on("?normalize",
|
||||||
HANDLED(meta_).on(string("?normalize"),
|
|
||||||
string(HANDLER(meta_).str(), 0, i));
|
string(HANDLER(meta_).str(), 0, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (HANDLED(meta_width_)) {
|
if (HANDLED(meta_width_)) {
|
||||||
HANDLER(prepend_format_).on
|
HANDLER(prepend_format_)
|
||||||
(string("?normalize"),
|
.on("?normalize", string("%(justify(truncated(tag(\"") +
|
||||||
string("%(justify(truncated(tag(\"") +
|
HANDLER(meta_).str() + "\"), " +
|
||||||
HANDLER(meta_).str() + "\"), " +
|
HANDLED(meta_width_).value + " - 1), " +
|
||||||
HANDLED(meta_width_).value.to_string() + " - 1), " +
|
HANDLED(meta_width_).value + "))");
|
||||||
HANDLED(meta_width_).value.to_string() + "))");
|
meta_width = lexical_cast<long>(HANDLED(meta_width_).value);
|
||||||
meta_width = HANDLED(meta_width_).value.to_long();
|
|
||||||
} else {
|
} else {
|
||||||
HANDLER(prepend_format_).on(string("?normalize"), string("%(tag(\"") +
|
HANDLER(prepend_format_)
|
||||||
HANDLER(meta_).str() + "\"))");
|
.on("?normalize", string("%(tag(\"") + HANDLER(meta_).str() + "\"))");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! HANDLED(prepend_width_))
|
|
||||||
HANDLER(prepend_width_).on_with(string("?normalize"), static_cast<long>(0));
|
|
||||||
|
|
||||||
if (verb == "print" || verb == "xact" || verb == "dump") {
|
if (verb == "print" || verb == "xact" || verb == "dump") {
|
||||||
HANDLER(related).on_only(string("?normalize"));
|
HANDLER(related_all).parent = this;
|
||||||
HANDLER(related_all).on_only(string("?normalize"));
|
HANDLER(related_all).on("?normalize");
|
||||||
}
|
}
|
||||||
else if (verb == "equity") {
|
else if (verb == "equity") {
|
||||||
HANDLER(equity).on_only(string("?normalize"));
|
HANDLER(equity).on("?normalize");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verb[0] != 'b' && verb[0] != 'r')
|
if (verb[0] != 'b' && verb[0] != 'r')
|
||||||
HANDLER(base).on_only(string("?normalize"));
|
HANDLER(base).on("?normalize");
|
||||||
|
|
||||||
// If a time period was specified with -p, check whether it also gave a
|
// If a time period was specified with -p, check whether it also gave a
|
||||||
// begin and/or end to the report period (though these can be overridden
|
// begin and/or end to the report period (though these can be overridden
|
||||||
|
|
@ -152,12 +148,10 @@ void report_t::normalize_options(const string& verb)
|
||||||
// to avoid option ordering issues were we to have done it during the
|
// to avoid option ordering issues were we to have done it during the
|
||||||
// initial parsing of the options.
|
// initial parsing of the options.
|
||||||
if (HANDLED(amount_data)) {
|
if (HANDLED(amount_data)) {
|
||||||
HANDLER(format_)
|
HANDLER(format_).on("?normalize", HANDLER(plot_amount_format_).value);
|
||||||
.on_with(string("?normalize"), HANDLER(plot_amount_format_).value);
|
|
||||||
}
|
}
|
||||||
else if (HANDLED(total_data)) {
|
else if (HANDLED(total_data)) {
|
||||||
HANDLER(format_)
|
HANDLER(format_).on("?normalize", HANDLER(plot_total_format_).value);
|
||||||
.on_with(string("?normalize"), HANDLER(plot_total_format_).value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the --exchange (-X) option was used, parse out any final price
|
// If the --exchange (-X) option was used, parse out any final price
|
||||||
|
|
@ -170,7 +164,7 @@ void report_t::normalize_options(const string& verb)
|
||||||
|
|
||||||
long cols = 0;
|
long cols = 0;
|
||||||
if (HANDLED(columns_))
|
if (HANDLED(columns_))
|
||||||
cols = HANDLER(columns_).value.to_long();
|
cols = lexical_cast<long>(HANDLER(columns_).value);
|
||||||
else if (const char * columns = std::getenv("COLUMNS"))
|
else if (const char * columns = std::getenv("COLUMNS"))
|
||||||
cols = lexical_cast<long>(columns);
|
cols = lexical_cast<long>(columns);
|
||||||
else
|
else
|
||||||
|
|
@ -182,23 +176,20 @@ void report_t::normalize_options(const string& verb)
|
||||||
if (cols > 0) {
|
if (cols > 0) {
|
||||||
DEBUG("auto.columns", "cols = " << cols);
|
DEBUG("auto.columns", "cols = " << cols);
|
||||||
|
|
||||||
if (! HANDLER(date_width_).specified)
|
long date_width = (HANDLED(date_width_) ?
|
||||||
HANDLER(date_width_)
|
lexical_cast<long>(HANDLER(date_width_).str()) :
|
||||||
.on_with(none, static_cast<long>(format_date(CURRENT_DATE(),
|
format_date(CURRENT_DATE(),FMT_PRINTED).length());
|
||||||
FMT_PRINTED).length()));
|
long payee_width = (HANDLED(payee_width_) ?
|
||||||
|
lexical_cast<long>(HANDLER(payee_width_).str()) :
|
||||||
long date_width = HANDLER(date_width_).value.to_long();
|
long(double(cols) * 0.263157));
|
||||||
long payee_width = (HANDLER(payee_width_).specified ?
|
long account_width = (HANDLED(account_width_) ?
|
||||||
HANDLER(payee_width_).value.to_long() :
|
lexical_cast<long>(HANDLER(account_width_).str()) :
|
||||||
int(double(cols) * 0.263157));
|
long(double(cols) * 0.302631));
|
||||||
long account_width = (HANDLER(account_width_).specified ?
|
long amount_width = (HANDLED(amount_width_) ?
|
||||||
HANDLER(account_width_).value.to_long() :
|
lexical_cast<long>(HANDLER(amount_width_).str()) :
|
||||||
int(double(cols) * 0.302631));
|
long(double(cols) * 0.157894));
|
||||||
long amount_width = (HANDLER(amount_width_).specified ?
|
long total_width = (HANDLED(total_width_) ?
|
||||||
HANDLER(amount_width_).value.to_long() :
|
lexical_cast<long>(HANDLER(total_width_).str()) :
|
||||||
int(double(cols) * 0.157894));
|
|
||||||
long total_width = (HANDLER(total_width_).specified ?
|
|
||||||
HANDLER(total_width_).value.to_long() :
|
|
||||||
amount_width);
|
amount_width);
|
||||||
|
|
||||||
DEBUG("auto.columns", "date_width = " << date_width);
|
DEBUG("auto.columns", "date_width = " << date_width);
|
||||||
|
|
@ -207,11 +198,11 @@ void report_t::normalize_options(const string& verb)
|
||||||
DEBUG("auto.columns", "amount_width = " << amount_width);
|
DEBUG("auto.columns", "amount_width = " << amount_width);
|
||||||
DEBUG("auto.columns", "total_width = " << total_width);
|
DEBUG("auto.columns", "total_width = " << total_width);
|
||||||
|
|
||||||
if (! HANDLER(date_width_).specified &&
|
if (! HANDLED(date_width_) &&
|
||||||
! HANDLER(payee_width_).specified &&
|
! HANDLED(payee_width_) &&
|
||||||
! HANDLER(account_width_).specified &&
|
! HANDLED(account_width_) &&
|
||||||
! HANDLER(amount_width_).specified &&
|
! HANDLED(amount_width_) &&
|
||||||
! HANDLER(total_width_).specified) {
|
! HANDLED(total_width_)) {
|
||||||
long total = (4 /* the spaces between */ + date_width + payee_width +
|
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) {
|
if (total > cols) {
|
||||||
|
|
@ -222,17 +213,19 @@ void report_t::normalize_options(const string& verb)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! HANDLED(meta_width_))
|
if (! HANDLED(meta_width_))
|
||||||
HANDLER(meta_width_).on_with(string("?normalize"), 0L);
|
HANDLER(meta_width_).value = "0";
|
||||||
if (! HANDLER(date_width_).specified)
|
if (! HANDLED(prepend_width_))
|
||||||
HANDLER(date_width_).on_with(string("?normalize"), date_width);
|
HANDLER(prepend_width_).value = "0";
|
||||||
if (! HANDLER(payee_width_).specified)
|
if (! HANDLED(date_width_))
|
||||||
HANDLER(payee_width_).on_with(string("?normalize"), payee_width);
|
HANDLER(date_width_).value = to_string(date_width);
|
||||||
if (! HANDLER(account_width_).specified)
|
if (! HANDLED(payee_width_))
|
||||||
HANDLER(account_width_).on_with(string("?normalize"), account_width);
|
HANDLER(payee_width_).value = to_string(payee_width);
|
||||||
if (! HANDLER(amount_width_).specified)
|
if (! HANDLED(account_width_))
|
||||||
HANDLER(amount_width_).on_with(string("?normalize"), amount_width);
|
HANDLER(account_width_).value = to_string(account_width);
|
||||||
if (! HANDLER(total_width_).specified)
|
if (! HANDLED(amount_width_))
|
||||||
HANDLER(total_width_).on_with(string("?normalize"), total_width);
|
HANDLER(amount_width_).value = to_string(amount_width);
|
||||||
|
if (! HANDLED(total_width_))
|
||||||
|
HANDLER(total_width_).value = to_string(total_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,7 +248,7 @@ void report_t::normalize_period()
|
||||||
if (! interval.duration)
|
if (! interval.duration)
|
||||||
HANDLER(period_).off();
|
HANDLER(period_).off();
|
||||||
else if (! HANDLED(sort_all_))
|
else if (! HANDLED(sort_all_))
|
||||||
HANDLER(sort_xacts_).on_only(string("?normalize"));
|
HANDLER(sort_xacts_).on("?normalize");
|
||||||
}
|
}
|
||||||
|
|
||||||
void report_t::parse_query_args(const value_t& args, const string& whence)
|
void report_t::parse_query_args(const value_t& args, const string& whence)
|
||||||
|
|
@ -278,7 +271,7 @@ void report_t::parse_query_args(const value_t& args, const string& whence)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.has_query(query_t::QUERY_BOLD)) {
|
if (query.has_query(query_t::QUERY_BOLD)) {
|
||||||
HANDLER(bold_if_).set_expr(whence, query.get_query(query_t::QUERY_BOLD));
|
HANDLER(bold_if_).on(whence, query.get_query(query_t::QUERY_BOLD));
|
||||||
DEBUG("report.predicate", "Bolding predicate = " << HANDLER(bold_if_).str());
|
DEBUG("report.predicate", "Bolding predicate = " << HANDLER(bold_if_).str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,9 +322,9 @@ void report_t::generate_report(post_handler_ptr handler)
|
||||||
|
|
||||||
generate_posts_iterator walker
|
generate_posts_iterator walker
|
||||||
(session, HANDLED(seed_) ?
|
(session, HANDLED(seed_) ?
|
||||||
static_cast<unsigned int>(HANDLER(seed_).value.to_long()) : 0,
|
lexical_cast<unsigned int>(HANDLER(seed_).str()) : 0,
|
||||||
HANDLED(head_) ?
|
HANDLED(head_) ?
|
||||||
static_cast<unsigned int>(HANDLER(head_).value.to_long()) : 50);
|
lexical_cast<unsigned int>(HANDLER(head_).str()) : 50);
|
||||||
|
|
||||||
pass_down_posts<generate_posts_iterator>(handler, walker);
|
pass_down_posts<generate_posts_iterator>(handler, walker);
|
||||||
}
|
}
|
||||||
|
|
@ -527,16 +520,17 @@ value_t report_t::fn_market(call_scope_t& args)
|
||||||
arg0 = tmp;
|
arg0 = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string target_commodity;
|
||||||
if (args.has<string>(2))
|
if (args.has<string>(2))
|
||||||
result = arg0.exchange_commodities(args.get<string>(2),
|
target_commodity = args.get<string>(2);
|
||||||
|
|
||||||
|
if (! target_commodity.empty())
|
||||||
|
result = arg0.exchange_commodities(target_commodity,
|
||||||
/* add_prices= */ false, moment);
|
/* add_prices= */ false, moment);
|
||||||
else
|
else
|
||||||
result = arg0.value(moment);
|
result = arg0.value(moment);
|
||||||
|
|
||||||
if (! result.is_null())
|
return ! result.is_null() ? result : arg0;
|
||||||
return result;
|
|
||||||
|
|
||||||
return args[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t report_t::fn_get_at(call_scope_t& args)
|
value_t report_t::fn_get_at(call_scope_t& args)
|
||||||
|
|
@ -1245,7 +1239,7 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
|
||||||
else if (is_eq(p, "display_total"))
|
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"))
|
else if (is_eq(p, "date"))
|
||||||
return MAKE_FUNCTOR(report_t::fn_now);
|
return MAKE_FUNCTOR(report_t::fn_today);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
|
|
@ -1404,85 +1398,98 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
|
||||||
return MAKE_OPT_HANDLER(report_t, handler);
|
return MAKE_OPT_HANDLER(report_t, handler);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#define POSTS_REPORT(formatter) \
|
#define POSTS_REPORTER(formatter) \
|
||||||
WRAP_FUNCTOR(reporter<>(post_handler_ptr(formatter), *this, \
|
WRAP_FUNCTOR(reporter<>(post_handler_ptr(formatter), *this, \
|
||||||
string("#") + p));
|
string("#") + p))
|
||||||
|
|
||||||
// Can't use WRAP_FUNCTOR here because the template arguments
|
// Can't use WRAP_FUNCTOR here because the template arguments
|
||||||
// confuse the parser
|
// confuse the parser
|
||||||
#define POSTS_REPORT_(method, formatter) \
|
#define POSTS_REPORTER_(method, formatter) \
|
||||||
expr_t::op_t::wrap_functor \
|
expr_t::op_t::wrap_functor \
|
||||||
(reporter<post_t, post_handler_ptr, method> \
|
(reporter<post_t, post_handler_ptr, method> \
|
||||||
(post_handler_ptr(formatter), *this, string("#") + p));
|
(post_handler_ptr(formatter), *this, string("#") + p))
|
||||||
|
|
||||||
#define ACCOUNTS_REPORT(formatter) \
|
#define FORMATTED_POSTS_REPORTER(format) \
|
||||||
|
POSTS_REPORTER \
|
||||||
|
(new format_posts \
|
||||||
|
(*this, report_format(HANDLER(format)), \
|
||||||
|
maybe_format(HANDLER(prepend_format_)), \
|
||||||
|
HANDLED(prepend_width_) ? \
|
||||||
|
lexical_cast<std::size_t>(HANDLER(prepend_width_).str()) : 0))
|
||||||
|
|
||||||
|
#define FORMATTED_COMMODITIES_REPORTER(format) \
|
||||||
|
POSTS_REPORTER_ \
|
||||||
|
(&report_t::commodities_report, \
|
||||||
|
new format_posts \
|
||||||
|
(*this, report_format(HANDLER(format)), \
|
||||||
|
maybe_format(HANDLER(prepend_format_)), \
|
||||||
|
HANDLED(prepend_width_) ? \
|
||||||
|
lexical_cast<std::size_t>(HANDLER(prepend_width_).str()) : 0))
|
||||||
|
|
||||||
|
#define ACCOUNTS_REPORTER(formatter) \
|
||||||
expr_t::op_t::wrap_functor(reporter<account_t, acct_handler_ptr, \
|
expr_t::op_t::wrap_functor(reporter<account_t, acct_handler_ptr, \
|
||||||
&report_t::accounts_report> \
|
&report_t::accounts_report> \
|
||||||
(acct_handler_ptr(formatter), *this, \
|
(acct_handler_ptr(formatter), *this, \
|
||||||
string("#") + p));
|
string("#") + p))
|
||||||
|
|
||||||
|
#define FORMATTED_ACCOUNTS_REPORTER(format) \
|
||||||
|
ACCOUNTS_REPORTER \
|
||||||
|
(new format_accounts \
|
||||||
|
(*this, report_format(HANDLER(format)), \
|
||||||
|
maybe_format(HANDLER(prepend_format_)), \
|
||||||
|
HANDLED(prepend_width_) ? \
|
||||||
|
lexical_cast<std::size_t>(HANDLER(prepend_width_).str()) : 0))
|
||||||
|
|
||||||
case symbol_t::COMMAND:
|
case symbol_t::COMMAND:
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case 'a':
|
case 'a':
|
||||||
if (is_eq(p, "accounts")) {
|
if (is_eq(p, "accounts")) {
|
||||||
return POSTS_REPORT(new report_accounts(*this));
|
return POSTS_REPORTER(new report_accounts(*this));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
if (*(p + 1) == '\0' || is_eq(p, "bal") || is_eq(p, "balance")) {
|
if (*(p + 1) == '\0' || is_eq(p, "bal") || is_eq(p, "balance")) {
|
||||||
return ACCOUNTS_REPORT(new format_accounts
|
return FORMATTED_ACCOUNTS_REPORTER(balance_format_);
|
||||||
(*this, report_format(HANDLER(balance_format_)),
|
|
||||||
maybe_format(HANDLER(prepend_format_)),
|
|
||||||
HANDLER(prepend_width_).value.to_size_t()));
|
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "budget")) {
|
else if (is_eq(p, "budget")) {
|
||||||
HANDLER(amount_).set_expr(string("#budget"), "(amount, 0)");
|
HANDLER(amount_).on(string("#budget"), "(amount, 0)");
|
||||||
|
|
||||||
budget_flags |= BUDGET_WRAP_VALUES;
|
budget_flags |= BUDGET_WRAP_VALUES;
|
||||||
if (! (budget_flags & ~BUDGET_WRAP_VALUES))
|
if (! (budget_flags & ~BUDGET_WRAP_VALUES))
|
||||||
budget_flags |= BUDGET_BUDGETED;
|
budget_flags |= BUDGET_BUDGETED;
|
||||||
|
|
||||||
return ACCOUNTS_REPORT(new format_accounts
|
return FORMATTED_ACCOUNTS_REPORTER(budget_format_);
|
||||||
(*this, report_format(HANDLER(budget_format_)),
|
|
||||||
maybe_format(HANDLER(prepend_format_)),
|
|
||||||
HANDLER(prepend_width_).value.to_size_t()));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
if (is_eq(p, "csv")) {
|
if (is_eq(p, "csv")) {
|
||||||
return POSTS_REPORT(new format_posts
|
return FORMATTED_POSTS_REPORTER(csv_format_);
|
||||||
(*this, report_format(HANDLER(csv_format_)),
|
|
||||||
maybe_format(HANDLER(prepend_format_)),
|
|
||||||
HANDLER(prepend_width_).value.to_size_t()));
|
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "cleared")) {
|
else if (is_eq(p, "cleared")) {
|
||||||
HANDLER(amount_).set_expr(string("#cleared"),
|
HANDLER(amount_).on(string("#cleared"),
|
||||||
"(amount, cleared ? amount : 0)");
|
"(amount, cleared ? amount : 0)");
|
||||||
return ACCOUNTS_REPORT(new format_accounts
|
return FORMATTED_ACCOUNTS_REPORTER(cleared_format_);
|
||||||
(*this, report_format(HANDLER(cleared_format_)),
|
|
||||||
maybe_format(HANDLER(prepend_format_)),
|
|
||||||
HANDLER(prepend_width_).value.to_size_t()));
|
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "convert")) {
|
else if (is_eq(p, "convert")) {
|
||||||
return WRAP_FUNCTOR(convert_command);
|
return WRAP_FUNCTOR(convert_command);
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "commodities")) {
|
else if (is_eq(p, "commodities")) {
|
||||||
return POSTS_REPORT(new report_commodities(*this));
|
return POSTS_REPORTER(new report_commodities(*this));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
if (is_eq(p, "equity")) {
|
if (is_eq(p, "equity")) {
|
||||||
HANDLER(generated).on_only(string("#equity"));
|
HANDLER(generated).on("#equity");
|
||||||
return POSTS_REPORT(new print_xacts(*this));
|
return POSTS_REPORTER(new print_xacts(*this));
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "entry")) {
|
else if (is_eq(p, "entry")) {
|
||||||
return WRAP_FUNCTOR(xact_command);
|
return WRAP_FUNCTOR(xact_command);
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "emacs")) {
|
else if (is_eq(p, "emacs")) {
|
||||||
return POSTS_REPORT(new format_emacs_posts(output_stream));
|
return POSTS_REPORTER(new format_emacs_posts(output_stream));
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "echo")) {
|
else if (is_eq(p, "echo")) {
|
||||||
return MAKE_FUNCTOR(report_t::echo_command);
|
return MAKE_FUNCTOR(report_t::echo_command);
|
||||||
|
|
@ -1491,43 +1498,32 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
if (is_eq(p, "org")) {
|
if (is_eq(p, "org")) {
|
||||||
return POSTS_REPORT(new posts_to_org_table
|
return POSTS_REPORTER(new posts_to_org_table
|
||||||
(*this, maybe_format(HANDLER(prepend_format_))));
|
(*this, maybe_format(HANDLER(prepend_format_))));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
if (*(p + 1) == '\0' || is_eq(p, "print")) {
|
if (*(p + 1) == '\0' || is_eq(p, "print")) {
|
||||||
return POSTS_REPORT(new print_xacts(*this, HANDLED(raw)));
|
return POSTS_REPORTER(new print_xacts(*this, HANDLED(raw)));
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "prices")) {
|
else if (is_eq(p, "prices")) {
|
||||||
return POSTS_REPORT_(&report_t::commodities_report,
|
return FORMATTED_COMMODITIES_REPORTER(prices_format_);
|
||||||
new format_posts
|
|
||||||
(*this, report_format(HANDLER(prices_format_)),
|
|
||||||
maybe_format(HANDLER(prepend_format_)),
|
|
||||||
HANDLER(prepend_width_).value.to_size_t()));
|
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "pricedb")) {
|
else if (is_eq(p, "pricedb")) {
|
||||||
return POSTS_REPORT_(&report_t::commodities_report,
|
return FORMATTED_COMMODITIES_REPORTER(pricedb_format_);
|
||||||
new format_posts
|
|
||||||
(*this, report_format(HANDLER(pricedb_format_)),
|
|
||||||
maybe_format(HANDLER(prepend_format_)),
|
|
||||||
HANDLER(prepend_width_).value.to_size_t()));
|
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "pricemap")) {
|
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")) {
|
else if (is_eq(p, "payees")) {
|
||||||
return POSTS_REPORT(new report_payees(*this));
|
return POSTS_REPORTER(new report_payees(*this));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
if (*(p + 1) == '\0' || is_eq(p, "reg") || is_eq(p, "register")) {
|
if (*(p + 1) == '\0' || is_eq(p, "reg") || is_eq(p, "register")) {
|
||||||
return POSTS_REPORT(new format_posts
|
return FORMATTED_POSTS_REPORTER(register_format_);
|
||||||
(*this, report_format(HANDLER(register_format_)),
|
|
||||||
maybe_format(HANDLER(prepend_format_)),
|
|
||||||
HANDLER(prepend_width_).value.to_size_t()));
|
|
||||||
}
|
}
|
||||||
else if (is_eq(p, "reload")) {
|
else if (is_eq(p, "reload")) {
|
||||||
return MAKE_FUNCTOR(report_t::reload_command);
|
return MAKE_FUNCTOR(report_t::reload_command);
|
||||||
|
|
@ -1545,7 +1541,7 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
|
||||||
if (is_eq(p, "xact"))
|
if (is_eq(p, "xact"))
|
||||||
return WRAP_FUNCTOR(xact_command);
|
return WRAP_FUNCTOR(xact_command);
|
||||||
else if (is_eq(p, "xml"))
|
else if (is_eq(p, "xml"))
|
||||||
return POSTS_REPORT(new format_xml(*this));
|
return POSTS_REPORTER(new format_xml(*this));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -1568,8 +1564,8 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
if (is_eq(p, "generate"))
|
if (is_eq(p, "generate"))
|
||||||
return POSTS_REPORT_(&report_t::generate_report,
|
return POSTS_REPORTER_(&report_t::generate_report,
|
||||||
new print_xacts(*this));
|
new print_xacts(*this));
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (is_eq(p, "parse"))
|
if (is_eq(p, "parse"))
|
||||||
|
|
|
||||||
635
src/report.h
635
src/report.h
|
|
@ -353,12 +353,16 @@ public:
|
||||||
* Option handlers
|
* Option handlers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
OPTION__(report_t, abbrev_len_,
|
OPTION__
|
||||||
CTOR(report_t, abbrev_len_) { on_with(none, 2L); });
|
(report_t, abbrev_len_,
|
||||||
|
CTOR(report_t, abbrev_len_) {
|
||||||
|
on(none, "2");
|
||||||
|
});
|
||||||
|
|
||||||
OPTION(report_t, account_);
|
OPTION(report_t, account_);
|
||||||
|
|
||||||
OPTION_(report_t, actual, DO() { // -L
|
OPTION_(report_t, actual, DO() { // -L
|
||||||
parent->HANDLER(limit_).on(string("--actual"), "actual");
|
OTHER(limit_).on(whence, "actual");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, add_budget, DO() {
|
OPTION_(report_t, add_budget, DO() {
|
||||||
|
|
@ -368,12 +372,8 @@ public:
|
||||||
OPTION__
|
OPTION__
|
||||||
(report_t, amount_, // -t
|
(report_t, amount_, // -t
|
||||||
DECL1(report_t, amount_, merged_expr_t, expr, ("amount_expr", "amount")) {}
|
DECL1(report_t, amount_, merged_expr_t, expr, ("amount_expr", "amount")) {}
|
||||||
void set_expr(const optional<string>& whence, const string& str) {
|
DO_(str) {
|
||||||
expr.append(str);
|
expr.append(str);
|
||||||
on(whence, str);
|
|
||||||
}
|
|
||||||
DO_(args) {
|
|
||||||
set_expr(args.get<string>(0), args.get<string>(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, amount_data); // -j
|
OPTION(report_t, amount_data); // -j
|
||||||
|
|
@ -381,216 +381,204 @@ public:
|
||||||
OPTION(report_t, auto_match);
|
OPTION(report_t, auto_match);
|
||||||
|
|
||||||
OPTION_(report_t, average, DO() { // -A
|
OPTION_(report_t, average, DO() { // -A
|
||||||
parent->HANDLER(display_total_)
|
OTHER(display_total_)
|
||||||
.set_expr(string("--average"), "count>0?(display_total/count):0");
|
.on(whence, "count>0?(display_total/count):0");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__(report_t, balance_format_, CTOR(report_t, balance_format_) {
|
OPTION__
|
||||||
on(none,
|
(report_t, balance_format_,
|
||||||
"%(ansify_if("
|
CTOR(report_t, balance_format_) {
|
||||||
" justify(scrub(display_total), 20, 20 + prepend_width, true, color),"
|
on(none,
|
||||||
" bold if should_bold))"
|
"%(ansify_if("
|
||||||
" %(!options.flat ? depth_spacer : \"\")"
|
" justify(scrub(display_total), 20,"
|
||||||
"%-(ansify_if("
|
" 20 + int(prepend_width), true, color),"
|
||||||
" ansify_if(partial_account(options.flat), blue if color),"
|
" bold if should_bold))"
|
||||||
" bold if should_bold))\n%/"
|
" %(!options.flat ? depth_spacer : \"\")"
|
||||||
"%$1\n%/"
|
"%-(ansify_if("
|
||||||
"%(prepend_width ? \" \" * prepend_width : \"\")"
|
" ansify_if(partial_account(options.flat), blue if color),"
|
||||||
"--------------------\n");
|
" bold if should_bold))\n%/"
|
||||||
});
|
"%$1\n%/"
|
||||||
|
"%(prepend_width ? \" \" * int(prepend_width) : \"\")"
|
||||||
|
"--------------------\n");
|
||||||
|
});
|
||||||
|
|
||||||
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(string("--basis"));
|
OTHER(revalued).on(whence);
|
||||||
parent->HANDLER(amount_).expr.set_base_expr("rounded(cost)");
|
OTHER(amount_).expr.set_base_expr("rounded(cost)");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, begin_, DO_(args) { // -b
|
OPTION_(report_t, begin_, DO_(str) { // -b
|
||||||
date_interval_t interval(args.get<string>(1));
|
date_interval_t interval(str);
|
||||||
optional<date_t> begin = interval.begin();
|
if (optional<date_t> begin = interval.begin()) {
|
||||||
if (! begin)
|
string predicate = "date>=[" + to_iso_extended_string(*begin) + "]";
|
||||||
|
OTHER(limit_).on(whence, predicate);
|
||||||
|
} else {
|
||||||
throw_(std::invalid_argument,
|
throw_(std::invalid_argument,
|
||||||
_("Could not determine beginning of period '%1'")
|
_("Could not determine beginning of period '%1'") << str);
|
||||||
<< args.get<string>(1));
|
}
|
||||||
|
|
||||||
string predicate = "date>=[" + to_iso_extended_string(*begin) + "]";
|
|
||||||
parent->HANDLER(limit_).on(string("--begin"), predicate);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__
|
OPTION_
|
||||||
(report_t, bold_if_,
|
(report_t, bold_if_,
|
||||||
expr_t expr;
|
expr_t expr;
|
||||||
CTOR(report_t, bold_if_) {}
|
DO_(str) {
|
||||||
void set_expr(const optional<string>& whence, const string& str) {
|
|
||||||
expr = str;
|
expr = str;
|
||||||
on(whence, str);
|
|
||||||
}
|
|
||||||
DO_(args) {
|
|
||||||
set_expr(args.get<string>(0), args.get<string>(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, budget, DO() {
|
OPTION_(report_t, budget, DO() {
|
||||||
parent->budget_flags |= BUDGET_BUDGETED;
|
parent->budget_flags |= BUDGET_BUDGETED;
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__(report_t, budget_format_, CTOR(report_t, budget_format_) {
|
OPTION__
|
||||||
on(none,
|
(report_t, budget_format_,
|
||||||
"%(justify(scrub(get_at(display_total, 0)), 12, -1, true, color))"
|
CTOR(report_t, budget_format_) {
|
||||||
" %(justify(-scrub(get_at(display_total, 1)), 12, "
|
on(none,
|
||||||
" 12 + 1 + 12, true, color))"
|
"%(justify(scrub(get_at(display_total, 0)), 12, -1, true, color))"
|
||||||
" %(justify(scrub(get_at(display_total, 1) + "
|
" %(justify(-scrub(get_at(display_total, 1)), 12, "
|
||||||
" get_at(display_total, 0)), 12, "
|
" 12 + 1 + 12, true, color))"
|
||||||
" 12 + 1 + 12 + 1 + 12, true, color))"
|
" %(justify(scrub(get_at(display_total, 1) + "
|
||||||
" %(ansify_if("
|
" get_at(display_total, 0)), 12, "
|
||||||
" justify((get_at(display_total, 1) ? "
|
" 12 + 1 + 12 + 1 + 12, true, color))"
|
||||||
" (100% * scrub(get_at(display_total, 0))) / "
|
" %(ansify_if("
|
||||||
" -scrub(get_at(display_total, 1)) : 0), "
|
" justify((get_at(display_total, 1) ? "
|
||||||
" 5, -1, true, false),"
|
" (100% * scrub(get_at(display_total, 0))) / "
|
||||||
" magenta if (color and get_at(display_total, 1) and "
|
" -scrub(get_at(display_total, 1)) : 0), "
|
||||||
" (abs(quantity(scrub(get_at(display_total, 0))) / "
|
" 5, -1, true, false),"
|
||||||
" quantity(scrub(get_at(display_total, 1)))) >= 1))))"
|
" magenta if (color and get_at(display_total, 1) and "
|
||||||
" %(!options.flat ? depth_spacer : \"\")"
|
" (abs(quantity(scrub(get_at(display_total, 0))) / "
|
||||||
"%-(ansify_if(partial_account(options.flat), blue if color))\n"
|
" quantity(scrub(get_at(display_total, 1)))) >= 1))))"
|
||||||
"%/%$1 %$2 %$3 %$4\n%/"
|
" %(!options.flat ? depth_spacer : \"\")"
|
||||||
"%(prepend_width ? \" \" * prepend_width : \"\")"
|
"%-(ansify_if(partial_account(options.flat), blue if color))\n"
|
||||||
"------------ ------------ ------------ -----\n");
|
"%/%$1 %$2 %$3 %$4\n%/"
|
||||||
});
|
"%(prepend_width ? \" \" * int(prepend_width) : \"\")"
|
||||||
|
"------------ ------------ ------------ -----\n");
|
||||||
|
});
|
||||||
|
|
||||||
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(string("--cleared"), "cleared");
|
OTHER(limit_).on(whence, "cleared");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__(report_t, cleared_format_, CTOR(report_t, cleared_format_) {
|
OPTION__
|
||||||
on(none,
|
(report_t, cleared_format_,
|
||||||
"%(justify(scrub(get_at(display_total, 0)), 16, 16 + prepend_width, "
|
CTOR(report_t, cleared_format_) {
|
||||||
" true, color)) %(justify(scrub(get_at(display_total, 1)), 18, "
|
on(none,
|
||||||
" 36 + prepend_width, true, color))"
|
"%(justify(scrub(get_at(display_total, 0)), 16, 16 + int(prepend_width), "
|
||||||
" %(latest_cleared ? format_date(latest_cleared) : \" \")"
|
" true, color)) %(justify(scrub(get_at(display_total, 1)), 18, "
|
||||||
" %(!options.flat ? depth_spacer : \"\")"
|
" 36 + int(prepend_width), true, color))"
|
||||||
"%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
|
" %(latest_cleared ? format_date(latest_cleared) : \" \")"
|
||||||
"%$1 %$2 %$3\n%/"
|
" %(!options.flat ? depth_spacer : \"\")"
|
||||||
"%(prepend_width ? \" \" * prepend_width : \"\")"
|
"%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
|
||||||
"---------------- ---------------- ---------\n");
|
"%$1 %$2 %$3\n%/"
|
||||||
});
|
"%(prepend_width ? \" \" * int(prepend_width) : \"\")"
|
||||||
|
"---------------- ---------------- ---------\n");
|
||||||
|
});
|
||||||
|
|
||||||
OPTION(report_t, color);
|
OPTION(report_t, color);
|
||||||
|
|
||||||
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(string("--collapse"), "post|depth<=1");
|
OTHER(display_).on(whence, "post|depth<=1");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, collapse_if_zero, DO() {
|
OPTION_(report_t, collapse_if_zero, DO() {
|
||||||
parent->HANDLER(collapse).on_only(string("--collapse-if-zero"));
|
OTHER(collapse).on(whence);
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, columns_);
|
OPTION(report_t, columns_);
|
||||||
OPTION(report_t, count);
|
OPTION(report_t, count);
|
||||||
|
|
||||||
OPTION__(report_t, csv_format_, CTOR(report_t, csv_format_) {
|
OPTION__
|
||||||
on(none,
|
(report_t, csv_format_,
|
||||||
"%(quoted(date)),"
|
CTOR(report_t, csv_format_) {
|
||||||
"%(quoted(code)),"
|
on(none,
|
||||||
"%(quoted(payee)),"
|
"%(quoted(date)),"
|
||||||
"%(quoted(display_account)),"
|
"%(quoted(code)),"
|
||||||
"%(quoted(commodity)),"
|
"%(quoted(payee)),"
|
||||||
"%(quoted(quantity(scrub(display_amount)))),"
|
"%(quoted(display_account)),"
|
||||||
"%(quoted(cleared ? \"*\" : (pending ? \"!\" : \"\"))),"
|
"%(quoted(commodity)),"
|
||||||
"%(quoted(join(note | xact.note)))\n");
|
"%(quoted(quantity(scrub(display_amount)))),"
|
||||||
});
|
"%(quoted(cleared ? \"*\" : (pending ? \"!\" : \"\"))),"
|
||||||
|
"%(quoted(join(note | xact.note)))\n");
|
||||||
|
});
|
||||||
|
|
||||||
OPTION_(report_t, current, DO() { // -c
|
OPTION_(report_t, current, DO() { // -c
|
||||||
parent->HANDLER(limit_).on(string("--current"), "date<=today");
|
OTHER(limit_).on(whence, "date<=today");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, daily, DO() { // -D
|
OPTION_(report_t, daily, DO() { // -D
|
||||||
parent->HANDLER(period_).on(string("--daily"), "daily");
|
OTHER(period_).on(whence, "daily");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, date_);
|
OPTION(report_t, date_);
|
||||||
OPTION(report_t, date_format_);
|
OPTION(report_t, date_format_);
|
||||||
OPTION(report_t, datetime_format_);
|
OPTION(report_t, datetime_format_);
|
||||||
|
|
||||||
OPTION_(report_t, depth_, DO_(args) {
|
OPTION_(report_t, depth_, DO_(str) {
|
||||||
parent->HANDLER(display_)
|
OTHER(display_).on(whence, string("depth<=") + str);
|
||||||
.on(string("--depth"), string("depth<=") + args.get<string>(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, deviation, DO() {
|
OPTION_(report_t, deviation, DO() {
|
||||||
parent->HANDLER(display_total_)
|
OTHER(display_total_)
|
||||||
.set_expr(string("--deviation"), "display_amount-display_total");
|
.on(whence, "display_amount-display_total");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__
|
OPTION_
|
||||||
(report_t, display_, // -d
|
(report_t, display_,
|
||||||
CTOR(report_t, display_) {}
|
DO_(str) { // -d
|
||||||
virtual void on_with(const optional<string>& whence, const value_t& text) {
|
if (handled)
|
||||||
if (! handled)
|
value = string("(") + value + ")&(" + str + ")";
|
||||||
option_t<report_t>::on_with(whence, text);
|
|
||||||
else
|
|
||||||
option_t<report_t>::on_with(whence,
|
|
||||||
string_value(string("(") + str() + ")&(" +
|
|
||||||
text.as_string() + ")"));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__
|
OPTION__
|
||||||
(report_t, display_amount_,
|
(report_t, display_amount_,
|
||||||
DECL1(report_t, display_amount_, merged_expr_t, expr,
|
DECL1(report_t, display_amount_, merged_expr_t, expr,
|
||||||
("display_amount", "amount_expr")) {}
|
("display_amount", "amount_expr")) {}
|
||||||
void set_expr(const optional<string>& whence, const string& str) {
|
DO_(str) {
|
||||||
expr.append(str);
|
expr.append(str);
|
||||||
on(whence, str);
|
|
||||||
}
|
|
||||||
DO_(args) {
|
|
||||||
set_expr(args.get<string>(0), args.get<string>(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__
|
OPTION__
|
||||||
(report_t, display_total_,
|
(report_t, display_total_,
|
||||||
DECL1(report_t, display_total_, merged_expr_t, expr,
|
DECL1(report_t, display_total_, merged_expr_t, expr,
|
||||||
("display_total", "total_expr")) {}
|
("display_total", "total_expr")) {}
|
||||||
void set_expr(const optional<string>& whence, const string& str) {
|
DO_(str) {
|
||||||
expr.append(str);
|
expr.append(str);
|
||||||
on(whence, str);
|
|
||||||
}
|
|
||||||
DO_(args) {
|
|
||||||
set_expr(args.get<string>(0), args.get<string>(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, dow);
|
OPTION(report_t, dow);
|
||||||
OPTION(report_t, aux_date);
|
OPTION(report_t, aux_date);
|
||||||
OPTION(report_t, empty); // -E
|
OPTION(report_t, empty); // -E
|
||||||
|
|
||||||
OPTION_(report_t, end_, DO_(args) { // -e
|
OPTION_(report_t, end_, DO_(str) { // -e
|
||||||
date_interval_t interval(args.get<string>(1));
|
|
||||||
// Use begin() here so that if the user says --end=2008, we end on
|
// Use begin() here so that if the user says --end=2008, we end on
|
||||||
// 2008/01/01 instead of 2009/01/01 (which is what end() would
|
// 2008/01/01 instead of 2009/01/01 (which is what end() would
|
||||||
// return).
|
// return).
|
||||||
optional<date_t> end = interval.begin();
|
date_interval_t interval(str);
|
||||||
if (! end)
|
if (optional<date_t> end = interval.begin()) {
|
||||||
|
string predicate = "date<[" + to_iso_extended_string(*end) + "]";
|
||||||
|
OTHER(limit_).on(whence, predicate);
|
||||||
|
|
||||||
|
parent->terminus = datetime_t(*end);
|
||||||
|
} else {
|
||||||
throw_(std::invalid_argument,
|
throw_(std::invalid_argument,
|
||||||
_("Could not determine end of period '%1'")
|
_("Could not determine end of period '%1'")
|
||||||
<< args.get<string>(1));
|
<< str);
|
||||||
|
}
|
||||||
string predicate = "date<[" + to_iso_extended_string(*end) + "]";
|
|
||||||
parent->HANDLER(limit_).on(string("--end"), predicate);
|
|
||||||
|
|
||||||
parent->terminus = datetime_t(*end);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, equity);
|
OPTION(report_t, equity);
|
||||||
OPTION(report_t, exact);
|
OPTION(report_t, exact);
|
||||||
|
|
||||||
OPTION_(report_t, exchange_, DO_(args) { // -X
|
OPTION_(report_t, exchange_, DO_() { // -X
|
||||||
on_with(args.get<string>(0), args[1]);
|
// Using -X implies -V. The main difference is that now
|
||||||
call_scope_t no_args(*parent);
|
// HANDLER(exchange_) contains the name of a commodity, which
|
||||||
no_args.push_back(args[0]);
|
// is accessed via the "exchange" value expression function.
|
||||||
parent->HANDLER(market).parent = parent;
|
OTHER(market).on(whence);
|
||||||
parent->HANDLER(market).handler(no_args);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, flat);
|
OPTION(report_t, flat);
|
||||||
|
|
@ -601,74 +589,65 @@ 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(string("--gain"));
|
OTHER(revalued).on(whence);
|
||||||
|
|
||||||
parent->HANDLER(amount_).expr.set_base_expr("(amount, cost)");
|
OTHER(amount_).expr.set_base_expr("(amount, cost)");
|
||||||
parent->HANDLER(total_).expr.set_base_expr("total");
|
OTHER(total_).expr.set_base_expr("total");
|
||||||
|
|
||||||
// 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_)
|
OTHER(display_amount_)
|
||||||
.set_expr(string("--gain"),
|
.on(whence,
|
||||||
"use_direct_amount ? amount :"
|
"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), value_date, exchange)"
|
" market(get_at(amount_expr, 0), value_date, exchange)"
|
||||||
" - get_at(amount_expr, 1))");
|
" - get_at(amount_expr, 1))");
|
||||||
parent->HANDLER(revalued_total_)
|
OTHER(revalued_total_)
|
||||||
.set_expr(string("--gain"),
|
.on(whence,
|
||||||
"(market(get_at(total_expr, 0), value_date, exchange), "
|
"(market(get_at(total_expr, 0), value_date, exchange), "
|
||||||
"get_at(total_expr, 1))");
|
"get_at(total_expr, 1))");
|
||||||
parent->HANDLER(display_total_)
|
OTHER(display_total_)
|
||||||
.set_expr(string("--gain"),
|
.on(whence,
|
||||||
"use_direct_amount ? total_expr :"
|
"use_direct_amount ? total_expr :"
|
||||||
" market(get_at(total_expr, 0), value_date, exchange)"
|
" market(get_at(total_expr, 0), value_date, exchange)"
|
||||||
" - get_at(total_expr, 1)");
|
" - get_at(total_expr, 1)");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, generated);
|
OPTION(report_t, generated);
|
||||||
|
|
||||||
OPTION__
|
OPTION_
|
||||||
(report_t, group_by_,
|
(report_t, group_by_,
|
||||||
expr_t expr;
|
expr_t expr;
|
||||||
CTOR(report_t, group_by_) {}
|
DO_(str) {
|
||||||
void set_expr(const optional<string>& whence, const string& str) {
|
|
||||||
expr = str;
|
expr = str;
|
||||||
on(whence, str);
|
|
||||||
}
|
|
||||||
DO_(args) {
|
|
||||||
set_expr(args.get<string>(0), args.get<string>(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__(report_t, group_title_format_, CTOR(report_t, group_title_format_) {
|
OPTION__
|
||||||
on(none, "%(value)\n");
|
(report_t, group_title_format_,
|
||||||
});
|
CTOR(report_t, group_title_format_) {
|
||||||
|
on(none, "%(value)\n");
|
||||||
|
});
|
||||||
|
|
||||||
OPTION(report_t, head_);
|
OPTION(report_t, head_);
|
||||||
|
|
||||||
OPTION_(report_t, historical, DO() { // -H
|
OPTION_(report_t, historical, DO() { // -H
|
||||||
parent->HANDLER(amount_)
|
OTHER(amount_)
|
||||||
.set_expr(string("--historical"),
|
.on(whence, "nail_down(amount_expr, "
|
||||||
"nail_down(amount_expr, (s,d,t -> market(s,value_date,t)))");
|
"market(amount_expr, value_date, exchange))");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
OPTION(report_t, inject_);
|
OPTION(report_t, inject_);
|
||||||
|
|
||||||
OPTION_(report_t, invert, DO() {
|
OPTION_(report_t, invert, DO() {
|
||||||
parent->HANDLER(amount_).set_expr(string("--invert"), "-amount");
|
OTHER(amount_).on(whence, "-amount");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__
|
OPTION_
|
||||||
(report_t, limit_, // -l
|
(report_t, limit_,
|
||||||
CTOR(report_t, limit_) {}
|
DO_(str) { // -l
|
||||||
virtual void on_with(const optional<string>& whence, const value_t& text) {
|
if (handled)
|
||||||
if (! handled)
|
value = string("(") + value + ")&(" + str + ")";
|
||||||
option_t<report_t>::on_with(whence, text);
|
|
||||||
else
|
|
||||||
option_t<report_t>::on_with(whence,
|
|
||||||
string_value(string("(") + str() + ")&(" +
|
|
||||||
text.as_string() + ")"));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, lot_dates);
|
OPTION(report_t, lot_dates);
|
||||||
|
|
@ -678,49 +657,44 @@ 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(string("--market"));
|
OTHER(revalued).on(whence);
|
||||||
parent->HANDLER(display_amount_)
|
|
||||||
.set_expr(string("--market"),
|
OTHER(display_amount_)
|
||||||
"market(display_amount, value_date, exchange)");
|
.on(whence, "market(display_amount, value_date, exchange)");
|
||||||
parent->HANDLER(display_total_)
|
OTHER(display_total_)
|
||||||
.set_expr(string("--market"),
|
.on(whence, "market(display_total, value_date, exchange)");
|
||||||
"market(display_total, value_date, exchange)");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, meta_);
|
OPTION(report_t, meta_);
|
||||||
|
|
||||||
OPTION_(report_t, monthly, DO() { // -M
|
OPTION_(report_t, monthly, DO() { // -M
|
||||||
parent->HANDLER(period_).on(string("--monthly"), "monthly");
|
OTHER(period_).on(whence, "monthly");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, no_color, DO() {
|
OPTION_(report_t, no_color, DO() {
|
||||||
parent->HANDLER(color).off();
|
OTHER(color).off();
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, no_rounding);
|
OPTION(report_t, no_rounding);
|
||||||
OPTION(report_t, no_titles);
|
OPTION(report_t, no_titles);
|
||||||
OPTION(report_t, no_total);
|
OPTION(report_t, no_total);
|
||||||
|
|
||||||
OPTION_(report_t, now_, DO_(args) {
|
OPTION_(report_t, now_, DO_(str) {
|
||||||
date_interval_t interval(args.get<string>(1));
|
date_interval_t interval(str);
|
||||||
optional<date_t> begin = interval.begin();
|
if (optional<date_t> begin = interval.begin()) {
|
||||||
if (! begin)
|
ledger::epoch = parent->terminus = datetime_t(*begin);
|
||||||
|
} else {
|
||||||
throw_(std::invalid_argument,
|
throw_(std::invalid_argument,
|
||||||
_("Could not determine beginning of period '%1'")
|
_("Could not determine beginning of period '%1'")
|
||||||
<< args.get<string>(1));
|
<< str);
|
||||||
ledger::epoch = parent->terminus = datetime_t(*begin);
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__
|
OPTION_
|
||||||
(report_t, only_,
|
(report_t, only_,
|
||||||
CTOR(report_t, only_) {}
|
DO_(str) {
|
||||||
virtual void on_with(const optional<string>& whence, const value_t& text) {
|
if (handled)
|
||||||
if (! handled)
|
value = string("(") + value + ")&(" + str + ")";
|
||||||
option_t<report_t>::on_with(whence, text);
|
|
||||||
else
|
|
||||||
option_t<report_t>::on_with(whence,
|
|
||||||
string_value(string("(") + str() + ")&(" +
|
|
||||||
text.as_string() + ")"));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, output_); // -o
|
OPTION(report_t, output_); // -o
|
||||||
|
|
@ -741,178 +715,162 @@ public:
|
||||||
setenv("LESS", "-FRSX", 0); // don't overwrite
|
setenv("LESS", "-FRSX", 0); // don't overwrite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
virtual void on_with(const optional<string>& whence, const value_t& text) {
|
|
||||||
string cmd(text.to_string());
|
|
||||||
if (cmd == "" || cmd == "false" || cmd == "off" ||
|
|
||||||
cmd == "none" || cmd == "no" || cmd == "disable")
|
|
||||||
option_t<report_t>::off();
|
|
||||||
else
|
|
||||||
option_t<report_t>::on_with(whence, text);
|
|
||||||
});
|
});
|
||||||
#else // HAVE_ISATTY
|
#else // HAVE_ISATTY
|
||||||
OPTION__
|
OPTION(report_t, pager_);
|
||||||
(report_t, pager_,
|
|
||||||
CTOR(report_t, pager_) {
|
|
||||||
}
|
|
||||||
virtual void on_with(const optional<string>& whence, const value_t& text) {
|
|
||||||
string cmd(text.to_string());
|
|
||||||
if (cmd == "" || cmd == "false" || cmd == "off" ||
|
|
||||||
cmd == "none" || cmd == "no" || cmd == "disable")
|
|
||||||
option_t<report_t>::off();
|
|
||||||
else
|
|
||||||
option_t<report_t>::on_with(whence, text);
|
|
||||||
});
|
|
||||||
#endif // HAVE_ISATTY
|
#endif // HAVE_ISATTY
|
||||||
|
|
||||||
|
OPTION_(report_t, no_pager, DO() {
|
||||||
|
OTHER(pager_).off();
|
||||||
|
});
|
||||||
|
|
||||||
OPTION(report_t, payee_);
|
OPTION(report_t, payee_);
|
||||||
|
|
||||||
OPTION_(report_t, pending, DO() { // -C
|
OPTION_(report_t, pending, DO() { // -C
|
||||||
parent->HANDLER(limit_).on(string("--pending"), "pending");
|
OTHER(limit_).on(whence, "pending");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, percent, DO() { // -%
|
OPTION_(report_t, percent, DO() { // -%
|
||||||
parent->HANDLER(total_)
|
OTHER(total_)
|
||||||
.set_expr(string("--percent"),
|
.on(whence,
|
||||||
"((is_account&parent&parent.total)?"
|
"((is_account&parent&parent.total)?"
|
||||||
" percent(scrub(total), scrub(parent.total)):0)");
|
" percent(scrub(total), scrub(parent.total)):0)");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__
|
OPTION_
|
||||||
(report_t, period_, // -p
|
(report_t, period_,
|
||||||
CTOR(report_t, period_) {}
|
DO_(str) { // -p
|
||||||
virtual void on_with(const optional<string>& whence, const value_t& text) {
|
if (handled)
|
||||||
if (! handled)
|
value += string(" ") + str;
|
||||||
option_t<report_t>::on_with(whence, text);
|
|
||||||
else
|
|
||||||
option_t<report_t>::on_with(whence,
|
|
||||||
string_value(text.as_string() + " " + str()));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, pivot_);
|
OPTION(report_t, pivot_);
|
||||||
|
|
||||||
OPTION__(report_t, plot_amount_format_, CTOR(report_t, plot_amount_format_) {
|
OPTION__
|
||||||
on(none,
|
(report_t, plot_amount_format_,
|
||||||
"%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_amount)))\n");
|
CTOR(report_t, plot_amount_format_) {
|
||||||
});
|
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__
|
||||||
on(none,
|
(report_t, plot_total_format_,
|
||||||
"%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_total)))\n");
|
CTOR(report_t, plot_total_format_) {
|
||||||
});
|
on(none,
|
||||||
|
"%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_total)))\n");
|
||||||
|
});
|
||||||
|
|
||||||
OPTION(report_t, prepend_format_);
|
OPTION(report_t, prepend_format_);
|
||||||
OPTION_(report_t, prepend_width_, DO_(args) {
|
OPTION(report_t, prepend_width_);
|
||||||
value = args.get<long>(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
OPTION_(report_t, price, DO() { // -I
|
OPTION_(report_t, price, DO() { // -I
|
||||||
parent->HANDLER(amount_).expr.set_base_expr("price");
|
OTHER(amount_).expr.set_base_expr("price");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__(report_t, prices_format_, CTOR(report_t, prices_format_) {
|
OPTION__
|
||||||
on(none,
|
(report_t, prices_format_,
|
||||||
"%(date) %-8(display_account) %(justify(scrub(display_amount), 12, "
|
CTOR(report_t, prices_format_) {
|
||||||
" 2 + 9 + 8 + 12, true, color))\n");
|
on(none,
|
||||||
});
|
"%(date) %-8(display_account) %(justify(scrub(display_amount), 12, "
|
||||||
|
" 2 + 9 + 8 + 12, true, color))\n");
|
||||||
|
});
|
||||||
|
|
||||||
OPTION__(report_t, pricedb_format_, CTOR(report_t, pricedb_format_) {
|
OPTION__
|
||||||
on(none,
|
(report_t, pricedb_format_,
|
||||||
"P %(datetime) %(display_account) %(scrub(display_amount))\n");
|
CTOR(report_t, pricedb_format_) {
|
||||||
});
|
on(none,
|
||||||
|
"P %(datetime) %(display_account) %(scrub(display_amount))\n");
|
||||||
|
});
|
||||||
|
|
||||||
OPTION(report_t, primary_date);
|
OPTION(report_t, primary_date);
|
||||||
|
|
||||||
OPTION_(report_t, quantity, DO() { // -O
|
OPTION_(report_t, quantity, DO() { // -O
|
||||||
parent->HANDLER(revalued).off();
|
OTHER(revalued).off();
|
||||||
parent->HANDLER(amount_).expr.set_base_expr("amount");
|
|
||||||
parent->HANDLER(total_).expr.set_base_expr("total");
|
OTHER(amount_).expr.set_base_expr("amount");
|
||||||
|
OTHER(total_).expr.set_base_expr("total");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, quarterly, DO() {
|
OPTION_(report_t, quarterly, DO() {
|
||||||
parent->HANDLER(period_).on(string("--quarterly"), "quarterly");
|
OTHER(period_).on(whence, "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(string("--real"), "real");
|
OTHER(limit_).on(whence, "real");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__(report_t, register_format_, CTOR(report_t, register_format_) {
|
OPTION__
|
||||||
on(none,
|
(report_t, register_format_,
|
||||||
"%(ansify_if("
|
CTOR(report_t, register_format_) {
|
||||||
" ansify_if(justify(format_date(date), date_width),"
|
on(none,
|
||||||
" green if color and date > today),"
|
"%(ansify_if("
|
||||||
" bold if should_bold))"
|
" ansify_if(justify(format_date(date), int(date_width)),"
|
||||||
" %(ansify_if("
|
" green if color and date > today),"
|
||||||
" ansify_if(justify(truncated(payee, payee_width), payee_width), "
|
" bold if should_bold))"
|
||||||
" bold if color and !cleared and actual),"
|
" %(ansify_if("
|
||||||
" bold if should_bold))"
|
" ansify_if(justify(truncated(payee, int(payee_width)), int(payee_width)), "
|
||||||
" %(ansify_if("
|
" bold if color and !cleared and actual),"
|
||||||
" ansify_if(justify(truncated(display_account, account_width, "
|
" bold if should_bold))"
|
||||||
" abbrev_len), account_width),"
|
" %(ansify_if("
|
||||||
" blue if color),"
|
" ansify_if(justify(truncated(display_account, int(account_width), "
|
||||||
" bold if should_bold))"
|
" abbrev_len), int(account_width)),"
|
||||||
" %(ansify_if("
|
" blue if color),"
|
||||||
" justify(scrub(display_amount), amount_width, "
|
" bold if should_bold))"
|
||||||
" 3 + meta_width + date_width + payee_width"
|
" %(ansify_if("
|
||||||
" + account_width + amount_width + prepend_width,"
|
" justify(scrub(display_amount), int(amount_width), "
|
||||||
" true, color),"
|
" 3 + int(meta_width) + int(date_width) + int(payee_width)"
|
||||||
" bold if should_bold))"
|
" + int(account_width) + int(amount_width) + int(prepend_width),"
|
||||||
" %(ansify_if("
|
" true, color),"
|
||||||
" justify(scrub(display_total), total_width, "
|
" bold if should_bold))"
|
||||||
" 4 + meta_width + date_width + payee_width"
|
" %(ansify_if("
|
||||||
" + account_width + amount_width + total_width"
|
" justify(scrub(display_total), int(total_width), "
|
||||||
" + prepend_width, true, color),"
|
" 4 + int(meta_width) + int(date_width) + int(payee_width)"
|
||||||
" bold if should_bold))\n%/"
|
" + int(account_width) + int(amount_width) + int(total_width)"
|
||||||
"%(justify(\" \", date_width))"
|
" + int(prepend_width), true, color),"
|
||||||
" %(ansify_if("
|
" bold if should_bold))\n%/"
|
||||||
" justify(truncated(has_tag(\"Payee\") ? payee : \" \", "
|
"%(justify(\" \", int(date_width)))"
|
||||||
" payee_width), payee_width),"
|
" %(ansify_if("
|
||||||
" bold if should_bold))"
|
" justify(truncated(has_tag(\"Payee\") ? payee : \" \", "
|
||||||
" %$3 %$4 %$5\n");
|
" int(payee_width)), int(payee_width)),"
|
||||||
});
|
" bold if should_bold))"
|
||||||
|
" %$3 %$4 %$5\n");
|
||||||
|
});
|
||||||
|
|
||||||
OPTION(report_t, related); // -r
|
OPTION(report_t, related); // -r
|
||||||
|
|
||||||
OPTION_(report_t, related_all, DO() {
|
OPTION_(report_t, related_all, DO() {
|
||||||
parent->HANDLER(related).on_only(string("--related-all"));
|
OTHER(related).on(whence);
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, revalued);
|
OPTION(report_t, revalued);
|
||||||
OPTION(report_t, revalued_only);
|
OPTION(report_t, revalued_only);
|
||||||
|
|
||||||
OPTION__
|
OPTION_
|
||||||
(report_t, revalued_total_,
|
(report_t, revalued_total_,
|
||||||
expr_t expr;
|
expr_t expr;
|
||||||
CTOR(report_t, revalued_total_) {}
|
DO_(str) {
|
||||||
void set_expr(const optional<string>& whence, const string& str) {
|
|
||||||
expr = str;
|
expr = str;
|
||||||
on(whence, str);
|
|
||||||
}
|
|
||||||
DO_(args) {
|
|
||||||
set_expr(args.get<string>(0), args.get<string>(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, rich_data);
|
OPTION(report_t, rich_data);
|
||||||
|
|
||||||
OPTION(report_t, seed_);
|
OPTION(report_t, seed_);
|
||||||
|
|
||||||
OPTION_(report_t, sort_, DO_(args) { // -S
|
OPTION_(report_t, sort_, DO_(str) { // -S
|
||||||
on_with(args.get<string>(0), args[1]);
|
OTHER(sort_xacts_).off();
|
||||||
parent->HANDLER(sort_xacts_).off();
|
OTHER(sort_all_).off();
|
||||||
parent->HANDLER(sort_all_).off();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, sort_all_, DO_(args) {
|
OPTION_(report_t, sort_all_, DO_(str) {
|
||||||
parent->HANDLER(sort_).on_with(string("--sort-all"), args[1]);
|
OTHER(sort_).on(whence, str);
|
||||||
parent->HANDLER(sort_xacts_).off();
|
OTHER(sort_xacts_).off();
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, sort_xacts_, DO_(args) {
|
OPTION_(report_t, sort_xacts_, DO_(str) {
|
||||||
parent->HANDLER(sort_).on_with(string("--sort-xacts"), args[1]);
|
OTHER(sort_).on(whence, str);
|
||||||
parent->HANDLER(sort_all_).off();
|
OTHER(sort_all_).off();
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, start_of_week_);
|
OPTION(report_t, start_of_week_);
|
||||||
|
|
@ -922,18 +880,13 @@ public:
|
||||||
OPTION__
|
OPTION__
|
||||||
(report_t, total_, // -T
|
(report_t, total_, // -T
|
||||||
DECL1(report_t, total_, merged_expr_t, expr, ("total_expr", "total")) {}
|
DECL1(report_t, total_, merged_expr_t, expr, ("total_expr", "total")) {}
|
||||||
void set_expr(const optional<string>& whence, const string& str) {
|
DO_(str) {
|
||||||
expr.append(str);
|
expr.append(str);
|
||||||
on(whence, str);
|
|
||||||
}
|
|
||||||
DO_(args) {
|
|
||||||
set_expr(args.get<string>(0), args.get<string>(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, total_data); // -J
|
OPTION(report_t, total_data); // -J
|
||||||
|
|
||||||
OPTION_(report_t, truncate_, DO_(args) {
|
OPTION_(report_t, truncate_, DO_(style) {
|
||||||
string style(args.get<string>(1));
|
|
||||||
if (style == "leading")
|
if (style == "leading")
|
||||||
format_t::default_style = format_t::TRUNCATE_LEADING;
|
format_t::default_style = format_t::TRUNCATE_LEADING;
|
||||||
else if (style == "middle")
|
else if (style == "middle")
|
||||||
|
|
@ -951,7 +904,7 @@ public:
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, uncleared, DO() { // -U
|
OPTION_(report_t, uncleared, DO() { // -U
|
||||||
parent->HANDLER(limit_).on(string("--uncleared"), "uncleared|pending");
|
OTHER(limit_).on(whence, "uncleared|pending");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, unrealized);
|
OPTION(report_t, unrealized);
|
||||||
|
|
@ -960,48 +913,28 @@ public:
|
||||||
OPTION(report_t, unrealized_losses_);
|
OPTION(report_t, unrealized_losses_);
|
||||||
|
|
||||||
OPTION_(report_t, unround, DO() {
|
OPTION_(report_t, unround, DO() {
|
||||||
parent->HANDLER(amount_)
|
OTHER(amount_).on(whence, "unrounded(amount_expr)");
|
||||||
.set_expr(string("--unround"), "unrounded(amount_expr)");
|
OTHER(total_).on(whence, "unrounded(total_expr)");
|
||||||
parent->HANDLER(total_)
|
|
||||||
.set_expr(string("--unround"), "unrounded(total_expr)");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, weekly, DO() { // -W
|
OPTION_(report_t, weekly, DO() { // -W
|
||||||
parent->HANDLER(period_).on(string("--weekly"), "weekly");
|
OTHER(period_).on(whence, "weekly");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, wide, DO() { // -w
|
OPTION_(report_t, wide, DO() { // -w
|
||||||
parent->HANDLER(columns_).on_with(string("--wide"), 132L);
|
OTHER(columns_).on(whence, "132");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, yearly, DO() { // -Y
|
OPTION_(report_t, yearly, DO() { // -Y
|
||||||
parent->HANDLER(period_).on(string("--yearly"), "yearly");
|
OTHER(period_).on(whence, "yearly");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION__(report_t, meta_width_,
|
OPTION(report_t, meta_width_);
|
||||||
bool specified;
|
OPTION(report_t, date_width_);
|
||||||
CTOR(report_t, meta_width_) { specified = false; }
|
OPTION(report_t, payee_width_);
|
||||||
DO_(args) { value = args.get<long>(1); specified = true; });
|
OPTION(report_t, account_width_);
|
||||||
OPTION__(report_t, date_width_,
|
OPTION(report_t, amount_width_);
|
||||||
bool specified;
|
OPTION(report_t, total_width_);
|
||||||
CTOR(report_t, date_width_) { specified = false; }
|
|
||||||
DO_(args) { value = args.get<long>(1); specified = true; });
|
|
||||||
OPTION__(report_t, payee_width_,
|
|
||||||
bool specified;
|
|
||||||
CTOR(report_t, payee_width_) { specified = false; }
|
|
||||||
DO_(args) { value = args.get<long>(1); specified = true; });
|
|
||||||
OPTION__(report_t, account_width_,
|
|
||||||
bool specified;
|
|
||||||
CTOR(report_t, account_width_) { specified = false; }
|
|
||||||
DO_(args) { value = args.get<long>(1); specified = true; });
|
|
||||||
OPTION__(report_t, amount_width_,
|
|
||||||
bool specified;
|
|
||||||
CTOR(report_t, amount_width_) { specified = false; }
|
|
||||||
DO_(args) { value = args.get<long>(1); specified = true; });
|
|
||||||
OPTION__(report_t, total_width_,
|
|
||||||
bool specified;
|
|
||||||
CTOR(report_t, total_width_) { specified = false; }
|
|
||||||
DO_(args) { value = args.get<long>(1); specified = true; });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,28 +128,24 @@ public:
|
||||||
|
|
||||||
OPTION__
|
OPTION__
|
||||||
(session_t, price_exp_, // -Z
|
(session_t, price_exp_, // -Z
|
||||||
CTOR(session_t, price_exp_) { value = 24L * 3600L; }
|
CTOR(session_t, price_exp_) { value = "24"; });
|
||||||
DO_(args) {
|
|
||||||
value = args.get<long>(1) * 60L;
|
|
||||||
});
|
|
||||||
|
|
||||||
OPTION__
|
OPTION__
|
||||||
(session_t, file_, // -f
|
(session_t, file_, // -f
|
||||||
std::list<path> data_files;
|
std::list<path> data_files;
|
||||||
CTOR(session_t, file_) {}
|
CTOR(session_t, file_) {}
|
||||||
DO_(args) {
|
DO_(str) {
|
||||||
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.get<string>(1));
|
data_files.push_back(str);
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(session_t, input_date_format_, DO_(args) {
|
OPTION_(session_t, input_date_format_, DO_(str) {
|
||||||
// This changes static variables inside times.h, which affects the basic
|
// This changes static variables inside times.h, which affects the
|
||||||
// date parser.
|
// basic date parser.
|
||||||
set_input_date_format(args.get<string>(1).c_str());
|
set_input_date_format(str.c_str());
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(session_t, explicit);
|
OPTION(session_t, explicit);
|
||||||
|
|
|
||||||
0
test/baseline/opt-no-pager.test
Normal file
0
test/baseline/opt-no-pager.test
Normal file
Loading…
Add table
Reference in a new issue