summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2004-08-28 04:26:48 -0400
committerJohn Wiegley <johnw@newartisans.com>2004-08-28 04:26:48 -0400
commitb4304515ff0501da47cbcd4b47c770e2bb55a83d (patch)
tree03bfa7fb21d09cffa20ded425016ad8b0aef7e21
parent863485ad8ff29399fb9eafd1cfc863c5e8aa27f6 (diff)
downloadfork-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.am34
-rwxr-xr-xacprep19
-rw-r--r--amount.cc6
-rw-r--r--balance.cc3
-rw-r--r--config.cc4
-rw-r--r--configure.in22
-rw-r--r--journal.cc82
-rw-r--r--ledger.h2
-rw-r--r--main.cc14
-rw-r--r--python.cc10
-rwxr-xr-xsetup.py15
-rw-r--r--textual.cc6
-rw-r--r--walk.cc4
-rw-r--r--walk.h16
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
diff --git a/acprep b/acprep
index 63fc2180..174d4767 100755
--- a/acprep
+++ b/acprep
@@ -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
diff --git a/amount.cc b/amount.cc
index 0af00602..4d39f29a 100644
--- a/amount.cc
+++ b/amount.cc
@@ -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)
diff --git a/balance.cc b/balance.cc
index b09f1425..f6392536 100644
--- a/balance.cc
+++ b/balance.cc
@@ -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();
diff --git a/config.cc b/config.cc
index 0b7e22c0..3d682395 100644
--- a/config.cc
+++ b/config.cc
@@ -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],
diff --git a/journal.cc b/journal.cc
index 3d2f60bd..5922cd34 100644
--- a/journal.cc
+++ b/journal.cc
@@ -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)
;
diff --git a/ledger.h b/ledger.h
index 3503e35a..8f56e950 100644
--- a/ledger.h
+++ b/ledger.h
@@ -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();
diff --git a/main.cc b/main.cc
index 3d069234..7a0b8141 100644
--- a/main.cc
+++ b/main.cc
@@ -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;
}
diff --git a/python.cc b/python.cc
index 9f023447..36d80c7c 100644
--- a/python.cc
+++ b/python.cc
@@ -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"])])
diff --git a/textual.cc b/textual.cc
index 074e1f00..0e8bdee1 100644
--- a/textual.cc
+++ b/textual.cc
@@ -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;
}
diff --git a/walk.cc b/walk.cc
index ffcaede0..0fadd1e6 100644
--- a/walk.cc
+++ b/walk.cc
@@ -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);
diff --git a/walk.h b/walk.h
index 6fa86272..7a8dc060 100644
--- a/walk.h
+++ b/walk.h
@@ -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)