diff options
-rw-r--r-- | src/iterators.cc | 30 | ||||
-rw-r--r-- | src/iterators.h | 24 | ||||
-rw-r--r-- | src/output.cc | 92 | ||||
-rw-r--r-- | src/output.h | 10 | ||||
-rw-r--r-- | src/report.cc | 4 | ||||
-rw-r--r-- | src/value.cc | 5 |
6 files changed, 97 insertions, 68 deletions
diff --git a/src/iterators.cc b/src/iterators.cc index 01f678d0..3a59c7aa 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -179,6 +179,33 @@ void sorted_accounts_iterator::sort_accounts(account_t& account, compare_items<account_t>(sort_cmp)); } +void sorted_accounts_iterator::push_all(account_t& account) +{ + accounts_deque_t& deque(accounts_list.back()); + + foreach (accounts_map::value_type& pair, account.accounts) { + deque.push_back(pair.second); + push_all(*pair.second); + } +} + +void sorted_accounts_iterator::push_back(account_t& account) +{ + accounts_list.push_back(accounts_deque_t()); + + if (flatten_all) { + push_all(account); + std::stable_sort(accounts_list.back().begin(), + accounts_list.back().end(), + compare_items<account_t>(sort_cmp)); + } else { + sort_accounts(account, accounts_list.back()); + } + + sorted_accounts_i.push_back(accounts_list.back().begin()); + sorted_accounts_end.push_back(accounts_list.back().end()); +} + account_t * sorted_accounts_iterator::operator()() { while (! sorted_accounts_i.empty() && @@ -195,9 +222,10 @@ account_t * sorted_accounts_iterator::operator()() assert(account); // If this account has children, queue them up to be iterated next. - if (! account->accounts.empty()) + if (! flatten_all && ! account->accounts.empty()) push_back(*account); + // Make sure the sorting value gets recalculated for this account account->xdata().drop_flags(ACCOUNT_EXT_SORT_CALC); return account; } diff --git a/src/iterators.h b/src/iterators.h index 8bf05986..92f887d0 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -244,6 +244,7 @@ public: class sorted_accounts_iterator : public accounts_iterator { expr_t sort_cmp; + bool flatten_all; typedef std::deque<account_t *> accounts_deque_t; @@ -252,13 +253,14 @@ class sorted_accounts_iterator : public accounts_iterator std::list<accounts_deque_t::const_iterator> sorted_accounts_end; public: - sorted_accounts_iterator(const string& sort_order) { - TRACE_CTOR(sorted_accounts_iterator, "const string&"); - sort_cmp = expr_t(sort_order); + sorted_accounts_iterator(const expr_t& _sort_cmp, bool _flatten_all) + : sort_cmp(_sort_cmp), flatten_all(_flatten_all) { + TRACE_CTOR(sorted_accounts_iterator, "const expr_t&, bool"); } - sorted_accounts_iterator(account_t& account, const string& sort_order) { - TRACE_CTOR(sorted_accounts_iterator, "account_t&, const string&"); - sort_cmp = expr_t(sort_order); + sorted_accounts_iterator(const expr_t& _sort_cmp, bool _flatten_all, + account_t& account) + : sort_cmp(_sort_cmp), flatten_all(_flatten_all) { + TRACE_CTOR(sorted_accounts_iterator, "const expr_t&, bool, account_t&"); push_back(account); } virtual ~sorted_accounts_iterator() throw() { @@ -266,14 +268,8 @@ public: } void sort_accounts(account_t& account, accounts_deque_t& deque); - - void push_back(account_t& account) { - accounts_list.push_back(accounts_deque_t()); - sort_accounts(account, accounts_list.back()); - - sorted_accounts_i.push_back(accounts_list.back().begin()); - sorted_accounts_end.push_back(accounts_list.back().end()); - } + void push_all(account_t& account); + void push_back(account_t& account); virtual account_t * operator()(); }; diff --git a/src/output.cc b/src/output.cc index 31208c26..bd55fe99 100644 --- a/src/output.cc +++ b/src/output.cc @@ -210,63 +210,64 @@ void format_entries::operator()(xact_t& xact) last_entry = xact.entry; } -std::size_t format_accounts::post_accounts(account_t& account) +void format_accounts::post_account(account_t& account) { - std::size_t displayed = 0; + bind_scope_t bound_scope(report, account); + bool format_account = false; - // Don't ever print the top-most account - if (account.parent) { - bind_scope_t bound_scope(report, account); - bool format_account = false; - - DEBUG("account.display", "Should we display " << account.fullname()); + DEBUG("account.display", "Should we display " << account.fullname()); - if (account.has_flags(ACCOUNT_EXT_MATCHING) || - (! flatten_list && - account.children_with_flags(ACCOUNT_EXT_MATCHING) > 1)) { - DEBUG("account.display", " Yes, because it matched"); - format_account = true; - } - else if (! flatten_list && - account.children_with_flags(ACCOUNT_EXT_VISITED) && - ! account.children_with_flags(ACCOUNT_EXT_MATCHING)) { + if (account.has_flags(ACCOUNT_EXT_MATCHING) || + (! flatten_list && + account.children_with_flags(ACCOUNT_EXT_MATCHING) > 1)) { + DEBUG("account.display", " Yes, because it matched"); + format_account = true; + } + else if (! flatten_list && + 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", - " 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 { + " And yes, because it matches the display predicate"); + format_account = true; + } else { DEBUG("account.display", - " No, neither it nor its children were eligible for display"); - } - - if (format_account) { - account.xdata().add_flags(ACCOUNT_EXT_DISPLAYED); - displayed++; - - format.format(report.output_stream, bound_scope); + " And no, because it didn't match the display predicate"); } } - - foreach (accounts_map::value_type pair, account.accounts) { - if (post_accounts(*pair.second) > 0) - displayed++; + else { + DEBUG("account.display", + " No, neither it nor its children were eligible for display"); } - return displayed; + if (format_account) { + account.xdata().add_flags(ACCOUNT_EXT_DISPLAYED); + format.format(report.output_stream, bound_scope); + } } void format_accounts::flush() { std::ostream& out(report.output_stream); - std::size_t top_displayed = post_accounts(*report.session.master.get()); + std::size_t top_displayed = 0; + + foreach (account_t * account, posted_accounts) { + post_account(*account); + + if (flatten_list && account->has_flags(ACCOUNT_EXT_DISPLAYED)) + top_displayed++; + } + + if (! flatten_list) { + foreach (accounts_map::value_type pair, report.session.master->accounts) { + if (pair.second->has_flags(ACCOUNT_EXT_DISPLAYED) || + pair.second->children_with_flags(ACCOUNT_EXT_DISPLAYED)) + top_displayed++; + } + } assert(report.session.master->has_xdata()); account_t::xdata_t& xdata(report.session.master->xdata()); @@ -300,6 +301,7 @@ void format_accounts::operator()(account_t& account) " But it did not match the display predicate"); } } + posted_accounts.push_back(&account); } format_equity::format_equity(report_t& _report, const string& _format) @@ -351,12 +353,12 @@ void format_equity::flush() out.flush(); } -std::size_t format_equity::post_accounts(account_t& account) +void format_equity::post_account(account_t& account) { std::ostream& out(report.output_stream); if (! account.has_flags(ACCOUNT_EXT_MATCHING)) - return 0; + return; value_t val = account.xdata().value; @@ -378,8 +380,6 @@ std::size_t format_equity::post_accounts(account_t& account) next_lines_format.format(out, bound_scope); } total += val; - - return 1; } } // namespace ledger diff --git a/src/output.h b/src/output.h index ded29143..7019b7b2 100644 --- a/src/output.h +++ b/src/output.h @@ -165,6 +165,8 @@ protected: item_predicate disp_pred; bool flatten_list; + std::list<account_t *> posted_accounts; + public: format_accounts(report_t& _report, const string& _format = "", @@ -184,8 +186,8 @@ public: TRACE_DTOR(format_accounts); } - virtual std::size_t post_accounts(account_t& account); - virtual void flush(); + virtual void post_account(account_t& account); + virtual void flush(); virtual void operator()(account_t& account); }; @@ -209,8 +211,8 @@ class format_equity : public format_accounts TRACE_DTOR(format_equity); } - virtual std::size_t post_accounts(account_t& account); - virtual void flush(); + virtual void post_account(account_t& account); + virtual void flush(); }; } // namespace ledger diff --git a/src/report.cc b/src/report.cc index 565ef77e..d9e88634 100644 --- a/src/report.cc +++ b/src/report.cc @@ -77,8 +77,8 @@ void report_t::accounts_report(acct_handler_ptr handler) if (! HANDLED(sort_)) iter.reset(new basic_accounts_iterator(*session.master)); else - iter.reset(new sorted_accounts_iterator(*session.master, - HANDLER(sort_).str())); + iter.reset(new sorted_accounts_iterator(HANDLER(sort_).str(), + HANDLED(flat), *session.master.get())); if (HANDLED(display_)) pass_down_accounts(handler, *iter.get(), diff --git a/src/value.cc b/src/value.cc index 96fb6647..3b9cfb00 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1424,6 +1424,9 @@ bool sort_value_is_less_than(const std::list<sort_value_t>& left_values, while (left_iter != left_values.end() && right_iter != right_values.end()) { + DEBUG("value.sort", + "Comparing " << (*left_iter).value << " < " << (*right_iter).value); + if ((*left_iter).value < (*right_iter).value) return ! (*left_iter).inverted; else if ((*left_iter).value > (*right_iter).value) @@ -1434,7 +1437,7 @@ bool sort_value_is_less_than(const std::list<sort_value_t>& left_values, assert(left_iter == left_values.end()); assert(right_iter == right_values.end()); - return true; + return false; } } // namespace ledger |