diff options
Diffstat (limited to 'walk.h')
-rw-r--r-- | walk.h | 664 |
1 files changed, 0 insertions, 664 deletions
diff --git a/walk.h b/walk.h deleted file mode 100644 index 887963bf..00000000 --- a/walk.h +++ /dev/null @@ -1,664 +0,0 @@ -#ifndef _WALK_H -#define _WALK_H - -#include "journal.h" -#include "balance.h" -#include "valexpr.h" -#include "datetime.h" - -#include <iostream> -#include <fstream> -#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_RECEIVED 0x0001 -#define TRANSACTION_HANDLED 0x0002 -#define TRANSACTION_TO_DISPLAY 0x0004 -#define TRANSACTION_DISPLAYED 0x0008 -#define TRANSACTION_NO_TOTAL 0x0010 -#define TRANSACTION_SORT_CALC 0x0020 -#define TRANSACTION_COMPOSITE 0x0040 -#define TRANSACTION_MATCHES 0x0080 - -struct transaction_xdata_t -{ - value_t total; - value_t sort_value; - value_t composite_amount; - unsigned int index; - unsigned short dflags; - std::time_t date; - account_t * account; - void * ptr; - - transaction_xdata_t() - : index(0), dflags(0), date(0), account(0), ptr(0) {} -}; - -inline bool transaction_has_xdata(const transaction_t& xact) { - return xact.data != NULL; -} - -inline transaction_xdata_t& transaction_xdata_(const transaction_t& xact) { - return *((transaction_xdata_t *) xact.data); -} - -transaction_xdata_t& transaction_xdata(const transaction_t& xact); -void add_transaction_to(const transaction_t& xact, value_t& value); - -inline account_t * xact_account(transaction_t& xact) { - account_t * account = transaction_xdata(xact).account; - if (account) - return account; - return xact.account; -} - -inline const account_t * xact_account(const transaction_t& xact) { - return xact_account(const_cast<transaction_t&>(xact)); -} - -////////////////////////////////////////////////////////////////////// - -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_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); -} - -////////////////////////////////////////////////////////////////////// - -class ignore_transactions : public item_handler<transaction_t> -{ - public: - virtual void operator()(transaction_t& xact) {} -}; - -class clear_transaction_xdata : public item_handler<transaction_t> -{ - public: - virtual void operator()(transaction_t& xact) { - if (xact.data) { - delete (transaction_xdata_t *) xact.data; - xact.data = NULL; - } - } -}; - -class truncate_entries : public item_handler<transaction_t> -{ - int head_count; - int tail_count; - - transactions_list xacts; - - public: - truncate_entries(item_handler<transaction_t> * handler, - int _head_count, int _tail_count) - : item_handler<transaction_t>(handler), - head_count(_head_count), tail_count(_tail_count) {} - - virtual void flush(); - virtual void operator()(transaction_t& xact) { - xacts.push_back(&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 push_to_transactions_list : public item_handler<transaction_t> -{ - public: - transactions_list& xact_list; - - push_to_transactions_list(transactions_list& _xact_list) - : xact_list(_xact_list) {} - - virtual void operator()(transaction_t& xact) { - xact_list.push_back(&xact); - } -}; - -class sort_transactions : public item_handler<transaction_t> -{ - typedef std::deque<transaction_t *> transactions_deque; - - 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(false) { - try { - sort_order = parse_value_expr(_sort_order); - allocated = true; - } - 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 post_accumulated_xacts(); - - virtual void flush() { - post_accumulated_xacts(); - item_handler<transaction_t>::flush(); - } - - virtual void operator()(transaction_t& xact) { - transactions.push_back(&xact); - } -}; - -class filter_transactions : public item_handler<transaction_t> -{ - item_predicate<transaction_t> pred; - - public: - filter_transactions(item_handler<transaction_t> * handler, - const value_expr_t * predicate) - : item_handler<transaction_t>(handler), pred(predicate) {} - - filter_transactions(item_handler<transaction_t> * handler, - const std::string& predicate) - : item_handler<transaction_t>(handler), pred(predicate) {} - - virtual void operator()(transaction_t& xact) { - if (pred(xact)) { - transaction_xdata(xact).dflags |= TRANSACTION_MATCHES; - (*handler)(xact); - } - } -}; - -class calc_transactions : public item_handler<transaction_t> -{ - transaction_t * last_xact; - - public: - calc_transactions(item_handler<transaction_t> * handler) - : item_handler<transaction_t>(handler), last_xact(NULL) {} - - virtual void operator()(transaction_t& xact); -}; - -class invert_transactions : public item_handler<transaction_t> -{ - public: - invert_transactions(item_handler<transaction_t> * handler) - : item_handler<transaction_t>(handler) {} - - virtual void operator()(transaction_t& xact); -}; - -inline void clear_entries_transactions(std::list<entry_t>& entries_list) { - for (std::list<entry_t>::iterator i = entries_list.begin(); - i != entries_list.end(); - i++) - (*i).transactions.clear(); -} - -class collapse_transactions : public item_handler<transaction_t> -{ - value_t subtotal; - unsigned int count; - entry_t * last_entry; - transaction_t * last_xact; - account_t totals_account; - - std::list<entry_t> entry_temps; - 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>") {} - - ~collapse_transactions() { - clear_entries_transactions(entry_temps); - } - - virtual void flush() { - if (subtotal) - report_subtotal(); - item_handler<transaction_t>::flush(); - } - - void report_subtotal(); - - virtual void operator()(transaction_t& xact); -}; - -class related_transactions : public item_handler<transaction_t> -{ - transactions_list transactions; - 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 flush(); - virtual void operator()(transaction_t& xact) { - transaction_xdata(xact).dflags |= TRANSACTION_RECEIVED; - transactions.push_back(&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; - value_t last_balance; - - 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) {} - - ~changed_value_transactions() { - clear_entries_transactions(entry_temps); - } - - virtual void flush() { - if (last_xact) { - output_diff(now); - 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> -{ - struct acct_value_t { - account_t * account; - value_t value; - - acct_value_t(account_t * a) : account(a) {} - acct_value_t(account_t * a, value_t& v) : account(a), value(v) {} - acct_value_t(const acct_value_t& av) - : account(av.account), value(av.value) {} - }; - - typedef std::map<std::string, acct_value_t> values_map; - typedef std::pair<std::string, acct_value_t> values_pair; - - protected: - values_map values; - - std::list<entry_t> entry_temps; - std::list<transaction_t> xact_temps; - - public: - std::time_t start; - std::time_t finish; - - subtotal_transactions(item_handler<transaction_t> * handler) - : item_handler<transaction_t>(handler), start(0), finish(0) {} -#ifdef DEBUG_ENABLED - subtotal_transactions(const subtotal_transactions&) { - assert(0); - } -#endif - - ~subtotal_transactions() { - clear_entries_transactions(entry_temps); - } - - void report_subtotal(const char * spec_fmt = NULL); - - virtual void flush() { - if (values.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; - bool started; - - sort_transactions * sorter; - - public: - interval_transactions(item_handler<transaction_t> * _handler, - const interval_t& _interval, - const value_expr_t * sort_order = NULL) - : subtotal_transactions(_handler), interval(_interval), - last_xact(NULL), started(false), sorter(NULL) { - if (sort_order) { - sorter = new sort_transactions(handler, sort_order); - handler = sorter; - } - } - interval_transactions(item_handler<transaction_t> * _handler, - const std::string& _interval, - const std::string& sort_order = "") - : subtotal_transactions(_handler), interval(_interval), - last_xact(NULL), started(false), sorter(NULL) { - if (! sort_order.empty()) { - sorter = new sort_transactions(handler, sort_order); - handler = sorter; - } - } - - virtual ~interval_transactions() { - if (sorter) - delete sorter; - } - - void report_subtotal(const std::time_t moment = 0); - - virtual void flush() { - if (last_xact) - report_subtotal(); - subtotal_transactions::flush(); - } - virtual void operator()(transaction_t& xact); -}; - -class by_payee_transactions : public item_handler<transaction_t> -{ - typedef std::map<std::string, subtotal_transactions *> payee_subtotals_map; - typedef std::pair<std::string, subtotal_transactions *> payee_subtotals_pair; - - payee_subtotals_map payee_subtotals; - - public: - by_payee_transactions(item_handler<transaction_t> * handler) - : item_handler<transaction_t>(handler) {} - - virtual ~by_payee_transactions(); - - virtual void flush(); - virtual void operator()(transaction_t& xact); -}; - -class set_comm_as_payee : public item_handler<transaction_t> -{ - std::list<entry_t> entry_temps; - std::list<transaction_t> xact_temps; - - public: - set_comm_as_payee(item_handler<transaction_t> * handler) - : item_handler<transaction_t>(handler) {} - - ~set_comm_as_payee() { - clear_entries_transactions(entry_temps); - } - - 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) { - std::time_t when = xact.date(); - struct std::tm * desc = std::localtime(&when); - days_of_the_week[desc->tm_wday].push_back(&xact); - } -}; - -class generate_transactions : public item_handler<transaction_t> -{ - protected: - typedef std::pair<interval_t, transaction_t *> pending_xacts_pair; - typedef std::list<pending_xacts_pair> pending_xacts_list; - - pending_xacts_list pending_xacts; - std::list<entry_t> entry_temps; - std::list<transaction_t> xact_temps; - - public: - generate_transactions(item_handler<transaction_t> * handler) - : item_handler<transaction_t>(handler) {} - - ~generate_transactions() { - clear_entries_transactions(entry_temps); - } - - void add_period_entries(period_entries_list& period_entries); - - virtual void add_transaction(const interval_t& period, transaction_t& xact); -}; - -#define BUDGET_NO_BUDGET 0x00 -#define BUDGET_BUDGETED 0x01 -#define BUDGET_UNBUDGETED 0x02 - -class budget_transactions : public generate_transactions -{ - unsigned short flags; - - public: - budget_transactions(item_handler<transaction_t> * handler, - unsigned long _flags = BUDGET_BUDGETED) - : generate_transactions(handler), flags(_flags) {} - - void report_budget_items(const std::time_t moment); - - virtual void operator()(transaction_t& xact); -}; - -class forecast_transactions : public generate_transactions -{ - item_predicate<transaction_t> pred; - - public: - forecast_transactions(item_handler<transaction_t> * handler, - const value_expr_t * predicate) - : generate_transactions(handler), pred(predicate) {} - - forecast_transactions(item_handler<transaction_t> * handler, - const std::string& predicate) - : generate_transactions(handler), pred(predicate) {} - - virtual void add_transaction(const interval_t& period, - transaction_t& xact); - virtual void flush(); -}; - - -////////////////////////////////////////////////////////////////////// -// -// Account walking functions -// - -#define ACCOUNT_TO_DISPLAY 0x0001 -#define ACCOUNT_DISPLAYED 0x0002 -#define ACCOUNT_SORT_CALC 0x0004 -#define ACCOUNT_HAS_NON_VIRTUALS 0x0008 -#define ACCOUNT_HAS_UNB_VIRTUALS 0x0010 - -struct account_xdata_t -{ - value_t value; - value_t total; - value_t sort_value; - unsigned int count; // transactions counted toward amount - unsigned int total_count; // transactions counted toward total - unsigned int virtuals; - unsigned short dflags; - - account_xdata_t() : count(0), total_count(0), virtuals(0), dflags(0) {} -}; - -inline bool account_has_xdata(const account_t& account) { - return account.data != NULL; -} - -inline account_xdata_t& account_xdata_(const account_t& account) { - return *((account_xdata_t *) account.data); -} - -account_xdata_t& account_xdata(const account_t& account); - -////////////////////////////////////////////////////////////////////// - -class clear_account_xdata : public item_handler<account_t> -{ - public: - virtual void operator()(account_t& acct) { - if (acct.data) { - delete (account_xdata_t *) acct.data; - acct.data = NULL; - } - } -}; - -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 walk_commodities(commodities_map& commodities, - item_handler<transaction_t>& handler); - -inline void clear_journal_xdata(journal_t * journal) { - clear_transaction_xdata xact_cleaner; - walk_entries(journal->entries, xact_cleaner); - - clear_account_xdata acct_cleaner; - walk_accounts(*journal->master, acct_cleaner); -} - -} // namespace ledger - -#endif // _WALK_H |