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
|
} // 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;
|
struct autoxact_finalizer_t : public entry_finalizer_t {
|
||||||
|
automated_transactions_t auto_xacts;
|
||||||
bool handle_auto_xacts(entry_t& entry);
|
virtual bool operator()(entry_t& entry) {
|
||||||
|
if (! auto_xacts.automated_transactions.empty())
|
||||||
|
auto_xacts.extend_entry(entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
||||||
|
|
|
||||||
44
journal.cc
44
journal.cc
|
|
@ -360,6 +360,7 @@ journal_t::~journal_t()
|
||||||
{
|
{
|
||||||
DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t");
|
DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t");
|
||||||
|
|
||||||
|
delete default_finalizer;
|
||||||
delete master;
|
delete master;
|
||||||
|
|
||||||
// Don't bother unhooking each entry's transactions from the
|
// 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);
|
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,
|
py_finalizers.push_back(py_entry_finalizer_t(x));
|
||||||
extract<journal_t::entry_finalize_hook_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,
|
for (std::list<py_entry_finalizer_t>::iterator i = py_finalizers.begin();
|
||||||
extract<journal_t::entry_finalize_hook_t>(x));
|
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);
|
run_hooks(journal.entry_finalize_hooks, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define EXC_TRANSLATOR(type) \
|
#define EXC_TRANSLATOR(type) \
|
||||||
void exc_translate_ ## type(const type& err) { \
|
void exc_translate_ ## type(const type& err) { \
|
||||||
PyErr_SetString(PyExc_RuntimeError, err.what()); \
|
PyErr_SetString(PyExc_RuntimeError, err.what()); \
|
||||||
|
|
@ -682,11 +698,9 @@ void export_journal()
|
||||||
|
|
||||||
.def("add_entry", &journal_t::add_entry)
|
.def("add_entry", &journal_t::add_entry)
|
||||||
.def("remove_entry", &journal_t::remove_entry)
|
.def("remove_entry", &journal_t::remove_entry)
|
||||||
#if 0
|
.def("add_entry_finalizer", py_add_entry_finalizer)
|
||||||
.def("add_entry_finalize_hook", py_add_entry_finalize_hook)
|
.def("remove_entry_finalizer", py_remove_entry_finalizer)
|
||||||
.def("remove_entry_finalize_hook", py_remove_entry_finalize_hook)
|
.def("run_entry_finalizers", py_run_entry_finalizers)
|
||||||
.def("run_entry_finalize_hooks", py_run_entry_finalize_hooks)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.def("valid", &journal_t::valid)
|
.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);
|
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>
|
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)
|
if (prepend)
|
||||||
list.push_front(func);
|
list.push_front(obj);
|
||||||
else
|
else
|
||||||
list.push_back(func);
|
list.push_back(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void remove_hook(std::list<T>& list, T func) {
|
void remove_hook(std::list<T>& list, T obj) {
|
||||||
list.remove(func);
|
list.remove(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename Data>
|
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();
|
for (typename std::list<T>::const_iterator i = list.begin();
|
||||||
i != list.end();
|
i != list.end();
|
||||||
i++)
|
i++)
|
||||||
if (! (*i)(entry))
|
if (! (*(*i))(item))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -212,14 +227,14 @@ class journal_t
|
||||||
|
|
||||||
mutable accounts_map accounts_cache;
|
mutable accounts_map accounts_cache;
|
||||||
|
|
||||||
typedef bool (*entry_finalize_hook_t)(entry_t& entry);
|
std::list<entry_finalizer_t *> entry_finalize_hooks;
|
||||||
|
entry_finalizer_t * default_finalizer;
|
||||||
std::list<entry_finalize_hook_t> entry_finalize_hooks;
|
|
||||||
|
|
||||||
journal_t() {
|
journal_t() {
|
||||||
master = new account_t(NULL, "");
|
master = new account_t(NULL, "");
|
||||||
item_pool = item_pool_end = 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();
|
~journal_t();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ void export_walk();
|
||||||
void export_format();
|
void export_format();
|
||||||
void export_valexpr();
|
void export_valexpr();
|
||||||
void export_datetime();
|
void export_datetime();
|
||||||
void export_autoxact();
|
|
||||||
void export_derive();
|
void export_derive();
|
||||||
|
|
||||||
void initialize_ledger_for_python()
|
void initialize_ledger_for_python()
|
||||||
|
|
@ -50,7 +49,6 @@ void initialize_ledger_for_python()
|
||||||
export_format();
|
export_format();
|
||||||
export_valexpr();
|
export_valexpr();
|
||||||
export_datetime();
|
export_datetime();
|
||||||
export_autoxact();
|
|
||||||
export_derive();
|
export_derive();
|
||||||
|
|
||||||
module_initialized = true;
|
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;
|
unsigned int errors = 0;
|
||||||
commodity_t * time_commodity = NULL;
|
commodity_t * time_commodity = NULL;
|
||||||
|
|
||||||
std::deque<account_t *> account_stack;
|
std::deque<account_t *> account_stack;
|
||||||
automated_transactions_t auto_xacts;
|
autoxact_finalizer_t autoxact_finalizer;
|
||||||
|
|
||||||
current_auto_xacts = &auto_xacts;
|
|
||||||
|
|
||||||
if (! master)
|
if (! master)
|
||||||
master = journal->master;
|
master = journal->master;
|
||||||
|
|
@ -433,10 +431,12 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
|
|
||||||
case '=': // automated transactions
|
case '=': // automated transactions
|
||||||
if (! added_autoxact_hook) {
|
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;
|
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;
|
break;
|
||||||
|
|
||||||
case '!': { // directive
|
case '!': { // directive
|
||||||
|
|
@ -449,8 +449,6 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
|
|
||||||
push_var<unsigned int> save_linenum(linenum);
|
push_var<unsigned int> save_linenum(linenum);
|
||||||
push_var<std::string> save_path(path);
|
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,
|
count += parse_journal_file(skip_ws(line), journal,
|
||||||
account_stack.front());
|
account_stack.front());
|
||||||
|
|
@ -496,6 +494,9 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
if (added_autoxact_hook)
|
||||||
|
remove_hook<entry_finalizer_t *>(journal->entry_finalize_hooks,
|
||||||
|
&autoxact_finalizer);
|
||||||
if (time_commodity) {
|
if (time_commodity) {
|
||||||
time_commodity->precision = 2;
|
time_commodity->precision = 2;
|
||||||
time_commodity->flags |= COMMODITY_STYLE_NOMARKET;
|
time_commodity->flags |= COMMODITY_STYLE_NOMARKET;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue