summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autoxact.cc25
-rw-r--r--autoxact.h11
-rw-r--r--journal.cc44
-rw-r--r--journal.h37
-rw-r--r--python.cc2
-rw-r--r--textual.cc17
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 <boost/python.hpp>
-#include <Python.h>
-
-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<bool>(pyobj.ptr(), entry);
+ }
+};
+
+std::list<py_entry_finalizer_t> py_finalizers;
-void py_add_entry_finalize_hook(journal_t& journal, object x)
+void py_add_entry_finalizer(journal_t& journal, object x)
{
- add_hook(journal.entry_finalize_hooks,
- extract<journal_t::entry_finalize_hook_t>(x));
+ py_finalizers.push_back(py_entry_finalizer_t(x));
+ add_hook<entry_finalizer_t *>(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<journal_t::entry_finalize_hook_t>(x));
+ for (std::list<py_entry_finalizer_t>::iterator i = py_finalizers.begin();
+ i != py_finalizers.end();
+ i++)
+ if ((*i).pyobj == x) {
+ remove_hook<entry_finalizer_t *>(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 <typename T>
-void add_hook(std::list<T>& list, T func, const bool prepend = false) {
+void add_hook(std::list<T>& 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 <typename T>
-void remove_hook(std::list<T>& list, T func) {
- list.remove(func);
+void remove_hook(std::list<T>& list, T obj) {
+ list.remove(obj);
}
template <typename T, typename Data>
-bool run_hooks(std::list<T>& list, Data& entry) {
+bool run_hooks(std::list<T>& list, Data& item) {
for (typename std::list<T>::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_hook_t> entry_finalize_hooks;
+ std::list<entry_finalizer_t *> 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_t *> account_stack;
- automated_transactions_t auto_xacts;
-
- current_auto_xacts = &auto_xacts;
+ std::deque<account_t *> 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<entry_finalizer_t *>(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<unsigned int> save_linenum(linenum);
push_var<std::string> save_path(path);
- push_var<automated_transactions_t *>
- 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<entry_finalizer_t *>(journal->entry_finalize_hooks,
+ &autoxact_finalizer);
if (time_commodity) {
time_commodity->precision = 2;
time_commodity->flags |= COMMODITY_STYLE_NOMARKET;