Re-enabled almost all of the old reporting code, which means it compiles now
within the new scheme.
This commit is contained in:
parent
5a90fe7357
commit
dfc14dfff3
6 changed files with 313 additions and 244 deletions
1
expr.h
1
expr.h
|
|
@ -39,6 +39,7 @@ namespace ledger {
|
|||
DECLARE_EXCEPTION(parse_error, std::runtime_error);
|
||||
DECLARE_EXCEPTION(compile_error, std::runtime_error);
|
||||
DECLARE_EXCEPTION(calc_error, std::runtime_error);
|
||||
DECLARE_EXCEPTION(usage_error, std::runtime_error);
|
||||
|
||||
class scope_t;
|
||||
class call_scope_t;
|
||||
|
|
|
|||
3
format.h
3
format.h
|
|
@ -61,6 +61,7 @@ class format_t : public noncopyable
|
|||
string format_string;
|
||||
scoped_ptr<element_t> elements;
|
||||
|
||||
public:
|
||||
enum elision_style_t {
|
||||
TRUNCATE_TRAILING,
|
||||
TRUNCATE_MIDDLE,
|
||||
|
|
@ -68,6 +69,8 @@ class format_t : public noncopyable
|
|||
ABBREVIATE
|
||||
};
|
||||
|
||||
private:
|
||||
// jww (2008-08-02): Should these four be here, or in session_t?
|
||||
static elision_style_t elision_style;
|
||||
static int abbrev_length;
|
||||
|
||||
|
|
|
|||
413
report.cc
413
report.cc
|
|
@ -34,6 +34,185 @@
|
|||
|
||||
namespace ledger {
|
||||
|
||||
#if 0
|
||||
void
|
||||
report_t::regexps_to_predicate(const std::string& command,
|
||||
std::list<std::string>::const_iterator begin,
|
||||
std::list<std::string>::const_iterator end,
|
||||
const bool account_regexp,
|
||||
const bool add_account_short_masks,
|
||||
const bool logical_and)
|
||||
{
|
||||
std::string regexps[2];
|
||||
|
||||
assert(begin != end);
|
||||
|
||||
// Treat the remaining command-line arguments as regular
|
||||
// expressions, used for refining report results.
|
||||
|
||||
for (std::list<std::string>::const_iterator i = begin;
|
||||
i != end;
|
||||
i++)
|
||||
if ((*i)[0] == '-') {
|
||||
if (! regexps[1].empty())
|
||||
regexps[1] += "|";
|
||||
regexps[1] += (*i).substr(1);
|
||||
}
|
||||
else if ((*i)[0] == '+') {
|
||||
if (! regexps[0].empty())
|
||||
regexps[0] += "|";
|
||||
regexps[0] += (*i).substr(1);
|
||||
}
|
||||
else {
|
||||
if (! regexps[0].empty())
|
||||
regexps[0] += "|";
|
||||
regexps[0] += *i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (regexps[i].empty())
|
||||
continue;
|
||||
|
||||
if (! predicate.empty())
|
||||
predicate += logical_and ? "&" : "|";
|
||||
|
||||
int add_predicate = 0; // 1 adds /.../, 2 adds ///.../
|
||||
if (i == 1) {
|
||||
predicate += "!";
|
||||
}
|
||||
else if (add_account_short_masks) {
|
||||
if (regexps[i].find(':') != std::string::npos ||
|
||||
regexps[i].find('.') != std::string::npos ||
|
||||
regexps[i].find('*') != std::string::npos ||
|
||||
regexps[i].find('+') != std::string::npos ||
|
||||
regexps[i].find('[') != std::string::npos ||
|
||||
regexps[i].find('(') != std::string::npos) {
|
||||
show_subtotal = true;
|
||||
add_predicate = 1;
|
||||
} else {
|
||||
add_predicate = 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
add_predicate = 1;
|
||||
}
|
||||
|
||||
if (i != 1 && command == "b" && account_regexp) {
|
||||
if (! show_related && ! show_all_related) {
|
||||
if (! display_predicate.empty())
|
||||
display_predicate += "&";
|
||||
if (! show_empty)
|
||||
display_predicate += "T&";
|
||||
|
||||
if (add_predicate == 2)
|
||||
display_predicate += "//";
|
||||
display_predicate += "/(?:";
|
||||
display_predicate += regexps[i];
|
||||
display_predicate += ")/";
|
||||
}
|
||||
else if (! show_empty) {
|
||||
if (! display_predicate.empty())
|
||||
display_predicate += "&";
|
||||
display_predicate += "T";
|
||||
}
|
||||
}
|
||||
|
||||
if (! account_regexp)
|
||||
predicate += "/";
|
||||
predicate += "/(?:";
|
||||
predicate += regexps[i];
|
||||
predicate += ")/";
|
||||
}
|
||||
}
|
||||
|
||||
void report_t::process_options(const std::string& command,
|
||||
strings_list::iterator arg,
|
||||
strings_list::iterator args_end)
|
||||
{
|
||||
// Configure some other options depending on report type
|
||||
|
||||
if (command == "p" || command == "e" || command == "w") {
|
||||
show_related =
|
||||
show_all_related = true;
|
||||
}
|
||||
else if (command == "E") {
|
||||
show_subtotal = true;
|
||||
}
|
||||
else if (show_related) {
|
||||
if (command == "r") {
|
||||
show_inverted = true;
|
||||
} else {
|
||||
show_subtotal = true;
|
||||
show_all_related = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (command != "b" && command != "r")
|
||||
amount_t::keep_base = true;
|
||||
|
||||
// Process remaining command-line arguments
|
||||
|
||||
if (command != "e") {
|
||||
// Treat the remaining command-line arguments as regular
|
||||
// expressions, used for refining report results.
|
||||
|
||||
std::list<std::string>::iterator i = arg;
|
||||
for (; i != args_end; i++)
|
||||
if (*i == "--")
|
||||
break;
|
||||
|
||||
if (i != arg)
|
||||
regexps_to_predicate(command, arg, i, true,
|
||||
(command == "b" && ! show_subtotal &&
|
||||
display_predicate.empty()));
|
||||
if (i != args_end && ++i != args_end)
|
||||
regexps_to_predicate(command, i, args_end);
|
||||
}
|
||||
|
||||
// Setup the default value for the display predicate
|
||||
|
||||
if (display_predicate.empty()) {
|
||||
if (command == "b") {
|
||||
if (! show_empty)
|
||||
display_predicate = "T";
|
||||
if (! show_subtotal) {
|
||||
if (! display_predicate.empty())
|
||||
display_predicate += "&";
|
||||
display_predicate += "l<=1";
|
||||
}
|
||||
}
|
||||
else if (command == "E") {
|
||||
display_predicate = "t";
|
||||
}
|
||||
else if (command == "r" && ! show_empty) {
|
||||
display_predicate = "a";
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_PRINT("ledger.config.predicates", "Predicate: " << predicate);
|
||||
DEBUG_PRINT("ledger.config.predicates", "Display P: " << display_predicate);
|
||||
|
||||
// Setup the values of %t and %T, used in format strings
|
||||
|
||||
if (! amount_expr.empty())
|
||||
ledger::amount_expr = amount_expr;
|
||||
if (! total_expr.empty())
|
||||
ledger::total_expr = total_expr;
|
||||
|
||||
// Now setup the various formatting strings
|
||||
|
||||
if (! date_output_format.empty())
|
||||
date_t::output_format = date_output_format;
|
||||
|
||||
amount_t::keep_price = keep_price;
|
||||
amount_t::keep_date = keep_date;
|
||||
amount_t::keep_tag = keep_tag;
|
||||
|
||||
if (! report_period.empty() && ! sort_all)
|
||||
entry_sort = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
xact_handler_ptr
|
||||
report_t::chain_xact_handlers(xact_handler_ptr base_handler,
|
||||
const bool handle_individual_xacts)
|
||||
|
|
@ -179,7 +358,7 @@ report_t::chain_xact_handlers(xact_handler_ptr base_handler,
|
|||
budget_xacts * budget_handler
|
||||
= new budget_xacts(handler, budget_flags);
|
||||
budget_handler->add_period_entries(journal->period_entries);
|
||||
handler.reset(budget_handler;
|
||||
handler.reset(budget_handler);
|
||||
|
||||
// Apply this before the budget handler, so that only matching
|
||||
// xacts are calculated toward the budget. The use of
|
||||
|
|
@ -239,8 +418,9 @@ void report_t::sum_all_accounts()
|
|||
sum_accounts(*session.master);
|
||||
}
|
||||
|
||||
void report_t::accounts_report(acct_handler_ptr handler,
|
||||
const bool print_final_total)
|
||||
void report_t::accounts_report(acct_handler_ptr handler,
|
||||
const bool print_final_total,
|
||||
optional<std::ostream&> ostream)
|
||||
{
|
||||
sum_all_accounts();
|
||||
|
||||
|
|
@ -253,16 +433,21 @@ void report_t::accounts_report(acct_handler_ptr handler,
|
|||
}
|
||||
handler->flush();
|
||||
|
||||
if (print_final_total && account_has_xdata(*session.master)) {
|
||||
account_xdata_t& xdata = account_xdata(*session.master);
|
||||
if (! show_collapsed && xdata.total) {
|
||||
#if 0
|
||||
*out << "--------------------\n";
|
||||
// jww (2008-08-02): I need access to the output formatter before this is
|
||||
// going to work.
|
||||
if (print_final_total) {
|
||||
assert(ostream);
|
||||
assert(account_has_xdata(*session.master));
|
||||
|
||||
account_xdata_t& xdata(account_xdata(*session.master));
|
||||
if (! show_collapsed && xdata.total) {
|
||||
*ostream << "--------------------\n";
|
||||
xdata.value = xdata.total;
|
||||
handler->format.format(*out, details_t(*journal->master));
|
||||
#endif
|
||||
handler->format.format(*ostream, *session.master);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (DO_VERIFY()) {
|
||||
session.clean_xacts();
|
||||
|
|
@ -278,30 +463,24 @@ void report_t::entry_report(const entry_t& entry, const string& format)
|
|||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
value_t report_t::abbrev(call_scope_t& args)
|
||||
{
|
||||
if (args.size() < 2)
|
||||
throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
|
||||
throw_(usage_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
|
||||
|
||||
string str = args[0].as_string();
|
||||
#if 0
|
||||
long wid = args[1];
|
||||
const var_t<string> str(args, 0);
|
||||
const var_t<long> wid(args, 1);
|
||||
const var_t<long> style(args, 2);
|
||||
const var_t<long> abbrev_len(args, 3);
|
||||
|
||||
elision_style_t style = session.elision_style;
|
||||
if (args.size() == 3)
|
||||
style = static_cast<elision_style_t>(args[2].as_long());
|
||||
#endif
|
||||
|
||||
long abbrev_len = session.abbrev_length;
|
||||
if (args.size() == 4)
|
||||
abbrev_len = args[3].as_long();
|
||||
|
||||
#if 0
|
||||
return value_t(abbreviate(str, wid, style, true,
|
||||
static_cast<int>(abbrev_len)), true);
|
||||
#else
|
||||
return NULL_VALUE;
|
||||
#endif
|
||||
return value_t(abbreviate(*str, *wid,
|
||||
(style ?
|
||||
static_cast<format_t::elision_style_t>(*style) :
|
||||
session.elision_style),
|
||||
true,
|
||||
abbrev_len ? *abbrev_len : session.abbrev_len),
|
||||
true);
|
||||
}
|
||||
|
||||
value_t report_t::ftime(call_scope_t& args)
|
||||
|
|
@ -314,36 +493,10 @@ value_t report_t::ftime(call_scope_t& args)
|
|||
string date_format;
|
||||
if (args.size() == 2)
|
||||
date_format = args[1].as_string();
|
||||
#if 0
|
||||
// jww (2007-04-18): Need to setup an output facet here
|
||||
else
|
||||
date_format = moment_t::output_format;
|
||||
|
||||
return string_value(date.as_string(date_format));
|
||||
#else
|
||||
return NULL_VALUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
optional<value_t>
|
||||
report_t::resolve(const string& name, call_scope_t& args)
|
||||
{
|
||||
const char * p = name.c_str();
|
||||
switch (*p) {
|
||||
case 'a':
|
||||
if (name == "abbrev") {
|
||||
return abbrev(args);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (name == "ftime") {
|
||||
return ftime(args);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return scope_t::resolve(name, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -356,13 +509,8 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
|
|||
p = p + 4;
|
||||
switch (*p) {
|
||||
case 'a':
|
||||
#if 0
|
||||
if (std::strcmp(p, "accounts") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_accounts);
|
||||
else
|
||||
#endif
|
||||
if (std::strcmp(p, "amount") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_amount);
|
||||
if (std::strcmp(p, "amount") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_amount);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
|
|
@ -370,73 +518,11 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
|
|||
return MAKE_FUNCTOR(report_t::option_bar);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 'c':
|
||||
if (std::strcmp(p, "clean") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_clean);
|
||||
else if (std::strcmp(p, "compact") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_compact);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'e':
|
||||
#if 0
|
||||
if (std::strcmp(p, "entries") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_entries);
|
||||
else if (std::strcmp(p, "eval") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_eval);
|
||||
else if (std::strcmp(p, "exclude") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_remove);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
#if 0
|
||||
if (std::strcmp(p, "foo") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_foo);
|
||||
else
|
||||
#endif
|
||||
if (std::strcmp(p, "format") == 0)
|
||||
if (std::strcmp(p, "format") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_format);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
#if 0
|
||||
if (std::strcmp(p, "include") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_select);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
#if 0
|
||||
if (! *(p + 1) || std::strcmp(p, "limit") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_limit);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 'm':
|
||||
if (std::strcmp(p, "merge") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_merge);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'r':
|
||||
#if 0
|
||||
if (std::strcmp(p, "remove") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_remove);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 's':
|
||||
if (std::strcmp(p, "select") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_select);
|
||||
else if (std::strcmp(p, "split") == 0)
|
||||
return MAKE_FUNCTOR(report_t::option_split);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 't':
|
||||
if (! *(p + 1))
|
||||
return MAKE_FUNCTOR(report_t::option_amount);
|
||||
|
|
@ -496,21 +582,20 @@ void format_xacts::operator()(xact_t& xact)
|
|||
|
||||
void format_entries::format_last_entry()
|
||||
{
|
||||
#if 0
|
||||
bool first = true;
|
||||
foreach (const transaction_t * xact, last_entry->xacts) {
|
||||
if (xact_has_xdata(*xact) &&
|
||||
xact_xdata_(*xact).dflags & XACT_TO_DISPLAY) {
|
||||
|
||||
foreach (xact_t * xact, last_entry->xacts) {
|
||||
if (xact->has_xdata() &&
|
||||
xact->xdata().has_flags(XACT_EXT_TO_DISPLAY)) {
|
||||
if (first) {
|
||||
first_line_format.format(output_stream, details_t(*xact));
|
||||
first_line_format.format(output_stream, *xact);
|
||||
first = false;
|
||||
} else {
|
||||
next_lines_format.format(output_stream, details_t(*xact));
|
||||
next_lines_format.format(output_stream, *xact);
|
||||
}
|
||||
xact_xdata_(*xact).dflags |= XACT_DISPLAYED;
|
||||
xact->xdata().add_flags(XACT_EXT_DISPLAYED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void format_entries::operator()(xact_t& xact)
|
||||
|
|
@ -557,29 +642,30 @@ void print_entry(std::ostream& out, const entry_base_t& entry_base,
|
|||
#endif
|
||||
}
|
||||
|
||||
bool disp_subaccounts_p(const account_t& account,
|
||||
bool disp_subaccounts_p(account_t& account,
|
||||
item_predicate<account_t>& disp_pred,
|
||||
const account_t *& to_show)
|
||||
account_t *& to_show)
|
||||
{
|
||||
bool display = false;
|
||||
#if 0
|
||||
unsigned int counted = 0;
|
||||
bool matches = disp_pred ? (*disp_pred)(account) : true;
|
||||
bool matches = disp_pred(account);
|
||||
bool computed = false;
|
||||
#endif
|
||||
value_t acct_total;
|
||||
value_t result;
|
||||
|
||||
to_show = NULL;
|
||||
|
||||
#if 0
|
||||
for (accounts_map::value_type pair, account.accounts) {
|
||||
if (disp_pred && ! (*disp_pred)(*pair.second))
|
||||
foreach (accounts_map::value_type pair, account.accounts) {
|
||||
if (! disp_pred(*pair.second))
|
||||
continue;
|
||||
|
||||
compute_total(result, details_t(*pair.second));
|
||||
#if 0
|
||||
compute_total(result, *pair.second);
|
||||
#endif
|
||||
if (! computed) {
|
||||
compute_total(acct_total, details_t(account));
|
||||
#if 0
|
||||
compute_total(acct_total, account);
|
||||
#endif
|
||||
computed = true;
|
||||
}
|
||||
|
||||
|
|
@ -590,13 +676,11 @@ bool disp_subaccounts_p(const account_t& account,
|
|||
to_show = pair.second;
|
||||
counted++;
|
||||
}
|
||||
#endif
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
bool display_account(const account_t& account,
|
||||
item_predicate<account_t>& disp_pred)
|
||||
bool display_account(account_t& account, item_predicate<account_t>& disp_pred)
|
||||
{
|
||||
// Never display an account that has already been displayed.
|
||||
if (account_has_xdata(account) &&
|
||||
|
|
@ -610,26 +694,23 @@ bool display_account(const account_t& account,
|
|||
// determine if it is a parent that must be displayed regardless of
|
||||
// the predicate.
|
||||
|
||||
const account_t * account_to_show = NULL;
|
||||
account_t * account_to_show = NULL;
|
||||
if (disp_subaccounts_p(account, disp_pred, account_to_show))
|
||||
return true;
|
||||
|
||||
return (! account_to_show &&
|
||||
disp_pred(const_cast<account_t&>(account)));
|
||||
return ! account_to_show && disp_pred(account);
|
||||
}
|
||||
|
||||
void format_accounts::operator()(account_t& account)
|
||||
{
|
||||
#if 0
|
||||
if (display_account(account, disp_pred)) {
|
||||
if (! account.parent) {
|
||||
account_xdata(account).dflags |= ACCOUNT_TO_DISPLAY;
|
||||
} else {
|
||||
format.format(output_stream, details_t(account));
|
||||
format.format(output_stream, account);
|
||||
account_xdata(account).dflags |= ACCOUNT_DISPLAYED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
format_equity::format_equity(std::ostream& _output_stream,
|
||||
|
|
@ -637,26 +718,23 @@ format_equity::format_equity(std::ostream& _output_stream,
|
|||
const string& display_predicate)
|
||||
: output_stream(_output_stream), disp_pred(display_predicate)
|
||||
{
|
||||
#if 0
|
||||
const char * f = _format.c_str();
|
||||
if (const char * p = std::strstr(f, "%/")) {
|
||||
first_line_format.reset(string(f, 0, p - f));
|
||||
next_lines_format.reset(string(p + 2));
|
||||
first_line_format.parse(string(f, 0, p - f));
|
||||
next_lines_format.parse(string(p + 2));
|
||||
} else {
|
||||
first_line_format.reset(_format);
|
||||
next_lines_format.reset(_format);
|
||||
first_line_format.parse(_format);
|
||||
next_lines_format.parse(_format);
|
||||
}
|
||||
|
||||
entry_t header_entry;
|
||||
header_entry.payee = "Opening Balances";
|
||||
header_entry._date = current_moment;
|
||||
first_line_format.format(output_stream, details_t(header_entry));
|
||||
#endif
|
||||
header_entry._date = current_date;
|
||||
first_line_format.format(output_stream, header_entry);
|
||||
}
|
||||
|
||||
void format_equity::flush()
|
||||
{
|
||||
#if 0
|
||||
account_xdata_t xdata;
|
||||
xdata.value = total;
|
||||
xdata.value.negate();
|
||||
|
|
@ -672,21 +750,19 @@ void format_equity::flush()
|
|||
else
|
||||
assert(false);
|
||||
|
||||
for (balance_t::amounts_map::value_type pair, bal->amounts) {
|
||||
foreach (balance_t::amounts_map::value_type pair, bal->amounts) {
|
||||
xdata.value = pair.second;
|
||||
xdata.value.negate();
|
||||
next_lines_format.format(output_stream, details_t(summary));
|
||||
next_lines_format.format(output_stream, summary);
|
||||
}
|
||||
} else {
|
||||
next_lines_format.format(output_stream, details_t(summary));
|
||||
next_lines_format.format(output_stream, summary);
|
||||
}
|
||||
output_stream.flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
void format_equity::operator()(account_t& account)
|
||||
{
|
||||
#if 0
|
||||
if (display_account(account, disp_pred)) {
|
||||
if (account_has_xdata(account)) {
|
||||
value_t val = account_xdata_(account).value;
|
||||
|
|
@ -700,19 +776,18 @@ void format_equity::operator()(account_t& account)
|
|||
else
|
||||
assert(false);
|
||||
|
||||
for (balance_t::amounts_map::value_type pair, bal->amounts) {
|
||||
foreach (balance_t::amounts_map::value_type pair, bal->amounts) {
|
||||
account_xdata_(account).value = pair.second;
|
||||
next_lines_format.format(output_stream, details_t(account));
|
||||
next_lines_format.format(output_stream, account);
|
||||
}
|
||||
account_xdata_(account).value = val;
|
||||
} else {
|
||||
next_lines_format.format(output_stream, details_t(account));
|
||||
next_lines_format.format(output_stream, account);
|
||||
}
|
||||
total += val;
|
||||
}
|
||||
account_xdata(account).dflags |= ACCOUNT_DISPLAYED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
83
report.h
83
report.h
|
|
@ -88,9 +88,8 @@ class report_t : public noncopyable, public scope_t
|
|||
|
||||
public:
|
||||
optional<path> output_file;
|
||||
|
||||
string format_string;
|
||||
string amount_expr;
|
||||
string total_expr;
|
||||
string date_output_format;
|
||||
string predicate;
|
||||
string secondary_predicate;
|
||||
|
|
@ -103,6 +102,9 @@ public:
|
|||
string reconcile_balance;
|
||||
string reconcile_date;
|
||||
|
||||
expr_t amount_expr;
|
||||
expr_t total_expr;
|
||||
|
||||
unsigned long budget_flags;
|
||||
|
||||
int head_entries;
|
||||
|
|
@ -135,7 +137,10 @@ public:
|
|||
session_t& session;
|
||||
|
||||
explicit report_t(session_t& _session)
|
||||
: head_entries(0),
|
||||
: amount_expr("amount"),
|
||||
total_expr("total"),
|
||||
|
||||
head_entries(0),
|
||||
tail_entries(0),
|
||||
|
||||
show_collapsed(false),
|
||||
|
|
@ -162,13 +167,6 @@ public:
|
|||
session(_session)
|
||||
{
|
||||
TRACE_CTOR(report_t, "session_t&");
|
||||
|
||||
#if 0
|
||||
eval("t=total,TOT=0,T()=(TOT=TOT+t,TOT)");
|
||||
|
||||
value_expr_t::amount_expr.reset(new value_expr("a"));
|
||||
value_expr_t::total_expr.reset(new value_expr("O"));
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~report_t() {
|
||||
|
|
@ -189,8 +187,9 @@ public:
|
|||
|
||||
void sum_all_accounts();
|
||||
|
||||
void accounts_report(acct_handler_ptr handler,
|
||||
const bool print_final_total = true);
|
||||
void accounts_report(acct_handler_ptr handler,
|
||||
const bool print_final_total = true,
|
||||
optional<std::ostream&> ostream = none);
|
||||
|
||||
void commodities_report(const string& format);
|
||||
|
||||
|
|
@ -243,54 +242,6 @@ public:
|
|||
return args[0];
|
||||
}
|
||||
|
||||
//
|
||||
// Transform options
|
||||
//
|
||||
|
||||
#if 0
|
||||
value_t option_select(call_scope_t& args) {
|
||||
transforms.push_back(new select_transform(args[0].as_string()));
|
||||
return NULL_VALUE;
|
||||
}
|
||||
value_t option_limit(call_scope_t& args) {
|
||||
string expr = (string("//xact[") +
|
||||
args[0].as_string() + "]");
|
||||
transforms.push_back(new select_transform(expr));
|
||||
return NULL_VALUE;
|
||||
}
|
||||
|
||||
value_t option_remove(call_scope_t& args) {
|
||||
transforms.push_back(new remove_transform(args[0].as_string()));
|
||||
return NULL_VALUE;
|
||||
}
|
||||
|
||||
value_t option_accounts(call_scope_t& args) {
|
||||
transforms.push_back(new accounts_transform);
|
||||
return NULL_VALUE;
|
||||
}
|
||||
value_t option_compact(call_scope_t& args) {
|
||||
transforms.push_back(new compact_transform);
|
||||
return NULL_VALUE;
|
||||
}
|
||||
value_t option_clean(call_scope_t& args) {
|
||||
transforms.push_back(new clean_transform);
|
||||
return NULL_VALUE;
|
||||
}
|
||||
value_t option_entries(call_scope_t& args) {
|
||||
transforms.push_back(new entries_transform);
|
||||
return NULL_VALUE;
|
||||
}
|
||||
|
||||
value_t option_split(call_scope_t& args) {
|
||||
transforms.push_back(new split_transform);
|
||||
return NULL_VALUE;
|
||||
}
|
||||
value_t option_merge(call_scope_t& args) {
|
||||
transforms.push_back(new merge_transform);
|
||||
return NULL_VALUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Scope members
|
||||
//
|
||||
|
|
@ -348,15 +299,15 @@ class format_entries : public format_xacts
|
|||
virtual void operator()(xact_t& xact);
|
||||
};
|
||||
|
||||
void print_entry(std::ostream& out, const entry_base_t& entry,
|
||||
const string& prefix = "");
|
||||
void print_entry(std::ostream& out,
|
||||
const entry_base_t& entry,
|
||||
const string& prefix = "");
|
||||
|
||||
bool disp_subaccounts_p(const account_t& account,
|
||||
bool disp_subaccounts_p(account_t& account,
|
||||
item_predicate<account_t>& disp_pred,
|
||||
const account_t *& to_show);
|
||||
account_t *& to_show);
|
||||
|
||||
bool display_account(const account_t& account,
|
||||
item_predicate<account_t>& disp_pred);
|
||||
bool display_account(account_t& account, item_predicate<account_t>& disp_pred);
|
||||
|
||||
class format_accounts : public item_handler<account_t>
|
||||
{
|
||||
|
|
|
|||
52
scope.h
52
scope.h
|
|
@ -209,27 +209,67 @@ public:
|
|||
template <typename T>
|
||||
class var_t : public noncopyable
|
||||
{
|
||||
value_t value;
|
||||
optional<value_t> value;
|
||||
|
||||
var_t();
|
||||
|
||||
public:
|
||||
var_t(scope_t& scope, const string& name) : value(scope.resolve(name)) {
|
||||
var_t(scope_t& scope, const string& name)
|
||||
{
|
||||
TRACE_CTOR(var_t, "scope_t&, const string&");
|
||||
|
||||
try {
|
||||
value = scope.resolve(name);
|
||||
}
|
||||
catch (...) {
|
||||
DEBUG("scope.var_t", "Failed lookup var_t(\"" << name << "\")");
|
||||
value = none;
|
||||
}
|
||||
}
|
||||
var_t(call_scope_t& scope, const unsigned int idx) : value(scope[idx]) {
|
||||
|
||||
var_t(call_scope_t& scope, const unsigned int idx)
|
||||
{
|
||||
TRACE_CTOR(var_t, "call_scope_t&, const unsigned int");
|
||||
|
||||
if (idx < scope.size())
|
||||
value = scope[idx];
|
||||
else
|
||||
value = none;
|
||||
}
|
||||
|
||||
~var_t() throw() {
|
||||
TRACE_DTOR(var_t);
|
||||
}
|
||||
|
||||
operator T() { assert(false); }
|
||||
operator bool() { return value; }
|
||||
|
||||
T& operator *();
|
||||
const T& operator *() const;
|
||||
|
||||
T * operator->() {
|
||||
return &**this;
|
||||
}
|
||||
const T * operator->() const {
|
||||
return &**this;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
inline var_t<long>::operator long() {
|
||||
return value.to_long();
|
||||
inline long& var_t<long>::operator *() {
|
||||
return value->as_long_lval();
|
||||
}
|
||||
template <>
|
||||
inline const long& var_t<long>::operator *() const {
|
||||
return value->as_long();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline string& var_t<string>::operator *() {
|
||||
return value->as_string_lval();
|
||||
}
|
||||
template <>
|
||||
inline const string& var_t<string>::operator *() const {
|
||||
return value->as_string();
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "scope.h"
|
||||
#include "journal.h"
|
||||
#include "account.h"
|
||||
#include "format.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
|
|
@ -75,9 +76,7 @@ public:
|
|||
datetime_t now;
|
||||
date_t today;
|
||||
|
||||
#if 0
|
||||
elision_style_t elision_style;
|
||||
#endif
|
||||
format_t::elision_style_t elision_style;
|
||||
int abbrev_length;
|
||||
|
||||
bool ansi_codes;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue