Corrected memory crashes when running the register command.

This commit is contained in:
John Wiegley 2007-05-08 00:19:48 +00:00
parent 30978b7fe5
commit ee4a167439
5 changed files with 35 additions and 17 deletions

View file

@ -111,6 +111,14 @@ public:
*this += (*i).second;
return *this;
}
balance_t& operator+=(const amount_t& amt) {
amounts_map::iterator i = amounts.find(&amt.commodity());
if (i != amounts.end())
(*i).second += amt;
else if (! amt.is_realzero())
amounts.insert(amounts_map::value_type(&amt.commodity(), amt));
return *this;
}
balance_t& operator-=(const balance_t& bal) {
for (amounts_map::const_iterator i = bal.amounts.begin();
i != bal.amounts.end();
@ -118,6 +126,18 @@ public:
*this -= (*i).second;
return *this;
}
balance_t& operator-=(const amount_t& amt) {
amounts_map::iterator i = amounts.find(&amt.commodity());
if (i != amounts.end()) {
(*i).second -= amt;
if ((*i).second.is_realzero())
amounts.erase(i);
}
else if (! amt.is_realzero()) {
amounts.insert(amounts_map::value_type(&amt.commodity(), - amt));
}
return *this;
}
balance_t& operator*=(const amount_t& amt);
balance_t& operator/=(const amount_t& amt);

View file

@ -311,7 +311,7 @@ static int read_and_report(report_t * report, int argc, char * argv[],
std::auto_ptr<xml::xpath_t::scope_t> locals
(new xml::xpath_t::scope_t(report, xml::xpath_t::scope_t::ARGUMENT));
locals->args = new value_t::sequence_t;
locals->args = value_t::sequence_t();
locals->args.push_back(out);
locals->args.push_back(journal->document);

View file

@ -180,8 +180,10 @@ class value_t
if (type != STRING) {
destroy();
type = STRING;
new((string *) data) string(str);
} else {
as_string() = str;
}
as_string() = str;
return *this;
}

View file

@ -329,25 +329,25 @@ void xml_write_value(std::ostream& out, const value_t& value,
switch (value.type) {
case value_t::BOOLEAN:
for (int i = 0; i < depth + 2; i++) out << ' ';
out << "<boolean>" << *((bool *) value.data) << "</boolean>\n";
out << "<boolean>" << value.as_boolean() << "</boolean>\n";
break;
case value_t::INTEGER:
for (int i = 0; i < depth + 2; i++) out << ' ';
out << "<integer>" << *((long *) value.data) << "</integer>\n";
out << "<integer>" << value.as_long() << "</integer>\n";
break;
case value_t::AMOUNT:
xml_write_amount(out, *((amount_t *) value.data), depth + 2);
xml_write_amount(out, value.as_amount(), depth + 2);
break;
case value_t::BALANCE:
bal = (balance_t *) value.data;
bal = &value.as_balance();
// fall through...
case value_t::BALANCE_PAIR:
if (! bal)
bal = &((balance_pair_t *) value.data)->quantity;
bal = &value.as_balance_pair()->quantity;
for (int i = 0; i < depth + 2; i++) out << ' ';
out << "<balance>\n";

View file

@ -1343,7 +1343,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
// First, look up the symbol as a node name within the current
// context. If any exist, then return the set of names.
std::auto_ptr<value_t::sequence_t> nodes(new value_t::sequence_t);
value_t::sequence_t nodes;
if (ptr->has_flags(XML_NODE_IS_PARENT)) {
parent_node_t * parent = static_cast<parent_node_t *>(ptr);
@ -1353,10 +1353,10 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
if ((kind == NODE_NAME &&
std::strcmp(name->c_str(), node->name()) == 0) ||
(kind == NODE_ID && name_id == node->name_id))
nodes->push_back(node);
nodes.push_back(node);
}
}
return wrap_value(nodes.release())->acquire();
return wrap_value(nodes)->acquire();
} else {
assert(ptr);
int id = ptr->document->lookup_name_id(*name);
@ -1745,7 +1745,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
std::auto_ptr<scope_t> call_args(new scope_t(scope));
call_args->kind = scope_t::ARGUMENT;
std::auto_ptr<value_t::sequence_t> call_seq;
value_t::sequence_t call_seq;
op_t * args = right;
while (args) {
@ -1757,16 +1757,12 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
args = NULL;
}
if (! call_seq.get())
call_seq.reset(new value_t::sequence_t);
// jww (2006-09-15): Need to return a reference to these, if
// there are undetermined arguments!
call_seq->push_back(arg->compile(context, scope, resolve)->value());
call_seq.push_back(arg->compile(context, scope, resolve)->value());
}
if (call_seq.get())
call_args->args = call_seq.release();
call_args->args = call_seq;
if (left->kind == FUNC_NAME) {
if (resolve) {