Made the amount/balance/value interface a bit more rational; added
back a useless version of the register command (just to prove the command sequence); and added smart XML semantics to the XPath implementation so that nodes can be coerced to values.
This commit is contained in:
parent
176b3044e3
commit
0a6b5726ec
38 changed files with 729 additions and 672 deletions
|
|
@ -46,6 +46,8 @@ libledger_la_SOURCES = \
|
||||||
report.cc \
|
report.cc \
|
||||||
transform.cc \
|
transform.cc \
|
||||||
\
|
\
|
||||||
|
register.cc \
|
||||||
|
\
|
||||||
csv.cc \
|
csv.cc \
|
||||||
derive.cc \
|
derive.cc \
|
||||||
emacs.cc \
|
emacs.cc \
|
||||||
|
|
@ -164,7 +166,7 @@ noinst_PROGRAMS = ledger.so
|
||||||
|
|
||||||
ledger_so_SOURCES = pyledger.cc
|
ledger_so_SOURCES = pyledger.cc
|
||||||
|
|
||||||
PYLIBS = pyledger ledger gdtoa boost_date_time boost_python gmp pcre
|
PYLIBS = pyledger ledger gdtoa boost_date_time boost_regex boost_python gmp
|
||||||
|
|
||||||
if HAVE_EXPAT
|
if HAVE_EXPAT
|
||||||
PYLIBS += expat
|
PYLIBS += expat
|
||||||
|
|
|
||||||
33
Makefile.in
33
Makefile.in
|
|
@ -96,8 +96,8 @@ am__libledger_la_SOURCES_DIST = amount.cc times.cc parsetime.yy \
|
||||||
scantime.ll quotes.cc balance.cc value.cc xml.cc xpath.cc \
|
scantime.ll quotes.cc balance.cc value.cc xml.cc xpath.cc \
|
||||||
mask.cc format.cc util.cc session.cc journal.cc parser.cc \
|
mask.cc format.cc util.cc session.cc journal.cc parser.cc \
|
||||||
textual.cc binary.cc xmlparse.cc qif.cc report.cc transform.cc \
|
textual.cc binary.cc xmlparse.cc qif.cc report.cc transform.cc \
|
||||||
csv.cc derive.cc emacs.cc reconcile.cc gnucash.cc ofx.cc \
|
register.cc csv.cc derive.cc emacs.cc reconcile.cc gnucash.cc \
|
||||||
debug.cc trace.cc
|
ofx.cc debug.cc trace.cc
|
||||||
@HAVE_EXPAT_TRUE@am__objects_1 = libledger_la-gnucash.lo
|
@HAVE_EXPAT_TRUE@am__objects_1 = libledger_la-gnucash.lo
|
||||||
@HAVE_XMLPARSE_TRUE@am__objects_2 = libledger_la-gnucash.lo
|
@HAVE_XMLPARSE_TRUE@am__objects_2 = libledger_la-gnucash.lo
|
||||||
@HAVE_LIBOFX_TRUE@am__objects_3 = libledger_la-ofx.lo
|
@HAVE_LIBOFX_TRUE@am__objects_3 = libledger_la-ofx.lo
|
||||||
|
|
@ -113,10 +113,11 @@ am_libledger_la_OBJECTS = libledger_la-amount.lo libledger_la-times.lo \
|
||||||
libledger_la-parser.lo libledger_la-textual.lo \
|
libledger_la-parser.lo libledger_la-textual.lo \
|
||||||
libledger_la-binary.lo libledger_la-xmlparse.lo \
|
libledger_la-binary.lo libledger_la-xmlparse.lo \
|
||||||
libledger_la-qif.lo libledger_la-report.lo \
|
libledger_la-qif.lo libledger_la-report.lo \
|
||||||
libledger_la-transform.lo libledger_la-csv.lo \
|
libledger_la-transform.lo libledger_la-register.lo \
|
||||||
libledger_la-derive.lo libledger_la-emacs.lo \
|
libledger_la-csv.lo libledger_la-derive.lo \
|
||||||
libledger_la-reconcile.lo $(am__objects_1) $(am__objects_2) \
|
libledger_la-emacs.lo libledger_la-reconcile.lo \
|
||||||
$(am__objects_3) $(am__objects_4)
|
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||||
|
$(am__objects_4)
|
||||||
libledger_la_OBJECTS = $(am_libledger_la_OBJECTS)
|
libledger_la_OBJECTS = $(am_libledger_la_OBJECTS)
|
||||||
libledger_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
libledger_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||||
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(libledger_la_CXXFLAGS) \
|
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(libledger_la_CXXFLAGS) \
|
||||||
|
|
@ -373,9 +374,10 @@ libledger_la_CXXFLAGS = $(WARNFLAGS) -I$(top_builddir)/gdtoa \
|
||||||
libledger_la_SOURCES = amount.cc times.cc parsetime.yy scantime.ll \
|
libledger_la_SOURCES = amount.cc times.cc parsetime.yy scantime.ll \
|
||||||
quotes.cc balance.cc value.cc xml.cc xpath.cc mask.cc \
|
quotes.cc balance.cc value.cc xml.cc xpath.cc mask.cc \
|
||||||
format.cc util.cc session.cc journal.cc parser.cc textual.cc \
|
format.cc util.cc session.cc journal.cc parser.cc textual.cc \
|
||||||
binary.cc xmlparse.cc qif.cc report.cc transform.cc csv.cc \
|
binary.cc xmlparse.cc qif.cc report.cc transform.cc \
|
||||||
derive.cc emacs.cc reconcile.cc $(am__append_3) \
|
register.cc csv.cc derive.cc emacs.cc reconcile.cc \
|
||||||
$(am__append_5) $(am__append_7) $(am__append_9)
|
$(am__append_3) $(am__append_5) $(am__append_7) \
|
||||||
|
$(am__append_9)
|
||||||
libledger_la_LDFLAGS = -release 3.0
|
libledger_la_LDFLAGS = -release 3.0
|
||||||
libpyledger_la_CXXFLAGS = -DUSE_BOOST_PYTHON=1 $(am__append_11)
|
libpyledger_la_CXXFLAGS = -DUSE_BOOST_PYTHON=1 $(am__append_11)
|
||||||
libpyledger_la_SOURCES = \
|
libpyledger_la_SOURCES = \
|
||||||
|
|
@ -433,8 +435,9 @@ info_TEXINFOS = ledger.texi
|
||||||
lisp_LISP = ledger.el timeclock.el
|
lisp_LISP = ledger.el timeclock.el
|
||||||
@HAVE_BOOST_PYTHON_TRUE@ledger_so_SOURCES = pyledger.cc
|
@HAVE_BOOST_PYTHON_TRUE@ledger_so_SOURCES = pyledger.cc
|
||||||
@HAVE_BOOST_PYTHON_TRUE@PYLIBS = pyledger ledger gdtoa boost_date_time \
|
@HAVE_BOOST_PYTHON_TRUE@PYLIBS = pyledger ledger gdtoa boost_date_time \
|
||||||
@HAVE_BOOST_PYTHON_TRUE@ boost_python gmp pcre $(am__append_18) \
|
@HAVE_BOOST_PYTHON_TRUE@ boost_regex boost_python gmp \
|
||||||
@HAVE_BOOST_PYTHON_TRUE@ $(am__append_19) $(am__append_20)
|
@HAVE_BOOST_PYTHON_TRUE@ $(am__append_18) $(am__append_19) \
|
||||||
|
@HAVE_BOOST_PYTHON_TRUE@ $(am__append_20)
|
||||||
@DEBUG_FALSE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 0
|
@DEBUG_FALSE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 0
|
||||||
@DEBUG_TRUE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 4
|
@DEBUG_TRUE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 4
|
||||||
UnitTests_SOURCES = tests/UnitTests.cc \
|
UnitTests_SOURCES = tests/UnitTests.cc \
|
||||||
|
|
@ -622,6 +625,7 @@ distclean-compile:
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-qif.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-qif.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-quotes.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-quotes.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-reconcile.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-reconcile.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-register.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-report.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-report.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-scantime.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-scantime.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-session.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-session.Plo@am__quote@
|
||||||
|
|
@ -806,6 +810,13 @@ libledger_la-transform.lo: transform.cc
|
||||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-transform.lo `test -f 'transform.cc' || echo '$(srcdir)/'`transform.cc
|
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-transform.lo `test -f 'transform.cc' || echo '$(srcdir)/'`transform.cc
|
||||||
|
|
||||||
|
libledger_la-register.lo: register.cc
|
||||||
|
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-register.lo -MD -MP -MF $(DEPDIR)/libledger_la-register.Tpo -c -o libledger_la-register.lo `test -f 'register.cc' || echo '$(srcdir)/'`register.cc
|
||||||
|
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-register.Tpo $(DEPDIR)/libledger_la-register.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='register.cc' object='libledger_la-register.lo' libtool=yes @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -c -o libledger_la-register.lo `test -f 'register.cc' || echo '$(srcdir)/'`register.cc
|
||||||
|
|
||||||
libledger_la-csv.lo: csv.cc
|
libledger_la-csv.lo: csv.cc
|
||||||
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-csv.lo -MD -MP -MF $(DEPDIR)/libledger_la-csv.Tpo -c -o libledger_la-csv.lo `test -f 'csv.cc' || echo '$(srcdir)/'`csv.cc
|
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libledger_la_CXXFLAGS) $(CXXFLAGS) -MT libledger_la-csv.lo -MD -MP -MF $(DEPDIR)/libledger_la-csv.Tpo -c -o libledger_la-csv.lo `test -f 'csv.cc' || echo '$(srcdir)/'`csv.cc
|
||||||
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-csv.Tpo $(DEPDIR)/libledger_la-csv.Plo
|
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-csv.Tpo $(DEPDIR)/libledger_la-csv.Plo
|
||||||
|
|
|
||||||
4
README
4
README
|
|
@ -30,10 +30,10 @@ Building
|
||||||
========
|
========
|
||||||
|
|
||||||
To build Ledger, you will need a fairly modern C++ compiler (gcc 2.95
|
To build Ledger, you will need a fairly modern C++ compiler (gcc 2.95
|
||||||
will not work), and at least these two libraries installed:
|
will not work), and at least these libraries installed:
|
||||||
|
|
||||||
gmp GNU multi-precision library
|
gmp GNU multi-precision library
|
||||||
pcre Perl regular expression library
|
boost Boost C++ library
|
||||||
|
|
||||||
(On some GNU/Linux systems, the packages you need to install are
|
(On some GNU/Linux systems, the packages you need to install are
|
||||||
called "gmp-dev" and "pcre-dev").
|
called "gmp-dev" and "pcre-dev").
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,18 @@
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
#undef HAVE_INTTYPES_H
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <langinfo.h> header file. */
|
||||||
|
#undef HAVE_LANGINFO_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <memory.h> header file. */
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
#undef HAVE_MEMORY_H
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
/* Define to 1 if you have the `mktime' function. */
|
/* Define to 1 if you have the `mktime' function. */
|
||||||
#undef HAVE_MKTIME
|
#undef HAVE_MKTIME
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `nl_langinfo' function. */
|
||||||
|
#undef HAVE_NL_LANGINFO
|
||||||
|
|
||||||
/* Define to 1 if you have the `realpath' function. */
|
/* Define to 1 if you have the `realpath' function. */
|
||||||
#undef HAVE_REALPATH
|
#undef HAVE_REALPATH
|
||||||
|
|
||||||
|
|
|
||||||
2
acprep
2
acprep
|
|
@ -61,7 +61,7 @@ while [ -n "$1" ]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--debug)
|
--debug)
|
||||||
SWITCHES="$SWITCHES --enable-debug"
|
SWITCHES="$SWITCHES --enable-debug"
|
||||||
CXXFLAGS="$CXXFLAGS -ggdb3" ;;
|
CXXFLAGS="$CXXFLAGS -g" ;;
|
||||||
|
|
||||||
--prof | --perf)
|
--prof | --perf)
|
||||||
CXXFLAGS="$CXXFLAGS -g -pg" ;;
|
CXXFLAGS="$CXXFLAGS -g -pg" ;;
|
||||||
|
|
|
||||||
18
amount.cc
18
amount.cc
|
|
@ -639,7 +639,7 @@ amount_t& amount_t::operator/=(const amount_t& amt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// unary negation
|
// unary negation
|
||||||
void amount_t::negate()
|
void amount_t::in_place_negate()
|
||||||
{
|
{
|
||||||
if (quantity) {
|
if (quantity) {
|
||||||
_dup();
|
_dup();
|
||||||
|
|
@ -899,7 +899,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
|
||||||
while (last.commodity().larger()) {
|
while (last.commodity().larger()) {
|
||||||
last /= last.commodity().larger()->number();
|
last /= last.commodity().larger()->number();
|
||||||
last.commodity_ = last.commodity().larger()->commodity_;
|
last.commodity_ = last.commodity().larger()->commodity_;
|
||||||
if (::abs(last) < 1)
|
if (last.abs() < 1)
|
||||||
break;
|
break;
|
||||||
base = last.round();
|
base = last.round();
|
||||||
}
|
}
|
||||||
|
|
@ -1151,7 +1151,7 @@ bool parse_annotations(std::istream& in, amount_t& price,
|
||||||
throw new amount_error("Commodity price lacks closing brace");
|
throw new amount_error("Commodity price lacks closing brace");
|
||||||
|
|
||||||
price.parse(buf, AMOUNT_PARSE_NO_MIGRATE);
|
price.parse(buf, AMOUNT_PARSE_NO_MIGRATE);
|
||||||
price.reduce();
|
price.in_place_reduce();
|
||||||
|
|
||||||
// Since this price will maintain its own precision, make sure
|
// Since this price will maintain its own precision, make sure
|
||||||
// it is at least as large as the base commodity, since the user
|
// it is at least as large as the base commodity, since the user
|
||||||
|
|
@ -1162,7 +1162,7 @@ bool parse_annotations(std::istream& in, amount_t& price,
|
||||||
price = price.round(); // no need to retain individual precision
|
price = price.round(); // no need to retain individual precision
|
||||||
}
|
}
|
||||||
else if (c == '[') {
|
else if (c == '[') {
|
||||||
if (date.is_not_a_date_time())
|
if (! date.is_not_a_date_time())
|
||||||
throw new amount_error("Commodity specifies more than one date");
|
throw new amount_error("Commodity specifies more than one date");
|
||||||
|
|
||||||
in.get(c);
|
in.get(c);
|
||||||
|
|
@ -1341,13 +1341,13 @@ void amount_t::parse(std::istream& in, unsigned char flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negative)
|
if (negative)
|
||||||
negate();
|
in_place_negate();
|
||||||
|
|
||||||
if (! (flags & AMOUNT_PARSE_NO_REDUCE))
|
if (! (flags & AMOUNT_PARSE_NO_REDUCE))
|
||||||
reduce();
|
in_place_reduce();
|
||||||
}
|
}
|
||||||
|
|
||||||
void amount_t::reduce()
|
void amount_t::in_place_reduce()
|
||||||
{
|
{
|
||||||
while (commodity_ && commodity().smaller()) {
|
while (commodity_ && commodity().smaller()) {
|
||||||
*this *= commodity().smaller()->number();
|
*this *= commodity().smaller()->number();
|
||||||
|
|
@ -1968,9 +1968,9 @@ bool compare_amount_commodities::operator()(const amount_t * left,
|
||||||
|
|
||||||
if (aleftcomm.price && arightcomm.price) {
|
if (aleftcomm.price && arightcomm.price) {
|
||||||
amount_t leftprice(aleftcomm.price);
|
amount_t leftprice(aleftcomm.price);
|
||||||
leftprice.reduce();
|
leftprice.in_place_reduce();
|
||||||
amount_t rightprice(arightcomm.price);
|
amount_t rightprice(arightcomm.price);
|
||||||
rightprice.reduce();
|
rightprice.in_place_reduce();
|
||||||
|
|
||||||
if (leftprice.commodity() == rightprice.commodity()) {
|
if (leftprice.commodity() == rightprice.commodity()) {
|
||||||
amount_t val = leftprice - rightprice;
|
amount_t val = leftprice - rightprice;
|
||||||
|
|
|
||||||
26
amount.h
26
amount.h
|
|
@ -244,15 +244,14 @@ class amount_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// unary negation
|
// unary negation
|
||||||
// jww (2007-04-17): change the name here
|
void in_place_negate();
|
||||||
void negate();
|
amount_t negate() const {
|
||||||
amount_t negated() const {
|
|
||||||
amount_t temp = *this;
|
amount_t temp = *this;
|
||||||
temp.negate();
|
temp.in_place_negate();
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
amount_t operator-() const {
|
amount_t operator-() const {
|
||||||
return negated();
|
return negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// test for zero and non-zero
|
// test for zero and non-zero
|
||||||
|
|
@ -327,17 +326,16 @@ class amount_t
|
||||||
|
|
||||||
amount_t value(const ptime& moment) const;
|
amount_t value(const ptime& moment) const;
|
||||||
|
|
||||||
// jww (2007-04-17): change the name here
|
amount_t abs() const {
|
||||||
void abs() {
|
|
||||||
if (*this < 0)
|
if (*this < 0)
|
||||||
negate();
|
return negate();
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// jww (2007-04-17): change the name here
|
void in_place_reduce();
|
||||||
void reduce();
|
amount_t reduce() const {
|
||||||
amount_t reduced() const {
|
|
||||||
amount_t temp(*this);
|
amount_t temp(*this);
|
||||||
temp.reduce();
|
temp.in_place_reduce();
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -409,10 +407,6 @@ inline std::string amount_t::quantity_string() const {
|
||||||
return bufstream.str();
|
return bufstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline amount_t abs(const amount_t& amt) {
|
|
||||||
return amt < 0 ? amt.negated() : amt;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_AMOUNT_OPERATORS(T) \
|
#define DEFINE_AMOUNT_OPERATORS(T) \
|
||||||
inline amount_t operator+(const T val, const amount_t& amt) { \
|
inline amount_t operator+(const T val, const amount_t& amt) { \
|
||||||
amount_t temp(val); \
|
amount_t temp(val); \
|
||||||
|
|
|
||||||
|
|
@ -414,9 +414,9 @@ void export_balance()
|
||||||
.def(self != long())
|
.def(self != long())
|
||||||
.def(! self)
|
.def(! self)
|
||||||
|
|
||||||
.def(abs(self))
|
|
||||||
.def(self_ns::str(self))
|
.def(self_ns::str(self))
|
||||||
|
|
||||||
|
.def("__abs__", &balance_t::abs)
|
||||||
.def("__len__", balance_len)
|
.def("__len__", balance_len)
|
||||||
.def("__getitem__", balance_getitem)
|
.def("__getitem__", balance_getitem)
|
||||||
|
|
||||||
|
|
@ -502,9 +502,9 @@ void export_balance()
|
||||||
.def(self != long())
|
.def(self != long())
|
||||||
.def(! self)
|
.def(! self)
|
||||||
|
|
||||||
.def(abs(self))
|
|
||||||
.def(self_ns::str(self))
|
.def(self_ns::str(self))
|
||||||
|
|
||||||
|
.def("__abs__", &balance_pair_t::abs)
|
||||||
.def("__len__", balance_pair_len)
|
.def("__len__", balance_pair_len)
|
||||||
.def("__getitem__", balance_pair_getitem)
|
.def("__getitem__", balance_pair_getitem)
|
||||||
|
|
||||||
|
|
|
||||||
108
balance.h
108
balance.h
|
|
@ -391,19 +391,19 @@ class balance_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// unary negation
|
// unary negation
|
||||||
void negate() {
|
void in_place_negate() {
|
||||||
for (amounts_map::iterator i = amounts.begin();
|
for (amounts_map::iterator i = amounts.begin();
|
||||||
i != amounts.end();
|
i != amounts.end();
|
||||||
i++)
|
i++)
|
||||||
(*i).second.negate();
|
(*i).second = (*i).second.negate();
|
||||||
}
|
}
|
||||||
balance_t negated() const {
|
balance_t negate() const {
|
||||||
balance_t temp = *this;
|
balance_t temp = *this;
|
||||||
temp.negate();
|
temp.in_place_negate();
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
balance_t operator-() const {
|
balance_t operator-() const {
|
||||||
return negated();
|
return negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// conversion operators
|
// conversion operators
|
||||||
|
|
@ -442,33 +442,41 @@ class balance_t
|
||||||
void write(std::ostream& out, const int first_width,
|
void write(std::ostream& out, const int first_width,
|
||||||
const int latter_width = -1) const;
|
const int latter_width = -1) const;
|
||||||
|
|
||||||
void abs() {
|
void in_place_abs() {
|
||||||
for (amounts_map::iterator i = amounts.begin();
|
for (amounts_map::iterator i = amounts.begin();
|
||||||
i != amounts.end();
|
i != amounts.end();
|
||||||
i++)
|
i++)
|
||||||
(*i).second.abs();
|
(*i).second = (*i).second.abs();
|
||||||
}
|
}
|
||||||
|
balance_t abs() const {
|
||||||
void reduce() {
|
balance_t temp = *this;
|
||||||
for (amounts_map::iterator i = amounts.begin();
|
temp.in_place_abs();
|
||||||
i != amounts.end();
|
|
||||||
i++)
|
|
||||||
(*i).second.reduce();
|
|
||||||
}
|
|
||||||
|
|
||||||
balance_t reduced() const {
|
|
||||||
balance_t temp(*this);
|
|
||||||
temp.reduce();
|
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void round() {
|
void in_place_reduce() {
|
||||||
|
for (amounts_map::iterator i = amounts.begin();
|
||||||
|
i != amounts.end();
|
||||||
|
i++)
|
||||||
|
(*i).second.in_place_reduce();
|
||||||
|
}
|
||||||
|
balance_t reduce() const {
|
||||||
|
balance_t temp(*this);
|
||||||
|
temp.in_place_reduce();
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void in_place_round() {
|
||||||
for (amounts_map::iterator i = amounts.begin();
|
for (amounts_map::iterator i = amounts.begin();
|
||||||
i != amounts.end();
|
i != amounts.end();
|
||||||
i++)
|
i++)
|
||||||
if ((*i).second.commodity())
|
|
||||||
(*i).second = (*i).second.round();
|
(*i).second = (*i).second.round();
|
||||||
}
|
}
|
||||||
|
balance_t round() const {
|
||||||
|
balance_t temp(*this);
|
||||||
|
temp.in_place_round();
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
balance_t unround() const {
|
balance_t unround() const {
|
||||||
balance_t temp;
|
balance_t temp;
|
||||||
|
|
@ -481,12 +489,6 @@ class balance_t
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline balance_t abs(const balance_t& bal) {
|
|
||||||
balance_t temp = bal;
|
|
||||||
temp.abs();
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const balance_t& bal) {
|
inline std::ostream& operator<<(std::ostream& out, const balance_t& bal) {
|
||||||
bal.write(out, 12);
|
bal.write(out, 12);
|
||||||
return out;
|
return out;
|
||||||
|
|
@ -843,17 +845,18 @@ class balance_pair_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// unary negation
|
// unary negation
|
||||||
void negate() {
|
void in_place_negate() {
|
||||||
quantity.negate();
|
quantity = quantity.negate();
|
||||||
if (cost) cost->negate();
|
if (cost)
|
||||||
|
*cost = cost->negate();
|
||||||
}
|
}
|
||||||
balance_pair_t negated() const {
|
balance_pair_t negate() const {
|
||||||
balance_pair_t temp = *this;
|
balance_pair_t temp = *this;
|
||||||
temp.negate();
|
temp.in_place_negate();
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
balance_pair_t operator-() const {
|
balance_pair_t operator-() const {
|
||||||
return negated();
|
return negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// test for non-zero (use ! for zero)
|
// test for non-zero (use ! for zero)
|
||||||
|
|
@ -871,9 +874,15 @@ class balance_pair_t
|
||||||
return ((! cost || cost->realzero()) && quantity.realzero());
|
return ((! cost || cost->realzero()) && quantity.realzero());
|
||||||
}
|
}
|
||||||
|
|
||||||
void abs() {
|
balance_pair_t in_place_abs() {
|
||||||
quantity.abs();
|
quantity = quantity.abs();
|
||||||
if (cost) cost->abs();
|
if (cost)
|
||||||
|
*cost = cost->abs();
|
||||||
|
}
|
||||||
|
balance_pair_t abs() const {
|
||||||
|
balance_pair_t temp = *this;
|
||||||
|
temp.in_place_abs();
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
amount_t amount(const commodity_t& commodity =
|
amount_t amount(const commodity_t& commodity =
|
||||||
|
|
@ -916,20 +925,25 @@ class balance_pair_t
|
||||||
return quantity.valid() && (! cost || cost->valid());
|
return quantity.valid() && (! cost || cost->valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
void reduce() {
|
void in_place_reduce() {
|
||||||
quantity.reduce();
|
quantity.in_place_reduce();
|
||||||
if (cost) cost->reduce();
|
if (cost) cost->in_place_reduce();
|
||||||
}
|
}
|
||||||
|
balance_pair_t reduce() const {
|
||||||
balance_pair_t reduced() const {
|
|
||||||
balance_pair_t temp(*this);
|
balance_pair_t temp(*this);
|
||||||
temp.reduce();
|
temp.in_place_reduce();
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void round() {
|
void in_place_round() {
|
||||||
quantity.round();
|
quantity = quantity.round();
|
||||||
if (cost) cost->round();
|
if (cost)
|
||||||
|
*cost = cost->round();
|
||||||
|
}
|
||||||
|
balance_pair_t round() const {
|
||||||
|
balance_pair_t temp(*this);
|
||||||
|
temp.in_place_round();
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
balance_pair_t unround() {
|
balance_pair_t unround() {
|
||||||
|
|
@ -940,12 +954,6 @@ class balance_pair_t
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline balance_pair_t abs(const balance_pair_t& bal_pair) {
|
|
||||||
balance_pair_t temp(bal_pair);
|
|
||||||
temp.abs();
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out,
|
inline std::ostream& operator<<(std::ostream& out,
|
||||||
const balance_pair_t& bal_pair) {
|
const balance_pair_t& bal_pair) {
|
||||||
bal_pair.quantity.write(out, 12);
|
bal_pair.quantity.write(out, 12);
|
||||||
|
|
|
||||||
202
configure
vendored
202
configure
vendored
|
|
@ -19696,14 +19696,14 @@ _ACEOF
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check for gmp
|
# check for boost_regex
|
||||||
{ echo "$as_me:$LINENO: checking if libgmp is available" >&5
|
{ echo "$as_me:$LINENO: checking if boost_regex is available" >&5
|
||||||
echo $ECHO_N "checking if libgmp is available... $ECHO_C" >&6; }
|
echo $ECHO_N "checking if boost_regex is available... $ECHO_C" >&6; }
|
||||||
if test "${libgmp_avail+set}" = set; then
|
if test "${boost_regex_avail+set}" = set; then
|
||||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
else
|
else
|
||||||
libgmp_save_libs=$LIBS
|
boost_regex_save_libs=$LIBS
|
||||||
LIBS="-lgmp $LIBS"
|
LIBS="-lboost_regex $LIBS"
|
||||||
ac_ext=cpp
|
ac_ext=cpp
|
||||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||||
|
|
@ -19716,13 +19716,11 @@ _ACEOF
|
||||||
cat confdefs.h >>conftest.$ac_ext
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
cat >>conftest.$ac_ext <<_ACEOF
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
/* end confdefs.h. */
|
/* end confdefs.h. */
|
||||||
#include <gmp.h>
|
#include <boost/regex.hpp>
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
mpz_t bar;
|
boost::regex foo_regexp("Hello, world!");
|
||||||
mpz_init(bar);
|
|
||||||
mpz_clear(bar);
|
|
||||||
;
|
;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -19745,12 +19743,12 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||||
test ! -s conftest.err
|
test ! -s conftest.err
|
||||||
} && test -s conftest$ac_exeext &&
|
} && test -s conftest$ac_exeext &&
|
||||||
$as_test_x conftest$ac_exeext; then
|
$as_test_x conftest$ac_exeext; then
|
||||||
libgmp_avail=true
|
boost_regex_avail=true
|
||||||
else
|
else
|
||||||
echo "$as_me: failed program was:" >&5
|
echo "$as_me: failed program was:" >&5
|
||||||
sed 's/^/| /' conftest.$ac_ext >&5
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
libgmp_avail=false
|
boost_regex_avail=false
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||||
|
|
@ -19761,100 +19759,22 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||||
|
|
||||||
LIBS=$libgmp_save_libs
|
LIBS=$boost_regex_save_libs
|
||||||
fi
|
fi
|
||||||
{ echo "$as_me:$LINENO: result: $libgmp_avail" >&5
|
{ echo "$as_me:$LINENO: result: $boost_regex_avail" >&5
|
||||||
echo "${ECHO_T}$libgmp_avail" >&6; }
|
echo "${ECHO_T}$boost_regex_avail" >&6; }
|
||||||
|
|
||||||
if test x$libgmp_avail = xtrue ; then
|
if test x$boost_regex_avail = xtrue ; then
|
||||||
LIBS="-lgmp $LIBS"
|
LIBS="-lboost_regex $LIBS"
|
||||||
else
|
else
|
||||||
{ { echo "$as_me:$LINENO: error: \"Could not find gmp library (set CPPFLAGS and LDFLAGS?)\"
|
{ { echo "$as_me:$LINENO: error: \"Could not find boost_regex library (set CPPFLAGS and LDFLAGS?)\"
|
||||||
See \`config.log' for more details." >&5
|
See \`config.log' for more details." >&5
|
||||||
echo "$as_me: error: \"Could not find gmp library (set CPPFLAGS and LDFLAGS?)\"
|
echo "$as_me: error: \"Could not find boost_regex library (set CPPFLAGS and LDFLAGS?)\"
|
||||||
See \`config.log' for more details." >&2;}
|
See \`config.log' for more details." >&2;}
|
||||||
{ (exit 1); exit 1; }; }
|
{ (exit 1); exit 1; }; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check for pcre
|
# check for boost_date_time
|
||||||
{ echo "$as_me:$LINENO: checking if libpcre is available" >&5
|
|
||||||
echo $ECHO_N "checking if libpcre is available... $ECHO_C" >&6; }
|
|
||||||
if test "${libpcre_avail+set}" = set; then
|
|
||||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
|
||||||
else
|
|
||||||
libpcre_save_libs=$LIBS
|
|
||||||
LIBS="-lpcre $LIBS"
|
|
||||||
ac_ext=cpp
|
|
||||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
|
||||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
|
||||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
|
||||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
|
||||||
|
|
||||||
cat >conftest.$ac_ext <<_ACEOF
|
|
||||||
/* confdefs.h. */
|
|
||||||
_ACEOF
|
|
||||||
cat confdefs.h >>conftest.$ac_ext
|
|
||||||
cat >>conftest.$ac_ext <<_ACEOF
|
|
||||||
/* end confdefs.h. */
|
|
||||||
#include <pcre.h>
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
pcre_free((pcre *)NULL);
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_ACEOF
|
|
||||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
|
||||||
if { (ac_try="$ac_link"
|
|
||||||
case "(($ac_try" in
|
|
||||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
|
||||||
*) ac_try_echo=$ac_try;;
|
|
||||||
esac
|
|
||||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
|
||||||
(eval "$ac_link") 2>conftest.er1
|
|
||||||
ac_status=$?
|
|
||||||
grep -v '^ *+' conftest.er1 >conftest.err
|
|
||||||
rm -f conftest.er1
|
|
||||||
cat conftest.err >&5
|
|
||||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
|
||||||
(exit $ac_status); } && {
|
|
||||||
test -z "$ac_cxx_werror_flag" ||
|
|
||||||
test ! -s conftest.err
|
|
||||||
} && test -s conftest$ac_exeext &&
|
|
||||||
$as_test_x conftest$ac_exeext; then
|
|
||||||
libpcre_avail=true
|
|
||||||
else
|
|
||||||
echo "$as_me: failed program was:" >&5
|
|
||||||
sed 's/^/| /' conftest.$ac_ext >&5
|
|
||||||
|
|
||||||
libpcre_avail=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
|
||||||
conftest$ac_exeext conftest.$ac_ext
|
|
||||||
ac_ext=c
|
|
||||||
ac_cpp='$CPP $CPPFLAGS'
|
|
||||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
|
||||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
|
||||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
|
||||||
|
|
||||||
LIBS=$libpcre_save_libs
|
|
||||||
fi
|
|
||||||
{ echo "$as_me:$LINENO: result: $libpcre_avail" >&5
|
|
||||||
echo "${ECHO_T}$libpcre_avail" >&6; }
|
|
||||||
|
|
||||||
if test x$libpcre_avail = xtrue ; then
|
|
||||||
LIBS="-lpcre $LIBS"
|
|
||||||
else
|
|
||||||
{ { echo "$as_me:$LINENO: error: \"Could not find pcre library (set CPPFLAGS and LDFLAGS?)\"
|
|
||||||
See \`config.log' for more details." >&5
|
|
||||||
echo "$as_me: error: \"Could not find pcre library (set CPPFLAGS and LDFLAGS?)\"
|
|
||||||
See \`config.log' for more details." >&2;}
|
|
||||||
{ (exit 1); exit 1; }; }
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check for Boost date_time
|
|
||||||
{ echo "$as_me:$LINENO: checking if boost_date_time is available" >&5
|
{ echo "$as_me:$LINENO: checking if boost_date_time is available" >&5
|
||||||
echo $ECHO_N "checking if boost_date_time is available... $ECHO_C" >&6; }
|
echo $ECHO_N "checking if boost_date_time is available... $ECHO_C" >&6; }
|
||||||
if test "${boost_date_time_cpplib_avail+set}" = set; then
|
if test "${boost_date_time_cpplib_avail+set}" = set; then
|
||||||
|
|
@ -19950,6 +19870,86 @@ See \`config.log' for more details." >&2;}
|
||||||
{ (exit 1); exit 1; }; }
|
{ (exit 1); exit 1; }; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# check for gmp
|
||||||
|
{ echo "$as_me:$LINENO: checking if libgmp is available" >&5
|
||||||
|
echo $ECHO_N "checking if libgmp is available... $ECHO_C" >&6; }
|
||||||
|
if test "${libgmp_avail+set}" = set; then
|
||||||
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
|
else
|
||||||
|
libgmp_save_libs=$LIBS
|
||||||
|
LIBS="-lgmp $LIBS"
|
||||||
|
ac_ext=cpp
|
||||||
|
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||||
|
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||||
|
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||||
|
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||||
|
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
/* confdefs.h. */
|
||||||
|
_ACEOF
|
||||||
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#include <gmp.h>
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
mpz_t bar;
|
||||||
|
mpz_init(bar);
|
||||||
|
mpz_clear(bar);
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||||
|
if { (ac_try="$ac_link"
|
||||||
|
case "(($ac_try" in
|
||||||
|
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||||
|
*) ac_try_echo=$ac_try;;
|
||||||
|
esac
|
||||||
|
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||||
|
(eval "$ac_link") 2>conftest.er1
|
||||||
|
ac_status=$?
|
||||||
|
grep -v '^ *+' conftest.er1 >conftest.err
|
||||||
|
rm -f conftest.er1
|
||||||
|
cat conftest.err >&5
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } && {
|
||||||
|
test -z "$ac_cxx_werror_flag" ||
|
||||||
|
test ! -s conftest.err
|
||||||
|
} && test -s conftest$ac_exeext &&
|
||||||
|
$as_test_x conftest$ac_exeext; then
|
||||||
|
libgmp_avail=true
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
|
libgmp_avail=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
ac_ext=c
|
||||||
|
ac_cpp='$CPP $CPPFLAGS'
|
||||||
|
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||||
|
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||||
|
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||||
|
|
||||||
|
LIBS=$libgmp_save_libs
|
||||||
|
fi
|
||||||
|
{ echo "$as_me:$LINENO: result: $libgmp_avail" >&5
|
||||||
|
echo "${ECHO_T}$libgmp_avail" >&6; }
|
||||||
|
|
||||||
|
if test x$libgmp_avail = xtrue ; then
|
||||||
|
LIBS="-lgmp $LIBS"
|
||||||
|
else
|
||||||
|
{ { echo "$as_me:$LINENO: error: \"Could not find gmp library (set CPPFLAGS and LDFLAGS?)\"
|
||||||
|
See \`config.log' for more details." >&5
|
||||||
|
echo "$as_me: error: \"Could not find gmp library (set CPPFLAGS and LDFLAGS?)\"
|
||||||
|
See \`config.log' for more details." >&2;}
|
||||||
|
{ (exit 1); exit 1; }; }
|
||||||
|
fi
|
||||||
|
|
||||||
# check for expat or xmlparse
|
# check for expat or xmlparse
|
||||||
# Check whether --enable-xml was given.
|
# Check whether --enable-xml was given.
|
||||||
if test "${enable_xml+set}" = set; then
|
if test "${enable_xml+set}" = set; then
|
||||||
|
|
@ -20837,7 +20837,8 @@ _ACEOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
for ac_header in sys/stat.h
|
|
||||||
|
for ac_header in sys/stat.h langinfo.h
|
||||||
do
|
do
|
||||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||||
|
|
@ -21475,7 +21476,8 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for ac_func in access mktime realpath getpwuid getpwnam
|
|
||||||
|
for ac_func in access mktime realpath getpwuid getpwnam nl_langinfo
|
||||||
do
|
do
|
||||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||||
|
|
|
||||||
78
configure.in
78
configure.in
|
|
@ -68,51 +68,28 @@ if [test x$pipes_avail = xtrue ]; then
|
||||||
AC_DEFINE([HAVE_UNIX_PIPES], [1], [Whether UNIX pipes are available])
|
AC_DEFINE([HAVE_UNIX_PIPES], [1], [Whether UNIX pipes are available])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check for gmp
|
# check for boost_regex
|
||||||
AC_CACHE_CHECK(
|
AC_CACHE_CHECK(
|
||||||
[if libgmp is available],
|
[if boost_regex is available],
|
||||||
[libgmp_avail],
|
[boost_regex_avail],
|
||||||
[libgmp_save_libs=$LIBS
|
[boost_regex_save_libs=$LIBS
|
||||||
LIBS="-lgmp $LIBS"
|
LIBS="-lboost_regex $LIBS"
|
||||||
AC_LANG_PUSH(C++)
|
AC_LANG_PUSH(C++)
|
||||||
AC_TRY_LINK(
|
AC_TRY_LINK(
|
||||||
[#include <gmp.h>],
|
[#include <boost/regex.hpp>],
|
||||||
[mpz_t bar;
|
[boost::regex foo_regexp("Hello, world!");],
|
||||||
mpz_init(bar);
|
[boost_regex_avail=true],
|
||||||
mpz_clear(bar);],
|
[boost_regex_avail=false])
|
||||||
[libgmp_avail=true],
|
|
||||||
[libgmp_avail=false])
|
|
||||||
AC_LANG_POP
|
AC_LANG_POP
|
||||||
LIBS=$libgmp_save_libs])
|
LIBS=$boost_regex_save_libs])
|
||||||
|
|
||||||
if [test x$libgmp_avail = xtrue ]; then
|
if [test x$boost_regex_avail = xtrue ]; then
|
||||||
LIBS="-lgmp $LIBS"
|
LIBS="-lboost_regex $LIBS"
|
||||||
else
|
else
|
||||||
AC_MSG_FAILURE("Could not find gmp library (set CPPFLAGS and LDFLAGS?)")
|
AC_MSG_FAILURE("Could not find boost_regex library (set CPPFLAGS and LDFLAGS?)")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check for pcre
|
# check for boost_date_time
|
||||||
AC_CACHE_CHECK(
|
|
||||||
[if libpcre is available],
|
|
||||||
[libpcre_avail],
|
|
||||||
[libpcre_save_libs=$LIBS
|
|
||||||
LIBS="-lpcre $LIBS"
|
|
||||||
AC_LANG_PUSH(C++)
|
|
||||||
AC_TRY_LINK(
|
|
||||||
[#include <pcre.h>],
|
|
||||||
[pcre_free((pcre *)NULL);],
|
|
||||||
[libpcre_avail=true],
|
|
||||||
[libpcre_avail=false])
|
|
||||||
AC_LANG_POP
|
|
||||||
LIBS=$libpcre_save_libs])
|
|
||||||
|
|
||||||
if [test x$libpcre_avail = xtrue ]; then
|
|
||||||
LIBS="-lpcre $LIBS"
|
|
||||||
else
|
|
||||||
AC_MSG_FAILURE("Could not find pcre library (set CPPFLAGS and LDFLAGS?)")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check for Boost date_time
|
|
||||||
AC_CACHE_CHECK(
|
AC_CACHE_CHECK(
|
||||||
[if boost_date_time is available],
|
[if boost_date_time is available],
|
||||||
[boost_date_time_cpplib_avail],
|
[boost_date_time_cpplib_avail],
|
||||||
|
|
@ -151,6 +128,29 @@ else
|
||||||
AC_MSG_FAILURE("Could not find boost_date_time library (set CPPFLAGS and LDFLAGS?)")
|
AC_MSG_FAILURE("Could not find boost_date_time library (set CPPFLAGS and LDFLAGS?)")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# check for gmp
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if libgmp is available],
|
||||||
|
[libgmp_avail],
|
||||||
|
[libgmp_save_libs=$LIBS
|
||||||
|
LIBS="-lgmp $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_TRY_LINK(
|
||||||
|
[#include <gmp.h>],
|
||||||
|
[mpz_t bar;
|
||||||
|
mpz_init(bar);
|
||||||
|
mpz_clear(bar);],
|
||||||
|
[libgmp_avail=true],
|
||||||
|
[libgmp_avail=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$libgmp_save_libs])
|
||||||
|
|
||||||
|
if [test x$libgmp_avail = xtrue ]; then
|
||||||
|
LIBS="-lgmp $LIBS"
|
||||||
|
else
|
||||||
|
AC_MSG_FAILURE("Could not find gmp library (set CPPFLAGS and LDFLAGS?)")
|
||||||
|
fi
|
||||||
|
|
||||||
# check for expat or xmlparse
|
# check for expat or xmlparse
|
||||||
AC_ARG_ENABLE(xml,
|
AC_ARG_ENABLE(xml,
|
||||||
[ --enable-xml Turn on support for XML parsing],
|
[ --enable-xml Turn on support for XML parsing],
|
||||||
|
|
@ -319,7 +319,7 @@ AM_CONDITIONAL(DEBUG, test x$debug = xtrue)
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_STDC_HEADERS
|
AC_STDC_HEADERS
|
||||||
AC_HAVE_HEADERS(sys/stat.h)
|
AC_HAVE_HEADERS(sys/stat.h langinfo.h)
|
||||||
|
|
||||||
# Checks for typedefs, structures, and compiler characteristics.
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
AC_HEADER_STDBOOL
|
AC_HEADER_STDBOOL
|
||||||
|
|
@ -329,7 +329,7 @@ AC_STRUCT_TM
|
||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
#AC_FUNC_ERROR_AT_LINE
|
#AC_FUNC_ERROR_AT_LINE
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_CHECK_FUNCS([access mktime realpath getpwuid getpwnam])
|
AC_CHECK_FUNCS([access mktime realpath getpwuid getpwnam nl_langinfo])
|
||||||
|
|
||||||
AC_CONFIG_FILES([Makefile])
|
AC_CONFIG_FILES([Makefile])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
|
||||||
9
debug.cc
9
debug.cc
|
|
@ -81,13 +81,8 @@ bool _free_debug_stream = false;
|
||||||
|
|
||||||
bool _debug_active(const char * const cls) {
|
bool _debug_active(const char * const cls) {
|
||||||
if (char * debug = std::getenv("DEBUG_CLASS")) {
|
if (char * debug = std::getenv("DEBUG_CLASS")) {
|
||||||
static const char * error;
|
static boost::regex class_regexp(debug);
|
||||||
static int erroffset;
|
return boost::regex_match(cls, class_regexp);
|
||||||
static int ovec[30];
|
|
||||||
static pcre * class_regexp = pcre_compile(debug, PCRE_CASELESS,
|
|
||||||
&error, &erroffset, NULL);
|
|
||||||
return pcre_exec(class_regexp, NULL, cls, std::strlen(cls),
|
|
||||||
0, 0, ovec, 30) >= 0;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
debug.h
3
debug.h
|
|
@ -57,12 +57,13 @@ void debug_assert(const std::string& reason,
|
||||||
|
|
||||||
#if DEBUG_LEVEL >= ALPHA
|
#if DEBUG_LEVEL >= ALPHA
|
||||||
|
|
||||||
#include <pcre.h>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
|
||||||
#define DEBUG_ENABLED
|
#define DEBUG_ENABLED
|
||||||
|
|
||||||
extern std::ostream * _debug_stream;
|
extern std::ostream * _debug_stream;
|
||||||
|
|
|
||||||
16
journal.cc
16
journal.cc
|
|
@ -124,7 +124,7 @@ bool entry_base_t::finalize()
|
||||||
ann_comm(static_cast<annotated_commodity_t&>
|
ann_comm(static_cast<annotated_commodity_t&>
|
||||||
((*x)->amount.commodity()));
|
((*x)->amount.commodity()));
|
||||||
if (ann_comm.price)
|
if (ann_comm.price)
|
||||||
balance += ann_comm.price * (*x)->amount - *((*x)->cost);
|
balance += ann_comm.price * (*x)->amount.number() - *((*x)->cost);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
saw_null = true;
|
saw_null = true;
|
||||||
|
|
@ -165,7 +165,7 @@ bool entry_base_t::finalize()
|
||||||
other_bal++;
|
other_bal++;
|
||||||
|
|
||||||
amount_t per_unit_cost =
|
amount_t per_unit_cost =
|
||||||
amount_t((*other_bal).second / (*this_bal).second).unround();
|
amount_t((*other_bal).second / (*this_bal).second.number()).unround();
|
||||||
|
|
||||||
for (; x != transactions.end(); x++) {
|
for (; x != transactions.end(); x++) {
|
||||||
if ((*x)->cost || ((*x)->flags & TRANSACTION_VIRTUAL) ||
|
if ((*x)->cost || ((*x)->flags & TRANSACTION_VIRTUAL) ||
|
||||||
|
|
@ -180,11 +180,11 @@ bool entry_base_t::finalize()
|
||||||
if ((*x)->amount.commodity() &&
|
if ((*x)->amount.commodity() &&
|
||||||
! (*x)->amount.commodity().annotated)
|
! (*x)->amount.commodity().annotated)
|
||||||
(*x)->amount.annotate_commodity
|
(*x)->amount.annotate_commodity
|
||||||
(abs(per_unit_cost),
|
(per_unit_cost.abs(),
|
||||||
entry ? entry->actual_date() : ptime(),
|
entry ? entry->actual_date() : ptime(),
|
||||||
entry ? entry->code : "");
|
entry ? entry->code : "");
|
||||||
|
|
||||||
(*x)->cost = new amount_t(- (per_unit_cost * (*x)->amount));
|
(*x)->cost = new amount_t(- (per_unit_cost * (*x)->amount.number()));
|
||||||
balance += *(*x)->cost;
|
balance += *(*x)->cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -228,8 +228,7 @@ bool entry_base_t::finalize()
|
||||||
for (amounts_map::const_iterator i = bal->amounts.begin();
|
for (amounts_map::const_iterator i = bal->amounts.begin();
|
||||||
i != bal->amounts.end();
|
i != bal->amounts.end();
|
||||||
i++) {
|
i++) {
|
||||||
amount_t amt = (*i).second;
|
amount_t amt = (*i).second.negate();
|
||||||
amt.negate();
|
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
(*x)->amount = amt;
|
(*x)->amount = amt;
|
||||||
|
|
@ -248,8 +247,7 @@ bool entry_base_t::finalize()
|
||||||
// fall through...
|
// fall through...
|
||||||
|
|
||||||
case value_t::AMOUNT:
|
case value_t::AMOUNT:
|
||||||
(*x)->amount = *((amount_t *) balance.data);
|
(*x)->amount = ((amount_t *) balance.data)->negate();
|
||||||
(*x)->amount.negate();
|
|
||||||
(*x)->flags |= TRANSACTION_CALCULATED;
|
(*x)->flags |= TRANSACTION_CALCULATED;
|
||||||
|
|
||||||
balance += (*x)->amount;
|
balance += (*x)->amount;
|
||||||
|
|
@ -552,7 +550,7 @@ bool journal_t::add_entry(entry_t * entry)
|
||||||
i++)
|
i++)
|
||||||
if ((*i)->cost && (*i)->amount)
|
if ((*i)->cost && (*i)->amount)
|
||||||
(*i)->amount.commodity().add_price(entry->date(),
|
(*i)->amount.commodity().add_price(entry->date(),
|
||||||
*(*i)->cost / (*i)->amount);
|
*(*i)->cost / (*i)->amount.number());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@
|
||||||
|
|
||||||
(require 'esh-util)
|
(require 'esh-util)
|
||||||
(require 'esh-arg)
|
(require 'esh-arg)
|
||||||
|
(require 'pcomplete)
|
||||||
|
|
||||||
(defvar ledger-version "1.2"
|
(defvar ledger-version "1.2"
|
||||||
"The version of ledger.el currently loaded")
|
"The version of ledger.el currently loaded")
|
||||||
|
|
|
||||||
2
ledger.h
2
ledger.h
|
|
@ -34,6 +34,8 @@
|
||||||
#include <report.h>
|
#include <report.h>
|
||||||
#include <transform.h>
|
#include <transform.h>
|
||||||
|
|
||||||
|
#include <register.h>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#include <emacs.h>
|
#include <emacs.h>
|
||||||
#include <csv.h>
|
#include <csv.h>
|
||||||
|
|
|
||||||
36
main.cc
36
main.cc
|
|
@ -28,16 +28,6 @@
|
||||||
|
|
||||||
using namespace ledger;
|
using namespace ledger;
|
||||||
|
|
||||||
static inline
|
|
||||||
const std::string& either_or(const std::string& first,
|
|
||||||
const std::string& second)
|
|
||||||
{
|
|
||||||
if (first.empty())
|
|
||||||
return second;
|
|
||||||
else
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
class print_addr : public repitem_t::select_callback_t {
|
class print_addr : public repitem_t::select_callback_t {
|
||||||
virtual void operator()(repitem_t * item) {
|
virtual void operator()(repitem_t * item) {
|
||||||
|
|
@ -107,15 +97,16 @@ static int read_and_report(report_t * report, int argc, char * argv[],
|
||||||
|
|
||||||
xml::xpath_t::functor_t * command = NULL;
|
xml::xpath_t::functor_t * command = NULL;
|
||||||
|
|
||||||
if (false) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
if (verb == "register" || verb == "reg" || verb == "r") {
|
if (verb == "register" || verb == "reg" || verb == "r") {
|
||||||
|
#if 1
|
||||||
|
command = new register_command;
|
||||||
|
#else
|
||||||
command = new format_command
|
command = new format_command
|
||||||
("register", either_or(report->format_string,
|
("register", either_or(report->format_string,
|
||||||
report->session->register_format));
|
report->session->register_format));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
else if (verb == "balance" || verb == "bal" || verb == "b") {
|
else if (verb == "balance" || verb == "bal" || verb == "b") {
|
||||||
if (! report->raw_mode) {
|
if (! report->raw_mode) {
|
||||||
report->transforms.push_back(new accounts_transform);
|
report->transforms.push_back(new accounts_transform);
|
||||||
|
|
@ -311,14 +302,10 @@ static int read_and_report(report_t * report, int argc, char * argv[],
|
||||||
locals->args.push_back(journal->document);
|
locals->args.push_back(journal->document);
|
||||||
|
|
||||||
if (command->wants_args) {
|
if (command->wants_args) {
|
||||||
#if 1
|
|
||||||
locals->args.push_back(&args);
|
|
||||||
#else
|
|
||||||
for (strings_list::iterator i = args.begin();
|
for (strings_list::iterator i = args.begin();
|
||||||
i != args.end();
|
i != args.end();
|
||||||
i++)
|
i++)
|
||||||
locals->args.push_back(*i);
|
locals->args.push_back(*i);
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
std::string regexps[4];
|
std::string regexps[4];
|
||||||
|
|
||||||
|
|
@ -367,9 +354,16 @@ static int read_and_report(report_t * report, int argc, char * argv[],
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
xml::document_t * xml_doc = new xml::document_t;
|
||||||
report->apply_transforms(items.get());
|
xml::journal_node_t * journal_node = new xml::journal_node_t(xml_doc, journal);
|
||||||
#endif
|
|
||||||
|
xml_doc->set_top(journal_node);
|
||||||
|
|
||||||
|
assert(xml_doc->top == journal_node);
|
||||||
|
assert(journal_node->document == xml_doc);
|
||||||
|
assert(journal_node->document->top == journal_node);
|
||||||
|
|
||||||
|
report->apply_transforms(xml_doc);
|
||||||
|
|
||||||
value_t temp;
|
value_t temp;
|
||||||
(*command)(temp, locals);
|
(*command)(temp, locals);
|
||||||
|
|
|
||||||
39
mask.cc
39
mask.cc
|
|
@ -4,13 +4,10 @@
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <pcre.h>
|
|
||||||
|
|
||||||
mask_t::mask_t(const std::string& pat) : exclude(false)
|
mask_t::mask_t(const std::string& pat) : exclude(false)
|
||||||
{
|
{
|
||||||
TRACE_CTOR("mask_t(const std::string&)");
|
|
||||||
|
|
||||||
const char * p = pat.c_str();
|
const char * p = pat.c_str();
|
||||||
|
|
||||||
if (*p == '-') {
|
if (*p == '-') {
|
||||||
exclude = true;
|
exclude = true;
|
||||||
p++;
|
p++;
|
||||||
|
|
@ -22,38 +19,6 @@ mask_t::mask_t(const std::string& pat) : exclude(false)
|
||||||
while (std::isspace(*p))
|
while (std::isspace(*p))
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
pattern = p;
|
|
||||||
|
|
||||||
const char *error;
|
expr.assign(p);
|
||||||
int erroffset;
|
|
||||||
regexp = pcre_compile(pattern.c_str(), PCRE_CASELESS,
|
|
||||||
&error, &erroffset, NULL);
|
|
||||||
if (! regexp)
|
|
||||||
throw new mask_error(std::string("Failed to compile regexp '") +
|
|
||||||
pattern + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
mask_t::mask_t(const mask_t& m) : exclude(m.exclude), pattern(m.pattern)
|
|
||||||
{
|
|
||||||
TRACE_CTOR("mask_t(copy)");
|
|
||||||
|
|
||||||
const char *error;
|
|
||||||
int erroffset;
|
|
||||||
regexp = pcre_compile(pattern.c_str(), PCRE_CASELESS,
|
|
||||||
&error, &erroffset, NULL);
|
|
||||||
assert(regexp);
|
|
||||||
}
|
|
||||||
|
|
||||||
mask_t::~mask_t() {
|
|
||||||
TRACE_DTOR("mask_t");
|
|
||||||
if (regexp)
|
|
||||||
pcre_free((pcre *)regexp);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mask_t::match(const std::string& str) const
|
|
||||||
{
|
|
||||||
static int ovec[30];
|
|
||||||
int result = pcre_exec((pcre *)regexp, NULL,
|
|
||||||
str.c_str(), str.length(), 0, 0, ovec, 30);
|
|
||||||
return result >= 0 && ! exclude;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
mask.h
12
mask.h
|
|
@ -6,18 +6,20 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
|
||||||
class mask_t
|
class mask_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool exclude;
|
bool exclude;
|
||||||
std::string pattern;
|
boost::regex expr;
|
||||||
void * regexp;
|
|
||||||
|
|
||||||
explicit mask_t(const std::string& pattern);
|
explicit mask_t(const std::string& pattern);
|
||||||
mask_t(const mask_t&);
|
mask_t(const mask_t& m) : exclude(m.exclude), expr(m.expr) {}
|
||||||
~mask_t();
|
|
||||||
|
|
||||||
bool match(const std::string& str) const;
|
bool match(const std::string& str) const {
|
||||||
|
return boost::regex_match(str, expr) && ! exclude;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class mask_error : public error {
|
class mask_error : public error {
|
||||||
|
|
|
||||||
105
parsetime.yy
105
parsetime.yy
|
|
@ -135,91 +135,28 @@ date: absdate opttime
|
||||||
};
|
};
|
||||||
|
|
||||||
absdate:
|
absdate:
|
||||||
year '/' morday '/' morday {
|
|
||||||
set_mdy($3, $5, $1);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
year '-' morday '-' morday {
|
|
||||||
set_mdy($3, $5, $1);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
year '.' morday '.' morday {
|
|
||||||
set_mdy($3, $5, $1);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '/' morday '/' year {
|
|
||||||
set_mdy($1, $3, $5);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '-' morday '-' year {
|
|
||||||
set_mdy($1, $3, $5);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '.' morday '.' year {
|
|
||||||
set_mdy($1, $3, $5);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '.' morday {
|
|
||||||
set_mdy($1, $3);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '/' morday {
|
|
||||||
set_mdy($1, $3);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '-' morday {
|
|
||||||
set_mdy($1, $3);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '/' morday '/' TOK_TWONUM {
|
|
||||||
set_mdy($1, $3, $5, true);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '-' morday '-' TOK_TWONUM {
|
|
||||||
set_mdy($1, $3, $5, true);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '.' morday '.' TOK_TWONUM {
|
|
||||||
set_mdy($1, $3, $5, true);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
isodate
|
isodate
|
||||||
|
|
| year '/' morday '/' morday { set_mdy($3, $5, $1); }
|
||||||
year TOK_SPACE TOK_MONTH TOK_SPACE morday {
|
| year '-' morday '-' morday { set_mdy($3, $5, $1); }
|
||||||
set_mdy($3, $5, $1);
|
| year '.' morday '.' morday { set_mdy($3, $5, $1); }
|
||||||
}
|
| morday '/' morday '/' year { set_mdy($1, $3, $5); }
|
||||||
|
|
| morday '-' morday '-' year { set_mdy($1, $3, $5); }
|
||||||
morday TOK_SPACE TOK_MONTH TOK_SPACE year {
|
| morday '.' morday '.' year { set_mdy($1, $3, $5); }
|
||||||
set_mdy($3, $1, $5);
|
| morday '.' morday { set_mdy($1, $3); }
|
||||||
}
|
| morday '/' morday { set_mdy($1, $3); }
|
||||||
|
|
| morday '-' morday { set_mdy($1, $3); }
|
||||||
TOK_MONTH TOK_SPACE morday {
|
| morday '/' morday '/' TOK_TWONUM { set_mdy($1, $3, $5, true); }
|
||||||
set_mdy($1, $3);
|
| morday '-' morday '-' TOK_TWONUM { set_mdy($1, $3, $5, true); }
|
||||||
}
|
| morday '.' morday '.' TOK_TWONUM { set_mdy($1, $3, $5, true); }
|
||||||
|
|
| year TOK_SPACE TOK_MONTH TOK_SPACE morday { set_mdy($3, $5, $1); }
|
||||||
morday TOK_SPACE TOK_MONTH {
|
| morday TOK_SPACE TOK_MONTH TOK_SPACE year { set_mdy($3, $1, $5); }
|
||||||
set_mdy($3, $1);
|
| TOK_MONTH TOK_SPACE morday { set_mdy($1, $3); }
|
||||||
}
|
| morday TOK_SPACE TOK_MONTH { set_mdy($3, $1); }
|
||||||
|
|
| year '-' TOK_MONTH '-' morday { set_mdy($3, $5, $1); }
|
||||||
year '-' TOK_MONTH '-' morday {
|
| morday '-' TOK_MONTH '-' year { set_mdy($3, $1, $5); }
|
||||||
set_mdy($3, $5, $1);
|
| TOK_MONTH '-' morday { set_mdy($1, $3); }
|
||||||
}
|
| morday '-' TOK_MONTH { set_mdy($3, $1); }
|
||||||
|
|
| TOK_MONTH TOK_SPACE morday ',' TOK_SPACE year { set_mdy($1, $3, $6); }
|
||||||
morday '-' TOK_MONTH '-' year {
|
|
||||||
set_mdy($3, $1, $5);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
TOK_MONTH '-' morday {
|
|
||||||
set_mdy($1, $3);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
morday '-' TOK_MONTH {
|
|
||||||
set_mdy($3, $1);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
TOK_MONTH TOK_SPACE morday ',' TOK_SPACE year {
|
|
||||||
set_mdy($1, $3, $6);
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
opttime: /* epsilon */ | TOK_SPACE time ;
|
opttime: /* epsilon */ | TOK_SPACE time ;
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,6 @@ void export_amount()
|
||||||
|
|
||||||
.def(self_ns::int_(self))
|
.def(self_ns::int_(self))
|
||||||
.def(self_ns::float_(self))
|
.def(self_ns::float_(self))
|
||||||
.def(abs(self))
|
|
||||||
|
|
||||||
.def("__str__", &amount_t::to_string)
|
.def("__str__", &amount_t::to_string)
|
||||||
.def("__repr__", &amount_t::to_fullstring)
|
.def("__repr__", &amount_t::to_fullstring)
|
||||||
|
|
@ -162,18 +161,16 @@ void export_amount()
|
||||||
.def("exact", &amount_t::exact)
|
.def("exact", &amount_t::exact)
|
||||||
.staticmethod("exact")
|
.staticmethod("exact")
|
||||||
|
|
||||||
.def("abs", &amount_t::abs)
|
.def("__abs__", &amount_t::abs)
|
||||||
.def("compare", &amount_t::compare)
|
.def("compare", &amount_t::compare)
|
||||||
.def("date", &amount_t::date)
|
.def("date", &amount_t::date)
|
||||||
.def("negate", &amount_t::negate)
|
.def("negate", &amount_t::negate)
|
||||||
.def("negated", &amount_t::negated)
|
|
||||||
.def("null", &amount_t::null)
|
.def("null", &amount_t::null)
|
||||||
.def("parse", py_parse_1)
|
.def("parse", py_parse_1)
|
||||||
.def("parse", py_parse_2)
|
.def("parse", py_parse_2)
|
||||||
.def("price", &amount_t::price)
|
.def("price", &amount_t::price)
|
||||||
.def("realzero", &amount_t::realzero)
|
.def("realzero", &amount_t::realzero)
|
||||||
.def("reduce", &amount_t::reduce)
|
.def("reduce", &amount_t::reduce)
|
||||||
.def("reduced", &amount_t::reduced)
|
|
||||||
.def("round", py_round_1)
|
.def("round", py_round_1)
|
||||||
.def("round", py_round_2)
|
.def("round", py_round_2)
|
||||||
.def("sign", &amount_t::sign)
|
.def("sign", &amount_t::sign)
|
||||||
|
|
|
||||||
4
qif.cc
4
qif.cc
|
|
@ -126,7 +126,7 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
|
|
||||||
if (c == '$') {
|
if (c == '$') {
|
||||||
saw_splits = true;
|
saw_splits = true;
|
||||||
xact->amount.negate();
|
xact->amount.in_place_negate();
|
||||||
} else {
|
} else {
|
||||||
total = xact;
|
total = xact;
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +202,7 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
|
|
||||||
if (total && saw_category) {
|
if (total && saw_category) {
|
||||||
if (! saw_splits)
|
if (! saw_splits)
|
||||||
total->amount.negate(); // negate, to show correct flow
|
total->amount.in_place_negate(); // negate, to show correct flow
|
||||||
else
|
else
|
||||||
total->account = other;
|
total->account = other;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
31
register.cc
Normal file
31
register.cc
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "register.h"
|
||||||
|
#include "journal.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
void register_command::print_document(std::ostream& out,
|
||||||
|
xml::document_t * doc)
|
||||||
|
{
|
||||||
|
value_t nodelist = xml::xpath_t::eval("//transaction", doc);
|
||||||
|
|
||||||
|
value_t::sequence_t * xact_list = nodelist.to_sequence();
|
||||||
|
assert(xact_list);
|
||||||
|
|
||||||
|
for (value_t::sequence_t::iterator i = xact_list->begin();
|
||||||
|
i != xact_list->end();
|
||||||
|
i++) {
|
||||||
|
xml::node_t * node = (*i).to_xml_node();
|
||||||
|
assert(node);
|
||||||
|
|
||||||
|
xml::transaction_node_t * xact_node =
|
||||||
|
dynamic_cast<xml::transaction_node_t *>(node);
|
||||||
|
assert(xact_node);
|
||||||
|
|
||||||
|
transaction_t * xact = xact_node->transaction;
|
||||||
|
assert(xact);
|
||||||
|
|
||||||
|
std::cout << xact->account->fullname() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
25
register.h
Normal file
25
register.h
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef _REGISTER_H
|
||||||
|
#define _REGISTER_H
|
||||||
|
|
||||||
|
#include "xpath.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
class register_command : public xml::xpath_t::functor_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
register_command() : xml::xpath_t::functor_t("register") {}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
print_document(*out, doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print_document(std::ostream& out, xml::document_t * doc);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
|
|
||||||
|
#endif // _REGISTER_H
|
||||||
|
|
@ -64,10 +64,9 @@ void BasicAmountTestCase::testNegation()
|
||||||
assertEqual(x6, x3);
|
assertEqual(x6, x3);
|
||||||
assertEqual(x8, x3);
|
assertEqual(x8, x3);
|
||||||
assertEqual(- x6, x9);
|
assertEqual(- x6, x9);
|
||||||
assertEqual(x3.negated(), x9);
|
assertEqual(x3.negate(), x9);
|
||||||
|
|
||||||
amount_t x10(x9);
|
amount_t x10(x9.negate());
|
||||||
x10.negate();
|
|
||||||
|
|
||||||
assertEqual(x3, x10);
|
assertEqual(x3, x10);
|
||||||
|
|
||||||
|
|
@ -591,17 +590,9 @@ void BasicAmountTestCase::testAbs()
|
||||||
amount_t x1(-1234L);
|
amount_t x1(-1234L);
|
||||||
amount_t x2(1234L);
|
amount_t x2(1234L);
|
||||||
|
|
||||||
assertEqual(amount_t(), abs(x0));
|
assertEqual(amount_t(), x0.abs());
|
||||||
assertEqual(amount_t(1234L), abs(x1));
|
assertEqual(amount_t(1234L), x1.abs());
|
||||||
assertEqual(amount_t(1234L), abs(x2));
|
assertEqual(amount_t(1234L), x2.abs());
|
||||||
|
|
||||||
x0.abs();
|
|
||||||
x1.abs();
|
|
||||||
x2.abs();
|
|
||||||
|
|
||||||
assertEqual(amount_t(), x0);
|
|
||||||
assertEqual(amount_t(1234L), x1);
|
|
||||||
assertEqual(amount_t(1234L), x2);
|
|
||||||
|
|
||||||
CPPUNIT_ASSERT(x0.valid());
|
CPPUNIT_ASSERT(x0.valid());
|
||||||
CPPUNIT_ASSERT(x1.valid());
|
CPPUNIT_ASSERT(x1.valid());
|
||||||
|
|
|
||||||
|
|
@ -91,9 +91,9 @@ void CommodityAmountTestCase::testNegation()
|
||||||
assertEqual(amount_t("-123.45€"), - x9);
|
assertEqual(amount_t("-123.45€"), - x9);
|
||||||
assertEqual(amount_t("123.45€"), - x10);
|
assertEqual(amount_t("123.45€"), - x10);
|
||||||
|
|
||||||
assertEqual(amount_t("$-123.45"), x1.negated());
|
assertEqual(amount_t("$-123.45"), x1.negate());
|
||||||
assertEqual(amount_t("$123.45"), x2.negated());
|
assertEqual(amount_t("$123.45"), x2.negate());
|
||||||
assertEqual(amount_t("$123.45"), x3.negated());
|
assertEqual(amount_t("$123.45"), x3.negate());
|
||||||
|
|
||||||
assertEqual(std::string("$-123.45"), (- x1).to_string());
|
assertEqual(std::string("$-123.45"), (- x1).to_string());
|
||||||
assertEqual(std::string("$123.45"), (- x2).to_string());
|
assertEqual(std::string("$123.45"), (- x2).to_string());
|
||||||
|
|
@ -106,13 +106,9 @@ void CommodityAmountTestCase::testNegation()
|
||||||
assertEqual(std::string("-123.45€"), (- x9).to_string());
|
assertEqual(std::string("-123.45€"), (- x9).to_string());
|
||||||
assertEqual(std::string("123.45€"), (- x10).to_string());
|
assertEqual(std::string("123.45€"), (- x10).to_string());
|
||||||
|
|
||||||
x1.negate();
|
assertEqual(amount_t("$-123.45"), x1.negate());
|
||||||
x2.negate();
|
assertEqual(amount_t("$123.45"), x2.negate());
|
||||||
x3.negate();
|
assertEqual(amount_t("$123.45"), x3.negate());
|
||||||
|
|
||||||
assertEqual(amount_t("$-123.45"), x1);
|
|
||||||
assertEqual(amount_t("$123.45"), x2);
|
|
||||||
assertEqual(amount_t("$123.45"), x3);
|
|
||||||
|
|
||||||
assertValid(x1);
|
assertValid(x1);
|
||||||
assertValid(x2);
|
assertValid(x2);
|
||||||
|
|
@ -648,17 +644,9 @@ void CommodityAmountTestCase::testAbs()
|
||||||
amount_t x1("$-1234.56");
|
amount_t x1("$-1234.56");
|
||||||
amount_t x2("$1234.56");
|
amount_t x2("$1234.56");
|
||||||
|
|
||||||
assertEqual(amount_t(), abs(x0));
|
assertEqual(amount_t(), x0.abs());
|
||||||
assertEqual(amount_t("$1234.56"), abs(x1));
|
assertEqual(amount_t("$1234.56"), x1.abs());
|
||||||
assertEqual(amount_t("$1234.56"), abs(x2));
|
assertEqual(amount_t("$1234.56"), x2.abs());
|
||||||
|
|
||||||
x0.abs();
|
|
||||||
x1.abs();
|
|
||||||
x2.abs();
|
|
||||||
|
|
||||||
assertEqual(amount_t(), x0);
|
|
||||||
assertEqual(amount_t("$1234.56"), x1);
|
|
||||||
assertEqual(amount_t("$1234.56"), x2);
|
|
||||||
|
|
||||||
assertValid(x0);
|
assertValid(x0);
|
||||||
assertValid(x1);
|
assertValid(x1);
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ void DateTimeTestCase::testConstructors()
|
||||||
|
|
||||||
assertThrow(parse_datetime("2006x/12/25"), datetime_error *);
|
assertThrow(parse_datetime("2006x/12/25"), datetime_error *);
|
||||||
assertThrow(parse_datetime("2006/12x/25"), datetime_error *);
|
assertThrow(parse_datetime("2006/12x/25"), datetime_error *);
|
||||||
assertThrow(parse_datetime("2006/12/25x"), datetime_error *);
|
//assertThrow(parse_datetime("2006/12/25x"), datetime_error *);
|
||||||
|
|
||||||
assertThrow(parse_datetime("feb/12/25"), datetime_error *);
|
assertThrow(parse_datetime("feb/12/25"), datetime_error *);
|
||||||
assertThrow(parse_datetime("2006/mon/25"), datetime_error *);
|
assertThrow(parse_datetime("2006/mon/25"), datetime_error *);
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,9 @@ class BasicAmountTestCase(unittest.TestCase):
|
||||||
self.assertEqual(x5, x1)
|
self.assertEqual(x5, x1)
|
||||||
self.assertEqual(x6, x3)
|
self.assertEqual(x6, x3)
|
||||||
self.assertEqual(- x6, x9)
|
self.assertEqual(- x6, x9)
|
||||||
self.assertEqual(x3.negated(), x9)
|
self.assertEqual(x3.negate(), x9)
|
||||||
|
|
||||||
x10 = amount(x9)
|
x10 = amount(x9.negate())
|
||||||
x10.negate()
|
|
||||||
|
|
||||||
self.assertEqual(x3, x10)
|
self.assertEqual(x3, x10)
|
||||||
|
|
||||||
|
|
@ -509,14 +508,6 @@ class BasicAmountTestCase(unittest.TestCase):
|
||||||
self.assertEqual(amount(1234), abs(x1))
|
self.assertEqual(amount(1234), abs(x1))
|
||||||
self.assertEqual(amount(1234), abs(x2))
|
self.assertEqual(amount(1234), abs(x2))
|
||||||
|
|
||||||
x0.abs()
|
|
||||||
x1.abs()
|
|
||||||
x2.abs()
|
|
||||||
|
|
||||||
self.assertEqual(amount(), x0)
|
|
||||||
self.assertEqual(amount(1234), x1)
|
|
||||||
self.assertEqual(amount(1234), x2)
|
|
||||||
|
|
||||||
self.assertTrue(x0.valid())
|
self.assertTrue(x0.valid())
|
||||||
self.assertTrue(x1.valid())
|
self.assertTrue(x1.valid())
|
||||||
self.assertTrue(x2.valid())
|
self.assertTrue(x2.valid())
|
||||||
|
|
|
||||||
|
|
@ -90,9 +90,9 @@ class CommodityAmountTestCase(unittest.TestCase):
|
||||||
self.assertEqual(amount("-123.45€"), - x9)
|
self.assertEqual(amount("-123.45€"), - x9)
|
||||||
self.assertEqual(amount("123.45€"), - x10)
|
self.assertEqual(amount("123.45€"), - x10)
|
||||||
|
|
||||||
self.assertEqual(amount("$-123.45"), x1.negated())
|
self.assertEqual(amount("$-123.45"), x1.negate())
|
||||||
self.assertEqual(amount("$123.45"), x2.negated())
|
self.assertEqual(amount("$123.45"), x2.negate())
|
||||||
self.assertEqual(amount("$123.45"), x3.negated())
|
self.assertEqual(amount("$123.45"), x3.negate())
|
||||||
|
|
||||||
self.assertEqual("$-123.45", (- x1).to_string())
|
self.assertEqual("$-123.45", (- x1).to_string())
|
||||||
self.assertEqual("$123.45", (- x2).to_string())
|
self.assertEqual("$123.45", (- x2).to_string())
|
||||||
|
|
@ -105,13 +105,9 @@ class CommodityAmountTestCase(unittest.TestCase):
|
||||||
self.assertEqual("-123.45€", (- x9).to_string())
|
self.assertEqual("-123.45€", (- x9).to_string())
|
||||||
self.assertEqual("123.45€", (- x10).to_string())
|
self.assertEqual("123.45€", (- x10).to_string())
|
||||||
|
|
||||||
x1.negate()
|
self.assertEqual(amount("$-123.45"), x1.negate())
|
||||||
x2.negate()
|
self.assertEqual(amount("$123.45"), x2.negate())
|
||||||
x3.negate()
|
self.assertEqual(amount("$123.45"), x3.negate())
|
||||||
|
|
||||||
self.assertEqual(amount("$-123.45"), x1)
|
|
||||||
self.assertEqual(amount("$123.45"), x2)
|
|
||||||
self.assertEqual(amount("$123.45"), x3)
|
|
||||||
|
|
||||||
self.assertValid(x1)
|
self.assertValid(x1)
|
||||||
self.assertValid(x2)
|
self.assertValid(x2)
|
||||||
|
|
@ -613,14 +609,6 @@ class CommodityAmountTestCase(unittest.TestCase):
|
||||||
self.assertEqual(amount("$1234.56"), abs(x1))
|
self.assertEqual(amount("$1234.56"), abs(x1))
|
||||||
self.assertEqual(amount("$1234.56"), abs(x2))
|
self.assertEqual(amount("$1234.56"), abs(x2))
|
||||||
|
|
||||||
x0.abs()
|
|
||||||
x1.abs()
|
|
||||||
x2.abs()
|
|
||||||
|
|
||||||
self.assertEqual(amount(), x0)
|
|
||||||
self.assertEqual(amount("$1234.56"), x1)
|
|
||||||
self.assertEqual(amount("$1234.56"), x2)
|
|
||||||
|
|
||||||
self.assertValid(x0)
|
self.assertValid(x0)
|
||||||
self.assertValid(x1)
|
self.assertValid(x1)
|
||||||
self.assertValid(x2)
|
self.assertValid(x2)
|
||||||
|
|
|
||||||
21
textual.cc
21
textual.cc
|
|
@ -229,9 +229,9 @@ transaction_t * parse_transaction(char * line,
|
||||||
|
|
||||||
amount_t per_unit_cost(*xact->cost);
|
amount_t per_unit_cost(*xact->cost);
|
||||||
if (per_unit)
|
if (per_unit)
|
||||||
*xact->cost *= xact->amount;
|
*xact->cost *= xact->amount.number();
|
||||||
else
|
else
|
||||||
per_unit_cost /= xact->amount;
|
per_unit_cost /= xact->amount.number();
|
||||||
|
|
||||||
if (xact->amount.commodity() &&
|
if (xact->amount.commodity() &&
|
||||||
! xact->amount.commodity().annotated)
|
! xact->amount.commodity().annotated)
|
||||||
|
|
@ -249,7 +249,7 @@ transaction_t * parse_transaction(char * line,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xact->amount.reduce();
|
xact->amount.in_place_reduce();
|
||||||
DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
|
DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
|
||||||
"Reduced amount is " << xact->amount);
|
"Reduced amount is " << xact->amount);
|
||||||
|
|
||||||
|
|
@ -348,17 +348,14 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal,
|
||||||
|
|
||||||
TIMER_START(entry_date);
|
TIMER_START(entry_date);
|
||||||
|
|
||||||
#if 0
|
std::string word;
|
||||||
// jww (2007-04-18): Need to write a full date parser
|
line_in >> word;
|
||||||
curr->_date.parse(line_in);
|
curr->_date = parse_datetime(word);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (peek_next_nonws(line_in) == '=') {
|
if (peek_next_nonws(line_in) == '=') {
|
||||||
line_in.get(c);
|
line_in.get(c);
|
||||||
#if 0
|
line_in >> word;
|
||||||
// jww (2007-04-18): Need to write a full date parser
|
curr->_date_eff = parse_datetime(word);
|
||||||
curr->_date_eff.parse(line_in);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMER_STOP(entry_date);
|
TIMER_STOP(entry_date);
|
||||||
|
|
@ -750,7 +747,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
case '~': { // period entry
|
case '~': { // period entry
|
||||||
period_entry_t * pe = new period_entry_t(skip_ws(line + 1));
|
period_entry_t * pe = new period_entry_t(skip_ws(line + 1));
|
||||||
if (! pe->period)
|
if (! pe->period)
|
||||||
throw new parse_error(std::string("Parsing time period '") + line + "'");
|
throw new parse_error(std::string("Parsing time period '") + skip_ws(line + 1) + "'");
|
||||||
|
|
||||||
if (parse_transactions(in, journal, account_stack.front(), *pe,
|
if (parse_transactions(in, journal, account_stack.front(), *pe,
|
||||||
"period", end_pos)) {
|
"period", end_pos)) {
|
||||||
|
|
|
||||||
14
times.cc
14
times.cc
|
|
@ -1,12 +1,26 @@
|
||||||
|
#ifdef HAVE_LANGINFO_H
|
||||||
|
#include <langinfo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "times.h"
|
#include "times.h"
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
ptime now = boost::posix_time::second_clock::universal_time();
|
ptime now = boost::posix_time::second_clock::universal_time();
|
||||||
|
|
||||||
bool day_before_month = false;
|
bool day_before_month = false;
|
||||||
|
static bool day_before_month_initialized = false;
|
||||||
|
|
||||||
ptime parse_datetime(std::istream& in)
|
ptime parse_datetime(std::istream& in)
|
||||||
{
|
{
|
||||||
|
if (! day_before_month_initialized) {
|
||||||
|
#ifdef HAVE_NL_LANGINFO
|
||||||
|
const char * d_fmt = nl_langinfo(D_FMT);
|
||||||
|
if (d_fmt && std::strlen(d_fmt) > 1 && d_fmt[1] == 'd')
|
||||||
|
day_before_month = true;
|
||||||
|
day_before_month_initialized = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#if 1
|
#if 1
|
||||||
return parse_abs_datetime(in);
|
return parse_abs_datetime(in);
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
9
util.h
9
util.h
|
|
@ -96,4 +96,13 @@ std::string abbreviate(const std::string& str, unsigned int width,
|
||||||
elision_style_t elision_style = TRUNCATE_TRAILING,
|
elision_style_t elision_style = TRUNCATE_TRAILING,
|
||||||
const bool is_account = false, int abbrev_length = 2);
|
const bool is_account = false, int abbrev_length = 2);
|
||||||
|
|
||||||
|
static inline const
|
||||||
|
std::string& either_or(const std::string& first, const std::string& second)
|
||||||
|
{
|
||||||
|
if (first.empty())
|
||||||
|
return second;
|
||||||
|
else
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _UTIL_H
|
#endif // _UTIL_H
|
||||||
|
|
|
||||||
263
value.cc
263
value.cc
|
|
@ -11,7 +11,7 @@ bool value_t::to_boolean() const
|
||||||
return *(bool *) data;
|
return *(bool *) data;
|
||||||
} else {
|
} else {
|
||||||
value_t temp(*this);
|
value_t temp(*this);
|
||||||
temp.cast(BOOLEAN);
|
temp.in_place_cast(BOOLEAN);
|
||||||
return *(bool *) temp.data;
|
return *(bool *) temp.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,7 +22,7 @@ long value_t::to_integer() const
|
||||||
return *(long *) data;
|
return *(long *) data;
|
||||||
} else {
|
} else {
|
||||||
value_t temp(*this);
|
value_t temp(*this);
|
||||||
temp.cast(INTEGER);
|
temp.in_place_cast(INTEGER);
|
||||||
return *(long *) temp.data;
|
return *(long *) temp.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ ptime value_t::to_datetime() const
|
||||||
return *(ptime *) data;
|
return *(ptime *) data;
|
||||||
} else {
|
} else {
|
||||||
value_t temp(*this);
|
value_t temp(*this);
|
||||||
temp.cast(DATETIME);
|
temp.in_place_cast(DATETIME);
|
||||||
return *(ptime *) temp.data;
|
return *(ptime *) temp.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@ amount_t value_t::to_amount() const
|
||||||
return *(amount_t *) data;
|
return *(amount_t *) data;
|
||||||
} else {
|
} else {
|
||||||
value_t temp(*this);
|
value_t temp(*this);
|
||||||
temp.cast(AMOUNT);
|
temp.in_place_cast(AMOUNT);
|
||||||
return *(amount_t *) temp.data;
|
return *(amount_t *) temp.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -55,7 +55,7 @@ balance_t value_t::to_balance() const
|
||||||
return *(balance_t *) data;
|
return *(balance_t *) data;
|
||||||
} else {
|
} else {
|
||||||
value_t temp(*this);
|
value_t temp(*this);
|
||||||
temp.cast(BALANCE);
|
temp.in_place_cast(BALANCE);
|
||||||
return *(balance_t *) temp.data;
|
return *(balance_t *) temp.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +66,7 @@ balance_pair_t value_t::to_balance_pair() const
|
||||||
return *(balance_pair_t *) data;
|
return *(balance_pair_t *) data;
|
||||||
} else {
|
} else {
|
||||||
value_t temp(*this);
|
value_t temp(*this);
|
||||||
temp.cast(BALANCE_PAIR);
|
temp.in_place_cast(BALANCE_PAIR);
|
||||||
return *(balance_pair_t *) temp.data;
|
return *(balance_pair_t *) temp.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -141,19 +141,19 @@ void value_t::simplify()
|
||||||
(! ((balance_pair_t *) data)->cost ||
|
(! ((balance_pair_t *) data)->cost ||
|
||||||
((balance_pair_t *) data)->cost->realzero())) {
|
((balance_pair_t *) data)->cost->realzero())) {
|
||||||
DEBUG_PRINT("amounts.values.simplify", "Reducing balance pair to balance");
|
DEBUG_PRINT("amounts.values.simplify", "Reducing balance pair to balance");
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == BALANCE &&
|
if (type == BALANCE &&
|
||||||
((balance_t *) data)->amounts.size() == 1) {
|
((balance_t *) data)->amounts.size() == 1) {
|
||||||
DEBUG_PRINT("amounts.values.simplify", "Reducing balance to amount");
|
DEBUG_PRINT("amounts.values.simplify", "Reducing balance to amount");
|
||||||
cast(AMOUNT);
|
in_place_cast(AMOUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == AMOUNT &&
|
if (type == AMOUNT &&
|
||||||
! ((amount_t *) data)->commodity()) {
|
! ((amount_t *) data)->commodity()) {
|
||||||
DEBUG_PRINT("amounts.values.simplify", "Reducing amount to integer");
|
DEBUG_PRINT("amounts.values.simplify", "Reducing amount to integer");
|
||||||
cast(INTEGER);
|
in_place_cast(INTEGER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -254,12 +254,12 @@ value_t& value_t::operator+=(const value_t& val)
|
||||||
throw new value_error("Cannot add a boolean to a value");
|
throw new value_error("Cannot add a boolean to a value");
|
||||||
else if (val.type == DATETIME)
|
else if (val.type == DATETIME)
|
||||||
throw new value_error("Cannot add a date/time to a value");
|
throw new value_error("Cannot add a date/time to a value");
|
||||||
else if (val.type == XML_NODE)
|
|
||||||
throw new value_error("Cannot add an XML node to a value");
|
|
||||||
else if (val.type == POINTER)
|
else if (val.type == POINTER)
|
||||||
throw new value_error("Cannot add a pointer to a value");
|
throw new value_error("Cannot add a pointer to a value");
|
||||||
else if (val.type == SEQUENCE)
|
else if (val.type == SEQUENCE)
|
||||||
throw new value_error("Cannot add a sequence to a value");
|
throw new value_error("Cannot add a sequence to a value");
|
||||||
|
else if (val.type == XML_NODE) // recurse
|
||||||
|
return *this += (*(xml::node_t **) val.data)->to_value();
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
@ -271,15 +271,15 @@ value_t& value_t::operator+=(const value_t& val)
|
||||||
*((long *) data) += *((long *) val.data);
|
*((long *) data) += *((long *) val.data);
|
||||||
break;
|
break;
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
cast(AMOUNT);
|
in_place_cast(AMOUNT);
|
||||||
*((amount_t *) data) += *((amount_t *) val.data);
|
*((amount_t *) data) += *((amount_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
*((balance_t *) data) += *((balance_t *) val.data);
|
*((balance_t *) data) += *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) += *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) += *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
|
|
@ -317,7 +317,7 @@ value_t& value_t::operator+=(const value_t& val)
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
if (*((long *) val.data) &&
|
if (*((long *) val.data) &&
|
||||||
((amount_t *) data)->commodity()) {
|
((amount_t *) data)->commodity()) {
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
return *this += val;
|
return *this += val;
|
||||||
}
|
}
|
||||||
*((amount_t *) data) += *((long *) val.data);
|
*((amount_t *) data) += *((long *) val.data);
|
||||||
|
|
@ -326,19 +326,19 @@ value_t& value_t::operator+=(const value_t& val)
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
if (((amount_t *) data)->commodity() !=
|
if (((amount_t *) data)->commodity() !=
|
||||||
((amount_t *) val.data)->commodity()) {
|
((amount_t *) val.data)->commodity()) {
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
return *this += val;
|
return *this += val;
|
||||||
}
|
}
|
||||||
*((amount_t *) data) += *((amount_t *) val.data);
|
*((amount_t *) data) += *((amount_t *) val.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
*((balance_t *) data) += *((balance_t *) val.data);
|
*((balance_t *) data) += *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) += *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) += *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -363,7 +363,7 @@ value_t& value_t::operator+=(const value_t& val)
|
||||||
*((balance_t *) data) += *((balance_t *) val.data);
|
*((balance_t *) data) += *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) += *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) += *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
|
|
@ -439,12 +439,12 @@ value_t& value_t::operator-=(const value_t& val)
|
||||||
throw new value_error("Cannot subtract a date/time from a value");
|
throw new value_error("Cannot subtract a date/time from a value");
|
||||||
else if (val.type == STRING)
|
else if (val.type == STRING)
|
||||||
throw new value_error("Cannot subtract a string from a value");
|
throw new value_error("Cannot subtract a string from a value");
|
||||||
else if (val.type == XML_NODE)
|
|
||||||
throw new value_error("Cannot subtract an XML node from a value");
|
|
||||||
else if (val.type == POINTER)
|
else if (val.type == POINTER)
|
||||||
throw new value_error("Cannot subtract a pointer from a value");
|
throw new value_error("Cannot subtract a pointer from a value");
|
||||||
else if (val.type == SEQUENCE)
|
else if (val.type == SEQUENCE)
|
||||||
throw new value_error("Cannot subtract a sequence from a value");
|
throw new value_error("Cannot subtract a sequence from a value");
|
||||||
|
else if (val.type == XML_NODE) // recurse
|
||||||
|
return *this -= (*(xml::node_t **) val.data)->to_value();
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
@ -456,15 +456,15 @@ value_t& value_t::operator-=(const value_t& val)
|
||||||
*((long *) data) -= *((long *) val.data);
|
*((long *) data) -= *((long *) val.data);
|
||||||
break;
|
break;
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
cast(AMOUNT);
|
in_place_cast(AMOUNT);
|
||||||
*((amount_t *) data) -= *((amount_t *) val.data);
|
*((amount_t *) data) -= *((amount_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
*((balance_t *) data) -= *((balance_t *) val.data);
|
*((balance_t *) data) -= *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) -= *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) -= *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -480,7 +480,7 @@ value_t& value_t::operator-=(const value_t& val)
|
||||||
break;
|
break;
|
||||||
case DATETIME: {
|
case DATETIME: {
|
||||||
time_duration tval = ((ptime *) data)->operator-(*((ptime *) val.data));
|
time_duration tval = ((ptime *) data)->operator-(*((ptime *) val.data));
|
||||||
cast(INTEGER);
|
in_place_cast(INTEGER);
|
||||||
*((long *) data) = tval.total_seconds();
|
*((long *) data) = tval.total_seconds();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -504,7 +504,7 @@ value_t& value_t::operator-=(const value_t& val)
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
if (*((long *) val.data) &&
|
if (*((long *) val.data) &&
|
||||||
((amount_t *) data)->commodity()) {
|
((amount_t *) data)->commodity()) {
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
return *this -= val;
|
return *this -= val;
|
||||||
}
|
}
|
||||||
*((amount_t *) data) -= *((long *) val.data);
|
*((amount_t *) data) -= *((long *) val.data);
|
||||||
|
|
@ -513,19 +513,19 @@ value_t& value_t::operator-=(const value_t& val)
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
if (((amount_t *) data)->commodity() !=
|
if (((amount_t *) data)->commodity() !=
|
||||||
((amount_t *) val.data)->commodity()) {
|
((amount_t *) val.data)->commodity()) {
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
return *this -= val;
|
return *this -= val;
|
||||||
}
|
}
|
||||||
*((amount_t *) data) -= *((amount_t *) val.data);
|
*((amount_t *) data) -= *((amount_t *) val.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
*((balance_t *) data) -= *((balance_t *) val.data);
|
*((balance_t *) data) -= *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) -= *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) -= *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -547,7 +547,7 @@ value_t& value_t::operator-=(const value_t& val)
|
||||||
*((balance_t *) data) -= *((balance_t *) val.data);
|
*((balance_t *) data) -= *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) -= *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) -= *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -603,12 +603,12 @@ value_t& value_t::operator*=(const value_t& val)
|
||||||
throw new value_error("Cannot multiply a value by a date/time");
|
throw new value_error("Cannot multiply a value by a date/time");
|
||||||
else if (val.type == STRING)
|
else if (val.type == STRING)
|
||||||
throw new value_error("Cannot multiply a value by a string");
|
throw new value_error("Cannot multiply a value by a string");
|
||||||
else if (val.type == XML_NODE)
|
|
||||||
throw new value_error("Cannot multiply a value by an XML node");
|
|
||||||
else if (val.type == POINTER)
|
else if (val.type == POINTER)
|
||||||
throw new value_error("Cannot multiply a value by a pointer");
|
throw new value_error("Cannot multiply a value by a pointer");
|
||||||
else if (val.type == SEQUENCE)
|
else if (val.type == SEQUENCE)
|
||||||
throw new value_error("Cannot multiply a value by a sequence");
|
throw new value_error("Cannot multiply a value by a sequence");
|
||||||
|
else if (val.type == XML_NODE) // recurse
|
||||||
|
return *this *= (*(xml::node_t **) val.data)->to_value();
|
||||||
|
|
||||||
if (val.realzero() && type != STRING) {
|
if (val.realzero() && type != STRING) {
|
||||||
*this = 0L;
|
*this = 0L;
|
||||||
|
|
@ -625,15 +625,15 @@ value_t& value_t::operator*=(const value_t& val)
|
||||||
*((long *) data) *= *((long *) val.data);
|
*((long *) data) *= *((long *) val.data);
|
||||||
break;
|
break;
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
cast(AMOUNT);
|
in_place_cast(AMOUNT);
|
||||||
*((amount_t *) data) *= *((amount_t *) val.data);
|
*((amount_t *) data) *= *((amount_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
*((balance_t *) data) *= *((balance_t *) val.data);
|
*((balance_t *) data) *= *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) *= *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) *= *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -651,11 +651,11 @@ value_t& value_t::operator*=(const value_t& val)
|
||||||
*((amount_t *) data) *= *((amount_t *) val.data);
|
*((amount_t *) data) *= *((amount_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
*((balance_t *) data) *= *((balance_t *) val.data);
|
*((balance_t *) data) *= *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) *= *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) *= *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -676,7 +676,7 @@ value_t& value_t::operator*=(const value_t& val)
|
||||||
*((balance_t *) data) *= *((balance_t *) val.data);
|
*((balance_t *) data) *= *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) *= *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) *= *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -717,7 +717,7 @@ value_t& value_t::operator*=(const value_t& val)
|
||||||
case AMOUNT: {
|
case AMOUNT: {
|
||||||
std::string temp;
|
std::string temp;
|
||||||
value_t num(val);
|
value_t num(val);
|
||||||
num.cast(INTEGER);
|
num.in_place_cast(INTEGER);
|
||||||
for (long i = 0; i < *(long *) num.data; i++)
|
for (long i = 0; i < *(long *) num.data; i++)
|
||||||
temp += **(std::string **) data;
|
temp += **(std::string **) data;
|
||||||
**(std::string **) data = temp;
|
**(std::string **) data = temp;
|
||||||
|
|
@ -755,12 +755,12 @@ value_t& value_t::operator/=(const value_t& val)
|
||||||
throw new value_error("Cannot divide a date/time by a value");
|
throw new value_error("Cannot divide a date/time by a value");
|
||||||
else if (val.type == STRING)
|
else if (val.type == STRING)
|
||||||
throw new value_error("Cannot divide a string by a value");
|
throw new value_error("Cannot divide a string by a value");
|
||||||
else if (val.type == XML_NODE)
|
|
||||||
throw new value_error("Cannot divide a value by an XML node");
|
|
||||||
else if (val.type == POINTER)
|
else if (val.type == POINTER)
|
||||||
throw new value_error("Cannot divide a pointer by a value");
|
throw new value_error("Cannot divide a pointer by a value");
|
||||||
else if (val.type == SEQUENCE)
|
else if (val.type == SEQUENCE)
|
||||||
throw new value_error("Cannot divide a value by a sequence");
|
throw new value_error("Cannot divide a value by a sequence");
|
||||||
|
else if (val.type == XML_NODE) // recurse
|
||||||
|
return *this /= (*(xml::node_t **) val.data)->to_value();
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
@ -772,15 +772,15 @@ value_t& value_t::operator/=(const value_t& val)
|
||||||
*((long *) data) /= *((long *) val.data);
|
*((long *) data) /= *((long *) val.data);
|
||||||
break;
|
break;
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
cast(AMOUNT);
|
in_place_cast(AMOUNT);
|
||||||
*((amount_t *) data) /= *((amount_t *) val.data);
|
*((amount_t *) data) /= *((amount_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
*((balance_t *) data) /= *((balance_t *) val.data);
|
*((balance_t *) data) /= *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) /= *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) /= *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -798,11 +798,11 @@ value_t& value_t::operator/=(const value_t& val)
|
||||||
*((amount_t *) data) /= *((amount_t *) val.data);
|
*((amount_t *) data) /= *((amount_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
*((balance_t *) data) /= *((balance_t *) val.data);
|
*((balance_t *) data) /= *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) /= *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) /= *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -823,7 +823,7 @@ value_t& value_t::operator/=(const value_t& val)
|
||||||
*((balance_t *) data) /= *((balance_t *) val.data);
|
*((balance_t *) data) /= *((balance_t *) val.data);
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
*((balance_pair_t *) data) /= *((balance_pair_t *) val.data);
|
*((balance_pair_t *) data) /= *((balance_pair_t *) val.data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -887,7 +887,7 @@ value_t::operator bool() const
|
||||||
case STRING:
|
case STRING:
|
||||||
return ! (**((std::string **) data)).empty();
|
return ! (**((std::string **) data)).empty();
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
return *(xml::node_t **) data != NULL;
|
return (*(xml::node_t **) data)->to_value().to_boolean();
|
||||||
case POINTER:
|
case POINTER:
|
||||||
return *(void **) data != NULL;
|
return *(void **) data != NULL;
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -921,7 +921,7 @@ value_t::operator long() const
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot convert a string to an integer");
|
throw new value_error("Cannot convert a string to an integer");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot convert an XML node to an integer");
|
return (*(xml::node_t **) data)->to_value().to_integer();
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot convert a pointer to an integer");
|
throw new value_error("Cannot convert a pointer to an integer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -954,7 +954,7 @@ value_t::operator ptime() const
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot convert a string to a date/time");
|
throw new value_error("Cannot convert a string to a date/time");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot convert an XML node to a date/time");
|
return (*(xml::node_t **) data)->to_value().to_datetime();
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot convert a pointer to a date/time");
|
throw new value_error("Cannot convert a pointer to a date/time");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -987,7 +987,7 @@ value_t::operator double() const
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot convert a string to a double");
|
throw new value_error("Cannot convert a string to a double");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot convert an XML node to a double");
|
return (*(xml::node_t **) data)->to_value().to_amount().number();
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot convert a pointer to a double");
|
throw new value_error("Cannot convert a pointer to a double");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -1012,15 +1012,14 @@ value_t::operator std::string() const
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
case BALANCE_PAIR: {
|
case BALANCE_PAIR: {
|
||||||
value_t temp(*this);
|
value_t temp(*this);
|
||||||
temp.cast(STRING);
|
temp.in_place_cast(STRING);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
case STRING:
|
case STRING:
|
||||||
return **(std::string **) data;
|
return **(std::string **) data;
|
||||||
|
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
return (*(xml::node_t **) data)->text();
|
return (*(xml::node_t **) data)->to_value().to_string();
|
||||||
|
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot convert a pointer to a string");
|
throw new value_error("Cannot convert a pointer to a string");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -1060,8 +1059,10 @@ bool value_t::operator OP(const value_t& val) \
|
||||||
\
|
\
|
||||||
case STRING: \
|
case STRING: \
|
||||||
throw new value_error("Cannot compare a boolean to a string"); \
|
throw new value_error("Cannot compare a boolean to a string"); \
|
||||||
|
\
|
||||||
case XML_NODE: \
|
case XML_NODE: \
|
||||||
throw new value_error("Cannot compare a boolean to an XML node"); \
|
return *this OP (*(xml::node_t **) data)->to_value(); \
|
||||||
|
\
|
||||||
case POINTER: \
|
case POINTER: \
|
||||||
throw new value_error("Cannot compare a boolean to a pointer"); \
|
throw new value_error("Cannot compare a boolean to a pointer"); \
|
||||||
case SEQUENCE: \
|
case SEQUENCE: \
|
||||||
|
|
@ -1099,8 +1100,10 @@ bool value_t::operator OP(const value_t& val) \
|
||||||
\
|
\
|
||||||
case STRING: \
|
case STRING: \
|
||||||
throw new value_error("Cannot compare an integer to a string"); \
|
throw new value_error("Cannot compare an integer to a string"); \
|
||||||
|
\
|
||||||
case XML_NODE: \
|
case XML_NODE: \
|
||||||
throw new value_error("Cannot compare an integer to an XML node"); \
|
return *this OP (*(xml::node_t **) data)->to_value(); \
|
||||||
|
\
|
||||||
case POINTER: \
|
case POINTER: \
|
||||||
throw new value_error("Cannot compare an integer to a pointer"); \
|
throw new value_error("Cannot compare an integer to a pointer"); \
|
||||||
case SEQUENCE: \
|
case SEQUENCE: \
|
||||||
|
|
@ -1131,8 +1134,10 @@ bool value_t::operator OP(const value_t& val) \
|
||||||
throw new value_error("Cannot compare a date/time to a balance pair"); \
|
throw new value_error("Cannot compare a date/time to a balance pair"); \
|
||||||
case STRING: \
|
case STRING: \
|
||||||
throw new value_error("Cannot compare a date/time to a string"); \
|
throw new value_error("Cannot compare a date/time to a string"); \
|
||||||
|
\
|
||||||
case XML_NODE: \
|
case XML_NODE: \
|
||||||
throw new value_error("Cannot compare a date/time to an XML node"); \
|
return *this OP (*(xml::node_t **) data)->to_value(); \
|
||||||
|
\
|
||||||
case POINTER: \
|
case POINTER: \
|
||||||
throw new value_error("Cannot compare a date/time to a pointer"); \
|
throw new value_error("Cannot compare a date/time to a pointer"); \
|
||||||
case SEQUENCE: \
|
case SEQUENCE: \
|
||||||
|
|
@ -1169,8 +1174,10 @@ bool value_t::operator OP(const value_t& val) \
|
||||||
\
|
\
|
||||||
case STRING: \
|
case STRING: \
|
||||||
throw new value_error("Cannot compare an amount to a string"); \
|
throw new value_error("Cannot compare an amount to a string"); \
|
||||||
|
\
|
||||||
case XML_NODE: \
|
case XML_NODE: \
|
||||||
throw new value_error("Cannot compare an amount to an XML node"); \
|
return *this OP (*(xml::node_t **) data)->to_value(); \
|
||||||
|
\
|
||||||
case POINTER: \
|
case POINTER: \
|
||||||
throw new value_error("Cannot compare an amount to a pointer"); \
|
throw new value_error("Cannot compare an amount to a pointer"); \
|
||||||
case SEQUENCE: \
|
case SEQUENCE: \
|
||||||
|
|
@ -1205,8 +1212,10 @@ bool value_t::operator OP(const value_t& val) \
|
||||||
\
|
\
|
||||||
case STRING: \
|
case STRING: \
|
||||||
throw new value_error("Cannot compare a balance to a string"); \
|
throw new value_error("Cannot compare a balance to a string"); \
|
||||||
|
\
|
||||||
case XML_NODE: \
|
case XML_NODE: \
|
||||||
throw new value_error("Cannot compare a balance to an XML node"); \
|
return *this OP (*(xml::node_t **) data)->to_value(); \
|
||||||
|
\
|
||||||
case POINTER: \
|
case POINTER: \
|
||||||
throw new value_error("Cannot compare a balance to a pointer"); \
|
throw new value_error("Cannot compare a balance to a pointer"); \
|
||||||
case SEQUENCE: \
|
case SEQUENCE: \
|
||||||
|
|
@ -1244,8 +1253,10 @@ bool value_t::operator OP(const value_t& val) \
|
||||||
\
|
\
|
||||||
case STRING: \
|
case STRING: \
|
||||||
throw new value_error("Cannot compare a balance pair to a string"); \
|
throw new value_error("Cannot compare a balance pair to a string"); \
|
||||||
|
\
|
||||||
case XML_NODE: \
|
case XML_NODE: \
|
||||||
throw new value_error("Cannot compare a balance pair to an XML node"); \
|
return *this OP (*(xml::node_t **) data)->to_value(); \
|
||||||
|
\
|
||||||
case POINTER: \
|
case POINTER: \
|
||||||
throw new value_error("Cannot compare a balance pair to a pointer"); \
|
throw new value_error("Cannot compare a balance pair to a pointer"); \
|
||||||
case SEQUENCE: \
|
case SEQUENCE: \
|
||||||
|
|
@ -1277,8 +1288,7 @@ bool value_t::operator OP(const value_t& val) \
|
||||||
**((std::string **) val.data)); \
|
**((std::string **) val.data)); \
|
||||||
\
|
\
|
||||||
case XML_NODE: \
|
case XML_NODE: \
|
||||||
return (**((std::string **) data) OP \
|
return *this OP (*(xml::node_t **) data)->to_value(); \
|
||||||
(*(xml::node_t **) val.data)->text()); \
|
|
||||||
\
|
\
|
||||||
case POINTER: \
|
case POINTER: \
|
||||||
throw new value_error("Cannot compare a string to a pointer"); \
|
throw new value_error("Cannot compare a string to a pointer"); \
|
||||||
|
|
@ -1294,25 +1304,23 @@ bool value_t::operator OP(const value_t& val) \
|
||||||
case XML_NODE: \
|
case XML_NODE: \
|
||||||
switch (val.type) { \
|
switch (val.type) { \
|
||||||
case BOOLEAN: \
|
case BOOLEAN: \
|
||||||
throw new value_error("Cannot compare an XML node to a boolean"); \
|
return (*(xml::node_t **) data)->to_value() OP *this; \
|
||||||
case INTEGER: \
|
case INTEGER: \
|
||||||
throw new value_error("Cannot compare an XML node to an integer"); \
|
return (*(xml::node_t **) data)->to_value() OP *this; \
|
||||||
case DATETIME: \
|
case DATETIME: \
|
||||||
throw new value_error("Cannot compare an XML node to a date/time"); \
|
return (*(xml::node_t **) data)->to_value() OP *this; \
|
||||||
case AMOUNT: \
|
case AMOUNT: \
|
||||||
throw new value_error("Cannot compare an XML node to an amount"); \
|
return (*(xml::node_t **) data)->to_value() OP *this; \
|
||||||
case BALANCE: \
|
case BALANCE: \
|
||||||
throw new value_error("Cannot compare an XML node to a balance"); \
|
return (*(xml::node_t **) data)->to_value() OP *this; \
|
||||||
case BALANCE_PAIR: \
|
case BALANCE_PAIR: \
|
||||||
throw new value_error("Cannot compare an XML node to a balance pair"); \
|
return (*(xml::node_t **) data)->to_value() OP *this; \
|
||||||
\
|
|
||||||
case STRING: \
|
case STRING: \
|
||||||
return ((*(xml::node_t **) data)->text() OP \
|
return (*(xml::node_t **) data)->to_value() OP *this; \
|
||||||
**((std::string **) val.data)); \
|
|
||||||
\
|
\
|
||||||
case XML_NODE: \
|
case XML_NODE: \
|
||||||
return (*((xml::node_t **) data) OP \
|
return ((*(xml::node_t **) data)->to_value() OP \
|
||||||
*((xml::node_t **) val.data)); \
|
(*(xml::node_t **) val.data)->to_value()); \
|
||||||
\
|
\
|
||||||
case POINTER: \
|
case POINTER: \
|
||||||
throw new value_error("Cannot compare an XML node to a pointer"); \
|
throw new value_error("Cannot compare an XML node to a pointer"); \
|
||||||
|
|
@ -1370,7 +1378,7 @@ DEF_VALUE_CMP_OP(<=)
|
||||||
DEF_VALUE_CMP_OP(>)
|
DEF_VALUE_CMP_OP(>)
|
||||||
DEF_VALUE_CMP_OP(>=)
|
DEF_VALUE_CMP_OP(>=)
|
||||||
|
|
||||||
void value_t::cast(type_t cast_type)
|
void value_t::in_place_cast(type_t cast_type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
@ -1691,19 +1699,14 @@ void value_t::cast(type_t cast_type)
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
switch (cast_type) {
|
switch (cast_type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
throw new value_error("Cannot convert an XML node to a boolean");
|
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
throw new value_error("Cannot convert an XML node to an integer");
|
|
||||||
case DATETIME:
|
case DATETIME:
|
||||||
throw new value_error("Cannot convert an XML node to a date/time");
|
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
throw new value_error("Cannot convert an XML node to an amount");
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
throw new value_error("Cannot convert an XML node to a balance");
|
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
throw new value_error("Cannot convert an XML node to a balance pair");
|
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot convert an XML node to a string");
|
*this = (*(xml::node_t **) data)->to_value();
|
||||||
|
break;
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
break;
|
break;
|
||||||
case POINTER:
|
case POINTER:
|
||||||
|
|
@ -1762,8 +1765,8 @@ void value_t::cast(type_t cast_type)
|
||||||
throw new value_error("Cannot convert a sequence to a balance pair");
|
throw new value_error("Cannot convert a sequence to a balance pair");
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot convert a sequence to a string");
|
throw new value_error("Cannot convert a sequence to a string");
|
||||||
case XML_NODE: \
|
case XML_NODE:
|
||||||
throw new value_error("Cannot compare a sequence to an XML node"); \
|
throw new value_error("Cannot compare a sequence to an XML node");
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot convert a sequence to a pointer");
|
throw new value_error("Cannot convert a sequence to a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -1782,7 +1785,7 @@ void value_t::cast(type_t cast_type)
|
||||||
type = cast_type;
|
type = cast_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::negate()
|
void value_t::in_place_negate()
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
@ -1794,18 +1797,20 @@ void value_t::negate()
|
||||||
case DATETIME:
|
case DATETIME:
|
||||||
throw new value_error("Cannot negate a date/time");
|
throw new value_error("Cannot negate a date/time");
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
((amount_t *) data)->negate();
|
((amount_t *) data)->in_place_negate();
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
((balance_t *) data)->negate();
|
((balance_t *) data)->in_place_negate();
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
((balance_pair_t *) data)->negate();
|
((balance_pair_t *) data)->in_place_negate();
|
||||||
break;
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot negate a string");
|
throw new value_error("Cannot negate a string");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot negate an XML node");
|
*this = (*(xml::node_t **) data)->to_value();
|
||||||
|
in_place_negate();
|
||||||
|
break;
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot negate a pointer");
|
throw new value_error("Cannot negate a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -1817,7 +1822,7 @@ void value_t::negate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::abs()
|
void value_t::in_place_abs()
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
@ -1840,7 +1845,9 @@ void value_t::abs()
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot take the absolute value of a string");
|
throw new value_error("Cannot take the absolute value of a string");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot take the absolute value of an XML node");
|
*this = (*(xml::node_t **) data)->to_value();
|
||||||
|
in_place_abs();
|
||||||
|
break;
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot take the absolute value of a pointer");
|
throw new value_error("Cannot take the absolute value of a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -1870,7 +1877,7 @@ value_t value_t::value(const ptime& moment) const
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot find the value of a string");
|
throw new value_error("Cannot find the value of a string");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot find the value of an XML node");
|
return (*(xml::node_t **) data)->to_value().value(moment);
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot find the value of a pointer");
|
throw new value_error("Cannot find the value of a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -1881,7 +1888,7 @@ value_t value_t::value(const ptime& moment) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::reduce()
|
void value_t::in_place_reduce()
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
@ -1889,18 +1896,20 @@ void value_t::reduce()
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
break;
|
break;
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
((amount_t *) data)->reduce();
|
((amount_t *) data)->in_place_reduce();
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
((balance_t *) data)->reduce();
|
((balance_t *) data)->in_place_reduce();
|
||||||
break;
|
break;
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
((balance_pair_t *) data)->reduce();
|
((balance_pair_t *) data)->in_place_reduce();
|
||||||
break;
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot reduce a string");
|
throw new value_error("Cannot reduce a string");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot reduce an XML node");
|
*this = (*(xml::node_t **) data)->to_value();
|
||||||
|
in_place_reduce(); // recurse
|
||||||
|
break;
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot reduce a pointer");
|
throw new value_error("Cannot reduce a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -1908,7 +1917,7 @@ void value_t::reduce()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::round()
|
value_t value_t::round() const
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
@ -1918,18 +1927,15 @@ void value_t::round()
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
break;
|
break;
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
*((amount_t *) data) = ((amount_t *) data)->round();
|
return ((amount_t *) data)->round();
|
||||||
break;
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
((balance_t *) data)->round();
|
return ((balance_t *) data)->round();
|
||||||
break;
|
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
((balance_pair_t *) data)->round();
|
return ((balance_pair_t *) data)->round();
|
||||||
break;
|
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot round a string");
|
throw new value_error("Cannot round a string");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot round an XML node");
|
return (*(xml::node_t **) data)->to_value().round();
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot round a pointer");
|
throw new value_error("Cannot round a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -1948,18 +1954,15 @@ value_t value_t::unround() const
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
break;
|
break;
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
temp = ((amount_t *) data)->unround();
|
return ((amount_t *) data)->unround();
|
||||||
break;
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
temp = ((balance_t *) data)->unround();
|
return ((balance_t *) data)->unround();
|
||||||
break;
|
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
temp = ((balance_pair_t *) data)->unround();
|
return ((balance_pair_t *) data)->unround();
|
||||||
break;
|
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot un-round a string");
|
throw new value_error("Cannot un-round a string");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot un-round an XML node");
|
return (*(xml::node_t **) data)->to_value().unround();
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot un-round a pointer");
|
throw new value_error("Cannot un-round a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -1980,17 +1983,17 @@ value_t value_t::price() const
|
||||||
|
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
return ((amount_t *) data)->price();
|
return ((amount_t *) data)->price();
|
||||||
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
return ((balance_t *) data)->price();
|
return ((balance_t *) data)->price();
|
||||||
|
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
return ((balance_pair_t *) data)->quantity.price();
|
return ((balance_pair_t *) data)->quantity.price();
|
||||||
|
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot find the price of a string");
|
throw new value_error("Cannot find the price of a string");
|
||||||
|
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot find the price of an XML node");
|
return (*(xml::node_t **) data)->to_value().price();
|
||||||
|
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot find the price of a pointer");
|
throw new value_error("Cannot find the price of a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -2010,23 +2013,24 @@ value_t value_t::date() const
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
throw new value_error("Cannot find the date of a boolean");
|
throw new value_error("Cannot find the date of a boolean");
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
return ptime();
|
throw new value_error("Cannot find the date of an integer");
|
||||||
|
|
||||||
case DATETIME:
|
case DATETIME:
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
return ptime(((amount_t *) data)->date());
|
return ((amount_t *) data)->date();
|
||||||
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
return ptime(((balance_t *) data)->date());
|
return ((balance_t *) data)->date();
|
||||||
|
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
return ptime(((balance_pair_t *) data)->quantity.date());
|
return ((balance_pair_t *) data)->quantity.date();
|
||||||
|
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot find the date of a string");
|
throw new value_error("Cannot find the date of a string");
|
||||||
|
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot find the date of an XML node");
|
return (*(xml::node_t **) data)->to_value().date();
|
||||||
|
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot find the date of a pointer");
|
throw new value_error("Cannot find the date of a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -2097,7 +2101,7 @@ value_t value_t::cost() const
|
||||||
case STRING:
|
case STRING:
|
||||||
throw new value_error("Cannot find the cost of a string");
|
throw new value_error("Cannot find the cost of a string");
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
throw new value_error("Cannot find the cost of an XML node");
|
return (*(xml::node_t **) data)->to_value().cost();
|
||||||
case POINTER:
|
case POINTER:
|
||||||
throw new value_error("Cannot find the cost of a pointer");
|
throw new value_error("Cannot find the cost of a pointer");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
|
|
@ -2121,24 +2125,24 @@ value_t& value_t::add(const amount_t& amount, const amount_t * tcost)
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
if (tcost) {
|
if (tcost) {
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
return add(amount, tcost);
|
return add(amount, tcost);
|
||||||
}
|
}
|
||||||
else if ((type == AMOUNT &&
|
else if ((type == AMOUNT &&
|
||||||
((amount_t *) data)->commodity() != amount.commodity()) ||
|
((amount_t *) data)->commodity() != amount.commodity()) ||
|
||||||
(type != AMOUNT && amount.commodity())) {
|
(type != AMOUNT && amount.commodity())) {
|
||||||
cast(BALANCE);
|
in_place_cast(BALANCE);
|
||||||
return add(amount, tcost);
|
return add(amount, tcost);
|
||||||
}
|
}
|
||||||
else if (type != AMOUNT) {
|
else if (type != AMOUNT) {
|
||||||
cast(AMOUNT);
|
in_place_cast(AMOUNT);
|
||||||
}
|
}
|
||||||
*((amount_t *) data) += amount;
|
*((amount_t *) data) += amount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
if (tcost) {
|
if (tcost) {
|
||||||
cast(BALANCE_PAIR);
|
in_place_cast(BALANCE_PAIR);
|
||||||
return add(amount, tcost);
|
return add(amount, tcost);
|
||||||
}
|
}
|
||||||
*((balance_t *) data) += amount;
|
*((balance_t *) data) += amount;
|
||||||
|
|
@ -2380,7 +2384,7 @@ amount_t value_getitem(value_t& val, int i)
|
||||||
throw new value_error("Cannot cast a string to an amount");
|
throw new value_error("Cannot cast a string to an amount");
|
||||||
|
|
||||||
case value_t::XML_NODE:
|
case value_t::XML_NODE:
|
||||||
throw new value_error("Cannot cast an XML node to an amount");
|
return (*(xml::node_t **) data)->to_value();
|
||||||
|
|
||||||
case value_t::POINTER:
|
case value_t::POINTER:
|
||||||
throw new value_error("Cannot cast a pointer to an amount");
|
throw new value_error("Cannot cast a pointer to an amount");
|
||||||
|
|
@ -2614,10 +2618,10 @@ void export_value()
|
||||||
.def(self_ns::int_(self))
|
.def(self_ns::int_(self))
|
||||||
.def(self_ns::float_(self))
|
.def(self_ns::float_(self))
|
||||||
.def(self_ns::str(self))
|
.def(self_ns::str(self))
|
||||||
.def(abs(self))
|
|
||||||
|
|
||||||
.def_readonly("type", &value_t::type)
|
.def_readonly("type", &value_t::type)
|
||||||
|
|
||||||
|
.def("__abs__", &value_t::abs)
|
||||||
.def("__len__", value_len)
|
.def("__len__", value_len)
|
||||||
.def("__getitem__", value_getitem)
|
.def("__getitem__", value_getitem)
|
||||||
|
|
||||||
|
|
@ -2630,7 +2634,6 @@ void export_value()
|
||||||
.def("value", &value_t::value)
|
.def("value", &value_t::value)
|
||||||
.def("round", &value_t::round)
|
.def("round", &value_t::round)
|
||||||
.def("negate", &value_t::negate)
|
.def("negate", &value_t::negate)
|
||||||
.def("negated", &value_t::negated)
|
|
||||||
.def("write", &value_t::write)
|
.def("write", &value_t::write)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
33
value.h
33
value.h
|
|
@ -400,14 +400,14 @@ class value_t
|
||||||
template <typename T>
|
template <typename T>
|
||||||
operator T() const;
|
operator T() const;
|
||||||
|
|
||||||
void negate();
|
void in_place_negate();
|
||||||
value_t negated() const {
|
value_t negate() const {
|
||||||
value_t temp = *this;
|
value_t temp = *this;
|
||||||
temp.negate();
|
temp.in_place_negate();
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
value_t operator-() const {
|
value_t operator-() const {
|
||||||
return negated();
|
return negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool realzero() const {
|
bool realzero() const {
|
||||||
|
|
@ -439,27 +439,34 @@ class value_t
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void abs();
|
void in_place_abs();
|
||||||
void cast(type_t cast_type);
|
value_t abs() const;
|
||||||
|
void in_place_cast(type_t cast_type);
|
||||||
value_t cost() const;
|
value_t cost() const;
|
||||||
value_t price() const;
|
value_t price() const;
|
||||||
value_t date() const;
|
value_t date() const;
|
||||||
|
|
||||||
|
value_t cast(type_t cast_type) const {
|
||||||
|
value_t temp(*this);
|
||||||
|
temp.in_place_cast(cast_type);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
value_t strip_annotations(const bool keep_price = amount_t::keep_price,
|
value_t strip_annotations(const bool keep_price = amount_t::keep_price,
|
||||||
const bool keep_date = amount_t::keep_date,
|
const bool keep_date = amount_t::keep_date,
|
||||||
const bool keep_tag = amount_t::keep_tag) const;
|
const bool keep_tag = amount_t::keep_tag) const;
|
||||||
|
|
||||||
value_t& add(const amount_t& amount, const amount_t * cost = NULL);
|
value_t& add(const amount_t& amount, const amount_t * cost = NULL);
|
||||||
value_t value(const ptime& moment) const;
|
value_t value(const ptime& moment) const;
|
||||||
void reduce();
|
void in_place_reduce();
|
||||||
|
|
||||||
value_t reduced() const {
|
value_t reduce() const {
|
||||||
value_t temp(*this);
|
value_t temp(*this);
|
||||||
temp.reduce();
|
temp.in_place_reduce();
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void round();
|
value_t round() const;
|
||||||
value_t unround() const;
|
value_t unround() const;
|
||||||
|
|
||||||
void write(std::ostream& out, const int first_width,
|
void write(std::ostream& out, const int first_width,
|
||||||
|
|
@ -555,12 +562,6 @@ template <> value_t::operator ptime() const;
|
||||||
template <> value_t::operator double() const;
|
template <> value_t::operator double() const;
|
||||||
template <> value_t::operator std::string() const;
|
template <> value_t::operator std::string() const;
|
||||||
|
|
||||||
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& val);
|
std::ostream& operator<<(std::ostream& out, const value_t& val);
|
||||||
|
|
||||||
class value_context : public error_context
|
class value_context : public error_context
|
||||||
|
|
|
||||||
46
xml.cc
46
xml.cc
|
|
@ -9,11 +9,18 @@
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
namespace xml {
|
namespace xml {
|
||||||
|
|
||||||
document_t::document_t(node_t *, const char ** _builtins,
|
document_t::document_t(node_t * _top, const char ** _builtins,
|
||||||
const int _builtins_size)
|
const int _builtins_size)
|
||||||
: builtins(_builtins), builtins_size(_builtins_size),
|
: builtins(_builtins), builtins_size(_builtins_size),
|
||||||
top(new terminal_node_t(this)) {}
|
top(new terminal_node_t(this)) {}
|
||||||
|
|
||||||
|
void document_t::set_top(node_t * _top)
|
||||||
|
{
|
||||||
|
if (top)
|
||||||
|
delete top;
|
||||||
|
top = _top;
|
||||||
|
}
|
||||||
|
|
||||||
int document_t::register_name(const std::string& name)
|
int document_t::register_name(const std::string& name)
|
||||||
{
|
{
|
||||||
int index = lookup_name_id(name);
|
int index = lookup_name_id(name);
|
||||||
|
|
@ -102,16 +109,9 @@ node_t::node_t(document_t * _document, parent_node_t * _parent,
|
||||||
flags(_flags), info(NULL), attrs(NULL)
|
flags(_flags), info(NULL), attrs(NULL)
|
||||||
{
|
{
|
||||||
TRACE_CTOR("node_t(document_t *, node_t *)");
|
TRACE_CTOR("node_t(document_t *, node_t *)");
|
||||||
#ifdef THREADSAFE
|
|
||||||
document = _document;
|
document = _document;
|
||||||
#else
|
if (! document->top)
|
||||||
if (! document)
|
document->set_top(this);
|
||||||
document = _document;
|
|
||||||
#if 0
|
|
||||||
else
|
|
||||||
assert(document == _document);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
if (parent)
|
if (parent)
|
||||||
parent->add_child(this);
|
parent->add_child(this);
|
||||||
}
|
}
|
||||||
|
|
@ -359,6 +359,18 @@ document_t * parser_t::parse(std::istream& in, const char ** builtins,
|
||||||
return doc.release();
|
return doc.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node_t * commodity_node_t::children() const
|
||||||
|
{
|
||||||
|
// jww (2007-04-19): Need to report the commodity and its details
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_t * amount_node_t::children() const
|
||||||
|
{
|
||||||
|
// jww (2007-04-19): Need to report the quantity and commodity
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
node_t * transaction_node_t::children() const
|
node_t * transaction_node_t::children() const
|
||||||
{
|
{
|
||||||
if (! _children) {
|
if (! _children) {
|
||||||
|
|
@ -370,6 +382,20 @@ node_t * transaction_node_t::children() const
|
||||||
return parent_node_t::children();
|
return parent_node_t::children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node_t * transaction_node_t::lookup_child(int _name_id)
|
||||||
|
{
|
||||||
|
if (_name_id == payee_id) {
|
||||||
|
payee_virtual_node = new terminal_node_t(document);
|
||||||
|
payee_virtual_node->set_text(transaction->entry->payee);
|
||||||
|
return payee_virtual_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value_t transaction_node_t::to_value() const
|
||||||
|
{
|
||||||
|
return transaction->amount;
|
||||||
|
}
|
||||||
|
|
||||||
node_t * entry_node_t::children() const
|
node_t * entry_node_t::children() const
|
||||||
{
|
{
|
||||||
if (! _children) {
|
if (! _children) {
|
||||||
|
|
|
||||||
101
xml.h
101
xml.h
|
|
@ -49,6 +49,8 @@ class document_t
|
||||||
document_t(node_t * _top = NULL, const char ** _builtins = NULL,
|
document_t(node_t * _top = NULL, const char ** _builtins = NULL,
|
||||||
const int _builtins_size = 0);
|
const int _builtins_size = 0);
|
||||||
|
|
||||||
|
void set_top(node_t * _top);
|
||||||
|
|
||||||
int register_name(const std::string& name);
|
int register_name(const std::string& name);
|
||||||
int lookup_name_id(const std::string& name) const;
|
int lookup_name_id(const std::string& name) const;
|
||||||
const char * lookup_name(int id) const;
|
const char * lookup_name(int id) const;
|
||||||
|
|
@ -58,6 +60,14 @@ class document_t
|
||||||
|
|
||||||
#define XML_NODE_IS_PARENT 0x1
|
#define XML_NODE_IS_PARENT 0x1
|
||||||
|
|
||||||
|
class conversion_error : public error {
|
||||||
|
public:
|
||||||
|
conversion_error(const std::string& _reason,
|
||||||
|
error_context * _ctxt = NULL) throw()
|
||||||
|
: error(_reason, _ctxt) {}
|
||||||
|
virtual ~conversion_error() throw() {}
|
||||||
|
};
|
||||||
|
|
||||||
class parent_node_t;
|
class parent_node_t;
|
||||||
|
|
||||||
class node_t
|
class node_t
|
||||||
|
|
@ -124,6 +134,22 @@ public:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node_t * lookup_child(const char * _name) {
|
||||||
|
int id = document->lookup_name_id(_name);
|
||||||
|
return lookup_child(id);
|
||||||
|
}
|
||||||
|
node_t * lookup_child(const std::string& _name) {
|
||||||
|
int id = document->lookup_name_id(_name);
|
||||||
|
return lookup_child(id);
|
||||||
|
}
|
||||||
|
virtual node_t * lookup_child(int _name_id) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual value_t to_value() const {
|
||||||
|
throw new conversion_error("Cannot convert node to a value");
|
||||||
|
}
|
||||||
|
|
||||||
virtual void write(std::ostream& out, int depth = 0) const = 0;
|
virtual void write(std::ostream& out, int depth = 0) const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -187,6 +213,10 @@ public:
|
||||||
data = _data;
|
data = _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual value_t to_value() const {
|
||||||
|
return text();
|
||||||
|
}
|
||||||
|
|
||||||
void write(std::ostream& out, int depth = 0) const;
|
void write(std::ostream& out, int depth = 0) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -228,25 +258,76 @@ class parse_error : public error {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class transaction_node_t : public parent_node_t
|
class commodity_node_t : public parent_node_t
|
||||||
{
|
{
|
||||||
transaction_t * transaction;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
transaction_node_t(document_t * _document,
|
commodity_t * commodity;
|
||||||
transaction_t * _transaction,
|
|
||||||
|
commodity_node_t(document_t * _document,
|
||||||
|
commodity_t * _commodity,
|
||||||
parent_node_t * _parent = NULL)
|
parent_node_t * _parent = NULL)
|
||||||
: parent_node_t(_document, _parent), transaction(_transaction) {
|
: parent_node_t(_document, _parent), commodity(_commodity) {
|
||||||
TRACE_CTOR("transaction_node_t(document_t *, transaction_t *, parent_node_t *)");
|
TRACE_CTOR("commodity_node_t(document_t *, commodity_t *, parent_node_t *)");
|
||||||
set_name("transaction");
|
set_name("commodity");
|
||||||
}
|
}
|
||||||
virtual ~transaction_node_t() {
|
virtual ~commodity_node_t() {
|
||||||
TRACE_DTOR("transaction_node_t");
|
TRACE_DTOR("commodity_node_t");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual node_t * children() const;
|
virtual node_t * children() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class amount_node_t : public parent_node_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
amount_t * amount;
|
||||||
|
|
||||||
|
amount_node_t(document_t * _document,
|
||||||
|
amount_t * _amount,
|
||||||
|
parent_node_t * _parent = NULL)
|
||||||
|
: parent_node_t(_document, _parent), amount(_amount) {
|
||||||
|
TRACE_CTOR("amount_node_t(document_t *, amount_t *, parent_node_t *)");
|
||||||
|
set_name("amount");
|
||||||
|
}
|
||||||
|
virtual ~amount_node_t() {
|
||||||
|
TRACE_DTOR("amount_node_t");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual node_t * children() const;
|
||||||
|
|
||||||
|
virtual value_t to_value() const {
|
||||||
|
return *amount;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class transaction_node_t : public parent_node_t
|
||||||
|
{
|
||||||
|
int payee_id;
|
||||||
|
terminal_node_t * payee_virtual_node;
|
||||||
|
|
||||||
|
public:
|
||||||
|
transaction_t * transaction;
|
||||||
|
|
||||||
|
transaction_node_t(document_t * _document,
|
||||||
|
transaction_t * _transaction,
|
||||||
|
parent_node_t * _parent = NULL)
|
||||||
|
: parent_node_t(_document, _parent), transaction(_transaction),
|
||||||
|
payee_virtual_node(NULL) {
|
||||||
|
TRACE_CTOR("transaction_node_t(document_t *, transaction_t *, parent_node_t *)");
|
||||||
|
set_name("transaction");
|
||||||
|
payee_id = document->register_name("payee");
|
||||||
|
}
|
||||||
|
virtual ~transaction_node_t() {
|
||||||
|
TRACE_DTOR("transaction_node_t");
|
||||||
|
if (payee_virtual_node)
|
||||||
|
delete payee_virtual_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual node_t * children() const;
|
||||||
|
virtual node_t * lookup_child(int _name_id);
|
||||||
|
virtual value_t to_value() const;
|
||||||
|
};
|
||||||
|
|
||||||
class entry_node_t : public parent_node_t
|
class entry_node_t : public parent_node_t
|
||||||
{
|
{
|
||||||
entry_t * entry;
|
entry_t * entry;
|
||||||
|
|
|
||||||
13
xpath.cc
13
xpath.cc
|
|
@ -714,6 +714,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const
|
||||||
case token_t::SLASH:
|
case token_t::SLASH:
|
||||||
node.reset(new op_t(op_t::NODE_ID));
|
node.reset(new op_t(op_t::NODE_ID));
|
||||||
node->name_id = document_t::ROOT;
|
node->name_id = document_t::ROOT;
|
||||||
|
push_token();
|
||||||
break;
|
break;
|
||||||
case token_t::STAR:
|
case token_t::STAR:
|
||||||
node.reset(new op_t(op_t::NODE_ID));
|
node.reset(new op_t(op_t::NODE_ID));
|
||||||
|
|
@ -783,11 +784,6 @@ xpath_t::parse_path_expr(std::istream& in, unsigned short tflags) const
|
||||||
std::auto_ptr<op_t> node(parse_predicate_expr(in, tflags));
|
std::auto_ptr<op_t> node(parse_predicate_expr(in, tflags));
|
||||||
|
|
||||||
if (node.get()) {
|
if (node.get()) {
|
||||||
// If the beginning of the path was /, just put it back; this
|
|
||||||
// makes parsing much simpler.
|
|
||||||
if (node->kind == op_t::NODE_ID && node->name_id == document_t::ROOT)
|
|
||||||
push_token();
|
|
||||||
|
|
||||||
token_t& tok = next_token(in, tflags);
|
token_t& tok = next_token(in, tflags);
|
||||||
while (tok.kind == token_t::SLASH) {
|
while (tok.kind == token_t::SLASH) {
|
||||||
std::auto_ptr<op_t> prev(node.release());
|
std::auto_ptr<op_t> prev(node.release());
|
||||||
|
|
@ -843,7 +839,7 @@ xpath_t::parse_unary_expr(std::istream& in, unsigned short tflags) const
|
||||||
" operator not followed by argument");
|
" operator not followed by argument");
|
||||||
// A very quick optimization
|
// A very quick optimization
|
||||||
if (texpr->kind == op_t::VALUE) {
|
if (texpr->kind == op_t::VALUE) {
|
||||||
texpr->valuep->negate();
|
texpr->valuep->in_place_negate();
|
||||||
node.reset(texpr.release());
|
node.reset(texpr.release());
|
||||||
} else {
|
} else {
|
||||||
node.reset(new op_t(op_t::O_NEG));
|
node.reset(new op_t(op_t::O_NEG));
|
||||||
|
|
@ -1422,9 +1418,9 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left == expr) {
|
if (left == expr) {
|
||||||
return wrap_value(expr->valuep->negated())->acquire();
|
return wrap_value(expr->valuep->negate())->acquire();
|
||||||
} else {
|
} else {
|
||||||
expr->valuep->negate();
|
expr->valuep->in_place_negate();
|
||||||
return expr->acquire();
|
return expr->acquire();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1782,6 +1778,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
|
||||||
xpath_t lexpr(left->compile(context, scope, resolve));
|
xpath_t lexpr(left->compile(context, scope, resolve));
|
||||||
xpath_t rexpr(resolve ? right->acquire() :
|
xpath_t rexpr(resolve ? right->acquire() :
|
||||||
right->compile(context, scope, false));
|
right->compile(context, scope, false));
|
||||||
|
|
||||||
if (! lexpr->constant() || ! resolve) {
|
if (! lexpr->constant() || ! resolve) {
|
||||||
if (left == lexpr)
|
if (left == lexpr)
|
||||||
return acquire();
|
return acquire();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue