From 4f56735dfa83b4415be52793bcc99fa4623b69a5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 24 Sep 2004 04:10:39 -0400 Subject: [PATCH] changed entry_finalizer scheme to use objects, not just function pointers --- autoxact.cc | 25 ------------------------- autoxact.h | 11 ++++++++--- journal.cc | 44 +++++++++++++++++++++++++++++--------------- journal.h | 37 ++++++++++++++++++++++++++----------- python.cc | 2 -- textual.cc | 17 +++++++++-------- 6 files changed, 72 insertions(+), 64 deletions(-) diff --git a/autoxact.cc b/autoxact.cc index 4de8122d..bed69e2e 100644 --- a/autoxact.cc +++ b/autoxact.cc @@ -27,29 +27,4 @@ void automated_transaction_t::extend_entry(entry_t& entry) } } -automated_transactions_t * current_auto_xacts = NULL; - -bool handle_auto_xacts(entry_t& entry) -{ - if (current_auto_xacts && - ! current_auto_xacts->automated_transactions.empty()) - current_auto_xacts->extend_entry(entry); - - return true; -} - } // namespace ledger - -#ifdef USE_BOOST_PYTHON - -#include -#include - -using namespace boost::python; -using namespace ledger; - -void export_autoxact() { - def("handle_auto_xacts", handle_auto_xacts); -} - -#endif // USE_BOOST_PYTHON diff --git a/autoxact.h b/autoxact.h index d3acd27c..c85890c6 100644 --- a/autoxact.h +++ b/autoxact.h @@ -88,9 +88,14 @@ public: } }; -extern automated_transactions_t * current_auto_xacts; - -bool handle_auto_xacts(entry_t& entry); +struct autoxact_finalizer_t : public entry_finalizer_t { + automated_transactions_t auto_xacts; + virtual bool operator()(entry_t& entry) { + if (! auto_xacts.automated_transactions.empty()) + auto_xacts.extend_entry(entry); + return true; + } +}; } // namespace ledger diff --git a/journal.cc b/journal.cc index af3f4832..4166d45e 100644 --- a/journal.cc +++ b/journal.cc @@ -360,6 +360,7 @@ journal_t::~journal_t() { DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t"); + delete default_finalizer; delete master; // Don't bother unhooking each entry's transactions from the @@ -574,27 +575,42 @@ account_t * py_find_account_2(journal_t& journal, const std::string& name, return journal.find_account(name, auto_create); } -#if 0 +struct py_entry_finalizer_t : public entry_finalizer_t { + object pyobj; + py_entry_finalizer_t() {} + py_entry_finalizer_t(object obj) : pyobj(obj) {} + py_entry_finalizer_t(const py_entry_finalizer_t& other) + : pyobj(other.pyobj) {} + virtual bool operator()(entry_t& entry) { + return call(pyobj.ptr(), entry); + } +}; -void py_add_entry_finalize_hook(journal_t& journal, object x) +std::list py_finalizers; + +void py_add_entry_finalizer(journal_t& journal, object x) { - add_hook(journal.entry_finalize_hooks, - extract(x)); + py_finalizers.push_back(py_entry_finalizer_t(x)); + add_hook(journal.entry_finalize_hooks, + &py_finalizers.back()); } -void py_remove_entry_finalize_hook(journal_t& journal, object x) +void py_remove_entry_finalizer(journal_t& journal, object x) { - remove_hook(journal.entry_finalize_hooks, - extract(x)); + for (std::list::iterator i = py_finalizers.begin(); + i != py_finalizers.end(); + i++) + if ((*i).pyobj == x) { + remove_hook(journal.entry_finalize_hooks, &(*i)); + return; + } } -void py_run_entry_finalize_hooks(journal_t& journal, entry_t& entry) +void py_run_entry_finalizers(journal_t& journal, entry_t& entry) { run_hooks(journal.entry_finalize_hooks, entry); } -#endif - #define EXC_TRANSLATOR(type) \ void exc_translate_ ## type(const type& err) { \ PyErr_SetString(PyExc_RuntimeError, err.what()); \ @@ -682,11 +698,9 @@ void export_journal() .def("add_entry", &journal_t::add_entry) .def("remove_entry", &journal_t::remove_entry) -#if 0 - .def("add_entry_finalize_hook", py_add_entry_finalize_hook) - .def("remove_entry_finalize_hook", py_remove_entry_finalize_hook) - .def("run_entry_finalize_hooks", py_run_entry_finalize_hooks) -#endif + .def("add_entry_finalizer", py_add_entry_finalizer) + .def("remove_entry_finalizer", py_remove_entry_finalizer) + .def("run_entry_finalizers", py_run_entry_finalizers) .def("valid", &journal_t::valid) ; diff --git a/journal.h b/journal.h index 367551c1..30271f6a 100644 --- a/journal.h +++ b/journal.h @@ -174,25 +174,40 @@ class account_t std::ostream& operator<<(std::ostream& out, const account_t& account); +struct entry_finalizer_t { + virtual ~entry_finalizer_t() {} + virtual bool operator()(entry_t& entry) = 0; +}; + +struct func_finalizer_t : public entry_finalizer_t { + typedef bool (*func_t)(entry_t& entry); + func_t func; + func_finalizer_t(func_t _func) : func(_func) {} + func_finalizer_t(const func_finalizer_t& other) : func(other.func) {} + virtual bool operator()(entry_t& entry) { + return func(entry); + } +}; + template -void add_hook(std::list& list, T func, const bool prepend = false) { +void add_hook(std::list& list, T obj, const bool prepend = false) { if (prepend) - list.push_front(func); + list.push_front(obj); else - list.push_back(func); + list.push_back(obj); } template -void remove_hook(std::list& list, T func) { - list.remove(func); +void remove_hook(std::list& list, T obj) { + list.remove(obj); } template -bool run_hooks(std::list& list, Data& entry) { +bool run_hooks(std::list& list, Data& item) { for (typename std::list::const_iterator i = list.begin(); i != list.end(); i++) - if (! (*i)(entry)) + if (! (*(*i))(item)) return false; return true; } @@ -212,14 +227,14 @@ class journal_t mutable accounts_map accounts_cache; - typedef bool (*entry_finalize_hook_t)(entry_t& entry); - - std::list entry_finalize_hooks; + std::list entry_finalize_hooks; + entry_finalizer_t * default_finalizer; journal_t() { master = new account_t(NULL, ""); item_pool = item_pool_end = NULL; - add_hook(entry_finalize_hooks, finalize_entry); + default_finalizer = new func_finalizer_t(finalize_entry); + add_hook(entry_finalize_hooks, default_finalizer); } ~journal_t(); diff --git a/python.cc b/python.cc index 55c607bd..78f98d5d 100644 --- a/python.cc +++ b/python.cc @@ -28,7 +28,6 @@ void export_walk(); void export_format(); void export_valexpr(); void export_datetime(); -void export_autoxact(); void export_derive(); void initialize_ledger_for_python() @@ -50,7 +49,6 @@ void initialize_ledger_for_python() export_format(); export_valexpr(); export_datetime(); - export_autoxact(); export_derive(); module_initialized = true; diff --git a/textual.cc b/textual.cc index b6bc934c..ac205441 100644 --- a/textual.cc +++ b/textual.cc @@ -230,10 +230,8 @@ unsigned int textual_parser_t::parse(std::istream& in, unsigned int errors = 0; commodity_t * time_commodity = NULL; - std::deque account_stack; - automated_transactions_t auto_xacts; - - current_auto_xacts = &auto_xacts; + std::deque account_stack; + autoxact_finalizer_t autoxact_finalizer; if (! master) master = journal->master; @@ -433,10 +431,12 @@ unsigned int textual_parser_t::parse(std::istream& in, case '=': // automated transactions if (! added_autoxact_hook) { - add_hook(journal->entry_finalize_hooks, handle_auto_xacts); + add_hook(journal->entry_finalize_hooks, + &autoxact_finalizer); added_autoxact_hook = true; } - parse_automated_transactions(in, account_stack.front(), auto_xacts); + parse_automated_transactions(in, account_stack.front(), + autoxact_finalizer.auto_xacts); break; case '!': { // directive @@ -449,8 +449,6 @@ unsigned int textual_parser_t::parse(std::istream& in, push_var save_linenum(linenum); push_var save_path(path); - push_var - save_current_auto_xacts(current_auto_xacts); count += parse_journal_file(skip_ws(line), journal, account_stack.front()); @@ -496,6 +494,9 @@ unsigned int textual_parser_t::parse(std::istream& in, } done: + if (added_autoxact_hook) + remove_hook(journal->entry_finalize_hooks, + &autoxact_finalizer); if (time_commodity) { time_commodity->precision = 2; time_commodity->flags |= COMMODITY_STYLE_NOMARKET;