More refactoring

This commit is contained in:
John Wiegley 2007-04-20 02:13:48 +00:00
parent 0a6b5726ec
commit 539370ff1b
25 changed files with 276 additions and 286 deletions

View file

@ -164,6 +164,11 @@ if HAVE_BOOST_PYTHON
noinst_PROGRAMS = ledger.so
CLEANFILES = ledger.so
clean-local:
rm -fr build
ledger_so_SOURCES = pyledger.cc
PYLIBS = pyledger ledger gdtoa boost_date_time boost_regex boost_python gmp

View file

@ -433,6 +433,7 @@ info_TEXINFOS = ledger.texi
######################################################################
lisp_LISP = ledger.el timeclock.el
@HAVE_BOOST_PYTHON_TRUE@CLEANFILES = ledger.so
@HAVE_BOOST_PYTHON_TRUE@ledger_so_SOURCES = pyledger.cc
@HAVE_BOOST_PYTHON_TRUE@PYLIBS = pyledger ledger gdtoa boost_date_time \
@HAVE_BOOST_PYTHON_TRUE@ boost_regex boost_python gmp \
@ -1589,6 +1590,7 @@ install-strip:
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@ -1599,11 +1601,12 @@ maintainer-clean-generic:
-rm -f parsetime.cc
-rm -f parsetime.h
-rm -f scantime.cc
@HAVE_BOOST_PYTHON_FALSE@clean-local:
@HAVE_BOOST_PYTHON_FALSE@install-exec-hook:
clean: clean-recursive
clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
clean-libLTLIBRARIES clean-libtool clean-lisp \
clean-libLTLIBRARIES clean-libtool clean-lisp clean-local \
clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-recursive
@ -1750,7 +1753,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-dvi-am uninstall-html-am \
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am am--refresh check check-TESTS check-am clean \
clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
clean-libLTLIBRARIES clean-libtool clean-lisp \
clean-libLTLIBRARIES clean-libtool clean-lisp clean-local \
clean-noinstPROGRAMS ctags ctags-recursive dist dist-all \
dist-bzip2 dist-gzip dist-hook dist-info dist-shar dist-tarZ \
dist-zip distcheck distclean distclean-compile \
@ -1777,6 +1780,9 @@ uninstall-am: uninstall-binPROGRAMS uninstall-dvi-am uninstall-html-am \
dist-hook:
rm -fr `find $(distdir) -name .svn`
@HAVE_BOOST_PYTHON_TRUE@clean-local:
@HAVE_BOOST_PYTHON_TRUE@ rm -fr build
@HAVE_BOOST_PYTHON_TRUE@ledger.so: pyledger.cc libledger.la gdtoa/libgdtoa.la libpyledger.la
@HAVE_BOOST_PYTHON_TRUE@ SRCDIR="$(srcdir)" \
@HAVE_BOOST_PYTHON_TRUE@ CFLAGS="$(CPPFLAGS)" \

View file

@ -747,7 +747,7 @@ amount_t::operator double() const
return std::atof(num.str().c_str());
}
amount_t amount_t::value(const ptime& moment) const
amount_t amount_t::value(const moment_t& moment) const
{
if (quantity) {
amount_t amt(commodity().value(moment));
@ -1132,7 +1132,7 @@ static void parse_commodity(std::istream& in, std::string& symbol)
}
bool parse_annotations(std::istream& in, amount_t& price,
ptime& date, std::string& tag)
moment_t& date, std::string& tag)
{
bool has_date = false;
@ -1162,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.is_not_a_date_time())
if (is_valid_moment(date))
throw new amount_error("Commodity specifies more than one date");
in.get(c);
@ -1212,7 +1212,7 @@ void amount_t::parse(std::istream& in, unsigned char flags)
std::string symbol;
std::string quant;
amount_t tprice;
ptime tdate;
moment_t tdate;
bool had_date = false;
std::string tag;
unsigned int comm_flags = COMMODITY_STYLE_DEFAULTS;
@ -1552,7 +1552,7 @@ bool amount_t::valid() const
}
void amount_t::annotate_commodity(const amount_t& tprice,
const ptime& tdate,
const moment_t& tdate,
const std::string& tag)
{
const commodity_t * this_base;
@ -1575,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.is_not_a_date_time() && this_ann ? this_ann->date : tdate,
! is_valid_moment(tdate) && this_ann ? this_ann->date : tdate,
tag.empty() && this_ann ? this_ann->tag : tag);
if (ann_comm)
set_commodity(*ann_comm);
@ -1604,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.is_not_a_date_time()) ||
(_keep_date && is_valid_moment(ann_comm.date)) ||
(_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 : ptime(),
_keep_date ? ann_comm.date : moment_t(),
_keep_tag ? ann_comm.tag : "");
} else {
new_comm = commodity_t::find_or_create(ann_comm.base_symbol());
@ -1635,7 +1635,7 @@ amount_t amount_t::price() const
return *this;
}
ptime amount_t::date() const
moment_t amount_t::date() const
{
if (commodity_ && commodity_->annotated) {
DEBUG_PRINT("amounts.commodities",
@ -1643,12 +1643,12 @@ ptime amount_t::date() const
<< ((annotated_commodity_t *)commodity_)->date);
return ((annotated_commodity_t *)commodity_)->date;
}
return ptime();
return moment_t();
}
void commodity_base_t::add_price(const ptime& date,
const amount_t& price)
void commodity_base_t::add_price(const moment_t& date,
const amount_t& price)
{
if (! history)
history = new history_t;
@ -1663,7 +1663,7 @@ void commodity_base_t::add_price(const ptime& date,
}
}
bool commodity_base_t::remove_price(const ptime& date)
bool commodity_base_t::remove_price(const moment_t& date)
{
if (history) {
history_map::size_type n = history->prices.erase(date);
@ -1773,15 +1773,15 @@ commodity_t * commodity_t::find(const std::string& symbol)
return NULL;
}
amount_t commodity_base_t::value(const ptime& moment)
amount_t commodity_base_t::value(const moment_t& moment)
{
ptime age;
moment_t age;
amount_t price;
if (history) {
assert(history->prices.size() > 0);
if (moment.is_not_a_date_time()) {
if (! is_valid_moment(moment)) {
history_map::reverse_iterator r = history->prices.rbegin();
age = (*r).first;
price = (*r).second;
@ -1799,7 +1799,7 @@ amount_t commodity_base_t::value(const ptime& moment)
age = (*i).first;
price = (*i).second;
} else {
age = ptime();
age = moment_t();
}
} else {
price = (*i).second;
@ -1811,7 +1811,7 @@ amount_t commodity_base_t::value(const ptime& moment)
if (updater && ! (flags & COMMODITY_STYLE_NOMARKET))
(*updater)(*this, moment, age,
(history && history->prices.size() > 0 ?
(*history->prices.rbegin()).first : ptime()), price);
(*history->prices.rbegin()).first : moment_t()), price);
return price;
}
@ -1827,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.is_not_a_date_time() &&
if (is_valid_moment(date) &&
(! comm.annotated ||
date != static_cast<const annotated_commodity_t&>(comm).date))
return false;
@ -1843,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 ptime& date,
const moment_t& date,
const std::string& tag)
{
if (price)
out << " {" << price << '}';
if (! date.is_not_a_date_time())
if (is_valid_moment(date))
out << " [" << date << ']';
if (! tag.empty())
@ -1859,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 ptime& date,
const moment_t& date,
const std::string& tag,
const std::string& mapping_key)
{
@ -1900,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 ptime& date,
const moment_t& date,
const std::string& tag)
{
if (price < 0)
@ -1926,7 +1926,7 @@ namespace {
commodity_t *
annotated_commodity_t::find_or_create(const commodity_t& comm,
const amount_t& price,
const ptime& date,
const moment_t& date,
const std::string& tag)
{
std::string name = make_qualified_name(comm, price, date, tag);
@ -1989,16 +1989,16 @@ bool compare_amount_commodities::operator()(const amount_t * left,
}
}
if (aleftcomm.date.is_not_a_date_time() &&
! arightcomm.date.is_not_a_date_time())
if (! is_valid_moment(aleftcomm.date) &&
is_valid_moment(arightcomm.date))
return true;
if (! aleftcomm.date.is_not_a_date_time() &&
arightcomm.date.is_not_a_date_time())
if (is_valid_moment(aleftcomm.date) &&
! is_valid_moment(arightcomm.date))
return false;
if (! aleftcomm.date.is_not_a_date_time() &&
! arightcomm.date.is_not_a_date_time()) {
time_duration diff = aleftcomm.date - arightcomm.date;
if (is_valid_moment(aleftcomm.date) &&
is_valid_moment(arightcomm.date)) {
duration_t diff = aleftcomm.date - arightcomm.date;
return diff.is_negative();
}

View file

@ -145,7 +145,7 @@ class amount_t
commodity_ = &comm;
}
void annotate_commodity(const amount_t& price,
const ptime& date = ptime(),
const moment_t& date = moment_t(),
const std::string& tag = "");
amount_t strip_annotations(const bool _keep_price = keep_price,
const bool _keep_date = keep_date,
@ -154,7 +154,7 @@ class amount_t
commodity_ = NULL;
}
amount_t price() const;
ptime date() const;
moment_t date() const;
bool null() const {
return ! quantity && ! has_commodity();
@ -324,7 +324,7 @@ class amount_t
return ! (*this == num);
}
amount_t value(const ptime& moment) const;
amount_t value(const moment_t& moment) const;
amount_t abs() const {
if (*this < 0)
@ -351,7 +351,7 @@ class amount_t
char * item_pool_end);
friend bool parse_annotations(std::istream& in, amount_t& price,
ptime& date, std::string& tag);
moment_t& date, std::string& tag);
// Streaming interface
@ -470,8 +470,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 ptime, amount_t> history_map;
typedef std::pair<const ptime, amount_t> history_pair;
typedef std::map<const moment_t, amount_t> history_map;
typedef std::pair<const moment_t, amount_t> history_pair;
class commodity_base_t;
@ -518,23 +518,21 @@ class commodity_base_t
struct history_t {
history_map prices;
ptime last_lookup;
// jww (2007-04-18): What is bogus_time?
ptime bogus_time;
history_t() : last_lookup(), bogus_time() {}
history_t() : last_lookup() {}
};
history_t * history;
void add_price(const ptime& date, const amount_t& price);
bool remove_price(const ptime& date);
amount_t value(const ptime& moment = now);
void add_price(const moment_t& date, const amount_t& price);
bool remove_price(const moment_t& date);
amount_t value(const moment_t& moment = now);
class updater_t {
public:
virtual ~updater_t() {}
virtual void operator()(commodity_base_t& commodity,
const ptime& moment,
const ptime& date,
const ptime& last,
const moment_t& moment,
const moment_t& date,
const moment_t& last,
amount_t& price) = 0;
};
friend class updater_t;
@ -665,13 +663,13 @@ class commodity_t
return base->history;
}
void add_price(const ptime& date, const amount_t& price) {
void add_price(const moment_t& date, const amount_t& price) {
return base->add_price(date, price);
}
bool remove_price(const ptime& date) {
bool remove_price(const moment_t& date) {
return base->remove_price(date);
}
amount_t value(const ptime& moment = now) const {
amount_t value(const moment_t& moment = now) const {
return base->value(moment);
}
@ -684,7 +682,7 @@ class annotated_commodity_t : public commodity_t
const commodity_t * ptr;
amount_t price;
ptime date;
moment_t date;
std::string tag;
explicit annotated_commodity_t() {
@ -700,19 +698,19 @@ class annotated_commodity_t : public commodity_t
static void write_annotations(std::ostream& out,
const amount_t& price,
const ptime& date,
const moment_t& date,
const std::string& tag);
private:
static commodity_t * create(const commodity_t& comm,
const amount_t& price,
const ptime& date,
const moment_t& 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 ptime& date,
const moment_t& 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 ptime& moment) const
balance_t balance_t::value(const moment_t& moment) const
{
balance_t temp;
@ -57,18 +57,18 @@ balance_t balance_t::price() const
return temp;
}
ptime balance_t::date() const
moment_t balance_t::date() const
{
ptime temp;
moment_t temp;
for (amounts_map::const_iterator i = amounts.begin();
i != amounts.end();
i++) {
ptime tdate = (*i).second.date();
if (temp.is_not_a_date_time() && ! tdate.is_not_a_date_time())
moment_t tdate = (*i).second.date();
if (! is_valid_moment(temp) && is_valid_moment(tdate))
temp = tdate;
else if (temp != tdate)
return ptime();
return moment_t();
}
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 ptime& moment = now) const;
balance_t value(const moment_t& moment = now) const;
balance_t price() const;
ptime date() const;
moment_t date() const;
balance_t
strip_annotations(const bool keep_price = amount_t::keep_price,
@ -889,13 +889,13 @@ class balance_pair_t
*commodity_t::null_commodity) const {
return quantity.amount(commodity);
}
balance_t value(const ptime& moment = now) const {
balance_t value(const moment_t& moment = now) const {
return quantity.value(moment);
}
balance_t price() const {
return quantity.price();
}
ptime date() const {
moment_t 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, *((ptime *) val.data));
read_binary_number(data, *((moment_t *) 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++) {
ptime when;
moment_t 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, *((ptime *) val.data));
write_binary_number(out, *((moment_t *) val.data));
break;
case value_t::AMOUNT:
write_binary_amount(out, *((amount_t *) val.data));

View file

@ -25,54 +25,70 @@ std::map<void *, int> ptrs;
void * operator new(std::size_t size) throw (std::bad_alloc) {
void * ptr = std::malloc(size);
#if 0 // jww (2007-04-19): these don't work with boost::regex
if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new(std::size_t size) throw (std::bad_alloc)\n");
}
#endif
return ptr;
}
void * operator new[](std::size_t size) throw (std::bad_alloc) {
void * ptr = std::malloc(size);
#if 0
if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new[](std::size_t) throw (std::bad_alloc)\n");
}
#endif
return ptr;
}
void * operator new(std::size_t size, const std::nothrow_t&) throw() {
void * ptr = std::malloc(size);
#if 0
if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new(std::size_t size, const std::nothrow_t&) throw()\n");
}
#endif
return ptr;
}
void * operator new[](std::size_t size, const std::nothrow_t&) throw() {
void * ptr = std::malloc(size);
#if 0
if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new[](std::size_t size, const std::nothrow_t&) throw()\n");
}
#endif
return ptr;
}
void operator delete(void * ptr) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete(void * ptr) throw()\n");
}
#endif
std::free(ptr);
}
void operator delete[](void * ptr) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete[](void * ptr) throw()\n");
}
#endif
std::free(ptr);
}
void operator delete(void * ptr, const std::nothrow_t&) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete(void * ptr, const std::nothrow_t&) throw()\n");
}
#endif
std::free(ptr);
}
void operator delete[](void * ptr, const std::nothrow_t&) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete[](void * ptr, const std::nothrow_t&) throw()\n");
}
#endif
std::free(ptr);
}
@ -81,8 +97,7 @@ bool _free_debug_stream = false;
bool _debug_active(const char * const cls) {
if (char * debug = std::getenv("DEBUG_CLASS")) {
static boost::regex class_regexp(debug);
return boost::regex_match(cls, class_regexp);
return boost::regex_match(cls, boost::regex(debug));
}
return false;
}

View file

@ -22,16 +22,16 @@ transaction_t::~transaction_t()
if (cost) delete cost;
}
ptime transaction_t::actual_date() const
moment_t transaction_t::actual_date() const
{
if (_date.is_not_a_date_time() && entry)
if (! is_valid_moment(_date) && entry)
return entry->actual_date();
return _date;
}
ptime transaction_t::effective_date() const
moment_t transaction_t::effective_date() const
{
if (_date_eff.is_not_a_date_time() && entry)
if (! is_valid_moment(_date_eff) && entry)
return entry->effective_date();
return _date_eff;
}
@ -181,7 +181,7 @@ bool entry_base_t::finalize()
! (*x)->amount.commodity().annotated)
(*x)->amount.annotate_commodity
(per_unit_cost.abs(),
entry ? entry->actual_date() : ptime(),
entry ? entry->actual_date() : moment_t(),
entry ? entry->code : "");
(*x)->cost = new amount_t(- (per_unit_cost * (*x)->amount.number()));
@ -310,7 +310,7 @@ void entry_t::add_transaction(transaction_t * xact)
bool entry_t::valid() const
{
if (_date.is_not_a_date_time() || ! journal) {
if (! is_valid_moment(_date) || ! journal) {
DEBUG_PRINT("ledger.validate", "entry_t: ! _date || ! journal");
return false;
}

View file

@ -23,8 +23,8 @@ class transaction_t
enum state_t { UNCLEARED, CLEARED, PENDING };
entry_t * entry;
ptime _date;
ptime _date_eff;
moment_t _date;
moment_t _date_eff;
account_t * account;
amount_t amount;
std::string amount_expr;
@ -67,9 +67,9 @@ class transaction_t
}
~transaction_t();
ptime actual_date() const;
ptime effective_date() const;
ptime date() const {
moment_t actual_date() const;
moment_t effective_date() const;
moment_t 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:
ptime _date;
ptime _date_eff;
moment_t _date;
moment_t _date_eff;
std::string code;
std::string payee;
@ -167,15 +167,15 @@ class entry_t : public entry_base_t
TRACE_DTOR("entry_t");
}
ptime actual_date() const {
moment_t actual_date() const {
return _date;
}
ptime effective_date() const {
if (_date_eff.is_not_a_date_time())
moment_t effective_date() const {
if (! is_valid_moment(_date_eff))
return _date;
return _date_eff;
}
ptime date() const {
moment_t date() const {
if (transaction_t::use_effective_date)
return effective_date();
else

View file

@ -186,7 +186,9 @@ static int read_and_report(report_t * report, int argc, char * argv[],
session.read_init();
std::cout << "Reading journal ..." << std::endl;
journal_t * journal = session.read_data(report->account);
std::cout << "Generating report ..." << std::endl;
// Configure the output stream

View file

@ -94,7 +94,7 @@
static struct std::tm * timeval;
namespace {
boost::posix_time::ptime moment;
boost::posix_time::moment_t moment;
yyFlexLexer * lexer;
@ -1444,7 +1444,7 @@ yyreduce:
#line 98 "parsetime.yy"
{
if (timeval->tm_gmtoff != -1) {
boost::posix_time::ptime::time_duration_type offset;
boost::posix_time::moment_t::time_duration_type offset;
offset = boost::posix_time::seconds(timeval->tm_gmtoff);
moment = boost::posix_time::from_time_t(timegm(timeval)) - offset;
} else {
@ -1871,7 +1871,7 @@ int yywrap()
return 1;
}
boost::posix_time::ptime parse_abs_datetime(std::istream& input)
boost::posix_time::moment_t parse_abs_datetime(std::istream& input)
{
lexer = new yyFlexLexer(&input);

View file

@ -7,7 +7,7 @@
static struct std::tm * timeval;
namespace {
boost::posix_time::ptime moment;
ledger::moment_t moment;
struct time_to_leave : std::exception {};
@ -21,7 +21,7 @@ namespace {
return lexer->yylex();
}
int month_to_int(char * name)
int month_to_int(const std::string& name)
{
switch (std::toupper(name[0])) {
case 'J':
@ -84,12 +84,14 @@ namespace {
const ledger::intorchar& min = ledger::intorchar(),
const ledger::intorchar& sec = ledger::intorchar())
{
if (ampm.sval && std::tolower(ampm.sval[0]) == 'a' && hour.ival == 12)
if (! ampm.sval.empty() &&
std::tolower(ampm.sval[0]) == 'a' && hour.ival == 12)
timeval->tm_hour = 0;
else if (ampm.sval && std::tolower(ampm.sval[0]) == 'p' && hour.ival == 12)
else if (! ampm.sval.empty() &&
std::tolower(ampm.sval[0]) == 'p' && hour.ival == 12)
timeval->tm_hour = 12;
else if (hour.ival < 0 || (! ampm.sval && hour.ival > 23) ||
(ampm.sval && hour.ival > 12))
else if (hour.ival < 0 || (ampm.sval.empty() && hour.ival > 23) ||
(! ampm.sval.empty() && hour.ival > 12))
throw ledger::datetime_error("Hour out of range");
else
timeval->tm_hour += hour.ival;
@ -230,7 +232,7 @@ int yywrap()
return 1;
}
boost::posix_time::ptime parse_abs_datetime(std::istream& input)
ledger::moment_t parse_abs_datetime(std::istream& input)
{
lexer = new yyFlexLexer(&input);
@ -244,18 +246,24 @@ boost::posix_time::ptime parse_abs_datetime(std::istream& input)
// jww (2007-04-19): Catch any boost errors thrown from here and
// push them onto the new error stack scheme.
try {
if (yyparse() == 0)
if (yyparse() == 0) {
delete lexer;
return moment;
}
}
catch (const time_to_leave&) {
delete lexer;
return moment;
}
catch (ledger::datetime_error *) {
delete lexer;
throw;
}
catch (...) {
delete lexer;
throw new ledger::datetime_error("Failed to parse date/time");
}
delete lexer;
throw new ledger::datetime_error("Failed to parse date/time");
}

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 ptime& moment,
const ptime& date,
const ptime& last,
const moment_t& moment,
const moment_t& date,
const moment_t& last,
amount_t& price) {
call_method<void>(self, "__call__", commodity, moment, date, last, price);
}

View file

@ -9,9 +9,9 @@
namespace ledger {
void quotes_by_script::operator()(commodity_base_t& commodity,
const ptime& moment,
const ptime& date,
const ptime& last,
const ptime& moment,
const ptime& date,
const ptime& last,
amount_t& price)
{
DEBUG_CLASS("ledger.quotes.download");
@ -21,13 +21,14 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
DEBUG_PRINT_TIME_(moment);
DEBUG_PRINT_TIME_(date);
DEBUG_PRINT_TIME_(last);
if (commodity.history)
DEBUG_PRINT_TIME_(commodity.history->last_lookup);
DEBUG_PRINT_("pricing_leeway is " << pricing_leeway);
if ((commodity.history &&
(now - commodity.history->last_lookup) < pricing_leeway) ||
(now - last) < pricing_leeway ||
(time_now - commodity.history->last_lookup) < pricing_leeway) ||
(time_now - last) < pricing_leeway ||
(price && moment > date && (moment - date) <= pricing_leeway))
return;
@ -59,7 +60,7 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
price.parse(buf);
commodity.add_price(now, price);
commodity.history->last_lookup = now;
commodity.history->last_lookup = time_now;
cache_dirty = true;
if (price && ! price_db.empty()) {

View file

@ -19,9 +19,9 @@ class quotes_by_script : public commodity_base_t::updater_t
cache_dirty(_cache_dirty) {}
virtual void operator()(commodity_base_t& commodity,
const ptime& moment,
const ptime& date,
const ptime& last,
const ptime& moment,
const ptime& date,
const ptime& last,
amount_t& price);
};

View file

@ -24,7 +24,15 @@ void register_command::print_document(std::ostream& out,
transaction_t * xact = xact_node->transaction;
assert(xact);
std::cout << xact->account->fullname() << std::endl;
std::cout << xact->entry->date() << ' '
<< std::setw(21) << std::left
<< abbreviate(xact->entry->payee, 21) << ' '
<< std::setw(21) << std::left
<< abbreviate(xact->account->fullname(), 21,
ABBREVIATE, true) << ' '
<< std::setw(12) << std::right
<< xact->amount
<< std::endl;
}
}

View file

@ -44,7 +44,7 @@ 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])");
ptime date = locals->args[0].to_datetime();
moment_t date = locals->args[0].to_datetime();
std::string date_format;
if (locals->args.size() == 2)
@ -52,7 +52,7 @@ void report_t::ftime(value_t& result, xml::xpath_t::scope_t * locals)
#if 0
// jww (2007-04-18): Need to setup an output facet here
else
date_format = ptime::output_format;
date_format = moment_t::output_format;
result.set_string(date.to_string(date_format));
#endif

View file

@ -138,7 +138,7 @@ bool session_t::resolve(const std::string& name, value_t& result,
if (name == "date_format") {
// jww (2007-04-18): What to do here?
#if 0
result.set_string(ptime::output_format);
result.set_string(moment_t::output_format);
#endif
return true;
}

View file

@ -37,7 +37,7 @@ class session_t : public xml::xpath_t::scope_t
bool verbose_mode;
bool trace_mode;
ptime now;
moment_t now;
elision_style_t elision_style;

View file

@ -30,7 +30,7 @@ static std::list<std::pair<std::string, int> > include_stack;
#ifdef TIMELOG_SUPPORT
struct time_entry_t {
ptime checkin;
moment_t checkin;
account_t * account;
std::string desc;
};
@ -494,7 +494,7 @@ bool textual_parser_t::test(std::istream& in) const
return true;
}
static void clock_out_from_timelog(const ptime& when,
static void clock_out_from_timelog(const moment_t& when,
account_t * account,
const char * desc,
journal_t * journal)
@ -678,7 +678,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
std::string date_field = date_field_ptr;
char * symbol_and_price;
ptime datetime;
moment_t datetime;
if (std::isdigit(time_field_ptr[0])) {
symbol_and_price = next_element(time_field_ptr);

View file

@ -6,12 +6,19 @@
namespace ledger {
ptime now = boost::posix_time::second_clock::universal_time();
ptime time_now = boost::posix_time::second_clock::universal_time();
date date_now = boost::gregorian::day_clock::universal_day();
#ifdef SUPPORT_DATE_AND_TIME
moment_t& now(time_now);
#else
moment_t& now(date_now);
#endif
bool day_before_month = false;
static bool day_before_month_initialized = false;
ptime parse_datetime(std::istream& in)
moment_t parse_datetime(std::istream& in)
{
if (! day_before_month_initialized) {
#ifdef HAVE_NL_LANGINFO
@ -21,86 +28,32 @@ ptime parse_datetime(std::istream& in)
day_before_month_initialized = true;
#endif
}
#if 1
#if 0
return parse_abs_datetime(in);
#else
std::string word;
if (! in.good() || in.eof())
return ptime();
return moment_t();
in >> word;
// Grammar
//
// datetime: absdate [time]
// | reldate
// | datetime preposition
//
// reldate: NOW | TODAY | YESTERDAY | TOMORROW
// | skip_or_quantity specifier
//
// skip_or_quantity: skip | quantity
//
// skip: LAST | NEXT
//
// quantity: INTEGER | CARDINAL
//
// specifier: DAY | WEEK | MONTH | QUARTER | YEAR | DECADE
//
// preposition: AGO | BACK
// | BEFORE reldate
// | SINCE/FROM reldate
// | UNTIL reldate
// | AFTER reldate
int year = ((word[0] - '0') * 1000 +
(word[1] - '0') * 100 +
(word[2] - '0') * 10 +
(word[3] - '0'));
if (std::isdigit(word[0])) {
// This could be any of a variety of formats:
//
// 20070702 [TIME]
// 22072007T171940
// 22072007T171940-0700
// 2007-07-02 [TIME]
// 2007/07/02 [TIME]
// 2007.07.02 [TIME]
// 2007-Jul-22 [TIME]
// 07-22-2007 [TIME]
// 07-22-07 [TIME]
// 07/22/2007 [TIME]
// 07/22/2007 [TIME]
// 07.22.2007 [TIME]
// 07.22.07 [TIME]
// 22-07-2007 [TIME]
// 22-07-07 [TIME]
// 22/07/2007 [TIME]
// 22/07/07 [TIME]
// 22.07.2007 [TIME]
// 22.07.07 [TIME]
// 22 Jul 2007 [TIME]
// 22 July 2007 [TIME]
//
// (NUMBER) (SPECIFIER)
int mon = ((word[5] - '0') * 10 +
(word[6] - '0'));
} else {
// If there is no starting digit, then it could be any of these:
//
// now
// today
// yesterday
// tomorrow
// (last|next) (week|month|quarter|year|decade)
// (one|two|three|four|five|six|seven|eight|nine|ten) SPECIFIER
// PREPOSITION DATE
//
// PREPOSITION = (from|after|before|since|until)
// SPECIFIER = (weeks?|months?|quarters?|years?|decades?) (ago|back)
//
//
}
int day = ((word[8] - '0') * 10 +
(word[9] - '0'));
return moment_t(boost::gregorian::date(year, mon, day));
#endif
}
ptime datetime_range_from_stream(std::istream& in)
moment_t datetime_range_from_stream(std::istream& in)
{
}

96
times.h
View file

@ -14,9 +14,34 @@
namespace ledger {
typedef boost::posix_time::ptime ptime;
typedef boost::posix_time::seconds seconds;
typedef ptime::time_duration_type time_duration;
typedef boost::posix_time::ptime ptime;
typedef ptime::time_duration_type time_duration;
typedef boost::gregorian::date date;
typedef boost::gregorian::date_duration date_duration;
typedef boost::posix_time::seconds seconds;
#define SUPPORT_DATE_AND_TIME 1
#ifdef SUPPORT_DATE_AND_TIME
typedef boost::posix_time::ptime moment_t;
typedef moment_t::time_duration_type duration_t;
inline bool is_valid_moment(const moment_t& moment) {
return ! moment.is_not_a_date_time();
}
#else // SUPPORT_DATE_AND_TIME
typedef boost::gregorian::date moment_t;
typedef boost::gregorian::date_duration duration_t;
inline bool is_valid_moment(const moment_t& moment) {
return ! moment.is_not_a_date();
}
#endif // SUPPORT_DATE_AND_TIME
extern moment_t& now;
class datetime_error : public error {
public:
@ -34,85 +59,54 @@ public:
return false;
}
void start(const ptime& moment) {}
ptime next() const {}
void start(const moment_t& moment) {}
moment_t next() const {}
void parse(std::istream& in) {}
};
#if 0
inline ptime ptime_local_to_utc(const ptime& when) {
inline moment_t ptime_local_to_utc(const moment_t& when) {
struct std::tm tm_gmt = to_tm(when);
return boost::posix_time::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),
inline moment_t ptime_from_local_date_string(const std::string& date_string) {
return ptime_local_to_utc(moment_t(boost::gregorian::from_string(date_string),
time_duration()));
}
inline ptime ptime_from_local_time_string(const std::string& time_string) {
inline moment_t ptime_from_local_time_string(const std::string& time_string) {
return ptime_local_to_utc(boost::posix_time::time_from_string(time_string));
}
#endif
ptime parse_datetime(std::istream& in);
moment_t parse_datetime(std::istream& in);
inline ptime parse_datetime(const std::string& str) {
inline moment_t parse_datetime(const std::string& str) {
std::istringstream instr(str);
return parse_datetime(instr);
}
extern ptime now;
extern ptime time_now;
extern date date_now;
extern bool day_before_month;
struct intorchar
{
int ival;
char * sval;
int ival;
std::string sval;
intorchar() : ival(-1), sval(NULL) {}
intorchar(int val) : ival(val), sval(NULL) {}
intorchar(char * val) : ival(-1), sval(NULL) {
set_sval(val);
}
intorchar(const intorchar& o) : ival(o.ival), sval(NULL) {
set_sval(o.sval);
}
~intorchar() {
clear_sval();
}
intorchar& operator=(const intorchar& o) {
if (&o == this)
return *this;
ival = o.ival;
set_sval(o.sval);
}
private:
void clear_sval() {
if (sval) {
delete[] sval;
sval = NULL;
}
}
void set_sval(char * val) {
clear_sval();
if (val) {
sval = new char[std::strlen(val) + 1];
std::strcpy(sval, val);
}
}
intorchar() : ival(-1) {}
intorchar(int val) : ival(val) {}
intorchar(const std::string& val) : ival(-1), sval(val) {}
intorchar(const intorchar& o) : ival(o.ival), sval(o.sval) {}
};
}
boost::posix_time::ptime parse_abs_datetime(std::istream& input);
ledger::moment_t parse_abs_datetime(std::istream& input);
#endif /* _TIMES_H */

View file

@ -27,14 +27,14 @@ long value_t::to_integer() const
}
}
ptime value_t::to_datetime() const
moment_t value_t::to_datetime() const
{
if (type == DATETIME) {
return *(ptime *) data;
return *(moment_t *) data;
} else {
value_t temp(*this);
temp.in_place_cast(DATETIME);
return *(ptime *) temp.data;
return *(moment_t *) temp.data;
}
}
@ -171,7 +171,7 @@ value_t& value_t::operator=(const value_t& val)
return *this;
}
else if (type == DATETIME && val.type == DATETIME) {
*((ptime *) data) = *((ptime *) val.data);
*((moment_t *) data) = *((moment_t *) 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:
*((ptime *) data) = *((ptime *) val.data);
*((moment_t *) data) = *((moment_t *) 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:
*((ptime *) data) += seconds(*((long *) val.data));
*((moment_t *) data) += date_duration(*((long *) val.data));
break;
case AMOUNT:
*((ptime *) data) += seconds(long(*((amount_t *) val.data)));
*((moment_t *) data) += date_duration(long(*((amount_t *) val.data)));
break;
case BALANCE:
*((ptime *) data) += seconds(long(*((balance_t *) val.data)));
*((moment_t *) data) += date_duration(long(*((balance_t *) val.data)));
break;
case BALANCE_PAIR:
*((ptime *) data) += seconds(long(*((balance_pair_t *) val.data)));
*((moment_t *) data) += date_duration(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:
*((ptime *) data) -= seconds(*((long *) val.data));
*((moment_t *) data) -= date_duration(*((long *) val.data));
break;
case DATETIME: {
time_duration tval = ((ptime *) data)->operator-(*((ptime *) val.data));
duration_t tval = ((moment_t *) data)->operator-(*((moment_t *) val.data));
in_place_cast(INTEGER);
*((long *) data) = tval.total_seconds();
*((long *) data) = tval.total_seconds() / 86400L;
break;
}
case AMOUNT:
*((ptime *) data) -= seconds(long(*((amount_t *) val.data)));
*((moment_t *) data) -= date_duration(long(*((amount_t *) val.data)));
break;
case BALANCE:
*((ptime *) data) -= seconds(long(*((balance_t *) val.data)));
*((moment_t *) data) -= date_duration(long(*((balance_t *) val.data)));
break;
case BALANCE_PAIR:
*((ptime *) data) -= seconds(long(*((balance_pair_t *) val.data)));
*((moment_t *) data) -= date_duration(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 ! ((ptime *) data)->is_not_a_date_time();
return is_valid_moment(*((moment_t *) data));
case AMOUNT:
return *(amount_t *) data;
case BALANCE:
@ -936,7 +936,7 @@ value_t::operator long() const
}
template <>
value_t::operator ptime() const
value_t::operator moment_t() const
{
switch (type) {
case BOOLEAN:
@ -944,7 +944,7 @@ value_t::operator ptime() const
case INTEGER:
throw new value_error("Cannot convert an integer to a date/time");
case DATETIME:
return *((ptime *) data);
return *((moment_t *) data);
case AMOUNT:
throw new value_error("Cannot convert an amount to a date/time");
case BALANCE:
@ -965,7 +965,7 @@ value_t::operator ptime() const
break;
}
assert(0);
return ptime();
return moment_t();
}
template <>
@ -1124,7 +1124,7 @@ bool value_t::operator OP(const value_t& val) \
throw new value_error("Cannot compare a date/time to an integer"); \
\
case DATETIME: \
return *((ptime *) data) OP *((ptime *) val.data); \
return *((moment_t *) data) OP *((moment_t *) val.data); \
\
case AMOUNT: \
throw new value_error("Cannot compare a date/time to an amount"); \
@ -1452,7 +1452,7 @@ void value_t::in_place_cast(type_t cast_type)
case DATETIME:
switch (cast_type) {
case BOOLEAN:
*((bool *) data) = ! ((ptime *) data)->is_not_a_date_time();
*((bool *) data) = is_valid_moment(*((moment_t *) data));
break;
case INTEGER:
throw new value_error("Cannot convert a date/time to an integer");
@ -1859,7 +1859,7 @@ void value_t::in_place_abs()
}
}
value_t value_t::value(const ptime& moment) const
value_t value_t::value(const moment_t& moment) const
{
switch (type) {
case BOOLEAN:
@ -2209,7 +2209,7 @@ std::ostream& operator<<(std::ostream& out, const value_t& val)
out << *(long *) val.data;
break;
case value_t::DATETIME:
out << *(ptime *) val.data;
out << *(moment_t *) val.data;
break;
case value_t::AMOUNT:
out << *(amount_t *) val.data;
@ -2284,7 +2284,7 @@ void value_context::describe(std::ostream& out) const throw()
out << *((long *) bal->data);
break;
case value_t::DATETIME:
out << *((ptime *) bal->data);
out << *((moment_t *) bal->data);
break;
case value_t::AMOUNT:
out << *((amount_t *) bal->data);
@ -2415,7 +2415,7 @@ void export_value()
.def(init<std::string>())
.def(init<double>())
.def(init<long>())
.def(init<ptime>())
.def(initmoment_t())
.def(self + self)
.def(self + other<std::string>())
@ -2517,7 +2517,7 @@ void export_value()
.def(self < other<balance_t>())
.def(self < other<amount_t>())
.def(self < long())
.def(self < other<ptime>())
.def(self < othermoment_t())
.def(self < double())
.def(other<std::string>() < self)
@ -2525,7 +2525,7 @@ void export_value()
.def(other<balance_t>() < self)
.def(other<amount_t>() < self)
.def(long() < self)
.def(other<ptime>() < self)
.def(othermoment_t() < self)
.def(double() < self)
.def(self <= self)
@ -2534,7 +2534,7 @@ void export_value()
.def(self <= other<balance_t>())
.def(self <= other<amount_t>())
.def(self <= long())
.def(self <= other<ptime>())
.def(self <= othermoment_t())
.def(self <= double())
.def(other<std::string>() <= self)
@ -2542,7 +2542,7 @@ void export_value()
.def(other<balance_t>() <= self)
.def(other<amount_t>() <= self)
.def(long() <= self)
.def(other<ptime>() <= self)
.def(othermoment_t() <= self)
.def(double() <= self)
.def(self > self)
@ -2551,7 +2551,7 @@ void export_value()
.def(self > other<balance_t>())
.def(self > other<amount_t>())
.def(self > long())
.def(self > other<ptime>())
.def(self > othermoment_t())
.def(self > double())
.def(other<std::string>() > self)
@ -2559,7 +2559,7 @@ void export_value()
.def(other<balance_t>() > self)
.def(other<amount_t>() > self)
.def(long() > self)
.def(other<ptime>() > self)
.def(othermoment_t() > self)
.def(double() > self)
.def(self >= self)
@ -2568,7 +2568,7 @@ void export_value()
.def(self >= other<balance_t>())
.def(self >= other<amount_t>())
.def(self >= long())
.def(self >= other<ptime>())
.def(self >= othermoment_t())
.def(self >= double())
.def(other<std::string>() >= self)
@ -2576,7 +2576,7 @@ void export_value()
.def(other<balance_t>() >= self)
.def(other<amount_t>() >= self)
.def(long() >= self)
.def(other<ptime>() >= self)
.def(othermoment_t() >= self)
.def(double() >= self)
.def(self == self)
@ -2585,7 +2585,7 @@ void export_value()
.def(self == other<balance_t>())
.def(self == other<amount_t>())
.def(self == long())
.def(self == other<ptime>())
.def(self == othermoment_t())
.def(self == double())
.def(other<std::string>() == self)
@ -2593,7 +2593,7 @@ void export_value()
.def(other<balance_t>() == self)
.def(other<amount_t>() == self)
.def(long() == self)
.def(other<ptime>() == self)
.def(othermoment_t() == self)
.def(double() == self)
.def(self != self)
@ -2602,7 +2602,7 @@ void export_value()
.def(self != other<balance_t>())
.def(self != other<amount_t>())
.def(self != long())
.def(self != other<ptime>())
.def(self != othermoment_t())
.def(self != double())
.def(other<std::string>() != self)
@ -2610,7 +2610,7 @@ void export_value()
.def(other<balance_t>() != self)
.def(other<amount_t>() != self)
.def(long() != self)
.def(other<ptime>() != self)
.def(othermoment_t() != self)
.def(double() != self)
.def(! self)

22
value.h
View file

@ -63,9 +63,9 @@ class value_t
*((long *) data) = val;
type = INTEGER;
}
value_t(const ptime val) {
TRACE_CTOR("value_t(const ptime)");
*((ptime *) data) = val;
value_t(const moment_t val) {
TRACE_CTOR("value_t(const moment_t)");
*((moment_t *) data) = val;
type = DATETIME;
}
value_t(const unsigned long val) {
@ -144,10 +144,10 @@ class value_t
}
return *this;
}
value_t& operator=(const ptime val) {
if ((ptime *) data != &val) {
value_t& operator=(const moment_t val) {
if ((moment_t *) data != &val) {
destroy();
*((ptime *) data) = val;
*((moment_t *) data) = val;
type = DATETIME;
}
return *this;
@ -276,7 +276,7 @@ class value_t
bool to_boolean() const;
long to_integer() const;
ptime to_datetime() const;
moment_t 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 ((ptime *) data)->is_not_a_date_time();
return ! is_valid_moment(*((moment_t *) data));
case AMOUNT:
return ((amount_t *) data)->realzero();
case BALANCE:
@ -457,7 +457,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 ptime& moment) const;
value_t value(const moment_t& moment) const;
void in_place_reduce();
value_t reduce() const {
@ -534,7 +534,7 @@ value_t::operator T() const
case INTEGER:
return *(long *) data;
case DATETIME:
return *(ptime *) data;
return *(moment_t *) data;
case AMOUNT:
return *(amount_t *) data;
case BALANCE:
@ -558,7 +558,7 @@ value_t::operator T() const
template <> value_t::operator bool() const;
template <> value_t::operator long() const;
template <> value_t::operator ptime() const;
template <> value_t::operator moment_t() const;
template <> value_t::operator double() const;
template <> value_t::operator std::string() const;