Initial round of changes to use boost_date_time

This commit is contained in:
John Wiegley 2007-04-18 23:50:25 +00:00
parent 4c460a1c40
commit ba2a54f3d2
35 changed files with 565 additions and 1330 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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())

148
amount.h
View file

@ -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;
#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 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;

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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));

191
configure vendored
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -1,5 +1,4 @@
#include "derive.h"
#include "datetime.h"
#include "error.h"
#include "mask.h"

View file

@ -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;

View file

@ -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));

View file

@ -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

View file

@ -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
ofx.cc
View file

@ -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"

View file

@ -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);
}

View file

@ -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
qif.cc
View file

@ -1,6 +1,5 @@
#include "journal.h"
#include "qif.h"
#include "datetime.h"
#include "error.h"
#include "util.h"

View file

@ -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 '") +

View file

@ -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);
};

View file

@ -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));
}

View file

@ -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;

View file

@ -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),

View file

@ -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);
}

View file

@ -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();
}

7
times.cc Normal file
View file

@ -0,0 +1,7 @@
#include "times.h"
namespace ledger {
ptime now = boost::posix_time::second_clock::universal_time();
}

41
times.h Normal file
View file

@ -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 */

View file

@ -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,

164
value.cc
View file

@ -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)

98
value.h
View file

@ -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; \
}
#define DEFINE_VALUE_OPERATORS(T, OP) \
inline value_t operator OP(const 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(/)
DEFINE_VALUE_OPERATORS(bool, ==)
DEFINE_VALUE_OPERATORS(bool, !=)
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_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
xml.cc
View file

@ -1,6 +1,5 @@
#include "xml.h"
#include "journal.h"
#include "datetime.h"
#include "error.h"
#include <iostream>