changed entry_finalizer scheme to use objects, not just function pointers
This commit is contained in:
parent
c715528f2f
commit
4f56735dfa
6 changed files with 72 additions and 64 deletions
25
autoxact.cc
25
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
|
||||
|
|
|
|||
11
autoxact.h
11
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
|
||||
|
||||
|
|
|
|||
44
journal.cc
44
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);
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
;
|
||||
|
|
|
|||
37
journal.h
37
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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
17
textual.cc
17
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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue