Rewrote the balance report again, to fix --depth
This commit is contained in:
parent
dd6c0ae80d
commit
77faaa926f
7 changed files with 199 additions and 59 deletions
|
|
@ -136,7 +136,7 @@ string account_t::partial_name(bool flat) const
|
||||||
acct && acct->parent;
|
acct && acct->parent;
|
||||||
acct = acct->parent) {
|
acct = acct->parent) {
|
||||||
if (! flat) {
|
if (! flat) {
|
||||||
std::size_t count = acct->children_with_flags(ACCOUNT_EXT_MATCHING);
|
std::size_t count = acct->children_with_flags(ACCOUNT_EXT_TO_DISPLAY);
|
||||||
assert(count > 0);
|
assert(count > 0);
|
||||||
if (count > 1)
|
if (count > 1)
|
||||||
break;
|
break;
|
||||||
|
|
@ -198,7 +198,7 @@ namespace {
|
||||||
for (const account_t * acct = account.parent;
|
for (const account_t * acct = account.parent;
|
||||||
acct && acct->parent;
|
acct && acct->parent;
|
||||||
acct = acct->parent) {
|
acct = acct->parent) {
|
||||||
std::size_t count = acct->children_with_flags(ACCOUNT_EXT_MATCHING);
|
std::size_t count = acct->children_with_flags(ACCOUNT_EXT_TO_DISPLAY);
|
||||||
assert(count > 0);
|
assert(count > 0);
|
||||||
if (count > 1)
|
if (count > 1)
|
||||||
depth++;
|
depth++;
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,8 @@ class account_t : public scope_t
|
||||||
#define ACCOUNT_EXT_AUTO_VIRTUALIZE 0x08
|
#define ACCOUNT_EXT_AUTO_VIRTUALIZE 0x08
|
||||||
#define ACCOUNT_EXT_VISITED 0x10
|
#define ACCOUNT_EXT_VISITED 0x10
|
||||||
#define ACCOUNT_EXT_MATCHING 0x20
|
#define ACCOUNT_EXT_MATCHING 0x20
|
||||||
#define ACCOUNT_EXT_DISPLAYED 0x40
|
#define ACCOUNT_EXT_TO_DISPLAY 0x40
|
||||||
|
#define ACCOUNT_EXT_DISPLAYED 0x80
|
||||||
|
|
||||||
struct details_t
|
struct details_t
|
||||||
{
|
{
|
||||||
|
|
|
||||||
101
src/output.cc
101
src/output.cc
|
|
@ -117,12 +117,6 @@ format_accounts::format_accounts(report_t& _report,
|
||||||
{
|
{
|
||||||
TRACE_CTOR(format_accounts, "report&, const string&");
|
TRACE_CTOR(format_accounts, "report&, const string&");
|
||||||
|
|
||||||
if (report.HANDLED(display_)) {
|
|
||||||
DEBUG("account.display",
|
|
||||||
"Account display predicate: " << report.HANDLER(display_).str());
|
|
||||||
disp_pred.predicate.parse(report.HANDLER(display_).str());
|
|
||||||
}
|
|
||||||
|
|
||||||
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, "%/")) {
|
||||||
|
|
@ -142,48 +136,62 @@ format_accounts::format_accounts(report_t& _report,
|
||||||
|
|
||||||
void format_accounts::post_account(account_t& account)
|
void format_accounts::post_account(account_t& account)
|
||||||
{
|
{
|
||||||
bind_scope_t bound_scope(report, account);
|
if (account.xdata().has_flags(ACCOUNT_EXT_TO_DISPLAY)) {
|
||||||
bool format_account = false;
|
|
||||||
|
|
||||||
DEBUG("account.display", "Should we display " << account.fullname());
|
|
||||||
|
|
||||||
if (account.has_flags(ACCOUNT_EXT_MATCHING) ||
|
|
||||||
(! report.HANDLED(flat) &&
|
|
||||||
account.children_with_flags(ACCOUNT_EXT_MATCHING) > 1)) {
|
|
||||||
DEBUG("account.display", " Yes, because it matched");
|
|
||||||
format_account = true;
|
|
||||||
}
|
|
||||||
else if (! report.HANDLED(flat) &&
|
|
||||||
account.children_with_flags(ACCOUNT_EXT_VISITED) &&
|
|
||||||
! account.children_with_flags(ACCOUNT_EXT_MATCHING)) {
|
|
||||||
DEBUG("account.display",
|
|
||||||
" Maybe, because it has visited, but no matching, children");
|
|
||||||
if (disp_pred(bound_scope)) {
|
|
||||||
DEBUG("account.display",
|
|
||||||
" And yes, because it matches the display predicate");
|
|
||||||
format_account = true;
|
|
||||||
} else {
|
|
||||||
DEBUG("account.display",
|
|
||||||
" And no, because it didn't match the display predicate");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DEBUG("account.display",
|
|
||||||
" No, neither it nor its children were eligible for display");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format_account) {
|
|
||||||
account.xdata().add_flags(ACCOUNT_EXT_DISPLAYED);
|
account.xdata().add_flags(ACCOUNT_EXT_DISPLAYED);
|
||||||
|
|
||||||
|
bind_scope_t bound_scope(report, account);
|
||||||
account_line_format.format(report.output_stream, bound_scope);
|
account_line_format.format(report.output_stream, bound_scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<std::size_t, std::size_t>
|
||||||
|
format_accounts::mark_accounts(account_t& account, const bool flat)
|
||||||
|
{
|
||||||
|
std::size_t visited = 0;
|
||||||
|
std::size_t to_display = 0;
|
||||||
|
|
||||||
|
foreach (accounts_map::value_type& pair, account.accounts) {
|
||||||
|
std::pair<std::size_t, std::size_t> i = mark_accounts(*pair.second, flat);
|
||||||
|
visited += i.first;
|
||||||
|
to_display += i.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG_ON)
|
||||||
|
DEBUG("account.display", "Considering account: " << account.fullname());
|
||||||
|
if (account.has_flags(ACCOUNT_EXT_VISITED))
|
||||||
|
DEBUG("account.display", " it was visited itself");
|
||||||
|
DEBUG("account.display", " it has " << visited << " visited children");
|
||||||
|
DEBUG("account.display",
|
||||||
|
" it has " << to_display << " children to display");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (account.has_flags(ACCOUNT_EXT_VISITED) || (! flat && visited > 0)) {
|
||||||
|
bind_scope_t bound_scope(report, account);
|
||||||
|
if (disp_pred(bound_scope) && (flat || to_display != 1)) {
|
||||||
|
account.xdata().add_flags(ACCOUNT_EXT_TO_DISPLAY);
|
||||||
|
DEBUG("account.display", "Marking account as TO_DISPLAY");
|
||||||
|
to_display = 1;
|
||||||
|
}
|
||||||
|
visited = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::pair<std::size_t, std::size_t>(visited, to_display);
|
||||||
|
}
|
||||||
|
|
||||||
void format_accounts::flush()
|
void format_accounts::flush()
|
||||||
{
|
{
|
||||||
std::ostream& out(report.output_stream);
|
std::ostream& out(report.output_stream);
|
||||||
|
|
||||||
|
if (report.HANDLED(display_)) {
|
||||||
|
DEBUG("account.display",
|
||||||
|
"Account display predicate: " << report.HANDLER(display_).str());
|
||||||
|
disp_pred.predicate.parse(report.HANDLER(display_).str());
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t top_displayed = 0;
|
std::size_t top_displayed = 0;
|
||||||
|
|
||||||
|
mark_accounts(*report.session.master, report.HANDLED(flat));
|
||||||
|
|
||||||
foreach (account_t * account, posted_accounts) {
|
foreach (account_t * account, posted_accounts) {
|
||||||
post_account(*account);
|
post_account(*account);
|
||||||
|
|
||||||
|
|
@ -194,8 +202,9 @@ void format_accounts::flush()
|
||||||
if (! report.HANDLED(flat)) {
|
if (! report.HANDLED(flat)) {
|
||||||
foreach (accounts_map::value_type pair, report.session.master->accounts) {
|
foreach (accounts_map::value_type pair, report.session.master->accounts) {
|
||||||
if (pair.second->has_flags(ACCOUNT_EXT_DISPLAYED) ||
|
if (pair.second->has_flags(ACCOUNT_EXT_DISPLAYED) ||
|
||||||
pair.second->children_with_flags(ACCOUNT_EXT_DISPLAYED))
|
pair.second->children_with_flags(ACCOUNT_EXT_DISPLAYED)) {
|
||||||
top_displayed++;
|
top_displayed++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,22 +220,6 @@ void format_accounts::flush()
|
||||||
|
|
||||||
void format_accounts::operator()(account_t& account)
|
void format_accounts::operator()(account_t& account)
|
||||||
{
|
{
|
||||||
DEBUG("account.display",
|
|
||||||
"Proposing to format account: " << account.fullname());
|
|
||||||
|
|
||||||
if (account.has_flags(ACCOUNT_EXT_VISITED)) {
|
|
||||||
DEBUG("account.display", " Account or its children was visited");
|
|
||||||
|
|
||||||
bind_scope_t bound_scope(report, account);
|
|
||||||
if (disp_pred(bound_scope)) {
|
|
||||||
DEBUG("account.display",
|
|
||||||
" And the account matched the display predicate");
|
|
||||||
account.xdata().add_flags(ACCOUNT_EXT_MATCHING);
|
|
||||||
} else {
|
|
||||||
DEBUG("account.display",
|
|
||||||
" But it did not match the display predicate");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
posted_accounts.push_back(&account);
|
posted_accounts.push_back(&account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,12 @@
|
||||||
#include "chain.h"
|
#include "chain.h"
|
||||||
#include "predicate.h"
|
#include "predicate.h"
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
#include "account.h"
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
class xact_t;
|
class xact_t;
|
||||||
class post_t;
|
class post_t;
|
||||||
class account_t;
|
|
||||||
class report_t;
|
class report_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -106,6 +106,9 @@ public:
|
||||||
TRACE_DTOR(format_accounts);
|
TRACE_DTOR(format_accounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<std::size_t, std::size_t>
|
||||||
|
mark_accounts(account_t& account, const bool flat);
|
||||||
|
|
||||||
virtual void post_account(account_t& account);
|
virtual void post_account(account_t& account);
|
||||||
virtual void flush();
|
virtual void flush();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -304,7 +304,7 @@ public:
|
||||||
|
|
||||||
OPTION_(report_t, depth_, DO_(scope) {
|
OPTION_(report_t, depth_, DO_(scope) {
|
||||||
interactive_t args(scope, "l");
|
interactive_t args(scope, "l");
|
||||||
parent->HANDLER(limit_).on(string("depth<=") + args.get<string>(0));
|
parent->HANDLER(display_).on(string("depth<=") + args.get<string>(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION_(report_t, deviation, DO() { // -D
|
OPTION_(report_t, deviation, DO() { // -D
|
||||||
|
|
|
||||||
83
test/baseline/opt-depth.test
Normal file
83
test/baseline/opt-depth.test
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
bal --depth 1
|
||||||
|
<<<
|
||||||
|
2008/01/01 January
|
||||||
|
Expenses:Books $10.00
|
||||||
|
Assets:Cash
|
||||||
|
|
||||||
|
2008/01/01 January
|
||||||
|
Expenses:One:Books $10.00
|
||||||
|
Expenses:One:Two:Books $10.00
|
||||||
|
Expenses:One:Two:Three:Books $10.00
|
||||||
|
Assets:Cash
|
||||||
|
|
||||||
|
2008/01/01 January
|
||||||
|
Assets:Cash 0
|
||||||
|
Income:Books
|
||||||
|
|
||||||
|
2008/01/01 January
|
||||||
|
Assets:Cash
|
||||||
|
Income:One:Books $-10.00
|
||||||
|
Income:One:Two:Books $-10.00
|
||||||
|
Income:One:Two:Three:Books $-10.00
|
||||||
|
>>>1
|
||||||
|
$-10.00 Assets
|
||||||
|
$40.00 Expenses
|
||||||
|
$-30.00 Income
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
|
bal --depth 2
|
||||||
|
>>>1
|
||||||
|
$-10.00 Assets:Cash
|
||||||
|
$40.00 Expenses
|
||||||
|
$10.00 Books
|
||||||
|
$30.00 One
|
||||||
|
$-30.00 Income:One
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
|
bal --depth 3
|
||||||
|
>>>1
|
||||||
|
$-10.00 Assets:Cash
|
||||||
|
$40.00 Expenses
|
||||||
|
$10.00 Books
|
||||||
|
$30.00 One
|
||||||
|
$10.00 Books
|
||||||
|
$20.00 Two
|
||||||
|
$-30.00 Income:One
|
||||||
|
$-10.00 Books
|
||||||
|
$-20.00 Two
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
|
bal --depth 4
|
||||||
|
>>>1
|
||||||
|
$-10.00 Assets:Cash
|
||||||
|
$40.00 Expenses
|
||||||
|
$10.00 Books
|
||||||
|
$30.00 One
|
||||||
|
$10.00 Books
|
||||||
|
$20.00 Two
|
||||||
|
$10.00 Books
|
||||||
|
$10.00 Three
|
||||||
|
$-30.00 Income:One
|
||||||
|
$-10.00 Books
|
||||||
|
$-20.00 Two
|
||||||
|
$-10.00 Books
|
||||||
|
$-10.00 Three
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
|
bal --depth 5
|
||||||
|
>>>1
|
||||||
|
$-10.00 Assets:Cash
|
||||||
|
$40.00 Expenses
|
||||||
|
$10.00 Books
|
||||||
|
$30.00 One
|
||||||
|
$10.00 Books
|
||||||
|
$20.00 Two
|
||||||
|
$10.00 Books
|
||||||
|
$10.00 Three:Books
|
||||||
|
$-30.00 Income:One
|
||||||
|
$-10.00 Books
|
||||||
|
$-20.00 Two
|
||||||
|
$-10.00 Books
|
||||||
|
$-10.00 Three:Books
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
60
test/baseline/opt-depth_flat.test
Normal file
60
test/baseline/opt-depth_flat.test
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
bal --depth 1 --flat
|
||||||
|
<<<
|
||||||
|
2008/01/01 January
|
||||||
|
Expenses:Books $10.00
|
||||||
|
Assets:Cash
|
||||||
|
|
||||||
|
2008/01/01 January
|
||||||
|
Expenses:One:Books $10.00
|
||||||
|
Expenses:One:Two:Books $10.00
|
||||||
|
Expenses:One:Two:Three:Books $10.00
|
||||||
|
Assets:Cash
|
||||||
|
|
||||||
|
2008/01/01 January
|
||||||
|
Assets:Cash 0
|
||||||
|
Income:Books
|
||||||
|
|
||||||
|
2008/01/01 January
|
||||||
|
Assets:Cash
|
||||||
|
Income:One:Books $-10.00
|
||||||
|
Income:One:Two:Books $-10.00
|
||||||
|
Income:One:Two:Three:Books $-10.00
|
||||||
|
>>>1
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
|
bal --depth 2 --flat
|
||||||
|
>>>1
|
||||||
|
$-10.00 Assets:Cash
|
||||||
|
$10.00 Expenses:Books
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
|
bal --depth 3 --flat
|
||||||
|
>>>1
|
||||||
|
$-10.00 Assets:Cash
|
||||||
|
$10.00 Expenses:Books
|
||||||
|
$10.00 Expenses:One:Books
|
||||||
|
$-10.00 Income:One:Books
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
|
bal --depth 4 --flat
|
||||||
|
>>>1
|
||||||
|
$-10.00 Assets:Cash
|
||||||
|
$10.00 Expenses:Books
|
||||||
|
$10.00 Expenses:One:Books
|
||||||
|
$10.00 Expenses:One:Two:Books
|
||||||
|
$-10.00 Income:One:Books
|
||||||
|
$-10.00 Income:One:Two:Books
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
|
bal --depth 5 --flat
|
||||||
|
>>>1
|
||||||
|
$-10.00 Assets:Cash
|
||||||
|
$10.00 Expenses:Books
|
||||||
|
$10.00 Expenses:One:Books
|
||||||
|
$10.00 Expenses:One:Two:Books
|
||||||
|
$10.00 Expenses:One:Two:Three:Books
|
||||||
|
$-10.00 Income:One:Books
|
||||||
|
$-10.00 Income:One:Two:Books
|
||||||
|
$-10.00 Income:One:Two:Three:Books
|
||||||
|
>>>2
|
||||||
|
=== 0
|
||||||
Loading…
Add table
Reference in a new issue