Rearranged many method names.
This commit is contained in:
parent
7868a53b70
commit
06e7c28202
23 changed files with 259 additions and 200 deletions
127
src/amount.cc
127
src/amount.cc
|
|
@ -46,15 +46,15 @@
|
||||||
|
|
||||||
namespace ledger {
|
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_price = false;
|
||||||
bool amount_t::keep_date = false;
|
bool amount_t::keep_date = false;
|
||||||
bool amount_t::keep_tag = false;
|
bool amount_t::keep_tag = false;
|
||||||
|
|
||||||
bool amount_t::full_strings = false;
|
bool amount_t::stream_fullstrings = false;
|
||||||
|
|
||||||
#ifndef THREADSAFE
|
#ifndef THREADSAFE
|
||||||
/**
|
/**
|
||||||
|
|
@ -65,30 +65,29 @@ static mpz_t temp;
|
||||||
static mpz_t divisor;
|
static mpz_t divisor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct amount_t::bigint_t
|
struct amount_t::bigint_t : public supports_flags<>
|
||||||
{
|
{
|
||||||
#define BIGINT_BULK_ALLOC 0x01
|
#define BIGINT_BULK_ALLOC 0x01
|
||||||
#define BIGINT_KEEP_PREC 0x02
|
#define BIGINT_KEEP_PREC 0x02
|
||||||
|
|
||||||
mpz_t val;
|
mpz_t val;
|
||||||
precision_t prec;
|
precision_t prec;
|
||||||
flags_t flags;
|
|
||||||
uint_least16_t ref;
|
uint_least16_t ref;
|
||||||
uint_fast32_t index;
|
uint_fast32_t index;
|
||||||
|
|
||||||
#define MPZ(bigint) ((bigint)->val)
|
#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, "");
|
TRACE_CTOR(bigint_t, "");
|
||||||
mpz_init(val);
|
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");
|
TRACE_CTOR(bigint_t, "mpz_t");
|
||||||
mpz_init_set(val, _val);
|
mpz_init_set(val, _val);
|
||||||
}
|
}
|
||||||
bigint_t(const bigint_t& other)
|
bigint_t(const bigint_t& other)
|
||||||
: prec(other.prec), flags(other.flags & BIGINT_KEEP_PREC),
|
: supports_flags<>(other.flags() & BIGINT_KEEP_PREC),
|
||||||
ref(1), index(0) {
|
prec(other.prec), ref(1), index(0) {
|
||||||
TRACE_CTOR(bigint_t, "copy");
|
TRACE_CTOR(bigint_t, "copy");
|
||||||
mpz_init_set(val, other.val);
|
mpz_init_set(val, other.val);
|
||||||
}
|
}
|
||||||
|
|
@ -105,12 +104,12 @@ void amount_t::initialize()
|
||||||
mpz_init(divisor);
|
mpz_init(divisor);
|
||||||
|
|
||||||
// jww (2007-05-02): Be very careful here!
|
// jww (2007-05-02): Be very careful here!
|
||||||
if (! default_pool)
|
if (! current_pool)
|
||||||
default_pool = new commodity_pool_t;
|
current_pool = new commodity_pool_t;
|
||||||
|
|
||||||
// Add time commodity conversions, so that timelog's may be parsed
|
// Add time commodity conversions, so that timelog's may be parsed
|
||||||
// in terms of seconds, but reported as minutes or hours.
|
// 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);
|
commodity->add_flags(COMMODITY_STYLE_NOMARKET | COMMODITY_STYLE_BUILTIN);
|
||||||
|
|
||||||
parse_conversion("1.0m", "60s");
|
parse_conversion("1.0m", "60s");
|
||||||
|
|
@ -126,9 +125,9 @@ void amount_t::shutdown()
|
||||||
mpz_clear(divisor);
|
mpz_clear(divisor);
|
||||||
|
|
||||||
// jww (2007-05-02): Be very careful here!
|
// jww (2007-05-02): Be very careful here!
|
||||||
if (default_pool) {
|
if (current_pool) {
|
||||||
checked_delete(default_pool);
|
checked_delete(current_pool);
|
||||||
default_pool = NULL;
|
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
|
// Never maintain a pointer into a bulk allocation pool; such
|
||||||
// pointers are not guaranteed to remain.
|
// 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);
|
quantity = new bigint_t(*amt.quantity);
|
||||||
} else {
|
} else {
|
||||||
quantity = amt.quantity;
|
quantity = amt.quantity;
|
||||||
|
|
@ -208,7 +207,7 @@ void amount_t::_release()
|
||||||
DEBUG("amounts.refs", quantity << " ref--, now " << (quantity->ref - 1));
|
DEBUG("amounts.refs", quantity << " ref--, now " << (quantity->ref - 1));
|
||||||
|
|
||||||
if (--quantity->ref == 0) {
|
if (--quantity->ref == 0) {
|
||||||
if (! (quantity->flags & BIGINT_BULK_ALLOC))
|
if (! (quantity->has_flags(BIGINT_BULK_ALLOC)))
|
||||||
checked_delete(quantity);
|
checked_delete(quantity);
|
||||||
else
|
else
|
||||||
quantity->~bigint_t();
|
quantity->~bigint_t();
|
||||||
|
|
@ -519,7 +518,7 @@ amount_t& amount_t::operator*=(const amount_t& amt)
|
||||||
if (! has_commodity())
|
if (! has_commodity())
|
||||||
commodity_ = amt.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();
|
precision_t comm_prec = commodity().precision();
|
||||||
if (quantity->prec > comm_prec + 6U) {
|
if (quantity->prec > comm_prec + 6U) {
|
||||||
mpz_round(MPZ(quantity), MPZ(quantity), 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
|
// times), then round the number to within the commodity's precision
|
||||||
// plus six places.
|
// 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();
|
precision_t comm_prec = commodity().precision();
|
||||||
if (quantity->prec > comm_prec + 6U) {
|
if (quantity->prec > comm_prec + 6U) {
|
||||||
mpz_round(MPZ(quantity), MPZ(quantity), 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;
|
amount_t t = *this;
|
||||||
|
|
||||||
if (! quantity || quantity->prec <= prec) {
|
if (! quantity || quantity->prec <= prec) {
|
||||||
if (quantity && quantity->flags & BIGINT_KEEP_PREC) {
|
if (quantity && quantity->has_flags(BIGINT_KEEP_PREC)) {
|
||||||
t._dup();
|
t._dup();
|
||||||
t.quantity->flags &= ~BIGINT_KEEP_PREC;
|
t.quantity->drop_flags(BIGINT_KEEP_PREC);
|
||||||
}
|
}
|
||||||
return t;
|
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);
|
mpz_round(MPZ(t.quantity), MPZ(t.quantity), t.quantity->prec, prec);
|
||||||
|
|
||||||
t.quantity->prec = prec;
|
t.quantity->prec = prec;
|
||||||
t.quantity->flags &= ~BIGINT_KEEP_PREC;
|
t.quantity->drop_flags(BIGINT_KEEP_PREC);
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
@ -624,16 +623,16 @@ amount_t amount_t::unround() const
|
||||||
if (! quantity) {
|
if (! quantity) {
|
||||||
amount_t t(0L);
|
amount_t t(0L);
|
||||||
assert(t.quantity);
|
assert(t.quantity);
|
||||||
t.quantity->flags |= BIGINT_KEEP_PREC;
|
t.quantity->add_flags(BIGINT_KEEP_PREC);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
else if (quantity->flags & BIGINT_KEEP_PREC) {
|
else if (quantity->has_flags(BIGINT_KEEP_PREC)) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
amount_t t = *this;
|
amount_t t = *this;
|
||||||
t._dup();
|
t._dup();
|
||||||
t.quantity->flags |= BIGINT_KEEP_PREC;
|
t.quantity->add_flags(BIGINT_KEEP_PREC);
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
@ -674,18 +673,18 @@ int amount_t::sign() const
|
||||||
return quantity ? mpz_sgn(MPZ(quantity)) : 0;
|
return quantity ? mpz_sgn(MPZ(quantity)) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool amount_t::zero() const
|
bool amount_t::is_zero() const
|
||||||
{
|
{
|
||||||
if (! quantity)
|
if (! quantity)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (has_commodity()) {
|
if (has_commodity()) {
|
||||||
if (quantity->prec <= commodity().precision())
|
if (quantity->prec <= commodity().precision())
|
||||||
return realzero();
|
return is_realzero();
|
||||||
else
|
else
|
||||||
return round(commodity().precision()).sign() == 0;
|
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:
|
// The possible syntax for an amount is:
|
||||||
//
|
//
|
||||||
|
|
@ -954,9 +953,10 @@ void amount_t::parse(std::istream& in, flags_t flags)
|
||||||
string symbol;
|
string symbol;
|
||||||
string quant;
|
string quant;
|
||||||
annotation_t details;
|
annotation_t details;
|
||||||
unsigned int comm_flags = COMMODITY_STYLE_DEFAULTS;
|
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
|
|
||||||
|
commodity_t::flags_t comm_flags = COMMODITY_STYLE_DEFAULTS;
|
||||||
|
|
||||||
char c = peek_next_nonws(in);
|
char c = peek_next_nonws(in);
|
||||||
if (c == '-') {
|
if (c == '-') {
|
||||||
negative = true;
|
negative = true;
|
||||||
|
|
@ -1007,15 +1007,15 @@ void amount_t::parse(std::istream& in, flags_t flags)
|
||||||
if (symbol.empty()) {
|
if (symbol.empty()) {
|
||||||
commodity_ = NULL;
|
commodity_ = NULL;
|
||||||
} else {
|
} else {
|
||||||
commodity_ = default_pool->find(symbol);
|
commodity_ = current_pool->find(symbol);
|
||||||
if (! commodity_) {
|
if (! commodity_) {
|
||||||
commodity_ = default_pool->create(symbol);
|
commodity_ = current_pool->create(symbol);
|
||||||
newly_created = true;
|
newly_created = true;
|
||||||
}
|
}
|
||||||
assert(commodity_);
|
assert(commodity_);
|
||||||
|
|
||||||
if (details)
|
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
|
// 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 &&
|
else if (last_comma != string::npos &&
|
||||||
commodity().flags() & COMMODITY_STYLE_EUROPEAN) {
|
commodity().has_flags(COMMODITY_STYLE_EUROPEAN)) {
|
||||||
quantity->prec = quant.length() - last_comma - 1;
|
quantity->prec = quant.length() - last_comma - 1;
|
||||||
}
|
}
|
||||||
else if (last_period != string::npos &&
|
else if (last_period != string::npos &&
|
||||||
! (commodity().flags() & COMMODITY_STYLE_EUROPEAN)) {
|
! (commodity().has_flags(COMMODITY_STYLE_EUROPEAN))) {
|
||||||
quantity->prec = quant.length() - last_period - 1;
|
quantity->prec = quant.length() - last_period - 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -1048,14 +1048,18 @@ void amount_t::parse(std::istream& in, flags_t flags)
|
||||||
// Set the commodity's flags and precision accordingly
|
// Set the commodity's flags and precision accordingly
|
||||||
|
|
||||||
if (commodity_ &&
|
if (commodity_ &&
|
||||||
(newly_created || ! (flags & AMOUNT_PARSE_NO_MIGRATE))) {
|
(newly_created || ! (tflags & AMOUNT_PARSE_NO_MIGRATE))) {
|
||||||
commodity().add_flags(comm_flags);
|
commodity().add_flags(comm_flags);
|
||||||
if (quantity->prec > commodity().precision())
|
if (quantity->prec > commodity().precision())
|
||||||
commodity().set_precision(quantity->prec);
|
commodity().set_precision(quantity->prec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & AMOUNT_PARSE_NO_MIGRATE)
|
// Setup the amount's own flags
|
||||||
quantity->flags |= BIGINT_KEEP_PREC;
|
|
||||||
|
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
|
// Now we have the final number. Remove commas and periods, if
|
||||||
// necessary.
|
// necessary.
|
||||||
|
|
@ -1082,7 +1086,7 @@ void amount_t::parse(std::istream& in, flags_t flags)
|
||||||
if (negative)
|
if (negative)
|
||||||
in_place_negate();
|
in_place_negate();
|
||||||
|
|
||||||
if (! (flags & AMOUNT_PARSE_NO_REDUCE))
|
if (! has_flags(AMOUNT_PARSE_NO_REDUCE))
|
||||||
in_place_reduce();
|
in_place_reduce();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1132,7 +1136,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
|
||||||
precision_t precision = 0;
|
precision_t precision = 0;
|
||||||
|
|
||||||
if (quantity) {
|
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_ui_pow_ui(divisor, 10, base.quantity->prec);
|
||||||
mpz_tdiv_qr(quotient, remainder, MPZ(base.quantity), divisor);
|
mpz_tdiv_qr(quotient, remainder, MPZ(base.quantity), divisor);
|
||||||
precision = base.quantity->prec;
|
precision = base.quantity->prec;
|
||||||
|
|
@ -1171,10 +1175,10 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
|
||||||
mpz_set(rquotient, remainder);
|
mpz_set(rquotient, remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! omit_commodity && ! (comm.flags() & COMMODITY_STYLE_SUFFIXED)) {
|
if (! omit_commodity && ! comm.has_flags(COMMODITY_STYLE_SUFFIXED)) {
|
||||||
comm.write(out);
|
comm.write(out);
|
||||||
|
|
||||||
if (comm.flags() & COMMODITY_STYLE_SEPARATED)
|
if (comm.has_flags(COMMODITY_STYLE_SEPARATED))
|
||||||
out << " ";
|
out << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1184,7 +1188,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
|
||||||
if (! quantity || mpz_sgn(quotient) == 0) {
|
if (! quantity || mpz_sgn(quotient) == 0) {
|
||||||
out << '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);
|
char * p = mpz_get_str(NULL, 10, quotient);
|
||||||
out << p;
|
out << p;
|
||||||
std::free(p);
|
std::free(p);
|
||||||
|
|
@ -1213,7 +1217,7 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
|
||||||
i != strs.rend();
|
i != strs.rend();
|
||||||
i++) {
|
i++) {
|
||||||
if (printed) {
|
if (printed) {
|
||||||
out << (comm.flags() & COMMODITY_STYLE_EUROPEAN ? '.' : ',');
|
out << (comm.has_flags(COMMODITY_STYLE_EUROPEAN) ? '.' : ',');
|
||||||
out.width(3);
|
out.width(3);
|
||||||
out.fill('0');
|
out.fill('0');
|
||||||
}
|
}
|
||||||
|
|
@ -1250,13 +1254,13 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
|
||||||
if (omit_commodity)
|
if (omit_commodity)
|
||||||
out << '.';
|
out << '.';
|
||||||
else
|
else
|
||||||
out << ((comm.flags() & COMMODITY_STYLE_EUROPEAN) ? ',' : '.');
|
out << (comm.has_flags(COMMODITY_STYLE_EUROPEAN) ? ',' : '.');
|
||||||
out << ender;
|
out << ender;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! omit_commodity && comm.flags() & COMMODITY_STYLE_SUFFIXED) {
|
if (! omit_commodity && comm.has_flags(COMMODITY_STYLE_SUFFIXED)) {
|
||||||
if (comm.flags() & COMMODITY_STYLE_SEPARATED)
|
if (comm.has_flags(COMMODITY_STYLE_SEPARATED))
|
||||||
out << " ";
|
out << " ";
|
||||||
|
|
||||||
comm.write(out);
|
comm.write(out);
|
||||||
|
|
@ -1292,9 +1296,9 @@ void amount_t::read(std::istream& in)
|
||||||
if (ident == 0xffffffff)
|
if (ident == 0xffffffff)
|
||||||
commodity_ = NULL;
|
commodity_ = NULL;
|
||||||
else if (ident == 0)
|
else if (ident == 0)
|
||||||
commodity_ = default_pool->null_commodity;
|
commodity_ = current_pool->null_commodity;
|
||||||
else {
|
else {
|
||||||
commodity_ = default_pool->find(ident - 1);
|
commodity_ = current_pool->find(ident - 1);
|
||||||
assert(commodity_);
|
assert(commodity_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1308,9 +1312,9 @@ void amount_t::read(char *& data)
|
||||||
if (ident == 0xffffffff)
|
if (ident == 0xffffffff)
|
||||||
commodity_ = NULL;
|
commodity_ = NULL;
|
||||||
else if (ident == 0)
|
else if (ident == 0)
|
||||||
commodity_ = default_pool->null_commodity;
|
commodity_ = current_pool->null_commodity;
|
||||||
else {
|
else {
|
||||||
commodity_ = default_pool->find(ident - 1);
|
commodity_ = current_pool->find(ident - 1);
|
||||||
assert(commodity_);
|
assert(commodity_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1357,9 +1361,9 @@ void amount_t::read_quantity(char *& data)
|
||||||
|
|
||||||
quantity->prec = *((precision_t *) data);
|
quantity->prec = *((precision_t *) data);
|
||||||
data += sizeof(precision_t);
|
data += sizeof(precision_t);
|
||||||
quantity->flags = *((flags_t *) data);
|
quantity->set_flags(*((flags_t *) data));
|
||||||
data += sizeof(flags_t);
|
data += sizeof(flags_t);
|
||||||
quantity->flags |= BIGINT_BULK_ALLOC;
|
quantity->add_flags(BIGINT_BULK_ALLOC);
|
||||||
} else {
|
} else {
|
||||||
uint_fast32_t index = *((uint_fast32_t *) data);
|
uint_fast32_t index = *((uint_fast32_t *) data);
|
||||||
data += sizeof(uint_fast32_t);
|
data += sizeof(uint_fast32_t);
|
||||||
|
|
@ -1399,7 +1403,10 @@ void amount_t::read_quantity(std::istream& in)
|
||||||
mpz_neg(MPZ(quantity), MPZ(quantity));
|
mpz_neg(MPZ(quantity), MPZ(quantity));
|
||||||
|
|
||||||
in.read((char *)&quantity->prec, sizeof(quantity->prec));
|
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 {
|
else {
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
@ -1436,9 +1443,9 @@ void amount_t::write_quantity(std::ostream& out) const
|
||||||
out.write(&byte, sizeof(byte));
|
out.write(&byte, sizeof(byte));
|
||||||
|
|
||||||
out.write((char *)&quantity->prec, sizeof(quantity->prec));
|
out.write((char *)&quantity->prec, sizeof(quantity->prec));
|
||||||
flags_t flags = quantity->flags & ~BIGINT_BULK_ALLOC;
|
bigint_t::flags_t tflags = quantity->flags() & ~BIGINT_BULK_ALLOC;
|
||||||
assert(sizeof(flags) == sizeof(quantity->flags));
|
assert(sizeof(tflags) == sizeof(bigint_t::flags_t));
|
||||||
out.write((char *)&flags, sizeof(flags));
|
out.write((char *)&tflags, sizeof(tflags));
|
||||||
} else {
|
} else {
|
||||||
assert(quantity->ref > 1);
|
assert(quantity->ref > 1);
|
||||||
|
|
||||||
|
|
|
||||||
59
src/amount.h
59
src/amount.h
|
|
@ -71,7 +71,8 @@ DECLARE_EXCEPTION(amount_error);
|
||||||
* degree.
|
* degree.
|
||||||
*/
|
*/
|
||||||
class amount_t
|
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, long,
|
||||||
ordered_field_operators<amount_t, unsigned long,
|
ordered_field_operators<amount_t, unsigned long,
|
||||||
ordered_field_operators<amount_t, double> > > >
|
ordered_field_operators<amount_t, double> > > >
|
||||||
|
|
@ -91,10 +92,10 @@ public:
|
||||||
typedef uint_least16_t precision_t;
|
typedef uint_least16_t precision_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default_pool is a static variable indicating which commodity
|
* The current_pool is a static variable indicating which commodity
|
||||||
* pool should be used when none is specified.
|
* pool should be used.
|
||||||
*/
|
*/
|
||||||
static commodity_pool_t * default_pool;
|
static commodity_pool_t * current_pool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `keep_base' member determines whether scalable commodities
|
* The `keep_base' member determines whether scalable commodities
|
||||||
|
|
@ -130,15 +131,15 @@ public:
|
||||||
static bool keep_tag;
|
static bool keep_tag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `full-strings' static member is currently only used by the
|
* The `stream_fullstrings' static member is currently only used by
|
||||||
* unit testing code. It causes amounts written to streams to use
|
* the unit testing code. It causes amounts written to streams to
|
||||||
* the `to_fullstring' method rather than the `to_string' method, so
|
* use the `to_fullstring' method rather than the `to_string'
|
||||||
* that complete precision is always displayed, no matter what the
|
* method, so that complete precision is always displayed, no matter
|
||||||
* precision of an individual commodity might be.
|
* what the precision of an individual commodity might be.
|
||||||
* @see to_string
|
* @see to_string
|
||||||
* @see to_fullstring
|
* @see to_fullstring
|
||||||
*/
|
*/
|
||||||
static bool full_strings;
|
static bool stream_fullstrings;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _init();
|
void _init();
|
||||||
|
|
@ -372,14 +373,14 @@ public:
|
||||||
* amount -- using its internal precision -- and not the display
|
* amount -- using its internal precision -- and not the display
|
||||||
* value. To test its display value, use: `round().sign()'.
|
* value. To test its display value, use: `round().sign()'.
|
||||||
*
|
*
|
||||||
* nonzero(), or operator bool, returns true if an amount's display
|
* is_nonzero(), or operator bool, returns true if an amount's
|
||||||
* value is not zero.
|
* display value is not zero.
|
||||||
*
|
*
|
||||||
* zero() returns true if an amount's display value is zero. Thus,
|
* is_zero() returns true if an amount's display value is zero.
|
||||||
* $0.0001 is considered zero().
|
* Thus, $0.0001 is considered zero().
|
||||||
*
|
*
|
||||||
* realzero() returns true if an amount's actual value is zero.
|
* is_realzero() returns true if an amount's actual value is zero.
|
||||||
* $0.0001 is not considered realzero().
|
* $0.0001 is not considered is_realzero().
|
||||||
*
|
*
|
||||||
* is_null() returns true if an amount has no value and no
|
* is_null() returns true if an amount has no value and no
|
||||||
* commodity. This occurs only if an unitialized amount has never
|
* commodity. This occurs only if an unitialized amount has never
|
||||||
|
|
@ -388,14 +389,14 @@ public:
|
||||||
int sign() const;
|
int sign() const;
|
||||||
|
|
||||||
operator bool() const {
|
operator bool() const {
|
||||||
return nonzero();
|
return is_nonzero();
|
||||||
}
|
}
|
||||||
bool nonzero() const {
|
bool is_nonzero() const {
|
||||||
return ! zero();
|
return ! is_zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool zero() const;
|
bool is_zero() const;
|
||||||
bool realzero() const {
|
bool is_realzero() const {
|
||||||
return sign() == 0;
|
return sign() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -550,12 +551,10 @@ public:
|
||||||
#define AMOUNT_PARSE_NO_MIGRATE 0x01
|
#define AMOUNT_PARSE_NO_MIGRATE 0x01
|
||||||
#define AMOUNT_PARSE_NO_REDUCE 0x02
|
#define AMOUNT_PARSE_NO_REDUCE 0x02
|
||||||
|
|
||||||
typedef uint_least8_t flags_t;
|
void parse(std::istream& in, flags_t bits = 0);
|
||||||
|
void parse(const string& str, flags_t bits = 0) {
|
||||||
void parse(std::istream& in, flags_t flags = 0);
|
|
||||||
void parse(const string& str, flags_t flags = 0) {
|
|
||||||
std::istringstream stream(str);
|
std::istringstream stream(str);
|
||||||
parse(stream, flags);
|
parse(stream, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_conversion(const string& larger_str,
|
static void parse_conversion(const string& larger_str,
|
||||||
|
|
@ -588,9 +587,9 @@ public:
|
||||||
* read(istream) reads an amount from the given input stream. It
|
* read(istream) reads an amount from the given input stream. It
|
||||||
* must have been put there using `write(ostream)'. The required
|
* must have been put there using `write(ostream)'. The required
|
||||||
* flow of logic is:
|
* flow of logic is:
|
||||||
* amount_t::default_pool->write(out)
|
* amount_t::current_pool->write(out)
|
||||||
* amount.write(out) // write out all amounts
|
* amount.write(out) // write out all amounts
|
||||||
* amount_t::default_pool->read(in)
|
* amount_t::current_pool->read(in)
|
||||||
* amount.read(in)
|
* amount.read(in)
|
||||||
*
|
*
|
||||||
* read(char *&) reads an amount from data which has been read from
|
* 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) {
|
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;
|
return out;
|
||||||
}
|
}
|
||||||
inline std::istream& operator>>(std::istream& in, amount_t& amt) {
|
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 {
|
inline commodity_t& amount_t::commodity() const {
|
||||||
// jww (2007-05-02): Should be a way to access null_commodity better
|
// 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
|
} // namespace ledger
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,11 @@ namespace ledger {
|
||||||
|
|
||||||
balance_t& balance_t::operator*=(const balance_t& bal)
|
balance_t& balance_t::operator*=(const balance_t& bal)
|
||||||
{
|
{
|
||||||
if (realzero() || bal.realzero()) {
|
if (is_realzero()) {
|
||||||
return *this = amount_t();
|
return *this;
|
||||||
|
}
|
||||||
|
else if (bal.is_realzero()) {
|
||||||
|
return *this = bal;
|
||||||
}
|
}
|
||||||
else if (bal.amounts.size() == 1) {
|
else if (bal.amounts.size() == 1) {
|
||||||
return *this *= (*bal.amounts.begin()).second;
|
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)
|
balance_t& balance_t::operator*=(const amount_t& amt)
|
||||||
{
|
{
|
||||||
if (realzero() || amt.realzero()) {
|
if (is_realzero()) {
|
||||||
return *this = amount_t();
|
return *this;
|
||||||
|
}
|
||||||
|
else if (amt.is_realzero()) {
|
||||||
|
return *this = amt;
|
||||||
}
|
}
|
||||||
else if (! amt.commodity()) {
|
else if (! amt.commodity()) {
|
||||||
// Multiplying by the null commodity causes all amounts to be
|
// 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)
|
balance_t& balance_t::operator/=(const balance_t& bal)
|
||||||
{
|
{
|
||||||
if (bal.realzero()) {
|
if (bal.is_realzero()) {
|
||||||
throw_(amount_error, "Divide by zero: " << *this << " / " << bal);
|
throw_(amount_error, "Divide by zero: " << *this << " / " << bal);
|
||||||
}
|
}
|
||||||
else if (realzero()) {
|
else if (is_realzero()) {
|
||||||
return *this = amount_t();
|
return *this;
|
||||||
}
|
}
|
||||||
else if (bal.amounts.size() == 1) {
|
else if (bal.amounts.size() == 1) {
|
||||||
return *this /= (*bal.amounts.begin()).second;
|
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)
|
balance_t& balance_t::operator/=(const amount_t& amt)
|
||||||
{
|
{
|
||||||
if (amt.realzero()) {
|
if (amt.is_realzero()) {
|
||||||
throw_(amount_error, "Divide by zero: " << *this << " / " << amt);
|
throw_(amount_error, "Divide by zero: " << *this << " / " << amt);
|
||||||
}
|
}
|
||||||
else if (realzero()) {
|
else if (is_realzero()) {
|
||||||
return *this = amount_t();
|
return *this;
|
||||||
}
|
}
|
||||||
else if (! amt.commodity()) {
|
else if (! amt.commodity()) {
|
||||||
// Dividing by the null commodity causes all amounts to be
|
// Dividing by the null commodity causes all amounts to be
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,7 @@ public:
|
||||||
}
|
}
|
||||||
balance_t(const amount_t& amt) {
|
balance_t(const amount_t& amt) {
|
||||||
TRACE_CTOR(balance_t, "const amount_t&");
|
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() {
|
~balance_t() {
|
||||||
TRACE_DTOR(balance_t);
|
TRACE_DTOR(balance_t);
|
||||||
|
|
@ -139,13 +138,13 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool realzero() const {
|
bool is_realzero() const {
|
||||||
if (amounts.size() == 0)
|
if (amounts.size() == 0)
|
||||||
return true;
|
return true;
|
||||||
for (amounts_map::const_iterator i = amounts.begin();
|
for (amounts_map::const_iterator i = amounts.begin();
|
||||||
i != amounts.end();
|
i != amounts.end();
|
||||||
i++)
|
i++)
|
||||||
if (! (*i).second.realzero())
|
if (! (*i).second.is_realzero())
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -324,8 +323,8 @@ public:
|
||||||
return quantity;
|
return quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool realzero() const {
|
bool is_realzero() const {
|
||||||
return ((! cost || cost->realzero()) && quantity.realzero());
|
return ((! cost || cost->is_realzero()) && quantity.is_realzero());
|
||||||
}
|
}
|
||||||
|
|
||||||
balance_pair_t abs() const {
|
balance_pair_t abs() const {
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,9 @@ public:
|
||||||
void set_flags(flags_t arg) {
|
void set_flags(flags_t arg) {
|
||||||
base->flags = arg;
|
base->flags = arg;
|
||||||
}
|
}
|
||||||
|
bool has_flags(flags_t arg) {
|
||||||
|
return base->flags & arg;
|
||||||
|
}
|
||||||
void add_flags(flags_t arg) {
|
void add_flags(flags_t arg) {
|
||||||
base->flags |= arg;
|
base->flags |= arg;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
38
src/flags.h
Normal file
38
src/flags.h
Normal file
|
|
@ -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
|
||||||
|
|
@ -191,7 +191,7 @@ void dataHandler(void *userData, const char *s, int len)
|
||||||
string symbol(s, len);
|
string symbol(s, len);
|
||||||
if (symbol == "USD") symbol = "$";
|
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);
|
assert(parser->curr_comm);
|
||||||
|
|
||||||
if (symbol != "$")
|
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
|
// GnuCash uses the USD commodity without defining it, which really
|
||||||
// means $.
|
// 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->set_precision(2);
|
||||||
usd->add_flags(COMMODITY_STYLE_THOUSANDS);
|
usd->add_flags(COMMODITY_STYLE_THOUSANDS);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,15 +146,15 @@ bool entry_base_t::finalize()
|
||||||
// the balance. This is done for the last eligible commodity.
|
// the balance. This is done for the last eligible commodity.
|
||||||
|
|
||||||
if (! saw_null && balance && balance.type == value_t::BALANCE &&
|
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();
|
transactions_list::const_iterator x = transactions.begin();
|
||||||
assert((*x)->amount);
|
assert((*x)->amount);
|
||||||
commodity_t& this_comm = (*x)->amount->commodity();
|
commodity_t& this_comm = (*x)->amount->commodity();
|
||||||
|
|
||||||
balance_t::amounts_map::const_iterator this_bal =
|
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_t::amounts_map::const_iterator other_bal =
|
||||||
balance.balance().amounts.begin();
|
balance.to_balance().amounts.begin();
|
||||||
if (this_bal == other_bal)
|
if (this_bal == other_bal)
|
||||||
other_bal++;
|
other_bal++;
|
||||||
|
|
||||||
|
|
@ -209,12 +209,12 @@ bool entry_base_t::finalize()
|
||||||
balance_t * bal = NULL;
|
balance_t * bal = NULL;
|
||||||
switch (balance.type) {
|
switch (balance.type) {
|
||||||
case value_t::BALANCE_PAIR:
|
case value_t::BALANCE_PAIR:
|
||||||
bal = &balance.balance_pair().quantity;
|
bal = &balance.to_balance_pair().quantity;
|
||||||
// fall through...
|
// fall through...
|
||||||
|
|
||||||
case value_t::BALANCE:
|
case value_t::BALANCE:
|
||||||
if (! bal)
|
if (! bal)
|
||||||
bal = &balance.balance();
|
bal = &balance.to_balance();
|
||||||
|
|
||||||
if (bal->amounts.size() < 2) {
|
if (bal->amounts.size() < 2) {
|
||||||
balance.cast(value_t::AMOUNT);
|
balance.cast(value_t::AMOUNT);
|
||||||
|
|
@ -243,7 +243,7 @@ bool entry_base_t::finalize()
|
||||||
// fall through...
|
// fall through...
|
||||||
|
|
||||||
case value_t::AMOUNT:
|
case value_t::AMOUNT:
|
||||||
(*x)->amount = balance.amount().negate();
|
(*x)->amount = balance.to_amount().negate();
|
||||||
(*x)->flags |= TRANSACTION_CALCULATED;
|
(*x)->flags |= TRANSACTION_CALCULATED;
|
||||||
|
|
||||||
balance += *(*x)->amount;
|
balance += *(*x)->amount;
|
||||||
|
|
|
||||||
|
|
@ -175,10 +175,10 @@ void export_amount()
|
||||||
.def("value", py_value_2)
|
.def("value", py_value_2)
|
||||||
|
|
||||||
.def("sign", &amount_t::sign)
|
.def("sign", &amount_t::sign)
|
||||||
.def("__nonzero__", &amount_t::nonzero)
|
.def("__nonzero__", &amount_t::is_nonzero)
|
||||||
.def("nonzero", &amount_t::nonzero)
|
.def("nonzero", &amount_t::is_nonzero)
|
||||||
.def("zero", &amount_t::zero)
|
.def("zero", &amount_t::is_zero)
|
||||||
.def("realzero", &amount_t::realzero)
|
.def("realzero", &amount_t::is_realzero)
|
||||||
.def("is_null", &amount_t::is_null)
|
.def("is_null", &amount_t::is_null)
|
||||||
|
|
||||||
.def("to_double", &amount_t::to_double)
|
.def("to_double", &amount_t::to_double)
|
||||||
|
|
|
||||||
|
|
@ -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()));
|
result = static_cast<const value_t&>(extract<value_t>(func.ptr()));
|
||||||
} else {
|
} else {
|
||||||
assert(locals->args.type == value_t::SEQUENCE);
|
assert(locals->args.type == value_t::SEQUENCE);
|
||||||
if (locals->args.sequence()->size() > 0) {
|
if (locals->args.to_sequence()->size() > 0) {
|
||||||
list arglist;
|
list arglist;
|
||||||
for (value_t::sequence_t::iterator
|
for (value_t::sequence_t::iterator
|
||||||
i = locals->args.sequence()->begin();
|
i = locals->args.to_sequence()->begin();
|
||||||
i != locals->args.sequence()->end();
|
i != locals->args.to_sequence()->end();
|
||||||
i++)
|
i++)
|
||||||
arglist.append(*i);
|
arglist.append(*i);
|
||||||
|
|
||||||
|
|
@ -155,10 +155,10 @@ void python_interpreter_t::lambda_t::operator()(value_t& result,
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
assert(locals->args.type == value_t::SEQUENCE);
|
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];
|
value_t item = locals->args[0];
|
||||||
assert(item.type == value_t::POINTER);
|
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&) {
|
catch (const error_already_set&) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
unsigned char prec = xact->amount->commodity().precision();
|
unsigned char prec = xact->amount->commodity().precision();
|
||||||
|
|
||||||
if (! def_commodity) {
|
if (! def_commodity) {
|
||||||
def_commodity = amount_t::default_pool->find_or_create("$");
|
def_commodity = amount_t::current_pool->find_or_create("$");
|
||||||
assert(def_commodity);
|
assert(def_commodity);
|
||||||
}
|
}
|
||||||
xact->amount->set_commodity(*def_commodity);
|
xact->amount->set_commodity(*def_commodity);
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,16 @@ void report_t::abbrev(value_t& result, xml::xpath_t::scope_t * locals)
|
||||||
if (locals->args.size() < 2)
|
if (locals->args.size() < 2)
|
||||||
throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
|
throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
|
||||||
|
|
||||||
string str = locals->args[0].string_value();
|
string str = locals->args[0].to_string();
|
||||||
long wid = locals->args[1];
|
long wid = locals->args[1];
|
||||||
|
|
||||||
elision_style_t style = session->elision_style;
|
elision_style_t style = session->elision_style;
|
||||||
if (locals->args.size() == 3)
|
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;
|
long abbrev_len = session->abbrev_length;
|
||||||
if (locals->args.size() == 4)
|
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));
|
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)
|
if (locals->args.size() < 1)
|
||||||
throw_(std::logic_error, "usage: ftime(DATE [, DATE_FORMAT])");
|
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;
|
string date_format;
|
||||||
if (locals->args.size() == 2)
|
if (locals->args.size() == 2)
|
||||||
date_format = locals->args[1].string_value();
|
date_format = locals->args[1].to_string();
|
||||||
#if 0
|
#if 0
|
||||||
// jww (2007-04-18): Need to setup an output facet here
|
// jww (2007-04-18): Need to setup an output facet here
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -60,18 +60,18 @@ class report_t : public xml::xpath_t::scope_t
|
||||||
xml::xpath_t(expr).compile((xml::document_t *)NULL, this);
|
xml::xpath_t(expr).compile((xml::document_t *)NULL, this);
|
||||||
}
|
}
|
||||||
void option_eval(value_t&, xml::xpath_t::scope_t * locals) {
|
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) {
|
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) {
|
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) {
|
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&) {
|
void option_raw(value_t&) {
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ class session_t : public xml::xpath_t::scope_t
|
||||||
//
|
//
|
||||||
|
|
||||||
void option_file(value_t&, xml::xpath_t::scope_t * locals) {
|
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
|
#if 0
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ parse_amount_expr(std::istream& in, journal_t *,
|
||||||
}
|
}
|
||||||
#endif
|
#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 << ": " <<
|
DEBUG("ledger.textual.parse", "line " << linenum << ": " <<
|
||||||
"The transaction amount is " << amount);
|
"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"
|
case 'D': { // a default commodity for "entry"
|
||||||
amount_t amt(skip_ws(line + 1));
|
amount_t amt(skip_ws(line + 1));
|
||||||
amount_t::default_pool->default_commodity = &amt.commodity();
|
amount_t::current_pool->default_commodity = &amt.commodity();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -757,7 +757,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
amount_t price(symbol_and_price);
|
amount_t price(symbol_and_price);
|
||||||
|
|
||||||
if (commodity_t * commodity =
|
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);
|
commodity->add_price(datetime, price);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -768,7 +768,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
parse_symbol(p, symbol);
|
parse_symbol(p, symbol);
|
||||||
|
|
||||||
if (commodity_t * commodity =
|
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);
|
commodity->add_flags(COMMODITY_STYLE_NOMARKET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -445,6 +445,13 @@ inline void throw_unexpected_error(char c, char wanted) {
|
||||||
|
|
||||||
#include "times.h"
|
#include "times.h"
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
*
|
||||||
|
* General support for objects with "flags"
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flags.h"
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
*
|
*
|
||||||
* General utility functions
|
* General utility functions
|
||||||
|
|
|
||||||
36
src/value.cc
36
src/value.cc
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
bool& value_t::boolean()
|
bool& value_t::to_boolean()
|
||||||
{
|
{
|
||||||
if (type == BOOLEAN) {
|
if (type == BOOLEAN) {
|
||||||
return *(bool *) data;
|
return *(bool *) data;
|
||||||
|
|
@ -15,7 +15,7 @@ bool& value_t::boolean()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long& value_t::integer()
|
long& value_t::to_long()
|
||||||
{
|
{
|
||||||
if (type == INTEGER) {
|
if (type == INTEGER) {
|
||||||
return *(long *) data;
|
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) {
|
if (type == DATETIME) {
|
||||||
return *(moment_t *) data;
|
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) {
|
if (type == AMOUNT) {
|
||||||
return *(amount_t *) data;
|
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) {
|
if (type == BALANCE) {
|
||||||
return *(balance_t *) data;
|
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) {
|
if (type == BALANCE_PAIR) {
|
||||||
return *(balance_pair_t *) data;
|
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) {
|
if (type == STRING) {
|
||||||
return **(string **) data;
|
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)
|
if (type == XML_NODE)
|
||||||
return *(xml::node_t **) data;
|
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");
|
throw_(value_error, "Value is not an XML node");
|
||||||
}
|
}
|
||||||
|
|
||||||
void *& value_t::pointer()
|
void *& value_t::to_pointer()
|
||||||
{
|
{
|
||||||
if (type == POINTER)
|
if (type == POINTER)
|
||||||
return *(void **) data;
|
return *(void **) data;
|
||||||
|
|
@ -105,7 +105,7 @@ void *& value_t::pointer()
|
||||||
throw_(value_error, "Value is not a 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)
|
if (type == SEQUENCE)
|
||||||
return *(sequence_t **) data;
|
return *(sequence_t **) data;
|
||||||
|
|
@ -138,7 +138,7 @@ void value_t::destroy()
|
||||||
|
|
||||||
void value_t::simplify()
|
void value_t::simplify()
|
||||||
{
|
{
|
||||||
if (realzero()) {
|
if (is_realzero()) {
|
||||||
DEBUG("amounts.values.simplify", "Zeroing type " << type);
|
DEBUG("amounts.values.simplify", "Zeroing type " << type);
|
||||||
*this = 0L;
|
*this = 0L;
|
||||||
return;
|
return;
|
||||||
|
|
@ -146,7 +146,7 @@ void value_t::simplify()
|
||||||
|
|
||||||
if (type == BALANCE_PAIR &&
|
if (type == BALANCE_PAIR &&
|
||||||
(! ((balance_pair_t *) data)->cost ||
|
(! ((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");
|
DEBUG("amounts.values.simplify", "Reducing balance pair to balance");
|
||||||
in_place_cast(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
|
else if (val.type == XML_NODE) // recurse
|
||||||
return *this *= (*(xml::node_t **) val.data)->to_value();
|
return *this *= (*(xml::node_t **) val.data)->to_value();
|
||||||
|
|
||||||
if (val.realzero() && type != STRING) {
|
if (val.is_realzero() && type != STRING) {
|
||||||
*this = 0L;
|
*this = 0L;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -893,7 +893,7 @@ value_t::operator bool() const
|
||||||
case STRING:
|
case STRING:
|
||||||
return ! (**((string **) data)).empty();
|
return ! (**((string **) data)).empty();
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
return (*(xml::node_t **) data)->to_value().boolean();
|
return (*(xml::node_t **) data)->to_value().to_boolean();
|
||||||
case POINTER:
|
case POINTER:
|
||||||
return *(void **) data != NULL;
|
return *(void **) data != NULL;
|
||||||
case SEQUENCE:
|
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) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
|
@ -1820,11 +1820,11 @@ bool value_t::realzero() const
|
||||||
case DATETIME:
|
case DATETIME:
|
||||||
return ! is_valid_moment(*((moment_t *) data));
|
return ! is_valid_moment(*((moment_t *) data));
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
return ((amount_t *) data)->realzero();
|
return ((amount_t *) data)->is_realzero();
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
return ((balance_t *) data)->realzero();
|
return ((balance_t *) data)->is_realzero();
|
||||||
case BALANCE_PAIR:
|
case BALANCE_PAIR:
|
||||||
return ((balance_pair_t *) data)->realzero();
|
return ((balance_pair_t *) data)->is_realzero();
|
||||||
case STRING:
|
case STRING:
|
||||||
return ((string *) data)->empty();
|
return ((string *) data)->empty();
|
||||||
case XML_NODE:
|
case XML_NODE:
|
||||||
|
|
|
||||||
28
src/value.h
28
src/value.h
|
|
@ -279,31 +279,31 @@ class value_t
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool& boolean();
|
bool& to_boolean();
|
||||||
long& integer();
|
long& to_long();
|
||||||
moment_t& datetime();
|
moment_t& to_datetime();
|
||||||
amount_t& amount();
|
amount_t& to_amount();
|
||||||
balance_t& balance();
|
balance_t& to_balance();
|
||||||
balance_pair_t& balance_pair();
|
balance_pair_t& to_balance_pair();
|
||||||
string& string_value();
|
string& to_string();
|
||||||
xml::node_t *& xml_node();
|
xml::node_t *& to_xml_node();
|
||||||
void *& pointer();
|
void *& to_pointer();
|
||||||
sequence_t *& sequence();
|
sequence_t *& to_sequence();
|
||||||
|
|
||||||
value_t& operator[](const int index) {
|
value_t& operator[](const int index) {
|
||||||
sequence_t * seq = sequence();
|
sequence_t * seq = to_sequence();
|
||||||
assert(seq);
|
assert(seq);
|
||||||
return (*seq)[index];
|
return (*seq)[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void push_back(const value_t& val) {
|
void push_back(const value_t& val) {
|
||||||
sequence_t * seq = sequence();
|
sequence_t * seq = to_sequence();
|
||||||
assert(seq);
|
assert(seq);
|
||||||
return seq->push_back(val);
|
return seq->push_back(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t size() const {
|
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);
|
assert(seq);
|
||||||
return seq->size();
|
return seq->size();
|
||||||
}
|
}
|
||||||
|
|
@ -359,7 +359,7 @@ class value_t
|
||||||
}
|
}
|
||||||
void in_place_negate();
|
void in_place_negate();
|
||||||
|
|
||||||
bool realzero() const;
|
bool is_realzero() const;
|
||||||
value_t abs() const;
|
value_t abs() const;
|
||||||
void in_place_cast(type_t cast_type);
|
void in_place_cast(type_t cast_type);
|
||||||
value_t cost() const;
|
value_t cost() const;
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ static void endElement(void *userData, const char *name)
|
||||||
}
|
}
|
||||||
else if (std::strcmp(name, "symbol") == 0) {
|
else if (std::strcmp(name, "symbol") == 0) {
|
||||||
assert(! curr_comm);
|
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);
|
assert(curr_comm);
|
||||||
curr_comm->add_flags(COMMODITY_STYLE_SUFFIXED);
|
curr_comm->add_flags(COMMODITY_STYLE_SUFFIXED);
|
||||||
if (! comm_flags.empty()) {
|
if (! comm_flags.empty()) {
|
||||||
|
|
|
||||||
34
src/xpath.cc
34
src/xpath.cc
|
|
@ -534,7 +534,7 @@ bool xpath_t::function_scope_t::resolve(const string& name,
|
||||||
case 't':
|
case 't':
|
||||||
if (name == "text") {
|
if (name == "text") {
|
||||||
if (value->type == value_t::XML_NODE)
|
if (value->type == value_t::XML_NODE)
|
||||||
result.set_string(value->xml_node()->text());
|
result.set_string(value->to_xml_node()->text());
|
||||||
else
|
else
|
||||||
throw_(calc_error, "Attempt to call text() on a non-node value");
|
throw_(calc_error, "Attempt to call text() on a non-node value");
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -650,7 +650,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const
|
||||||
#endif /* USE_BOOST_PYTHON */
|
#endif /* USE_BOOST_PYTHON */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
string ident = tok.value.string_value();
|
string ident = tok.value.to_string();
|
||||||
int id = -1;
|
int id = -1;
|
||||||
if (std::isdigit(ident[0])) {
|
if (std::isdigit(ident[0])) {
|
||||||
node.reset(new op_t(op_t::ARG_INDEX));
|
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");
|
throw_(parse_error, "@ symbol must be followed by attribute name");
|
||||||
|
|
||||||
node.reset(new op_t(op_t::ATTR_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;
|
break;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -1184,7 +1184,7 @@ void xpath_t::op_t::find_values(value_t * context, scope_t * scope,
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
if (context->type == value_t::XML_NODE) {
|
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) {
|
if (ptr->flags & XML_NODE_IS_PARENT) {
|
||||||
parent_node_t * parent = static_cast<parent_node_t *>(ptr);
|
parent_node_t * parent = static_cast<parent_node_t *>(ptr);
|
||||||
for (node_t * node = parent->children();
|
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);
|
return *expr->valuep == value_t((long)index + 1);
|
||||||
|
|
||||||
default:
|
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)
|
if ((*i).type != value_t::POINTER)
|
||||||
*opp = wrap_value(*i)->acquire();
|
*opp = wrap_value(*i)->acquire();
|
||||||
else
|
else
|
||||||
*opp = static_cast<op_t *>((*i).pointer());
|
*opp = static_cast<op_t *>((*i).to_pointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
return lit_seq.release();
|
return lit_seq.release();
|
||||||
|
|
@ -1256,7 +1256,7 @@ void xpath_t::op_t::append_value(value_t& val,
|
||||||
value_t::sequence_t& result_seq)
|
value_t::sequence_t& result_seq)
|
||||||
{
|
{
|
||||||
if (val.type == value_t::SEQUENCE) {
|
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();
|
for (value_t::sequence_t::iterator i = subseq->begin();
|
||||||
i != subseq->end();
|
i != subseq->end();
|
||||||
i++)
|
i++)
|
||||||
|
|
@ -1284,8 +1284,8 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
|
||||||
case document_t::PARENT:
|
case document_t::PARENT:
|
||||||
if (context->type != value_t::XML_NODE)
|
if (context->type != value_t::XML_NODE)
|
||||||
throw_(compile_error, "Referencing parent node from a non-node value");
|
throw_(compile_error, "Referencing parent node from a non-node value");
|
||||||
else if (context->xml_node()->parent)
|
else if (context->to_xml_node()->parent)
|
||||||
return wrap_value(context->xml_node()->parent)->acquire();
|
return wrap_value(context->to_xml_node()->parent)->acquire();
|
||||||
else
|
else
|
||||||
throw_(compile_error, "Referencing parent node from the root node");
|
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)
|
if (context->type != value_t::XML_NODE)
|
||||||
throw_(compile_error, "Referencing root node from a non-node value");
|
throw_(compile_error, "Referencing root node from a non-node value");
|
||||||
else
|
else
|
||||||
return wrap_value(context->xml_node()->document->top)->acquire();
|
return wrap_value(context->to_xml_node()->document->top)->acquire();
|
||||||
|
|
||||||
case document_t::ALL: {
|
case document_t::ALL: {
|
||||||
if (context->type != value_t::XML_NODE)
|
if (context->type != value_t::XML_NODE)
|
||||||
throw_(compile_error, "Referencing child nodes from a non-node value");
|
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))
|
if (! (ptr->flags & XML_NODE_IS_PARENT))
|
||||||
throw_(compile_error, "Request for child nodes of a leaf node");
|
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:
|
case NODE_NAME:
|
||||||
if (context->type == value_t::XML_NODE) {
|
if (context->type == value_t::XML_NODE) {
|
||||||
node_t * ptr = context->xml_node();
|
node_t * ptr = context->to_xml_node();
|
||||||
if (resolve) {
|
if (resolve) {
|
||||||
// First, look up the symbol as a node name within the current
|
// First, look up the symbol as a node name within the current
|
||||||
// context. If any exist, then return the set of names.
|
// 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: {
|
case ATTR_NAME: {
|
||||||
// jww (2006-09-29): Attrs should map strings to values, not strings
|
// 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();
|
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:
|
case ARG_INDEX:
|
||||||
if (scope && scope->kind == scope_t::ARGUMENT) {
|
if (scope && scope->kind == scope_t::ARGUMENT) {
|
||||||
assert(scope->args.type == value_t::SEQUENCE);
|
assert(scope->args.type == value_t::SEQUENCE);
|
||||||
if (arg_index < scope->args.sequence()->size())
|
if (arg_index < scope->args.to_sequence()->size())
|
||||||
return wrap_value((*scope->args.sequence())[arg_index])->acquire();
|
return wrap_value((*scope->args.to_sequence())[arg_index])->acquire();
|
||||||
else
|
else
|
||||||
throw_(compile_error, "Reference to non-existing argument");
|
throw_(compile_error, "Reference to non-existing argument");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1815,7 +1815,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::SEQUENCE: {
|
case value_t::SEQUENCE: {
|
||||||
value_t::sequence_t * seq = lexpr->valuep->sequence();
|
value_t::sequence_t * seq = lexpr->valuep->to_sequence();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (value_t::sequence_t::iterator i = seq->begin();
|
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 (! symbol.empty()) {
|
||||||
if (amount_t::default_pool->find(symbol))
|
if (amount_t::current_pool->find(symbol))
|
||||||
out << '@';
|
out << '@';
|
||||||
out << symbol;
|
out << symbol;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -760,7 +760,7 @@ inline std::ostream& operator<<(std::ostream& out, const xpath_t::op_t& op) {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T * get_ptr(xml::xpath_t::scope_t * locals, unsigned int idx) {
|
inline T * get_ptr(xml::xpath_t::scope_t * locals, unsigned int idx) {
|
||||||
assert(locals->args.size() > 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);
|
assert(ptr);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -585,10 +585,10 @@ void BasicAmountTestCase::testForZero()
|
||||||
|
|
||||||
CPPUNIT_ASSERT(! x0);
|
CPPUNIT_ASSERT(! x0);
|
||||||
CPPUNIT_ASSERT(x1);
|
CPPUNIT_ASSERT(x1);
|
||||||
CPPUNIT_ASSERT(x0.zero());
|
CPPUNIT_ASSERT(x0.is_zero());
|
||||||
CPPUNIT_ASSERT(x0.realzero());
|
CPPUNIT_ASSERT(x0.is_realzero());
|
||||||
CPPUNIT_ASSERT(! x1.zero());
|
CPPUNIT_ASSERT(! x1.is_zero());
|
||||||
CPPUNIT_ASSERT(! x1.realzero());
|
CPPUNIT_ASSERT(! x1.is_realzero());
|
||||||
|
|
||||||
CPPUNIT_ASSERT(x0.valid());
|
CPPUNIT_ASSERT(x0.valid());
|
||||||
CPPUNIT_ASSERT(x1.valid());
|
CPPUNIT_ASSERT(x1.valid());
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,12 @@ void CommodityAmountTestCase::setUp()
|
||||||
// Cause the display precision for dollars to be initialized to 2.
|
// Cause the display precision for dollars to be initialized to 2.
|
||||||
amount_t x1("$1.00");
|
amount_t x1("$1.00");
|
||||||
assertTrue(x1);
|
assertTrue(x1);
|
||||||
amount_t::full_strings = true; // makes error reports from UnitTests accurate
|
amount_t::stream_fullstrings = true; // makes error reports from UnitTests accurate
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommodityAmountTestCase::tearDown()
|
void CommodityAmountTestCase::tearDown()
|
||||||
{
|
{
|
||||||
amount_t::full_strings = false;
|
amount_t::stream_fullstrings = false;
|
||||||
|
|
||||||
ledger::set_session_context();
|
ledger::set_session_context();
|
||||||
}
|
}
|
||||||
|
|
@ -185,8 +185,8 @@ void CommodityAmountTestCase::testEquality()
|
||||||
amount_t x10 = "-123.45€";
|
amount_t x10 = "-123.45€";
|
||||||
|
|
||||||
assertTrue(x0.is_null());
|
assertTrue(x0.is_null());
|
||||||
assertTrue(x0.zero());
|
assertTrue(x0.is_zero());
|
||||||
assertTrue(x0.realzero());
|
assertTrue(x0.is_realzero());
|
||||||
assertTrue(x0.sign() == 0);
|
assertTrue(x0.sign() == 0);
|
||||||
assertTrue(x0.compare(x1) < 0);
|
assertTrue(x0.compare(x1) < 0);
|
||||||
assertTrue(x0.compare(x2) > 0);
|
assertTrue(x0.compare(x2) > 0);
|
||||||
|
|
@ -578,8 +578,8 @@ void CommodityAmountTestCase::testForZero()
|
||||||
amount_t x1(internalAmount("$0.000000000000000000001"));
|
amount_t x1(internalAmount("$0.000000000000000000001"));
|
||||||
|
|
||||||
assertFalse(x1);
|
assertFalse(x1);
|
||||||
assertTrue(x1.zero());
|
assertTrue(x1.is_zero());
|
||||||
assertFalse(x1.realzero());
|
assertFalse(x1.is_realzero());
|
||||||
|
|
||||||
assertValid(x1);
|
assertValid(x1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue