fixed the "-o bal rent" report again

This commit is contained in:
John Wiegley 2004-08-05 22:49:18 -04:00
parent 50f75e0a5c
commit ef2e0beb64
3 changed files with 98 additions and 156 deletions

View file

@ -54,13 +54,19 @@ struct format_t
static std::auto_ptr<node_t> value_expr; static std::auto_ptr<node_t> value_expr;
static std::auto_ptr<node_t> total_expr; static std::auto_ptr<node_t> total_expr;
format_t(const std::string& _format) { format_t(const std::string& _format) : elements(NULL) {
elements = parse_elements(_format); reset(_format);
} }
~format_t() { ~format_t() {
if (elements) delete elements; if (elements) delete elements;
} }
void reset(const std::string& _format) {
if (elements)
delete elements;
elements = parse_elements(_format);
}
static element_t * parse_elements(const std::string& fmt); static element_t * parse_elements(const std::string& fmt);
void format_elements(std::ostream& out, const details_t& details) const; void format_elements(std::ostream& out, const details_t& details) const;

87
main.cc
View file

@ -19,68 +19,6 @@ namespace ledger {
static const std::string bal_fmt = "%20T %2_%-n\n"; static const std::string bal_fmt = "%20T %2_%-n\n";
#if 0
unsigned int show_balances(std::ostream& out,
items_deque& items,
const node_t * predicate,
const node_t * sort_order,
const format_t& format,
const bool show_expanded,
const item_t * displayed_parent)
{
unsigned int headlines = 0;
value_predicate pred_obj(predicate);
for (items_deque::const_iterator i = items.begin();
i != items.end();
i++) {
const item_t * parent = displayed_parent;
if (pred_obj(*i) &&
((*i)->subitems.size() != 1 ||
(*i)->total != (*i)->subitems[0]->total)) {
format.format_elements(out, *i, parent);
parent = *i;
if (! displayed_parent->parent)
headlines++;
}
if (sort_order)
(*i)->sort(sort_order);
if (show_expanded)
headlines += show_balances(out, (*i)->subitems, predicate,
sort_order, format, true, parent);
}
return headlines;
}
void balance_report(std::ostream& out,
item_t * top,
const node_t * predicate,
const node_t * sort_order,
const format_t& format,
const bool show_expanded,
const bool show_subtotals)
{
if (sort_order)
top->sort(sort_order);
unsigned int headlines = show_balances(out, top->subitems, predicate,
sort_order, format, show_expanded,
top);
if (show_subtotals && headlines > 1 && top->total) {
std::cout << "--------------------\n";
format.format_elements(std::cout, top);
}
}
#endif
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// //
// The command-line register and print report // The command-line register and print report
@ -797,16 +735,21 @@ int main(int argc, char * argv[])
// Now handle the command that was identified above. // Now handle the command that was identified above.
unsigned int xact_display_flags = MATCHING_TRANSACTIONS;
if (command == "p" || command == "e") { if (command == "p" || command == "e") {
show_related = true;
show_expanded = true; show_expanded = true;
} }
else if (command == "E") { else if (command == "E") {
show_expanded = true; show_expanded = true;
} }
else if (show_related && command == "r") { else if (show_related && command == "r") {
xact_display_flags = OTHER_TRANSACTIONS;
show_inverted = true; show_inverted = true;
} }
else if (show_related) {
xact_display_flags |= OTHER_TRANSACTIONS;
}
const char * f; const char * f;
if (! format_string.empty()) if (! format_string.empty())
@ -821,14 +764,13 @@ int main(int argc, char * argv[])
if (command == "b") { if (command == "b") {
format_t format(f); format_t format(f);
walk_accounts(journal->master, format_account(std::cout, format), walk_accounts(journal->master, format_account(std::cout, format),
predicate.get(), show_related, show_inverted, predicate.get(), xact_display_flags, show_subtotals,
show_subtotals, display_predicate.get(), sort_order.get()); display_predicate.get(), sort_order.get());
if (! display_predicate.get() || if (! display_predicate.get() ||
item_predicate(display_predicate.get())(journal->master)) { item_predicate<account_t>(display_predicate.get())(journal->master)) {
std::string end_format = "--------------------\n"; std::string end_format = "--------------------\n";
end_format += f; format.reset(end_format + f);
format.elements = format_t::parse_elements(end_format);
format_account(std::cout, format)(journal->master, true); format_account(std::cout, format)(journal->master, true);
} }
} else { } else {
@ -844,22 +786,21 @@ int main(int argc, char * argv[])
format_t format(first_line_format); format_t format(first_line_format);
format_t nformat(next_lines_format); format_t nformat(next_lines_format);
format_transaction formatter(std::cout, format, nformat); format_transaction formatter(std::cout, format, nformat, show_inverted);
if (! sort_order.get()) { if (! sort_order.get()) {
walk_entries(journal->entries.begin(), journal->entries.end(), walk_entries(journal->entries.begin(), journal->entries.end(),
formatter, predicate.get(), show_related, show_inverted, formatter, predicate.get(), xact_display_flags,
display_predicate.get()); display_predicate.get());
} else { } else {
transactions_deque transactions_pool; transactions_deque transactions_pool;
walk_entries(journal->entries.begin(), journal->entries.end(), walk_entries(journal->entries.begin(), journal->entries.end(),
collect_transactions(transactions_pool), predicate.get(), collect_transactions(transactions_pool), predicate.get(),
show_related, show_inverted, display_predicate.get()); xact_display_flags, display_predicate.get());
std::stable_sort(transactions_pool.begin(), transactions_pool.end(), std::stable_sort(transactions_pool.begin(), transactions_pool.end(),
compare_items<transaction_t>(sort_order.get())); compare_items<transaction_t>(sort_order.get()));
walk_transactions(transactions_pool.begin(), transactions_pool.end(), walk_transactions(transactions_pool.begin(), transactions_pool.end(),
formatter, NULL, show_related, show_inverted, formatter);
display_predicate.get());
} }
} }

157
walk.h
View file

@ -11,37 +11,18 @@
namespace ledger { namespace ledger {
template <typename T>
class item_predicate class item_predicate
{ {
const node_t * predicate; const node_t * predicate;
public: public:
item_predicate(const node_t * _predicate) : predicate(_predicate) {} item_predicate(const node_t * _predicate) : predicate(_predicate) {}
bool operator()(const entry_t * entry) const { bool operator()(const T * item) const {
if (predicate) { if (predicate) {
balance_t result; balance_t result;
predicate->compute(result, details_t(entry)); predicate->compute(result, details_t(item));
return result;
} else {
return true;
}
}
bool operator()(const transaction_t * xact) const {
if (predicate) {
balance_t result;
predicate->compute(result, details_t(xact));
return result;
} else {
return true;
}
}
bool operator()(const account_t * account) const {
if (predicate) {
balance_t result;
predicate->compute(result, details_t(account));
return result; return result;
} else { } else {
return true; return true;
@ -66,19 +47,21 @@ class format_transaction
std::ostream& output_stream; std::ostream& output_stream;
const format_t& first_line_format; const format_t& first_line_format;
const format_t& next_lines_format; const format_t& next_lines_format;
const bool inverted;
unsigned int index; unsigned int index;
entry_t * last_entry; entry_t * last_entry;
public: public:
format_transaction(std::ostream& _output_stream, format_transaction(std::ostream& _output_stream,
const format_t& _first_line_format, const format_t& _first_line_format,
const format_t& _next_lines_format) const format_t& _next_lines_format,
const bool _inverted)
: output_stream(_output_stream), : output_stream(_output_stream),
first_line_format(_first_line_format), first_line_format(_first_line_format),
next_lines_format(_next_lines_format), next_lines_format(_next_lines_format),
index(0), last_entry(NULL) {} inverted(_inverted), index(0), last_entry(NULL) {}
void operator()(transaction_t * xact, const bool inverted); void operator()(transaction_t * xact);
}; };
template <typename T> template <typename T>
@ -111,7 +94,7 @@ class collect_transactions
collect_transactions(transactions_deque& _transactions) collect_transactions(transactions_deque& _transactions)
: transactions(_transactions) {} : transactions(_transactions) {}
void operator()(transaction_t * xact, const bool inverted) { void operator()(transaction_t * xact) {
transactions.push_back(xact); transactions.push_back(xact);
} }
}; };
@ -126,26 +109,27 @@ inline void sort_transactions(transactions_deque& transactions,
class ignore_transaction class ignore_transaction
{ {
public: public:
void operator()(transaction_t * xact, const bool inverted) const {} void operator()(transaction_t * xact) const {}
}; };
#define MATCHING_TRANSACTIONS 0x01
#define OTHER_TRANSACTIONS 0x02
template <typename Function> template <typename Function>
void handle_transaction(transaction_t * xact, void handle_transaction(transaction_t * xact, Function functor,
Function functor, item_predicate<transaction_t>& pred_functor,
item_predicate& pred_functor, unsigned int flags)
const bool related,
const bool inverted)
{ {
// If inverted is true, it implies related. if ((flags & MATCHING_TRANSACTIONS) &&
if (! inverted && ! (xact->flags & TRANSACTION_HANDLED)) { ! (xact->flags & TRANSACTION_HANDLED)) {
xact->flags |= TRANSACTION_HANDLED; xact->flags |= TRANSACTION_HANDLED;
if (pred_functor(xact)) { if (pred_functor(xact)) {
xact->flags |= TRANSACTION_DISPLAYED; xact->flags |= TRANSACTION_DISPLAYED;
functor(xact, inverted); functor(xact);
} }
} }
if (related) if (flags & OTHER_TRANSACTIONS)
for (transactions_list::iterator i = xact->entry->transactions.begin(); for (transactions_list::iterator i = xact->entry->transactions.begin();
i != xact->entry->transactions.end(); i != xact->entry->transactions.end();
i++) { i++) {
@ -156,7 +140,7 @@ void handle_transaction(transaction_t * xact,
(*i)->flags |= TRANSACTION_HANDLED; (*i)->flags |= TRANSACTION_HANDLED;
if (pred_functor(xact)) { if (pred_functor(xact)) {
xact->flags |= TRANSACTION_DISPLAYED; xact->flags |= TRANSACTION_DISPLAYED;
functor(*i, inverted); functor(*i);
} }
} }
} }
@ -164,47 +148,36 @@ void handle_transaction(transaction_t * xact,
template <typename Function> template <typename Function>
void walk_entries(entries_list::iterator begin, void walk_entries(entries_list::iterator begin,
entries_list::iterator end, entries_list::iterator end,
Function functor, Function functor,
const node_t * predicate, const node_t * predicate,
const bool related, unsigned int flags,
const bool inverted, const node_t * display_predicate = NULL)
const node_t * display_predicate = NULL)
{ {
item_predicate pred_functor(predicate); item_predicate<transaction_t> pred_functor(predicate);
item_predicate disp_pred_functor(display_predicate); item_predicate<transaction_t> disp_pred_functor(display_predicate);
for (entries_list::iterator i = begin; i != end; i++) for (entries_list::iterator i = begin; i != end; i++)
for (transactions_list::iterator j = (*i)->transactions.begin(); for (transactions_list::iterator j = (*i)->transactions.begin();
j != (*i)->transactions.end(); j != (*i)->transactions.end();
j++) j++)
if (pred_functor(*j)) if (pred_functor(*j))
handle_transaction(*j, functor, disp_pred_functor, related, inverted); handle_transaction(*j, functor, disp_pred_functor, flags);
} }
template <typename Function> template <typename Function>
void walk_transactions(transactions_list::iterator begin, void walk_transactions(transactions_list::iterator begin,
transactions_list::iterator end, transactions_list::iterator end, Function functor)
Function functor,
const node_t * predicate,
const bool related,
const bool inverted,
const node_t * display_predicate = NULL)
{ {
for (transactions_list::iterator i = begin; i != end; i++) for (transactions_list::iterator i = begin; i != end; i++)
functor(*i, inverted); functor(*i);
} }
template <typename Function> template <typename Function>
void walk_transactions(transactions_deque::iterator begin, void walk_transactions(transactions_deque::iterator begin,
transactions_deque::iterator end, transactions_deque::iterator end, Function functor)
Function functor,
const node_t * predicate,
const bool related,
const bool inverted,
const node_t * display_predicate = NULL)
{ {
for (transactions_deque::iterator i = begin; i != end; i++) for (transactions_deque::iterator i = begin; i != end; i++)
functor(*i, inverted); functor(*i);
} }
class format_account class format_account
@ -236,26 +209,24 @@ inline void sort_accounts(account_t * account,
} }
template <typename Function> template <typename Function>
void walk__accounts(const account_t * account, void walk__accounts(const account_t * account, Function functor,
Function functor, item_predicate<account_t>& disp_pred_functor)
const node_t * display_predicate)
{ {
if (! display_predicate || item_predicate(display_predicate)(account)) if (disp_pred_functor(account))
functor(account); functor(account);
for (accounts_map::const_iterator i = account->accounts.begin(); for (accounts_map::const_iterator i = account->accounts.begin();
i != account->accounts.end(); i != account->accounts.end();
i++) i++)
walk__accounts((*i).second, functor, display_predicate); walk__accounts((*i).second, functor, disp_pred_functor);
} }
template <typename Function> template <typename Function>
void walk__accounts_sorted(const account_t * account, void walk__accounts_sorted(const account_t * account, Function functor,
Function functor, const node_t * sort_order,
const node_t * sort_order, item_predicate<account_t>& disp_pred_functor)
const node_t * display_predicate)
{ {
if (! display_predicate || item_predicate(display_predicate)(account)) if (disp_pred_functor(account))
functor(account); functor(account);
accounts_deque accounts; accounts_deque accounts;
@ -271,32 +242,56 @@ void walk__accounts_sorted(const account_t * account,
for (accounts_deque::const_iterator i = accounts.begin(); for (accounts_deque::const_iterator i = accounts.begin();
i != accounts.end(); i != accounts.end();
i++) i++)
walk__accounts_sorted(*i, functor, sort_order, display_predicate); walk__accounts_sorted(*i, functor, sort_order, disp_pred_functor);
} }
void calc__accounts(account_t * account, template <typename Function>
const node_t * predicate, void for_each_account(account_t * account, Function functor)
const bool related, {
const bool inverted, functor(account);
const bool calc_subtotals);
for (accounts_map::iterator i = account->accounts.begin();
i != account->accounts.end();
i++)
walk__accounts((*i).second, functor);
}
void calc__accounts(account_t * account,
item_predicate<transaction_t>& pred_functor,
unsigned int flags);
inline void sum__accounts(account_t * account)
{
for (accounts_map::iterator i = account->accounts.begin();
i != account->accounts.end();
i++) {
sum__accounts((*i).second);
account->total += (*i).second->total;
}
account->total += account->value;
}
template <typename Function> template <typename Function>
void walk_accounts(account_t * account, void walk_accounts(account_t * account,
Function functor, Function functor,
const node_t * predicate, const node_t * predicate,
const bool related, unsigned int flags,
const bool inverted,
const bool calc_subtotals, const bool calc_subtotals,
const node_t * display_predicate = NULL, const node_t * display_predicate = NULL,
const node_t * sort_order = NULL) const node_t * sort_order = NULL)
{ {
calc__accounts(account, predicate, related, inverted, calc_subtotals); item_predicate<transaction_t> pred_functor(predicate);
item_predicate<account_t> disp_pred_functor(display_predicate);
calc__accounts(account, pred_functor, flags);
if (calc_subtotals)
sum__accounts(account);
if (sort_order) if (sort_order)
walk__accounts_sorted<Function>(account, functor, sort_order, walk__accounts_sorted<Function>(account, functor, sort_order,
display_predicate); disp_pred_functor);
else else
walk__accounts<Function>(account, functor, display_predicate); walk__accounts<Function>(account, functor, disp_pred_functor);
} }
} // namespace ledger } // namespace ledger