summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ledger.h14
-rw-r--r--main.cc4
-rw-r--r--valexpr.cc42
-rw-r--r--valexpr.h19
-rw-r--r--walk.h173
5 files changed, 123 insertions, 129 deletions
diff --git a/ledger.h b/ledger.h
index 7f20538e..2abf0416 100644
--- a/ledger.h
+++ b/ledger.h
@@ -34,12 +34,14 @@ class account_t;
class transaction_t
{
public:
- entry_t * entry;
- account_t * account;
- amount_t amount;
- amount_t cost;
- unsigned int flags;
- std::string note;
+ entry_t * entry;
+ account_t * account;
+ amount_t amount;
+ amount_t cost;
+ unsigned int flags;
+ std::string note;
+ balance_pair_t total;
+ unsigned int index;
transaction_t(entry_t * _entry, account_t * _account)
: entry(_entry), account(_account), flags(TRANSACTION_NORMAL) {}
diff --git a/main.cc b/main.cc
index caaa84cf..d2512e59 100644
--- a/main.cc
+++ b/main.cc
@@ -822,7 +822,7 @@ int main(int argc, char * argv[])
format_t format(f);
walk_accounts(journal->master, format_account(std::cout, format),
predicate.get(), show_related, show_inverted,
- show_subtotals, display_predicate.get());
+ show_subtotals, display_predicate.get(), sort_order.get());
if (! display_predicate.get() ||
item_predicate(display_predicate.get())(journal->master)) {
@@ -856,7 +856,7 @@ int main(int argc, char * argv[])
collect_transactions(transactions_pool), predicate.get(),
show_related, show_inverted, display_predicate.get());
std::stable_sort(transactions_pool.begin(), transactions_pool.end(),
- compare_transactions(sort_order.get()));
+ compare_items<transaction_t>(sort_order.get()));
walk_transactions(transactions_pool.begin(), transactions_pool.end(),
formatter, NULL, show_related, show_inverted,
display_predicate.get());
diff --git a/valexpr.cc b/valexpr.cc
index d563c3da..37bb7a80 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -116,34 +116,36 @@ void node_t::compute(balance_t& result, const details_t& details) const
break;
case BALANCE:
- if (details.balance) {
- result = details.balance->quantity;
- if (details.xact)
- result -= details.xact->amount;
- else if (details.account)
- result -= details.account->value.quantity;
+ if (details.xact) {
+ result = details.xact->total.quantity;
+ result -= details.xact->amount;
+ }
+ else if (details.account) {
+ result = details.account->total.quantity;
+ result -= details.account->value.quantity;
}
break;
case COST_BALANCE:
- if (details.balance) {
- result = details.balance->cost;
- if (details.xact)
- result -= details.xact->cost;
- else if (details.account)
- result -= details.account->value.cost;
+ if (details.xact) {
+ result = details.xact->total.cost;
+ result -= details.xact->cost;
+ }
+ else if (details.account) {
+ result = details.account->total.cost;
+ result -= details.account->value.cost;
}
break;
case TOTAL:
- if (details.balance)
- result = details.balance->quantity;
+ if (details.xact)
+ result = details.xact->total.quantity;
else if (details.account)
result = details.account->total.quantity;
break;
case COST_TOTAL:
- if (details.balance)
- result = details.balance->cost;
+ if (details.xact)
+ result = details.xact->total.cost;
else if (details.account)
result = details.account->total.cost;
break;
@@ -164,15 +166,15 @@ void node_t::compute(balance_t& result, const details_t& details) const
break;
case INDEX:
- if (details.index)
- result = *details.index + 1;
+ if (details.xact)
+ result = details.xact->index + 1;
break;
case F_ARITH_MEAN:
- if (details.index) {
+ if (details.xact) {
assert(left);
left->compute(result, details);
- result /= amount_t(*details.index + 1);
+ result /= amount_t(details.xact->index + 1);
}
break;
diff --git a/valexpr.h b/valexpr.h
index 0d4413e7..d2521998 100644
--- a/valexpr.h
+++ b/valexpr.h
@@ -33,26 +33,17 @@ struct details_t
const entry_t * entry;
const transaction_t * xact;
const account_t * account;
- const balance_pair_t * balance;
- const unsigned int * index;
const unsigned int depth;
- details_t(const entry_t * _entry,
- const balance_pair_t * _balance = NULL,
- const unsigned int * _index = NULL)
- : entry(_entry), xact(NULL), account(NULL),
- balance(_balance), index(_index), depth(0) {}
+ details_t(const entry_t * _entry)
+ : entry(_entry), xact(NULL), account(NULL), depth(0) {}
- details_t(const transaction_t * _xact,
- const balance_pair_t * _balance = NULL,
- const unsigned int * _index = NULL)
- : entry(_xact->entry), xact(_xact), account(_xact->account),
- balance(_balance), index(_index), depth(0) {}
+ details_t(const transaction_t * _xact)
+ : entry(_xact->entry), xact(_xact), account(_xact->account), depth(0) {}
details_t(const account_t * _account,
const unsigned int _depth = 0)
- : entry(NULL), xact(NULL), account(_account),
- balance(NULL), index(NULL), depth(_depth) {}
+ : entry(NULL), xact(NULL), account(_account), depth(_depth) {}
};
struct node_t
diff --git a/walk.h b/walk.h
index f8dba7ed..05539f95 100644
--- a/walk.h
+++ b/walk.h
@@ -14,19 +14,14 @@ namespace ledger {
class item_predicate
{
const node_t * predicate;
- balance_pair_t * balance;
- unsigned int * index;
public:
- item_predicate(const node_t * _predicate,
- balance_pair_t * _balance = NULL,
- unsigned int * _index = NULL)
- : predicate(_predicate), balance(_balance), index(_index) {}
+ item_predicate(const node_t * _predicate) : predicate(_predicate) {}
bool operator()(const entry_t * entry) const {
if (predicate) {
balance_t result;
- predicate->compute(result, details_t(entry, balance, index));
+ predicate->compute(result, details_t(entry));
return result;
} else {
return true;
@@ -36,7 +31,7 @@ class item_predicate
bool operator()(const transaction_t * xact) const {
if (predicate) {
balance_t result;
- predicate->compute(result, details_t(xact, balance, index));
+ predicate->compute(result, details_t(xact));
return result;
} else {
return true;
@@ -68,10 +63,11 @@ inline void add_to_balance_pair(balance_pair_t& balance,
class format_transaction
{
- std::ostream& output_stream;
- const format_t& first_line_format;
- const format_t& next_lines_format;
- mutable entry_t * last_entry;
+ std::ostream& output_stream;
+ const format_t& first_line_format;
+ const format_t& next_lines_format;
+ unsigned int index;
+ entry_t * last_entry;
public:
format_transaction(std::ostream& _output_stream,
@@ -80,24 +76,21 @@ class format_transaction
: output_stream(_output_stream),
first_line_format(_first_line_format),
next_lines_format(_next_lines_format),
- last_entry(NULL) {}
+ index(0), last_entry(NULL) {}
- void operator()(transaction_t * xact,
- balance_pair_t * balance,
- unsigned int * index,
- const bool inverted) const;
+ void operator()(transaction_t * xact, const bool inverted);
};
-struct compare_transactions {
+template <typename T>
+struct compare_items {
const node_t * sort_order;
- compare_transactions(const node_t * _sort_order)
+ compare_items(const node_t * _sort_order)
: sort_order(_sort_order) {
assert(sort_order);
}
- bool operator()(const transaction_t * left,
- const transaction_t * right) const {
+ bool operator()(const T * left, const T * right) const {
assert(left);
assert(right);
balance_t left_result;
@@ -118,21 +111,22 @@ class collect_transactions
collect_transactions(transactions_deque& _transactions)
: transactions(_transactions) {}
- void operator()(transaction_t * xact,
- balance_pair_t * balance,
- unsigned int * index,
- const bool inverted) {
+ void operator()(transaction_t * xact, const bool inverted) {
transactions.push_back(xact);
}
};
+inline void sort_transactions(transactions_deque& transactions,
+ const node_t * sort_order)
+{
+ std::stable_sort(transactions.begin(), transactions.end(),
+ compare_items<transaction_t>(sort_order));
+}
+
class ignore_transaction
{
public:
- void operator()(transaction_t * xact,
- balance_pair_t * balance,
- unsigned int * index,
- const bool inverted) const {}
+ void operator()(transaction_t * xact, const bool inverted) const {}
};
template <typename Function>
@@ -140,16 +134,14 @@ void handle_transaction(transaction_t * xact,
Function functor,
item_predicate& pred_functor,
const bool related,
- const bool inverted,
- balance_pair_t * balance = NULL,
- unsigned int * index = NULL)
+ const bool inverted)
{
// If inverted is true, it implies related.
if (! inverted && ! (xact->flags & TRANSACTION_HANDLED)) {
xact->flags |= TRANSACTION_HANDLED;
if (pred_functor(xact)) {
xact->flags |= TRANSACTION_DISPLAYED;
- functor(xact, balance, index, inverted);
+ functor(xact, inverted);
}
}
@@ -164,7 +156,7 @@ void handle_transaction(transaction_t * xact,
(*i)->flags |= TRANSACTION_HANDLED;
if (pred_functor(xact)) {
xact->flags |= TRANSACTION_DISPLAYED;
- functor(*i, balance, index, inverted);
+ functor(*i, inverted);
}
}
}
@@ -178,18 +170,15 @@ void walk_entries(entries_list::iterator begin,
const bool inverted,
const node_t * display_predicate = NULL)
{
- balance_pair_t balance;
- unsigned int index;
- item_predicate pred_functor(predicate, &balance, &index);
- item_predicate disp_pred_functor(display_predicate, &balance, &index);
+ item_predicate pred_functor(predicate);
+ item_predicate disp_pred_functor(display_predicate);
for (entries_list::iterator i = begin; i != end; i++)
for (transactions_list::iterator j = (*i)->transactions.begin();
j != (*i)->transactions.end();
j++)
if (pred_functor(*j))
- handle_transaction(*j, functor, disp_pred_functor,
- related, inverted, &balance, &index);
+ handle_transaction(*j, functor, disp_pred_functor, related, inverted);
}
template <typename Function>
@@ -201,11 +190,8 @@ void walk_transactions(transactions_list::iterator begin,
const bool inverted,
const node_t * display_predicate = NULL)
{
- balance_pair_t balance;
- unsigned int index;
-
for (transactions_list::iterator i = begin; i != end; i++)
- functor(*i, &balance, &index, inverted);
+ functor(*i, inverted);
}
template <typename Function>
@@ -217,19 +203,15 @@ void walk_transactions(transactions_deque::iterator begin,
const bool inverted,
const node_t * display_predicate = NULL)
{
- balance_pair_t balance;
- unsigned int index;
-
for (transactions_deque::iterator i = begin; i != end; i++)
- functor(*i, &balance, &index, inverted);
+ functor(*i, inverted);
}
class format_account
{
- std::ostream& output_stream;
- const format_t& format;
-
- mutable const account_t * last_account;
+ std::ostream& output_stream;
+ const format_t& format;
+ const account_t * last_account;
public:
format_account(std::ostream& _output_stream, const format_t& _format)
@@ -238,11 +220,20 @@ class format_account
void operator()(const account_t * account, bool report_top = false);
};
-void calc__accounts(account_t * account,
- const node_t * predicate,
- const bool related,
- const bool inverted,
- const bool calc_subtotals);
+typedef std::deque<account_t *> accounts_deque;
+
+inline void sort_accounts(account_t * account,
+ accounts_deque& accounts,
+ const node_t * sort_order)
+{
+ for (accounts_map::iterator i = account->accounts.begin();
+ i != account->accounts.end();
+ i++)
+ accounts.push_back((*i).second);
+
+ std::stable_sort(accounts.begin(), accounts.end(),
+ compare_items<account_t>(sort_order));
+}
template <typename Function>
void walk__accounts(const account_t * account,
@@ -259,47 +250,55 @@ void walk__accounts(const account_t * account,
}
template <typename Function>
+void walk__accounts_sorted(const account_t * account,
+ Function functor,
+ const node_t * sort_order,
+ const node_t * display_predicate)
+{
+ if (! display_predicate || item_predicate(display_predicate)(account))
+ functor(account);
+
+ accounts_deque accounts;
+
+ for (accounts_map::const_iterator i = account->accounts.begin();
+ i != account->accounts.end();
+ i++)
+ accounts.push_back((*i).second);
+
+ std::stable_sort(accounts.begin(), accounts.end(),
+ compare_items<account_t>(sort_order));
+
+ for (accounts_deque::const_iterator i = accounts.begin();
+ i != accounts.end();
+ i++)
+ walk__accounts_sorted(*i, functor, sort_order, display_predicate);
+}
+
+void calc__accounts(account_t * account,
+ const node_t * predicate,
+ const bool related,
+ const bool inverted,
+ const bool calc_subtotals);
+
+template <typename Function>
void walk_accounts(account_t * account,
Function functor,
const node_t * predicate,
const bool related,
const bool inverted,
const bool calc_subtotals,
- const node_t * display_predicate = NULL)
+ const node_t * display_predicate = NULL,
+ const node_t * sort_order = NULL)
{
calc__accounts(account, predicate, related, inverted, calc_subtotals);
- walk__accounts<Function>(account, functor, display_predicate);
-}
-#if 0
-
-void sum_entries(entries_list& entries,
- account_t * account,
- const bool show_subtotals)
-{
- for (entries_list::const_iterator i = entries.begin();
- i != entries.end();
- i++)
- for (transactions_list::const_iterator j = (*i)->transactions.begin();
- j != (*i)->transactions.end();
- j++)
- if ((*j)->account == account) {
- account->value += *(*j);
- if (show_subtotals)
- for (account_t * a = account;
- a;
- a = a->parent)
- a->total += *(*j);
- }
-
- for (accounts_map::iterator i = account->accounts.begin();
- i != account->accounts.end();
- i++)
- sum_items(entries, *i, show_subtotals);
+ if (sort_order)
+ walk__accounts_sorted<Function>(account, functor, sort_order,
+ display_predicate);
+ else
+ walk__accounts<Function>(account, functor, display_predicate);
}
-#endif
-
} // namespace ledger
#endif // _WALK_H