diff options
Diffstat (limited to 'walk.h')
-rw-r--r-- | walk.h | 485 |
1 files changed, 0 insertions, 485 deletions
diff --git a/walk.h b/walk.h deleted file mode 100644 index 0ac9e133..00000000 --- a/walk.h +++ /dev/null @@ -1,485 +0,0 @@ -#ifndef _WALK_H -#define _WALK_H - -#include "journal.h" -#include "balance.h" -#include "valexpr.h" -#include "datetime.h" - -#include <iostream> -#include <deque> - -namespace ledger { - -template <typename T> -struct item_handler { - item_handler * handler; - - public: - item_handler() : handler(NULL) { - DEBUG_PRINT("ledger.memory.ctors", "ctor item_handler<T>"); - } - item_handler(item_handler * _handler) : handler(_handler) { - DEBUG_PRINT("ledger.memory.ctors", "ctor item_handler<T>"); - } - - virtual ~item_handler() { - DEBUG_PRINT("ledger.memory.dtors", "dtor item_handler<T>"); - } - virtual void flush() { - if (handler) - handler->flush(); - } - virtual void operator()(T& item) { - if (handler) - (*handler)(item); - } -}; - -template <typename T> -class compare_items { - const value_expr_t * sort_order; - public: - compare_items(const value_expr_t * _sort_order) - : sort_order(_sort_order) { - assert(sort_order); - } - bool operator()(const T * left, const T * right); -}; - -template <typename T> -bool compare_items<T>::operator()(const T * left, const T * right) -{ - assert(left); - assert(right); - - value_t left_result; - value_t right_result; - sort_order->compute(left_result, details_t(*left)); - sort_order->compute(right_result, details_t(*right)); - - return left_result < right_result; -} - -template <> -bool compare_items<transaction_t>::operator()(const transaction_t * left, - const transaction_t * right); - -template <> -bool compare_items<account_t>::operator()(const account_t * left, - const account_t * right); - -////////////////////////////////////////////////////////////////////// -// -// Transaction handlers -// - -#define TRANSACTION_HANDLED 0x0001 -#define TRANSACTION_TO_DISPLAY 0x0002 -#define TRANSACTION_DISPLAYED 0x0004 -#define TRANSACTION_NO_TOTAL 0x0008 -#define TRANSACTION_SORT_CALC 0x0010 - -struct transaction_xdata_t -{ - value_t total; - value_t sort_value; - unsigned int index; - unsigned short dflags; - - transaction_xdata_t() : index(0), dflags(0) { - DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_xdata_t"); - } -#ifdef DEBUG_ENABLED - ~transaction_xdata_t() { - DEBUG_PRINT("ledger.memory.dtors", "dtor transaction_xdata_t"); - } -#endif -}; - -inline bool transaction_has_xdata(const transaction_t& xact) { - return xact.data != NULL; -} - -extern std::list<transaction_xdata_t> transactions_xdata; -extern std::list<void **> transactions_xdata_ptrs; - -inline transaction_xdata_t& transaction_xdata(const transaction_t& xact) { - if (! xact.data) { - transactions_xdata.push_back(transaction_xdata_t()); - xact.data = &transactions_xdata.back(); - transactions_xdata_ptrs.push_back(&xact.data); - } - return *((transaction_xdata_t *) xact.data); -} - -////////////////////////////////////////////////////////////////////// - -typedef std::deque<transaction_t *> transactions_deque; -typedef std::deque<entry_t *> entries_deque; - -inline void walk_transactions(transactions_list::iterator begin, - transactions_list::iterator end, - item_handler<transaction_t>& handler) { - for (transactions_list::iterator i = begin; i != end; i++) - handler(**i); -} - -inline void walk_transactions(transactions_list& list, - item_handler<transaction_t>& handler) { - walk_transactions(list.begin(), list.end(), handler); -} - -inline void walk_transactions(transactions_deque::iterator begin, - transactions_deque::iterator end, - item_handler<transaction_t>& handler) { - for (transactions_deque::iterator i = begin; i != end; i++) - handler(**i); -} - -inline void walk_transactions(transactions_deque& deque, - item_handler<transaction_t>& handler) { - walk_transactions(deque.begin(), deque.end(), handler); -} - -inline void walk_entries(entries_list::iterator begin, - entries_list::iterator end, - item_handler<transaction_t>& handler) { - for (entries_list::iterator i = begin; i != end; i++) - walk_transactions((*i)->transactions, handler); -} - -inline void walk_entries(entries_list& list, - item_handler<transaction_t>& handler) { - walk_entries(list.begin(), list.end(), handler); -} - -void clear_transactions_xdata(); - -////////////////////////////////////////////////////////////////////// - -class ignore_transactions : public item_handler<transaction_t> -{ - public: - virtual void operator()(transaction_t& xact) {} -}; - -class set_account_value : public item_handler<transaction_t> -{ - public: - set_account_value(item_handler<transaction_t> * handler = NULL) - : item_handler<transaction_t>(handler) {} - - virtual void operator()(transaction_t& xact); -}; - -class sort_transactions : public item_handler<transaction_t> -{ - transactions_deque transactions; - const value_expr_t * sort_order; - bool allocated; - - public: - sort_transactions(item_handler<transaction_t> * handler, - const value_expr_t * _sort_order) - : item_handler<transaction_t>(handler), - sort_order(_sort_order), allocated(false) {} - - sort_transactions(item_handler<transaction_t> * handler, - const std::string& _sort_order) - : item_handler<transaction_t>(handler), allocated(true) { - try { - sort_order = parse_value_expr(_sort_order); - } - catch (value_expr_error& err) { - throw value_expr_error(std::string("In sort string '") + _sort_order + - "': " + err.what()); - } - } - - virtual ~sort_transactions() { - assert(sort_order); - if (allocated) - delete sort_order; - } - - virtual void flush(); - virtual void operator()(transaction_t& xact) { - transactions.push_back(&xact); - } -}; - -class filter_transactions : public item_handler<transaction_t> -{ - const item_predicate<transaction_t> * pred; - bool allocated; - - public: - filter_transactions(item_handler<transaction_t> * handler, - const item_predicate<transaction_t> * predicate) - : item_handler<transaction_t>(handler), - pred(predicate), allocated(false) {} - - filter_transactions(item_handler<transaction_t> * handler, - const std::string& predicate) - : item_handler<transaction_t>(handler), - pred(new item_predicate<transaction_t>(predicate)), - allocated(true) {} - - virtual ~filter_transactions() { - if (allocated) - delete pred; - } - - virtual void operator()(transaction_t& xact) { - if ((*pred)(xact)) - (*handler)(xact); - } -}; - -class calc_transactions : public item_handler<transaction_t> -{ - transaction_t * last_xact; - const bool inverted; - - public: - calc_transactions(item_handler<transaction_t> * handler, - const bool _inverted = false) - : item_handler<transaction_t>(handler), - last_xact(NULL), inverted(_inverted) {} - - virtual void operator()(transaction_t& xact); -}; - -class collapse_transactions : public item_handler<transaction_t> -{ - balance_pair_t subtotal; - unsigned int count; - entry_t * last_entry; - transaction_t * last_xact; - account_t totals_account; - - std::list<transaction_t> xact_temps; - - public: - collapse_transactions(item_handler<transaction_t> * handler) - : item_handler<transaction_t>(handler), count(0), - last_entry(NULL), last_xact(NULL), totals_account(NULL, "<Total>") {} - - virtual void flush() { - if (subtotal) - report_cumulative_subtotal(); - item_handler<transaction_t>::flush(); - } - - void report_cumulative_subtotal(); - - virtual void operator()(transaction_t& xact) { - // If we've reached a new entry, report on the subtotal - // accumulated thus far. - - if (last_entry && last_entry != xact.entry && count > 0) - report_cumulative_subtotal(); - - add_transaction_to(xact, subtotal); - count++; - - last_entry = xact.entry; - last_xact = &xact; - } -}; - -class changed_value_transactions : public item_handler<transaction_t> -{ - // This filter requires that calc_transactions be used at some point - // later in the chain. - - bool changed_values_only; - transaction_t * last_xact; - std::list<entry_t> entry_temps; - std::list<transaction_t> xact_temps; - - public: - changed_value_transactions(item_handler<transaction_t> * handler, - bool _changed_values_only) - : item_handler<transaction_t>(handler), - changed_values_only(_changed_values_only), last_xact(NULL) {} - - virtual void flush() { - if (last_xact) { - output_diff(std::time(NULL)); - last_xact = NULL; - } - item_handler<transaction_t>::flush(); - } - - void output_diff(const std::time_t current); - - virtual void operator()(transaction_t& xact); -}; - -class subtotal_transactions : public item_handler<transaction_t> -{ - typedef std::map<account_t *, balance_pair_t> balances_map; - typedef std::pair<account_t *, balance_pair_t> balances_pair; - - protected: - std::time_t start; - std::time_t finish; - balances_map balances; - std::list<entry_t> entry_temps; - std::list<transaction_t> xact_temps; - - public: - subtotal_transactions(item_handler<transaction_t> * handler) - : item_handler<transaction_t>(handler) {} - - void report_subtotal(const char * spec_fmt = NULL); - - virtual void flush() { - if (balances.size() > 0) - report_subtotal(); - item_handler<transaction_t>::flush(); - } - virtual void operator()(transaction_t& xact); -}; - -class interval_transactions : public subtotal_transactions -{ - interval_t interval; - transaction_t * last_xact; - - public: - interval_transactions(item_handler<transaction_t> * handler, - const interval_t& _interval) - : subtotal_transactions(handler), interval(_interval), - last_xact(NULL) {} - - interval_transactions(item_handler<transaction_t> * handler, - const std::string& _interval) - : subtotal_transactions(handler), interval(_interval), - last_xact(NULL) {} - - virtual ~interval_transactions() { - start = interval.begin; - finish = interval.increment(interval.begin); - } - - virtual void operator()(transaction_t& xact); -}; - -class dow_transactions : public subtotal_transactions -{ - transactions_list days_of_the_week[7]; - - public: - dow_transactions(item_handler<transaction_t> * handler) - : subtotal_transactions(handler) {} - - virtual void flush(); - virtual void operator()(transaction_t& xact) { - struct std::tm * desc = std::localtime(&xact.entry->date); - days_of_the_week[desc->tm_wday].push_back(&xact); - } -}; - -class related_transactions : public item_handler<transaction_t> -{ - bool also_matching; - - public: - related_transactions(item_handler<transaction_t> * handler, - const bool _also_matching = false) - : item_handler<transaction_t>(handler), - also_matching(_also_matching) {} - - virtual void operator()(transaction_t& xact) { - for (transactions_list::iterator i = xact.entry->transactions.begin(); - i != xact.entry->transactions.end(); - i++) - if ((! transaction_has_xdata(**i) || - ! (transaction_xdata(**i).dflags & TRANSACTION_HANDLED)) && - (*i == &xact ? also_matching : - ! ((*i)->flags & TRANSACTION_AUTO))) { - transaction_xdata(**i).dflags |= TRANSACTION_HANDLED; - (*handler)(**i); - } - } -}; - - -////////////////////////////////////////////////////////////////////// -// -// Account walking functions -// - -#define ACCOUNT_TO_DISPLAY 0x1 -#define ACCOUNT_DISPLAYED 0x2 -#define ACCOUNT_SORT_CALC 0x4 - -struct account_xdata_t -{ - value_t value; - value_t total; - value_t sort_value; - unsigned int count; // transactions counted toward total - unsigned int subcount; - unsigned short dflags; - - account_xdata_t() : count(0), subcount(0), dflags(0) { - DEBUG_PRINT("ledger.memory.ctors", "ctor account_xdata_t"); - } -#ifdef DEBUG_ENABLED - ~account_xdata_t() { - DEBUG_PRINT("ledger.memory.dtors", "dtor account_xdata_t"); - } -#endif -}; - -inline bool account_has_xdata(const account_t& account) { - return account.data != NULL; -} - -extern std::list<account_xdata_t> accounts_xdata; -extern std::list<void **> accounts_xdata_ptrs; - -inline account_xdata_t& account_xdata(const account_t& account) { - if (! account.data) { - accounts_xdata.push_back(account_xdata_t()); - account.data = &accounts_xdata.back(); - accounts_xdata_ptrs.push_back(&account.data); - } - return *((account_xdata_t *) account.data); -} - -inline void set_account_value::operator()(transaction_t& xact) { - add_transaction_to(xact, account_xdata(*xact.account).value); - account_xdata(*xact.account).subcount++; - - if (handler) - (*handler)(xact); -} - -////////////////////////////////////////////////////////////////////// - -void sum_accounts(account_t& account); - -typedef std::deque<account_t *> accounts_deque; - -void sort_accounts(account_t& account, - const value_expr_t * sort_order, - accounts_deque& accounts); - -void walk_accounts(account_t& account, - item_handler<account_t>& handler, - const value_expr_t * sort_order = NULL); - -void walk_accounts(account_t& account, - item_handler<account_t>& handler, - const std::string& sort_string); - -void clear_accounts_xdata(); - -} // namespace ledger - -#endif // _WALK_H |