Cleared out all warnings; started work on getting Python up again.

This commit is contained in:
John Wiegley 2007-04-15 02:55:16 +00:00
parent 691c29a696
commit a087e6ea97
35 changed files with 1123 additions and 1004 deletions

View file

@ -1,6 +1,9 @@
lib_LTLIBRARIES = libledger.la
if HAVE_BOOST_PYTHON
lib_LTLIBRARIES += libpyledger.la
endif
libledger_la_CXXFLAGS =
libledger_la_CXXFLAGS = $(WARNFLAGS)
libledger_la_SOURCES = \
amount.cc \
quotes.cc \
@ -30,6 +33,7 @@ libledger_la_SOURCES = \
derive.cc \
emacs.cc \
reconcile.cc
if HAVE_EXPAT
libledger_la_CXXFLAGS += -DHAVE_EXPAT=1
libledger_la_SOURCES += gnucash.cc
@ -42,16 +46,29 @@ if HAVE_LIBOFX
libledger_la_CXXFLAGS += -DHAVE_LIBOFX=1
libledger_la_SOURCES += ofx.cc
endif
if HAVE_BOOST_PYTHON
libledger_la_CXXFLAGS += -DUSE_BOOST_PYTHON=1
libledger_la_SOURCES += py_eval.cc
endif
if DEBUG
libledger_la_CXXFLAGS += -DDEBUG_LEVEL=4
libledger_la_SOURCES += debug.cc
endif
if HAVE_BOOST_PYTHON
libledger_la_CXXFLAGS += -DUSE_BOOST_PYTHON=1
endif
libledger_la_LDFLAGS = -release 3.0
libpyledger_la_CXXFLAGS = -DUSE_BOOST_PYTHON=1
libpyledger_la_SOURCES = \
py_eval.cc \
py_amount.cc
if DEBUG
libpyledger_la_CXXFLAGS += -DDEBUG_LEVEL=4
endif
libpyledger_la_LDFLAGS = -release 3.0
pkginclude_HEADERS = \
acconf.h \
amount.h \
@ -106,6 +123,7 @@ ledger_CXXFLAGS += -DHAVE_LIBOFX=1
endif
if HAVE_BOOST_PYTHON
ledger_CXXFLAGS += -DUSE_BOOST_PYTHON=1
ledger_LDADD += libpyledger.la
endif
if DEBUG
ledger_CXXFLAGS += -DDEBUG_LEVEL=4
@ -125,7 +143,7 @@ if HAVE_BOOST_PYTHON
noinst_PROGRAMS = ledger.so
ledger.so: pyledger.cc libledger.la
ledger.so: pyledger.cc libledger.la libpyledger.la
CFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS) -L. -L.libs" \
python setup.py build --build-lib=.
@ -142,12 +160,13 @@ TESTS = UnitTests
check_PROGRAMS = $(TESTS)
UnitTests_SOURCES = tests/UnitTests.cc \
\
tests/corelib/numerics/BasicAmountTest.cc
UnitTests_LDADD = $(lib_LTLIBRARIES) -lcppunit
UnitTests_LDFLAGS = $(LIBADD_DL)
UnitTests_CXXFLAGS = -Itests
UnitTests_CXXFLAGS = -I. -Itests
if HAVE_EXPAT
UnitTests_CXXFLAGS += -DHAVE_EXPAT=1
endif
@ -165,6 +184,10 @@ endif
all: check
check-syntax:
g++ -I. -Itests $(CPPFLAGS) $(UnitTests_CXXFLAGS) \
-o /dev/null -S $(CHK_SOURCES)
all-clean: maintainer-clean
rm -fr *~ .*~ .\#* *.html *.info *.pdf *.a *.so *.o *.lo *.la \
*.elc *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr \

36
acprep
View file

@ -23,7 +23,7 @@ INCDIRS="$INCDIRS -I/usr/include/httpd/xml"
INCDIRS="$INCDIRS -I/Library/Frameworks/Python.framework/Versions/2.5/include/python2.5"
LIBDIRS="-L/usr/local/lib"
LIBDIRS="$LIBDIRS -L/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5"
LIBDIRS="$LIBDIRS -L/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/config"
SYSTEM=`uname -s`
if [ $SYSTEM = Linux ]; then
@ -36,6 +36,12 @@ else
CXXFLAGS=""
fi
WARNFLAGS="-Wall -Wextra -Wfloat-equal -Wno-endif-labels -Wshadow"
WARNFLAGS="$WARNFLAGS -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion"
WARNFLAGS="$WARNFLAGS -Wconversion -Wshorten-64-to-32 -Wsign-compare"
WARNFLAGS="$WARNFLAGS -Wmissing-field-initializers -Wmissing-noreturn"
WARNFLAGS="$WARNFLAGS -pedantic-errors"
# Building the command-line tool as a shared library is a luxury,
# since there are no clients except a GUI tool which might use it (and
# that is built again anyway by Xcode).
@ -54,34 +60,34 @@ HERE="$PWD"
if [ "$1" = "--debug" ]; then
shift 1
"$HERE/configure" --srcdir="$HERE" \
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="-g" $SWITCHES \
--enable-debug "$@"
elif [ "$1" = "--python-debug" ]; then
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="$CXXFLAGS -ggdb3" \
WARNFLAGS="$WARNFLAGS" $SWITCHES --enable-debug "$@"
elif [ "$1" = "--python-debug" -o "$1" = "--debug-python" ]; then
shift 1
"$HERE/configure" --srcdir="$HERE" \
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="-g" $SWITCHES \
--enable-debug --enable-python "$@"
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="$CXXFLAGS -ggdb3" \
WARNFLAGS="$WARNFLAGS" $SWITCHES --enable-debug --enable-python "$@"
elif [ "$1" = "--opt" ]; then
shift 1
"$HERE/configure" --srcdir="$HERE" \
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450 -fPIC" "$@" $SWITCHES
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" WARNFLAGS="$WARNFLAGS" \
CXXFLAGS="$CXXFLAGS -fomit-frame-pointer -O3 -fPIC" "$@" $SWITCHES
elif [ "$1" = "--flat-opt" ]; then
shift 1
"$HERE/configure" --srcdir="$HERE" \
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450" "$@" $SWITCHES
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" WARNFLAGS="$WARNFLAGS" \
CXXFLAGS="$CXXFLAGS -fomit-frame-pointer -O3" "$@" $SWITCHES
elif [ "$1" = "--safe-opt" ]; then
shift 1
"$HERE/configure" --srcdir="$HERE" \
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450 -fPIC -DDEBUG_LEVEL=1" "$@" \
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" WARNFLAGS="$WARNFLAGS" \
CXXFLAGS="$CXXFLAGS -fomit-frame-pointer -O3 -fPIC -DDEBUG_LEVEL=1" "$@" \
$SWITCHES
elif [ "$1" = "--perf" ]; then
shift 1
"$HERE/configure" --srcdir="$HERE" \
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="-g -pg" "$@" \
$SWITCHES
"$HERE/configure" --srcdir="$HERE" WARNFLAGS="$WARNFLAGS" \
CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
CXXFLAGS="$CXXFLAGS -ggdb3 -pg" "$@" $SWITCHES
fi
rm AUTHORS COPYING

340
amount.cc
View file

@ -173,10 +173,10 @@ static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec)
mpz_tdiv_q(out, out, divisor);
}
amount_t::amount_t(const bool value)
amount_t::amount_t(const bool val)
{
TRACE_CTOR("amount_t(const bool)");
if (value) {
if (val) {
quantity = &true_value;
quantity->ref++;
} else {
@ -185,24 +185,24 @@ amount_t::amount_t(const bool value)
commodity_ = NULL;
}
amount_t::amount_t(const long value)
amount_t::amount_t(const long val)
{
TRACE_CTOR("amount_t(const long)");
if (value != 0) {
if (val != 0) {
quantity = new bigint_t;
mpz_set_si(MPZ(quantity), value);
mpz_set_si(MPZ(quantity), val);
} else {
quantity = NULL;
}
commodity_ = NULL;
}
amount_t::amount_t(const unsigned long value)
amount_t::amount_t(const unsigned long val)
{
TRACE_CTOR("amount_t(const unsigned long)");
if (value != 0) {
if (val != 0) {
quantity = new bigint_t;
mpz_set_ui(MPZ(quantity), value);
mpz_set_ui(MPZ(quantity), val);
} else {
quantity = NULL;
}
@ -210,10 +210,10 @@ amount_t::amount_t(const unsigned long value)
}
namespace {
unsigned char convert_double(mpz_t dest, double value)
unsigned char convert_double(mpz_t dest, double val)
{
mpf_t temp;
mpf_init_set_d(temp, value);
mpf_init_set_d(temp, val);
mp_exp_t exp;
char * buf = mpf_get_str(NULL, &exp, 10, 10, temp);
@ -231,15 +231,11 @@ namespace {
}
}
amount_t::amount_t(const double value)
amount_t::amount_t(const double val)
{
TRACE_CTOR("amount_t(const double)");
if (value != 0.0) {
quantity = new bigint_t;
quantity->prec = convert_double(MPZ(quantity), value);
} else {
quantity = NULL;
}
quantity = new bigint_t;
quantity->prec = convert_double(MPZ(quantity), val);
commodity_ = NULL;
}
@ -295,16 +291,16 @@ void amount_t::_copy(const amount_t& amt)
commodity_ = amt.commodity_;
}
amount_t& amount_t::operator=(const std::string& value)
amount_t& amount_t::operator=(const std::string& val)
{
std::istringstream str(value);
std::istringstream str(val);
parse(str);
return *this;
}
amount_t& amount_t::operator=(const char * value)
amount_t& amount_t::operator=(const char * val)
{
std::string valstr(value);
std::string valstr(val);
std::istringstream str(valstr);
parse(str);
return *this;
@ -322,9 +318,9 @@ amount_t& amount_t::operator=(const amount_t& amt)
return *this;
}
amount_t& amount_t::operator=(const bool value)
amount_t& amount_t::operator=(const bool val)
{
if (! value) {
if (! val) {
if (quantity)
_clear();
} else {
@ -337,42 +333,37 @@ amount_t& amount_t::operator=(const bool value)
return *this;
}
amount_t& amount_t::operator=(const long value)
amount_t& amount_t::operator=(const long val)
{
if (value == 0) {
if (val == 0) {
if (quantity)
_clear();
} else {
commodity_ = NULL;
_init();
mpz_set_si(MPZ(quantity), value);
mpz_set_si(MPZ(quantity), val);
}
return *this;
}
amount_t& amount_t::operator=(const unsigned long value)
amount_t& amount_t::operator=(const unsigned long val)
{
if (value == 0) {
if (val == 0) {
if (quantity)
_clear();
} else {
commodity_ = NULL;
_init();
mpz_set_ui(MPZ(quantity), value);
mpz_set_ui(MPZ(quantity), val);
}
return *this;
}
amount_t& amount_t::operator=(const double value)
amount_t& amount_t::operator=(const double val)
{
if (value == 0.0) {
if (quantity)
_clear();
} else {
commodity_ = NULL;
_init();
quantity->prec = convert_double(MPZ(quantity), value);
}
commodity_ = NULL;
_init();
quantity->prec = convert_double(MPZ(quantity), val);
return *this;
}
@ -436,9 +427,9 @@ amount_t& amount_t::operator+=(const amount_t& amt)
mpz_add(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
}
else {
amount_t temp = amt;
temp._resize(quantity->prec);
mpz_add(MPZ(quantity), MPZ(quantity), MPZ(temp.quantity));
amount_t t = amt;
t._resize(quantity->prec);
mpz_add(MPZ(quantity), MPZ(quantity), MPZ(t.quantity));
}
return *this;
@ -472,9 +463,9 @@ amount_t& amount_t::operator-=(const amount_t& amt)
mpz_sub(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
}
else {
amount_t temp = amt;
temp._resize(quantity->prec);
mpz_sub(MPZ(quantity), MPZ(quantity), MPZ(temp.quantity));
amount_t t = amt;
t._resize(quantity->prec);
mpz_sub(MPZ(quantity), MPZ(quantity), MPZ(t.quantity));
}
return *this;
@ -563,14 +554,14 @@ int amount_t::compare(const amount_t& amt) const
return mpz_cmp(MPZ(quantity), MPZ(amt.quantity));
}
else if (quantity->prec < amt.quantity->prec) {
amount_t temp = *this;
temp._resize(amt.quantity->prec);
return mpz_cmp(MPZ(temp.quantity), MPZ(amt.quantity));
amount_t t = *this;
t._resize(amt.quantity->prec);
return mpz_cmp(MPZ(t.quantity), MPZ(amt.quantity));
}
else {
amount_t temp = amt;
temp._resize(quantity->prec);
return mpz_cmp(MPZ(quantity), MPZ(temp.quantity));
amount_t t = amt;
t._resize(quantity->prec);
return mpz_cmp(MPZ(quantity), MPZ(t.quantity));
}
}
@ -663,43 +654,43 @@ amount_t amount_t::value(const datetime_t& moment) const
amount_t amount_t::round(unsigned int prec) const
{
amount_t temp = *this;
amount_t t = *this;
if (! quantity || quantity->prec <= prec) {
if (quantity && quantity->flags & BIGINT_KEEP_PREC) {
temp._dup();
temp.quantity->flags &= ~BIGINT_KEEP_PREC;
t._dup();
t.quantity->flags &= ~BIGINT_KEEP_PREC;
}
return temp;
return t;
}
temp._dup();
t._dup();
mpz_round(MPZ(temp.quantity), MPZ(temp.quantity), temp.quantity->prec, prec);
mpz_round(MPZ(t.quantity), MPZ(t.quantity), t.quantity->prec, prec);
temp.quantity->prec = prec;
temp.quantity->flags &= ~BIGINT_KEEP_PREC;
t.quantity->prec = prec;
t.quantity->flags &= ~BIGINT_KEEP_PREC;
return temp;
return t;
}
amount_t amount_t::unround() const
{
if (! quantity) {
amount_t temp(0L);
assert(temp.quantity);
temp.quantity->flags |= BIGINT_KEEP_PREC;
return temp;
amount_t t(0L);
assert(t.quantity);
t.quantity->flags |= BIGINT_KEEP_PREC;
return t;
}
else if (quantity->flags & BIGINT_KEEP_PREC) {
return *this;
}
amount_t temp = *this;
temp._dup();
temp.quantity->flags |= BIGINT_KEEP_PREC;
amount_t t = *this;
t._dup();
t.quantity->flags |= BIGINT_KEEP_PREC;
return temp;
return t;
}
void amount_t::print_quantity(std::ostream& out) const
@ -1117,8 +1108,8 @@ void amount_t::parse(std::istream& in, unsigned char flags)
std::string symbol;
std::string quant;
amount_t price;
datetime_t date;
amount_t tprice;
datetime_t tdate;
std::string tag;
unsigned int comm_flags = COMMODITY_STYLE_DEFAULTS;
bool negative = false;
@ -1144,7 +1135,7 @@ void amount_t::parse(std::istream& in, unsigned char flags)
comm_flags |= COMMODITY_STYLE_SUFFIXED;
if (! in.eof() && ((n = in.peek()) != '\n'))
parse_annotations(in, price, date, tag);
parse_annotations(in, tprice, tdate, tag);
}
} else {
parse_commodity(in, symbol);
@ -1156,7 +1147,7 @@ void amount_t::parse(std::istream& in, unsigned char flags)
parse_quantity(in, quant);
if (! quant.empty() && ! in.eof() && ((n = in.peek()) != '\n'))
parse_annotations(in, price, date, tag);
parse_annotations(in, tprice, tdate, tag);
}
}
@ -1180,9 +1171,9 @@ void amount_t::parse(std::istream& in, unsigned char flags)
}
assert(commodity_);
if (! price.realzero() || date || ! tag.empty())
if (! tprice.realzero() || tdate || ! tag.empty())
commodity_ =
annotated_commodity_t::find_or_create(*commodity_, price, date, tag);
annotated_commodity_t::find_or_create(*commodity_, tprice, tdate, tag);
}
// Determine the precision of the amount, based on the usage of
@ -1456,8 +1447,8 @@ bool amount_t::valid() const
return true;
}
void amount_t::annotate_commodity(const amount_t& price,
const datetime_t& date,
void amount_t::annotate_commodity(const amount_t& tprice,
const datetime_t& tdate,
const std::string& tag)
{
const commodity_t * this_base;
@ -1473,14 +1464,14 @@ void amount_t::annotate_commodity(const amount_t& price,
DEBUG_PRINT("amounts.commodities", "Annotating commodity for amount "
<< *this << std::endl
<< " price " << price << " "
<< " date " << date << " "
<< " price " << tprice << " "
<< " date " << tdate << " "
<< " tag " << tag);
commodity_t * ann_comm =
annotated_commodity_t::find_or_create
(*this_base, ! price && this_ann ? this_ann->price : price,
! date && this_ann ? this_ann->date : date,
(*this_base, ! tprice && this_ann ? this_ann->price : tprice,
! tdate && this_ann ? this_ann->date : tdate,
tag.empty() && this_ann ? this_ann->tag : tag);
if (ann_comm)
set_commodity(*ann_comm);
@ -1521,22 +1512,21 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
}
assert(new_comm);
amount_t temp(*this);
temp.set_commodity(*new_comm);
amount_t t(*this);
t.set_commodity(*new_comm);
DEBUG_PRINT("amounts.commodities", " Reduced amount is " << t);
DEBUG_PRINT("amounts.commodities", " Reduced amount is " << temp);
return temp;
return t;
}
amount_t amount_t::price() const
{
if (commodity_ && commodity_->annotated) {
amount_t temp(((annotated_commodity_t *)commodity_)->price);
temp *= *this;
amount_t t(((annotated_commodity_t *)commodity_)->price);
t *= *this;
DEBUG_PRINT("amounts.commodities",
"Returning price of " << *this << " = " << temp);
return temp;
"Returning price of " << *this << " = " << t);
return t;
}
return *this;
}
@ -1920,177 +1910,3 @@ bool compare_amount_commodities::operator()(const amount_t * left,
}
} // namespace ledger
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
#include <Python.h>
using namespace boost::python;
using namespace ledger;
int py_amount_quantity(amount_t& amount)
{
std::ostringstream quant;
amount.print_quantity(quant);
return std::atol(quant.str().c_str());
}
void py_parse_1(amount_t& amount, const std::string& str,
unsigned char flags) {
amount.parse(str, flags);
}
void py_parse_2(amount_t& amount, const std::string& str) {
amount.parse(str);
}
struct commodity_updater_wrap : public commodity_base_t::updater_t
{
PyObject * self;
commodity_updater_wrap(PyObject * self_) : self(self_) {}
virtual void operator()(commodity_base_t& commodity,
const datetime_t& moment,
const datetime_t& date,
const datetime_t& last,
amount_t& price) {
call_method<void>(self, "__call__", commodity, moment, date, last, price);
}
};
commodity_t * py_find_commodity(const std::string& symbol)
{
return commodity_t::find(symbol);
}
#define EXC_TRANSLATOR(type) \
void exc_translate_ ## type(const type& err) { \
PyErr_SetString(PyExc_RuntimeError, err.what()); \
}
EXC_TRANSLATOR(amount_error)
void export_amount()
{
scope().attr("AMOUNT_PARSE_NO_MIGRATE") = AMOUNT_PARSE_NO_MIGRATE;
scope().attr("AMOUNT_PARSE_NO_REDUCE") = AMOUNT_PARSE_NO_REDUCE;
class_< amount_t > ("Amount")
.def(init<amount_t>())
.def(init<std::string>())
.def(init<char *>())
.def(init<bool>())
.def(init<long>())
.def(init<unsigned long>())
.def(init<double>())
.def(self += self)
.def(self += long())
.def(self + self)
.def(self + long())
.def(self -= self)
.def(self -= long())
.def(self - self)
.def(self - long())
.def(self *= self)
.def(self *= long())
.def(self * self)
.def(self * long())
.def(self /= self)
.def(self /= long())
.def(self / self)
.def(self / long())
.def(- self)
.def(self < self)
.def(self < long())
.def(self <= self)
.def(self <= long())
.def(self > self)
.def(self > long())
.def(self >= self)
.def(self >= long())
.def(self == self)
.def(self == long())
.def(self != self)
.def(self != long())
.def(! self)
.def(self_ns::int_(self))
.def(self_ns::float_(self))
.def(self_ns::str(self))
.def(abs(self))
.add_property("commodity",
make_function(&amount_t::commodity,
return_value_policy<reference_existing_object>()),
make_function(&amount_t::set_commodity,
with_custodian_and_ward<1, 2>()))
.def("strip_annotations", &amount_t::strip_annotations)
.def("negate", &amount_t::negate)
.def("negated", &amount_t::negated)
.def("parse", py_parse_1)
.def("parse", py_parse_2)
.def("reduce", &amount_t::reduce)
.def("valid", &amount_t::valid)
;
class_< commodity_base_t::updater_t, commodity_updater_wrap,
boost::noncopyable >
("Updater")
;
scope().attr("COMMODITY_STYLE_DEFAULTS") = COMMODITY_STYLE_DEFAULTS;
scope().attr("COMMODITY_STYLE_SUFFIXED") = COMMODITY_STYLE_SUFFIXED;
scope().attr("COMMODITY_STYLE_SEPARATED") = COMMODITY_STYLE_SEPARATED;
scope().attr("COMMODITY_STYLE_EUROPEAN") = COMMODITY_STYLE_EUROPEAN;
scope().attr("COMMODITY_STYLE_THOUSANDS") = COMMODITY_STYLE_THOUSANDS;
scope().attr("COMMODITY_STYLE_NOMARKET") = COMMODITY_STYLE_NOMARKET;
scope().attr("COMMODITY_STYLE_BUILTIN") = COMMODITY_STYLE_BUILTIN;
class_< commodity_t > ("Commodity")
.add_property("symbol", &commodity_t::symbol)
.add_property("name", &commodity_t::name, &commodity_t::set_name)
.add_property("note", &commodity_t::note, &commodity_t::set_note)
.add_property("precision", &commodity_t::precision,
&commodity_t::set_precision)
.add_property("flags", &commodity_t::flags, &commodity_t::set_flags)
.add_property("add_flags", &commodity_t::add_flags)
.add_property("drop_flags", &commodity_t::drop_flags)
.add_property("updater", &commodity_t::updater)
.add_property("smaller",
make_getter(&commodity_t::smaller,
return_value_policy<reference_existing_object>()),
make_setter(&commodity_t::smaller,
return_value_policy<reference_existing_object>()))
.add_property("larger",
make_getter(&commodity_t::larger,
return_value_policy<reference_existing_object>()),
make_setter(&commodity_t::larger,
return_value_policy<reference_existing_object>()))
.def(self_ns::str(self))
.def("find", py_find_commodity,
return_value_policy<reference_existing_object>())
.staticmethod("find")
.def("add_price", &commodity_t::add_price)
.def("remove_price", &commodity_t::remove_price)
.def("value", &commodity_t::value)
.def("valid", &commodity_t::valid)
;
#define EXC_TRANSLATE(type) \
register_exception_translator<type>(&exc_translate_ ## type);
EXC_TRANSLATE(amount_error);
}
#endif // USE_BOOST_PYTHON

122
amount.h
View file

@ -54,18 +54,18 @@ class amount_t
else
commodity_ = NULL;
}
amount_t(const std::string& value) : quantity(NULL) {
amount_t(const std::string& val) : quantity(NULL) {
TRACE_CTOR("amount_t(const std::string&)");
parse(value);
parse(val);
}
amount_t(const char * value) : quantity(NULL) {
amount_t(const char * val) : quantity(NULL) {
TRACE_CTOR("amount_t(const char *)");
parse(value);
parse(val);
}
amount_t(const bool value);
amount_t(const long value);
amount_t(const unsigned long value);
amount_t(const double value);
amount_t(const bool val);
amount_t(const long val);
amount_t(const unsigned long val);
amount_t(const double val);
// destructor
~amount_t() {
@ -92,19 +92,19 @@ class amount_t
datetime_t date() const;
bool null() const {
return ! quantity && ! commodity_;
return ! quantity && ! has_commodity();
}
std::string quantity_string() const;
// assignment operator
amount_t& operator=(const amount_t& amt);
amount_t& operator=(const std::string& value);
amount_t& operator=(const char * value);
amount_t& operator=(const bool value);
amount_t& operator=(const long value);
amount_t& operator=(const unsigned long value);
amount_t& operator=(const double value);
amount_t& operator=(const std::string& val);
amount_t& operator=(const char * val);
amount_t& operator=(const bool val);
amount_t& operator=(const long val);
amount_t& operator=(const unsigned long val);
amount_t& operator=(const double val);
// general methods
amount_t round(unsigned int prec) const;
@ -118,20 +118,20 @@ class amount_t
amount_t& operator/=(const amount_t& amt);
template <typename T>
amount_t& operator+=(T value) {
return *this += amount_t(value);
amount_t& operator+=(T val) {
return *this += amount_t(val);
}
template <typename T>
amount_t& operator-=(T value) {
return *this -= amount_t(value);
amount_t& operator-=(T val) {
return *this -= amount_t(val);
}
template <typename T>
amount_t& operator*=(T value) {
return *this *= amount_t(value);
amount_t& operator*=(T val) {
return *this *= amount_t(val);
}
template <typename T>
amount_t& operator/=(T value) {
return *this /= amount_t(value);
amount_t& operator/=(T val) {
return *this /= amount_t(val);
}
// simple arithmetic
@ -157,27 +157,27 @@ class amount_t
}
template <typename T>
amount_t operator+(T value) const {
amount_t operator+(T val) const {
amount_t temp = *this;
temp += value;
temp += val;
return temp;
}
template <typename T>
amount_t operator-(T value) const {
amount_t operator-(T val) const {
amount_t temp = *this;
temp -= value;
temp -= val;
return temp;
}
template <typename T>
amount_t operator*(T value) const {
amount_t operator*(T val) const {
amount_t temp = *this;
temp *= value;
temp *= val;
return temp;
}
template <typename T>
amount_t operator/(T value) const {
amount_t operator/(T val) const {
amount_t temp = *this;
temp /= value;
temp /= val;
return temp;
}
@ -310,6 +310,64 @@ inline amount_t abs(const amount_t& amt) {
return amt < 0 ? amt.negated() : amt;
}
template <typename T>
inline amount_t operator+(const T val, const amount_t& amt) {
amount_t temp(val);
temp += amt;
return temp;
}
template <typename T>
inline amount_t operator-(const T val, const amount_t& amt) {
amount_t temp(val);
temp -= amt;
return temp;
}
template <typename T>
inline amount_t operator*(const T val, const amount_t& amt) {
amount_t temp(val);
temp *= amt;
return temp;
}
template <typename T>
inline amount_t operator/(const T val, const amount_t& amt) {
amount_t temp(val);
temp /= amt;
return temp;
}
template <typename T>
inline bool operator<(const T val, const amount_t& amt) {
return amount_t(val) < amt;
}
template <typename T>
inline bool operator<=(const T val, const amount_t& amt) {
return amount_t(val) <= amt;
}
template <typename T>
inline bool operator>(const T val, const amount_t& amt) {
return amount_t(val) > amt;
}
template <typename T>
inline bool operator>=(const T val, const amount_t& amt) {
return amount_t(val) >= amt;
}
template <typename T>
inline bool operator==(const T val, const amount_t& amt) {
return amount_t(val) == amt;
}
template <typename T>
inline bool operator!=(const T val, const amount_t& amt) {
return amount_t(val) != amt;
}
inline std::ostream& operator<<(std::ostream& out, const amount_t& amt) {
amt.print(out);
return out;
@ -602,7 +660,7 @@ void parse_conversion(const std::string& larger_str,
class amount_error : public error {
public:
amount_error(const std::string& reason) throw() : error(reason) {}
amount_error(const std::string& _reason) throw() : error(_reason) {}
virtual ~amount_error() throw() {}
};

View file

@ -64,10 +64,10 @@ datetime_t balance_t::date() const
for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end();
i++) {
datetime_t date = (*i).second.date();
if (! temp && date)
temp = date;
else if (temp != date)
datetime_t tdate = (*i).second.date();
if (! temp && tdate)
temp = tdate;
else if (temp != tdate)
return datetime_t();
}
@ -320,6 +320,7 @@ balance_t::operator amount_t() const
} // namespace ledger
#if 0
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
@ -528,3 +529,4 @@ void export_balance()
}
#endif // USE_BOOST_PYTHON
#endif

View file

@ -39,9 +39,9 @@ class balance_t
amounts.insert(amounts_pair(&amt.commodity(), amt));
}
template <typename T>
balance_t(T value) {
balance_t(T val) {
TRACE_CTOR("balance_t(T)");
amount_t amt(value);
amount_t amt(val);
if (! amt.realzero())
amounts.insert(amounts_pair(&amt.commodity(), amt));
}
@ -63,9 +63,9 @@ class balance_t
return *this;
}
template <typename T>
balance_t& operator=(T value) {
balance_t& operator=(T val) {
amounts.clear();
*this += value;
*this += val;
return *this;
}
@ -517,7 +517,7 @@ class balance_pair_t
TRACE_CTOR("balance_pair_t(const amount_t&)");
}
template <typename T>
balance_pair_t(T value) : quantity(value), cost(NULL) {
balance_pair_t(T val) : quantity(val), cost(NULL) {
TRACE_CTOR("balance_pair_t(T)");
}
@ -557,12 +557,12 @@ class balance_pair_t
return *this;
}
template <typename T>
balance_pair_t& operator=(T value) {
balance_pair_t& operator=(T val) {
if (cost) {
delete cost;
cost = NULL;
}
quantity = value;
quantity = val;
return *this;
}
@ -902,13 +902,13 @@ class balance_pair_t
quantity.write(out, first_width, latter_width);
}
balance_pair_t& add(const amount_t& amount,
balance_pair_t& add(const amount_t& amt,
const amount_t * a_cost = NULL) {
if (a_cost && ! cost)
cost = new balance_t(quantity);
quantity += amount;
quantity += amt;
if (cost)
*cost += a_cost ? *a_cost : amount;
*cost += a_cost ? *a_cost : amt;
return *this;
}
@ -941,7 +941,7 @@ class balance_pair_t
};
inline balance_pair_t abs(const balance_pair_t& bal_pair) {
balance_pair_t temp;
balance_pair_t temp(bal_pair);
temp.abs();
return temp;
}

View file

@ -117,9 +117,9 @@ void datetime_t::parse(std::istream& in)
istream_pos_type beg_pos = in.tellg();
int hour = 0;
int min = 0;
int sec = 0;
int thour = 0;
int tmin = 0;
int tsec = 0;
// Now look for the (optional) time specifier. If no time is given,
// we use midnight of the given day.
@ -131,8 +131,8 @@ void datetime_t::parse(std::istream& in)
if (buf[0] == '\0')
goto abort;
hour = std::atoi(buf);
if (hour > 23)
thour = std::atoi(buf);
if (thour > 23)
goto abort;
if (in.peek() == ':') {
@ -141,8 +141,8 @@ void datetime_t::parse(std::istream& in)
if (buf[0] == '\0')
goto abort;
min = std::atoi(buf);
if (min > 59)
tmin = std::atoi(buf);
if (tmin > 59)
goto abort;
if (in.peek() == ':') {
@ -151,24 +151,24 @@ void datetime_t::parse(std::istream& in)
if (buf[0] == '\0')
goto abort;
sec = std::atoi(buf);
if (sec > 59)
tsec = std::atoi(buf);
if (tsec > 59)
goto abort;
}
}
c = peek_next_nonws(in);
if (c == 'a' || c == 'p' || c == 'A' || c == 'P') {
if (hour > 12)
if (thour > 12)
goto abort;
in.get(c);
if (c == 'p' || c == 'P') {
if (hour != 12)
hour += 12;
if (thour != 12)
thour += 12;
} else {
if (hour == 12)
hour = 0;
if (thour == 12)
thour = 0;
}
c = in.peek();
@ -178,9 +178,9 @@ void datetime_t::parse(std::istream& in)
struct std::tm * desc = std::localtime(&when);
desc->tm_hour = hour;
desc->tm_min = min;
desc->tm_sec = sec;
desc->tm_hour = thour;
desc->tm_min = tmin;
desc->tm_sec = tsec;
desc->tm_isdst = -1;
when = std::mktime(desc);
@ -453,6 +453,7 @@ void interval_t::parse(std::istream& in)
}
}
#if 0
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
@ -571,3 +572,4 @@ void export_datetime()
}
#endif // USE_BOOST_PYTHON
#endif

View file

@ -8,7 +8,7 @@
class date_error : public error {
public:
date_error(const std::string& reason) throw() : error(reason) {}
date_error(const std::string& _reason) throw() : error(_reason) {}
virtual ~date_error() throw() {}
};
@ -71,12 +71,11 @@ class date_t
virtual date_t& operator+=(const long days) {
// jww (2006-03-26): This is not accurate enough when DST is in effect!
assert(0);
when += days * 86400;
return *this;
}
virtual date_t& operator-=(const long days) {
assert(0);
// jww (2006-03-26): This is not accurate enough when DST is in effect!
when -= days * 86400;
return *this;
}
@ -167,7 +166,7 @@ inline std::istream& operator>>(std::istream& in, date_t& moment) {
class datetime_error : public error {
public:
datetime_error(const std::string& reason) throw() : error(reason) {}
datetime_error(const std::string& _reason) throw() : error(_reason) {}
virtual ~datetime_error() throw() {}
};
@ -176,7 +175,7 @@ class datetime_t : public date_t
public:
static datetime_t now;
datetime_t() : date_t() {}
datetime_t() : date_t(now.when) {}
datetime_t(const datetime_t& _when) : date_t(_when.when) {}
datetime_t(const date_t& _when) : date_t(_when) {}

View file

@ -102,6 +102,7 @@ bool _debug_active(const char * const cls);
#include "trace.h"
#if 0
void * operator new(std::size_t) throw (std::bad_alloc);
void * operator new[](std::size_t) throw (std::bad_alloc);
void operator delete(void*) throw();
@ -110,6 +111,7 @@ void * operator new(std::size_t, const std::nothrow_t&) throw();
void * operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw();
#endif
#else // DEBUG_LEVEL

20
error.h
View file

@ -27,8 +27,8 @@ class file_context : public error_context
unsigned long line;
public:
file_context(const std::string& _file, unsigned long _line,
const std::string& desc = "") throw()
: error_context(desc), file(_file), line(_line) {}
const std::string& _desc = "") throw()
: error_context(_desc), file(_file), line(_line) {}
virtual ~file_context() throw() {}
virtual void describe(std::ostream& out) const throw() {
@ -45,8 +45,8 @@ class line_context : public error_context {
long pos;
line_context(const std::string& _line, long _pos,
const std::string& desc = "") throw()
: error_context(desc), line(_line), pos(_pos) {}
const std::string& _desc = "") throw()
: error_context(_desc), line(_line), pos(_pos) {}
virtual ~line_context() throw() {}
virtual void describe(std::ostream& out) const throw() {
@ -103,22 +103,22 @@ class str_exception : public std::exception {
class error : public str_exception {
public:
error(const std::string& reason, error_context * ctxt = NULL) throw()
: str_exception(reason, ctxt) {}
error(const std::string& _reason, error_context * _ctxt = NULL) throw()
: str_exception(_reason, _ctxt) {}
virtual ~error() throw() {}
};
class fatal : public str_exception {
public:
fatal(const std::string& reason, error_context * ctxt = NULL) throw()
: str_exception(reason, ctxt) {}
fatal(const std::string& _reason, error_context * _ctxt = NULL) throw()
: str_exception(_reason, _ctxt) {}
virtual ~fatal() throw() {}
};
class fatal_assert : public fatal {
public:
fatal_assert(const std::string& reason, error_context * ctxt = NULL) throw()
: fatal(std::string("assertion failed '") + reason + "'", ctxt) {}
fatal_assert(const std::string& _reason, error_context * _ctxt = NULL) throw()
: fatal(std::string("assertion failed '") + _reason + "'", _ctxt) {}
virtual ~fatal_assert() throw() {}
};

View file

@ -1,9 +1,11 @@
#include "format.h"
#include "error.h"
#include "util.h"
#if 0
#ifdef USE_BOOST_PYTHON
#include "py_eval.h"
#endif
#endif
#include <cstdlib>
@ -239,6 +241,7 @@ int format_t::format(std::ostream& out, xml::node_t * context,
} // namespace ledger
#if 0
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
@ -256,3 +259,4 @@ void export_format()
}
#endif // USE_BOOST_PYTHON
#endif

View file

@ -2,9 +2,11 @@
#include "datetime.h"
#include "mask.h"
#include "format.h"
#if 0
#ifdef USE_BOOST_PYTHON
#include "py_eval.h"
#endif
#endif
#include "acconf.h"
#include <fstream>
@ -662,6 +664,7 @@ xact_context::xact_context(const ledger::transaction_t& _xact,
} // namespace ledger
#if 0
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
@ -1043,3 +1046,4 @@ void export_journal()
}
#endif // USE_BOOST_PYTHON
#endif

View file

@ -202,8 +202,8 @@ class entry_context : public error_context {
const entry_base_t& entry;
entry_context(const entry_base_t& _entry,
const std::string& desc = "") throw()
: error_context(desc), entry(_entry) {}
const std::string& _desc = "") throw()
: error_context(_desc), entry(_entry) {}
virtual ~entry_context() throw() {}
virtual void describe(std::ostream& out) const throw();
@ -211,8 +211,9 @@ class entry_context : public error_context {
class balance_error : public error {
public:
balance_error(const std::string& reason, error_context * ctxt = NULL) throw()
: error(reason, ctxt) {}
balance_error(const std::string& _reason,
error_context * _ctxt = NULL) throw()
: error(_reason, _ctxt) {}
virtual ~balance_error() throw() {}
};
@ -342,7 +343,8 @@ struct func_finalizer_t : public entry_finalizer_t {
typedef bool (*func_t)(entry_t& entry, bool post);
func_t func;
func_finalizer_t(func_t _func) : func(_func) {}
func_finalizer_t(const func_finalizer_t& other) : func(other.func) {}
func_finalizer_t(const func_finalizer_t& other) :
entry_finalizer_t(), func(other.func) {}
virtual bool operator()(entry_t& entry, bool post) {
return func(entry, post);
}

2
mask.h
View file

@ -22,7 +22,7 @@ class mask_t
class mask_error : public error {
public:
mask_error(const std::string& reason) throw() : error(reason) {}
mask_error(const std::string& _reason) throw() : error(_reason) {}
virtual ~mask_error() throw() {}
};

View file

@ -2,18 +2,22 @@
#include "report.h"
#include "debug.h"
#include "error.h"
#if 0
#ifdef USE_BOOST_PYTHON
#include "py_eval.h"
#endif
#endif
#include <iostream>
#include <cstdarg>
#include "util.h"
#if 0
#ifdef USE_BOOST_PYTHON
static ledger::option_t * find_option(const std::string& name);
#endif
#endif
namespace ledger {
@ -205,6 +209,7 @@ void process_arguments(int argc, char ** argv, const bool anywhere,
} // namespace ledger
#if 0
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
@ -286,3 +291,4 @@ void export_option()
}
#endif // USE_BOOST_PYTHON
#endif

View file

@ -1,5 +1,6 @@
#include "parser.h"
#if 0
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
@ -47,3 +48,4 @@ void export_parser() {
}
#endif // USE_BOOST_PYTHON
#endif

View file

@ -26,8 +26,9 @@ class parser_t
class parse_error : public error {
public:
parse_error(const std::string& reason, error_context * ctxt = NULL) throw()
: error(reason, ctxt) {}
parse_error(const std::string& _reason,
error_context * _ctxt = NULL) throw()
: error(_reason, _ctxt) {}
virtual ~parse_error() throw() {}
};

226
py_amount.cc Normal file
View file

@ -0,0 +1,226 @@
#include <boost/python.hpp>
#include <Python.h>
#include "amount.h"
using namespace boost::python;
using namespace ledger;
int py_amount_quantity(amount_t& amount)
{
std::ostringstream quant;
amount.print_quantity(quant);
return std::atol(quant.str().c_str());
}
void py_parse_1(amount_t& amount, const std::string& str,
unsigned char flags) {
amount.parse(str, flags);
}
void py_parse_2(amount_t& amount, const std::string& str) {
amount.parse(str);
}
struct commodity_updater_wrap : public commodity_base_t::updater_t
{
PyObject * self;
commodity_updater_wrap(PyObject * self_) : self(self_) {}
virtual void operator()(commodity_base_t& commodity,
const datetime_t& moment,
const datetime_t& date,
const datetime_t& last,
amount_t& price) {
call_method<void>(self, "__call__", commodity, moment, date, last, price);
}
};
commodity_t * py_find_commodity(const std::string& symbol)
{
return commodity_t::find(symbol);
}
#define EXC_TRANSLATOR(type) \
void exc_translate_ ## type(const type& err) { \
PyErr_SetString(PyExc_RuntimeError, err.what()); \
}
EXC_TRANSLATOR(amount_error)
void export_amount()
{
scope().attr("AMOUNT_PARSE_NO_MIGRATE") = AMOUNT_PARSE_NO_MIGRATE;
scope().attr("AMOUNT_PARSE_NO_REDUCE") = AMOUNT_PARSE_NO_REDUCE;
class_< amount_t > ("amount")
//.def(init<>())
.def(init<amount_t>())
.def(init<std::string>())
.def(init<char *>())
.def(init<bool>())
.def(init<long>())
.def(init<unsigned long>())
.def(init<double>())
.def(self += self)
.def(self += long())
.def(self += double())
.def(self + self)
.def(self + long())
.def(long() + self)
.def(self + double())
.def(double() + self)
.def(self -= self)
.def(self -= long())
.def(self -= double())
.def(self - self)
.def(self - long())
.def(long() - self)
.def(self - double())
.def(double() - self)
.def(self *= self)
.def(self *= long())
.def(self *= double())
.def(self * self)
.def(self * long())
.def(long() * self)
.def(self * double())
.def(double() * self)
.def(self /= self)
.def(self /= long())
.def(self /= double())
.def(self / self)
.def(self / long())
.def(long() / self)
.def(self / double())
.def(double() / self)
.def(- self)
.def(self < self)
.def(self < long())
.def(long() < self)
.def(self <= self)
.def(self <= long())
.def(long() <= self)
.def(self > self)
.def(self > long())
.def(long() > self)
.def(self >= self)
.def(self >= long())
.def(long() >= self)
.def(self == self)
.def(self == long())
.def(long() == self)
.def(self != self)
.def(self != long())
.def(long() != self)
.def(! self)
.def(self_ns::int_(self))
.def(self_ns::float_(self))
.def(self_ns::str(self))
.def(abs(self))
#if 0
.def("has_commodity", &amount_t::has_commodity)
.add_property("commodity",
make_function(&amount_t::commodity,
return_value_policy<reference_existing_object>()),
make_function(&amount_t::set_commodity,
with_custodian_and_ward<1, 2>()))
.def("annotate_commodity", &amount_t::annotate_commodity)
.def("strip_annotations", &amount_t::strip_annotations)
.def("clear_commodity", &amount_t::clear_commodity)
.def("quantity_string", &amount_t::quantity_string)
.def("abs", &amount_t::abs)
.def("compare", &amount_t::compare)
.def("date", &amount_t::date)
.def("negate", &amount_t::negate)
.def("negated", &amount_t::negated)
.def("null", &amount_t::null)
.def("parse", py_parse_1)
.def("parse", py_parse_2)
.def("price", &amount_t::price)
.def("reduce", &amount_t::reduce)
.def("reduced", &amount_t::reduced)
.def("sign", &amount_t::sign)
.def("value", &amount_t::value)
.def("valid", &amount_t::valid)
#endif
;
class_< commodity_base_t::updater_t, commodity_updater_wrap,
boost::noncopyable >
("updater")
;
scope().attr("COMMODITY_STYLE_DEFAULTS") = COMMODITY_STYLE_DEFAULTS;
scope().attr("COMMODITY_STYLE_SUFFIXED") = COMMODITY_STYLE_SUFFIXED;
scope().attr("COMMODITY_STYLE_SEPARATED") = COMMODITY_STYLE_SEPARATED;
scope().attr("COMMODITY_STYLE_EUROPEAN") = COMMODITY_STYLE_EUROPEAN;
scope().attr("COMMODITY_STYLE_THOUSANDS") = COMMODITY_STYLE_THOUSANDS;
scope().attr("COMMODITY_STYLE_NOMARKET") = COMMODITY_STYLE_NOMARKET;
scope().attr("COMMODITY_STYLE_BUILTIN") = COMMODITY_STYLE_BUILTIN;
class_< commodity_t > ("commodity")
#if 0
.add_property("symbol", &commodity_t::symbol)
.add_property("name", &commodity_t::name, &commodity_t::set_name)
.add_property("note", &commodity_t::note, &commodity_t::set_note)
.add_property("precision", &commodity_t::precision,
&commodity_t::set_precision)
.add_property("flags", &commodity_t::flags, &commodity_t::set_flags)
.add_property("add_flags", &commodity_t::add_flags)
.add_property("drop_flags", &commodity_t::drop_flags)
//.add_property("updater", &commodity_t::updater)
.add_property("smaller",
make_getter(&commodity_t::smaller,
return_value_policy<reference_existing_object>()),
make_setter(&commodity_t::smaller,
return_value_policy<reference_existing_object>()))
.add_property("larger",
make_getter(&commodity_t::larger,
return_value_policy<reference_existing_object>()),
make_setter(&commodity_t::larger,
return_value_policy<reference_existing_object>()))
.def(self_ns::str(self))
.def("find", py_find_commodity,
return_value_policy<reference_existing_object>())
.staticmethod("find")
.def("add_price", &commodity_t::add_price)
.def("remove_price", &commodity_t::remove_price)
.def("value", &commodity_t::value)
.def("valid", &commodity_t::valid)
#endif
;
#define EXC_TRANSLATE(type) \
register_exception_translator<type>(&exc_translate_ ## type);
EXC_TRANSLATE(amount_error);
}

View file

@ -5,6 +5,7 @@
#include <istream>
void export_amount();
#if 0
void export_balance();
void export_value();
void export_datetime();
@ -18,6 +19,7 @@ void export_format();
void export_valexpr();
void shutdown_option();
#endif
namespace ledger {
@ -25,6 +27,7 @@ namespace {
void initialize_ledger_for_python()
{
export_amount();
#if 0
export_balance();
export_value();
export_datetime();
@ -36,12 +39,15 @@ namespace {
export_format();
export_report();
export_valexpr();
#endif
}
}
void shutdown_ledger_for_python()
{
#if 0
shutdown_option();
#endif
}
struct python_run
@ -57,8 +63,8 @@ struct python_run
}
};
python_interpreter_t::python_interpreter_t(valexpr_t::scope_t * parent)
: valexpr_t::scope_t(parent),
python_interpreter_t::python_interpreter_t(xml::xpath_t::scope_t * parent)
: xml::xpath_t::scope_t(parent),
mmodule(borrowed(PyImport_AddModule("__main__"))),
nspace(handle<>(borrowed(PyModule_GetDict(mmodule.get()))))
{
@ -145,16 +151,18 @@ object python_interpreter_t::eval(const std::string& str, py_eval_mode_t mode)
}
void python_interpreter_t::functor_t::operator()(value_t& result,
valexpr_t::scope_t * locals)
xml::xpath_t::scope_t * locals)
{
try {
if (! PyCallable_Check(func.ptr())) {
result = extract<value_t>(func.ptr());
result = static_cast<const value_t&>(extract<value_t>(func.ptr()));
} else {
if (locals->arg_scope && locals->args.size() > 0) {
assert(locals->args.type == value_t::SEQUENCE);
if (locals->args.to_sequence()->size() > 0) {
list arglist;
for (valexpr_t::scope_t::args_list::iterator i = locals->args.begin();
i != locals->args.end();
for (value_t::sequence_t::iterator
i = locals->args.to_sequence()->begin();
i != locals->args.to_sequence()->end();
i++)
arglist.append(*i);
@ -165,7 +173,7 @@ void python_interpreter_t::functor_t::operator()(value_t& result,
}
else if (PyObject * err = PyErr_Occurred()) {
PyErr_Print();
throw new valexpr_t::calc_error
throw new xml::xpath_t::calc_error
(std::string("While calling Python function '") + name() + "'");
} else {
assert(0);
@ -177,24 +185,24 @@ void python_interpreter_t::functor_t::operator()(value_t& result,
}
catch (const error_already_set&) {
PyErr_Print();
throw new valexpr_t::calc_error
throw new xml::xpath_t::calc_error
(std::string("While calling Python function '") + name() + "'");
}
}
void python_interpreter_t::lambda_t::operator()(value_t& result,
valexpr_t::scope_t * locals)
xml::xpath_t::scope_t * locals)
{
try {
assert(locals->arg_scope && locals->args.size() == 1);
assert(locals->args.type == value_t::SEQUENCE);
assert(locals->args.to_sequence()->size() == 1);
value_t item = locals->args[0];
assert(item.type == value_t::POINTER);
result = call<value_t>(func.ptr(), (repitem_t *)*(void **)item.data);
result = call<value_t>(func.ptr(), (xml::node_t *)*(void **)item.data);
}
catch (const error_already_set&) {
PyErr_Print();
throw new valexpr_t::calc_error
("While evaluating Python lambda expression");
throw new xml::xpath_t::calc_error("While evaluating Python lambda expression");
}
}

View file

@ -1,7 +1,7 @@
#ifndef _PY_EVAL_H
#define _PY_EVAL_H
#include "valexpr.h"
#include "xpath.h"
#include "pyfstream.h"
#include <string>
@ -15,13 +15,14 @@ namespace ledger {
void shutdown_ledger_for_python();
class python_interpreter_t : public valexpr_t::scope_t
class python_interpreter_t : public xml::xpath_t::scope_t
{
handle<> mmodule;
dict nspace;
public:
python_interpreter_t(valexpr_t::scope_t * parent);
dict nspace;
python_interpreter_t(xml::xpath_t::scope_t * parent);
virtual ~python_interpreter_t() {
Py_Finalize();
@ -42,35 +43,35 @@ class python_interpreter_t : public valexpr_t::scope_t
return eval(str, mode);
}
class functor_t : public valexpr_t::functor_t {
class functor_t : public xml::xpath_t::functor_t {
protected:
object func;
public:
python_functor_t(const std::string& name, object _func)
: valexpr_t::functor_t(name), func(_func) {}
functor_t(const std::string& name, object _func)
: xml::xpath_t::functor_t(name), func(_func) {}
virtual void operator()(value_t& result, valexpr_t::scope_t * locals);
virtual void operator()(value_t& result, xml::xpath_t::scope_t * locals);
};
virtual void define(const std::string& name, valexpr_t::node_t * def) {
virtual void define(const std::string& name, xml::xpath_t::op_t * def) {
// Pass any definitions up to our parent
parent->define(name, def);
}
virtual node_t * lookup(const std::string& name) {
virtual xml::xpath_t::op_t * lookup(const std::string& name) {
object func = eval(name);
if (! func)
return parent ? parent->lookup(name) : NULL;
return valexpr_t::wrap_functor(new python_functor_t(name, func));
return xml::xpath_t::wrap_functor(new functor_t(name, func));
}
class lambda_t : public functor_t {
public:
python_lambda_t(object code) : python_functor_t("<lambda>"> code) {}
lambda_t(object code) : functor_t("<lambda>", code) {}
virtual void operator()(value_t& result, valexpr_t::scope_t * locals);
virtual void operator()(value_t& result, xml::xpath_t::scope_t * locals);
};
;
};
} // namespace ledger

8
qif.cc
View file

@ -38,10 +38,10 @@ bool qif_parser_t::test(std::istream& in) const
std::strcmp(magic, "\r\n!T") == 0);
}
unsigned int qif_parser_t::parse(std::istream& in,
journal_t * journal,
account_t * master,
const std::string * original_file)
unsigned int qif_parser_t::parse(std::istream& in,
journal_t * journal,
account_t * master,
const std::string *)
{
std::auto_ptr<entry_t> entry;
std::auto_ptr<amount_t> amount;

View file

@ -27,9 +27,9 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
DEBUG_PRINT_("pricing_leeway is " << pricing_leeway);
if ((commodity.history &&
(datetime_t::now - commodity.history->last_lookup) < pricing_leeway) ||
(datetime_t::now - last) < pricing_leeway ||
(price && moment > date && (moment - date) <= pricing_leeway))
(datetime_t::now - commodity.history->last_lookup) < (long)pricing_leeway) ||
(datetime_t::now - last) < (long)pricing_leeway ||
(price && moment > date && (moment - date) <= (long)pricing_leeway))
return;
using namespace std;

View file

@ -186,6 +186,7 @@ xml::xpath_t::op_t * report_t::lookup(const std::string& name)
} // namespace ledger
#if 0
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
@ -205,3 +206,4 @@ void export_report()
}
#endif // USE_BOOST_PYTHON
#endif

View file

@ -190,6 +190,7 @@ xml::xpath_t::op_t * session_t::lookup(const std::string& name)
} // namespace ledger
#if 0
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
@ -231,3 +232,4 @@ void export_session()
}
#endif // USE_BOOST_PYTHON
#endif

View file

@ -49,8 +49,8 @@ class session_t : public xml::xpath_t::scope_t
std::list<journal_t *> journals;
std::list<parser_t *> parsers;
session_t(xml::xpath_t::scope_t * parent = NULL) :
xml::xpath_t::scope_t(parent),
session_t(xml::xpath_t::scope_t * _parent = NULL) :
xml::xpath_t::scope_t(_parent),
register_format
("%((//entry)%{date} %-.20{payee}"
@ -170,6 +170,7 @@ class session_t : public xml::xpath_t::scope_t
verbose_mode = true;
}
#if 0
#ifdef USE_BOOST_PYTHON
void option_import(value_t&) {
python_import(optarg);
@ -178,6 +179,7 @@ class session_t : public xml::xpath_t::scope_t
python_eval(std::cin, PY_EVAL_MULTI);
}
#endif
#endif
};
} // namespace ledger

View file

@ -4,7 +4,7 @@ from distutils.core import setup, Extension
import os
libs = ["ledger", "boost_python", "gmp", "pcre"]
libs = ["ledger", "pyledger", "boost_python", "gmp", "pcre"]
if os.environ.has_key ("HAVE_EXPAT") and\
os.environ["HAVE_EXPAT"] == "true":

View file

@ -130,6 +130,7 @@ void BasicAmountTest::testIntegerAddition()
assertEquals(amount_t(579L), x1 + y1);
assertEquals(amount_t(579L), x1 + 456L);
assertEquals(amount_t(579L), 456L + x1);
x1 += amount_t(456L);
assertEquals(amount_t(579L), x1);
@ -154,6 +155,7 @@ void BasicAmountTest::testFractionalAddition()
assertEquals(amount_t(579.579), x1 + y1);
assertEquals(amount_t(579.579), x1 + 456.456);
assertEquals(amount_t(579.579), 456.456 + x1);
x1 += amount_t(456.456);
assertEquals(amount_t(579.579), x1);
@ -174,6 +176,8 @@ void BasicAmountTest::testIntegerSubtraction()
assertEquals(amount_t(333L), y1 - x1);
assertEquals(amount_t(-333L), x1 - y1);
assertEquals(amount_t(23L), x1 - 100L);
assertEquals(amount_t(-23L), 100L - x1);
x1 -= amount_t(456L);
assertEquals(amount_t(-333L), x1);
@ -221,14 +225,18 @@ void BasicAmountTest::testIntegerMultiplication()
assertEquals(amount_t(0L), x1 * 0L);
assertEquals(amount_t(0L), amount_t(0L) * x1);
assertEquals(amount_t(0L), 0L * x1);
assertEquals(x1, x1 * 1L);
assertEquals(x1, amount_t(1L) * x1);
assertEquals(x1, 1L * x1);
assertEquals(- x1, x1 * -1L);
assertEquals(- x1, amount_t(-1L) * x1);
assertEquals(- x1, -1L * x1);
assertEquals(amount_t(56088L), x1 * y1);
assertEquals(amount_t(56088L), y1 * x1);
assertEquals(amount_t(56088L), x1 * 456L);
assertEquals(amount_t(56088L), amount_t(456L) * x1);
assertEquals(amount_t(56088L), 456L * x1);
x1 *= amount_t(123L);
assertEquals(amount_t(15129L), x1);
@ -253,14 +261,18 @@ void BasicAmountTest::testFractionalMultiplication()
assertEquals(amount_t(0L), x1 * 0L);
assertEquals(amount_t(0L), amount_t(0L) * x1);
assertEquals(amount_t(0L), 0L * x1);
assertEquals(x1, x1 * 1L);
assertEquals(x1, amount_t(1L) * x1);
assertEquals(x1, 1L * x1);
assertEquals(- x1, x1 * -1L);
assertEquals(- x1, amount_t(-1L) * x1);
assertEquals(- x1, -1L * x1);
assertEquals(amount_t("56200.232088"), x1 * y1);
assertEquals(amount_t("56200.232088"), y1 * x1);
assertEquals(amount_t("56200.232088"), x1 * 456.456);
assertEquals(amount_t("56200.232088"), amount_t(456.456) * x1);
assertEquals(amount_t("56200.232088"), 456.456 * x1);
x1 *= amount_t(123.123);
assertEquals(amount_t("15159.273129"), x1);
@ -282,14 +294,18 @@ void BasicAmountTest::testIntegerDivision()
assertThrow(x1 / 0L, amount_error *);
assertEquals(amount_t(0L), amount_t(0L) / x1);
assertEquals(amount_t(0L), 0L / x1);
assertEquals(x1, x1 / 1L);
assertEquals(amount_t("0.008130"), amount_t(1L) / x1);
assertEquals(amount_t("0.008130"), 1L / x1);
assertEquals(- x1, x1 / -1L);
assertEquals(- amount_t("0.008130"), amount_t(-1L) / x1);
assertEquals(- amount_t("0.008130"), -1L / x1);
assertEquals(amount_t("0.269736"), x1 / y1);
assertEquals(amount_t("3.707317"), y1 / x1);
assertEquals(amount_t("0.269736"), x1 / 456L);
assertEquals(amount_t("3.707317"), amount_t(456L) / x1);
assertEquals(amount_t("3.707317"), 456L / x1);
x1 /= amount_t(456L);
assertEquals(amount_t("0.269736"), x1);
@ -310,14 +326,18 @@ void BasicAmountTest::testFractionalDivision()
assertThrow(x1 / 0L, amount_error *);
assertEquals(amount_t("0.008121"), amount_t(1.0) / x1);
assertEquals(amount_t("0.008121"), 1.0 / x1);
assertEquals(x1, x1 / 1.0);
assertEquals(amount_t("0.008121"), amount_t(1.0) / x1);
assertEquals(amount_t("0.008121"), 1.0 / x1);
assertEquals(- x1, x1 / -1.0);
assertEquals(- amount_t("0.008121"), amount_t(-1.0) / x1);
assertEquals(- amount_t("0.008121"), -1.0 / x1);
assertEquals(amount_t("0.269736842105"), x1 / y1);
assertEquals(amount_t("3.707317073170"), y1 / x1);
assertEquals(amount_t("0.269736842105"), x1 / 456.456);
assertEquals(amount_t("3.707317073170"), amount_t(456.456) / x1);
assertEquals(amount_t("3.707317073170"), 456.456 / x1);
x1 /= amount_t(456.456);
assertEquals(amount_t("0.269736842105"), x1);

View file

@ -10,6 +10,7 @@ namespace ledger {
class transform_t {
public:
virtual ~transform_t() {}
virtual void execute(xml::document_t * document) = 0;
};

View file

@ -73,7 +73,7 @@ std::string abbreviate(const std::string& str, unsigned int width,
elision_style_t elision_style, const bool is_account,
int abbrev_length)
{
const int len = str.length();
const unsigned int len = str.length();
if (len <= width)
return str;
@ -110,7 +110,7 @@ std::string abbreviate(const std::string& str, unsigned int width,
parts.push_back(std::string(str, beg));
std::string result;
int newlen = len;
unsigned int newlen = len;
for (std::list<std::string>::iterator i = parts.begin();
i != parts.end();
i++) {

488
value.cc

File diff suppressed because it is too large Load diff

239
value.h
View file

@ -49,62 +49,62 @@ class value_t
type = INTEGER;
}
value_t(const value_t& value) : type(INTEGER) {
value_t(const value_t& val) : type(INTEGER) {
TRACE_CTOR("value_t(copy)");
*this = value;
*this = val;
}
value_t(const bool value) {
value_t(const bool val) {
TRACE_CTOR("value_t(const bool)");
*((bool *) data) = value;
*((bool *) data) = val;
type = BOOLEAN;
}
value_t(const long value) {
value_t(const long val) {
TRACE_CTOR("value_t(const long)");
*((long *) data) = value;
*((long *) data) = val;
type = INTEGER;
}
value_t(const datetime_t value) {
value_t(const datetime_t val) {
TRACE_CTOR("value_t(const datetime_t)");
*((datetime_t *) data) = value;
*((datetime_t *) data) = val;
type = DATETIME;
}
value_t(const unsigned long value) {
value_t(const unsigned long val) {
TRACE_CTOR("value_t(const unsigned long)");
new((amount_t *) data) amount_t(value);
new((amount_t *) data) amount_t(val);
type = AMOUNT;
}
value_t(const double value) {
value_t(const double val) {
TRACE_CTOR("value_t(const double)");
new((amount_t *) data) amount_t(value);
new((amount_t *) data) amount_t(val);
type = AMOUNT;
}
value_t(const std::string& value, bool literal = false) {
value_t(const std::string& val, bool literal = false) {
TRACE_CTOR("value_t(const std::string&, bool)");
if (literal) {
type = INTEGER;
set_string(value);
set_string(val);
} else {
new((amount_t *) data) amount_t(value);
new((amount_t *) data) amount_t(val);
type = AMOUNT;
}
}
value_t(const char * value) {
value_t(const char * val) {
TRACE_CTOR("value_t(const char *)");
new((amount_t *) data) amount_t(value);
new((amount_t *) data) amount_t(val);
type = AMOUNT;
}
value_t(const amount_t& value) {
value_t(const amount_t& val) {
TRACE_CTOR("value_t(const amount_t&)");
new((amount_t *)data) amount_t(value);
new((amount_t *)data) amount_t(val);
type = AMOUNT;
}
value_t(const balance_t& value) : type(INTEGER) {
value_t(const balance_t& val) : type(INTEGER) {
TRACE_CTOR("value_t(const balance_t&)");
*this = value;
*this = val;
}
value_t(const balance_pair_t& value) : type(INTEGER) {
value_t(const balance_pair_t& val) : type(INTEGER) {
TRACE_CTOR("value_t(const balance_pair_t&)");
*this = value;
*this = val;
}
value_t(xml::node_t * xml_node) : type(INTEGER) { // gets set in =
TRACE_CTOR("value_t(xml::node_t *)");
@ -127,89 +127,89 @@ class value_t
void destroy();
void simplify();
value_t& operator=(const value_t& value);
value_t& operator=(const bool value) {
if ((bool *) data != &value) {
value_t& operator=(const value_t& val);
value_t& operator=(const bool val) {
if ((bool *) data != &val) {
destroy();
*((bool *) data) = value;
*((bool *) data) = val;
type = BOOLEAN;
}
return *this;
}
value_t& operator=(const long value) {
if ((long *) data != &value) {
value_t& operator=(const long val) {
if ((long *) data != &val) {
destroy();
*((long *) data) = value;
*((long *) data) = val;
type = INTEGER;
}
return *this;
}
value_t& operator=(const datetime_t value) {
if ((datetime_t *) data != &value) {
value_t& operator=(const datetime_t val) {
if ((datetime_t *) data != &val) {
destroy();
*((datetime_t *) data) = value;
*((datetime_t *) data) = val;
type = DATETIME;
}
return *this;
}
value_t& operator=(const unsigned long value) {
return *this = amount_t(value);
value_t& operator=(const unsigned long val) {
return *this = amount_t(val);
}
value_t& operator=(const double value) {
return *this = amount_t(value);
value_t& operator=(const double val) {
return *this = amount_t(val);
}
value_t& operator=(const std::string& value) {
return *this = amount_t(value);
value_t& operator=(const std::string& val) {
return *this = amount_t(val);
}
value_t& operator=(const char * value) {
return *this = amount_t(value);
value_t& operator=(const char * val) {
return *this = amount_t(val);
}
value_t& operator=(const amount_t& value) {
value_t& operator=(const amount_t& val) {
if (type == AMOUNT &&
(amount_t *) data == &value)
(amount_t *) data == &val)
return *this;
if (value.realzero()) {
if (val.realzero()) {
return *this = 0L;
} else {
destroy();
new((amount_t *)data) amount_t(value);
new((amount_t *)data) amount_t(val);
type = AMOUNT;
}
return *this;
}
value_t& operator=(const balance_t& value) {
value_t& operator=(const balance_t& val) {
if (type == BALANCE &&
(balance_t *) data == &value)
(balance_t *) data == &val)
return *this;
if (value.realzero()) {
if (val.realzero()) {
return *this = 0L;
}
else if (value.amounts.size() == 1) {
return *this = (*value.amounts.begin()).second;
else if (val.amounts.size() == 1) {
return *this = (*val.amounts.begin()).second;
}
else {
destroy();
new((balance_t *)data) balance_t(value);
new((balance_t *)data) balance_t(val);
type = BALANCE;
return *this;
}
}
value_t& operator=(const balance_pair_t& value) {
value_t& operator=(const balance_pair_t& val) {
if (type == BALANCE_PAIR &&
(balance_pair_t *) data == &value)
(balance_pair_t *) data == &val)
return *this;
if (value.realzero()) {
if (val.realzero()) {
return *this = 0L;
}
else if (! value.cost) {
return *this = value.quantity;
else if (! val.cost) {
return *this = val.quantity;
}
else {
destroy();
new((balance_pair_t *)data) balance_pair_t(value);
new((balance_pair_t *)data) balance_pair_t(val);
type = BALANCE_PAIR;
return *this;
}
@ -291,10 +291,10 @@ class value_t
return (*seq)[index];
}
void push_back(const value_t& value) {
void push_back(const value_t& val) {
sequence_t * seq = to_sequence();
assert(seq);
return seq->push_back(value);
return seq->push_back(val);
}
std::size_t size() const {
@ -303,98 +303,98 @@ class value_t
return seq->size();
}
value_t& operator+=(const value_t& value);
value_t& operator-=(const value_t& value);
value_t& operator*=(const value_t& value);
value_t& operator/=(const value_t& value);
value_t& operator+=(const value_t& val);
value_t& operator-=(const value_t& val);
value_t& operator*=(const value_t& val);
value_t& operator/=(const value_t& val);
template <typename T>
value_t& operator+=(const T& value) {
return *this += value_t(value);
value_t& operator+=(const T& val) {
return *this += value_t(val);
}
template <typename T>
value_t& operator-=(const T& value) {
return *this -= value_t(value);
value_t& operator-=(const T& val) {
return *this -= value_t(val);
}
template <typename T>
value_t& operator*=(const T& value) {
return *this *= value_t(value);
value_t& operator*=(const T& val) {
return *this *= value_t(val);
}
template <typename T>
value_t& operator/=(const T& value) {
return *this /= value_t(value);
value_t& operator/=(const T& val) {
return *this /= value_t(val);
}
value_t operator+(const value_t& value) {
value_t operator+(const value_t& val) {
value_t temp(*this);
temp += value;
temp += val;
return temp;
}
value_t operator-(const value_t& value) {
value_t operator-(const value_t& val) {
value_t temp(*this);
temp -= value;
temp -= val;
return temp;
}
value_t operator*(const value_t& value) {
value_t operator*(const value_t& val) {
value_t temp(*this);
temp *= value;
temp *= val;
return temp;
}
value_t operator/(const value_t& value) {
value_t operator/(const value_t& val) {
value_t temp(*this);
temp /= value;
temp /= val;
return temp;
}
template <typename T>
value_t operator+(const T& value) {
return *this + value_t(value);
value_t operator+(const T& val) {
return *this + value_t(val);
}
template <typename T>
value_t operator-(const T& value) {
return *this - value_t(value);
value_t operator-(const T& val) {
return *this - value_t(val);
}
template <typename T>
value_t operator*(const T& value) {
return *this * value_t(value);
value_t operator*(const T& val) {
return *this * value_t(val);
}
template <typename T>
value_t operator/(const T& value) {
return *this / value_t(value);
value_t operator/(const T& val) {
return *this / value_t(val);
}
bool operator<(const value_t& value);
bool operator<=(const value_t& value);
bool operator>(const value_t& value);
bool operator>=(const value_t& value);
bool operator==(const value_t& value);
bool operator!=(const value_t& value) {
return ! (*this == value);
bool operator<(const value_t& val);
bool operator<=(const value_t& val);
bool operator>(const value_t& val);
bool operator>=(const value_t& val);
bool operator==(const value_t& val);
bool operator!=(const value_t& val) {
return ! (*this == val);
}
template <typename T>
bool operator<(const T& value) {
return *this < value_t(value);
bool operator<(const T& val) {
return *this < value_t(val);
}
template <typename T>
bool operator<=(const T& value) {
return *this <= value_t(value);
bool operator<=(const T& val) {
return *this <= value_t(val);
}
template <typename T>
bool operator>(const T& value) {
return *this > value_t(value);
bool operator>(const T& val) {
return *this > value_t(val);
}
template <typename T>
bool operator>=(const T& value) {
return *this >= value_t(value);
bool operator>=(const T& val) {
return *this >= value_t(val);
}
template <typename T>
bool operator==(const T& value) {
return *this == value_t(value);
bool operator==(const T& val) {
return *this == value_t(val);
}
template <typename T>
bool operator!=(const T& value) {
return ! (*this == value);
bool operator!=(const T& val) {
return ! (*this == val);
}
template <typename T>
@ -467,21 +467,21 @@ class value_t
};
#define DEF_VALUE_AUX_OP(OP) \
inline value_t operator OP(const balance_pair_t& value, \
inline value_t operator OP(const balance_pair_t& val, \
const value_t& obj) { \
return value_t(value) OP obj; \
return value_t(val) OP obj; \
} \
inline value_t operator OP(const balance_t& value, \
inline value_t operator OP(const balance_t& val, \
const value_t& obj) { \
return value_t(value) OP obj; \
return value_t(val) OP obj; \
} \
inline value_t operator OP(const amount_t& value, \
inline value_t operator OP(const amount_t& val, \
const value_t& obj) { \
return value_t(value) OP obj; \
return value_t(val) OP obj; \
} \
template <typename T> \
inline value_t operator OP(T value, const value_t& obj) { \
return value_t(value) OP obj; \
inline value_t operator OP(T val, const value_t& obj) { \
return value_t(val) OP obj; \
}
DEF_VALUE_AUX_OP(+)
@ -533,13 +533,13 @@ template <> value_t::operator datetime_t() const;
template <> value_t::operator double() const;
template <> value_t::operator std::string() const;
inline value_t abs(const value_t& value) {
value_t temp(value);
inline value_t abs(const value_t& val) {
value_t temp(val);
temp.abs();
return temp;
}
std::ostream& operator<<(std::ostream& out, const value_t& value);
std::ostream& operator<<(std::ostream& out, const value_t& val);
class value_context : public error_context
{
@ -554,8 +554,9 @@ class value_context : public error_context
class value_error : public error {
public:
value_error(const std::string& reason, error_context * ctxt = NULL) throw()
: error(reason, ctxt) {}
value_error(const std::string& _reason,
error_context * _ctxt = NULL) throw()
: error(_reason, _ctxt) {}
virtual ~value_error() throw() {}
};

11
xml.cc
View file

@ -10,7 +10,7 @@
namespace ledger {
namespace xml {
document_t::document_t(node_t * _top, const char ** _builtins,
document_t::document_t(node_t *, const char ** _builtins,
const int _builtins_size)
: builtins(_builtins), builtins_size(_builtins_size),
top(new terminal_node_t(this)) {}
@ -99,9 +99,8 @@ document_t * node_t::document;
node_t::node_t(document_t * _document, parent_node_t * _parent,
unsigned int _flags)
: name_id(-1),
parent(_parent),
next(NULL), prev(NULL), flags(_flags), info(NULL), attrs(NULL)
: name_id(0), parent(_parent), next(NULL), prev(NULL),
flags(_flags), info(NULL), attrs(NULL)
{
TRACE_CTOR("node_t(document_t *, node_t *)");
#ifdef THREADSAFE
@ -144,9 +143,9 @@ void parent_node_t::clear()
{
node_t * child = _children;
while (child) {
node_t * next = child->next;
node_t * tnext = child->next;
delete child;
child = next;
child = tnext;
}
}

33
xml.h
View file

@ -63,7 +63,7 @@ class parent_node_t;
class node_t
{
public:
int name_id;
unsigned int name_id;
#ifdef THREADSAFE
document_t * document;
#else
@ -210,6 +210,7 @@ class parser_t
parser_t() : document(NULL), pending(NULL), pending_attrs(NULL),
handled_data(false) {}
virtual ~parser_t() {}
virtual bool test(std::istream& in) const;
virtual document_t * parse(std::istream& in,
@ -219,8 +220,9 @@ class parser_t
class parse_error : public error {
public:
parse_error(const std::string& reason, error_context * ctxt = NULL) throw()
: error(reason, ctxt) {}
parse_error(const std::string& _reason,
error_context * _ctxt = NULL) throw()
: error(_reason, _ctxt) {}
virtual ~parse_error() throw() {}
};
@ -231,9 +233,10 @@ class transaction_node_t : public parent_node_t
transaction_t * transaction;
public:
transaction_node_t(document_t * document, transaction_t * _transaction,
parent_node_t * parent = NULL)
: parent_node_t(document, parent), transaction(_transaction) {
transaction_node_t(document_t * _document,
transaction_t * _transaction,
parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), transaction(_transaction) {
TRACE_CTOR("transaction_node_t(document_t *, transaction_t *, parent_node_t *)");
set_name("transaction");
}
@ -249,9 +252,9 @@ class entry_node_t : public parent_node_t
entry_t * entry;
public:
entry_node_t(document_t * document, entry_t * _entry,
parent_node_t * parent = NULL)
: parent_node_t(document, parent), entry(_entry) {
entry_node_t(document_t * _document, entry_t * _entry,
parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), entry(_entry) {
TRACE_CTOR("entry_node_t(document_t *, entry_t *, parent_node_t *)");
set_name("entry");
}
@ -267,9 +270,9 @@ class account_node_t : public parent_node_t
account_t * account;
public:
account_node_t(document_t * document, account_t * _account,
parent_node_t * parent = NULL)
: parent_node_t(document, parent), account(_account) {
account_node_t(document_t * _document, account_t * _account,
parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), account(_account) {
TRACE_CTOR("account_node_t(document_t *, account_t *, parent_node_t *)");
set_name("account");
}
@ -285,9 +288,9 @@ class journal_node_t : public parent_node_t
journal_t * journal;
public:
journal_node_t(document_t * document, journal_t * _journal,
parent_node_t * parent = NULL)
: parent_node_t(document, parent), journal(_journal) {
journal_node_t(document_t * _document, journal_t * _journal,
parent_node_t * _parent = NULL)
: parent_node_t(_document, _parent), journal(_journal) {
TRACE_CTOR("journal_node_t(document_t *, journal_t *, parent_node_t *)");
set_name("journal");
}

283
xpath.cc
View file

@ -397,7 +397,7 @@ void xpath_t::token_t::next(std::istream& in, unsigned short flags)
void xpath_t::token_t::rewind(std::istream& in)
{
for (int i = 0; i < length; i++)
for (unsigned int i = 0; i < length; i++)
in.unget();
}
@ -484,9 +484,9 @@ void xpath_t::scope_t::define(const std::string& name, op_t * def)
(*i).second->release();
symbols.erase(i);
std::pair<symbol_map::iterator, bool> result
std::pair<symbol_map::iterator, bool> result2
= symbols.insert(symbol_pair(name, def));
if (! result.second)
if (! result2.second)
throw new compile_error(std::string("Redefinition of '") +
name + "' in same scope");
}
@ -613,11 +613,11 @@ void xpath_t::op_t::get_value(value_t& result) const
}
xpath_t::op_t *
xpath_t::parse_value_term(std::istream& in, unsigned short flags) const
xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node;
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
switch (tok.kind) {
case token_t::VALUE:
@ -626,6 +626,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short flags) const
break;
case token_t::IDENT: {
#if 0
#ifdef USE_BOOST_PYTHON
if (tok.value->to_string() == "lambda") // special
try {
@ -649,6 +650,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short flags) const
catch(const boost::python::error_already_set&) {
throw new parse_error("Error parsing lambda expression");
}
#endif /* USE_BOOST_PYTHON */
#endif
std::string ident = tok.value.to_string();
@ -661,16 +663,16 @@ xpath_t::parse_value_term(std::istream& in, unsigned short flags) const
}
// An identifier followed by ( represents a function call
tok = next_token(in, flags);
tok = next_token(in, tflags);
if (tok.kind == token_t::LPAREN) {
node->kind = op_t::FUNC_NAME;
std::auto_ptr<op_t> call_node;
call_node.reset(new op_t(op_t::O_EVAL));
call_node->set_left(node.release());
call_node->set_right(parse_value_expr(in, flags | XPATH_PARSE_PARTIAL));
call_node->set_right(parse_value_expr(in, tflags | XPATH_PARSE_PARTIAL));
tok = next_token(in, flags);
tok = next_token(in, tflags);
if (tok.kind != token_t::RPAREN)
tok.unexpected(); // jww (2006-09-09): wanted )
@ -682,7 +684,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short flags) const
}
case token_t::AT_SYM:
tok = next_token(in, flags);
tok = next_token(in, tflags);
if (tok.kind != token_t::IDENT)
throw parse_error("@ symbol must be followed by attribute name");
@ -692,7 +694,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short flags) const
#if 0
case token_t::DOLLAR:
tok = next_token(in, flags);
tok = next_token(in, tflags);
if (tok.kind != token_t::IDENT)
throw parse_error("$ symbol must be followed by variable name");
@ -719,11 +721,11 @@ xpath_t::parse_value_term(std::istream& in, unsigned short flags) const
break;
case token_t::LPAREN:
node.reset(parse_value_expr(in, flags | XPATH_PARSE_PARTIAL));
node.reset(parse_value_expr(in, tflags | XPATH_PARSE_PARTIAL));
if (! node.get())
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
tok = next_token(in, flags);
tok = next_token(in, tflags);
if (tok.kind != token_t::RPAREN)
tok.unexpected(); // jww (2006-09-09): wanted )
break;
@ -739,30 +741,34 @@ xpath_t::parse_value_term(std::istream& in, unsigned short flags) const
break;
}
#if 0
#ifdef USE_BOOST_PYTHON
done:
#endif
#endif
return node.release();
}
xpath_t::op_t *
xpath_t::parse_predicate_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_predicate_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_value_term(in, flags));
std::auto_ptr<op_t> node(parse_value_term(in, tflags));
if (node.get()) {
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
while (tok.kind == token_t::LBRACKET) {
std::auto_ptr<op_t> prev(node.release());
node.reset(new op_t(op_t::O_PRED));
node->set_left(prev.release());
node->set_right(parse_value_expr(in, flags | XPATH_PARSE_PARTIAL));
node->set_right(parse_value_expr(in, tflags | XPATH_PARSE_PARTIAL));
if (! node->right)
throw new parse_error("[ operator not followed by valid expression");
tok = next_token(in, flags);
tok = next_token(in, tflags);
if (tok.kind != token_t::RBRACKET)
tok.unexpected(); // jww (2006-09-09): wanted ]
tok = next_token(in, flags);
tok = next_token(in, tflags);
}
push_token(tok);
@ -772,9 +778,9 @@ xpath_t::parse_predicate_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_path_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_path_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_predicate_expr(in, flags));
std::auto_ptr<op_t> node(parse_predicate_expr(in, tflags));
if (node.get()) {
// If the beginning of the path was /, just put it back; this
@ -782,22 +788,22 @@ xpath_t::parse_path_expr(std::istream& in, unsigned short flags) const
if (node->kind == op_t::NODE_ID && node->name_id == document_t::ROOT)
push_token();
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
while (tok.kind == token_t::SLASH) {
std::auto_ptr<op_t> prev(node.release());
tok = next_token(in, flags);
tok = next_token(in, tflags);
node.reset(new op_t(tok.kind == token_t::SLASH ?
op_t::O_RFIND : op_t::O_FIND));
if (tok.kind != token_t::SLASH)
push_token(tok);
node->set_left(prev.release());
node->set_right(parse_predicate_expr(in, flags));
node->set_right(parse_predicate_expr(in, tflags));
if (! node->right)
throw new parse_error("/ operator not followed by a valid term");
tok = next_token(in, flags);
tok = next_token(in, tflags);
}
push_token(tok);
@ -807,59 +813,59 @@ xpath_t::parse_path_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_unary_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_unary_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node;
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
switch (tok.kind) {
case token_t::EXCLAM: {
std::auto_ptr<op_t> expr(parse_path_expr(in, flags));
if (! expr.get())
std::auto_ptr<op_t> texpr(parse_path_expr(in, tflags));
if (! texpr.get())
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
// A very quick optimization
if (expr->kind == op_t::VALUE) {
*expr->valuep = ! *expr->valuep;
node.reset(expr.release());
if (texpr->kind == op_t::VALUE) {
*texpr->valuep = ! *texpr->valuep;
node.reset(texpr.release());
} else {
node.reset(new op_t(op_t::O_NOT));
node->set_left(expr.release());
node->set_left(texpr.release());
}
break;
}
case token_t::MINUS: {
std::auto_ptr<op_t> expr(parse_path_expr(in, flags));
if (! expr.get())
std::auto_ptr<op_t> texpr(parse_path_expr(in, tflags));
if (! texpr.get())
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
// A very quick optimization
if (expr->kind == op_t::VALUE) {
expr->valuep->negate();
node.reset(expr.release());
if (texpr->kind == op_t::VALUE) {
texpr->valuep->negate();
node.reset(texpr.release());
} else {
node.reset(new op_t(op_t::O_NEG));
node->set_left(expr.release());
node->set_left(texpr.release());
}
break;
}
#if 0
case token_t::PERCENT: {
std::auto_ptr<op_t> expr(parse_path_expr(in, flags));
if (! expr.get())
std::auto_ptr<op_t> texpr(parse_path_expr(in, tflags));
if (! texpr.get())
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
// A very quick optimization
if (expr->kind == op_t::VALUE) {
if (texpr->kind == op_t::VALUE) {
static value_t perc("100.0%");
*expr->valuep = perc * *expr->valuep;
node.reset(expr.release());
*texpr->valuep = perc * *texpr->valuep;
node.reset(texpr.release());
} else {
node.reset(new op_t(op_t::O_PERC));
node->set_left(expr.release());
node->set_left(texpr.release());
}
break;
}
@ -867,7 +873,7 @@ xpath_t::parse_unary_expr(std::istream& in, unsigned short flags) const
default:
push_token(tok);
node.reset(parse_path_expr(in, flags));
node.reset(parse_path_expr(in, tflags));
break;
}
@ -875,17 +881,17 @@ xpath_t::parse_unary_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_union_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_union_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_unary_expr(in, flags));
std::auto_ptr<op_t> node(parse_unary_expr(in, tflags));
if (node.get()) {
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::PIPE || tok.kind == token_t::KW_UNION) {
std::auto_ptr<op_t> prev(node.release());
node.reset(new op_t(op_t::O_UNION));
node->set_left(prev.release());
node->set_right(parse_union_expr(in, flags));
node->set_right(parse_union_expr(in, tflags));
if (! node->right)
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
@ -897,23 +903,23 @@ xpath_t::parse_union_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_mul_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_mul_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_union_expr(in, flags));
std::auto_ptr<op_t> node(parse_union_expr(in, tflags));
if (node.get()) {
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::STAR || tok.kind == token_t::KW_DIV) {
std::auto_ptr<op_t> prev(node.release());
node.reset(new op_t(tok.kind == token_t::STAR ?
op_t::O_MUL : op_t::O_DIV));
node->set_left(prev.release());
node->set_right(parse_mul_expr(in, flags));
node->set_right(parse_mul_expr(in, tflags));
if (! node->right)
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
tok = next_token(in, flags);
tok = next_token(in, tflags);
}
push_token(tok);
}
@ -922,24 +928,24 @@ xpath_t::parse_mul_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_add_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_add_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_mul_expr(in, flags));
std::auto_ptr<op_t> node(parse_mul_expr(in, tflags));
if (node.get()) {
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::PLUS ||
tok.kind == token_t::MINUS) {
std::auto_ptr<op_t> prev(node.release());
node.reset(new op_t(tok.kind == token_t::PLUS ?
op_t::O_ADD : op_t::O_SUB));
node->set_left(prev.release());
node->set_right(parse_add_expr(in, flags));
node->set_right(parse_add_expr(in, tflags));
if (! node->right)
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
tok = next_token(in, flags);
tok = next_token(in, tflags);
}
push_token(tok);
}
@ -948,16 +954,16 @@ xpath_t::parse_add_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_logic_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_logic_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_add_expr(in, flags));
std::auto_ptr<op_t> node(parse_add_expr(in, tflags));
if (node.get()) {
op_t::kind_t kind = op_t::LAST;
unsigned short _flags = flags;
unsigned short _flags = tflags;
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
switch (tok.kind) {
case token_t::ASSIGN:
kind = op_t::O_DEFINE;
@ -1000,7 +1006,7 @@ xpath_t::parse_logic_expr(std::istream& in, unsigned short flags) const
node.reset(new op_t(kind));
node->set_left(prev.release());
if (kind == op_t::O_DEFINE)
node->set_right(parse_querycolon_expr(in, flags));
node->set_right(parse_querycolon_expr(in, tflags));
else
node->set_right(parse_add_expr(in, _flags));
@ -1019,17 +1025,17 @@ xpath_t::parse_logic_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_and_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_and_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_logic_expr(in, flags));
std::auto_ptr<op_t> node(parse_logic_expr(in, tflags));
if (node.get()) {
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::KW_AND) {
std::auto_ptr<op_t> prev(node.release());
node.reset(new op_t(op_t::O_AND));
node->set_left(prev.release());
node->set_right(parse_and_expr(in, flags));
node->set_right(parse_and_expr(in, tflags));
if (! node->right)
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
@ -1041,17 +1047,17 @@ xpath_t::parse_and_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_or_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_or_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_and_expr(in, flags));
std::auto_ptr<op_t> node(parse_and_expr(in, tflags));
if (node.get()) {
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::KW_OR) {
std::auto_ptr<op_t> prev(node.release());
node.reset(new op_t(op_t::O_OR));
node->set_left(prev.release());
node->set_right(parse_or_expr(in, flags));
node->set_right(parse_or_expr(in, tflags));
if (! node->right)
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
@ -1063,25 +1069,25 @@ xpath_t::parse_or_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_querycolon_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_querycolon_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_or_expr(in, flags));
std::auto_ptr<op_t> node(parse_or_expr(in, tflags));
if (node.get()) {
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::QUESTION) {
std::auto_ptr<op_t> prev(node.release());
node.reset(new op_t(op_t::O_QUES));
node->set_left(prev.release());
node->set_right(new op_t(op_t::O_COLON));
node->right->set_left(parse_querycolon_expr(in, flags));
node->right->set_left(parse_querycolon_expr(in, tflags));
if (! node->right)
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
tok = next_token(in, flags);
tok = next_token(in, tflags);
if (tok.kind != token_t::COLON)
tok.unexpected(); // jww (2006-09-09): wanted :
node->right->set_right(parse_querycolon_expr(in, flags));
node->right->set_right(parse_querycolon_expr(in, tflags));
if (! node->right)
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
@ -1093,31 +1099,31 @@ xpath_t::parse_querycolon_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_value_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_value_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_querycolon_expr(in, flags));
std::auto_ptr<op_t> node(parse_querycolon_expr(in, tflags));
if (node.get()) {
token_t& tok = next_token(in, flags);
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::COMMA) {
std::auto_ptr<op_t> prev(node.release());
node.reset(new op_t(op_t::O_COMMA));
node->set_left(prev.release());
node->set_right(parse_value_expr(in, flags));
node->set_right(parse_value_expr(in, tflags));
if (! node->right)
throw new parse_error(std::string(tok.symbol) +
" operator not followed by argument");
tok = next_token(in, flags);
tok = next_token(in, tflags);
}
if (tok.kind != token_t::TOK_EOF) {
if (flags & XPATH_PARSE_PARTIAL)
if (tflags & XPATH_PARSE_PARTIAL)
push_token(tok);
else
tok.unexpected();
}
}
else if (! (flags & XPATH_PARSE_PARTIAL)) {
else if (! (tflags & XPATH_PARSE_PARTIAL)) {
throw new parse_error(std::string("Failed to parse value expression"));
}
@ -1125,9 +1131,9 @@ xpath_t::parse_value_expr(std::istream& in, unsigned short flags) const
}
xpath_t::op_t *
xpath_t::parse_expr(std::istream& in, unsigned short flags) const
xpath_t::parse_expr(std::istream& in, unsigned short tflags) const
{
std::auto_ptr<op_t> node(parse_value_expr(in, flags));
std::auto_ptr<op_t> node(parse_value_expr(in, tflags));
if (use_lookahead) {
use_lookahead = false;
@ -1150,13 +1156,13 @@ xpath_t::op_t::new_node(kind_t kind, op_t * left, op_t * right)
}
xpath_t::op_t *
xpath_t::op_t::copy(op_t * left, op_t * right) const
xpath_t::op_t::copy(op_t * tleft, op_t * tright) const
{
std::auto_ptr<op_t> node(new op_t(kind));
if (left)
node->set_left(left);
if (right)
node->set_right(right);
if (tleft)
node->set_left(tleft);
if (tright)
node->set_right(tright);
return node.release();
}
@ -1239,17 +1245,17 @@ xpath_t::op_t * xpath_t::op_t::defer_sequence(value_t::sequence_t& result_seq)
return lit_seq.release();
}
void xpath_t::op_t::append_value(value_t& value,
void xpath_t::op_t::append_value(value_t& val,
value_t::sequence_t& result_seq)
{
if (value.type == value_t::SEQUENCE) {
value_t::sequence_t * subseq = value.to_sequence();
if (val.type == value_t::SEQUENCE) {
value_t::sequence_t * subseq = val.to_sequence();
for (value_t::sequence_t::iterator i = subseq->begin();
i != subseq->end();
i++)
result_seq.push_back(*i);
} else {
result_seq.push_back(value);
result_seq.push_back(val);
}
}
@ -2380,6 +2386,7 @@ void xpath_t::op_t::dump(std::ostream& out, const int depth) const
} // namespace xml
} // namespace ledger
#if 0
#ifdef USE_BOOST_PYTHON
#include <boost/python.hpp>
@ -2465,88 +2472,4 @@ void export_xpath()
}
#endif // USE_BOOST_PYTHON
#ifdef TEST
#if ! defined(HAVE_EXPAT) && ! defined(HAVE_XMLPARSE)
#error No XML parser library was found during configure
#endif
#if 0
#include "session.h"
#include "format.h"
#endif
int main(int argc, char *argv[])
{
using namespace ledger;
using namespace ledger::xml;
try {
parser_t parser;
std::auto_ptr<document_t> doc;
std::ifstream input(argv[1]);
if (parser.test(input)) {
doc.reset(parser.parse(input));
doc->write(std::cout);
} else {
std::cerr << "Could not parse XML file: " << argv[1] << std::endl;
return 1;
}
xpath_t expr(argv[2]);
if (expr) {
std::cout << "Parsed:" << std::endl;
expr.dump(std::cout);
std::cout << std::endl;
expr.compile(doc.get());
std::cout << "Compiled:" << std::endl;
expr.dump(std::cout);
std::cout << std::endl;
value_t temp;
expr.calc(temp, doc->top);
std::cout << "Calculated value: " << temp << std::endl;
} else {
std::cerr << "Failed to parse value expression!" << std::endl;
}
#if 0
{
ledger::session_t session;
std::auto_ptr<xpath_t::scope_t>
locals(new xpath_t::scope_t(&session.globals));
ledger::format_t fmt(std::string("%20|%40{") + argv[1] + "}\n");
fmt.format(std::cout, locals.get());
}
#endif
}
catch (error * err) {
std::cout.flush();
if (err->context.empty())
err->context.push_front(new error_context(""));
err->reveal_context(std::cerr, "Error");
std::cerr << err->what() << std::endl;
delete err;
return 1;
}
catch (fatal * err) {
std::cout.flush();
if (err->context.empty())
err->context.push_front(new error_context(""));
err->reveal_context(std::cerr, "Fatal");
std::cerr << err->what() << std::endl;
delete err;
return 1;
}
catch (const std::exception& err) {
std::cout.flush();
std::cerr << "Error: " << err.what() << std::endl;
return 1;
}
}
#endif // TEST

62
xpath.h
View file

@ -20,25 +20,25 @@ public:
class parse_error : public error {
public:
parse_error(const std::string& reason,
error_context * ctxt = NULL) throw()
: error(reason, ctxt) {}
parse_error(const std::string& _reason,
error_context * _ctxt = NULL) throw()
: error(_reason, _ctxt) {}
virtual ~parse_error() throw() {}
};
class compile_error : public error {
public:
compile_error(const std::string& reason,
error_context * ctxt = NULL) throw()
: error(reason, ctxt) {}
compile_error(const std::string& _reason,
error_context * _ctxt = NULL) throw()
: error(_reason, _ctxt) {}
virtual ~compile_error() throw() {}
};
class calc_error : public error {
public:
calc_error(const std::string& reason,
error_context * ctxt = NULL) throw()
: error(reason, ctxt) {}
calc_error(const std::string& _reason,
error_context * _ctxt = NULL) throw()
: error(_reason, _ctxt) {}
virtual ~calc_error() throw() {}
};
@ -78,8 +78,8 @@ public:
T * ptr;
U T::*dptr;
member_functor_t(const std::string& name, T * _ptr, U T::*_dptr)
: functor_t(name, false), ptr(_ptr), dptr(_dptr) {}
member_functor_t(const std::string& _name, T * _ptr, U T::*_dptr)
: functor_t(_name, false), ptr(_ptr), dptr(_dptr) {}
virtual void operator()(value_t& result, scope_t * locals) {
assert(ptr);
@ -94,8 +94,8 @@ public:
T * ptr;
std::string T::*dptr;
member_functor_t(const std::string& name, T * _ptr, std::string T::*_dptr)
: functor_t(name, false), ptr(_ptr), dptr(_dptr) {}
member_functor_t(const std::string& _name, T * _ptr, std::string T::*_dptr)
: functor_t(_name, false), ptr(_ptr), dptr(_dptr) {}
virtual void operator()(value_t& result, scope_t * locals) {
assert(ptr);
@ -110,13 +110,15 @@ public:
T * ptr;
void (T::*mptr)(value_t& result);
memfun_functor_t(const std::string& name, T * _ptr,
memfun_functor_t(const std::string& _name, T * _ptr,
void (T::*_mptr)(value_t& result))
: functor_t(name, false), ptr(_ptr), mptr(_mptr) {}
: functor_t(_name, false), ptr(_ptr), mptr(_mptr) {}
virtual void operator()(value_t& result, scope_t * locals = NULL) {
virtual void operator()(value_t& result,
scope_t * locals = NULL) {
assert(ptr);
assert(mptr);
assert(locals || locals == NULL);
(ptr->*mptr)(result);
}
};
@ -127,9 +129,9 @@ public:
T * ptr;
void (T::*mptr)(value_t& result, scope_t * locals);
memfun_args_functor_t(const std::string& name, T * _ptr,
memfun_args_functor_t(const std::string& _name, T * _ptr,
void (T::*_mptr)(value_t& result, scope_t * locals))
: functor_t(name, true), ptr(_ptr), mptr(_mptr) {}
: functor_t(_name, true), ptr(_ptr), mptr(_mptr) {}
virtual void operator()(value_t& result, scope_t * locals) {
assert(ptr);
@ -221,8 +223,8 @@ public:
public:
function_scope_t(value_t::sequence_t * _sequence, value_t * _value,
int _index, scope_t * parent = NULL)
: scope_t(parent, STATIC),
int _index, scope_t * _parent = NULL)
: scope_t(_parent, STATIC),
sequence(_sequence), value(_value), index(_index) {}
virtual bool resolve(const std::string& name, value_t& result,
@ -549,11 +551,11 @@ public:
#endif
mutable bool use_lookahead;
token_t& next_token(std::istream& in, unsigned short flags) const {
token_t& next_token(std::istream& in, unsigned short tflags) const {
if (use_lookahead)
use_lookahead = false;
else
lookahead.next(in, flags);
lookahead.next(in, tflags);
return lookahead;
}
void push_token(const token_t& tok) const {
@ -581,11 +583,11 @@ public:
unsigned short flags = XPATH_PARSE_RELAXED) const;
op_t * parse_expr(const std::string& str,
unsigned short flags = XPATH_PARSE_RELAXED) const
unsigned short tflags = XPATH_PARSE_RELAXED) const
{
std::istringstream stream(str);
try {
return parse_expr(stream, flags);
return parse_expr(stream, tflags);
}
catch (error * err) {
err->context.push_back
@ -596,8 +598,8 @@ public:
}
op_t * parse_expr(const char * p,
unsigned short flags = XPATH_PARSE_RELAXED) const {
return parse_expr(std::string(p), flags);
unsigned short tflags = XPATH_PARSE_RELAXED) const {
return parse_expr(std::string(p), tflags);
}
bool write(std::ostream& out,
@ -721,11 +723,11 @@ public:
calc(temp, document ? document->top : NULL, scope);
return temp;
}
virtual value_t calc(node_t * context, scope_t * scope = NULL) const {
virtual value_t calc(node_t * tcontext, scope_t * scope = NULL) const {
if (! ptr)
return 0L;
value_t temp;
calc(temp, context, scope);
calc(temp, tcontext, scope);
return temp;
}
@ -749,7 +751,7 @@ public:
} // namespace xml
template <typename T>
inline T * get_ptr(xml::xpath_t::scope_t * locals, int idx) {
inline T * get_ptr(xml::xpath_t::scope_t * locals, unsigned int idx) {
assert(locals->args.size() > idx);
T * ptr = static_cast<T *>(locals->args[idx].to_pointer());
assert(ptr);
@ -761,7 +763,7 @@ class xml_command : public xml::xpath_t::functor_t
public:
xml_command() : xml::xpath_t::functor_t("xml") {}
virtual void operator()(value_t& result, xml::xpath_t::scope_t * locals) {
virtual void operator()(value_t&, xml::xpath_t::scope_t * locals) {
std::ostream * out = get_ptr<std::ostream>(locals, 0);
xml::document_t * doc = get_ptr<xml::document_t>(locals, 1);