*** empty log message ***

This commit is contained in:
John Wiegley 2006-02-28 03:20:06 +00:00
parent 08ad1f544f
commit a2423f99db
6 changed files with 45 additions and 35 deletions

View file

@ -144,9 +144,12 @@ class balance_t
// multiplication and divide
balance_t& operator*=(const balance_t& bal) {
if (amounts.size() == 1 && bal.amounts.size() == 1)
if (! *this || ! bal)
return (*this = 0L);
else if (amounts.size() == 1 && bal.amounts.size() == 1)
return *this *= (*bal.amounts.begin()).second;
throw amount_error("It makes no sense to multiply two balances");
else
throw amount_error("It makes no sense to multiply two balances");
}
balance_t& operator*=(const amount_t& amt) {
// Multiplying by the null commodity causes all amounts to be
@ -173,9 +176,14 @@ class balance_t
}
balance_t& operator/=(const balance_t& bal) {
if (amounts.size() == 1 && bal.amounts.size() == 1)
if (! *this)
return (*this = 0L);
else if (! bal)
throw amount_error("Attempt to divide by zero");
else if (amounts.size() == 1 && bal.amounts.size() == 1)
return *this /= (*bal.amounts.begin()).second;
throw amount_error("It makes no sense to divide two balances");
else
throw amount_error("It makes no sense to divide two balances");
}
balance_t& operator/=(const amount_t& amt) {
// Dividing by the null commodity causes all amounts to be
@ -428,9 +436,8 @@ class balance_t
balance_t value(const std::time_t moment) const;
balance_t price() const;
void write(std::ostream& out,
const int first_width,
const int latter_width = -1) const;
void write(std::ostream& out, const int first_width,
const int latter_width = -1) const;
void abs() {
for (amounts_map::iterator i = amounts.begin();
@ -563,7 +570,6 @@ class balance_pair_t
else
cost = new balance_t(*bal_pair.cost);
}
return *this;
}
balance_pair_t& operator+=(const balance_t& bal) {
@ -594,7 +600,6 @@ class balance_pair_t
else
cost = new balance_t(- *bal_pair.cost);
}
return *this;
}
balance_pair_t& operator-=(const balance_t& bal) {
@ -677,7 +682,6 @@ class balance_pair_t
cost = NULL;
}
}
return *this;
}
balance_pair_t& operator*=(const balance_t& bal) {
@ -694,21 +698,19 @@ class balance_pair_t
}
balance_pair_t& operator/=(const balance_pair_t& bal_pair) {
quantity /= bal_pair.quantity;
if (bal_pair.quantity)
quantity /= bal_pair.quantity;
else
throw amount_error("Attempt to divide by zero");
if (bal_pair.price) {
if (price)
*price /= *bal_pair.price;
} else {
throw amount_error("Attempt to divide by zero");
}
if (bal_pair.cost) {
if (cost)
*cost /= *bal_pair.cost;
} else {
throw amount_error("Attempt to divide by zero");
}
return *this;
}
balance_pair_t& operator/=(const balance_t& bal) {
@ -899,8 +901,7 @@ class balance_pair_t
balance_pair_t& add(const amount_t& amount,
const amount_t * a_price = NULL,
const amount_t * a_cost = NULL)
{
const amount_t * a_cost = NULL) {
quantity += amount;
if (a_price) {
@ -915,7 +916,6 @@ class balance_pair_t
else
cost = new balance_t(*a_cost);
}
return *this;
}

View file

@ -343,9 +343,9 @@ inline void read_binary_transaction(char *& data, transaction_t * xact)
xact->data = NULL;
if (xact->amount_expr)
compute_amount(xact->amount_expr, xact->amount, *xact);
compute_amount(xact->amount_expr, xact->amount, xact);
if (xact->cost_expr)
compute_amount(xact->cost_expr, *xact->cost, *xact);
compute_amount(xact->cost_expr, *xact->cost, xact);
}
inline void read_binary_entry_base(char *& data, entry_base_t * entry,

View file

@ -164,7 +164,7 @@ value_expr_t * parse_amount(const char * text, amount_t& amt,
if (altbuf)
delete[] altbuf;
if (! compute_amount(expr, amt, xact))
if (! compute_amount(expr, amt, &xact))
throw parse_error(path, linenum, "Value expression yields a balance");
}

View file

@ -19,10 +19,11 @@ details_t::details_t(const transaction_t& _xact)
DEBUG_PRINT("ledger.memory.ctors", "ctor details_t");
}
bool compute_amount(value_expr_t * expr, amount_t& amt, transaction_t& xact)
bool compute_amount(value_expr_t * expr, amount_t& amt,
const transaction_t * xact, value_expr_t * context)
{
value_t result;
expr->compute(result, details_t(xact));
expr->compute(result, xact ? details_t(*xact) : details_t(), context);
switch (result.type) {
case value_t::BOOLEAN:
amt = *((bool *) result.data);
@ -537,11 +538,10 @@ void value_expr_t::compute(value_t& result, const details_t& details,
index = 0;
expr = find_leaf(context, 1, index);
value_t temp;
expr->compute(temp, details, context);
if (expr->kind == CONSTANT_T)
result = result.value(expr->constant_t);
amount_t moment;
if (compute_amount(expr, moment, details.xact, context))
result = result.value((long)moment);
else
throw compute_error("Invalid date passed to P(value,date)");
@ -1279,6 +1279,7 @@ void init_value_expr()
globals->define("P", node);
globals->define("val", node);
globals->define("value", node);
parse_boolean_expr("current_value(x)=P(x,m)", globals);
// Macros
node = parse_value_expr("P(a,d)");

View file

@ -215,10 +215,18 @@ struct scope_t
DEBUG_PRINT("ledger.valexpr.syms",
"Defining '" << name << "' = " << def);
std::pair<symbol_map::iterator, bool> result
= symbols.insert(symbol_pair(name, def->acquire()));
if (! result.second)
throw value_expr_error(std::string("Redefinition of '") +
name + "' in same scope");
= symbols.insert(symbol_pair(name, def));
if (! result.second) {
symbols.erase(name);
std::pair<symbol_map::iterator, bool> result
= symbols.insert(symbol_pair(name, def));
if (! result.second) {
def->release();
throw value_expr_error(std::string("Redefinition of '") +
name + "' in same scope");
}
}
def->acquire();
}
value_expr_t * lookup(const std::string& name) {
symbol_map::const_iterator i = symbols.find(name);
@ -237,7 +245,9 @@ extern bool initialized;
void init_value_expr();
bool compute_amount(value_expr_t * expr, amount_t& amt, transaction_t& xact);
bool compute_amount(value_expr_t * expr, amount_t& amt,
const transaction_t * xact,
value_expr_t * context = NULL);
struct scope_t;
value_expr_t * parse_boolean_expr(std::istream& in, scope_t * scope);

View file

@ -733,11 +733,10 @@ value_t value_t::price() const
return *this;
case BALANCE_PAIR:
assert(((balance_pair_t *) data)->price);
if (((balance_pair_t *) data)->price)
return *(((balance_pair_t *) data)->price);
else
return ((balance_pair_t *) data)->quantity;
return 0L;
default:
assert(0);