First round of work to get the balance report working again.
This commit is contained in:
parent
966b231f23
commit
9c9a34388a
11 changed files with 230 additions and 199 deletions
35
account.cc
35
account.cc
|
|
@ -112,10 +112,33 @@ std::ostream& operator<<(std::ostream& out, const account_t& account)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
value_t get_total(account_t& account) {
|
||||||
|
assert(account.xdata_);
|
||||||
|
return account.xdata_->total;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <value_t (*Func)(account_t&)>
|
||||||
|
value_t get_wrapper(call_scope_t& scope) {
|
||||||
|
return (*Func)(find_scope<account_t>(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expr_t::ptr_op_t account_t::lookup(const string& name)
|
expr_t::ptr_op_t account_t::lookup(const string& name)
|
||||||
{
|
{
|
||||||
switch (name[0]) {
|
switch (name[0]) {
|
||||||
case 'a':
|
case 'f':
|
||||||
|
if (name.find("fmt_") == 0) {
|
||||||
|
switch (name[4]) {
|
||||||
|
case 'T':
|
||||||
|
return WRAP_FUNCTOR(get_wrapper<&get_total>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
if (name == "total")
|
||||||
|
return WRAP_FUNCTOR(get_wrapper<&get_total>);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return expr_t::ptr_op_t();
|
return expr_t::ptr_op_t();
|
||||||
|
|
@ -150,7 +173,11 @@ void account_t::calculate_sums()
|
||||||
foreach (accounts_map::value_type& pair, accounts) {
|
foreach (accounts_map::value_type& pair, accounts) {
|
||||||
(*pair.second).calculate_sums();
|
(*pair.second).calculate_sums();
|
||||||
|
|
||||||
|
if (xd.total.is_null())
|
||||||
|
xd.total = (*pair.second).xdata().total;
|
||||||
|
else
|
||||||
xd.total += (*pair.second).xdata().total;
|
xd.total += (*pair.second).xdata().total;
|
||||||
|
|
||||||
xd.total_count += ((*pair.second).xdata().total_count +
|
xd.total_count += ((*pair.second).xdata().total_count +
|
||||||
(*pair.second).xdata().count);
|
(*pair.second).xdata().count);
|
||||||
}
|
}
|
||||||
|
|
@ -159,8 +186,12 @@ void account_t::calculate_sums()
|
||||||
#if 0
|
#if 0
|
||||||
compute_amount(result, details_t(account));
|
compute_amount(result, details_t(account));
|
||||||
#endif
|
#endif
|
||||||
if (! result.is_realzero())
|
|
||||||
|
if (xd.total.is_null())
|
||||||
|
xd.total = result;
|
||||||
|
else
|
||||||
xd.total += result;
|
xd.total += result;
|
||||||
|
|
||||||
xd.total_count += xd.count;
|
xd.total_count += xd.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
127
main.cc
127
main.cc
|
|
@ -150,52 +150,37 @@ namespace ledger {
|
||||||
return final_value_expr;
|
return final_value_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Formatter = format_xacts>
|
template <class Formatter = format_xacts,
|
||||||
class xacts_report
|
class handler_ptr = xact_handler_ptr,
|
||||||
|
void (report_t::*report_method)(handler_ptr) =
|
||||||
|
&report_t::xacts_report>
|
||||||
|
class reporter
|
||||||
{
|
{
|
||||||
string format_name;
|
string format_name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
xacts_report(const string& _format_name)
|
reporter(const string& _format_name)
|
||||||
: format_name(_format_name) {}
|
: format_name(_format_name) {}
|
||||||
|
|
||||||
value_t operator()(call_scope_t& args)
|
value_t operator()(call_scope_t& args)
|
||||||
{
|
{
|
||||||
ptr_t<std::ostream> ostream(args, 0);
|
|
||||||
var_t<string> format(args, format_name);
|
|
||||||
report_t& report(find_scope<report_t>(args));
|
report_t& report(find_scope<report_t>(args));
|
||||||
|
var_t<string> format(args, format_name);
|
||||||
|
|
||||||
if (! report.format_string.empty())
|
if (! report.format_string.empty())
|
||||||
*format = report.format_string;
|
*format = report.format_string;
|
||||||
|
|
||||||
|
if (args.value().is_sequence() &&
|
||||||
|
args.value().size() > 1) {
|
||||||
if (! report.predicate.empty())
|
if (! report.predicate.empty())
|
||||||
report.predicate = string("(") + report.predicate + ")&";
|
report.predicate = string("(") + report.predicate + ")&";
|
||||||
report.predicate +=
|
report.predicate +=
|
||||||
args_to_predicate(++args.value().as_sequence().begin(),
|
args_to_predicate(++args.value().as_sequence().begin(),
|
||||||
args.value().as_sequence().end());
|
args.value().as_sequence().end());
|
||||||
|
|
||||||
report.xacts_report(xact_handler_ptr(new Formatter(*ostream,
|
|
||||||
*format)));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
template <class Formatter = format_accounts>
|
(report.*report_method)(handler_ptr(new Formatter(report, *format)));
|
||||||
class accounts_report
|
|
||||||
{
|
|
||||||
string format_name;
|
|
||||||
|
|
||||||
public:
|
|
||||||
accounts_report(const string& _format_name)
|
|
||||||
: format_name(_format_name) {}
|
|
||||||
|
|
||||||
value_t operator()(call_scope_t& args)
|
|
||||||
{
|
|
||||||
ptr_t<std::ostream> ostream(args, 0);
|
|
||||||
var_t<string> format(args, format_name);
|
|
||||||
|
|
||||||
find_scope<report_t>(args).accounts_report
|
|
||||||
(acct_handler_ptr(new Formatter(*ostream, *format)));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -261,10 +246,10 @@ namespace ledger {
|
||||||
#ifdef HAVE_UNIX_PIPES
|
#ifdef HAVE_UNIX_PIPES
|
||||||
int status, pfd[2]; // Pipe file descriptors
|
int status, pfd[2]; // Pipe file descriptors
|
||||||
#endif
|
#endif
|
||||||
std::ostream * out = &std::cout;
|
report.output_stream = &std::cout;
|
||||||
|
|
||||||
if (report.output_file) {
|
if (report.output_file) {
|
||||||
out = new ofstream(*report.output_file);
|
report.output_stream = new ofstream(*report.output_file);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_UNIX_PIPES
|
#ifdef HAVE_UNIX_PIPES
|
||||||
else if (report.pager) {
|
else if (report.pager) {
|
||||||
|
|
@ -298,7 +283,7 @@ namespace ledger {
|
||||||
}
|
}
|
||||||
else { // parent
|
else { // parent
|
||||||
close(pfd[0]);
|
close(pfd[0]);
|
||||||
out = new boost::fdostream(pfd[1]);
|
report.output_stream = new boost::fdostream(pfd[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -306,80 +291,82 @@ namespace ledger {
|
||||||
// Read the command word and see if it's any of the debugging commands
|
// Read the command word and see if it's any of the debugging commands
|
||||||
// that Ledger supports.
|
// that Ledger supports.
|
||||||
|
|
||||||
|
std::ostream& out(*report.output_stream);
|
||||||
|
|
||||||
string verb = *arg++;
|
string verb = *arg++;
|
||||||
|
|
||||||
if (verb == "parse") {
|
if (verb == "parse") {
|
||||||
expr_t expr(*arg);
|
expr_t expr(*arg);
|
||||||
|
|
||||||
*out << "Value expression as input: " << *arg << std::endl;
|
out << "Value expression as input: " << *arg << std::endl;
|
||||||
|
|
||||||
*out << "Value expression as parsed: ";
|
out << "Value expression as parsed: ";
|
||||||
expr.print(*out, report);
|
expr.print(out, report);
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
|
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
*out << "--- Parsed tree ---" << std::endl;
|
out << "--- Parsed tree ---" << std::endl;
|
||||||
expr.dump(*out);
|
expr.dump(out);
|
||||||
|
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
*out << "--- Calculated value ---" << std::endl;
|
out << "--- Calculated value ---" << std::endl;
|
||||||
expr.calc(report).print(*out);
|
expr.calc(report).print(out);
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (verb == "compile") {
|
else if (verb == "compile") {
|
||||||
expr_t expr(*arg);
|
expr_t expr(*arg);
|
||||||
|
|
||||||
*out << "Value expression as input: " << *arg << std::endl;
|
out << "Value expression as input: " << *arg << std::endl;
|
||||||
*out << "Value expression as parsed: ";
|
out << "Value expression as parsed: ";
|
||||||
expr.print(*out, report);
|
expr.print(out, report);
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
|
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
*out << "--- Parsed tree ---" << std::endl;
|
out << "--- Parsed tree ---" << std::endl;
|
||||||
expr.dump(*out);
|
expr.dump(out);
|
||||||
|
|
||||||
expr.compile(report);
|
expr.compile(report);
|
||||||
|
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
*out << "--- Compiled tree ---" << std::endl;
|
out << "--- Compiled tree ---" << std::endl;
|
||||||
expr.dump(*out);
|
expr.dump(out);
|
||||||
|
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
*out << "--- Calculated value ---" << std::endl;
|
out << "--- Calculated value ---" << std::endl;
|
||||||
expr.calc(report).print(*out);
|
expr.calc(report).print(out);
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (verb == "eval") {
|
else if (verb == "eval") {
|
||||||
expr_t expr(*arg);
|
expr_t expr(*arg);
|
||||||
*out << expr.calc(report).strip_annotations() << std::endl;
|
out << expr.calc(report).strip_annotations() << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (verb == "format") {
|
else if (verb == "format") {
|
||||||
format_t fmt(*arg);
|
format_t fmt(*arg);
|
||||||
fmt.dump(*out);
|
fmt.dump(out);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (verb == "period") {
|
else if (verb == "period") {
|
||||||
interval_t interval(*arg);
|
interval_t interval(*arg);
|
||||||
|
|
||||||
if (! is_valid(interval.begin)) {
|
if (! is_valid(interval.begin)) {
|
||||||
*out << "Time period has no beginning." << std::endl;
|
out << "Time period has no beginning." << std::endl;
|
||||||
} else {
|
} else {
|
||||||
*out << "begin: " << format_date(interval.begin) << std::endl;
|
out << "begin: " << format_date(interval.begin) << std::endl;
|
||||||
*out << " end: " << format_date(interval.end) << std::endl;
|
out << " end: " << format_date(interval.end) << std::endl;
|
||||||
*out << std::endl;
|
out << std::endl;
|
||||||
|
|
||||||
date_t date = interval.first();
|
date_t date = interval.first();
|
||||||
|
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
*out << std::right;
|
out << std::right;
|
||||||
out->width(2);
|
out.width(2);
|
||||||
|
|
||||||
*out << i << ": " << format_date(date) << std::endl;
|
out << i << ": " << format_date(date) << std::endl;
|
||||||
|
|
||||||
date = interval.increment(date);
|
date = interval.increment(date);
|
||||||
if (is_valid(interval.end) && date >= interval.end)
|
if (is_valid(interval.end) && date >= interval.end)
|
||||||
|
|
@ -420,13 +407,15 @@ namespace ledger {
|
||||||
function_t command;
|
function_t command;
|
||||||
|
|
||||||
if (verb == "register" || verb == "reg" || verb == "r")
|
if (verb == "register" || verb == "reg" || verb == "r")
|
||||||
command = xacts_report<>("register_format");
|
command = reporter<>("register_format");
|
||||||
else if (verb == "print" || verb == "p")
|
else if (verb == "print" || verb == "p")
|
||||||
command = xacts_report<>("print_format");
|
command = reporter<>("print_format");
|
||||||
else if (verb == "balance" || verb == "bal" || verb == "b")
|
else if (verb == "balance" || verb == "bal" || verb == "b")
|
||||||
command = accounts_report<>("balance_format");
|
command = reporter<format_accounts, acct_handler_ptr,
|
||||||
|
&report_t::accounts_report>("balance_format");
|
||||||
else if (verb == "equity")
|
else if (verb == "equity")
|
||||||
command = accounts_report<format_equity>("print_format");
|
command = reporter<format_equity, acct_handler_ptr,
|
||||||
|
&report_t::accounts_report>("print_format");
|
||||||
#if 0
|
#if 0
|
||||||
else if (verb == "entry")
|
else if (verb == "entry")
|
||||||
command = entry_command();
|
command = entry_command();
|
||||||
|
|
@ -462,8 +451,6 @@ namespace ledger {
|
||||||
|
|
||||||
call_scope_t command_args(report);
|
call_scope_t command_args(report);
|
||||||
|
|
||||||
command_args.push_back(value_t(out));
|
|
||||||
|
|
||||||
for (strings_list::iterator i = arg; i != args.end(); i++)
|
for (strings_list::iterator i = arg; i != args.end(); i++)
|
||||||
command_args.push_back(string_value(*i));
|
command_args.push_back(string_value(*i));
|
||||||
|
|
||||||
|
|
@ -490,7 +477,7 @@ namespace ledger {
|
||||||
|
|
||||||
#ifdef HAVE_UNIX_PIPES
|
#ifdef HAVE_UNIX_PIPES
|
||||||
if (! report.output_file && report.pager) {
|
if (! report.output_file && report.pager) {
|
||||||
checked_delete(out);
|
checked_delete(report.output_stream);
|
||||||
close(pfd[1]);
|
close(pfd[1]);
|
||||||
|
|
||||||
// Wait for child to finish
|
// Wait for child to finish
|
||||||
|
|
@ -500,7 +487,7 @@ namespace ledger {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (DO_VERIFY() && report.output_file) {
|
else if (DO_VERIFY() && report.output_file) {
|
||||||
checked_delete(out);
|
checked_delete(report.output_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
76
output.cc
76
output.cc
|
|
@ -33,13 +33,13 @@
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
format_xacts::format_xacts(std::ostream& _output_stream,
|
format_xacts::format_xacts(report_t& _report, const string& format)
|
||||||
const string& format)
|
: report(_report), last_entry(NULL), last_xact(NULL)
|
||||||
: output_stream(_output_stream), last_entry(NULL), last_xact(NULL)
|
|
||||||
{
|
{
|
||||||
TRACE_CTOR(format_xacts, "std::ostream&, const string&");
|
TRACE_CTOR(format_xacts, "report&, const string&");
|
||||||
|
|
||||||
const char * f = format.c_str();
|
const char * f = format.c_str();
|
||||||
|
|
||||||
if (const char * p = std::strstr(f, "%/")) {
|
if (const char * p = std::strstr(f, "%/")) {
|
||||||
first_line_format.parse(string(f, 0, p - f));
|
first_line_format.parse(string(f, 0, p - f));
|
||||||
next_lines_format.parse(string(p + 2));
|
next_lines_format.parse(string(p + 2));
|
||||||
|
|
@ -51,17 +51,19 @@ format_xacts::format_xacts(std::ostream& _output_stream,
|
||||||
|
|
||||||
void format_xacts::operator()(xact_t& xact)
|
void format_xacts::operator()(xact_t& xact)
|
||||||
{
|
{
|
||||||
|
std::ostream& out(*report.output_stream);
|
||||||
|
|
||||||
if (! xact.has_xdata() ||
|
if (! xact.has_xdata() ||
|
||||||
! xact.xdata().has_flags(XACT_EXT_DISPLAYED)) {
|
! xact.xdata().has_flags(XACT_EXT_DISPLAYED)) {
|
||||||
if (last_entry != xact.entry) {
|
if (last_entry != xact.entry) {
|
||||||
first_line_format.format(output_stream, xact);
|
first_line_format.format(out, xact);
|
||||||
last_entry = xact.entry;
|
last_entry = xact.entry;
|
||||||
}
|
}
|
||||||
else if (last_xact && last_xact->date() != xact.date()) {
|
else if (last_xact && last_xact->date() != xact.date()) {
|
||||||
first_line_format.format(output_stream, xact);
|
first_line_format.format(out, xact);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
next_lines_format.format(output_stream, xact);
|
next_lines_format.format(out, xact);
|
||||||
}
|
}
|
||||||
|
|
||||||
xact.xdata().add_flags(XACT_EXT_DISPLAYED);
|
xact.xdata().add_flags(XACT_EXT_DISPLAYED);
|
||||||
|
|
@ -72,15 +74,16 @@ void format_xacts::operator()(xact_t& xact)
|
||||||
void format_entries::format_last_entry()
|
void format_entries::format_last_entry()
|
||||||
{
|
{
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
std::ostream& out(*report.output_stream);
|
||||||
|
|
||||||
foreach (xact_t * xact, last_entry->xacts) {
|
foreach (xact_t * xact, last_entry->xacts) {
|
||||||
if (xact->has_xdata() &&
|
if (xact->has_xdata() &&
|
||||||
xact->xdata().has_flags(XACT_EXT_TO_DISPLAY)) {
|
xact->xdata().has_flags(XACT_EXT_TO_DISPLAY)) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first_line_format.format(output_stream, *xact);
|
first_line_format.format(out, *xact);
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
next_lines_format.format(output_stream, *xact);
|
next_lines_format.format(out, *xact);
|
||||||
}
|
}
|
||||||
xact->xdata().add_flags(XACT_EXT_DISPLAYED);
|
xact->xdata().add_flags(XACT_EXT_DISPLAYED);
|
||||||
}
|
}
|
||||||
|
|
@ -131,13 +134,37 @@ void print_entry(std::ostream& out, const entry_base_t& entry_base,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void format_accounts::flush()
|
||||||
|
{
|
||||||
|
std::ostream& out(*report.output_stream);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// jww (2008-08-02): I need access to the output formatter before this is
|
||||||
|
// going to work.
|
||||||
|
if (print_final_total) {
|
||||||
|
assert(out);
|
||||||
|
assert(account_has_xdata(*session.master));
|
||||||
|
|
||||||
|
account_xdata_t& xdata(account_xdata(*session.master));
|
||||||
|
|
||||||
|
if (! show_collapsed && xdata.total) {
|
||||||
|
out << "--------------------\n";
|
||||||
|
xdata.value = xdata.total;
|
||||||
|
handler->format.format(out, *session.master);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
void format_accounts::operator()(account_t& account)
|
void format_accounts::operator()(account_t& account)
|
||||||
{
|
{
|
||||||
if (display_account(account)) {
|
if (display_account(account)) {
|
||||||
if (! account.parent) {
|
if (! account.parent) {
|
||||||
account.xdata().add_flags(ACCOUNT_EXT_TO_DISPLAY);
|
account.xdata().add_flags(ACCOUNT_EXT_TO_DISPLAY);
|
||||||
} else {
|
} else {
|
||||||
format.format(output_stream, account);
|
format.format(*report.output_stream, account);
|
||||||
account.xdata().add_flags(ACCOUNT_EXT_DISPLAYED);
|
account.xdata().add_flags(ACCOUNT_EXT_DISPLAYED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -159,13 +186,11 @@ bool format_accounts::disp_subaccounts_p(account_t& account,
|
||||||
if (! disp_pred(*pair.second))
|
if (! disp_pred(*pair.second))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#if 0
|
call_scope_t args(*pair.second);
|
||||||
compute_total(result, *pair.second);
|
result = report.get_total_expr(args);
|
||||||
#endif
|
|
||||||
if (! computed) {
|
if (! computed) {
|
||||||
#if 0
|
call_scope_t args(account);
|
||||||
compute_total(acct_total, account);
|
acct_total = report.get_total_expr(args);
|
||||||
#endif
|
|
||||||
computed = true;
|
computed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,10 +226,10 @@ bool format_accounts::display_account(account_t& account)
|
||||||
return ! account_to_show && disp_pred(account);
|
return ! account_to_show && disp_pred(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
format_equity::format_equity(std::ostream& _output_stream,
|
format_equity::format_equity(report_t& _report,
|
||||||
const string& _format,
|
const string& _format,
|
||||||
const string& display_predicate)
|
const string& display_predicate)
|
||||||
: format_accounts(_output_stream, "", display_predicate)
|
: format_accounts(_report, "", display_predicate)
|
||||||
{
|
{
|
||||||
const char * f = _format.c_str();
|
const char * f = _format.c_str();
|
||||||
|
|
||||||
|
|
@ -219,7 +244,7 @@ format_equity::format_equity(std::ostream& _output_stream,
|
||||||
entry_t header_entry;
|
entry_t header_entry;
|
||||||
header_entry.payee = "Opening Balances";
|
header_entry.payee = "Opening Balances";
|
||||||
header_entry._date = current_date;
|
header_entry._date = current_date;
|
||||||
first_line_format.format(output_stream, header_entry);
|
first_line_format.format(*report.output_stream, header_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_equity::flush()
|
void format_equity::flush()
|
||||||
|
|
@ -227,6 +252,7 @@ void format_equity::flush()
|
||||||
account_t summary(NULL, "Equity:Opening Balances");
|
account_t summary(NULL, "Equity:Opening Balances");
|
||||||
|
|
||||||
account_t::xdata_t& xdata(summary.xdata());
|
account_t::xdata_t& xdata(summary.xdata());
|
||||||
|
std::ostream& out(*report.output_stream);
|
||||||
|
|
||||||
xdata.value = total.negate();
|
xdata.value = total.negate();
|
||||||
|
|
||||||
|
|
@ -242,16 +268,18 @@ void format_equity::flush()
|
||||||
foreach (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 = pair.second;
|
||||||
xdata.value.negate();
|
xdata.value.negate();
|
||||||
next_lines_format.format(output_stream, summary);
|
next_lines_format.format(out, summary);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
next_lines_format.format(output_stream, summary);
|
next_lines_format.format(out, summary);
|
||||||
}
|
}
|
||||||
output_stream.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_equity::operator()(account_t& account)
|
void format_equity::operator()(account_t& account)
|
||||||
{
|
{
|
||||||
|
std::ostream& out(*report.output_stream);
|
||||||
|
|
||||||
if (display_account(account)) {
|
if (display_account(account)) {
|
||||||
if (account.has_xdata()) {
|
if (account.has_xdata()) {
|
||||||
value_t val = account.xdata().value;
|
value_t val = account.xdata().value;
|
||||||
|
|
@ -267,11 +295,11 @@ void format_equity::operator()(account_t& account)
|
||||||
|
|
||||||
foreach (balance_t::amounts_map::value_type pair, bal->amounts) {
|
foreach (balance_t::amounts_map::value_type pair, bal->amounts) {
|
||||||
account.xdata().value = pair.second;
|
account.xdata().value = pair.second;
|
||||||
next_lines_format.format(output_stream, account);
|
next_lines_format.format(out, account);
|
||||||
}
|
}
|
||||||
account.xdata().value = val;
|
account.xdata().value = val;
|
||||||
} else {
|
} else {
|
||||||
next_lines_format.format(output_stream, account);
|
next_lines_format.format(out, account);
|
||||||
}
|
}
|
||||||
total += val;
|
total += val;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
33
output.h
33
output.h
|
|
@ -32,7 +32,7 @@
|
||||||
#ifndef _OUTPUT_H
|
#ifndef _OUTPUT_H
|
||||||
#define _OUTPUT_H
|
#define _OUTPUT_H
|
||||||
|
|
||||||
#include "session.h"
|
#include "report.h"
|
||||||
#include "handler.h"
|
#include "handler.h"
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
|
||||||
|
|
@ -41,21 +41,20 @@ namespace ledger {
|
||||||
class format_xacts : public item_handler<xact_t>
|
class format_xacts : public item_handler<xact_t>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
std::ostream& output_stream;
|
report_t& report;
|
||||||
format_t first_line_format;
|
format_t first_line_format;
|
||||||
format_t next_lines_format;
|
format_t next_lines_format;
|
||||||
entry_t * last_entry;
|
entry_t * last_entry;
|
||||||
xact_t * last_xact;
|
xact_t * last_xact;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
format_xacts(std::ostream& _output_stream,
|
format_xacts(report_t& _report, const string& format);
|
||||||
const string& format);
|
|
||||||
virtual ~format_xacts() {
|
virtual ~format_xacts() {
|
||||||
TRACE_DTOR(format_xacts);
|
TRACE_DTOR(format_xacts);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void flush() {
|
virtual void flush() {
|
||||||
output_stream.flush();
|
report.output_stream->flush();
|
||||||
}
|
}
|
||||||
virtual void operator()(xact_t& xact);
|
virtual void operator()(xact_t& xact);
|
||||||
};
|
};
|
||||||
|
|
@ -63,9 +62,9 @@ public:
|
||||||
class format_entries : public format_xacts
|
class format_entries : public format_xacts
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
format_entries(std::ostream& output_stream, const string& format)
|
format_entries(report_t& _report, const string& format)
|
||||||
: format_xacts(output_stream, format) {
|
: format_xacts(_report, format) {
|
||||||
TRACE_CTOR(format_entries, "std::ostream&, const string&");
|
TRACE_CTOR(format_entries, "report_t&, const string&");
|
||||||
}
|
}
|
||||||
virtual ~format_entries() {
|
virtual ~format_entries() {
|
||||||
TRACE_DTOR(format_entries);
|
TRACE_DTOR(format_entries);
|
||||||
|
|
@ -91,7 +90,7 @@ private:
|
||||||
class format_accounts : public item_handler<account_t>
|
class format_accounts : public item_handler<account_t>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
std::ostream& output_stream;
|
report_t& report;
|
||||||
|
|
||||||
item_predicate<account_t> disp_pred;
|
item_predicate<account_t> disp_pred;
|
||||||
|
|
||||||
|
|
@ -101,20 +100,18 @@ protected:
|
||||||
public:
|
public:
|
||||||
format_t format;
|
format_t format;
|
||||||
|
|
||||||
format_accounts(std::ostream& _output_stream,
|
format_accounts(report_t& _report,
|
||||||
const string& _format,
|
const string& _format,
|
||||||
const string& display_predicate = "")
|
const string& display_predicate = "" /*,
|
||||||
: output_stream(_output_stream), disp_pred(display_predicate),
|
const bool print_final_total = true */)
|
||||||
format(_format) {
|
: report(_report), disp_pred(display_predicate), format(_format) {
|
||||||
TRACE_CTOR(format_accounts, "std::ostream&, const string&, const string&");
|
TRACE_CTOR(format_accounts, "report&, const string&, const string&");
|
||||||
}
|
}
|
||||||
virtual ~format_accounts() {
|
virtual ~format_accounts() {
|
||||||
TRACE_DTOR(format_accounts);
|
TRACE_DTOR(format_accounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void flush() {
|
virtual void flush();
|
||||||
output_stream.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void operator()(account_t& account);
|
virtual void operator()(account_t& account);
|
||||||
};
|
};
|
||||||
|
|
@ -127,7 +124,7 @@ class format_equity : public format_accounts
|
||||||
mutable value_t total;
|
mutable value_t total;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
format_equity(std::ostream& _output_stream,
|
format_equity(report_t& _report,
|
||||||
const string& _format,
|
const string& _format,
|
||||||
const string& display_predicate = "");
|
const string& display_predicate = "");
|
||||||
virtual ~format_equity() {
|
virtual ~format_equity() {
|
||||||
|
|
|
||||||
20
report.cc
20
report.cc
|
|
@ -331,9 +331,7 @@ void report_t::sum_all_accounts()
|
||||||
session.master->calculate_sums();
|
session.master->calculate_sums();
|
||||||
}
|
}
|
||||||
|
|
||||||
void report_t::accounts_report(acct_handler_ptr handler,
|
void report_t::accounts_report(acct_handler_ptr handler)
|
||||||
const bool print_final_total,
|
|
||||||
optional<std::ostream&> ostream)
|
|
||||||
{
|
{
|
||||||
sum_all_accounts();
|
sum_all_accounts();
|
||||||
|
|
||||||
|
|
@ -346,22 +344,6 @@ void report_t::accounts_report(acct_handler_ptr handler,
|
||||||
}
|
}
|
||||||
handler->flush();
|
handler->flush();
|
||||||
|
|
||||||
#if 0
|
|
||||||
// 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(*ostream, *session.master);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (DO_VERIFY()) {
|
if (DO_VERIFY()) {
|
||||||
session.clean_xacts();
|
session.clean_xacts();
|
||||||
session.clean_accounts();
|
session.clean_accounts();
|
||||||
|
|
|
||||||
5
report.h
5
report.h
|
|
@ -87,6 +87,7 @@ class report_t : public noncopyable, public scope_t
|
||||||
|
|
||||||
public:
|
public:
|
||||||
optional<path> output_file;
|
optional<path> output_file;
|
||||||
|
std::ostream * output_stream;
|
||||||
|
|
||||||
string format_string;
|
string format_string;
|
||||||
string date_output_format;
|
string date_output_format;
|
||||||
|
|
@ -186,9 +187,7 @@ public:
|
||||||
|
|
||||||
void sum_all_accounts();
|
void sum_all_accounts();
|
||||||
|
|
||||||
void accounts_report(acct_handler_ptr handler,
|
void accounts_report(acct_handler_ptr handler);
|
||||||
const bool print_final_total = true,
|
|
||||||
optional<std::ostream&> ostream = none);
|
|
||||||
|
|
||||||
void commodities_report(const string& format);
|
void commodities_report(const string& format);
|
||||||
|
|
||||||
|
|
|
||||||
3
value.cc
3
value.cc
|
|
@ -835,6 +835,9 @@ value_t& value_t::operator/=(const value_t& val)
|
||||||
bool value_t::operator==(const value_t& val) const
|
bool value_t::operator==(const value_t& val) const
|
||||||
{
|
{
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
|
case VOID:
|
||||||
|
return val.type() == VOID;
|
||||||
|
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
if (val.is_boolean())
|
if (val.is_boolean())
|
||||||
return as_boolean() == val.as_boolean();
|
return as_boolean() == val.as_boolean();
|
||||||
|
|
|
||||||
2
xact.cc
2
xact.cc
|
|
@ -266,6 +266,8 @@ void xact_t::add_to_value(value_t& value)
|
||||||
value += xdata_->value;
|
value += xdata_->value;
|
||||||
}
|
}
|
||||||
else if (cost || (! value.is_null() && ! value.is_realzero())) {
|
else if (cost || (! value.is_null() && ! value.is_realzero())) {
|
||||||
|
if (value.is_null())
|
||||||
|
value = amount_t();
|
||||||
value.add(amount, cost);
|
value.add(amount, cost);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
72
xml.cc
72
xml.cc
|
|
@ -387,28 +387,30 @@ void output_xml_string(std::ostream& out, const string& str)
|
||||||
|
|
||||||
void format_xml_entries::format_last_entry()
|
void format_xml_entries::format_last_entry()
|
||||||
{
|
{
|
||||||
|
std::ostream& out(*report.output_stream);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// jww (2008-05-08): Need to format these dates
|
// jww (2008-05-08): Need to format these dates
|
||||||
output_stream << " <entry>\n"
|
out << " <entry>\n"
|
||||||
<< " <en:date>" << last_entry->_date.to_string("%Y/%m/%d")
|
<< " <en:date>" << last_entry->_date.to_string("%Y/%m/%d")
|
||||||
<< "</en:date>\n";
|
<< "</en:date>\n";
|
||||||
|
|
||||||
if (is_valid(last_entry->_date_eff))
|
if (is_valid(last_entry->_date_eff))
|
||||||
output_stream << " <en:date_eff>"
|
out << " <en:date_eff>"
|
||||||
<< last_entry->_date_eff.to_string("%Y/%m/%d")
|
<< last_entry->_date_eff.to_string("%Y/%m/%d")
|
||||||
<< "</en:date_eff>\n";
|
<< "</en:date_eff>\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (last_entry->code) {
|
if (last_entry->code) {
|
||||||
output_stream << " <en:code>";
|
out << " <en:code>";
|
||||||
output_xml_string(output_stream, *last_entry->code);
|
output_xml_string(out, *last_entry->code);
|
||||||
output_stream << "</en:code>\n";
|
out << "</en:code>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! last_entry->payee.empty()) {
|
if (! last_entry->payee.empty()) {
|
||||||
output_stream << " <en:payee>";
|
out << " <en:payee>";
|
||||||
output_xml_string(output_stream, last_entry->payee);
|
output_xml_string(out, last_entry->payee);
|
||||||
output_stream << "</en:payee>\n";
|
out << "</en:payee>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
@ -416,34 +418,34 @@ void format_xml_entries::format_last_entry()
|
||||||
if (xact->has_xdata() &&
|
if (xact->has_xdata() &&
|
||||||
xact->xdata().has_flags(XACT_EXT_TO_DISPLAY)) {
|
xact->xdata().has_flags(XACT_EXT_TO_DISPLAY)) {
|
||||||
if (first) {
|
if (first) {
|
||||||
output_stream << " <en:xacts>\n";
|
out << " <en:xacts>\n";
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
output_stream << " <xact>\n";
|
out << " <xact>\n";
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// jww (2008-05-08): Need to format these
|
// jww (2008-05-08): Need to format these
|
||||||
if (xact->_date)
|
if (xact->_date)
|
||||||
output_stream << " <tr:date>"
|
out << " <tr:date>"
|
||||||
<< xact->_date.to_string("%Y/%m/%d")
|
<< xact->_date.to_string("%Y/%m/%d")
|
||||||
<< "</tr:date>\n";
|
<< "</tr:date>\n";
|
||||||
|
|
||||||
if (is_valid(xact->_date_eff))
|
if (is_valid(xact->_date_eff))
|
||||||
output_stream << " <tr:date_eff>"
|
out << " <tr:date_eff>"
|
||||||
<< xact->_date_eff.to_string("%Y/%m/%d")
|
<< xact->_date_eff.to_string("%Y/%m/%d")
|
||||||
<< "</tr:date_eff>\n";
|
<< "</tr:date_eff>\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (xact->state == xact_t::CLEARED)
|
if (xact->state == xact_t::CLEARED)
|
||||||
output_stream << " <tr:cleared/>\n";
|
out << " <tr:cleared/>\n";
|
||||||
else if (xact->state == xact_t::PENDING)
|
else if (xact->state == xact_t::PENDING)
|
||||||
output_stream << " <tr:pending/>\n";
|
out << " <tr:pending/>\n";
|
||||||
|
|
||||||
if (xact->has_flags(XACT_VIRTUAL))
|
if (xact->has_flags(XACT_VIRTUAL))
|
||||||
output_stream << " <tr:virtual/>\n";
|
out << " <tr:virtual/>\n";
|
||||||
if (xact->has_flags(XACT_AUTO))
|
if (xact->has_flags(XACT_AUTO))
|
||||||
output_stream << " <tr:generated/>\n";
|
out << " <tr:generated/>\n";
|
||||||
|
|
||||||
if (xact->account) {
|
if (xact->account) {
|
||||||
string name = xact->account->fullname();
|
string name = xact->account->fullname();
|
||||||
|
|
@ -452,46 +454,46 @@ void format_xml_entries::format_last_entry()
|
||||||
else if (name == "<Unknown>")
|
else if (name == "<Unknown>")
|
||||||
name = "[UNKNOWN]";
|
name = "[UNKNOWN]";
|
||||||
|
|
||||||
output_stream << " <tr:account>";
|
out << " <tr:account>";
|
||||||
output_xml_string(output_stream, name);
|
output_xml_string(out, name);
|
||||||
output_stream << "</tr:account>\n";
|
out << "</tr:account>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
output_stream << " <tr:amount>\n";
|
out << " <tr:amount>\n";
|
||||||
if (xact->xdata().has_flags(XACT_EXT_COMPOUND))
|
if (xact->xdata().has_flags(XACT_EXT_COMPOUND))
|
||||||
xml_write_value(output_stream, xact->xdata().value, 10);
|
xml_write_value(out, xact->xdata().value, 10);
|
||||||
else
|
else
|
||||||
xml_write_value(output_stream, value_t(xact->amount), 10);
|
xml_write_value(out, value_t(xact->amount), 10);
|
||||||
output_stream << " </tr:amount>\n";
|
out << " </tr:amount>\n";
|
||||||
|
|
||||||
if (xact->cost) {
|
if (xact->cost) {
|
||||||
output_stream << " <tr:cost>\n";
|
out << " <tr:cost>\n";
|
||||||
xml_write_value(output_stream, value_t(*xact->cost), 10);
|
xml_write_value(out, value_t(*xact->cost), 10);
|
||||||
output_stream << " </tr:cost>\n";
|
out << " </tr:cost>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xact->note) {
|
if (xact->note) {
|
||||||
output_stream << " <tr:note>";
|
out << " <tr:note>";
|
||||||
output_xml_string(output_stream, *xact->note);
|
output_xml_string(out, *xact->note);
|
||||||
output_stream << "</tr:note>\n";
|
out << "</tr:note>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_totals) {
|
if (show_totals) {
|
||||||
output_stream << " <total>\n";
|
out << " <total>\n";
|
||||||
xml_write_value(output_stream, xact->xdata().total, 10);
|
xml_write_value(out, xact->xdata().total, 10);
|
||||||
output_stream << " </total>\n";
|
out << " </total>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
output_stream << " </xact>\n";
|
out << " </xact>\n";
|
||||||
|
|
||||||
xact->xdata().add_flags(XACT_EXT_DISPLAYED);
|
xact->xdata().add_flags(XACT_EXT_DISPLAYED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! first)
|
if (! first)
|
||||||
output_stream << " </en:xacts>\n";
|
out << " </en:xacts>\n";
|
||||||
|
|
||||||
output_stream << " </entry>\n";
|
out << " </entry>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
8
xml.h
8
xml.h
|
|
@ -61,11 +61,11 @@ class format_xml_entries : public format_entries
|
||||||
format_xml_entries();
|
format_xml_entries();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
format_xml_entries(std::ostream& output_stream,
|
format_xml_entries(report_t& _report,
|
||||||
const bool _show_totals = false)
|
const bool _show_totals = false)
|
||||||
: format_entries(output_stream, ""), show_totals(_show_totals) {
|
: format_entries(_report, ""), show_totals(_show_totals) {
|
||||||
TRACE_CTOR(format_xml_entries, "std::ostream&, const bool");
|
TRACE_CTOR(format_xml_entries, "std::ostream&, const bool");
|
||||||
output_stream << "<?xml version=\"1.0\"?>\n"
|
*report.output_stream << "<?xml version=\"1.0\"?>\n"
|
||||||
<< "<ledger version=\"2.5\">\n";
|
<< "<ledger version=\"2.5\">\n";
|
||||||
}
|
}
|
||||||
virtual ~format_xml_entries() throw() {
|
virtual ~format_xml_entries() throw() {
|
||||||
|
|
@ -74,7 +74,7 @@ public:
|
||||||
|
|
||||||
virtual void flush() {
|
virtual void flush() {
|
||||||
format_entries::flush();
|
format_entries::flush();
|
||||||
output_stream << "</ledger>" << std::endl;
|
*report.output_stream << "</ledger>" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void format_last_entry();
|
virtual void format_last_entry();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue