summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xacprep3
-rw-r--r--autoxact.cc11
-rw-r--r--autoxact.h4
-rw-r--r--format.cc94
-rw-r--r--format.h99
-rw-r--r--journal.cc24
-rw-r--r--ledger.h5
-rw-r--r--main.cc2
-rwxr-xr-xmain.py70
-rw-r--r--textual.cc27
-rw-r--r--textual.h29
-rw-r--r--valexpr.cc10
-rw-r--r--walk.cc127
-rw-r--r--walk.h71
14 files changed, 383 insertions, 193 deletions
diff --git a/acprep b/acprep
index f479a924..17c9d2f3 100755
--- a/acprep
+++ b/acprep
@@ -23,6 +23,9 @@ if [ "$1" = "--debug" ]; then
elif [ "$1" = "--opt" ]; then
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
CXXFLAGS="-fomit-frame-pointer -fastf -mcpu=7450 -fPIC"
+elif [ "$1" = "--flat-opt" ]; then
+ ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
+ CXXFLAGS="-fomit-frame-pointer -fastf -mcpu=7450" --disable-shared
elif [ "$1" = "--perf" ]; then
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="-g -pg"
fi
diff --git a/autoxact.cc b/autoxact.cc
index d358daf3..cc07ad2f 100644
--- a/autoxact.cc
+++ b/autoxact.cc
@@ -27,4 +27,15 @@ 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
diff --git a/autoxact.h b/autoxact.h
index 9e25d967..301a2b26 100644
--- a/autoxact.h
+++ b/autoxact.h
@@ -88,6 +88,10 @@ public:
}
};
+extern automated_transactions_t * current_auto_xacts;
+
+bool handle_auto_xacts(entry_t * entry);
+
} // namespace ledger
#endif // _AUTOXACT_H
diff --git a/format.cc b/format.cc
index 33c465ca..cb5d3027 100644
--- a/format.cc
+++ b/format.cc
@@ -373,10 +373,37 @@ void format_t::format(std::ostream& out, const details_t& details) const
}
}
-bool format_account::disp_subaccounts_p(const account_t& account,
- const item_predicate<account_t>&
- disp_pred,
- const account_t *& to_show)
+format_transactions::format_transactions(std::ostream& _output_stream,
+ const std::string& format)
+ : output_stream(_output_stream), last_entry(NULL)
+{
+ const char * f = format.c_str();
+ if (const char * p = std::strstr(f, "%/")) {
+ first_line_format.reset(std::string(f, 0, p - f));
+ next_lines_format.reset(std::string(p + 2));
+ } else {
+ first_line_format.reset(format);
+ next_lines_format.reset(format);
+ }
+}
+
+void format_transactions::operator()(transaction_t& xact)
+{
+ if (! transaction_has_xdata(xact) ||
+ ! (transaction_xdata(xact).dflags & TRANSACTION_DISPLAYED)) {
+ if (last_entry != xact.entry) {
+ first_line_format.format(output_stream, details_t(xact));
+ last_entry = xact.entry;
+ } else {
+ next_lines_format.format(output_stream, details_t(xact));
+ }
+ transaction_xdata(xact).dflags |= TRANSACTION_DISPLAYED;
+ }
+}
+
+bool disp_subaccounts_p(const account_t& account,
+ const item_predicate<account_t>& disp_pred,
+ const account_t *& to_show)
{
bool display = false;
unsigned int counted = 0;
@@ -410,8 +437,8 @@ bool format_account::disp_subaccounts_p(const account_t& account,
return display;
}
-bool format_account::display_account(const account_t& account,
- const item_predicate<account_t>& disp_pred)
+bool display_account(const account_t& account,
+ const item_predicate<account_t>& disp_pred)
{
// Never display an account that has already been displayed.
if (account_has_xdata(account) &&
@@ -432,6 +459,59 @@ bool format_account::display_account(const account_t& account,
return ! account_to_show && disp_pred(account);
}
+void format_account::operator()(account_t& account)
+{
+ if (display_account(account, disp_pred)) {
+ if (! account.parent) {
+ account_xdata(account).dflags |= ACCOUNT_TO_DISPLAY;
+ } else {
+ format.format(output_stream, details_t(account));
+ account_xdata(account).dflags |= ACCOUNT_DISPLAYED;
+ }
+ }
+}
+
+format_equity::format_equity(std::ostream& _output_stream,
+ const std::string& _format,
+ const std::string& display_predicate)
+ : output_stream(_output_stream), disp_pred(display_predicate)
+{
+ const char * f = _format.c_str();
+ if (const char * p = std::strstr(f, "%/")) {
+ first_line_format.reset(std::string(f, 0, p - f));
+ next_lines_format.reset(std::string(p + 2));
+ } else {
+ first_line_format.reset(_format);
+ next_lines_format.reset(_format);
+ }
+
+ entry_t header_entry;
+ header_entry.payee = "Opening Balances";
+ header_entry.date = std::time(NULL);
+ first_line_format.format(output_stream, details_t(header_entry));
+}
+
+void format_equity::flush()
+{
+ account_xdata_t xdata;
+ xdata.value = total;
+ xdata.value.negate();
+ account_t summary(NULL, "Equity:Opening Balances");
+ summary.data = &xdata;
+ next_lines_format.format(output_stream, details_t(summary));
+ output_stream.flush();
+}
+
+void format_equity::operator()(account_t& account)
+{
+ if (display_account(account, disp_pred)) {
+ next_lines_format.format(output_stream, details_t(account));
+ if (account_has_xdata(account))
+ total += account_xdata(account).value;
+ account_xdata(account).dflags |= ACCOUNT_DISPLAYED;
+ }
+}
+
} // namespace ledger
#ifdef USE_BOOST_PYTHON
@@ -471,6 +551,8 @@ void export_format()
#if 0
def("partial_account_name", partial_account_name);
#endif
+
+ def("display_account", display_account);
}
#endif // USE_BOOST_PYTHON
diff --git a/format.h b/format.h
index b388d40e..945645f2 100644
--- a/format.h
+++ b/format.h
@@ -97,36 +97,27 @@ class format_transactions : public item_handler<transaction_t>
public:
format_transactions(std::ostream& _output_stream,
- const std::string& format)
- : output_stream(_output_stream), last_entry(NULL) {
- const char * f = format.c_str();
- if (const char * p = std::strstr(f, "%/")) {
- first_line_format.reset(std::string(f, 0, p - f));
- next_lines_format.reset(std::string(p + 2));
- } else {
- first_line_format.reset(format);
- next_lines_format.reset(format);
- }
- }
+ const std::string& format);
virtual void flush() {
output_stream.flush();
}
- virtual void operator()(transaction_t& xact) {
- if (! transaction_has_xdata(xact) ||
- ! (transaction_xdata(xact).dflags & TRANSACTION_DISPLAYED)) {
- if (last_entry != xact.entry) {
- first_line_format.format(output_stream, details_t(xact));
- last_entry = xact.entry;
- } else {
- next_lines_format.format(output_stream, details_t(xact));
- }
- transaction_xdata(xact).dflags |= TRANSACTION_DISPLAYED;
- }
- }
+ virtual void operator()(transaction_t& xact);
};
+bool disp_subaccounts_p(const account_t& account,
+ const item_predicate<account_t>& disp_pred,
+ const account_t *& to_show);
+
+inline bool disp_subaccounts_p(const account_t& account) {
+ const account_t * temp;
+ return disp_subaccounts_p(account, item_predicate<account_t>(NULL), temp);
+ }
+
+bool display_account(const account_t& account,
+ const item_predicate<account_t>& disp_pred);
+
class format_account : public item_handler<account_t>
{
std::ostream& output_stream;
@@ -142,38 +133,18 @@ class format_account : public item_handler<account_t>
: output_stream(_output_stream), format(_format),
disp_pred(display_predicate) {}
- static bool disp_subaccounts_p(const account_t& account,
- const item_predicate<account_t>& disp_pred,
- const account_t *& to_show);
- static bool disp_subaccounts_p(const account_t& account) {
- const account_t * temp;
- return disp_subaccounts_p(account, item_predicate<account_t>(NULL), temp);
- }
-
- static bool display_account(const account_t& account,
- const item_predicate<account_t>& disp_pred);
-
virtual void flush() {
output_stream.flush();
}
- virtual void operator()(account_t& account) {
- if (display_account(account, disp_pred)) {
- if (! account.parent) {
- account_xdata(account).dflags |= ACCOUNT_TO_DISPLAY;
- } else {
- format.format(output_stream, details_t(account));
- account_xdata(account).dflags |= ACCOUNT_DISPLAYED;
- }
- }
- }
+ virtual void operator()(account_t& account);
};
class format_equity : public item_handler<account_t>
{
- std::ostream& output_stream;
- const format_t& first_line_format;
- const format_t& next_lines_format;
+ std::ostream& output_stream;
+ format_t first_line_format;
+ format_t next_lines_format;
item_predicate<account_t> disp_pred;
@@ -181,37 +152,11 @@ class format_equity : public item_handler<account_t>
public:
format_equity(std::ostream& _output_stream,
- const format_t& _first_line_format,
- const format_t& _next_lines_format,
- const std::string& display_predicate = NULL)
- : output_stream(_output_stream),
- first_line_format(_first_line_format),
- next_lines_format(_next_lines_format),
- disp_pred(display_predicate) {
- entry_t header_entry;
- header_entry.payee = "Opening Balances";
- header_entry.date = std::time(NULL);
- first_line_format.format(output_stream, details_t(header_entry));
- }
+ const std::string& _format,
+ const std::string& display_predicate);
- virtual void flush() {
- account_xdata_t xdata;
- xdata.value = total;
- xdata.value.negate();
- account_t summary(NULL, "Equity:Opening Balances");
- summary.data = &xdata;
- next_lines_format.format(output_stream, details_t(summary));
- output_stream.flush();
- }
-
- virtual void operator()(account_t& account) {
- if (format_account::display_account(account, disp_pred)) {
- next_lines_format.format(output_stream, details_t(account));
- if (account_has_xdata(account))
- total += account_xdata(account).value;
- account_xdata(account).dflags |= ACCOUNT_DISPLAYED;
- }
- }
+ virtual void flush();
+ virtual void operator()(account_t& account);
};
} // namespace ledger
diff --git a/journal.cc b/journal.cc
index dde4a1d2..4fedc206 100644
--- a/journal.cc
+++ b/journal.cc
@@ -193,15 +193,8 @@ account_t * account_t::find_account(const std::string& name,
bool account_t::remove_transaction(transaction_t * xact)
{
- for (transactions_list::iterator i = transactions.begin();
- i != transactions.end();
- i++)
- if (*i == xact) {
- transactions.erase(i);
- return true;
- }
-
- return false;
+ transactions.remove(xact);
+ return true;
}
std::string account_t::fullname() const
@@ -224,6 +217,12 @@ std::string account_t::fullname() const
}
}
+std::ostream& operator<<(std::ostream& out, const account_t& account)
+{
+ out << account.fullname();
+ return out;
+}
+
bool account_t::valid() const
{
if (name.find('-') != std::string::npos)
@@ -599,7 +598,9 @@ void export_journal()
.def(self == self)
.def(self != self)
- .def_readwrite("parent", &account_t::parent)
+ .add_property("parent",
+ make_getter(&account_t::parent,
+ return_internal_reference<1>()))
.def_readwrite("name", &account_t::name)
.def_readwrite("note", &account_t::note)
.def_readonly("depth", &account_t::depth)
@@ -624,6 +625,9 @@ void export_journal()
.def(self == self)
.def(self != self)
+ .add_property("master",
+ make_getter(&journal_t::master,
+ return_internal_reference<1>()))
.def_readonly("sources", &journal_t::sources)
.def("__len__", entries_len)
diff --git a/ledger.h b/ledger.h
index cc177f82..1aef2e3a 100644
--- a/ledger.h
+++ b/ledger.h
@@ -178,10 +178,7 @@ class account_t
bool valid() const;
};
-inline std::ostream& operator<<(std::ostream& out, const account_t& acct) {
- out << acct.fullname();
- return out;
-}
+std::ostream& operator<<(std::ostream& out, const account_t& account);
typedef std::list<entry_t *> entries_list;
diff --git a/main.cc b/main.cc
index 145497d8..db1eacd4 100644
--- a/main.cc
+++ b/main.cc
@@ -1,6 +1,7 @@
#include "ledger.h"
#include "parser.h"
#include "textual.h"
+#include "autoxact.h"
#include "binary.h"
#include "qif.h"
#include "acconf.h"
@@ -216,6 +217,7 @@ int parse_and_report(int argc, char * argv[], char * envp[])
#endif
std::auto_ptr<qif_parser_t> qif_parser(new qif_parser_t);
std::auto_ptr<textual_parser_t> text_parser(new textual_parser_t);
+ text_parser->add_finalize_hook(handle_auto_xacts);
register_parser(bin_parser.get());
#ifdef READ_GNUCASH
diff --git a/main.py b/main.py
index 458470f0..3a5fe7bc 100755
--- a/main.py
+++ b/main.py
@@ -116,12 +116,44 @@ class FormatTransaction (TransactionHandler):
self.output.flush ()
def __call__ (self, xact):
- if self.nformatter is not None and self.last_entry is not None and \
- xact.entry == self.last_entry:
- self.output.write(self.nformatter.format(xact))
+ if not transaction_has_xdata (xact) or \
+ not transaction_xdata (xact).dflags & TRANSACTION_DISPLAYED:
+ if self.nformatter is not None and \
+ self.last_entry is not None and \
+ xact.entry == self.last_entry:
+ self.output.write(self.nformatter.format(xact))
+ else:
+ self.output.write(self.formatter.format(xact))
+ self.last_entry = xact.entry
+
+class FormatAccount (AccountHandler):
+ output = None
+
+ def __init__ (self, fmt, pred):
+ self.formatter = Format (fmt)
+ self.predicate = AccountPredicate (pred)
+
+ if config.output_file:
+ self.output = open(config.output_file, "w")
else:
- self.output.write(self.formatter.format(xact))
- self.last_entry = xact.entry
+ self.output = sys.stdout
+
+ AccountHandler.__init__ (self)
+
+ def __del__ (self):
+ if config.output_file:
+ self.output.close ()
+
+ def flush (self):
+ self.output.flush ()
+
+ def __call__ (self, account):
+ if display_account (account, self.predicate):
+ if not account.parent:
+ account_xdata (account).dflags |= ACCOUNT_TO_DISPLAY
+ else:
+ self.output.write(self.formatter.format(account))
+ account_xdata (account).dflags |= ACCOUNT_DISPLAYED
if command == "b" or command == "E":
handler = SetAccountValue()
@@ -166,28 +198,24 @@ else:
handler.flush ()
-#if command == "b":
-# format_account acct_formatter(out, config.format,
-# config.display_predicate);
-# sum_accounts(*journal->master);
-# walk_accounts(*journal->master, acct_formatter, config.sort_string);
-# acct_formatter.flush();
-#
-# if (journal->master->data) {
-# ACCT_DATA(journal->master)->value = ACCT_DATA(journal->master)->total;
-#
-# if (ACCT_DATA(journal->master)->dflags & ACCOUNT_TO_DISPLAY) {
-# out << "--------------------\n";
-# config.format.format(out, details_t(*journal->master));
-# }
-# }
+if command == "b":
+ acct_formatter = FormatAccount (format, config.display_predicate)
+ sum_accounts (journal.master)
+ walk_accounts (journal.master, acct_formatter, config.sort_string)
+ acct_formatter.flush ()
+ #if account_has_xdata(journal.master):
+ # account_xdata(journal.master).value = account_xdata(journal.master).total;
+ #
+ # if account_xdata(journal.master).dflags & ACCOUNT_TO_DISPLAY:
+ # print "--------------------"
+ # config.format.format(out, details_t(*journal->master));
+
#elif command == "E":
# format_equity acct_formatter(out, config.format, config.nformat,
# config.display_predicate);
# sum_accounts(*journal->master);
# walk_accounts(*journal->master, acct_formatter, config.sort_string);
# acct_formatter.flush();
-# }
if config.use_cache and config.cache_dirty and config.cache_file:
write_binary_journal(config.cache_file, journal);
diff --git a/textual.cc b/textual.cc
index e95d0eff..4f60d898 100644
--- a/textual.cc
+++ b/textual.cc
@@ -121,7 +121,8 @@ transaction_t * parse_transaction(std::istream& in, account_t * account,
return parse_transaction_text(line, account, entry);
}
-void parse_automated_transactions(std::istream& in, account_t * account,
+void parse_automated_transactions(std::istream& in,
+ account_t * account,
automated_transactions_t& auto_xacts)
{
static char line[MAX_LINE + 1];
@@ -238,7 +239,8 @@ namespace {
TIMER_DEF(entry_date, "parsing entry date");
}
-entry_t * parse_entry(std::istream& in, account_t * master)
+entry_t * parse_entry(std::istream& in, account_t * master,
+ textual_parser_t& parser)
{
std::auto_ptr<entry_t> curr(new entry_t);
@@ -296,8 +298,10 @@ entry_t * parse_entry(std::istream& in, account_t * master)
TIMER_START(entry_finish);
- if (curr->transactions.empty() || ! finalize_entry(curr.get()))
+ if (curr->transactions.empty() ||
+ ! parser.run_finalize_hooks(curr.get())) {
return NULL; // ~auto_ptr will delete curr
+ }
TIMER_STOP(entry_finish);
@@ -326,6 +330,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
std::deque<account_t *> account_stack;
automated_transactions_t auto_xacts;
+ current_auto_xacts = &auto_xacts;
+
if (! master)
master = journal->master;
@@ -417,10 +423,10 @@ unsigned int textual_parser_t::parse(std::istream& in,
= new transaction_t(last_account, amt, TRANSACTION_VIRTUAL);
curr->add_transaction(xact);
- if (! finalize_entry(curr.get()) ||
+ if (! run_finalize_hooks(curr.get()) ||
! journal->add_entry(curr.release()))
- assert(0);
-
+ throw parse_error(path, linenum,
+ "Failed to record 'out' timelog entry");
count++;
} else {
throw parse_error(path, linenum, "Cannot parse timelog entry date");
@@ -551,7 +557,9 @@ unsigned int textual_parser_t::parse(std::istream& in,
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,
account_stack.front());
}
@@ -566,10 +574,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
default: {
unsigned int first_line = linenum;
- if (entry_t * entry = parse_entry(in, account_stack.front())) {
- if (! auto_xacts.automated_transactions.empty())
- auto_xacts.extend_entry(entry);
-
+ if (entry_t * entry = parse_entry(in, account_stack.front(), *this)) {
if (journal->add_entry(entry))
count++;
else
diff --git a/textual.h b/textual.h
index 5fe17dd8..a58153da 100644
--- a/textual.h
+++ b/textual.h
@@ -5,13 +5,42 @@
namespace ledger {
+bool finalize_entry(entry_t * entry);
+
class textual_parser_t : public parser_t
{
public:
+ typedef bool (*finalize_hook_t)(entry_t * entry);
+
+ std::list<finalize_hook_t> finalize_hooks;
+
+ textual_parser_t() {
+ add_finalize_hook(finalize_entry);
+ }
+
virtual bool test(std::istream& in) const {
return true;
}
+ void add_finalize_hook(finalize_hook_t func, bool prepend = false) {
+ if (prepend)
+ finalize_hooks.push_front(func);
+ else
+ finalize_hooks.push_back(func);
+ }
+ void remove_finalize_hook(finalize_hook_t func) {
+ finalize_hooks.remove(func);
+ }
+ bool run_finalize_hooks(entry_t * entry) {
+ for (std::list<finalize_hook_t>::const_iterator i
+ = finalize_hooks.begin();
+ i != finalize_hooks.end();
+ i++)
+ if (! (*i)(entry))
+ return false;
+ return true;
+ }
+
virtual unsigned int parse(std::istream& in,
journal_t * journal,
account_t * master = NULL,
diff --git a/valexpr.cc b/valexpr.cc
index 46c30e06..862f730d 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -945,6 +945,16 @@ void export_valexpr()
def("parse_value_expr", py_parse_value_expr,
return_value_policy<manage_new_object>());
+
+ class_< item_predicate<transaction_t> >
+ ("TransactionPredicate", init<std::string>())
+ .def("__call__", &item_predicate<transaction_t>::operator())
+ ;
+
+ class_< item_predicate<account_t> >
+ ("AccountPredicate", init<std::string>())
+ .def("__call__", &item_predicate<account_t>::operator())
+ ;
}
#endif // USE_BOOST_PYTHON
diff --git a/walk.cc b/walk.cc
index ae4624eb..205d4d65 100644
--- a/walk.cc
+++ b/walk.cc
@@ -298,6 +298,76 @@ void dow_transactions::flush()
}
}
+void sum_accounts(account_t& account)
+{
+ for (accounts_map::iterator i = account.accounts.begin();
+ i != account.accounts.end();
+ i++) {
+ sum_accounts(*(*i).second);
+ account_xdata(account).total += account_xdata(*(*i).second).total;
+ account_xdata(account).count += (account_xdata(*(*i).second).count +
+ account_xdata(*(*i).second).subcount);
+ }
+ account_xdata(account).total += account_xdata(account).value;
+ account_xdata(account).count += account_xdata(account).subcount;
+}
+
+void sort_accounts(account_t& account,
+ const value_expr_t * sort_order,
+ accounts_deque& accounts)
+{
+ for (accounts_map::iterator i = account.accounts.begin();
+ i != account.accounts.end();
+ i++)
+ accounts.push_back((*i).second);
+
+ std::stable_sort(accounts.begin(), accounts.end(),
+ compare_items<account_t>(sort_order));
+}
+
+void walk_accounts(account_t& account,
+ item_handler<account_t>& handler,
+ const value_expr_t * sort_order)
+{
+ handler(account);
+
+ if (sort_order) {
+ accounts_deque accounts;
+ sort_accounts(account, sort_order, accounts);
+ for (accounts_deque::const_iterator i = accounts.begin();
+ i != accounts.end();
+ i++)
+ walk_accounts(**i, handler, sort_order);
+ } else {
+ for (accounts_map::const_iterator i = account.accounts.begin();
+ i != account.accounts.end();
+ i++)
+ walk_accounts(*(*i).second, handler, NULL);
+ }
+}
+
+void walk_accounts(account_t& account,
+ item_handler<account_t>& handler,
+ const std::string& sort_string)
+{
+ if (! sort_string.empty()) {
+ std::auto_ptr<value_expr_t> sort_order(parse_value_expr(sort_string));
+ walk_accounts(account, handler, sort_order.get());
+ } else {
+ walk_accounts(account, handler);
+ }
+}
+
+void clear_accounts_xdata()
+{
+ accounts_xdata.clear();
+
+ for (std::list<void **>::iterator i = accounts_xdata_ptrs.begin();
+ i != accounts_xdata_ptrs.end();
+ i++)
+ **i = NULL;
+}
+
} // namespace ledger
#ifdef USE_BOOST_PYTHON
@@ -324,7 +394,7 @@ struct item_handler_wrap : public item_handler<T>
}
virtual void operator()(T& item) {
- call_method<void>(self, "__call__", item);
+ call_method<void>(self, "__call__", ptr(&item));
}
void default_call(T& item) {
item_handler<T>::operator()(item);
@@ -344,6 +414,26 @@ void py_walk_transactions(entry_t& entry, item_handler<transaction_t>& handler)
walk_transactions(entry.transactions, handler);
}
+void py_walk_accounts_1(account_t& account,
+ item_handler<account_t>& handler)
+{
+ walk_accounts(account, handler);
+}
+
+void py_walk_accounts_2(account_t& account,
+ item_handler<account_t>& handler,
+ const value_expr_t * sort_order)
+{
+ walk_accounts(account, handler, sort_order);
+}
+
+void py_walk_accounts_3(account_t& account,
+ item_handler<account_t>& handler,
+ const std::string& sort_string)
+{
+ walk_accounts(account, handler, sort_string);
+}
+
void export_walk()
{
typedef item_handler<transaction_t> xact_handler_t;
@@ -377,9 +467,8 @@ void export_walk()
.def("__call__", &ignore_transactions::operator());
;
- class_< set_account_value, bases<xact_handler_t> >
- ("SetAccountValue", init<xact_handler_t *>()
- [with_custodian_and_ward<1, 2>()])
+ class_< set_account_value, bases<xact_handler_t> > ("SetAccountValue")
+ .def(init<xact_handler_t *>()[with_custodian_and_ward<1, 2>()])
.def("flush", &xact_handler_t::flush)
.def("__call__", &set_account_value::operator());
;
@@ -455,6 +544,36 @@ void export_walk()
def("walk_entries", py_walk_entries);
def("walk_transactions", py_walk_transactions);
+
+ typedef item_handler<account_t> account_handler_t;
+
+ scope().attr("ACCOUNT_DISPLAYED") = ACCOUNT_DISPLAYED;
+ scope().attr("ACCOUNT_TO_DISPLAY") = ACCOUNT_TO_DISPLAY;
+
+ class_< account_xdata_t > ("AccountXData")
+ .def_readwrite("value", &account_xdata_t::value)
+ .def_readwrite("total", &account_xdata_t::total)
+ .def_readwrite("count", &account_xdata_t::count)
+ .def_readwrite("subcount", &account_xdata_t::subcount)
+ .def_readwrite("dflags", &account_xdata_t::dflags)
+ ;
+
+ def("account_has_xdata", account_has_xdata);
+ def("account_xdata", account_xdata, return_internal_reference<1>());
+
+ class_< account_handler_t, item_handler_wrap<account_t> > ("AccountHandler")
+ .def(init<account_handler_t *>())
+
+ .def("flush", &account_handler_t::flush,
+ &item_handler_wrap<account_t>::default_flush)
+ .def("__call__", &account_handler_t::operator(),
+ &item_handler_wrap<account_t>::default_call)
+ ;
+
+ def("sum_accounts", sum_accounts);
+ def("walk_accounts", py_walk_accounts_1);
+ def("walk_accounts", py_walk_accounts_2);
+ def("walk_accounts", py_walk_accounts_3);
}
#endif // USE_BOOST_PYTHON
diff --git a/walk.h b/walk.h
index 846ccfe1..147c900b 100644
--- a/walk.h
+++ b/walk.h
@@ -444,72 +444,23 @@ inline void set_account_value::operator()(transaction_t& xact) {
//////////////////////////////////////////////////////////////////////
-inline void sum_accounts(account_t& account) {
- for (accounts_map::iterator i = account.accounts.begin();
- i != account.accounts.end();
- i++) {
- sum_accounts(*(*i).second);
- account_xdata(account).total += account_xdata(*(*i).second).total;
- account_xdata(account).count += (account_xdata(*(*i).second).count +
- account_xdata(*(*i).second).subcount);
- }
- account_xdata(account).total += account_xdata(account).value;
- account_xdata(account).count += account_xdata(account).subcount;
-}
+void sum_accounts(account_t& account);
typedef std::deque<account_t *> accounts_deque;
-inline void sort_accounts(account_t& account,
- const value_expr_t * sort_order,
- accounts_deque& accounts) {
- for (accounts_map::iterator i = account.accounts.begin();
- i != account.accounts.end();
- i++)
- accounts.push_back((*i).second);
-
- std::stable_sort(accounts.begin(), accounts.end(),
- compare_items<account_t>(sort_order));
-}
-
-inline void walk_accounts(account_t& account,
- item_handler<account_t>& handler,
- const value_expr_t * sort_order = NULL) {
- handler(account);
-
- if (sort_order) {
- accounts_deque accounts;
- sort_accounts(account, sort_order, accounts);
- for (accounts_deque::const_iterator i = accounts.begin();
- i != accounts.end();
- i++)
- walk_accounts(**i, handler, sort_order);
- } else {
- for (accounts_map::const_iterator i = account.accounts.begin();
- i != account.accounts.end();
- i++)
- walk_accounts(*(*i).second, handler, NULL);
- }
-}
+void sort_accounts(account_t& account,
+ const value_expr_t * sort_order,
+ accounts_deque& accounts);
-inline void walk_accounts(account_t& account,
- item_handler<account_t>& handler,
- const std::string& sort_string) {
- if (! sort_string.empty()) {
- std::auto_ptr<value_expr_t> sort_order(parse_value_expr(sort_string));
- walk_accounts(account, handler, sort_order.get());
- } else {
- walk_accounts(account, handler);
- }
-}
+void walk_accounts(account_t& account,
+ item_handler<account_t>& handler,
+ const value_expr_t * sort_order = NULL);
-inline void clear_accounts_xdata() {
- accounts_xdata.clear();
+void walk_accounts(account_t& account,
+ item_handler<account_t>& handler,
+ const std::string& sort_string);
- for (std::list<void **>::iterator i = accounts_xdata_ptrs.begin();
- i != accounts_xdata_ptrs.end();
- i++)
- **i = NULL;
-}
+void clear_accounts_xdata();
} // namespace ledger