changed entry_finalizer scheme to use objects, not just function pointers

This commit is contained in:
John Wiegley 2004-09-24 04:10:39 -04:00
parent c715528f2f
commit 4f56735dfa
6 changed files with 72 additions and 64 deletions

View file

@ -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

View file

@ -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

View file

@ -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);
}
};
void py_add_entry_finalize_hook(journal_t& journal, object x)
std::list<py_entry_finalizer_t> py_finalizers;
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)
;

View file

@ -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();

View file

@ -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;

View file

@ -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;