Many changes.

This commit is contained in:
John Wiegley 2007-05-21 20:42:05 +00:00
parent f12d41f233
commit 7380da43ab
62 changed files with 392 additions and 1313 deletions

View file

@ -9,15 +9,11 @@ ESC_srcdir=`echo "$(srcdir)" | sed 's/\//\\\\\//g'`
ESC_builddir=`echo "$(top_builddir)" | sed 's/\//\\\\\//g'` ESC_builddir=`echo "$(top_builddir)" | sed 's/\//\\\\\//g'`
ESC_distdir=`echo "$(distdir)" | sed 's/\//\\\\\//g'` ESC_distdir=`echo "$(distdir)" | sed 's/\//\\\\\//g'`
#(cd $(distdir)/docs; zip -r doxygen-html.zip html; rm -fr html)
dist-hook: dist-hook:
rm -fr `find $(distdir) -name .svn` rm -fr `find $(distdir) -name .svn`
lib_LTLIBRARIES = libledger.la lib_LTLIBRARIES = libledger.la
if HAVE_BOOST_PYTHON
lib_LTLIBRARIES += libpyledger.la
endif
AM_YFLAGS = -d AM_YFLAGS = -d
AM_LFLAGS = -o $(LEX_OUTPUT_ROOT).c AM_LFLAGS = -o $(LEX_OUTPUT_ROOT).c
@ -34,38 +30,42 @@ libledger_la_CPPFLAGS = -I$(top_builddir)/gdtoa -I$(srcdir)/gdtoa \
libledger_la_LDFLAGS = -release $(PACKAGE_VERSION) libledger_la_LDFLAGS = -release $(PACKAGE_VERSION)
libledger_la_SOURCES = \ libledger_la_SOURCES = \
src/utils.cc \ src/utility/utils.cc \
src/times.cc \ src/utility/times.cc \
src/mask.cc \ src/utility/binary.cc \
src/abbrev.cc \ src/utility/mask.cc \
src/commodity.cc \ src/numerics/commodity.cc \
src/amount.cc \ src/numerics/amount.cc \
src/balance.cc \ src/numerics/balance.cc \
src/value.cc \ src/numerics/value.cc \
src/document.cc \ src/data/document.cc \
src/node.cc \ src/data/node.cc \
src/compile.cc \ src/data/textual.cc \
src/jbuilder.cc \ src/data/compile.cc \
src/xpath.cc \ src/data/journal.cc \
src/journal.cc \ src/data/jbuilder.cc \
src/textual.cc \ src/traversal/xpath.cc \
src/binary.cc \ src/traversal/transform.cc \
src/transform.cc \ src/traversal/abbrev.cc \
src/report.cc \ src/driver/session.cc \
src/session.cc src/driver/report.cc
#if HAVE_EXPAT if HAVE_BOOST_PYTHON
#libledger_la_CPPFLAGS += -DHAVE_EXPAT=1 Python_SRC = \
#libledger_la_SOURCES += src/gnucash.cc src/python/pyinterp.cc \
#endif src/python/pyledger.cc \
#if HAVE_XMLPARSE src/python/py_amount.cc \
#libledger_la_CPPFLAGS += -DHAVE_XMLPARSE=1 src/python/py_commodity.cc \
#libledger_la_SOURCES += src/gnucash.cc src/python/py_times.cc \
#endif src/python/py_utils.cc
#if HAVE_LIBOFX
#libledger_la_CPPFLAGS += -DHAVE_LIBOFX=1 libledger_la_SOURCES += $(Python_SRC)
#libledger_la_SOURCES += src/ofx.cc endif
#endif
if HAVE_LIBOFX
libledger_la_CPPFLAGS += -DHAVE_LIBOFX=1
libledger_la_SOURCES += src/ofx.cc
endif
if DEBUG if DEBUG
libledger_la_CPPFLAGS += -DDEBUG_MODE libledger_la_CPPFLAGS += -DDEBUG_MODE
endif endif
@ -76,60 +76,45 @@ nodist_libledger_la_SOURCES = system.hh.gch
BUILT_SOURCES += system.hh.gch BUILT_SOURCES += system.hh.gch
CLEANFILES += system.hh.gch system.hh CLEANFILES += system.hh.gch system.hh
$(top_builddir)/system.hh.gch: $(srcdir)/src/system.hh acconf.h $(top_builddir)/system.hh.gch: $(srcdir)/src/utility/system.hh acconf.h
echo "#include \"src/system.hh\"" > $(top_builddir)/system.hh echo "#include \"src/system.hh\"" > $(top_builddir)/system.hh
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(libledger_la_CPPFLAGS) \ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(libledger_la_CPPFLAGS) \
-o $@ $(srcdir)/src/system.hh -o $@ $(srcdir)/src/utility/system.hh
endif endif
libpyledger_la_CPPFLAGS = $(libledger_la_CPPFLAGS)
libpyledger_la_LDFLAGS = -release $(PACKAGE_VERSION)
libpyledger_la_SOURCES = \
src/pyinterp.cc \
src/py_utils.cc \
src/py_times.cc \
src/py_commodity.cc \
src/py_amount.cc
pkginclude_HEADERS = \ pkginclude_HEADERS = \
src/abbrev.h \ src/ledger.h \
src/amount.h \ src/utility/binary.h \
src/balance.h \ src/utility/context.h \
src/balpair.h \ src/utility/flags.h \
src/binary.h \ src/utility/mask.h \
src/builder.h \ src/utility/pushvar.h \
src/jbuilder.h \ src/utility/times.h \
src/commodity.h \ src/utility/utils.h \
src/compile.h \ src/numerics/amount.h \
src/context.h \ src/numerics/balance.h \
src/document.h \ src/numerics/balpair.h \
src/fdstream.hpp \ src/numerics/commodity.h \
src/flags.h \ src/numerics/value.h \
src/format.h \ src/data/builder.h \
src/journal.h \ src/data/compile.h \
src/ledger.h \ src/data/document.h \
src/mask.h \ src/data/jbuilder.h \
src/node.h \ src/data/journal.h \
src/option.h \ src/data/node.h \
src/parser.h \ src/data/parser.h \
src/pyfstream.h \ src/data/textual.h \
src/pyinterp.h \ src/traversal/abbrev.h \
src/pyledger.h \ src/traversal/transform.h \
src/pyutils.h \ src/traversal/xpath.h \
src/report.h \ src/driver/option.h \
src/scoped_execute.h \ src/driver/report.h \
src/session.h \ src/driver/session.h \
src/system.hh \ src/python/pyfstream.h \
src/textual.h \ src/python/pyinterp.h \
src/times.h \ src/python/pyledger.h \
src/transform.h \ src/python/pyutils.h
src/tuples.hpp \
src/utils.h \
src/value.h \
src/xpath.h
############################################################################### ###############################################################################
@ -138,14 +123,7 @@ bin_PROGRAMS = ledger
ledger_CPPFLAGS = $(libledger_la_CPPFLAGS) ledger_CPPFLAGS = $(libledger_la_CPPFLAGS)
ledger_LDADD = $(LIBOBJS) libledger.la gdtoa/libgdtoa.la $(LEXLIB) ledger_LDADD = $(LIBOBJS) libledger.la gdtoa/libgdtoa.la $(LEXLIB)
ledger_LDFLAGS = -static # for the sake of command-line speed ledger_LDFLAGS = -static # for the sake of command-line speed
ledger_SOURCES = src/driver/option.cc src/driver/main.cc
ledger_SOURCES = \
src/option.cc \
src/main.cc
if HAVE_BOOST_PYTHON
ledger_LDADD += libpyledger.la
endif
nodist_info_TEXINFOS = docs/ledger.texi nodist_info_TEXINFOS = docs/ledger.texi
@ -166,31 +144,18 @@ CLEANFILES += ledger.so
clean-local: clean-local:
rm -fr build rm -fr build
ledger_so_SOURCES = \ ledger_so_SOURCES = $(Python_SRC)
src/pyledger.cc \ ledger_so_DEPENDENCIES = libledger.la gdtoa/libgdtoa.la
src/pyinterp.cc \
src/py_utils.cc \
src/py_times.cc \
src/py_commodity.cc \
src/py_amount.cc
ledger_so_DEPENDENCIES = libledger.la gdtoa/libgdtoa.la libpyledger.la PYLIBS = ledger gdtoa gmp \
boost_date_time$(BOOST_SUFFIX) \
PYLIBS = pyledger ledger gdtoa gmp
PYLIBS += boost_date_time$(BOOST_SUFFIX) \
boost_filesystem$(BOOST_SUFFIX) \ boost_filesystem$(BOOST_SUFFIX) \
boost_regex$(BOOST_SUFFIX) \ boost_regex$(BOOST_SUFFIX) \
boost_python$(BOOST_SUFFIX) boost_python$(BOOST_SUFFIX)
#if HAVE_EXPAT if HAVE_LIBOFX
#PYLIBS += expat PYLIBS += ofx
#endif endif
#if HAVE_XMLPARSE
#PYLIBS += xmlparse xmltok
#endif
#if HAVE_LIBOFX
#PYLIBS += ofx
#endif
ledger.so: $(ledger_so_SOURCES) $(ledger_so_DEPENDENCIES) ledger.so: $(ledger_so_SOURCES) $(ledger_so_DEPENDENCIES)
CFLAGS="$(CPPFLAGS) -I$(srcdir) $(libledger_la_CPPFLAGS)" \ CFLAGS="$(CPPFLAGS) -I$(srcdir) $(libledger_la_CPPFLAGS)" \

View file

@ -7,7 +7,7 @@ AC_INIT([ledger],[3.0],[johnw@newartisans.com])
AC_CONFIG_SRCDIR(ledger) AC_CONFIG_SRCDIR(ledger)
AM_INIT_AUTOMAKE([dist-bzip2]) AM_INIT_AUTOMAKE([dist-bzip2])
AC_CONFIG_SRCDIR([src/main.cc]) AC_CONFIG_SRCDIR([src/driver/main.cc])
AC_CONFIG_HEADER([acconf.h]) AC_CONFIG_HEADER([acconf.h])
AC_CONFIG_SUBDIRS([gdtoa]) AC_CONFIG_SUBDIRS([gdtoa])
@ -17,14 +17,6 @@ AC_PROG_MAKE_SET
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AM_PROG_LIBTOOL AM_PROG_LIBTOOL
#AC_PROG_YACC
#AC_PROG_LEX
#if test "$LEX" != flex; then
# LEX="$SHELL $missing_dir/missing flex"
# AC_SUBST(LEX_OUTPUT_ROOT, lex.yy)
# AC_SUBST(LEXLIB, '')
#fi
# Checks for emacs lisp path # Checks for emacs lisp path
AM_PATH_LISPDIR AM_PATH_LISPDIR
@ -61,30 +53,35 @@ AC_CACHE_CHECK(
[if pipes can be used], [if pipes can be used],
[pipes_avail], [pipes_avail],
[AC_LANG_PUSH(C++) [AC_LANG_PUSH(C++)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> AC_LINK_IFELSE(
#include <sys/wait.h> [AC_LANG_PROGRAM(
#include <unistd.h> [[#include <sys/types.h>
#include <stdlib.h> #include <sys/wait.h>
#include <string.h> #include <unistd.h>
#include <stdio.h>]], [[int status, pfd[2]; #include <stdlib.h>
status = pipe(pfd); #include <string.h>
status = fork(); #include <stdio.h>]],
if (status < 0) { [[int status, pfd[2];
; status = pipe(pfd);
} else if (status == 0) { status = fork();
char *arg0; if (status < 0) {
;
} else if (status == 0) {
char *arg0;
status = dup2(pfd[0], STDIN_FILENO); status = dup2(pfd[0], STDIN_FILENO);
close(pfd[1]); close(pfd[1]);
close(pfd[0]); close(pfd[0]);
execlp("", arg0, (char *)0); execlp("", arg0, (char *)0);
perror("execl"); perror("execl");
exit(1); exit(1);
} else { } else {
close(pfd[0]); close(pfd[0]);
}]])],[pipes_avail=true],[pipes_avail=false]) }]])],
[pipes_avail=true],
[pipes_avail=false])
AC_LANG_POP]) AC_LANG_POP])
if [test x$pipes_avail = xtrue ]; then if [test x$pipes_avail = xtrue ]; then
@ -98,7 +95,12 @@ AC_CACHE_CHECK(
[boost_regex_save_libs=$LIBS [boost_regex_save_libs=$LIBS
LIBS="-lboost_regex$BOOST_SUFFIX $LIBS" LIBS="-lboost_regex$BOOST_SUFFIX $LIBS"
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <boost/regex.hpp>]], [[boost::regex foo_regexp("Hello, world!");]])],[boost_regex_avail=true],[boost_regex_avail=false]) AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <boost/regex.hpp>]],
[[boost::regex foo_regexp("Hello, world!");]])],
[boost_regex_avail=true],
[boost_regex_avail=false])
AC_LANG_POP AC_LANG_POP
LIBS=$boost_regex_save_libs]) LIBS=$boost_regex_save_libs])
@ -115,25 +117,30 @@ AC_CACHE_CHECK(
[boost_date_time_save_libs=$LIBS [boost_date_time_save_libs=$LIBS
LIBS="-lboost_date_time$BOOST_SUFFIX $LIBS" LIBS="-lboost_date_time$BOOST_SUFFIX $LIBS"
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <boost/date_time/posix_time/posix_time.hpp> AC_LINK_IFELSE(
#include <boost/date_time/gregorian/gregorian.hpp> [AC_LANG_PROGRAM(
#include <boost/date_time/local_time_adjustor.hpp> [[#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/time_duration.hpp> #include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/local_time_adjustor.hpp>
#include <boost/date_time/time_duration.hpp>
using namespace boost::posix_time; using namespace boost::posix_time;
using namespace boost::date_time; using namespace boost::date_time;
#include <ctime> #include <ctime>
inline ptime time_to_system_local(const ptime& when) { inline ptime time_to_system_local(const ptime& when) {
struct std::tm tm_gmt = to_tm(when); struct std::tm tm_gmt = to_tm(when);
return from_time_t(mktime(&tm_gmt)); return from_time_t(mktime(&tm_gmt));
}]], [[ptime t10 = ptime(boost::gregorian::from_string("2007-01-15"), }]],
ptime::time_duration_type()); [[ptime t10 = ptime(boost::gregorian::from_string("2007-01-15"),
ptime::time_duration_type());
ptime t12 = time_to_system_local(t10); ptime t12 = time_to_system_local(t10);
return t10 != t12;]])],[boost_date_time_cpplib_avail=true],[boost_date_time_cpplib_avail=false]) return t10 != t12;]])],
[boost_date_time_cpplib_avail=true],
[boost_date_time_cpplib_avail=false])
AC_LANG_POP AC_LANG_POP
LIBS=$boost_date_time_save_libs]) LIBS=$boost_date_time_save_libs])
@ -150,7 +157,12 @@ AC_CACHE_CHECK(
[boost_filesystem_save_libs=$LIBS [boost_filesystem_save_libs=$LIBS
LIBS="-lboost_filesystem$BOOST_SUFFIX $LIBS" LIBS="-lboost_filesystem$BOOST_SUFFIX $LIBS"
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <boost/filesystem/path.hpp>]], [[boost::filesystem::path this_path("Hello");]])],[boost_filesystem_cpplib_avail=true],[boost_filesystem_cpplib_avail=false]) AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <boost/filesystem/path.hpp>]],
[[boost::filesystem::path this_path("Hello");]])],
[boost_filesystem_cpplib_avail=true],
[boost_filesystem_cpplib_avail=false])
AC_LANG_POP AC_LANG_POP
LIBS=$boost_filesystem_save_libs]) LIBS=$boost_filesystem_save_libs])
@ -167,7 +179,12 @@ fi
# [boost_signals_save_libs=$LIBS # [boost_signals_save_libs=$LIBS
# LIBS="-lboost_signals$BOOST_SUFFIX $LIBS" # LIBS="-lboost_signals$BOOST_SUFFIX $LIBS"
# AC_LANG_PUSH(C++) # AC_LANG_PUSH(C++)
# AC_LINK_IFELSE([AC_LANG_PROGRAM([[# #include <boost/signal.hpp>]], [[# boost::signal<void (void)> this_signal;]])],[# boost_signals_cpplib_avail=true],[# boost_signals_cpplib_avail=false]) # AC_LINK_IFELSE(
# [AC_LANG_PROGRAM(
# [[#include <boost/signal.hpp>]],
# [[boost::signal<void (void)> this_signal;]])],
# [boost_signals_cpplib_avail=true],
# [boost_signals_cpplib_avail=false])
# AC_LANG_POP # AC_LANG_POP
# LIBS=$boost_signals_save_libs]) # LIBS=$boost_signals_save_libs])
# #
@ -196,71 +213,6 @@ else
AC_MSG_FAILURE("Could not find gmp library (set CPPFLAGS and LDFLAGS?)") AC_MSG_FAILURE("Could not find gmp library (set CPPFLAGS and LDFLAGS?)")
fi fi
## check for expat or xmlparse
#AC_ARG_ENABLE(xml,
# [ --enable-xml Turn on support for XML parsing],
# [case "${enableval}" in
# yes) xml=true ;;
# no) xml=false ;;
# *) AC_MSG_ERROR(bad value ${enableval} for --enable-xml) ;;
# esac],[xml=true])
#
#AM_CONDITIONAL(USE_XML, test x$xml = xtrue)
#
#if [test x$xml = xtrue ]; then
# AC_CACHE_CHECK(
# [if libexpat is available],
# [libexpat_avail],
# [libexpat_save_libs=$LIBS
# LIBS="-lexpat $LIBS"
# AC_LANG_PUSH(C++)
# AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
# extern "C" {
# #include <expat.h> // expat XML parser
# }]], [[XML_Parser parser = XML_ParserCreate(NULL);
# return parser != NULL;]])],[libexpat_avail=true],[libexpat_avail=false])
# AC_LANG_POP
# LIBS=$libexpat_save_libs])
#
# if [test x$libexpat_avail = xtrue ]; then
# AM_CONDITIONAL(HAVE_EXPAT, true)
# LIBS="-lexpat $LIBS"
# else
# AM_CONDITIONAL(HAVE_EXPAT, false)
# fi
#else
# AM_CONDITIONAL(HAVE_EXPAT, false)
#fi
#
#if [test x$xml = xtrue ]; then
# if [test x$libexpat_avail = xfalse ]; then
# AC_CACHE_CHECK(
# [if libxmlparse is available],
# [libxmlparse_avail],
# [libxmlparse_save_libs=$LIBS
# LIBS="-lxmlparse -lxmltok $LIBS"
# AC_LANG_PUSH(C++)
# AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
# extern "C" {
# #include <xmlparse.h> // expat XML parser
# }]], [[XML_Parser parser = XML_ParserCreate(NULL);
# return parser != NULL;]])],[libxmlparse_avail=true],[libxmlparse_avail=false])
# AC_LANG_POP
# LIBS=$libxmlparse_save_libs])
#
# if [test x$libxmlparse_avail = xtrue ]; then
# AM_CONDITIONAL(HAVE_XMLPARSE, true)
# LIBS="-lxmlparse -lxmltok $LIBS"
# else
# AM_CONDITIONAL(HAVE_XMLPARSE, false)
# fi
# else
# AM_CONDITIONAL(HAVE_XMLPARSE, false)
# fi
#else
# AM_CONDITIONAL(HAVE_XMLPARSE, false)
#fi
# check for libofx # check for libofx
AC_ARG_ENABLE(ofx, AC_ARG_ENABLE(ofx,
[ --enable-ofx Turn on support for OFX/OCF parsing], [ --enable-ofx Turn on support for OFX/OCF parsing],
@ -279,7 +231,12 @@ if [test x$ofx = xtrue ]; then
[libofx_save_libs=$LIBS [libofx_save_libs=$LIBS
LIBS="-lofx $LIBS" LIBS="-lofx $LIBS"
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <libofx.h>]], [[ LibofxContextPtr libofx_context = libofx_get_new_context();]])],[libofx_avail=true],[libofx_avail=false]) AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <libofx.h>]],
[[LibofxContextPtr libofx_context = libofx_get_new_context();]])],
[libofx_avail=true],
[libofx_avail=false])
AC_LANG_POP AC_LANG_POP
LIBS=$libofx_save_libs]) LIBS=$libofx_save_libs])
@ -313,12 +270,17 @@ if [test x$python = xtrue ]; then
[boost_python_save_libs=$LIBS [boost_python_save_libs=$LIBS
LIBS="-lboost_python$BOOST_SUFFIX -lpython$PYTHON_VERSION $LIBS" LIBS="-lboost_python$BOOST_SUFFIX -lpython$PYTHON_VERSION $LIBS"
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <boost/python.hpp> AC_LINK_IFELSE(
using namespace boost::python; [AC_LANG_PROGRAM(
class foo {}; [[#include <boost/python.hpp>
BOOST_PYTHON_MODULE(samp) { using namespace boost::python;
class_< foo > ("foo") ; class foo {};
}]], [[return 0]])],[boost_python_cpplib_avail=true],[boost_python_cpplib_avail=false]) BOOST_PYTHON_MODULE(samp) {
class_< foo > ("foo") ;
}]],
[[return 0]])],
[boost_python_cpplib_avail=true],
[boost_python_cpplib_avail=false])
AC_LANG_POP AC_LANG_POP
LIBS=$boost_python_save_libs]) LIBS=$boost_python_save_libs])
@ -342,15 +304,20 @@ AC_CACHE_CHECK(
[cppunit_save_libs=$LIBS [cppunit_save_libs=$LIBS
LIBS="-lcppunit $LIBS" LIBS="-lcppunit $LIBS"
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <cppunit/CompilerOutputter.h> AC_LINK_IFELSE(
#include <cppunit/TestResult.h> [AC_LANG_PROGRAM(
#include <cppunit/TestResultCollector.h> [[#include <cppunit/CompilerOutputter.h>
#include <cppunit/TestRunner.h> #include <cppunit/TestResult.h>
#include <cppunit/TextTestProgressListener.h> #include <cppunit/TestResultCollector.h>
#include <cppunit/BriefTestProgressListener.h> #include <cppunit/TestRunner.h>
#include <cppunit/XmlOutputter.h> #include <cppunit/TextTestProgressListener.h>
#include <cppunit/extensions/TestFactoryRegistry.h>]], [[CPPUNIT_NS::TestResult controller; #include <cppunit/BriefTestProgressListener.h>
CPPUNIT_NS::TestResultCollector result;]])],[cppunit_avail=true],[cppunit_avail=false]) #include <cppunit/XmlOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>]],
[[CPPUNIT_NS::TestResult controller;
CPPUNIT_NS::TestResultCollector result;]])],
[cppunit_avail=true],
[cppunit_avail=false])
AC_LANG_POP AC_LANG_POP
LIBS=$cppunit_save_libs]) LIBS=$cppunit_save_libs])

View file

@ -1,14 +1,12 @@
- What does SEQUENCE + VALUE mean in XPath? Does it add VALUE to - What does SEQUENCE + VALUE mean in XPath? Does it add VALUE to
every member of SEQUENCE? every member of SEQUENCE?
- Add tracing code for functions that records call count and total Answer: No, it doesn't; this should throw an error
time spent, as well as average time per call. This would implement
selective profiling.
- Make sure that if any constructors cause memory to be allocated, - Make sure that if any constructors cause memory to be allocated, the
that the memory is held by an auto_ptr until the constructor is memory is held by an auto_ptr until the constructor is done;
done; otherwise, an exception raised from within the constructor otherwise, an exception raised from within the constructor will not
will not call the destructor to free the memory. call the destructor to free the memory.
- Using mmap for the binary reader; or determine if the performance is - Using mmap for the binary reader; or determine if the performance is
even worth the maintenance headaches of that code altogether. even worth the maintenance headaches of that code altogether.

View file

@ -585,29 +585,35 @@ amount_t& amount_t::in_place_negate()
return *this; return *this;
} }
amount_t amount_t::round(precision_t prec) const amount_t amount_t::round(const optional<precision_t>& prec) const
{ {
if (! quantity) if (! quantity)
throw_(amount_error, "Cannot round an uninitialized amount"); throw_(amount_error, "Cannot round an uninitialized amount");
amount_t t(*this); if (! prec) {
if (! has_commodity())
return *this;
return round(commodity().precision());
} else {
amount_t t(*this);
if (quantity->prec <= prec) { if (quantity->prec <= *prec) {
if (quantity && quantity->has_flags(BIGINT_KEEP_PREC)) { if (quantity && quantity->has_flags(BIGINT_KEEP_PREC)) {
t._dup(); t._dup();
t.quantity->drop_flags(BIGINT_KEEP_PREC); t.quantity->drop_flags(BIGINT_KEEP_PREC);
}
return t;
} }
t._dup();
mpz_round(MPZ(t.quantity), MPZ(t.quantity), t.quantity->prec, *prec);
t.quantity->prec = *prec;
t.quantity->drop_flags(BIGINT_KEEP_PREC);
return t; return t;
} }
t._dup();
mpz_round(MPZ(t.quantity), MPZ(t.quantity), t.quantity->prec, prec);
t.quantity->prec = prec;
t.quantity->drop_flags(BIGINT_KEEP_PREC);
return t;
} }
amount_t amount_t::unround() const amount_t amount_t::unround() const
@ -1212,10 +1218,12 @@ namespace {
void amount_t::read(std::istream& in) void amount_t::read(std::istream& in)
{ {
using ledger::binary;
// Read in the commodity for this amount // Read in the commodity for this amount
commodity_t::ident_t ident; commodity_t::ident_t ident;
read_binary_long(in, ident); read_long(in, ident);
if (ident == 0xffffffff) if (ident == 0xffffffff)
commodity_ = NULL; commodity_ = NULL;
else if (ident == 0) else if (ident == 0)
@ -1258,10 +1266,12 @@ void amount_t::read(std::istream& in)
void amount_t::read(const char *& data) void amount_t::read(const char *& data)
{ {
using ledger::binary;
// Read in the commodity for this amount // Read in the commodity for this amount
commodity_t::ident_t ident; commodity_t::ident_t ident;
read_binary_long(data, ident); read_long(data, ident);
if (ident == 0xffffffff) if (ident == 0xffffffff)
commodity_ = NULL; commodity_ = NULL;
else if (ident == 0) else if (ident == 0)
@ -1313,15 +1323,17 @@ void amount_t::read(const char *& data)
void amount_t::write(std::ostream& out, bool optimized) const void amount_t::write(std::ostream& out, bool optimized) const
{ {
using ledger::binary;
// Write out the commodity for this amount // Write out the commodity for this amount
if (! quantity) if (! quantity)
throw_(amount_error, "Cannot serialize an uninitialized amount"); throw_(amount_error, "Cannot serialize an uninitialized amount");
if (commodity_) if (commodity_)
write_binary_long(out, commodity_->ident); write_long(out, commodity_->ident);
else else
write_binary_long<commodity_t::ident_t>(out, 0xffffffff); write_long<commodity_t::ident_t>(out, 0xffffffff);
// Write out the quantity // Write out the quantity

View file

@ -294,11 +294,11 @@ public:
* abs() returns the absolute value of an amount. It is equivalent * abs() returns the absolute value of an amount. It is equivalent
* to: `(x < 0) ? - x : x'. * to: `(x < 0) ? - x : x'.
* *
* round(precision_t) rounds an amount's internal value to the given * round(optional<precision_t>) rounds an amount's internal value to
* precision. * the given precision, or to the commodity's current display
* * precision if no precision value is given. This method changes
* round() rounds an amount to its commodity's current display * the internal value of the amount, if it's internal precision was
* precision. This also changes the internal value of the amount. * greater than the rounding precision.
* *
* unround() yields an amount whose display precision is never * unround() yields an amount whose display precision is never
* truncated, even though its commodity normally displays only * truncated, even though its commodity normally displays only
@ -347,8 +347,7 @@ public:
return *this; return *this;
} }
amount_t round(precision_t prec) const; amount_t round(const optional<precision_t>& prec) const;
amount_t round() const;
amount_t unround() const; amount_t unround() const;
amount_t reduce() const { amount_t reduce() const {
@ -700,16 +699,7 @@ inline bool amount_t::operator==(const amount_t& amt) const {
return compare(amt) == 0; return compare(amt) == 0;
} }
inline amount_t amount_t::round() const {
if (! quantity)
throw_(amount_error, "Cannot round an uninitialized amount");
if (! has_commodity())
return *this;
return round(commodity().precision());
}
inline commodity_t& amount_t::commodity() const { inline commodity_t& amount_t::commodity() const {
// jww (2007-05-02): Should be a way to access null_commodity better
return has_commodity() ? *commodity_ : *current_pool->null_commodity; return has_commodity() ? *commodity_ : *current_pool->null_commodity;
} }

View file

@ -234,7 +234,26 @@ public:
balance_t& operator-=(const amount_t& amt); balance_t& operator-=(const amount_t& amt);
balance_t& operator*=(const amount_t& amt); balance_t& operator*=(const amount_t& amt);
balance_t& operator*=(const double val) {
return *this *= amount_t(val);
}
balance_t& operator*=(const unsigned long val) {
return *this *= amount_t(val);
}
balance_t& operator*=(const long val) {
return *this *= amount_t(val);
}
balance_t& operator/=(const amount_t& amt); balance_t& operator/=(const amount_t& amt);
balance_t& operator/=(const double val) {
return *this /= amount_t(val);
}
balance_t& operator/=(const unsigned long val) {
return *this /= amount_t(val);
}
balance_t& operator/=(const long val) {
return *this /= amount_t(val);
}
/** /**
* Unary arithmetic operators. There are only a few unary methods * Unary arithmetic operators. There are only a few unary methods

View file

@ -167,21 +167,50 @@ public:
return *this = balance_t(str); return *this = balance_t(str);
} }
// in-place arithmetic /**
* Binary arithmetic operators. Balances support addition and
* subtraction of other balance pairs, balances or amounts, but
* multiplication and division are restricted to uncommoditized
* amounts only.
*/
balance_pair_t& operator+=(const balance_pair_t& bal_pair) { balance_pair_t& operator+=(const balance_pair_t& bal_pair) {
if (bal_pair.cost && ! cost) balance_t::operator+=(bal_pair);
cost = quantity; if (bal_pair.cost) {
quantity += bal_pair.quantity; if (! cost)
if (cost) *cost = quantity();
*cost += bal_pair.cost ? *bal_pair.cost : bal_pair.quantity; *cost += *bal_pair.cost;
}
return *this; return *this;
} }
balance_pair_t& operator-=(const balance_pair_t& bal_pair) { balance_pair_t& operator-=(const balance_pair_t& bal_pair) {
if (bal_pair.cost && ! cost) balance_t::operator+=(bal_pair);
cost = quantity; if (bal_pair.cost) {
quantity -= bal_pair.quantity; if (! cost)
*cost = quantity();
*cost += *bal_pair.cost;
}
return *this;
}
balance_pair_t& operator*=(const amount_t& amt) {
balance_t::operator*=(amt);
if (cost) if (cost)
*cost -= bal_pair.cost ? *bal_pair.cost : bal_pair.quantity; *cost *= amt;
return *this;
}
balance_pair_t& operator*=(const double val) {
return *this *= amount_t(val);
}
balance_pair_t& operator*=(const unsigned long val) {
return *this *= amount_t(val);
}
balance_pair_t& operator*=(const long val) {
return *this *= amount_t(val);
}
balance_pair_t& operator/=(const amount_t& amt) {
balance_t::operator/=(amt);
if (cost)
*cost /= amt;
return *this; return *this;
} }

File diff suppressed because it is too large Load diff

View file

@ -29,217 +29,203 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _BINARY_H #ifndef BINARY_H
#define _BINARY_H #define BINARY_H
#include "parser.h"
namespace ledger { namespace ledger {
namespace binary {
#if 0
class binary_parser_t : public parser_t
{
public:
virtual bool test(std::istream& in) const;
virtual unsigned int parse(std::istream& in,
journal_t * journal,
account_t * master = NULL,
const string * original_file = NULL);
};
#endif
template <typename T> template <typename T>
inline void read_binary_number_nocheck(std::istream& in, T& num) { inline void read_number_nocheck(std::istream& in, T& num) {
in.read((char *)&num, sizeof(num)); in.read((char *)&num, sizeof(num));
} }
template <typename T> template <typename T>
inline void read_binary_number_nocheck(const char *& data, T& num) { inline void read_number_nocheck(const char *& data, T& num) {
num = *((T *) data); num = *((T *) data);
data += sizeof(T); data += sizeof(T);
} }
template <typename T> template <typename T>
inline T read_binary_number_nocheck(std::istream& in) { inline T read_number_nocheck(std::istream& in) {
T num; T num;
read_binary_number_nocheck(in, num); read_number_nocheck(in, num);
return num; return num;
} }
template <typename T> template <typename T>
inline T read_binary_number_nocheck(const char *& data) { inline T read_number_nocheck(const char *& data) {
T num; T num;
read_binary_number_nocheck(data, num); read_number_nocheck(data, num);
return num; return num;
} }
#if DEBUG_LEVEL >= ALPHA #if DEBUG_LEVEL >= ALPHA
#define read_binary_guard(in, id) \ #define read_guard(in, id) \
if (read_binary_number_nocheck<unsigned short>(in) != id) \ if (read_number_nocheck<unsigned short>(in) != id) \
assert(false); assert(false);
#else #else
#define read_binary_guard(in, id) #define read_guard(in, id)
#endif #endif
template <typename T> template <typename T>
inline void read_binary_number(std::istream& in, T& num) { inline void read_number(std::istream& in, T& num) {
read_binary_guard(in, 0x2003); read_guard(in, 0x2003);
in.read((char *)&num, sizeof(num)); in.read((char *)&num, sizeof(num));
read_binary_guard(in, 0x2004); read_guard(in, 0x2004);
} }
template <typename T> template <typename T>
inline void read_binary_number(const char *& data, T& num) { inline void read_number(const char *& data, T& num) {
read_binary_guard(data, 0x2003); read_guard(data, 0x2003);
num = *((T *) data); num = *((T *) data);
data += sizeof(T); data += sizeof(T);
read_binary_guard(data, 0x2004); read_guard(data, 0x2004);
} }
template <typename T> template <typename T>
inline T read_binary_number(std::istream& in) { inline T read_number(std::istream& in) {
T num; T num;
read_binary_number(in, num); read_number(in, num);
return num; return num;
} }
template <typename T> template <typename T>
inline T read_binary_number(const char *& data) { inline T read_number(const char *& data) {
T num; T num;
read_binary_number(data, num); read_number(data, num);
return num; return num;
} }
void read_binary_bool(std::istream& in, bool& num); void read_bool(std::istream& in, bool& num);
void read_binary_bool(const char *& data, bool& num); void read_bool(const char *& data, bool& num);
inline bool read_binary_bool(std::istream& in) { inline bool read_bool(std::istream& in) {
bool num; bool num;
read_binary_bool(in, num); read_bool(in, num);
return num; return num;
} }
inline bool read_binary_bool(const char *& data) { inline bool read_bool(const char *& data) {
bool num; bool num;
read_binary_bool(data, num); read_bool(data, num);
return num; return num;
} }
template <typename T> template <typename T>
void read_binary_long(std::istream& in, T& num) void read_long(std::istream& in, T& num)
{ {
read_binary_guard(in, 0x2001); read_guard(in, 0x2001);
unsigned char len; unsigned char len;
read_binary_number_nocheck(in, len); read_number_nocheck(in, len);
num = 0; num = 0;
unsigned char temp; unsigned char temp;
if (len > 3) { if (len > 3) {
read_binary_number_nocheck(in, temp); read_number_nocheck(in, temp);
num |= ((unsigned long)temp) << 24; num |= ((unsigned long)temp) << 24;
} }
if (len > 2) { if (len > 2) {
read_binary_number_nocheck(in, temp); read_number_nocheck(in, temp);
num |= ((unsigned long)temp) << 16; num |= ((unsigned long)temp) << 16;
} }
if (len > 1) { if (len > 1) {
read_binary_number_nocheck(in, temp); read_number_nocheck(in, temp);
num |= ((unsigned long)temp) << 8; num |= ((unsigned long)temp) << 8;
} }
read_binary_number_nocheck(in, temp); read_number_nocheck(in, temp);
num |= ((unsigned long)temp); num |= ((unsigned long)temp);
read_binary_guard(in, 0x2002); read_guard(in, 0x2002);
} }
template <typename T> template <typename T>
void read_binary_long(const char *& data, T& num) void read_long(const char *& data, T& num)
{ {
read_binary_guard(data, 0x2001); read_guard(data, 0x2001);
unsigned char len; unsigned char len;
read_binary_number_nocheck(data, len); read_number_nocheck(data, len);
num = 0; num = 0;
unsigned char temp; unsigned char temp;
if (len > 3) { if (len > 3) {
read_binary_number_nocheck(data, temp); read_number_nocheck(data, temp);
num |= ((unsigned long)temp) << 24; num |= ((unsigned long)temp) << 24;
} }
if (len > 2) { if (len > 2) {
read_binary_number_nocheck(data, temp); read_number_nocheck(data, temp);
num |= ((unsigned long)temp) << 16; num |= ((unsigned long)temp) << 16;
} }
if (len > 1) { if (len > 1) {
read_binary_number_nocheck(data, temp); read_number_nocheck(data, temp);
num |= ((unsigned long)temp) << 8; num |= ((unsigned long)temp) << 8;
} }
read_binary_number_nocheck(data, temp); read_number_nocheck(data, temp);
num |= ((unsigned long)temp); num |= ((unsigned long)temp);
read_binary_guard(data, 0x2002); read_guard(data, 0x2002);
} }
template <typename T> template <typename T>
inline T read_binary_long(std::istream& in) { inline T read_long(std::istream& in) {
T num; T num;
read_binary_long(in, num); read_long(in, num);
return num; return num;
} }
template <typename T> template <typename T>
inline T read_binary_long(const char *& data) { inline T read_long(const char *& data) {
T num; T num;
read_binary_long(data, num); read_long(data, num);
return num; return num;
} }
void read_binary_string(std::istream& in, string& str); void read_string(std::istream& in, string& str);
void read_binary_string(const char *& data, string& str); void read_string(const char *& data, string& str);
void read_binary_string(const char *& data, string * str); void read_string(const char *& data, string * str);
inline string read_binary_string(std::istream& in) { inline string read_string(std::istream& in) {
string temp; string temp;
read_binary_string(in, temp); read_string(in, temp);
return temp; return temp;
} }
inline string read_binary_string(const char *& data) { inline string read_string(const char *& data) {
string temp; string temp;
read_binary_string(data, temp); read_string(data, temp);
return temp; return temp;
} }
template <typename T> template <typename T>
inline void write_binary_number_nocheck(std::ostream& out, T num) { inline void write_number_nocheck(std::ostream& out, T num) {
out.write((char *)&num, sizeof(num)); out.write((char *)&num, sizeof(num));
} }
#if DEBUG_LEVEL >= ALPHA #if DEBUG_LEVEL >= ALPHA
#define write_binary_guard(out, id) \ #define write_guard(out, id) \
write_binary_number_nocheck<unsigned short>(out, id) write_number_nocheck<unsigned short>(out, id)
#else #else
#define write_binary_guard(in, id) #define write_guard(in, id)
#endif #endif
template <typename T> template <typename T>
inline void write_binary_number(std::ostream& out, T num) { inline void write_number(std::ostream& out, T num) {
write_binary_guard(out, 0x2003); write_guard(out, 0x2003);
out.write((char *)&num, sizeof(num)); out.write((char *)&num, sizeof(num));
write_binary_guard(out, 0x2004); write_guard(out, 0x2004);
} }
void write_binary_bool(std::ostream& out, bool num); void write_bool(std::ostream& out, bool num);
template <typename T> template <typename T>
void write_binary_long(std::ostream& out, T num) void write_long(std::ostream& out, T num)
{ {
write_binary_guard(out, 0x2001); write_guard(out, 0x2001);
unsigned char len = 4; unsigned char len = 4;
if (((unsigned long)num) < 0x00000100UL) if (((unsigned long)num) < 0x00000100UL)
@ -248,36 +234,36 @@ void write_binary_long(std::ostream& out, T num)
len = 2; len = 2;
else if (((unsigned long)num) < 0x01000000UL) else if (((unsigned long)num) < 0x01000000UL)
len = 3; len = 3;
write_binary_number_nocheck<unsigned char>(out, len); write_number_nocheck<unsigned char>(out, len);
unsigned char temp; unsigned char temp;
if (len > 3) { if (len > 3) {
temp = (((unsigned long)num) & 0xFF000000UL) >> 24; temp = (((unsigned long)num) & 0xFF000000UL) >> 24;
write_binary_number_nocheck(out, temp); write_number_nocheck(out, temp);
} }
if (len > 2) { if (len > 2) {
temp = (((unsigned long)num) & 0x00FF0000UL) >> 16; temp = (((unsigned long)num) & 0x00FF0000UL) >> 16;
write_binary_number_nocheck(out, temp); write_number_nocheck(out, temp);
} }
if (len > 1) { if (len > 1) {
temp = (((unsigned long)num) & 0x0000FF00UL) >> 8; temp = (((unsigned long)num) & 0x0000FF00UL) >> 8;
write_binary_number_nocheck(out, temp); write_number_nocheck(out, temp);
} }
temp = (((unsigned long)num) & 0x000000FFUL); temp = (((unsigned long)num) & 0x000000FFUL);
write_binary_number_nocheck(out, temp); write_number_nocheck(out, temp);
write_binary_guard(out, 0x2002); write_guard(out, 0x2002);
} }
void write_binary_string(std::ostream& out, const string& str); void write_string(std::ostream& out, const string& str);
template <typename T>
inline void write_object(std::ostream& out, const T& journal) {
assert(false);
}
} // namespace binary
#if 0
void write_binary_journal(std::ostream& out, journal_t * journal);
#endif
} // namespace ledger } // namespace ledger
#endif // _BINARY_H #endif // BINARY_H

View file

@ -49,7 +49,7 @@
* - exception framework * - exception framework
* - date/time type * - date/time type
* - supports_flags<> for objects that use flags * - supports_flags<> for objects that use flags
* - scoped_execute<> for guaranteeing code execution * - push_variable<> for restoring variable values
*/ */
#ifndef _UTILS_H #ifndef _UTILS_H
@ -512,7 +512,7 @@ inline void throw_unexpected_error(char, char) {
#include "times.h" #include "times.h"
#include "flags.h" #include "flags.h"
#include "scoped_execute.h" #include "pushvar.h"
/********************************************************************** /**********************************************************************
* *