diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/amount.cc | 127 | ||||
-rw-r--r-- | src/amount.h | 59 | ||||
-rw-r--r-- | src/balance.cc | 26 | ||||
-rw-r--r-- | src/balance.h | 11 | ||||
-rw-r--r-- | src/commodity.h | 3 | ||||
-rw-r--r-- | src/flags.h | 38 | ||||
-rw-r--r-- | src/gnucash.cc | 4 | ||||
-rw-r--r-- | src/journal.cc | 12 | ||||
-rw-r--r-- | src/py_amount.cc | 8 | ||||
-rw-r--r-- | src/pyinterp.cc | 10 | ||||
-rw-r--r-- | src/qif.cc | 2 | ||||
-rw-r--r-- | src/report.cc | 12 | ||||
-rw-r--r-- | src/report.h | 8 | ||||
-rw-r--r-- | src/session.h | 2 | ||||
-rw-r--r-- | src/textual.cc | 8 | ||||
-rw-r--r-- | src/utils.h | 7 | ||||
-rw-r--r-- | src/value.cc | 36 | ||||
-rw-r--r-- | src/value.h | 28 | ||||
-rw-r--r-- | src/xmlparse.cc | 2 | ||||
-rw-r--r-- | src/xpath.cc | 34 | ||||
-rw-r--r-- | src/xpath.h | 2 |
21 files changed, 249 insertions, 190 deletions
diff --git a/src/amount.cc b/src/amount.cc index 65720ddd..88717e24 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -46,15 +46,15 @@ namespace ledger { -commodity_pool_t * amount_t::default_pool = NULL; +commodity_pool_t * amount_t::current_pool = NULL; -bool amount_t::keep_base = false; +bool amount_t::keep_base = false; -bool amount_t::keep_price = false; -bool amount_t::keep_date = false; -bool amount_t::keep_tag = false; +bool amount_t::keep_price = false; +bool amount_t::keep_date = false; +bool amount_t::keep_tag = false; -bool amount_t::full_strings = false; +bool amount_t::stream_fullstrings = false; #ifndef THREADSAFE /** @@ -65,30 +65,29 @@ static mpz_t temp; static mpz_t divisor; #endif -struct amount_t::bigint_t +struct amount_t::bigint_t : public supports_flags<> { #define BIGINT_BULK_ALLOC 0x01 #define BIGINT_KEEP_PREC 0x02 mpz_t val; precision_t prec; - flags_t flags; uint_least16_t ref; uint_fast32_t index; #define MPZ(bigint) ((bigint)->val) - bigint_t() : prec(0), flags(0), ref(1), index(0) { + bigint_t() : prec(0), ref(1), index(0) { TRACE_CTOR(bigint_t, ""); mpz_init(val); } - bigint_t(mpz_t _val) : prec(0), flags(0), ref(1), index(0) { + bigint_t(mpz_t _val) : prec(0), ref(1), index(0) { TRACE_CTOR(bigint_t, "mpz_t"); mpz_init_set(val, _val); } bigint_t(const bigint_t& other) - : prec(other.prec), flags(other.flags & BIGINT_KEEP_PREC), - ref(1), index(0) { + : supports_flags<>(other.flags() & BIGINT_KEEP_PREC), + prec(other.prec), ref(1), index(0) { TRACE_CTOR(bigint_t, "copy"); mpz_init_set(val, other.val); } @@ -105,12 +104,12 @@ void amount_t::initialize() mpz_init(divisor); // jww (2007-05-02): Be very careful here! - if (! default_pool) - default_pool = new commodity_pool_t; + if (! current_pool) + current_pool = new commodity_pool_t; // Add time commodity conversions, so that timelog's may be parsed // in terms of seconds, but reported as minutes or hours. - if (commodity_t * commodity = default_pool->create("s")) { + if (commodity_t * commodity = current_pool->create("s")) { commodity->add_flags(COMMODITY_STYLE_NOMARKET | COMMODITY_STYLE_BUILTIN); parse_conversion("1.0m", "60s"); @@ -126,9 +125,9 @@ void amount_t::shutdown() mpz_clear(divisor); // jww (2007-05-02): Be very careful here! - if (default_pool) { - checked_delete(default_pool); - default_pool = NULL; + if (current_pool) { + checked_delete(current_pool); + current_pool = NULL; } } @@ -151,7 +150,7 @@ void amount_t::_copy(const amount_t& amt) // Never maintain a pointer into a bulk allocation pool; such // pointers are not guaranteed to remain. - if (amt.quantity->flags & BIGINT_BULK_ALLOC) { + if (amt.quantity->has_flags(BIGINT_BULK_ALLOC)) { quantity = new bigint_t(*amt.quantity); } else { quantity = amt.quantity; @@ -208,7 +207,7 @@ void amount_t::_release() DEBUG("amounts.refs", quantity << " ref--, now " << (quantity->ref - 1)); if (--quantity->ref == 0) { - if (! (quantity->flags & BIGINT_BULK_ALLOC)) + if (! (quantity->has_flags(BIGINT_BULK_ALLOC))) checked_delete(quantity); else quantity->~bigint_t(); @@ -519,7 +518,7 @@ amount_t& amount_t::operator*=(const amount_t& amt) if (! has_commodity()) commodity_ = amt.commodity_; - if (has_commodity() && ! (quantity->flags & BIGINT_KEEP_PREC)) { + if (has_commodity() && ! (quantity->has_flags(BIGINT_KEEP_PREC))) { precision_t comm_prec = commodity().precision(); if (quantity->prec > comm_prec + 6U) { mpz_round(MPZ(quantity), MPZ(quantity), quantity->prec, comm_prec + 6U); @@ -571,7 +570,7 @@ amount_t& amount_t::operator/=(const amount_t& amt) // times), then round the number to within the commodity's precision // plus six places. - if (has_commodity() && ! (quantity->flags & BIGINT_KEEP_PREC)) { + if (has_commodity() && ! (quantity->has_flags(BIGINT_KEEP_PREC))) { precision_t comm_prec = commodity().precision(); if (quantity->prec > comm_prec + 6U) { mpz_round(MPZ(quantity), MPZ(quantity), quantity->prec, comm_prec + 6U); @@ -602,9 +601,9 @@ amount_t amount_t::round(precision_t prec) const amount_t t = *this; if (! quantity || quantity->prec <= prec) { - if (quantity && quantity->flags & BIGINT_KEEP_PREC) { + if (quantity && quantity->has_flags(BIGINT_KEEP_PREC)) { t._dup(); - t.quantity->flags &= ~BIGINT_KEEP_PREC; + t.quantity->drop_flags(BIGINT_KEEP_PREC); } return t; } @@ -614,7 +613,7 @@ amount_t amount_t::round(precision_t prec) const mpz_round(MPZ(t.quantity), MPZ(t.quantity), t.quantity->prec, prec); t.quantity->prec = prec; - t.quantity->flags &= ~BIGINT_KEEP_PREC; + t.quantity->drop_flags(BIGINT_KEEP_PREC); return t; } @@ -624,16 +623,16 @@ amount_t amount_t::unround() const if (! quantity) { amount_t t(0L); assert(t.quantity); - t.quantity->flags |= BIGINT_KEEP_PREC; + t.quantity->add_flags(BIGINT_KEEP_PREC); return t; } - else if (quantity->flags & BIGINT_KEEP_PREC) { + else if (quantity->has_flags(BIGINT_KEEP_PREC)) { return *this; } amount_t t = *this; t._dup(); - t.quantity->flags |= BIGINT_KEEP_PREC; + t.quantity->add_flags(BIGINT_KEEP_PREC); return t; } @@ -674,18 +673,18 @@ int amount_t::sign() const return quantity ? mpz_sgn(MPZ(quantity)) : 0; } -bool amount_t::zero() const +bool amount_t::is_zero() const { if (! quantity) return true; if (has_commodity()) { if (quantity->prec <= commodity().precision()) - return realzero(); + return is_realzero(); else return round(commodity().precision()).sign() == 0; } - return realzero(); + return is_realzero(); } @@ -944,7 +943,7 @@ namespace { } } -void amount_t::parse(std::istream& in, flags_t flags) +void amount_t::parse(std::istream& in, flags_t tflags) { // The possible syntax for an amount is: // @@ -954,9 +953,10 @@ void amount_t::parse(std::istream& in, flags_t flags) string symbol; string quant; annotation_t details; - unsigned int comm_flags = COMMODITY_STYLE_DEFAULTS; bool negative = false; + commodity_t::flags_t comm_flags = COMMODITY_STYLE_DEFAULTS; + char c = peek_next_nonws(in); if (c == '-') { negative = true; @@ -1007,15 +1007,15 @@ void amount_t::parse(std::istream& in, flags_t flags) if (symbol.empty()) { commodity_ = NULL; } else { - commodity_ = default_pool->find(symbol); + commodity_ = current_pool->find(symbol); if (! commodity_) { - commodity_ = default_pool->create(symbol); + commodity_ = current_pool->create(symbol); newly_created = true; } assert(commodity_); if (details) - commodity_ = default_pool->find_or_create(*commodity_, details); + commodity_ = current_pool->find_or_create(*commodity_, details); } // Determine the precision of the amount, based on the usage of @@ -1034,11 +1034,11 @@ void amount_t::parse(std::istream& in, flags_t flags) } } else if (last_comma != string::npos && - commodity().flags() & COMMODITY_STYLE_EUROPEAN) { + commodity().has_flags(COMMODITY_STYLE_EUROPEAN)) { quantity->prec = quant.length() - last_comma - 1; } else if (last_period != string::npos && - ! (commodity().flags() & COMMODITY_STYLE_EUROPEAN)) { + ! (commodity().has_flags(COMMODITY_STYLE_EUROPEAN))) { quantity->prec = quant.length() - last_period - 1; } else { @@ -1048,14 +1048,18 @@ void amount_t::parse(std::istream& in, flags_t flags) // Set the commodity's flags and precision accordingly if (commodity_ && - (newly_created || ! (flags & AMOUNT_PARSE_NO_MIGRATE))) { + (newly_created || ! (tflags & AMOUNT_PARSE_NO_MIGRATE))) { commodity().add_flags(comm_flags); if (quantity->prec > commodity().precision()) commodity().set_precision(quantity->prec); } - if (flags & AMOUNT_PARSE_NO_MIGRATE) - quantity->flags |= BIGINT_KEEP_PREC; + // Setup the amount's own flags + + set_flags(tflags); + + if (has_flags(AMOUNT_PARSE_NO_MIGRATE)) + quantity->add_flags(BIGINT_KEEP_PREC); // Now we have the final number. Remove commas and periods, if // necessary. @@ -1082,7 +1086,7 @@ void amount_t::parse(std::istream& in, flags_t flags) if (negative) in_place_negate(); - if (! (flags & AMOUNT_PARSE_NO_REDUCE)) + if (! has_flags(AMOUNT_PARSE_NO_REDUCE)) in_place_reduce(); } @@ -1132,7 +1136,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, precision_t precision = 0; if (quantity) { - if (! comm || full_precision || base.quantity->flags & BIGINT_KEEP_PREC) { + if (! comm || full_precision || base.quantity->has_flags(BIGINT_KEEP_PREC)) { mpz_ui_pow_ui(divisor, 10, base.quantity->prec); mpz_tdiv_qr(quotient, remainder, MPZ(base.quantity), divisor); precision = base.quantity->prec; @@ -1171,10 +1175,10 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, mpz_set(rquotient, remainder); } - if (! omit_commodity && ! (comm.flags() & COMMODITY_STYLE_SUFFIXED)) { + if (! omit_commodity && ! comm.has_flags(COMMODITY_STYLE_SUFFIXED)) { comm.write(out); - if (comm.flags() & COMMODITY_STYLE_SEPARATED) + if (comm.has_flags(COMMODITY_STYLE_SEPARATED)) out << " "; } @@ -1184,7 +1188,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, if (! quantity || mpz_sgn(quotient) == 0) { out << '0'; } - else if (omit_commodity || ! (comm.flags() & COMMODITY_STYLE_THOUSANDS)) { + else if (omit_commodity || ! comm.has_flags(COMMODITY_STYLE_THOUSANDS)) { char * p = mpz_get_str(NULL, 10, quotient); out << p; std::free(p); @@ -1213,7 +1217,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, i != strs.rend(); i++) { if (printed) { - out << (comm.flags() & COMMODITY_STYLE_EUROPEAN ? '.' : ','); + out << (comm.has_flags(COMMODITY_STYLE_EUROPEAN) ? '.' : ','); out.width(3); out.fill('0'); } @@ -1250,13 +1254,13 @@ void amount_t::print(std::ostream& _out, bool omit_commodity, if (omit_commodity) out << '.'; else - out << ((comm.flags() & COMMODITY_STYLE_EUROPEAN) ? ',' : '.'); + out << (comm.has_flags(COMMODITY_STYLE_EUROPEAN) ? ',' : '.'); out << ender; } } - if (! omit_commodity && comm.flags() & COMMODITY_STYLE_SUFFIXED) { - if (comm.flags() & COMMODITY_STYLE_SEPARATED) + if (! omit_commodity && comm.has_flags(COMMODITY_STYLE_SUFFIXED)) { + if (comm.has_flags(COMMODITY_STYLE_SEPARATED)) out << " "; comm.write(out); @@ -1292,9 +1296,9 @@ void amount_t::read(std::istream& in) if (ident == 0xffffffff) commodity_ = NULL; else if (ident == 0) - commodity_ = default_pool->null_commodity; + commodity_ = current_pool->null_commodity; else { - commodity_ = default_pool->find(ident - 1); + commodity_ = current_pool->find(ident - 1); assert(commodity_); } @@ -1308,9 +1312,9 @@ void amount_t::read(char *& data) if (ident == 0xffffffff) commodity_ = NULL; else if (ident == 0) - commodity_ = default_pool->null_commodity; + commodity_ = current_pool->null_commodity; else { - commodity_ = default_pool->find(ident - 1); + commodity_ = current_pool->find(ident - 1); assert(commodity_); } @@ -1357,9 +1361,9 @@ void amount_t::read_quantity(char *& data) quantity->prec = *((precision_t *) data); data += sizeof(precision_t); - quantity->flags = *((flags_t *) data); + quantity->set_flags(*((flags_t *) data)); data += sizeof(flags_t); - quantity->flags |= BIGINT_BULK_ALLOC; + quantity->add_flags(BIGINT_BULK_ALLOC); } else { uint_fast32_t index = *((uint_fast32_t *) data); data += sizeof(uint_fast32_t); @@ -1399,7 +1403,10 @@ void amount_t::read_quantity(std::istream& in) mpz_neg(MPZ(quantity), MPZ(quantity)); in.read((char *)&quantity->prec, sizeof(quantity->prec)); - in.read((char *)&quantity->flags, sizeof(quantity->flags)); + + bigint_t::flags_t tflags; + in.read((char *)&tflags, sizeof(tflags)); + quantity->set_flags(tflags); } else { assert(0); @@ -1436,9 +1443,9 @@ void amount_t::write_quantity(std::ostream& out) const out.write(&byte, sizeof(byte)); out.write((char *)&quantity->prec, sizeof(quantity->prec)); - flags_t flags = quantity->flags & ~BIGINT_BULK_ALLOC; - assert(sizeof(flags) == sizeof(quantity->flags)); - out.write((char *)&flags, sizeof(flags)); + bigint_t::flags_t tflags = quantity->flags() & ~BIGINT_BULK_ALLOC; + assert(sizeof(tflags) == sizeof(bigint_t::flags_t)); + out.write((char *)&tflags, sizeof(tflags)); } else { assert(quantity->ref > 1); diff --git a/src/amount.h b/src/amount.h index 6f5137ab..f185cf7b 100644 --- a/src/amount.h +++ b/src/amount.h @@ -71,7 +71,8 @@ DECLARE_EXCEPTION(amount_error); * degree. */ class amount_t - : public ordered_field_operators<amount_t, + : public supports_flags<>, + ordered_field_operators<amount_t, ordered_field_operators<amount_t, long, ordered_field_operators<amount_t, unsigned long, ordered_field_operators<amount_t, double> > > > @@ -91,10 +92,10 @@ public: typedef uint_least16_t precision_t; /** - * The default_pool is a static variable indicating which commodity - * pool should be used when none is specified. + * The current_pool is a static variable indicating which commodity + * pool should be used. */ - static commodity_pool_t * default_pool; + static commodity_pool_t * current_pool; /** * The `keep_base' member determines whether scalable commodities @@ -130,15 +131,15 @@ public: static bool keep_tag; /** - * The `full-strings' static member is currently only used by the - * unit testing code. It causes amounts written to streams to use - * the `to_fullstring' method rather than the `to_string' method, so - * that complete precision is always displayed, no matter what the - * precision of an individual commodity might be. + * The `stream_fullstrings' static member is currently only used by + * the unit testing code. It causes amounts written to streams to + * use the `to_fullstring' method rather than the `to_string' + * method, so that complete precision is always displayed, no matter + * what the precision of an individual commodity might be. * @see to_string * @see to_fullstring */ - static bool full_strings; + static bool stream_fullstrings; protected: void _init(); @@ -372,14 +373,14 @@ public: * amount -- using its internal precision -- and not the display * value. To test its display value, use: `round().sign()'. * - * nonzero(), or operator bool, returns true if an amount's display - * value is not zero. + * is_nonzero(), or operator bool, returns true if an amount's + * display value is not zero. * - * zero() returns true if an amount's display value is zero. Thus, - * $0.0001 is considered zero(). + * is_zero() returns true if an amount's display value is zero. + * Thus, $0.0001 is considered zero(). * - * realzero() returns true if an amount's actual value is zero. - * $0.0001 is not considered realzero(). + * is_realzero() returns true if an amount's actual value is zero. + * $0.0001 is not considered is_realzero(). * * is_null() returns true if an amount has no value and no * commodity. This occurs only if an unitialized amount has never @@ -388,14 +389,14 @@ public: int sign() const; operator bool() const { - return nonzero(); + return is_nonzero(); } - bool nonzero() const { - return ! zero(); + bool is_nonzero() const { + return ! is_zero(); } - bool zero() const; - bool realzero() const { + bool is_zero() const; + bool is_realzero() const { return sign() == 0; } @@ -550,12 +551,10 @@ public: #define AMOUNT_PARSE_NO_MIGRATE 0x01 #define AMOUNT_PARSE_NO_REDUCE 0x02 - typedef uint_least8_t flags_t; - - void parse(std::istream& in, flags_t flags = 0); - void parse(const string& str, flags_t flags = 0) { + void parse(std::istream& in, flags_t bits = 0); + void parse(const string& str, flags_t bits = 0) { std::istringstream stream(str); - parse(stream, flags); + parse(stream, bits); } static void parse_conversion(const string& larger_str, @@ -588,9 +587,9 @@ public: * read(istream) reads an amount from the given input stream. It * must have been put there using `write(ostream)'. The required * flow of logic is: - * amount_t::default_pool->write(out) + * amount_t::current_pool->write(out) * amount.write(out) // write out all amounts - * amount_t::default_pool->read(in) + * amount_t::current_pool->read(in) * amount.read(in) * * read(char *&) reads an amount from data which has been read from @@ -658,7 +657,7 @@ inline string amount_t::quantity_string() const { } inline std::ostream& operator<<(std::ostream& out, const amount_t& amt) { - amt.print(out, false, amount_t::full_strings); + amt.print(out, false, amount_t::stream_fullstrings); return out; } inline std::istream& operator>>(std::istream& in, amount_t& amt) { @@ -690,7 +689,7 @@ inline bool amount_t::has_commodity() const { inline commodity_t& amount_t::commodity() const { // jww (2007-05-02): Should be a way to access null_commodity better - return has_commodity() ? *commodity_ : *default_pool->null_commodity; + return has_commodity() ? *commodity_ : *current_pool->null_commodity; } } // namespace ledger diff --git a/src/balance.cc b/src/balance.cc index dd822963..cafd0f01 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -4,8 +4,11 @@ namespace ledger { balance_t& balance_t::operator*=(const balance_t& bal) { - if (realzero() || bal.realzero()) { - return *this = amount_t(); + if (is_realzero()) { + return *this; + } + else if (bal.is_realzero()) { + return *this = bal; } else if (bal.amounts.size() == 1) { return *this *= (*bal.amounts.begin()).second; @@ -34,8 +37,11 @@ balance_t& balance_t::operator*=(const balance_t& bal) balance_t& balance_t::operator*=(const amount_t& amt) { - if (realzero() || amt.realzero()) { - return *this = amount_t(); + if (is_realzero()) { + return *this; + } + else if (amt.is_realzero()) { + return *this = amt; } else if (! amt.commodity()) { // Multiplying by the null commodity causes all amounts to be @@ -72,11 +78,11 @@ balance_t& balance_t::operator*=(const amount_t& amt) balance_t& balance_t::operator/=(const balance_t& bal) { - if (bal.realzero()) { + if (bal.is_realzero()) { throw_(amount_error, "Divide by zero: " << *this << " / " << bal); } - else if (realzero()) { - return *this = amount_t(); + else if (is_realzero()) { + return *this; } else if (bal.amounts.size() == 1) { return *this /= (*bal.amounts.begin()).second; @@ -97,11 +103,11 @@ balance_t& balance_t::operator/=(const balance_t& bal) balance_t& balance_t::operator/=(const amount_t& amt) { - if (amt.realzero()) { + if (amt.is_realzero()) { throw_(amount_error, "Divide by zero: " << *this << " / " << amt); } - else if (realzero()) { - return *this = amount_t(); + else if (is_realzero()) { + return *this; } else if (! amt.commodity()) { // Dividing by the null commodity causes all amounts to be diff --git a/src/balance.h b/src/balance.h index 62f9ba86..769d8d83 100644 --- a/src/balance.h +++ b/src/balance.h @@ -36,8 +36,7 @@ public: } balance_t(const amount_t& amt) { TRACE_CTOR(balance_t, "const amount_t&"); - if (! amt.realzero()) - amounts.insert(amounts_pair(&amt.commodity(), amt)); + amounts.insert(amounts_pair(&amt.commodity(), amt)); } ~balance_t() { TRACE_DTOR(balance_t); @@ -139,13 +138,13 @@ public: return false; } - bool realzero() const { + bool is_realzero() const { if (amounts.size() == 0) return true; for (amounts_map::const_iterator i = amounts.begin(); i != amounts.end(); i++) - if (! (*i).second.realzero()) + if (! (*i).second.is_realzero()) return false; return true; } @@ -324,8 +323,8 @@ public: return quantity; } - bool realzero() const { - return ((! cost || cost->realzero()) && quantity.realzero()); + bool is_realzero() const { + return ((! cost || cost->is_realzero()) && quantity.is_realzero()); } balance_pair_t abs() const { diff --git a/src/commodity.h b/src/commodity.h index 93c1f3be..fc1a23de 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -183,6 +183,9 @@ public: void set_flags(flags_t arg) { base->flags = arg; } + bool has_flags(flags_t arg) { + return base->flags & arg; + } void add_flags(flags_t arg) { base->flags |= arg; } diff --git a/src/flags.h b/src/flags.h new file mode 100644 index 00000000..e68884ca --- /dev/null +++ b/src/flags.h @@ -0,0 +1,38 @@ +#ifndef _FLAGS_H +#define _FLAGS_H + +template <typename T = uint_least8_t> +class supports_flags +{ +public: + typedef T flags_t; + +protected: + flags_t flags_; + +public: + supports_flags() : flags_(0) {} + supports_flags(const flags_t arg) : flags_(arg) {} + + flags_t flags() const { + return flags_; + } + bool has_flags(const flags_t arg) const { + return flags_ & arg; + } + + void set_flags(const flags_t arg) { + flags_ = arg; + } + void clear_flags() { + flags_ = 0; + } + void add_flags(const flags_t arg) { + flags_ |= arg; + } + void drop_flags(const flags_t arg) { + flags_ &= ~arg; + } +}; + +#endif // _FLAGS_H diff --git a/src/gnucash.cc b/src/gnucash.cc index 50b1f8f8..284595fe 100644 --- a/src/gnucash.cc +++ b/src/gnucash.cc @@ -191,7 +191,7 @@ void dataHandler(void *userData, const char *s, int len) string symbol(s, len); if (symbol == "USD") symbol = "$"; - parser->curr_comm = amount_t::default_pool->find_or_create(symbol); + parser->curr_comm = amount_t::current_pool->find_or_create(symbol); assert(parser->curr_comm); if (symbol != "$") @@ -320,7 +320,7 @@ unsigned int gnucash_parser_t::parse(std::istream& in, // GnuCash uses the USD commodity without defining it, which really // means $. - commodity_t * usd = amount_t::default_pool->find_or_create("$"); + commodity_t * usd = amount_t::current_pool->find_or_create("$"); usd->set_precision(2); usd->add_flags(COMMODITY_STYLE_THOUSANDS); diff --git a/src/journal.cc b/src/journal.cc index 7674bd4d..5ba7d421 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -146,15 +146,15 @@ bool entry_base_t::finalize() // the balance. This is done for the last eligible commodity. if (! saw_null && balance && balance.type == value_t::BALANCE && - balance.balance().amounts.size() == 2) { + balance.to_balance().amounts.size() == 2) { transactions_list::const_iterator x = transactions.begin(); assert((*x)->amount); commodity_t& this_comm = (*x)->amount->commodity(); balance_t::amounts_map::const_iterator this_bal = - balance.balance().amounts.find(&this_comm); + balance.to_balance().amounts.find(&this_comm); balance_t::amounts_map::const_iterator other_bal = - balance.balance().amounts.begin(); + balance.to_balance().amounts.begin(); if (this_bal == other_bal) other_bal++; @@ -209,12 +209,12 @@ bool entry_base_t::finalize() balance_t * bal = NULL; switch (balance.type) { case value_t::BALANCE_PAIR: - bal = &balance.balance_pair().quantity; + bal = &balance.to_balance_pair().quantity; // fall through... case value_t::BALANCE: if (! bal) - bal = &balance.balance(); + bal = &balance.to_balance(); if (bal->amounts.size() < 2) { balance.cast(value_t::AMOUNT); @@ -243,7 +243,7 @@ bool entry_base_t::finalize() // fall through... case value_t::AMOUNT: - (*x)->amount = balance.amount().negate(); + (*x)->amount = balance.to_amount().negate(); (*x)->flags |= TRANSACTION_CALCULATED; balance += *(*x)->amount; diff --git a/src/py_amount.cc b/src/py_amount.cc index c4f476c3..2d93067d 100644 --- a/src/py_amount.cc +++ b/src/py_amount.cc @@ -175,10 +175,10 @@ void export_amount() .def("value", py_value_2) .def("sign", &amount_t::sign) - .def("__nonzero__", &amount_t::nonzero) - .def("nonzero", &amount_t::nonzero) - .def("zero", &amount_t::zero) - .def("realzero", &amount_t::realzero) + .def("__nonzero__", &amount_t::is_nonzero) + .def("nonzero", &amount_t::is_nonzero) + .def("zero", &amount_t::is_zero) + .def("realzero", &amount_t::is_realzero) .def("is_null", &amount_t::is_null) .def("to_double", &amount_t::to_double) diff --git a/src/pyinterp.cc b/src/pyinterp.cc index c0e22740..39735533 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -117,11 +117,11 @@ void python_interpreter_t::functor_t::operator()(value_t& result, result = static_cast<const value_t&>(extract<value_t>(func.ptr())); } else { assert(locals->args.type == value_t::SEQUENCE); - if (locals->args.sequence()->size() > 0) { + if (locals->args.to_sequence()->size() > 0) { list arglist; for (value_t::sequence_t::iterator - i = locals->args.sequence()->begin(); - i != locals->args.sequence()->end(); + i = locals->args.to_sequence()->begin(); + i != locals->args.to_sequence()->end(); i++) arglist.append(*i); @@ -155,10 +155,10 @@ void python_interpreter_t::lambda_t::operator()(value_t& result, { try { assert(locals->args.type == value_t::SEQUENCE); - assert(locals->args.sequence()->size() == 1); + assert(locals->args.to_sequence()->size() == 1); value_t item = locals->args[0]; assert(item.type == value_t::POINTER); - result = call<value_t>(func.ptr(), item.xml_node()); + result = call<value_t>(func.ptr(), item.to_xml_node()); } catch (const error_already_set&) { PyErr_Print(); @@ -110,7 +110,7 @@ unsigned int qif_parser_t::parse(std::istream& in, unsigned char prec = xact->amount->commodity().precision(); if (! def_commodity) { - def_commodity = amount_t::default_pool->find_or_create("$"); + def_commodity = amount_t::current_pool->find_or_create("$"); assert(def_commodity); } xact->amount->set_commodity(*def_commodity); diff --git a/src/report.cc b/src/report.cc index 65ceabd1..0de6d9e6 100644 --- a/src/report.cc +++ b/src/report.cc @@ -20,16 +20,16 @@ void report_t::abbrev(value_t& result, xml::xpath_t::scope_t * locals) if (locals->args.size() < 2) throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])"); - string str = locals->args[0].string_value(); - long wid = locals->args[1]; + string str = locals->args[0].to_string(); + long wid = locals->args[1]; elision_style_t style = session->elision_style; if (locals->args.size() == 3) - style = (elision_style_t)locals->args[2].integer(); + style = (elision_style_t)locals->args[2].to_long(); long abbrev_len = session->abbrev_length; if (locals->args.size() == 4) - abbrev_len = locals->args[3].integer(); + abbrev_len = locals->args[3].to_long(); result.set_string(abbreviate(str, wid, style, true, (int)abbrev_len)); } @@ -39,11 +39,11 @@ void report_t::ftime(value_t&, xml::xpath_t::scope_t * locals) if (locals->args.size() < 1) throw_(std::logic_error, "usage: ftime(DATE [, DATE_FORMAT])"); - moment_t date = locals->args[0].datetime(); + moment_t date = locals->args[0].to_datetime(); string date_format; if (locals->args.size() == 2) - date_format = locals->args[1].string_value(); + date_format = locals->args[1].to_string(); #if 0 // jww (2007-04-18): Need to setup an output facet here else diff --git a/src/report.h b/src/report.h index 21ee261f..ca066566 100644 --- a/src/report.h +++ b/src/report.h @@ -60,18 +60,18 @@ class report_t : public xml::xpath_t::scope_t xml::xpath_t(expr).compile((xml::document_t *)NULL, this); } void option_eval(value_t&, xml::xpath_t::scope_t * locals) { - eval(locals->args[0].string_value()); + eval(locals->args[0].to_string()); } void option_amount(value_t&, xml::xpath_t::scope_t * locals) { - eval(string("t=") + locals->args[0].string_value()); + eval(string("t=") + locals->args[0].to_string()); } void option_total(value_t&, xml::xpath_t::scope_t * locals) { - eval(string("T()=") + locals->args[0].string_value()); + eval(string("T()=") + locals->args[0].to_string()); } void option_format(value_t&, xml::xpath_t::scope_t * locals) { - format_string = locals->args[0].string_value(); + format_string = locals->args[0].to_string(); } void option_raw(value_t&) { diff --git a/src/session.h b/src/session.h index c8d83065..a2e9c358 100644 --- a/src/session.h +++ b/src/session.h @@ -172,7 +172,7 @@ class session_t : public xml::xpath_t::scope_t // void option_file(value_t&, xml::xpath_t::scope_t * locals) { - data_file = locals->args.string_value(); + data_file = locals->args.to_string(); } #if 0 diff --git a/src/textual.cc b/src/textual.cc index 6e7e3ee2..8ed83698 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -66,7 +66,7 @@ parse_amount_expr(std::istream& in, journal_t *, } #endif - amount = xpath.calc(static_cast<xml::transaction_node_t *>(xact.data)).amount(); + amount = xpath.calc(xact.data).to_amount(); DEBUG("ledger.textual.parse", "line " << linenum << ": " << "The transaction amount is " << amount); @@ -718,7 +718,7 @@ unsigned int textual_parser_t::parse(std::istream& in, case 'D': { // a default commodity for "entry" amount_t amt(skip_ws(line + 1)); - amount_t::default_pool->default_commodity = &amt.commodity(); + amount_t::current_pool->default_commodity = &amt.commodity(); break; } @@ -757,7 +757,7 @@ unsigned int textual_parser_t::parse(std::istream& in, amount_t price(symbol_and_price); if (commodity_t * commodity = - amount_t::default_pool->find_or_create(symbol)) + amount_t::current_pool->find_or_create(symbol)) commodity->add_price(datetime, price); break; } @@ -768,7 +768,7 @@ unsigned int textual_parser_t::parse(std::istream& in, parse_symbol(p, symbol); if (commodity_t * commodity = - amount_t::default_pool->find_or_create(symbol)) + amount_t::current_pool->find_or_create(symbol)) commodity->add_flags(COMMODITY_STYLE_NOMARKET); break; } diff --git a/src/utils.h b/src/utils.h index ddc6de85..22fc48dc 100644 --- a/src/utils.h +++ b/src/utils.h @@ -447,6 +447,13 @@ inline void throw_unexpected_error(char c, char wanted) { /********************************************************************** * + * General support for objects with "flags" + */ + +#include "flags.h" + +/********************************************************************** + * * General utility functions */ diff --git a/src/value.cc b/src/value.cc index 4451a543..2c9f307a 100644 --- a/src/value.cc +++ b/src/value.cc @@ -3,7 +3,7 @@ namespace ledger { -bool& value_t::boolean() +bool& value_t::to_boolean() { if (type == BOOLEAN) { return *(bool *) data; @@ -15,7 +15,7 @@ bool& value_t::boolean() } } -long& value_t::integer() +long& value_t::to_long() { if (type == INTEGER) { return *(long *) data; @@ -27,7 +27,7 @@ long& value_t::integer() } } -moment_t& value_t::datetime() +moment_t& value_t::to_datetime() { if (type == DATETIME) { return *(moment_t *) data; @@ -39,7 +39,7 @@ moment_t& value_t::datetime() } } -amount_t& value_t::amount() +amount_t& value_t::to_amount() { if (type == AMOUNT) { return *(amount_t *) data; @@ -51,7 +51,7 @@ amount_t& value_t::amount() } } -balance_t& value_t::balance() +balance_t& value_t::to_balance() { if (type == BALANCE) { return *(balance_t *) data; @@ -63,7 +63,7 @@ balance_t& value_t::balance() } } -balance_pair_t& value_t::balance_pair() +balance_pair_t& value_t::to_balance_pair() { if (type == BALANCE_PAIR) { return *(balance_pair_t *) data; @@ -75,7 +75,7 @@ balance_pair_t& value_t::balance_pair() } } -string& value_t::string_value() +string& value_t::to_string() { if (type == STRING) { return **(string **) data; @@ -89,7 +89,7 @@ string& value_t::string_value() } } -xml::node_t *& value_t::xml_node() +xml::node_t *& value_t::to_xml_node() { if (type == XML_NODE) return *(xml::node_t **) data; @@ -97,7 +97,7 @@ xml::node_t *& value_t::xml_node() throw_(value_error, "Value is not an XML node"); } -void *& value_t::pointer() +void *& value_t::to_pointer() { if (type == POINTER) return *(void **) data; @@ -105,7 +105,7 @@ void *& value_t::pointer() throw_(value_error, "Value is not a pointer"); } -value_t::sequence_t *& value_t::sequence() +value_t::sequence_t *& value_t::to_sequence() { if (type == SEQUENCE) return *(sequence_t **) data; @@ -138,7 +138,7 @@ void value_t::destroy() void value_t::simplify() { - if (realzero()) { + if (is_realzero()) { DEBUG("amounts.values.simplify", "Zeroing type " << type); *this = 0L; return; @@ -146,7 +146,7 @@ void value_t::simplify() if (type == BALANCE_PAIR && (! ((balance_pair_t *) data)->cost || - ((balance_pair_t *) data)->cost->realzero())) { + ((balance_pair_t *) data)->cost->is_realzero())) { DEBUG("amounts.values.simplify", "Reducing balance pair to balance"); in_place_cast(BALANCE); } @@ -617,7 +617,7 @@ value_t& value_t::operator*=(const value_t& val) else if (val.type == XML_NODE) // recurse return *this *= (*(xml::node_t **) val.data)->to_value(); - if (val.realzero() && type != STRING) { + if (val.is_realzero() && type != STRING) { *this = 0L; return *this; } @@ -893,7 +893,7 @@ value_t::operator bool() const case STRING: return ! (**((string **) data)).empty(); case XML_NODE: - return (*(xml::node_t **) data)->to_value().boolean(); + return (*(xml::node_t **) data)->to_value().to_boolean(); case POINTER: return *(void **) data != NULL; case SEQUENCE: @@ -1810,7 +1810,7 @@ void value_t::in_place_negate() } } -bool value_t::realzero() const +bool value_t::is_realzero() const { switch (type) { case BOOLEAN: @@ -1820,11 +1820,11 @@ bool value_t::realzero() const case DATETIME: return ! is_valid_moment(*((moment_t *) data)); case AMOUNT: - return ((amount_t *) data)->realzero(); + return ((amount_t *) data)->is_realzero(); case BALANCE: - return ((balance_t *) data)->realzero(); + return ((balance_t *) data)->is_realzero(); case BALANCE_PAIR: - return ((balance_pair_t *) data)->realzero(); + return ((balance_pair_t *) data)->is_realzero(); case STRING: return ((string *) data)->empty(); case XML_NODE: diff --git a/src/value.h b/src/value.h index d8c18fe4..7d6f36be 100644 --- a/src/value.h +++ b/src/value.h @@ -279,31 +279,31 @@ class value_t return *this; } - bool& boolean(); - long& integer(); - moment_t& datetime(); - amount_t& amount(); - balance_t& balance(); - balance_pair_t& balance_pair(); - string& string_value(); - xml::node_t *& xml_node(); - void *& pointer(); - sequence_t *& sequence(); + bool& to_boolean(); + long& to_long(); + moment_t& to_datetime(); + amount_t& to_amount(); + balance_t& to_balance(); + balance_pair_t& to_balance_pair(); + string& to_string(); + xml::node_t *& to_xml_node(); + void *& to_pointer(); + sequence_t *& to_sequence(); value_t& operator[](const int index) { - sequence_t * seq = sequence(); + sequence_t * seq = to_sequence(); assert(seq); return (*seq)[index]; } void push_back(const value_t& val) { - sequence_t * seq = sequence(); + sequence_t * seq = to_sequence(); assert(seq); return seq->push_back(val); } std::size_t size() const { - sequence_t * seq = const_cast<value_t&>(*this).sequence(); + sequence_t * seq = const_cast<value_t&>(*this).to_sequence(); assert(seq); return seq->size(); } @@ -359,7 +359,7 @@ class value_t } void in_place_negate(); - bool realzero() const; + bool is_realzero() const; value_t abs() const; void in_place_cast(type_t cast_type); value_t cost() const; diff --git a/src/xmlparse.cc b/src/xmlparse.cc index c54e5969..48a307a0 100644 --- a/src/xmlparse.cc +++ b/src/xmlparse.cc @@ -104,7 +104,7 @@ static void endElement(void *userData, const char *name) } else if (std::strcmp(name, "symbol") == 0) { assert(! curr_comm); - curr_comm = amount_t::default_pool->find_or_create(data); + curr_comm = amount_t::current_pool->find_or_create(data); assert(curr_comm); curr_comm->add_flags(COMMODITY_STYLE_SUFFIXED); if (! comm_flags.empty()) { diff --git a/src/xpath.cc b/src/xpath.cc index 86b0c1c4..8fea995e 100644 --- a/src/xpath.cc +++ b/src/xpath.cc @@ -534,7 +534,7 @@ bool xpath_t::function_scope_t::resolve(const string& name, case 't': if (name == "text") { if (value->type == value_t::XML_NODE) - result.set_string(value->xml_node()->text()); + result.set_string(value->to_xml_node()->text()); else throw_(calc_error, "Attempt to call text() on a non-node value"); return true; @@ -650,7 +650,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const #endif /* USE_BOOST_PYTHON */ #endif - string ident = tok.value.string_value(); + string ident = tok.value.to_string(); int id = -1; if (std::isdigit(ident[0])) { node.reset(new op_t(op_t::ARG_INDEX)); @@ -692,7 +692,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const throw_(parse_error, "@ symbol must be followed by attribute name"); node.reset(new op_t(op_t::ATTR_NAME)); - node->name = new string(tok.value.string_value()); + node->name = new string(tok.value.to_string()); break; #if 0 @@ -1184,7 +1184,7 @@ void xpath_t::op_t::find_values(value_t * context, scope_t * scope, if (recursive) { if (context->type == value_t::XML_NODE) { - node_t * ptr = context->xml_node(); + node_t * ptr = context->to_xml_node(); if (ptr->flags & XML_NODE_IS_PARENT) { parent_node_t * parent = static_cast<parent_node_t *>(ptr); for (node_t * node = parent->children(); @@ -1214,7 +1214,7 @@ bool xpath_t::op_t::test_value(value_t * context, scope_t * scope, return *expr->valuep == value_t((long)index + 1); default: - return expr->valuep->boolean(); + return expr->valuep->to_boolean(); } } @@ -1246,7 +1246,7 @@ xpath_t::op_t * xpath_t::op_t::defer_sequence(value_t::sequence_t& result_seq) if ((*i).type != value_t::POINTER) *opp = wrap_value(*i)->acquire(); else - *opp = static_cast<op_t *>((*i).pointer()); + *opp = static_cast<op_t *>((*i).to_pointer()); } return lit_seq.release(); @@ -1256,7 +1256,7 @@ void xpath_t::op_t::append_value(value_t& val, value_t::sequence_t& result_seq) { if (val.type == value_t::SEQUENCE) { - value_t::sequence_t * subseq = val.sequence(); + value_t::sequence_t * subseq = val.to_sequence(); for (value_t::sequence_t::iterator i = subseq->begin(); i != subseq->end(); i++) @@ -1284,8 +1284,8 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, case document_t::PARENT: if (context->type != value_t::XML_NODE) throw_(compile_error, "Referencing parent node from a non-node value"); - else if (context->xml_node()->parent) - return wrap_value(context->xml_node()->parent)->acquire(); + else if (context->to_xml_node()->parent) + return wrap_value(context->to_xml_node()->parent)->acquire(); else throw_(compile_error, "Referencing parent node from the root node"); @@ -1293,13 +1293,13 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, if (context->type != value_t::XML_NODE) throw_(compile_error, "Referencing root node from a non-node value"); else - return wrap_value(context->xml_node()->document->top)->acquire(); + return wrap_value(context->to_xml_node()->document->top)->acquire(); case document_t::ALL: { if (context->type != value_t::XML_NODE) throw_(compile_error, "Referencing child nodes from a non-node value"); - node_t * ptr = context->xml_node(); + node_t * ptr = context->to_xml_node(); if (! (ptr->flags & XML_NODE_IS_PARENT)) throw_(compile_error, "Request for child nodes of a leaf node"); @@ -1319,7 +1319,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, case NODE_NAME: if (context->type == value_t::XML_NODE) { - node_t * ptr = context->xml_node(); + node_t * ptr = context->to_xml_node(); if (resolve) { // First, look up the symbol as a node name within the current // context. If any exist, then return the set of names. @@ -1352,7 +1352,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, case ATTR_NAME: { // jww (2006-09-29): Attrs should map strings to values, not strings - const char * value = context->xml_node()->get_attr(name->c_str()); + const char * value = context->to_xml_node()->get_attr(name->c_str()); return wrap_value(value)->acquire(); } @@ -1372,8 +1372,8 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, case ARG_INDEX: if (scope && scope->kind == scope_t::ARGUMENT) { assert(scope->args.type == value_t::SEQUENCE); - if (arg_index < scope->args.sequence()->size()) - return wrap_value((*scope->args.sequence())[arg_index])->acquire(); + if (arg_index < scope->args.to_sequence()->size()) + return wrap_value((*scope->args.to_sequence())[arg_index])->acquire(); else throw_(compile_error, "Reference to non-existing argument"); } else { @@ -1815,7 +1815,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, } case value_t::SEQUENCE: { - value_t::sequence_t * seq = lexpr->valuep->sequence(); + value_t::sequence_t * seq = lexpr->valuep->to_sequence(); int index = 0; for (value_t::sequence_t::iterator i = seq->begin(); @@ -2286,7 +2286,7 @@ bool xpath_t::op_t::write(std::ostream& out, } if (! symbol.empty()) { - if (amount_t::default_pool->find(symbol)) + if (amount_t::current_pool->find(symbol)) out << '@'; out << symbol; } diff --git a/src/xpath.h b/src/xpath.h index 16790e2b..638ec482 100644 --- a/src/xpath.h +++ b/src/xpath.h @@ -760,7 +760,7 @@ inline std::ostream& operator<<(std::ostream& out, const xpath_t::op_t& op) { template <typename T> inline T * get_ptr(xml::xpath_t::scope_t * locals, unsigned int idx) { assert(locals->args.size() > idx); - T * ptr = static_cast<T *>(locals->args[idx].pointer()); + T * ptr = static_cast<T *>(locals->args[idx].to_pointer()); assert(ptr); return ptr; } |