diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/amount.cc | 63 | ||||
-rw-r--r-- | src/amount.h | 41 | ||||
-rw-r--r-- | src/balance.cc | 43 | ||||
-rw-r--r-- | src/balance.h | 14 | ||||
-rw-r--r-- | src/ledger.h | 3 | ||||
-rw-r--r-- | src/main.cc | 5 | ||||
-rw-r--r-- | src/system.hh | 2 | ||||
-rw-r--r-- | src/times.cc | 2 | ||||
-rw-r--r-- | src/times.h | 2 | ||||
-rw-r--r-- | src/utils.cc | 1 | ||||
-rw-r--r-- | src/utils.h | 51 | ||||
-rw-r--r-- | src/value.cc | 97 | ||||
-rw-r--r-- | src/value.h | 1 |
13 files changed, 226 insertions, 99 deletions
diff --git a/src/amount.cc b/src/amount.cc index dabca4e4..6020a0aa 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -59,11 +59,13 @@ bool amount_t::full_strings = false; class amount_t::bigint_t { public: - mpz_t val; - unsigned char prec; - unsigned char flags; - unsigned int ref; - unsigned int index; + typedef uint8_t precision_t; + + mpz_t val; + precision_t prec; + uint8_t flags; + uint_least16_t ref; + uint_fast32_t index; bigint_t() : prec(0), flags(0), ref(1), index(0) { TRACE_CTOR(bigint_t, ""); @@ -245,7 +247,7 @@ amount_t::amount_t(const unsigned long val) } namespace { - unsigned char convert_double(mpz_t dest, double val) + amount_t::bigint_t::precision_t convert_double(mpz_t dest, double val) { #ifndef HAVE_GDTOA // This code is far too imprecise to be worthwhile. @@ -285,7 +287,7 @@ namespace { mpz_set_str(dest, buf, 10); free(buf); - return (unsigned char)exp; + return amount_t::bigint_t::precision_t(exp); #else int decpt, sign; char * buf = dtoa(val, 0, 0, &decpt, &sign, NULL); @@ -830,7 +832,7 @@ void amount_t::print_quantity(std::ostream& out) const // outputting it. NOTE: `rquotient' is used here as a temp variable! commodity_t& comm(commodity()); - unsigned char precision; + bigint_t::precision_t precision; if (! comm || quantity->flags & BIGINT_KEEP_PREC) { mpz_ui_pow_ui(divisor, 10, quantity->prec); @@ -932,7 +934,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, // outputting it. NOTE: `rquotient' is used here as a temp variable! commodity_t& comm(base.commodity()); - unsigned char precision = 0; + bigint_t::precision_t precision = 0; if (quantity) { if (! comm || full_precision || base.quantity->flags & BIGINT_KEEP_PREC) { @@ -1213,7 +1215,7 @@ bool parse_annotations(std::istream& in, amount_t& price, return has_date; } -void amount_t::parse(std::istream& in, unsigned char flags) +void amount_t::parse(std::istream& in, uint8_t flags) { // The possible syntax for an amount is: // @@ -1425,10 +1427,10 @@ void amount_t::write(std::ostream& out) const #ifndef THREADSAFE -static char * bigints; -static char * bigints_next; -static unsigned int bigints_index; -static unsigned int bigints_count; +static char * bigints; +static char * bigints_next; +static uint_fast32_t bigints_index; +static uint_fast32_t bigints_count; #endif void amount_t::read_quantity(char *& data) @@ -1452,14 +1454,14 @@ void amount_t::read_quantity(char *& data) if (negative) mpz_neg(MPZ(quantity), MPZ(quantity)); - quantity->prec = *((unsigned char *) data); - data += sizeof(unsigned char); - quantity->flags = *((unsigned char *) data); - data += sizeof(unsigned char); + quantity->prec = *((bigint_t::precision_t *) data); + data += sizeof(bigint_t::precision_t); + quantity->flags = *((uint8_t *) data); + data += sizeof(uint8_t); quantity->flags |= BIGINT_BULK_ALLOC; } else { - unsigned int index = *((unsigned int *) data); - data += sizeof(unsigned int); + uint_fast32_t index = *((uint_fast32_t *) data); + data += sizeof(uint_fast32_t); quantity = (bigint_t *) (bigints + (index - 1) * sizeof(bigint_t)); DEBUG("amounts.refs", @@ -1533,7 +1535,7 @@ void amount_t::write_quantity(std::ostream& out) const out.write(&byte, sizeof(byte)); out.write((char *)&quantity->prec, sizeof(quantity->prec)); - unsigned char flags = quantity->flags & ~BIGINT_BULK_ALLOC; + uint8_t flags = quantity->flags & ~BIGINT_BULK_ALLOC; assert(sizeof(flags) == sizeof(quantity->flags)); out.write((char *)&flags, sizeof(flags)); } else { @@ -1634,7 +1636,7 @@ amount_t amount_t::strip_annotations(const bool _keep_price, return t; } -amount_t amount_t::price() const +optional<amount_t> amount_t::price() const { if (commodity_ && commodity_->annotated) { amount_t t(((annotated_commodity_t *)commodity_)->price); @@ -1643,10 +1645,10 @@ amount_t amount_t::price() const "Returning price of " << *this << " = " << t); return t; } - return *this; + return optional<amount_t>(); } -moment_t amount_t::date() const +optional<moment_t> amount_t::date() const { if (commodity_ && commodity_->annotated) { DEBUG("amounts.commodities", @@ -1654,7 +1656,18 @@ moment_t amount_t::date() const << ((annotated_commodity_t *)commodity_)->date); return ((annotated_commodity_t *)commodity_)->date; } - return moment_t(); + return optional<moment_t>(); +} + +optional<string> amount_t::tag() const +{ + if (commodity_ && commodity_->annotated) { + DEBUG("amounts.commodities", + "Returning tag of " << *this << " = " + << ((annotated_commodity_t *)commodity_)->tag); + return ((annotated_commodity_t *)commodity_)->tag; + } + return optional<string>(); } diff --git a/src/amount.h b/src/amount.h index 3c8b03f6..84be02b3 100644 --- a/src/amount.h +++ b/src/amount.h @@ -48,7 +48,6 @@ #define _AMOUNT_H #include "utils.h" -#include "times.h" namespace ledger { @@ -126,27 +125,34 @@ class amount_t } amount_t number() const { + if (! has_commodity()) + return *this; amount_t temp(*this); temp.clear_commodity(); return temp; } bool has_commodity() const; - commodity_t& commodity() const; void set_commodity(commodity_t& comm) { commodity_ = &comm; } - void annotate_commodity(const amount_t& price, - const moment_t& date = moment_t(), - const string& tag = ""); - amount_t strip_annotations(const bool _keep_price = keep_price, - const bool _keep_date = keep_date, - const bool _keep_tag = keep_tag) const; void clear_commodity() { commodity_ = NULL; } - amount_t price() const; - moment_t date() const; + + commodity_t& commodity() const; + + void annotate_commodity(const amount_t& price, + const moment_t& date = moment_t(), + const string& tag = ""); + + amount_t strip_annotations(const bool _keep_price = keep_price, + const bool _keep_date = keep_date, + const bool _keep_tag = keep_tag) const; + + optional<amount_t> price() const; + optional<moment_t> date() const; + optional<string> tag() const; bool null() const { return ! quantity && ! has_commodity(); @@ -247,7 +253,7 @@ class amount_t } // test for zero and non-zero - int sign() const; + int sign() const; bool zero() const; bool realzero() const { return sign() == 0; @@ -688,9 +694,9 @@ class annotated_commodity_t : public commodity_t public: const commodity_t * ptr; - amount_t price; - moment_t date; - string tag; + amount_t price; + moment_t date; + string tag; explicit annotated_commodity_t() { TRACE_CTOR(annotated_commodity_t, ""); @@ -732,6 +738,8 @@ inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) { } inline amount_t amount_t::round() const { + if (! has_commodity()) + return *this; return round(commodity().precision()); } @@ -740,10 +748,7 @@ inline bool amount_t::has_commodity() const { } inline commodity_t& amount_t::commodity() const { - if (! commodity_) - return *commodity_t::null_commodity; - else - return *commodity_; + return has_commodity() ? *commodity_ : *commodity_t::null_commodity; } void parse_conversion(const string& larger_str, diff --git a/src/balance.cc b/src/balance.cc index 73fd668c..462a7074 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -39,30 +39,51 @@ balance_t balance_t::value(const moment_t& moment) const return temp; } -balance_t balance_t::price() const +optional<balance_t> balance_t::price() const { - balance_t temp; + optional<balance_t> temp; for (amounts_map::const_iterator i = amounts.begin(); i != amounts.end(); - i++) - temp += (*i).second.price(); + i++) { + optional<amount_t> i_price = (*i).second.price(); + if (i_price) { + if (! temp) + temp = balance_t(); + *temp += *i_price; + } + } + return temp; +} +optional<moment_t> balance_t::date() const +{ + optional<moment_t> temp; + + for (amounts_map::const_iterator i = amounts.begin(); + i != amounts.end(); + i++) { + optional<moment_t> tdate = (*i).second.date(); + if (! temp && tdate) + temp = *tdate; + else if (temp && tdate && temp != tdate) + return optional<moment_t>(); + } return temp; } -moment_t balance_t::date() const +optional<string> balance_t::tag() const { - moment_t temp; + optional<string> temp; for (amounts_map::const_iterator i = amounts.begin(); i != amounts.end(); i++) { - moment_t tdate = (*i).second.date(); - if (! is_valid_moment(temp) && is_valid_moment(tdate)) - temp = tdate; - else if (temp != tdate) - return moment_t(); + optional<string> ttag = (*i).second.tag(); + if (! temp && ttag) + temp = *ttag; + else if (temp && ttag && temp != ttag) + return optional<string>(); } return temp; } diff --git a/src/balance.h b/src/balance.h index 2a6f3072..e8665335 100644 --- a/src/balance.h +++ b/src/balance.h @@ -435,8 +435,10 @@ class balance_t amount_t amount(const commodity_t& commodity = *commodity_t::null_commodity) const; balance_t value(const moment_t& moment = now) const; - balance_t price() const; - moment_t date() const; + + optional<balance_t> price() const; + optional<moment_t> date() const; + optional<string> tag() const; balance_t strip_annotations(const bool keep_price = amount_t::keep_price, @@ -896,12 +898,16 @@ class balance_pair_t balance_t value(const moment_t& moment = now) const { return quantity.value(moment); } - balance_t price() const { + + optional<balance_t> price() const { return quantity.price(); } - moment_t date() const { + optional<moment_t> date() const { return quantity.date(); } + optional<string> tag() const { + return quantity.tag(); + } balance_t strip_annotations(const bool keep_price = amount_t::keep_price, diff --git a/src/ledger.h b/src/ledger.h index 2122ece3..a9c2e5b3 100644 --- a/src/ledger.h +++ b/src/ledger.h @@ -23,9 +23,6 @@ #include <parser.h> #include <textual.h> #include <binary.h> -#include <gnucash.h> -#include <qif.h> -#include <ofx.h> #include <report.h> #include <transform.h> diff --git a/src/main.cc b/src/main.cc index 506d17bb..0af4da0d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -3,9 +3,12 @@ #else #include <ledger.h> #endif -#include <option.h> #include "acconf.h" +#include "option.h" +#include "gnucash.h" +#include "qif.h" +#include "ofx.h" #ifdef HAVE_UNIX_PIPES #include <sys/types.h> diff --git a/src/system.hh b/src/system.hh index a1c686c0..ce7a71be 100644 --- a/src/system.hh +++ b/src/system.hh @@ -82,7 +82,7 @@ namespace std { #define HAVE_GDTOA 1 #ifdef HAVE_GDTOA -#include <gdtoa/gdtoa.h> +#include "gdtoa.h" #endif extern "C" { diff --git a/src/times.cc b/src/times.cc index 8966d598..a11d4d50 100644 --- a/src/times.cc +++ b/src/times.cc @@ -1,4 +1,4 @@ -#include "times.h" +#include "utils.h" namespace ledger { diff --git a/src/times.h b/src/times.h index a05e5d74..78b942e0 100644 --- a/src/times.h +++ b/src/times.h @@ -1,8 +1,6 @@ #ifndef _TIMES_H #define _TIMES_H -#include "utils.h" - namespace ledger { #define SUPPORT_DATE_AND_TIME 1 diff --git a/src/utils.cc b/src/utils.cc index f37ec650..41bca6be 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,5 +1,4 @@ #include "utils.h" -#include "times.h" /********************************************************************** * diff --git a/src/utils.h b/src/utils.h index 8be512fb..da6aaa27 100644 --- a/src/utils.h +++ b/src/utils.h @@ -5,6 +5,26 @@ /********************************************************************** * + * Default values + */ + +#if defined(FULL_DEBUG) +#define VERIFY_ON 1 +#define TRACING_ON 1 +#define DEBUG_ON 1 +#define TIMERS_ON 1 +#define FREE_MEMORY 1 +#elif defined(NO_DEBUG) +#define NO_ASSERTS 1 +#define NO_LOGGING 1 +#else +#define VERIFY_ON 1 // compiled in, use --verify to enable +#define TRACING_ON 1 // use --trace X to enable +#define TIMERS_ON 1 +#endif + +/********************************************************************** + * * Forward declarations */ @@ -31,26 +51,6 @@ namespace ledger { /********************************************************************** * - * Default values - */ - -#if defined(FULL_DEBUG) -#define VERIFY_ON 1 -#define TRACING_ON 1 -#define DEBUG_ON 1 -#define TIMERS_ON 1 -#define FREE_MEMORY 1 -#elif defined(NO_DEBUG) -#define NO_ASSERTS 1 -#define NO_LOGGING 1 -#else -#define VERIFY_ON 1 // compiled in, use --verify to enable -#define TRACING_ON 1 // use --trace X to enable -#define TIMERS_ON 1 // jww (2007-04-25): is this correct? -#endif - -/********************************************************************** - * * Assertions */ @@ -72,6 +72,10 @@ namespace ledger { ((x) ? ((void)0) : debug_assert(#x, BOOST_CURRENT_FUNCTION, \ __FILE__, __LINE__)) +#else // ! ASSERTS_ON + +#define assert(x) + #endif // ASSERTS_ON /********************************************************************** @@ -431,6 +435,13 @@ inline void throw_unexpected_error(char c, char wanted) { /********************************************************************** * + * Date/time support classes + */ + +#include "times.h" + +/********************************************************************** + * * General utility functions */ diff --git a/src/value.cc b/src/value.cc index c5c67b34..74a3bd8f 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1981,12 +1981,24 @@ value_t value_t::price() const case DATETIME: throw_(value_error, "Cannot find the price of a date/time"); - case AMOUNT: - return ((amount_t *) data)->price(); - case BALANCE: - return ((balance_t *) data)->price(); - case BALANCE_PAIR: - return ((balance_pair_t *) data)->quantity.price(); + case AMOUNT: { + optional<amount_t> temp = ((amount_t *) data)->price(); + if (! temp) + return false; + return *temp; + } + case BALANCE: { + optional<balance_t> temp = ((balance_t *) data)->price(); + if (! temp) + return false; + return *temp; + } + case BALANCE_PAIR: { + optional<balance_t> temp = ((balance_pair_t *) data)->price(); + if (! temp) + return false; + return *temp; + } case STRING: throw_(value_error, "Cannot find the price of a string"); @@ -2018,12 +2030,73 @@ value_t value_t::date() const case DATETIME: return *this; - case AMOUNT: - return ((amount_t *) data)->date(); - case BALANCE: - return ((balance_t *) data)->date(); - case BALANCE_PAIR: - return ((balance_pair_t *) data)->quantity.date(); + case AMOUNT: { + optional<moment_t> temp = ((amount_t *) data)->date(); + if (! temp) + return false; + return *temp; + } + case BALANCE: { + optional<moment_t> temp = ((balance_t *) data)->date(); + if (! temp) + return false; + return *temp; + } + case BALANCE_PAIR: { + optional<moment_t> temp = ((balance_pair_t *) data)->date(); + if (! temp) + return false; + return *temp; + } + + case STRING: + throw_(value_error, "Cannot find the date of a string"); + + case XML_NODE: + return (*(xml::node_t **) data)->to_value().date(); + + case POINTER: + throw_(value_error, "Cannot find the date of a pointer"); + case SEQUENCE: + throw_(value_error, "Cannot find the date of a sequence"); + + default: + assert(0); + break; + } + assert(0); + return value_t(); +} + +value_t value_t::tag() const +{ + switch (type) { + case BOOLEAN: + throw_(value_error, "Cannot find the date of a boolean"); + case INTEGER: + throw_(value_error, "Cannot find the date of an integer"); + + case DATETIME: + return *this; + + case AMOUNT: { + optional<string> temp = ((amount_t *) data)->tag(); + if (! temp) + return false; + return *temp; + } + case BALANCE: { + optional<string> temp = ((balance_t *) data)->tag(); + if (! temp) + return false; + return *temp; + } + case BALANCE_PAIR: { + optional<string> temp = ((balance_pair_t *) data)->tag(); + if (! temp) + return false; + return *temp; + } case STRING: throw_(value_error, "Cannot find the date of a string"); diff --git a/src/value.h b/src/value.h index f3a31c76..0737fac1 100644 --- a/src/value.h +++ b/src/value.h @@ -441,6 +441,7 @@ class value_t value_t cost() const; value_t price() const; value_t date() const; + value_t tag() const; value_t cast(type_t cast_type) const { value_t temp(*this); |