diff options
author | John Wiegley <johnw@newartisans.com> | 2004-08-28 04:26:48 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2004-08-28 04:26:48 -0400 |
commit | b4304515ff0501da47cbcd4b47c770e2bb55a83d (patch) | |
tree | 03bfa7fb21d09cffa20ded425016ad8b0aef7e21 | |
parent | 863485ad8ff29399fb9eafd1cfc863c5e8aa27f6 (diff) | |
download | fork-ledger-b4304515ff0501da47cbcd4b47c770e2bb55a83d.tar.gz fork-ledger-b4304515ff0501da47cbcd4b47c770e2bb55a83d.tar.bz2 fork-ledger-b4304515ff0501da47cbcd4b47c770e2bb55a83d.zip |
ledger.so (the python module) now builds based on autoconf discovery
-rw-r--r-- | Makefile.am | 34 | ||||
-rwxr-xr-x | acprep | 19 | ||||
-rw-r--r-- | amount.cc | 6 | ||||
-rw-r--r-- | balance.cc | 3 | ||||
-rw-r--r-- | config.cc | 4 | ||||
-rw-r--r-- | configure.in | 22 | ||||
-rw-r--r-- | journal.cc | 82 | ||||
-rw-r--r-- | ledger.h | 2 | ||||
-rw-r--r-- | main.cc | 14 | ||||
-rw-r--r-- | python.cc | 10 | ||||
-rwxr-xr-x | setup.py | 15 | ||||
-rw-r--r-- | textual.cc | 6 | ||||
-rw-r--r-- | walk.cc | 4 | ||||
-rw-r--r-- | walk.h | 16 |
14 files changed, 180 insertions, 57 deletions
diff --git a/Makefile.am b/Makefile.am index 76197716..5ce8a2e5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,6 +2,9 @@ lib_LTLIBRARIES = libledger.la libledger_la_SOURCES = amount.cc autoxact.cc balance.cc binary.cc config.cc \ datetime.cc format.cc journal.cc option.cc parser.cc qif.cc quotes.cc \ textual.cc valexpr.cc value.cc walk.cc +if READ_GNUCASH +libledger_la_SOURCES += gnucash.cc +endif if DEBUG libledger_la_CXXFLAGS = -DDEBUG_LEVEL=4 libledger_la_SOURCES += debug.cc @@ -10,11 +13,10 @@ if STANDALONE libledger_a_CXXFLAGS = -DSGI_STL_USE_SINGLE_CLIENT_ALLOCATOR=1 endif endif -if READ_GNUCASH -libledger_la_SOURCES += gnucash.cc -endif libledger_la_LDFLAGS = -version-info 2:0 +###################################################################### + bin_PROGRAMS = ledger if DEBUG ledger_CXXFLAGS = -DDEBUG_LEVEL=4 @@ -47,3 +49,29 @@ nobase_include_HEADERS = \ value.h \ walk.h info_TEXINFOS = ledger.texi + +###################################################################### + +if HAVE_PYTHON +if HAVE_BOOST_PYTHON + +noinst_LIBRARIES = libledger_bpy.a +libledger_bpy_a_SOURCES = amount.cc autoxact.cc balance.cc binary.cc config.cc \ + datetime.cc format.cc journal.cc option.cc parser.cc qif.cc quotes.cc \ + textual.cc valexpr.cc value.cc walk.cc +libledger_bpy_a_CXXFLAGS = -DUSE_BOOST_PYTHON=1 +if READ_GNUCASH +libledger_bpy_a_SOURCES += gnucash.cc +endif +if DEBUG +libledger_bpy_a_CXXFLAGS += -DDEBUG_LEVEL=4 +libledger_bpy_a_SOURCES += debug.cc +endif + +bin_PROGRAMS += ledger.so + +ledger.so: python.cc libledger_bpy.a + CFLAGS="$(CPPFLAGS) -L." python setup.py build --build-lib=. + +endif +endif @@ -14,23 +14,18 @@ fi autoconf INCDIRS="-I/sw/include -I/usr/include/httpd/xml -I/sw/include/python2.3" -LIBFLAGS="-L/sw/lib" - -if [ "$1" = "--boost" ]; then - BOOST="-DUSE_BOOST_PYTHON=1 -Wno-long-double" - shift -fi +INCDIRS="$INCDIRS -Wno-long-double" +LIBDIRS="-L/sw/lib" if [ "$1" = "--debug" ]; then - ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBFLAGS" \ - CXXFLAGS="-g $BOOST" --enable-debug --disable-shared + ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \ + CXXFLAGS="-g" --enable-debug --disable-shared elif [ "$1" = "--opt" ]; then - ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBFLAGS" \ - CXXFLAGS="-fomit-frame-pointer -fastf -mcpu=7450 -fPIC $BOOST" \ + ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \ + CXXFLAGS="-fomit-frame-pointer -fastf -mcpu=7450 -fPIC" \ --enable-standalone elif [ "$1" = "--perf" ]; then - ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBFLAGS" \ - CXXFLAGS="-g -pg $BOOST" + ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="-g -pg" fi rm AUTHORS ChangeLog @@ -36,7 +36,9 @@ class amount_t::bigint_t { } ~bigint_t() { DEBUG_PRINT("ledger.memory.dtors", "dtor amount_t::bigint_t"); +#if DEBUG_LEVEL >= BETA assert(ref == 0); +#endif mpz_clear(val); } }; @@ -1099,9 +1101,7 @@ void export_amount() .def(! self) .def(abs(self)) -#if 0 - .def(str(self)) -#endif + .def(self_ns::str(self)) .def("negate", &amount_t::negate) .def("parse", parse_1) @@ -58,8 +58,7 @@ void balance_t::write(std::ostream& out, if ((*i).second) sorted.push_back(&(*i).second); - std::stable_sort(sorted.begin(), sorted.end(), - compare_amount_commodities()); + std::stable_sort(sorted.begin(), sorted.end(), compare_amount_commodities()); for (amounts_deque::const_iterator i = sorted.begin(); i != sorted.end(); @@ -119,12 +119,12 @@ DEF_OPT_HANDLERS(); OPT_BEGIN(help, "h") { option_help(std::cout); - std::exit(0); + throw 0; } OPT_END(help); OPT_BEGIN(version, "v") { show_version(std::cout); - std::exit(0); + throw 0; } OPT_END(version); OPT_BEGIN(init, "i:") { diff --git a/configure.in b/configure.in index 3faa10fe..6fd1cbab 100644 --- a/configure.in +++ b/configure.in @@ -26,6 +26,28 @@ AC_CHECK_LIB([xmlparse], [XML_ParserCreate], AM_CONDITIONAL(READ_GNUCASH, false)], [-lxmltok]) +AM_PATH_PYTHON(2.2,, :) +AM_CONDITIONAL(HAVE_PYTHON, [test "$PYTHON" != :]) +AC_CACHE_CHECK( + [if boost_python is available], + [boost_python_cpplib_avail], + [boost_python_save_libs=$LIBS + LIBS="-lboost_python $LIBS" + AC_LANG_PUSH(C++) + AC_TRY_COMPILE( + [#include <boost/python.hpp> + using namespace boost::python; + class foo {}; + BOOST_PYTHON_MODULE(samp) { + class_< foo > ("foo") ; + }], + [return 0], + [boost_python_cpplib_avail=true], + [boost_python_cpplib_avail=false]) + AC_LANG_POP + LIBS=$boost_python_save_libs]) +AM_CONDITIONAL(HAVE_BOOST_PYTHON, test x$boost_python_cpplib_avail = xtrue) + # Check for options AC_ARG_ENABLE(debug, [ --enable-debug Turn on debugging], @@ -270,8 +270,9 @@ bool journal_t::remove_entry(entry_t * entry) for (transactions_list::const_iterator i = entry->transactions.begin(); i != entry->transactions.end(); - i++) + i++) { (*i)->account->remove_transaction(*i); + } return true; } @@ -447,13 +448,61 @@ using namespace ledger; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(journal_find_account_overloads, find_account, 1, 2) -#if 0 -template <typename T> -struct ptr_to_ref +unsigned int transactions_len(entry_t& entry) { - ptr_to_ref(T *) {} -}; -#endif + return entry.transactions.size(); +} + +transaction_t& transactions_getitem(entry_t& entry, int i) +{ + std::size_t len = entry.transactions.size(); + + if (abs(i) >= len) { + PyErr_SetString(PyExc_IndexError, "Index out of range"); + throw_error_already_set(); + } + + return *(entry.transactions[i < 0 ? len + i : i]); +} + +unsigned int entries_len(journal_t& journal) +{ + return journal.entries.size(); +} + +entry_t& entries_getitem(journal_t& journal, int i) +{ + std::size_t len = journal.entries.size(); + + if (abs(i) >= len) { + PyErr_SetString(PyExc_IndexError, "Index out of range"); + throw_error_already_set(); + } + + return *(journal.entries[i < 0 ? len + i : i]); +} + +unsigned int accounts_len(account_t& account) +{ + return account.accounts.size(); +} + +account_t& accounts_getitem(account_t& account, int index) +{ + std::size_t len = account.accounts.size(); + + if (abs(index) >= len) { + PyErr_SetString(PyExc_IndexError, "Index out of range"); + throw_error_already_set(); + } + + int x = 0; + for (accounts_map::iterator i = account.accounts.begin(); + i != account.accounts.end(); + i++) + if (x++ == index) + return *((*i).second); +} void export_journal() { @@ -480,7 +529,10 @@ void export_journal() .def_readwrite("state", &entry_t::state) .def_readwrite("code", &entry_t::code) .def_readwrite("payee", &entry_t::payee) - .def_readonly("transactions", &entry_t::transactions) + + .def("__len__", transactions_len) + .def("__getitem__", transactions_getitem, + return_value_policy<reference_existing_object>()) .def("add_transaction", &entry_t::add_transaction) .def("remove_transaction", &entry_t::remove_transaction) @@ -498,9 +550,7 @@ void export_journal() .def_readwrite("data", &account_t::data) .def_readonly("ident", &account_t::ident) -#if 0 - .def(str(self)) -#endif + .def(self_ns::str(self)) .def("fullname", &account_t::fullname) .def("add_account", &account_t::add_account) @@ -522,9 +572,11 @@ void export_journal() ; class_< journal_t > ("Journal") - .def_readwrite("master", &journal_t::master) - .def_readonly("entries", &journal_t::entries) - .def_readwrite("sources", &journal_t::sources) + .def_readonly("sources", &journal_t::sources) + + .def("__len__", entries_len) + .def("__getitem__", entries_getitem, + return_value_policy<reference_existing_object>()) .def("add_account", &journal_t::add_account) .def("remove_account", &journal_t::remove_account) @@ -537,7 +589,7 @@ void export_journal() .def("add_entry", &journal_t::add_entry) .def("remove_entry", &journal_t::remove_entry) .def("derive_entry", &journal_t::derive_entry, - return_value_policy<reference_existing_object>()) + return_value_policy<manage_new_object>()) .def("valid", &journal_t::valid) ; @@ -174,7 +174,7 @@ class journal_t journal_t() { master = new account_t(NULL, ""); - item_pool = NULL; + item_pool = item_pool_end = NULL; } ~journal_t(); @@ -22,7 +22,6 @@ using namespace ledger; #include <iostream> #include <fstream> #include <sstream> -#include <list> #include <memory> #include <algorithm> #include <iterator> @@ -643,14 +642,23 @@ int parse_and_report(int argc, char * argv[], char * envp[]) int main(int argc, char * argv[], char * envp[]) { + int status = 0; + initialize(); - int status = parse_and_report(argc, argv, envp); + try { + status = parse_and_report(argc, argv, envp); + } + catch (int& val) { +#if DEBUG_LEVEL >= BETA + shutdown(); +#endif + return val; + } #if DEBUG_LEVEL >= BETA shutdown(); #endif - return status; } @@ -2,6 +2,15 @@ using namespace boost::python; +#include "ledger.h" +#include "acconf.h" + +static struct cleanup_ledger_t { + ~cleanup_ledger_t() { + ledger::shutdown(); + } +} _cleanup_ledger; + void export_amount(); void export_balance(); void export_value(); @@ -26,4 +35,5 @@ BOOST_PYTHON_MODULE(ledger) { #ifdef READ_GNUCASH export_gnucash(); #endif + ledger::initialize(); } diff --git a/setup.py b/setup.py new file mode 100755 index 00000000..e447d35e --- /dev/null +++ b/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +from distutils.core import setup, Extension + +setup(name = "Ledger", + version = "2.0b", + description = "Ledger Accounting Tool", + author = "John Wiegley", + author_email = "johnw@newartisans.com", + url = "http://www.newartisans.com/johnw/", + ext_modules = [ + Extension("ledger", ["python.cc"], + define_macros = [('PYTHON_MODULE', None)], + libraries = ["ledger_bpy", "boost_python", "gmp", "pcre", + "xmlparse", "xmltok"])]) @@ -158,8 +158,6 @@ bool finalize_entry(entry_t * entry) x++) if (! ((*x)->flags & TRANSACTION_VIRTUAL) || ((*x)->flags & TRANSACTION_BALANCE)) { - DEBUG_PRINT("ledger.textual.finalize", - "item cost is " << ((*x)->cost ? *(*x)->cost : (*x)->amount)); amount_t * p = (*x)->cost ? (*x)->cost : &(*x)->amount; if (*p) balance += *p; @@ -220,10 +218,6 @@ bool finalize_entry(entry_t * entry) balance = 0U; } -#if 0 - DEBUG_PRINT("ledger.textual.finalize", "balance is " << balance); -#endif - return ! balance; } @@ -8,7 +8,7 @@ void sort_transactions::flush() std::stable_sort(transactions.begin(), transactions.end(), compare_items<transaction_t>(sort_order)); - for (transactions_list::iterator i = transactions.begin(); + for (std::deque<transaction_t *>::iterator i = transactions.begin(); i != transactions.end(); i++) (*handler)(*i); @@ -286,7 +286,7 @@ void interval_transactions::operator()(transaction_t * xact) void dow_transactions::flush() { for (int i = 0; i < 7; i++) { - for (transactions_list::iterator d = days_of_the_week[i].begin(); + for (std::deque<transaction_t *>::iterator d = days_of_the_week[i].begin(); d != days_of_the_week[i].end(); d++) subtotal_transactions::operator()(*d); @@ -177,8 +177,8 @@ class set_account_value : public item_handler<transaction_t> class sort_transactions : public item_handler<transaction_t> { - transactions_list transactions; - const value_expr_t * sort_order; + std::deque<transaction_t *> transactions; + const value_expr_t * sort_order; public: sort_transactions(item_handler<transaction_t> * handler, @@ -282,8 +282,8 @@ class changed_value_transactions : public item_handler<transaction_t> // This filter requires that calc_transactions be used at some point // later in the chain. - bool changed_values_only; - transaction_t * last_xact; + bool changed_values_only; + transaction_t * last_xact; entries_list entry_temps; transactions_list xact_temps; @@ -324,9 +324,9 @@ class subtotal_transactions : public item_handler<transaction_t> typedef std::pair<account_t *, balance_pair_t> balances_pair; protected: - std::time_t start; - std::time_t finish; - balances_map balances; + std::time_t start; + std::time_t finish; + balances_map balances; entries_list entry_temps; transactions_list xact_temps; @@ -382,7 +382,7 @@ class interval_transactions : public subtotal_transactions class dow_transactions : public subtotal_transactions { - transactions_list days_of_the_week[7]; + std::deque<transaction_t *> days_of_the_week[7]; public: dow_transactions(item_handler<transaction_t> * handler) |