diff options
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | Makefile.in | 44 | ||||
-rw-r--r-- | acconf.h.in | 6 | ||||
-rw-r--r-- | amount.cc | 93 | ||||
-rw-r--r-- | amount.h | 148 | ||||
-rw-r--r-- | balance.cc | 13 | ||||
-rw-r--r-- | balance.h | 8 | ||||
-rw-r--r-- | binary.cc | 6 | ||||
-rwxr-xr-x | configure | 191 | ||||
-rw-r--r-- | configure.in | 48 | ||||
-rw-r--r-- | datetime.cc | 575 | ||||
-rw-r--r-- | datetime.h | 320 | ||||
-rw-r--r-- | debug.h | 2 | ||||
-rw-r--r-- | derive.cc | 1 | ||||
-rw-r--r-- | gnucash.cc | 2 | ||||
-rw-r--r-- | journal.cc | 7 | ||||
-rw-r--r-- | journal.h | 22 | ||||
-rw-r--r-- | ledger.h | 1 | ||||
-rw-r--r-- | ofx.cc | 1 | ||||
-rw-r--r-- | py_amount.cc | 6 | ||||
-rw-r--r-- | py_eval.cc | 2 | ||||
-rw-r--r-- | qif.cc | 1 | ||||
-rw-r--r-- | quotes.cc | 25 | ||||
-rw-r--r-- | quotes.h | 10 | ||||
-rw-r--r-- | report.cc | 4 | ||||
-rw-r--r-- | session.cc | 2 | ||||
-rw-r--r-- | session.h | 4 | ||||
-rw-r--r-- | tests/corelib/numerics/Commodity.cc | 15 | ||||
-rw-r--r-- | textual.cc | 17 | ||||
-rw-r--r-- | times.cc | 7 | ||||
-rw-r--r-- | times.h | 41 | ||||
-rw-r--r-- | trace.cc | 4 | ||||
-rw-r--r-- | value.cc | 164 | ||||
-rw-r--r-- | value.h | 102 | ||||
-rw-r--r-- | xml.cc | 1 |
35 files changed, 567 insertions, 1332 deletions
diff --git a/Makefile.am b/Makefile.am index 4d5aa886..5de2dd82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,10 +13,10 @@ endif libledger_la_CXXFLAGS = $(WARNFLAGS) -I$(top_builddir)/gdtoa libledger_la_SOURCES = \ amount.cc \ + times.cc \ quotes.cc \ balance.cc \ value.cc \ - datetime.cc \ xml.cc \ xpath.cc \ mask.cc \ @@ -76,10 +76,10 @@ libpyledger_la_LDFLAGS = -release 3.0 pkginclude_HEADERS = \ amount.h \ + times.h \ balance.h \ binary.h \ csv.h \ - datetime.h \ debug.h \ derive.h \ emacs.h \ @@ -151,7 +151,7 @@ noinst_PROGRAMS = ledger.so ledger_so_SOURCES = pyledger.cc -PYLIBS = pyledger ledger gdtoa boost_python gmp pcre +PYLIBS = pyledger ledger gdtoa boost_date_time boost_python gmp pcre if HAVE_EXPAT PYLIBS += expat diff --git a/Makefile.in b/Makefile.in index bf8e69c8..a7600bda 100644 --- a/Makefile.in +++ b/Makefile.in @@ -89,8 +89,8 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libledger_la_LIBADD = -am__libledger_la_SOURCES_DIST = amount.cc quotes.cc balance.cc \ - value.cc datetime.cc xml.cc xpath.cc mask.cc format.cc util.cc \ +am__libledger_la_SOURCES_DIST = amount.cc times.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 binary.cc \ xmlparse.cc qif.cc report.cc transform.cc csv.cc derive.cc \ emacs.cc reconcile.cc gnucash.cc ofx.cc debug.cc trace.cc @@ -99,10 +99,10 @@ am__libledger_la_SOURCES_DIST = amount.cc quotes.cc balance.cc \ @HAVE_LIBOFX_TRUE@am__objects_3 = libledger_la-ofx.lo @DEBUG_TRUE@am__objects_4 = libledger_la-debug.lo \ @DEBUG_TRUE@ libledger_la-trace.lo -am_libledger_la_OBJECTS = libledger_la-amount.lo \ +am_libledger_la_OBJECTS = libledger_la-amount.lo libledger_la-times.lo \ libledger_la-quotes.lo libledger_la-balance.lo \ - libledger_la-value.lo libledger_la-datetime.lo \ - libledger_la-xml.lo libledger_la-xpath.lo libledger_la-mask.lo \ + libledger_la-value.lo libledger_la-xml.lo \ + libledger_la-xpath.lo libledger_la-mask.lo \ libledger_la-format.lo libledger_la-util.lo \ libledger_la-session.lo libledger_la-journal.lo \ libledger_la-parser.lo libledger_la-textual.lo \ @@ -341,12 +341,12 @@ lib_LTLIBRARIES = libledger.la $(am__append_1) libledger_la_CXXFLAGS = $(WARNFLAGS) -I$(top_builddir)/gdtoa \ $(am__append_2) $(am__append_4) $(am__append_6) \ $(am__append_8) $(am__append_10) -libledger_la_SOURCES = amount.cc quotes.cc balance.cc value.cc \ - datetime.cc xml.cc xpath.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 csv.cc derive.cc \ - emacs.cc reconcile.cc $(am__append_3) $(am__append_5) \ - $(am__append_7) $(am__append_9) +libledger_la_SOURCES = amount.cc times.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 binary.cc xmlparse.cc qif.cc \ + report.cc transform.cc csv.cc derive.cc emacs.cc reconcile.cc \ + $(am__append_3) $(am__append_5) $(am__append_7) \ + $(am__append_9) libledger_la_LDFLAGS = -release 3.0 libpyledger_la_CXXFLAGS = -DUSE_BOOST_PYTHON=1 $(am__append_11) libpyledger_la_SOURCES = \ @@ -356,10 +356,10 @@ libpyledger_la_SOURCES = \ libpyledger_la_LDFLAGS = -release 3.0 pkginclude_HEADERS = \ amount.h \ + times.h \ balance.h \ binary.h \ csv.h \ - datetime.h \ debug.h \ derive.h \ emacs.h \ @@ -399,8 +399,8 @@ ledger_LDADD = $(LIBOBJS) libledger.la gdtoa/libgdtoa.la \ ledger_LDFLAGS = -static # for the sake of command-line speed info_TEXINFOS = ledger.texi @HAVE_BOOST_PYTHON_TRUE@ledger_so_SOURCES = pyledger.cc -@HAVE_BOOST_PYTHON_TRUE@PYLIBS = pyledger ledger gdtoa boost_python \ -@HAVE_BOOST_PYTHON_TRUE@ gmp pcre $(am__append_18) \ +@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@ $(am__append_19) $(am__append_20) @DEBUG_FALSE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 0 @DEBUG_TRUE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 4 @@ -569,7 +569,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-balance.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-binary.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-csv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-datetime.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-derive.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-emacs.Plo@am__quote@ @@ -585,6 +584,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-report.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-textual.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-times.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-trace.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-transform.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libledger_la-util.Plo@am__quote@ @@ -624,6 +624,13 @@ libledger_la-amount.lo: amount.cc @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-amount.lo `test -f 'amount.cc' || echo '$(srcdir)/'`amount.cc +libledger_la-times.lo: times.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-times.lo -MD -MP -MF $(DEPDIR)/libledger_la-times.Tpo -c -o libledger_la-times.lo `test -f 'times.cc' || echo '$(srcdir)/'`times.cc +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-times.Tpo $(DEPDIR)/libledger_la-times.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='times.cc' object='libledger_la-times.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-times.lo `test -f 'times.cc' || echo '$(srcdir)/'`times.cc + libledger_la-quotes.lo: quotes.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-quotes.lo -MD -MP -MF $(DEPDIR)/libledger_la-quotes.Tpo -c -o libledger_la-quotes.lo `test -f 'quotes.cc' || echo '$(srcdir)/'`quotes.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-quotes.Tpo $(DEPDIR)/libledger_la-quotes.Plo @@ -645,13 +652,6 @@ libledger_la-value.lo: value.cc @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-value.lo `test -f 'value.cc' || echo '$(srcdir)/'`value.cc -libledger_la-datetime.lo: datetime.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-datetime.lo -MD -MP -MF $(DEPDIR)/libledger_la-datetime.Tpo -c -o libledger_la-datetime.lo `test -f 'datetime.cc' || echo '$(srcdir)/'`datetime.cc -@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-datetime.Tpo $(DEPDIR)/libledger_la-datetime.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='datetime.cc' object='libledger_la-datetime.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-datetime.lo `test -f 'datetime.cc' || echo '$(srcdir)/'`datetime.cc - libledger_la-xml.lo: xml.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-xml.lo -MD -MP -MF $(DEPDIR)/libledger_la-xml.Tpo -c -o libledger_la-xml.lo `test -f 'xml.cc' || echo '$(srcdir)/'`xml.cc @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libledger_la-xml.Tpo $(DEPDIR)/libledger_la-xml.Plo diff --git a/acconf.h.in b/acconf.h.in index 6e7c03d3..e1f233dd 100644 --- a/acconf.h.in +++ b/acconf.h.in @@ -33,18 +33,12 @@ /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H -/* Define to 1 if you have the `strftime' function. */ -#undef HAVE_STRFTIME - /* Define to 1 if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H -/* Define to 1 if you have the `strptime' function. */ -#undef HAVE_STRPTIME - /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H @@ -210,18 +210,6 @@ static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec) mpz_tdiv_q(out, out, divisor); } -amount_t::amount_t(const bool val) -{ - TRACE_CTOR("amount_t(const bool)"); - if (val) { - quantity = &true_value; - quantity->ref++; - } else { - quantity = NULL; - } - commodity_ = NULL; -} - amount_t::amount_t(const long val) { TRACE_CTOR("amount_t(const long)"); @@ -419,21 +407,6 @@ amount_t& amount_t::operator=(const amount_t& amt) return *this; } -amount_t& amount_t::operator=(const bool val) -{ - if (! val) { - if (quantity) - _clear(); - } else { - commodity_ = NULL; - if (quantity) - _release(); - quantity = &true_value; - quantity->ref++; - } - return *this; -} - amount_t& amount_t::operator=(const long val) { if (val == 0) { @@ -774,12 +747,12 @@ amount_t::operator double() const return std::atof(num.str().c_str()); } -amount_t amount_t::value(const datetime_t& moment) const +amount_t amount_t::value(const ptime& moment) const { if (quantity) { amount_t amt(commodity().value(moment)); if (! amt.realzero()) - return (amt * *this).round(); + return (amt * number()).round(); } return *this; } @@ -1159,7 +1132,7 @@ static void parse_commodity(std::istream& in, std::string& symbol) } bool parse_annotations(std::istream& in, amount_t& price, - datetime_t& date, std::string& tag) + ptime& date, std::string& tag) { bool has_date = false; @@ -1189,7 +1162,7 @@ bool parse_annotations(std::istream& in, amount_t& price, price = price.round(); // no need to retain individual precision } else if (c == '[') { - if (date) + if (date.is_not_a_date_time()) throw new amount_error("Commodity specifies more than one date"); in.get(c); @@ -1199,7 +1172,7 @@ bool parse_annotations(std::istream& in, amount_t& price, else throw new amount_error("Commodity date lacks closing bracket"); - date = buf; + date = ptime_from_local_date_string(buf); has_date = true; } else if (c == '(') { @@ -1239,7 +1212,7 @@ void amount_t::parse(std::istream& in, unsigned char flags) std::string symbol; std::string quant; amount_t tprice; - datetime_t tdate; + ptime tdate; bool had_date = false; std::string tag; unsigned int comm_flags = COMMODITY_STYLE_DEFAULTS; @@ -1579,7 +1552,7 @@ bool amount_t::valid() const } void amount_t::annotate_commodity(const amount_t& tprice, - const datetime_t& tdate, + const ptime& tdate, const std::string& tag) { const commodity_t * this_base; @@ -1602,7 +1575,7 @@ void amount_t::annotate_commodity(const amount_t& tprice, commodity_t * ann_comm = annotated_commodity_t::find_or_create (*this_base, ! tprice && this_ann ? this_ann->price : tprice, - ! tdate && this_ann ? this_ann->date : tdate, + tdate.is_not_a_date_time() && this_ann ? this_ann->date : tdate, tag.empty() && this_ann ? this_ann->tag : tag); if (ann_comm) set_commodity(*ann_comm); @@ -1631,12 +1604,12 @@ amount_t amount_t::strip_annotations(const bool _keep_price, commodity_t * new_comm; if ((_keep_price && ann_comm.price) || - (_keep_date && ann_comm.date) || - (_keep_tag && ! ann_comm.tag.empty())) + (_keep_date && ! ann_comm.date.is_not_a_date_time()) || + (_keep_tag && ! ann_comm.tag.empty())) { new_comm = annotated_commodity_t::find_or_create (*ann_comm.ptr, _keep_price ? ann_comm.price : amount_t(), - _keep_date ? ann_comm.date : datetime_t(), + _keep_date ? ann_comm.date : ptime(), _keep_tag ? ann_comm.tag : ""); } else { new_comm = commodity_t::find_or_create(ann_comm.base_symbol()); @@ -1662,7 +1635,7 @@ amount_t amount_t::price() const return *this; } -datetime_t amount_t::date() const +ptime amount_t::date() const { if (commodity_ && commodity_->annotated) { DEBUG_PRINT("amounts.commodities", @@ -1670,11 +1643,11 @@ datetime_t amount_t::date() const << ((annotated_commodity_t *)commodity_)->date); return ((annotated_commodity_t *)commodity_)->date; } - return 0L; + return ptime(); } -void commodity_base_t::add_price(const datetime_t& date, +void commodity_base_t::add_price(const ptime& date, const amount_t& price) { if (! history) @@ -1690,7 +1663,7 @@ void commodity_base_t::add_price(const datetime_t& date, } } -bool commodity_base_t::remove_price(const datetime_t& date) +bool commodity_base_t::remove_price(const ptime& date) { if (history) { history_map::size_type n = history->prices.erase(date); @@ -1800,15 +1773,15 @@ commodity_t * commodity_t::find(const std::string& symbol) return NULL; } -amount_t commodity_base_t::value(const datetime_t& moment) +amount_t commodity_base_t::value(const ptime& moment) { - datetime_t age; + ptime age; amount_t price; if (history) { assert(history->prices.size() > 0); - if (! moment) { + if (moment.is_not_a_date_time()) { history_map::reverse_iterator r = history->prices.rbegin(); age = (*r).first; price = (*r).second; @@ -1826,7 +1799,7 @@ amount_t commodity_base_t::value(const datetime_t& moment) age = (*i).first; price = (*i).second; } else { - age = 0; + age = ptime(); } } else { price = (*i).second; @@ -1838,7 +1811,7 @@ amount_t commodity_base_t::value(const datetime_t& moment) if (updater && ! (flags & COMMODITY_STYLE_NOMARKET)) (*updater)(*this, moment, age, (history && history->prices.size() > 0 ? - (*history->prices.rbegin()).first : datetime_t()), price); + (*history->prices.rbegin()).first : ptime()), price); return price; } @@ -1854,7 +1827,7 @@ bool annotated_commodity_t::operator==(const commodity_t& comm) const price != static_cast<const annotated_commodity_t&>(comm).price)) return false; - if (date && + if (! date.is_not_a_date_time() && (! comm.annotated || date != static_cast<const annotated_commodity_t&>(comm).date)) return false; @@ -1870,13 +1843,13 @@ bool annotated_commodity_t::operator==(const commodity_t& comm) const void annotated_commodity_t::write_annotations(std::ostream& out, const amount_t& price, - const datetime_t& date, + const ptime& date, const std::string& tag) { if (price) out << " {" << price << '}'; - if (date) + if (! date.is_not_a_date_time()) out << " [" << date << ']'; if (! tag.empty()) @@ -1886,7 +1859,7 @@ annotated_commodity_t::write_annotations(std::ostream& out, commodity_t * annotated_commodity_t::create(const commodity_t& comm, const amount_t& price, - const datetime_t& date, + const ptime& date, const std::string& tag, const std::string& mapping_key) { @@ -1927,7 +1900,7 @@ annotated_commodity_t::create(const commodity_t& comm, namespace { std::string make_qualified_name(const commodity_t& comm, const amount_t& price, - const datetime_t& date, + const ptime& date, const std::string& tag) { if (price < 0) @@ -1953,7 +1926,7 @@ namespace { commodity_t * annotated_commodity_t::find_or_create(const commodity_t& comm, const amount_t& price, - const datetime_t& date, + const ptime& date, const std::string& tag) { std::string name = make_qualified_name(comm, price, date, tag); @@ -2016,15 +1989,17 @@ bool compare_amount_commodities::operator()(const amount_t * left, } } - if (! aleftcomm.date && arightcomm.date) + if (aleftcomm.date.is_not_a_date_time() && + ! arightcomm.date.is_not_a_date_time()) return true; - if (aleftcomm.date && ! arightcomm.date) + if (! aleftcomm.date.is_not_a_date_time() && + arightcomm.date.is_not_a_date_time()) return false; - if (aleftcomm.date && arightcomm.date) { - int diff = aleftcomm.date - arightcomm.date; - if (diff) - return diff < 0; + if (! aleftcomm.date.is_not_a_date_time() && + ! arightcomm.date.is_not_a_date_time()) { + time_duration diff = aleftcomm.date - arightcomm.date; + return diff.is_negative(); } if (aleftcomm.tag.empty() && ! arightcomm.tag.empty()) @@ -42,13 +42,13 @@ #include <cassert> #include <exception> -#include "datetime.h" +#include "times.h" #include "debug.h" #include "error.h" namespace ledger { -extern bool do_cleanup; +extern bool do_cleanup; class commodity_t; @@ -94,7 +94,6 @@ class amount_t TRACE_CTOR("amount_t(const char *)"); parse(val); } - amount_t(const bool val); amount_t(const long val); amount_t(const unsigned long val); amount_t(const double val); @@ -118,7 +117,7 @@ class amount_t commodity_ = &comm; } void annotate_commodity(const amount_t& price, - const datetime_t& date = datetime_t(), + const ptime& date = ptime(), const std::string& tag = ""); amount_t strip_annotations(const bool _keep_price = keep_price, const bool _keep_date = keep_date, @@ -127,7 +126,7 @@ class amount_t commodity_ = NULL; } amount_t price() const; - datetime_t date() const; + ptime date() const; bool null() const { return ! quantity && ! has_commodity(); @@ -137,7 +136,6 @@ class amount_t amount_t& operator=(const amount_t& amt); amount_t& operator=(const std::string& val); amount_t& operator=(const char * val); - amount_t& operator=(const bool val); amount_t& operator=(const long val); amount_t& operator=(const unsigned long val); amount_t& operator=(const double val); @@ -299,7 +297,7 @@ class amount_t return ! (*this == num); } - amount_t value(const datetime_t& moment) const; + amount_t value(const ptime& moment) const; // jww (2007-04-17): change the name here void abs() { @@ -327,7 +325,7 @@ class amount_t char * item_pool_end); friend bool parse_annotations(std::istream& in, amount_t& price, - datetime_t& date, std::string& tag); + ptime& date, std::string& tag); // Streaming interface @@ -387,63 +385,50 @@ inline amount_t abs(const amount_t& amt) { return amt < 0 ? amt.negated() : amt; } -template <typename T> -inline amount_t operator+(const T val, const amount_t& amt) { - amount_t temp(val); - temp += amt; - return temp; -} - -template <typename T> -inline amount_t operator-(const T val, const amount_t& amt) { - amount_t temp(val); - temp -= amt; - return temp; +#define DEFINE_AMOUNT_OPERATORS(T) \ +inline amount_t operator+(const T val, const amount_t& amt) { \ + amount_t temp(val); \ + temp += amt; \ + return temp; \ +} \ +inline amount_t operator-(const T val, const amount_t& amt) { \ + amount_t temp(val); \ + temp -= amt; \ + return temp; \ +} \ +inline amount_t operator*(const T val, const amount_t& amt) { \ + amount_t temp(val); \ + temp *= amt; \ + return temp; \ +} \ +inline amount_t operator/(const T val, const amount_t& amt) { \ + amount_t temp(val); \ + temp /= amt; \ + return temp; \ +} \ + \ +inline bool operator<(const T val, const amount_t& amt) { \ + return amount_t(val) < amt; \ +} \ +inline bool operator<=(const T val, const amount_t& amt) { \ + return amount_t(val) <= amt; \ +} \ +inline bool operator>(const T val, const amount_t& amt) { \ + return amount_t(val) > amt; \ +} \ +inline bool operator>=(const T val, const amount_t& amt) { \ + return amount_t(val) >= amt; \ +} \ +inline bool operator==(const T val, const amount_t& amt) { \ + return amount_t(val) == amt; \ +} \ +inline bool operator!=(const T val, const amount_t& amt) { \ + return amount_t(val) != amt; \ } -template <typename T> -inline amount_t operator*(const T val, const amount_t& amt) { - amount_t temp(val); - temp *= amt; - return temp; -} - -template <typename T> -inline amount_t operator/(const T val, const amount_t& amt) { - amount_t temp(val); - temp /= amt; - return temp; -} - -template <typename T> -inline bool operator<(const T val, const amount_t& amt) { - return amount_t(val) < amt; -} - -template <typename T> -inline bool operator<=(const T val, const amount_t& amt) { - return amount_t(val) <= amt; -} - -template <typename T> -inline bool operator>(const T val, const amount_t& amt) { - return amount_t(val) > amt; -} - -template <typename T> -inline bool operator>=(const T val, const amount_t& amt) { - return amount_t(val) >= amt; -} - -template <typename T> -inline bool operator==(const T val, const amount_t& amt) { - return amount_t(val) == amt; -} - -template <typename T> -inline bool operator!=(const T val, const amount_t& amt) { - return amount_t(val) != amt; -} +DEFINE_AMOUNT_OPERATORS(long) +DEFINE_AMOUNT_OPERATORS(unsigned long) +DEFINE_AMOUNT_OPERATORS(double) inline std::ostream& operator<<(std::ostream& out, const amount_t& amt) { amt.print(out, false, amount_t::full_strings); @@ -463,8 +448,8 @@ inline std::istream& operator>>(std::istream& in, amount_t& amt) { #define COMMODITY_STYLE_NOMARKET 0x0010 #define COMMODITY_STYLE_BUILTIN 0x0020 -typedef std::map<const datetime_t, amount_t> history_map; -typedef std::pair<const datetime_t, amount_t> history_pair; +typedef std::map<const ptime, amount_t> history_map; +typedef std::pair<const ptime, amount_t> history_pair; class commodity_base_t; @@ -510,23 +495,24 @@ class commodity_base_t struct history_t { history_map prices; - datetime_t last_lookup; - datetime_t bogus_time; - history_t() : last_lookup(0), bogus_time(0) {} + ptime last_lookup; + // jww (2007-04-18): What is bogus_time? + ptime bogus_time; + history_t() : last_lookup(), bogus_time() {} }; history_t * history; - void add_price(const datetime_t& date, const amount_t& price); - bool remove_price(const datetime_t& date); - amount_t value(const datetime_t& moment = datetime_t::now); + void add_price(const ptime& date, const amount_t& price); + bool remove_price(const ptime& date); + amount_t value(const ptime& moment = now); class updater_t { public: virtual ~updater_t() {} virtual void operator()(commodity_base_t& commodity, - const datetime_t& moment, - const datetime_t& date, - const datetime_t& last, + const ptime& moment, + const ptime& date, + const ptime& last, amount_t& price) = 0; }; friend class updater_t; @@ -657,13 +643,13 @@ class commodity_t return base->history; } - void add_price(const datetime_t& date, const amount_t& price) { + void add_price(const ptime& date, const amount_t& price) { return base->add_price(date, price); } - bool remove_price(const datetime_t& date) { + bool remove_price(const ptime& date) { return base->remove_price(date); } - amount_t value(const datetime_t& moment = datetime_t::now) const { + amount_t value(const ptime& moment = now) const { return base->value(moment); } @@ -676,7 +662,7 @@ class annotated_commodity_t : public commodity_t const commodity_t * ptr; amount_t price; - datetime_t date; + ptime date; std::string tag; explicit annotated_commodity_t() { @@ -692,19 +678,19 @@ class annotated_commodity_t : public commodity_t static void write_annotations(std::ostream& out, const amount_t& price, - const datetime_t& date, + const ptime& date, const std::string& tag); private: static commodity_t * create(const commodity_t& comm, const amount_t& price, - const datetime_t& date, + const ptime& date, const std::string& tag, const std::string& mapping_key); static commodity_t * find_or_create(const commodity_t& comm, const amount_t& price, - const datetime_t& date, + const ptime& date, const std::string& tag); friend class amount_t; @@ -33,7 +33,7 @@ amount_t balance_t::amount(const commodity_t& commodity) const return amount_t(); } -balance_t balance_t::value(const datetime_t& moment) const +balance_t balance_t::value(const ptime& moment) const { balance_t temp; @@ -57,20 +57,19 @@ balance_t balance_t::price() const return temp; } -datetime_t balance_t::date() const +ptime balance_t::date() const { - datetime_t temp; + ptime temp; for (amounts_map::const_iterator i = amounts.begin(); i != amounts.end(); i++) { - datetime_t tdate = (*i).second.date(); - if (! temp && tdate) + ptime tdate = (*i).second.date(); + if (temp.is_not_a_date_time() && ! tdate.is_not_a_date_time()) temp = tdate; else if (temp != tdate) - return datetime_t(); + return ptime(); } - return temp; } @@ -430,9 +430,9 @@ class balance_t amount_t amount(const commodity_t& commodity = *commodity_t::null_commodity) const; - balance_t value(const datetime_t& moment = datetime_t::now) const; + balance_t value(const ptime& moment = now) const; balance_t price() const; - datetime_t date() const; + ptime date() const; balance_t strip_annotations(const bool keep_price = amount_t::keep_price, @@ -880,13 +880,13 @@ class balance_pair_t *commodity_t::null_commodity) const { return quantity.amount(commodity); } - balance_t value(const datetime_t& moment = datetime_t::now) const { + balance_t value(const ptime& moment = now) const { return quantity.value(moment); } balance_t price() const { return quantity.price(); } - datetime_t date() const { + ptime date() const { return quantity.date(); } @@ -135,7 +135,7 @@ inline void read_binary_value(char *& data, value_t& val) read_binary_long(data, *((long *) val.data)); break; case value_t::DATETIME: - read_binary_number(data, *((datetime_t *) val.data)); + read_binary_number(data, *((ptime *) val.data)); break; case value_t::AMOUNT: read_binary_amount(data, *((amount_t *) val.data)); @@ -281,7 +281,7 @@ inline void read_binary_commodity_base_extra(char *& data, for (unsigned long i = 0, count = read_binary_long<unsigned long>(data); i < count; i++) { - datetime_t when; + ptime when; read_binary_number(data, when); amount_t amt; read_binary_amount(data, amt); @@ -661,7 +661,7 @@ void write_binary_value(std::ostream& out, const value_t& val) write_binary_long(out, *((long *) val.data)); break; case value_t::DATETIME: - write_binary_number(out, *((datetime_t *) val.data)); + write_binary_number(out, *((ptime *) val.data)); break; case value_t::AMOUNT: write_binary_amount(out, *((amount_t *) val.data)); @@ -875,10 +875,6 @@ LIBTOOL EMACS EMACSLOADPATH lispdir -HAVE_GMP_TRUE -HAVE_GMP_FALSE -HAVE_PCRE_TRUE -HAVE_PCRE_FALSE USE_XML_TRUE USE_XML_FALSE HAVE_EXPAT_TRUE @@ -4852,7 +4848,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 4855 "configure"' > conftest.$ac_ext + echo '#line 4851 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7111,11 +7107,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7114: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7110: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7118: \$? = $ac_status" >&5 + echo "$as_me:7114: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7379,11 +7375,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7382: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7378: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7386: \$? = $ac_status" >&5 + echo "$as_me:7382: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7483,11 +7479,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7486: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7482: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7490: \$? = $ac_status" >&5 + echo "$as_me:7486: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9791,7 +9787,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<EOF -#line 9794 "configure" +#line 9790 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9891,7 +9887,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<EOF -#line 9894 "configure" +#line 9890 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12227,11 +12223,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12230: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12226: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12234: \$? = $ac_status" >&5 + echo "$as_me:12230: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -12331,11 +12327,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12334: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12330: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12338: \$? = $ac_status" >&5 + echo "$as_me:12334: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -13901,11 +13897,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13904: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13900: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:13908: \$? = $ac_status" >&5 + echo "$as_me:13904: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14005,11 +14001,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14008: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14004: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14012: \$? = $ac_status" >&5 + echo "$as_me:14008: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16203,11 +16199,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16206: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16202: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16210: \$? = $ac_status" >&5 + echo "$as_me:16206: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -16471,11 +16467,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16474: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16470: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16478: \$? = $ac_status" >&5 + echo "$as_me:16474: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -16575,11 +16571,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16578: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16574: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:16582: \$? = $ac_status" >&5 + echo "$as_me:16578: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -19503,14 +19499,6 @@ fi echo "${ECHO_T}$libgmp_avail" >&6; } if test x$libgmp_avail = xtrue ; then - if true; then - HAVE_GMP_TRUE= - HAVE_GMP_FALSE='#' -else - HAVE_GMP_TRUE='#' - HAVE_GMP_FALSE= -fi - LIBS="-lgmp $LIBS" else { { echo "$as_me:$LINENO: error: \"Could not find gmp library (set CPPFLAGS and LDFLAGS?)\" @@ -19589,14 +19577,6 @@ fi echo "${ECHO_T}$libpcre_avail" >&6; } if test x$libpcre_avail = xtrue ; then - if true; then - HAVE_PCRE_TRUE= - HAVE_PCRE_FALSE='#' -else - HAVE_PCRE_TRUE='#' - HAVE_PCRE_FALSE= -fi - LIBS="-lpcre $LIBS" else { { echo "$as_me:$LINENO: error: \"Could not find pcre library (set CPPFLAGS and LDFLAGS?)\" @@ -19606,6 +19586,102 @@ 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 $ECHO_N "checking if boost_date_time is available... $ECHO_C" >&6; } +if test "${boost_date_time_cpplib_avail+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + boost_date_time_save_libs=$LIBS + LIBS="-lboost_date_time $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 <boost/date_time/posix_time/posix_time.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::date_time; + + #include <ctime> + + inline ptime time_to_system_local(const ptime& when) { + struct std::tm tm_gmt = to_tm(when); + return from_time_t(mktime(&tm_gmt)); + } +int +main () +{ +ptime t10 = ptime(boost::gregorian::from_string("2007-01-15"), + ptime::time_duration_type()); + + ptime t12 = time_to_system_local(t10); + + return t10 != t12; + ; + 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 + boost_date_time_cpplib_avail=true +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + boost_date_time_cpplib_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=$boost_date_time_save_libs +fi +{ echo "$as_me:$LINENO: result: $boost_date_time_cpplib_avail" >&5 +echo "${ECHO_T}$boost_date_time_cpplib_avail" >&6; } + +if test x$boost_date_time_cpplib_avail = xtrue ; then + LIBS="-lboost_date_time $LIBS" +else + { { echo "$as_me:$LINENO: error: \"Could not find boost_date_time library (set CPPFLAGS and LDFLAGS?)\" +See \`config.log' for more details." >&5 +echo "$as_me: error: \"Could not find boost_date_time library (set CPPFLAGS and LDFLAGS?)\" +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + # check for expat or xmlparse # Check whether --enable-xml was given. if test "${enable_xml+set}" = set; then @@ -19620,6 +19696,7 @@ else xml=true fi + if test x$xml = xtrue; then USE_XML_TRUE= USE_XML_FALSE='#' @@ -19860,6 +19937,7 @@ else ofx=true fi + if test x$ofx = xtrue; then USE_OFX_TRUE= USE_OFX_FALSE='#' @@ -19982,6 +20060,7 @@ else python=false fi + if test x$python = xtrue; then USE_PYTHON_TRUE= USE_PYTHON_FALSE='#' @@ -20248,6 +20327,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { echo "$as_me:$LINENO: result: $boost_python_cpplib_avail" >&5 echo "${ECHO_T}$boost_python_cpplib_avail" >&6; } + if test x$boost_python_cpplib_avail = xtrue ; then if true; then HAVE_BOOST_PYTHON_TRUE= @@ -20303,6 +20383,7 @@ else debug=false fi + if test x$debug = xtrue; then DEBUG_TRUE= DEBUG_FALSE='#' @@ -21126,9 +21207,7 @@ fi - - -for ac_func in access mktime realpath strftime strptime getpwuid getpwnam +for ac_func in access mktime realpath getpwuid getpwnam do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -21341,20 +21420,6 @@ echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi -if test -z "${HAVE_GMP_TRUE}" && test -z "${HAVE_GMP_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"HAVE_GMP\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"HAVE_GMP\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${HAVE_PCRE_TRUE}" && test -z "${HAVE_PCRE_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"HAVE_PCRE\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"HAVE_PCRE\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi if test -z "${USE_XML_TRUE}" && test -z "${USE_XML_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"USE_XML\" was never defined. Usually this means the macro was only invoked conditionally." >&5 @@ -22159,10 +22224,6 @@ LIBTOOL!$LIBTOOL$ac_delim EMACS!$EMACS$ac_delim EMACSLOADPATH!$EMACSLOADPATH$ac_delim lispdir!$lispdir$ac_delim -HAVE_GMP_TRUE!$HAVE_GMP_TRUE$ac_delim -HAVE_GMP_FALSE!$HAVE_GMP_FALSE$ac_delim -HAVE_PCRE_TRUE!$HAVE_PCRE_TRUE$ac_delim -HAVE_PCRE_FALSE!$HAVE_PCRE_FALSE$ac_delim USE_XML_TRUE!$USE_XML_TRUE$ac_delim USE_XML_FALSE!$USE_XML_FALSE$ac_delim HAVE_EXPAT_TRUE!$HAVE_EXPAT_TRUE$ac_delim @@ -22192,7 +22253,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 39; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 35; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/configure.in b/configure.in index 0c6e249a..f4f1e9b7 100644 --- a/configure.in +++ b/configure.in @@ -77,7 +77,6 @@ AC_CACHE_CHECK( LIBS=$libgmp_save_libs]) if [test x$libgmp_avail = xtrue ]; then - AM_CONDITIONAL(HAVE_GMP, true) LIBS="-lgmp $LIBS" else AC_MSG_FAILURE("Could not find gmp library (set CPPFLAGS and LDFLAGS?)") @@ -99,12 +98,50 @@ AC_CACHE_CHECK( LIBS=$libpcre_save_libs]) if [test x$libpcre_avail = xtrue ]; then - AM_CONDITIONAL(HAVE_PCRE, true) 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( + [if boost_date_time is available], + [boost_date_time_cpplib_avail], + [boost_date_time_save_libs=$LIBS + LIBS="-lboost_date_time $LIBS" + AC_LANG_PUSH(C++) + AC_TRY_LINK( + [#include <boost/date_time/posix_time/posix_time.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::date_time; + + #include <ctime> + + inline ptime time_to_system_local(const ptime& when) { + struct std::tm tm_gmt = to_tm(when); + return from_time_t(mktime(&tm_gmt)); + }], + [ptime t10 = ptime(boost::gregorian::from_string("2007-01-15"), + ptime::time_duration_type()); + + ptime t12 = time_to_system_local(t10); + + return t10 != t12;], + [boost_date_time_cpplib_avail=true], + [boost_date_time_cpplib_avail=false]) + AC_LANG_POP + LIBS=$boost_date_time_save_libs]) + +if [test x$boost_date_time_cpplib_avail = xtrue ]; then + LIBS="-lboost_date_time $LIBS" +else + AC_MSG_FAILURE("Could not find boost_date_time library (set CPPFLAGS and LDFLAGS?)") +fi + # check for expat or xmlparse AC_ARG_ENABLE(xml, [ --enable-xml Turn on support for XML parsing], @@ -113,6 +150,7 @@ AC_ARG_ENABLE(xml, 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 @@ -185,6 +223,7 @@ AC_ARG_ENABLE(ofx, no) ofx=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-ofx) ;; esac],[ofx=true]) + AM_CONDITIONAL(USE_OFX, test x$ofx = xtrue) if [test x$ofx = xtrue ]; then @@ -220,6 +259,7 @@ AC_ARG_ENABLE(python, no) python=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-python) ;; esac],[python=false]) + AM_CONDITIONAL(USE_PYTHON, test x$python = xtrue) if [test x$python = xtrue ]; then @@ -243,6 +283,7 @@ if [test x$python = xtrue ]; then [boost_python_cpplib_avail=false]) AC_LANG_POP LIBS=$boost_python_save_libs]) + if [test x$boost_python_cpplib_avail = xtrue ]; then AM_CONDITIONAL(HAVE_BOOST_PYTHON, true) LIBS="-lboost_python -lpython$PYTHON_VERSION $LIBS" @@ -264,6 +305,7 @@ AC_ARG_ENABLE(debug, no) debug=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;; esac],[debug=false]) + AM_CONDITIONAL(DEBUG, test x$debug = xtrue) # Checks for header files. @@ -278,7 +320,7 @@ AC_STRUCT_TM # Checks for library functions. #AC_FUNC_ERROR_AT_LINE AC_HEADER_STDC -AC_CHECK_FUNCS([access mktime realpath strftime strptime getpwuid getpwnam]) +AC_CHECK_FUNCS([access mktime realpath getpwuid getpwnam]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/datetime.cc b/datetime.cc deleted file mode 100644 index 1038b87d..00000000 --- a/datetime.cc +++ /dev/null @@ -1,575 +0,0 @@ -#if defined(__GNUG__) && __GNUG__ < 3 -#define _XOPEN_SOURCE -#endif - -#include "datetime.h" -#include "util.h" - -#include <ctime> -#include <cctype> - -date_t date_t::now(std::time(NULL)); -int date_t::current_year = date_t::now.year(); -std::string date_t::input_format; -std::string date_t::output_format = "%Y/%m/%d"; - -const char * date_t::formats[] = { - "%Y/%m/%d", - "%m/%d", - "%Y.%m.%d", - "%m.%d", - "%Y-%m-%d", - "%m-%d", - "%a", - "%A", - "%b", - "%B", - "%Y", - NULL -}; - -datetime_t datetime_t::now(std::time(NULL)); - -namespace { -#if 0 - static std::time_t base = -1; - static int base_year = -1; -#endif - - static const int month_days[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - - bool parse_date_mask(const char * date_str, struct std::tm * result) - { - if (! date_t::input_format.empty()) { - std::memset(result, INT_MAX, sizeof(struct std::tm)); - if (strptime(date_str, date_t::input_format.c_str(), result)) - return true; - } - for (const char ** f = date_t::formats; *f; f++) { - std::memset(result, INT_MAX, sizeof(struct std::tm)); - if (strptime(date_str, *f, result)) - return true; - } - return false; - } - - bool parse_date(const char * date_str, std::time_t * result, const int year) - { - struct std::tm when; - - if (! parse_date_mask(date_str, &when)) - return false; - - when.tm_hour = 0; - when.tm_min = 0; - when.tm_sec = 0; - - if (when.tm_year == -1) - when.tm_year = ((year == -1) ? date_t::current_year : (year - 1900)); - - if (when.tm_mon == -1) - when.tm_mon = 0; - - if (when.tm_mday == -1) - when.tm_mday = 1; - - *result = std::mktime(&when); - - return true; - } - - inline bool quick_parse_date(const char * date_str, std::time_t * result) - { - return parse_date(date_str, result, date_t::current_year + 1900); - } -} - -date_t::date_t(const std::string& _when) -{ - if (! quick_parse_date(_when.c_str(), &when)) - throw new date_error - (std::string("Invalid date string: ") + _when); -} - -void date_t::parse(std::istream& in) -{ - char buf[256]; - char c = peek_next_nonws(in); - READ_INTO(in, buf, 255, c, - std::isalnum(c) || c == '-' || c == '.' || c == '/'); - - if (! quick_parse_date(buf, &when)) - throw new date_error - (std::string("Invalid date string: ") + buf); -} - -datetime_t::datetime_t(const std::string& _when) -{ - std::istringstream datestr(_when); - parse(datestr); // parse both the date and optional time -} - -void datetime_t::parse(std::istream& in) -{ - date_t::parse(in); // first grab the date part - - istream_pos_type beg_pos = in.tellg(); - - int thour = 0; - int tmin = 0; - int tsec = 0; - - // Now look for the (optional) time specifier. If no time is given, - // we use midnight of the given day. - char buf[256]; - char c = peek_next_nonws(in); - if (! std::isdigit(c)) - goto abort; - READ_INTO(in, buf, 255, c, std::isdigit(c)); - if (buf[0] == '\0') - goto abort; - - thour = std::atoi(buf); - if (thour > 23) - goto abort; - - if (in.peek() == ':') { - in.get(c); - READ_INTO(in, buf, 255, c, std::isdigit(c)); - if (buf[0] == '\0') - goto abort; - - tmin = std::atoi(buf); - if (tmin > 59) - goto abort; - - if (in.peek() == ':') { - in.get(c); - READ_INTO(in, buf, 255, c, std::isdigit(c)); - if (buf[0] == '\0') - goto abort; - - tsec = std::atoi(buf); - if (tsec > 59) - goto abort; - } - } - - c = peek_next_nonws(in); - if (c == 'a' || c == 'p' || c == 'A' || c == 'P') { - if (thour > 12) - goto abort; - in.get(c); - - if (c == 'p' || c == 'P') { - if (thour != 12) - thour += 12; - } else { - if (thour == 12) - thour = 0; - } - - c = in.peek(); - if (c == 'm' || c == 'M') - in.get(c); - } - - struct std::tm * desc = std::localtime(&when); - - desc->tm_hour = thour; - desc->tm_min = tmin; - desc->tm_sec = tsec; - desc->tm_isdst = -1; - - when = std::mktime(desc); - - return; // the time has been successfully parsed - - abort: // there was no valid time string to parse - in.clear(); - in.seekg(beg_pos, std::ios::beg); -} - -std::ostream& operator<<(std::ostream& out, const datetime_t& moment) -{ - std::string format = datetime_t::output_format; - std::tm * when = moment.localtime(); - if (when->tm_hour != 0 || when->tm_min != 0 || when->tm_sec != 0) - format += " %H:%M:%S"; - - char buf[64]; - std::strftime(buf, 63, format.c_str(), when); - out << buf; - return out; -} - -datetime_t interval_t::first(const datetime_t& moment) const -{ - datetime_t quant(begin); - - if (moment && moment > quant) { - // Find an efficient starting point for the upcoming while loop. - // We want a date early enough that the range will be correct, but - // late enough that we don't spend hundreds of thousands of loops - // skipping through time. - - struct std::tm * desc = std::localtime(&moment.when); - - if (years) - desc->tm_mon = 0; - desc->tm_mday = 1; - - desc->tm_hour = 0; - desc->tm_min = 0; - desc->tm_sec = 0; - desc->tm_isdst = -1; - - quant = std::mktime(desc); - - datetime_t temp; - while (moment >= (temp = increment(quant))) { - if (quant == temp) - break; - quant = temp; - } - } - - return quant; -} - -datetime_t interval_t::increment(const datetime_t& moment) const -{ - struct std::tm * desc = std::localtime(&moment.when); - - if (years) - desc->tm_year += years; - if (months) - desc->tm_mon += months; - if (days) - desc->tm_mon += days; - - desc->tm_hour += hours; - desc->tm_min += minutes; - desc->tm_sec += seconds; - - desc->tm_isdst = -1; - - return std::mktime(desc); -} - -namespace { - void parse_inclusion_specifier(const std::string& word, - datetime_t * begin, datetime_t * end) - { - struct std::tm when; - - if (! parse_date_mask(word.c_str(), &when)) - throw new datetime_error(std::string("Could not parse date mask: ") + word); - - when.tm_hour = 0; - when.tm_min = 0; - when.tm_sec = 0; - when.tm_isdst = -1; - - bool saw_year = true; - bool saw_mon = true; - bool saw_day = true; - - if (when.tm_year == -1) { - when.tm_year = date_t::current_year; - saw_year = false; - } - if (when.tm_mon == -1) { - when.tm_mon = 0; - saw_mon = false; - } else { - saw_year = false; // don't increment by year if month used - } - if (when.tm_mday == -1) { - when.tm_mday = 1; - saw_day = false; - } else { - saw_mon = false; // don't increment by month if day used - saw_year = false; // don't increment by year if day used - } - - if (begin) { - *begin = std::mktime(&when); - if (end) - *end = interval_t(saw_day ? 86400 : 0, saw_mon ? 1 : 0, - saw_year ? 1 : 0).increment(*begin); - } - else if (end) { - *end = std::mktime(&when); - } - } - - inline void read_lower_word(std::istream& in, std::string& word) { - in >> word; - for (int i = 0, l = word.length(); i < l; i++) - word[i] = std::tolower(word[i]); - } - - void parse_date_words(std::istream& in, std::string& word, - datetime_t * begin, datetime_t * end) - { - std::string type; - - bool mon_spec = false; - char buf[32]; - - if (word == "this" || word == "last" || word == "next") { - type = word; - if (! in.eof()) - read_lower_word(in, word); - else - word = "month"; - } else { - type = "this"; - } - - if (word == "month") { - std::strftime(buf, 31, "%B", datetime_t::now.localtime()); - word = buf; - mon_spec = true; - } - else if (word == "year") { - std::strftime(buf, 31, "%Y", datetime_t::now.localtime()); - word = buf; - } - - parse_inclusion_specifier(word, begin, end); - - if (type == "last") { - if (mon_spec) { - if (begin) - *begin = interval_t(0, -1, 0).increment(*begin); - if (end) - *end = interval_t(0, -1, 0).increment(*end); - } else { - if (begin) - *begin = interval_t(0, 0, -1).increment(*begin); - if (end) - *end = interval_t(0, 0, -1).increment(*end); - } - } - else if (type == "next") { - if (mon_spec) { - if (begin) - *begin = interval_t(0, 1, 0).increment(*begin); - if (end) - *end = interval_t(0, 1, 0).increment(*end); - } else { - if (begin) - *begin = interval_t(0, 0, 1).increment(*begin); - if (end) - *end = interval_t(0, 0, 1).increment(*end); - } - } - } -} - -void interval_t::parse(std::istream& in) -{ - std::string word; - - while (! in.eof()) { - read_lower_word(in, word); - if (word == "every") { - read_lower_word(in, word); - if (std::isdigit(word[0])) { - int quantity = std::atol(word.c_str()); - read_lower_word(in, word); - if (word == "days") - days = quantity; - else if (word == "weeks") - days = 7 * quantity; - else if (word == "months") - months = quantity; - else if (word == "quarters") - months = 3 * quantity; - else if (word == "years") - years = quantity; - else if (word == "hours") - hours = quantity; - else if (word == "minutes") - minutes = quantity; - else if (word == "seconds") - seconds = quantity; - } - else if (word == "day") - days = 1; - else if (word == "week") - days = 7; - else if (word == "month") - months = 1; - else if (word == "quarter") - months = 3; - else if (word == "year") - years = 1; - else if (word == "hour") - hours = 1; - else if (word == "minute") - minutes = 1; - else if (word == "second") - seconds = 1; - } - else if (word == "daily") - days = 1; - else if (word == "weekly") - days = 7; - else if (word == "biweekly") - days = 14; - else if (word == "monthly") - months = 1; - else if (word == "bimonthly") - months = 2; - else if (word == "quarterly") - months = 3; - else if (word == "yearly") - years = 1; - else if (word == "hourly") - hours = 1; - else if (word == "this" || word == "last" || word == "next") { - parse_date_words(in, word, &begin, &end); - } - else if (word == "in") { - read_lower_word(in, word); - parse_date_words(in, word, &begin, &end); - } - else if (word == "from" || word == "since") { - read_lower_word(in, word); - parse_date_words(in, word, &begin, NULL); - } - else if (word == "to" || word == "until") { - read_lower_word(in, word); - parse_date_words(in, word, NULL, &end); - } - else { - parse_inclusion_specifier(word, &begin, &end); - } - } -} - -#if 0 -#ifdef USE_BOOST_PYTHON - -#include <boost/python.hpp> - -using namespace boost::python; - -unsigned int interval_len(interval_t& interval) -{ - int periods = 1; - std::time_t when = interval.first(); - while (interval.end && when < interval.end) { - when = interval.increment(when); - if (when < interval.end) - periods++; - } - return periods; -} - -std::time_t interval_getitem(interval_t& interval, int i) -{ - static std::time_t last_index = 0; - static std::time_t last_moment = 0; - - if (i == 0) { - last_index = 0; - last_moment = interval.first(); - } - else { - last_moment = interval.increment(last_moment); - if (interval.end && last_moment >= interval.end) { - PyErr_SetString(PyExc_IndexError, "Index out of range"); - throw_error_already_set(); - } - } - return last_moment; -} - -std::time_t py_parse_date(const char * date_str) -{ - std::time_t temp; - if (parse_date(date_str, &temp)) - return temp; - return 0; -} - -std::time_t py_parse_date_yr(const char * date_str, const int year) -{ - std::time_t temp; - if (parse_date(date_str, &temp, year)) - return temp; - return 0; -} - -void export_datetime() -{ - class_< date_t > ("Date") - .def("now", &date_t::now) - .def("formats", &date_t::formats) - .def("current_year", &date_t::current_year) - .def("input_format", &date_t::input_format) - .def("output_format", &date_t::output_format) - - .def(init<>()) - .def(init<const date_t&>()) - .def(init<const std::time_t&>()) - .def(init<const interval_t&>()) - .def(init<const std::string&>()) - - .def(self += other<const interval_t&>()) - .def(self -= other<const date_t&>()) - .def(self += long()) - .def(self -= long()) - - .def(self < other<const date_t&>()) - .def(self <= other<const date_t&>()) - .def(self > other<const date_t&>()) - .def(self >= other<const date_t&>()) - .def(self == other<const date_t&>()) - .def(self != other<const date_t&>()) - - .def("year", &date_t::year) - .def("month", &date_t::month) - .def("day", &date_t::day) - .def("wday", &date_t::wday) - .def("localtime", &date_t::localtime) - - .def("write", &date_t::write) - .def("parse", &date_t::parse) - ; - - class_< interval_t > - ("Interval", init<optional<int, int, int, std::time_t, std::time_t> >()) - .def(init<std::string>()) - .def(! self) - - .def_readwrite("years", &interval_t::years) - .def_readwrite("months", &interval_t::months) - .def_readwrite("days", &interval_t::days) - .def_readwrite("hours", &interval_t::hours) - .def_readwrite("minutes", &interval_t::minutes) - .def_readwrite("seconds", &interval_t::seconds) - - .def_readwrite("begin", &interval_t::begin) - .def_readwrite("end", &interval_t::end) - - .def("__len__", interval_len) - .def("__getitem__", interval_getitem) - - .def("start", &interval_t::start) - .def("first", &interval_t::first) - .def("increment", &interval_t::increment) - ; - - def("parse_date", py_parse_date); - def("parse_date", py_parse_date_yr); -} - -#endif // USE_BOOST_PYTHON -#endif diff --git a/datetime.h b/datetime.h deleted file mode 100644 index cd7b3a16..00000000 --- a/datetime.h +++ /dev/null @@ -1,320 +0,0 @@ -#ifndef _DATETIME_H -#define _DATETIME_H - -#include <ctime> -#include <sstream> - -#include "error.h" - -class date_error : public error { - public: - date_error(const std::string& _reason) throw() : error(_reason) {} - virtual ~date_error() throw() {} -}; - -struct interval_t; -class datetime_t; - -class date_t -{ - date_t(const datetime_t& _when); - - protected: - std::time_t when; - - public: - static date_t now; - static const char * formats[]; - static int current_year; - static std::string input_format; - static std::string output_format; - - date_t() : when(0) {} - date_t(const date_t& _when) : when(_when.when) {} - - date_t(const std::time_t _when) : when(_when) { -#if 0 - struct std::tm * moment = std::localtime(&_when); - moment->tm_hour = 0; - moment->tm_min = 0; - moment->tm_sec = 0; - when = std::mktime(moment); -#endif - } - date_t(const interval_t& period); - date_t(const std::string& _when); - - virtual ~date_t() {} - - date_t& operator=(const date_t& _when) { - when = _when.when; - return *this; - } - date_t& operator=(const std::time_t _when) { - return *this = date_t(_when); - } - date_t& operator=(const datetime_t& _when) { - return *this = date_t(_when); - } - date_t& operator=(const interval_t& period) { - return *this = date_t(period); - } - date_t& operator=(const std::string& _when) { - return *this = date_t(_when); - } - - date_t& operator+=(const interval_t& period); - - long operator-=(const date_t& date) { - return (when - date.when) / 86400; - } - - virtual date_t& operator+=(const long days) { - // jww (2006-03-26): This is not accurate enough when DST is in effect! - when += days * 86400; - return *this; - } - virtual date_t& operator-=(const long days) { - // jww (2006-03-26): This is not accurate enough when DST is in effect! - when -= days * 86400; - return *this; - } - -#define DEF_DATE_OP(OP) \ - bool operator OP(const date_t& other) const { \ - return when OP other.when; \ - } - - DEF_DATE_OP(<) - DEF_DATE_OP(<=) - DEF_DATE_OP(>) - DEF_DATE_OP(>=) - DEF_DATE_OP(==) - DEF_DATE_OP(!=) - - operator bool() const { - return when != 0; - } - operator std::time_t() const { - return when; - } - operator std::string() const { - return to_string(); - } - - std::string to_string(const std::string& format = output_format) const { - char buf[64]; - std::strftime(buf, 63, format.c_str(), localtime()); - return buf; - } - - int year() const { - return localtime()->tm_year + 1900; - } - int month() const { - return localtime()->tm_mon + 1; - } - int day() const { - return localtime()->tm_mday; - } - int wday() const { - return localtime()->tm_wday; - } - - std::tm * localtime() const { - return std::localtime(&when); - } - - void write(std::ostream& out, - const std::string& format = output_format) const { - out << to_string(format); - } - - void parse(std::istream& in); - - friend class datetime_t; - friend struct interval_t; -}; - -inline long operator-(const date_t& left, const date_t& right) { - date_t temp(left); - temp -= right; - return temp; -} - -inline date_t operator+(const date_t& left, const long days) { - date_t temp(left); - temp += days; - return temp; -} - -inline date_t operator-(const date_t& left, const long days) { - date_t temp(left); - temp -= days; - return temp; -} - -inline std::ostream& operator<<(std::ostream& out, const date_t& moment) { - moment.write(out); - return out; -} - -inline std::istream& operator>>(std::istream& in, date_t& moment) { - moment.parse(in); - return in; -} - -class datetime_error : public error { - public: - datetime_error(const std::string& _reason) throw() : error(_reason) {} - virtual ~datetime_error() throw() {} -}; - -class datetime_t : public date_t -{ - public: - static datetime_t now; - - datetime_t() : date_t(now.when) {} - datetime_t(const datetime_t& _when) : date_t(_when.when) {} - datetime_t(const date_t& _when) : date_t(_when) {} - - datetime_t(const std::time_t _when) : date_t(_when) {} - datetime_t(const std::string& _when); - - datetime_t& operator=(const datetime_t& _when) { - when = _when.when; - return *this; - } - datetime_t& operator=(const date_t& _when) { - when = _when.when; - return *this; - } - datetime_t& operator=(const std::time_t _when) { - return *this = datetime_t(_when); - } - datetime_t& operator=(const std::string& _when) { - return *this = datetime_t(_when); - } - - long operator-=(const datetime_t& date) { - return when - date.when; - } - - virtual datetime_t& operator+=(const long secs) { - when += secs; - return *this; - } - virtual datetime_t& operator-=(const long secs) { - when -= secs; - return *this; - } - -#define DEF_DATETIME_OP(OP) \ - bool operator OP(const datetime_t& other) const { \ - return when OP other.when; \ - } - - DEF_DATETIME_OP(<) - DEF_DATETIME_OP(<=) - DEF_DATETIME_OP(>) - DEF_DATETIME_OP(>=) - DEF_DATETIME_OP(==) - DEF_DATETIME_OP(!=) - - int hour() const { - return localtime()->tm_hour; - } - int min() const { - return localtime()->tm_min; - } - int sec() const { - return localtime()->tm_sec; - } - - void parse(std::istream& in); -}; - -inline long operator-(const datetime_t& left, const datetime_t& right) { - std::time_t left_time(left); - std::time_t right_time(right); - return left_time - right_time; -} - -inline datetime_t operator+(const datetime_t& left, const long seconds) { - datetime_t temp(left); - temp += seconds; - return temp; -} - -inline datetime_t operator-(const datetime_t& left, const long seconds) { - datetime_t temp(left); - temp -= seconds; - return temp; -} - -std::ostream& operator<<(std::ostream& out, const datetime_t& moment); - -inline std::istream& operator>>(std::istream& in, datetime_t& moment) { - moment.parse(in); - return in; -} - -struct interval_t -{ - unsigned short years; - unsigned short months; - unsigned short days; - unsigned short hours; - unsigned short minutes; - unsigned short seconds; - - datetime_t begin; - datetime_t end; - - interval_t(int _days = 0, int _months = 0, int _years = 0, - const date_t& _begin = date_t(), - const date_t& _end = date_t()) - : years(_years), months(_months), days(_days), - hours(0), minutes(0), seconds(0), - begin(_begin), end(_end) {} - - interval_t(const std::string& desc) - : years(0), months(0), days(0), - hours(0), minutes(0), seconds(0) { - std::istringstream stream(desc); - parse(stream); - } - - operator bool() const { - return (years > 0 || months > 0 || days > 0 || - hours > 0 || minutes > 0 || seconds > 0); - } - - void start(const datetime_t& moment) { - begin = first(moment); - } - datetime_t first(const datetime_t& moment = datetime_t()) const; - datetime_t increment(const datetime_t&) const; - - void parse(std::istream& in); -}; - -inline date_t::date_t(const interval_t& period) { - when = period.first().when; -} - -inline date_t& date_t::operator+=(const interval_t& period) { - return *this = period.increment(*this); -} - -inline date_t::date_t(const datetime_t& _when) { - assert(0); - struct std::tm * moment = _when.localtime(); - moment->tm_hour = 0; - moment->tm_min = 0; - moment->tm_sec = 0; - when = std::mktime(moment); -} - -#endif // _DATETIME_H @@ -63,8 +63,6 @@ void debug_assert(const std::string& reason, #include <iostream> #include <cstdlib> -#include "datetime.h" - #define DEBUG_ENABLED extern std::ostream * _debug_stream; @@ -1,5 +1,4 @@ #include "derive.h" -#include "datetime.h" #include "error.h" #include "mask.h" @@ -318,7 +318,7 @@ unsigned int gnucash_parser_t::parse(std::istream& in, // user specified. // // jww (2006-09-13): Make this parser local somehow. - date_t::input_format = "%Y-%m-%d %H:%M:%S %z"; + //date_t::input_format = "%Y-%m-%d %H:%M:%S %z"; count = 0; action = NO_ACTION; @@ -1,5 +1,4 @@ #include "journal.h" -#include "datetime.h" #include "mask.h" #include "format.h" #if 0 @@ -23,14 +22,14 @@ transaction_t::~transaction_t() if (cost) delete cost; } -datetime_t transaction_t::actual_date() const +ptime transaction_t::actual_date() const { if (! _date && entry) return entry->actual_date(); return _date; } -datetime_t transaction_t::effective_date() const +ptime transaction_t::effective_date() const { if (! _date_eff && entry) return entry->effective_date(); @@ -182,7 +181,7 @@ bool entry_base_t::finalize() ! (*x)->amount.commodity().annotated) (*x)->amount.annotate_commodity (abs(per_unit_cost), - entry ? entry->actual_date() : datetime_t(), + entry ? entry->actual_date() : ptime(), entry ? entry->code : ""); (*x)->cost = new amount_t(- (per_unit_cost * (*x)->amount)); @@ -23,8 +23,8 @@ class transaction_t enum state_t { UNCLEARED, CLEARED, PENDING }; entry_t * entry; - datetime_t _date; - datetime_t _date_eff; + ptime _date; + ptime _date_eff; account_t * account; amount_t amount; std::string amount_expr; @@ -67,9 +67,9 @@ class transaction_t } ~transaction_t(); - datetime_t actual_date() const; - datetime_t effective_date() const; - datetime_t date() const { + ptime actual_date() const; + ptime effective_date() const; + ptime date() const { if (use_effective_date) return effective_date(); else @@ -151,8 +151,8 @@ class entry_base_t class entry_t : public entry_base_t { public: - datetime_t _date; - datetime_t _date_eff; + ptime _date; + ptime _date_eff; std::string code; std::string payee; @@ -167,15 +167,15 @@ class entry_t : public entry_base_t TRACE_DTOR("entry_t"); } - datetime_t actual_date() const { + ptime actual_date() const { return _date; } - datetime_t effective_date() const { - if (! _date_eff) + ptime effective_date() const { + if (_date_eff.is_not_a_date_time()) return _date; return _date_eff; } - datetime_t date() const { + ptime date() const { if (transaction_t::use_effective_date) return effective_date(); else @@ -13,7 +13,6 @@ #include <amount.h> #include <balance.h> #include <value.h> -#include <datetime.h> #include <xml.h> #include <xpath.h> #include <format.h> @@ -1,7 +1,6 @@ #include "journal.h" #include "ofx.h" #include "format.h" -#include "datetime.h" #include "error.h" #include "debug.h" #include "util.h" diff --git a/py_amount.cc b/py_amount.cc index 18fd3588..afa5b963 100644 --- a/py_amount.cc +++ b/py_amount.cc @@ -34,9 +34,9 @@ struct commodity_updater_wrap : public commodity_base_t::updater_t commodity_updater_wrap(PyObject * self_) : self(self_) {} virtual void operator()(commodity_base_t& commodity, - const datetime_t& moment, - const datetime_t& date, - const datetime_t& last, + const ptime& moment, + const ptime& date, + const ptime& last, amount_t& price) { call_method<void>(self, "__call__", commodity, moment, date, last, price); } @@ -8,7 +8,6 @@ void export_amount(); #if 0 void export_balance(); void export_value(); -void export_datetime(); void export_journal(); void export_parser(); @@ -29,7 +28,6 @@ void initialize_ledger_for_python() #if 0 export_balance(); export_value(); - export_datetime(); export_journal(); export_parser(); @@ -1,6 +1,5 @@ #include "journal.h" #include "qif.h" -#include "datetime.h" #include "error.h" #include "util.h" @@ -1,5 +1,4 @@ #include "quotes.h" -#include "datetime.h" #include "error.h" #include "debug.h" @@ -10,15 +9,15 @@ namespace ledger { void quotes_by_script::operator()(commodity_base_t& commodity, - const datetime_t& moment, - const datetime_t& date, - const datetime_t& last, + const ptime& moment, + const ptime& date, + const ptime& last, amount_t& price) { DEBUG_CLASS("ledger.quotes.download"); DEBUG_PRINT_("commodity: " << commodity.symbol); - DEBUG_PRINT_TIME_(datetime_t::now); + DEBUG_PRINT_TIME_(now); DEBUG_PRINT_TIME_(moment); DEBUG_PRINT_TIME_(date); DEBUG_PRINT_TIME_(last); @@ -27,9 +26,9 @@ void quotes_by_script::operator()(commodity_base_t& commodity, DEBUG_PRINT_("pricing_leeway is " << pricing_leeway); if ((commodity.history && - (datetime_t::now - commodity.history->last_lookup) < (long)pricing_leeway) || - (datetime_t::now - last) < (long)pricing_leeway || - (price && moment > date && (moment - date) <= (long)pricing_leeway)) + (now - commodity.history->last_lookup) < pricing_leeway) || + (now - last) < pricing_leeway || + (price && moment > date && (moment - date) <= pricing_leeway)) return; using namespace std; @@ -58,9 +57,9 @@ void quotes_by_script::operator()(commodity_base_t& commodity, DEBUG_PRINT_("downloaded quote: " << buf); price.parse(buf); - commodity.add_price(datetime_t::now, price); + commodity.add_price(now, price); - commodity.history->last_lookup = datetime_t::now; + commodity.history->last_lookup = now; cache_dirty = true; if (price && ! price_db.empty()) { @@ -69,8 +68,12 @@ void quotes_by_script::operator()(commodity_base_t& commodity, #else ofstream database(price_db.c_str(), ios_base::out | ios_base::app); #endif - database << "P " << datetime_t::now.to_string("%Y/%m/%d %H:%M:%S") +#if 0 + // jww (2007-04-18): Need to convert to local time and print + // here, print with UTC timezone specifier + database << "P " << now.to_string("%Y/%m/%d %H:%M:%S") << " " << commodity.symbol << " " << price << endl; +#endif } } else { throw new error(std::string("Failed to download price for '") + @@ -8,20 +8,20 @@ namespace ledger { class quotes_by_script : public commodity_base_t::updater_t { std::string price_db; - unsigned long pricing_leeway; + time_duration pricing_leeway; bool& cache_dirty; public: quotes_by_script(std::string _price_db, - unsigned long _pricing_leeway, + time_duration _pricing_leeway, bool& _cache_dirty) : price_db(_price_db), pricing_leeway(_pricing_leeway), cache_dirty(_cache_dirty) {} virtual void operator()(commodity_base_t& commodity, - const datetime_t& moment, - const datetime_t& date, - const datetime_t& last, + const ptime& moment, + const ptime& date, + const ptime& last, amount_t& price); }; @@ -44,13 +44,13 @@ void report_t::ftime(value_t& result, xml::xpath_t::scope_t * locals) if (locals->args.size() < 1) throw new error("usage: ftime(DATE [, DATE_FORMAT])"); - datetime_t date = locals->args[0].to_datetime(); + ptime date = locals->args[0].to_datetime(); std::string date_format; if (locals->args.size() == 2) date_format = locals->args[1].to_string(); else - date_format = datetime_t::output_format; + date_format = ptime::output_format; result.set_string(date.to_string(date_format)); } @@ -136,7 +136,7 @@ bool session_t::resolve(const std::string& name, value_t& result, switch (*p) { case 'd': if (name == "date_format") { - result.set_string(datetime_t::output_format); + result.set_string(ptime::output_format); return true; } break; @@ -37,7 +37,7 @@ class session_t : public xml::xpath_t::scope_t bool verbose_mode; bool trace_mode; - datetime_t now; + ptime now; elision_style_t elision_style; @@ -90,7 +90,7 @@ class session_t : public xml::xpath_t::scope_t verbose_mode(false), trace_mode(false), - now(datetime_t::now), + now(now), elision_style(ABBREVIATE), abbrev_length(2), diff --git a/tests/corelib/numerics/Commodity.cc b/tests/corelib/numerics/Commodity.cc index 77cdd7b9..b15211f6 100644 --- a/tests/corelib/numerics/Commodity.cc +++ b/tests/corelib/numerics/Commodity.cc @@ -15,10 +15,23 @@ void CommodityTestCase::testConstructors() void CommodityTestCase::testPriceHistory() { + datetime_t jan17_07("2007/01/17 00:00:00"); + datetime_t feb27_07("2007/02/27 18:00:00"); + datetime_t feb28_07("2007/02/28 06:00:00"); + datetime_t feb28_07sbm("2007/02/28 11:59:59"); + datetime_t mar01_07("2007/03/01 00:00:00"); + datetime_t apr15_07("2007/04/15 13:00:00"); + // jww (2007-04-17): tbd amount_t x1("100.10 AAPL"); - assertEqual(x1, x1.value(datetime_t())); + // Commodities cannot be constructed by themselves, since a great + // deal of their state depends on how they were seen to be used. + commodity_t& aapl(x1.commodity()); + + aapl.add_price(datetime_t(), amount_t("$10.20")); + + assertEqual(amount_t("$1021.02"), x1.value(datetime_t())); assertValid(x1); } @@ -30,7 +30,7 @@ static std::list<std::pair<std::string, int> > include_stack; #ifdef TIMELOG_SUPPORT struct time_entry_t { - datetime_t checkin; + ptime checkin; account_t * account; std::string desc; }; @@ -491,7 +491,7 @@ bool textual_parser_t::test(std::istream& in) const return true; } -static void clock_out_from_timelog(const datetime_t& when, +static void clock_out_from_timelog(const ptime& when, account_t * account, const char * desc, journal_t * journal) @@ -674,16 +674,17 @@ unsigned int textual_parser_t::parse(std::istream& in, if (! time_field_ptr) break; std::string date_field = date_field_ptr; - char * symbol_and_price; - datetime_t datetime; + char * symbol_and_price; + ptime datetime; if (std::isdigit(time_field_ptr[0])) { symbol_and_price = next_element(time_field_ptr); if (! symbol_and_price) break; - datetime = date_field + " " + time_field_ptr; + datetime = ptime_from_local_time_string(date_field + " " + + time_field_ptr); } else { symbol_and_price = time_field_ptr; - datetime = date_t(date_field); + datetime = ptime_from_local_date_string(date_field); } std::string symbol; @@ -706,7 +707,7 @@ unsigned int textual_parser_t::parse(std::istream& in, } case 'Y': // set current year - date_t::current_year = std::atoi(skip_ws(line + 1)) - 1900; + date_t::current_year = std::atoi(skip_ws(line + 1)); break; #ifdef TIMELOG_SUPPORT @@ -879,7 +880,7 @@ unsigned int textual_parser_t::parse(std::istream& in, for (std::list<time_entry_t>::iterator i = time_entries.begin(); i != time_entries.end(); i++) - clock_out_from_timelog(datetime_t::now, (*i).account, NULL, journal); + clock_out_from_timelog(now, (*i).account, NULL, journal); time_entries.clear(); } diff --git a/times.cc b/times.cc new file mode 100644 index 00000000..60926112 --- /dev/null +++ b/times.cc @@ -0,0 +1,7 @@ +#include "times.h" + +namespace ledger { + + ptime now = boost::posix_time::second_clock::universal_time(); + +} diff --git a/times.h b/times.h new file mode 100644 index 00000000..953d3d4d --- /dev/null +++ b/times.h @@ -0,0 +1,41 @@ +#ifndef _TIMES_H +#define _TIMES_H + +#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/date_time/posix_time/posix_time_duration.hpp> +#include <boost/date_time/posix_time/posix_time_config.hpp> +#include <boost/date_time/local_time_adjustor.hpp> + +#include <ctime> +#include <string> + +namespace ledger { + +using namespace boost::posix_time; +using namespace boost::date_time; + +typedef ptime::time_duration_type time_duration; + +class interval_t {}; + +inline ptime ptime_local_to_utc(const ptime& when) { + struct std::tm tm_gmt = to_tm(when); + return from_time_t(std::mktime(&tm_gmt)); +} + +// jww (2007-04-18): I need to make a general parsing function +// instead, and then make these into private methods. +inline ptime ptime_from_local_date_string(const std::string& date_string) { + return ptime_local_to_utc(ptime(boost::gregorian::from_string(date_string), + time_duration())); +} + +inline ptime ptime_from_local_time_string(const std::string& time_string) { + return ptime_local_to_utc(time_from_string(time_string)); +} + +extern ptime now; + +} + +#endif /* _TIMES_H */ @@ -8,8 +8,8 @@ bool trace_mode; void trace(const std::string& cat, const std::string& str) { char buf[32]; - std::strftime(buf, 31, "%H:%M:%S", datetime_t::now.localtime()); - std::cerr << buf << " " << cat << ": " << str << std::endl; + std::cerr << now.to_short_string() << " " << cat << ": " << str + << std::endl; } void trace_push(const std::string& cat, const std::string& str, @@ -27,14 +27,14 @@ long value_t::to_integer() const } } -datetime_t value_t::to_datetime() const +ptime value_t::to_datetime() const { if (type == DATETIME) { - return *(datetime_t *) data; + return *(ptime *) data; } else { value_t temp(*this); temp.cast(DATETIME); - return *(datetime_t *) temp.data; + return *(ptime *) temp.data; } } @@ -171,7 +171,7 @@ value_t& value_t::operator=(const value_t& val) return *this; } else if (type == DATETIME && val.type == DATETIME) { - *((datetime_t *) data) = *((datetime_t *) val.data); + *((ptime *) data) = *((ptime *) val.data); return *this; } else if (type == AMOUNT && val.type == AMOUNT) { @@ -207,7 +207,7 @@ value_t& value_t::operator=(const value_t& val) break; case DATETIME: - *((datetime_t *) data) = *((datetime_t *) val.data); + *((ptime *) data) = *((ptime *) val.data); break; case AMOUNT: @@ -293,16 +293,16 @@ value_t& value_t::operator+=(const value_t& val) case DATETIME: switch (val.type) { case INTEGER: - *((datetime_t *) data) += *((long *) val.data); + *((ptime *) data) += seconds(*((long *) val.data)); break; case AMOUNT: - *((datetime_t *) data) += long(*((amount_t *) val.data)); + *((ptime *) data) += seconds(long(*((amount_t *) val.data))); break; case BALANCE: - *((datetime_t *) data) += long(*((balance_t *) val.data)); + *((ptime *) data) += seconds(long(*((balance_t *) val.data))); break; case BALANCE_PAIR: - *((datetime_t *) data) += long(*((balance_pair_t *) val.data)); + *((ptime *) data) += seconds(long(*((balance_pair_t *) val.data))); break; case STRING: throw new value_error("Cannot add a string to an date/time"); @@ -476,22 +476,22 @@ value_t& value_t::operator-=(const value_t& val) case DATETIME: switch (val.type) { case INTEGER: - *((datetime_t *) data) -= *((long *) val.data); + *((ptime *) data) -= seconds(*((long *) val.data)); break; case DATETIME: { - long tval = *((datetime_t *) data) - *((datetime_t *) val.data); + time_duration tval = ((ptime *) data)->operator-(*((ptime *) val.data)); cast(INTEGER); - *((long *) data) = tval; + *((long *) data) = tval.total_seconds(); break; } case AMOUNT: - *((datetime_t *) data) -= long(*((amount_t *) val.data)); + *((ptime *) data) -= seconds(long(*((amount_t *) val.data))); break; case BALANCE: - *((datetime_t *) data) -= long(*((balance_t *) val.data)); + *((ptime *) data) -= seconds(long(*((balance_t *) val.data))); break; case BALANCE_PAIR: - *((datetime_t *) data) -= long(*((balance_pair_t *) val.data)); + *((ptime *) data) -= seconds(long(*((balance_pair_t *) val.data))); break; default: assert(0); @@ -877,7 +877,7 @@ value_t::operator bool() const case INTEGER: return *(long *) data; case DATETIME: - return *(datetime_t *) data; + return ! ((ptime *) data)->is_not_a_date_time(); case AMOUNT: return *(amount_t *) data; case BALANCE: @@ -911,7 +911,7 @@ value_t::operator long() const case INTEGER: return *((long *) data); case DATETIME: - return *((datetime_t *) data); + throw new value_error("Cannot convert a date/time to an integer"); case AMOUNT: return *((amount_t *) data); case BALANCE: @@ -936,15 +936,15 @@ value_t::operator long() const } template <> -value_t::operator datetime_t() const +value_t::operator ptime() const { switch (type) { case BOOLEAN: throw new value_error("Cannot convert a boolean to a date/time"); case INTEGER: - return *((long *) data); + throw new value_error("Cannot convert an integer to a date/time"); case DATETIME: - return *((datetime_t *) data); + return *((ptime *) data); case AMOUNT: throw new value_error("Cannot convert an amount to a date/time"); case BALANCE: @@ -965,7 +965,7 @@ value_t::operator datetime_t() const break; } assert(0); - return 0; + return ptime(); } template <> @@ -1039,15 +1039,15 @@ bool value_t::operator OP(const value_t& val) \ { \ switch (type) { \ case BOOLEAN: \ - switch (val.type) { \ + switch (val.type) { \ case BOOLEAN: \ - return *((bool *) data) OP *((bool *) val.data); \ + return *((bool *) data) OP *((bool *) val.data); \ \ case INTEGER: \ return *((bool *) data) OP bool(*((long *) val.data)); \ \ case DATETIME: \ - return *((bool *) data) OP bool(*((datetime_t *) val.data)); \ + throw new value_error("Cannot compare a boolean to a date/time"); \ \ case AMOUNT: \ return *((bool *) data) OP bool(*((amount_t *) val.data)); \ @@ -1056,16 +1056,16 @@ bool value_t::operator OP(const value_t& val) \ return *((bool *) data) OP bool(*((balance_t *) val.data)); \ \ case BALANCE_PAIR: \ - return *((bool *) data) OP bool(*((balance_pair_t *) val.data)); \ + return *((bool *) data) OP bool(*((balance_pair_t *) val.data)); \ \ case STRING: \ throw new value_error("Cannot compare a boolean to a string"); \ case XML_NODE: \ throw new value_error("Cannot compare a boolean to an XML node"); \ 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: \ - throw new value_error("Cannot compare a boolean to a sequence"); \ + throw new value_error("Cannot compare a boolean to a sequence"); \ \ default: \ assert(0); \ @@ -1074,7 +1074,7 @@ bool value_t::operator OP(const value_t& val) \ break; \ \ case INTEGER: \ - switch (val.type) { \ + switch (val.type) { \ case BOOLEAN: \ return (*((long *) data) OP \ ((long) *((bool *) val.data))); \ @@ -1083,8 +1083,7 @@ bool value_t::operator OP(const value_t& val) \ return (*((long *) data) OP *((long *) val.data)); \ \ case DATETIME: \ - return (*((long *) data) OP \ - ((long) *((datetime_t *) val.data))); \ + throw new value_error("Cannot compare an integer to a date/time"); \ \ case AMOUNT: \ return (amount_t(*((long *) data)) OP \ @@ -1096,14 +1095,14 @@ bool value_t::operator OP(const value_t& val) \ \ case BALANCE_PAIR: \ return (balance_pair_t(*((long *) data)) OP \ - *((balance_pair_t *) val.data)); \ + *((balance_pair_t *) val.data)); \ \ case STRING: \ throw new value_error("Cannot compare an integer to a string"); \ case XML_NODE: \ throw new value_error("Cannot compare an integer to an XML node"); \ 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: \ throw new value_error("Cannot compare an integer to a sequence"); \ \ @@ -1114,17 +1113,15 @@ bool value_t::operator OP(const value_t& val) \ break; \ \ case DATETIME: \ - switch (val.type) { \ + switch (val.type) { \ case BOOLEAN: \ throw new value_error("Cannot compare a date/time to a boolean"); \ \ case INTEGER: \ - return (*((datetime_t *) data) OP \ - datetime_t(*((long *) val.data))); \ + throw new value_error("Cannot compare a date/time to an integer"); \ \ case DATETIME: \ - return (*((datetime_t *) data) OP \ - *((datetime_t *) val.data)); \ + return *((ptime *) data) OP *((ptime *) val.data); \ \ case AMOUNT: \ throw new value_error("Cannot compare a date/time to an amount"); \ @@ -1148,19 +1145,19 @@ bool value_t::operator OP(const value_t& val) \ break; \ \ case AMOUNT: \ - switch (val.type) { \ + switch (val.type) { \ case BOOLEAN: \ throw new value_error("Cannot compare an amount to a boolean"); \ \ case INTEGER: \ return (*((amount_t *) data) OP \ - amount_t(*((long *) val.data))); \ + amount_t(*((long *) val.data))); \ \ case DATETIME: \ throw new value_error("Cannot compare an amount to a date/time"); \ \ case AMOUNT: \ - return *((amount_t *) data) OP *((amount_t *) val.data); \ + return *((amount_t *) data) OP *((amount_t *) val.data); \ \ case BALANCE: \ return (balance_t(*((amount_t *) data)) OP \ @@ -1168,16 +1165,16 @@ bool value_t::operator OP(const value_t& val) \ \ case BALANCE_PAIR: \ return (balance_t(*((amount_t *) data)) OP \ - *((balance_pair_t *) val.data)); \ + *((balance_pair_t *) val.data)); \ \ case STRING: \ throw new value_error("Cannot compare an amount to a string"); \ case XML_NODE: \ throw new value_error("Cannot compare an amount to an XML node"); \ 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: \ - throw new value_error("Cannot compare an amount to a sequence"); \ + throw new value_error("Cannot compare an amount to a sequence"); \ \ default: \ assert(0); \ @@ -1186,7 +1183,7 @@ bool value_t::operator OP(const value_t& val) \ break; \ \ case BALANCE: \ - switch (val.type) { \ + switch (val.type) { \ case BOOLEAN: \ throw new value_error("Cannot compare a balance to a boolean"); \ \ @@ -1197,23 +1194,23 @@ bool value_t::operator OP(const value_t& val) \ throw new value_error("Cannot compare a balance to a date/time"); \ \ case AMOUNT: \ - return *((balance_t *) data) OP *((amount_t *) val.data); \ + return *((balance_t *) data) OP *((amount_t *) val.data); \ \ case BALANCE: \ return *((balance_t *) data) OP *((balance_t *) val.data); \ \ case BALANCE_PAIR: \ return (*((balance_t *) data) OP \ - ((balance_pair_t *) val.data)->quantity); \ + ((balance_pair_t *) val.data)->quantity); \ \ case STRING: \ throw new value_error("Cannot compare a balance to a string"); \ case XML_NODE: \ throw new value_error("Cannot compare a balance to an XML node"); \ 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: \ - throw new value_error("Cannot compare a balance to a sequence"); \ + throw new value_error("Cannot compare a balance to a sequence"); \ \ default: \ assert(0); \ @@ -1222,9 +1219,9 @@ bool value_t::operator OP(const value_t& val) \ break; \ \ case BALANCE_PAIR: \ - switch (val.type) { \ + switch (val.type) { \ case BOOLEAN: \ - throw new value_error("Cannot compare a balance pair to a boolean"); \ + throw new value_error("Cannot compare a balance pair to a boolean"); \ \ case INTEGER: \ return (((balance_pair_t *) data)->quantity OP \ @@ -1243,7 +1240,7 @@ bool value_t::operator OP(const value_t& val) \ \ case BALANCE_PAIR: \ return (*((balance_pair_t *) data) OP \ - *((balance_pair_t *) val.data)); \ + *((balance_pair_t *) val.data)); \ \ case STRING: \ throw new value_error("Cannot compare a balance pair to a string"); \ @@ -1261,7 +1258,7 @@ bool value_t::operator OP(const value_t& val) \ break; \ \ case STRING: \ - switch (val.type) { \ + switch (val.type) { \ case BOOLEAN: \ throw new value_error("Cannot compare a string to a boolean"); \ case INTEGER: \ @@ -1284,9 +1281,9 @@ bool value_t::operator OP(const value_t& val) \ (*(xml::node_t **) val.data)->text()); \ \ case POINTER: \ - throw new value_error("Cannot compare a string to a pointer"); \ + throw new value_error("Cannot compare a string to a pointer"); \ case SEQUENCE: \ - throw new value_error("Cannot compare a string to a sequence"); \ + throw new value_error("Cannot compare a string to a sequence"); \ \ default: \ assert(0); \ @@ -1295,13 +1292,13 @@ bool value_t::operator OP(const value_t& val) \ break; \ \ case XML_NODE: \ - switch (val.type) { \ + switch (val.type) { \ case BOOLEAN: \ throw new value_error("Cannot compare an XML node to a boolean"); \ case INTEGER: \ - throw new value_error("Cannot compare an XML node to an integer"); \ + throw new value_error("Cannot compare an XML node to an integer"); \ case DATETIME: \ - throw new value_error("Cannot compare an XML node to a date/time"); \ + throw new value_error("Cannot compare an XML node to a date/time"); \ case AMOUNT: \ throw new value_error("Cannot compare an XML node to an amount"); \ case BALANCE: \ @@ -1329,7 +1326,7 @@ bool value_t::operator OP(const value_t& val) \ break; \ \ case POINTER: \ - switch (val.type) { \ + switch (val.type) { \ case BOOLEAN: \ throw new value_error("Cannot compare a pointer to a boolean"); \ case INTEGER: \ @@ -1349,7 +1346,7 @@ bool value_t::operator OP(const value_t& val) \ case POINTER: \ return (*((void **) data) OP *((void **) val.data)); \ case SEQUENCE: \ - throw new value_error("Cannot compare a pointer to a sequence"); \ + throw new value_error("Cannot compare a pointer to a sequence"); \ \ default: \ assert(0); \ @@ -1414,8 +1411,8 @@ void value_t::cast(type_t cast_type) case INTEGER: break; case DATETIME: - *((datetime_t *) data) = datetime_t(*((long *) data)); - break; + throw new value_error("Cannot convert an integer to a date/time"); + case AMOUNT: new((amount_t *)data) amount_t(*((long *) data)); break; @@ -1447,11 +1444,10 @@ void value_t::cast(type_t cast_type) case DATETIME: switch (cast_type) { case BOOLEAN: - *((bool *) data) = *((datetime_t *) data); + *((bool *) data) = ! ((ptime *) data)->is_not_a_date_time(); break; case INTEGER: - *((long *) data) = *((datetime_t *) data); - break; + throw new value_error("Cannot convert a date/time to an integer"); case DATETIME: break; case AMOUNT: @@ -1856,7 +1852,7 @@ void value_t::abs() } } -value_t value_t::value(const datetime_t& moment) const +value_t value_t::value(const ptime& moment) const { switch (type) { case BOOLEAN: @@ -2014,18 +2010,18 @@ value_t value_t::date() const case BOOLEAN: throw new value_error("Cannot find the date of a boolean"); case INTEGER: - return datetime_t(); + return ptime(); case DATETIME: return *this; case AMOUNT: - return datetime_t(((amount_t *) data)->date()); + return ptime(((amount_t *) data)->date()); case BALANCE: - return datetime_t(((balance_t *) data)->date()); + return ptime(((balance_t *) data)->date()); case BALANCE_PAIR: - return datetime_t(((balance_pair_t *) data)->quantity.date()); + return ptime(((balance_pair_t *) data)->quantity.date()); case STRING: throw new value_error("Cannot find the date of a string"); @@ -2209,7 +2205,7 @@ std::ostream& operator<<(std::ostream& out, const value_t& val) out << *(long *) val.data; break; case value_t::DATETIME: - out << *(datetime_t *) val.data; + out << *(ptime *) val.data; break; case value_t::AMOUNT: out << *(amount_t *) val.data; @@ -2284,7 +2280,7 @@ void value_context::describe(std::ostream& out) const throw() out << *((long *) bal->data); break; case value_t::DATETIME: - out << *((datetime_t *) bal->data); + out << *((ptime *) bal->data); break; case value_t::AMOUNT: out << *((amount_t *) bal->data); @@ -2415,7 +2411,7 @@ void export_value() .def(init<std::string>()) .def(init<double>()) .def(init<long>()) - .def(init<datetime_t>()) + .def(init<ptime>()) .def(self + self) .def(self + other<std::string>()) @@ -2517,7 +2513,7 @@ void export_value() .def(self < other<balance_t>()) .def(self < other<amount_t>()) .def(self < long()) - .def(self < other<datetime_t>()) + .def(self < other<ptime>()) .def(self < double()) .def(other<std::string>() < self) @@ -2525,7 +2521,7 @@ void export_value() .def(other<balance_t>() < self) .def(other<amount_t>() < self) .def(long() < self) - .def(other<datetime_t>() < self) + .def(other<ptime>() < self) .def(double() < self) .def(self <= self) @@ -2534,7 +2530,7 @@ void export_value() .def(self <= other<balance_t>()) .def(self <= other<amount_t>()) .def(self <= long()) - .def(self <= other<datetime_t>()) + .def(self <= other<ptime>()) .def(self <= double()) .def(other<std::string>() <= self) @@ -2542,7 +2538,7 @@ void export_value() .def(other<balance_t>() <= self) .def(other<amount_t>() <= self) .def(long() <= self) - .def(other<datetime_t>() <= self) + .def(other<ptime>() <= self) .def(double() <= self) .def(self > self) @@ -2551,7 +2547,7 @@ void export_value() .def(self > other<balance_t>()) .def(self > other<amount_t>()) .def(self > long()) - .def(self > other<datetime_t>()) + .def(self > other<ptime>()) .def(self > double()) .def(other<std::string>() > self) @@ -2559,7 +2555,7 @@ void export_value() .def(other<balance_t>() > self) .def(other<amount_t>() > self) .def(long() > self) - .def(other<datetime_t>() > self) + .def(other<ptime>() > self) .def(double() > self) .def(self >= self) @@ -2568,7 +2564,7 @@ void export_value() .def(self >= other<balance_t>()) .def(self >= other<amount_t>()) .def(self >= long()) - .def(self >= other<datetime_t>()) + .def(self >= other<ptime>()) .def(self >= double()) .def(other<std::string>() >= self) @@ -2576,7 +2572,7 @@ void export_value() .def(other<balance_t>() >= self) .def(other<amount_t>() >= self) .def(long() >= self) - .def(other<datetime_t>() >= self) + .def(other<ptime>() >= self) .def(double() >= self) .def(self == self) @@ -2585,7 +2581,7 @@ void export_value() .def(self == other<balance_t>()) .def(self == other<amount_t>()) .def(self == long()) - .def(self == other<datetime_t>()) + .def(self == other<ptime>()) .def(self == double()) .def(other<std::string>() == self) @@ -2593,7 +2589,7 @@ void export_value() .def(other<balance_t>() == self) .def(other<amount_t>() == self) .def(long() == self) - .def(other<datetime_t>() == self) + .def(other<ptime>() == self) .def(double() == self) .def(self != self) @@ -2602,7 +2598,7 @@ void export_value() .def(self != other<balance_t>()) .def(self != other<amount_t>()) .def(self != long()) - .def(self != other<datetime_t>()) + .def(self != other<ptime>()) .def(self != double()) .def(other<std::string>() != self) @@ -2610,7 +2606,7 @@ void export_value() .def(other<balance_t>() != self) .def(other<amount_t>() != self) .def(long() != self) - .def(other<datetime_t>() != self) + .def(other<ptime>() != self) .def(double() != self) .def(! self) @@ -63,9 +63,9 @@ class value_t *((long *) data) = val; type = INTEGER; } - value_t(const datetime_t val) { - TRACE_CTOR("value_t(const datetime_t)"); - *((datetime_t *) data) = val; + value_t(const ptime val) { + TRACE_CTOR("value_t(const ptime)"); + *((ptime *) data) = val; type = DATETIME; } value_t(const unsigned long val) { @@ -144,10 +144,10 @@ class value_t } return *this; } - value_t& operator=(const datetime_t val) { - if ((datetime_t *) data != &val) { + value_t& operator=(const ptime val) { + if ((ptime *) data != &val) { destroy(); - *((datetime_t *) data) = val; + *((ptime *) data) = val; type = DATETIME; } return *this; @@ -276,7 +276,7 @@ class value_t bool to_boolean() const; long to_integer() const; - datetime_t to_datetime() const; + ptime to_datetime() const; amount_t to_amount() const; balance_t to_balance() const; balance_pair_t to_balance_pair() const; @@ -417,7 +417,7 @@ class value_t case INTEGER: return *((long *) data) == 0; case DATETIME: - return ! *((datetime_t *) data); + return ((ptime *) data)->is_not_a_date_time(); case AMOUNT: return ((amount_t *) data)->realzero(); case BALANCE: @@ -450,7 +450,7 @@ class value_t const bool keep_tag = amount_t::keep_tag) const; value_t& add(const amount_t& amount, const amount_t * cost = NULL); - value_t value(const datetime_t& moment) const; + value_t value(const ptime& moment) const; void reduce(); value_t reduced() const { @@ -466,35 +466,57 @@ class value_t const int latter_width = -1) const; }; -#define DEF_VALUE_AUX_OP(OP) \ - inline value_t operator OP(const balance_pair_t& val, \ - const value_t& obj) { \ - return value_t(val) OP obj; \ - } \ - inline value_t operator OP(const balance_t& val, \ - const value_t& obj) { \ - return value_t(val) OP obj; \ - } \ - inline value_t operator OP(const amount_t& val, \ - const value_t& obj) { \ - return value_t(val) OP obj; \ - } \ - template <typename T> \ - inline value_t operator OP(T val, const value_t& obj) { \ - return value_t(val) OP obj; \ - } - -DEF_VALUE_AUX_OP(+) -DEF_VALUE_AUX_OP(-) -DEF_VALUE_AUX_OP(*) -DEF_VALUE_AUX_OP(/) - -DEF_VALUE_AUX_OP(<) -DEF_VALUE_AUX_OP(<=) -DEF_VALUE_AUX_OP(>) -DEF_VALUE_AUX_OP(>=) -DEF_VALUE_AUX_OP(==) -DEF_VALUE_AUX_OP(!=) +#define DEFINE_VALUE_OPERATORS(T, OP) \ +inline value_t operator OP(const T& val, const value_t& obj) { \ + return value_t(val) OP obj; \ +} + +DEFINE_VALUE_OPERATORS(bool, ==) +DEFINE_VALUE_OPERATORS(bool, !=) + +DEFINE_VALUE_OPERATORS(long, +) +DEFINE_VALUE_OPERATORS(long, -) +DEFINE_VALUE_OPERATORS(long, *) +DEFINE_VALUE_OPERATORS(long, /) +DEFINE_VALUE_OPERATORS(long, <) +DEFINE_VALUE_OPERATORS(long, <=) +DEFINE_VALUE_OPERATORS(long, >) +DEFINE_VALUE_OPERATORS(long, >=) +DEFINE_VALUE_OPERATORS(long, ==) +DEFINE_VALUE_OPERATORS(long, !=) + +DEFINE_VALUE_OPERATORS(amount_t, +) +DEFINE_VALUE_OPERATORS(amount_t, -) +DEFINE_VALUE_OPERATORS(amount_t, *) +DEFINE_VALUE_OPERATORS(amount_t, /) +DEFINE_VALUE_OPERATORS(amount_t, <) +DEFINE_VALUE_OPERATORS(amount_t, <=) +DEFINE_VALUE_OPERATORS(amount_t, >) +DEFINE_VALUE_OPERATORS(amount_t, >=) +DEFINE_VALUE_OPERATORS(amount_t, ==) +DEFINE_VALUE_OPERATORS(amount_t, !=) + +DEFINE_VALUE_OPERATORS(balance_t, +) +DEFINE_VALUE_OPERATORS(balance_t, -) +DEFINE_VALUE_OPERATORS(balance_t, *) +DEFINE_VALUE_OPERATORS(balance_t, /) +DEFINE_VALUE_OPERATORS(balance_t, <) +DEFINE_VALUE_OPERATORS(balance_t, <=) +DEFINE_VALUE_OPERATORS(balance_t, >) +DEFINE_VALUE_OPERATORS(balance_t, >=) +DEFINE_VALUE_OPERATORS(balance_t, ==) +DEFINE_VALUE_OPERATORS(balance_t, !=) + +DEFINE_VALUE_OPERATORS(balance_pair_t, +) +DEFINE_VALUE_OPERATORS(balance_pair_t, -) +DEFINE_VALUE_OPERATORS(balance_pair_t, *) +DEFINE_VALUE_OPERATORS(balance_pair_t, /) +DEFINE_VALUE_OPERATORS(balance_pair_t, <) +DEFINE_VALUE_OPERATORS(balance_pair_t, <=) +DEFINE_VALUE_OPERATORS(balance_pair_t, >) +DEFINE_VALUE_OPERATORS(balance_pair_t, >=) +DEFINE_VALUE_OPERATORS(balance_pair_t, ==) +DEFINE_VALUE_OPERATORS(balance_pair_t, !=) template <typename T> value_t::operator T() const @@ -505,7 +527,7 @@ value_t::operator T() const case INTEGER: return *(long *) data; case DATETIME: - return *(datetime_t *) data; + return *(ptime *) data; case AMOUNT: return *(amount_t *) data; case BALANCE: @@ -529,7 +551,7 @@ value_t::operator T() const template <> value_t::operator bool() const; template <> value_t::operator long() const; -template <> value_t::operator datetime_t() const; +template <> value_t::operator ptime() const; template <> value_t::operator double() const; template <> value_t::operator std::string() const; @@ -1,6 +1,5 @@ #include "xml.h" #include "journal.h" -#include "datetime.h" #include "error.h" #include <iostream> |