summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2007-05-08 00:19:48 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 03:38:40 -0400
commitee4a16743960122bf2b626f62827b7332680ebf5 (patch)
treedab8682d742718a86f0529dd86a0c832ffeb0102
parent30978b7fe5ee93413b2e05b54942f6550832b222 (diff)
downloadfork-ledger-ee4a16743960122bf2b626f62827b7332680ebf5.tar.gz
fork-ledger-ee4a16743960122bf2b626f62827b7332680ebf5.tar.bz2
fork-ledger-ee4a16743960122bf2b626f62827b7332680ebf5.zip
Corrected memory crashes when running the register command.
-rw-r--r--src/balance.h20
-rw-r--r--src/main.cc2
-rw-r--r--src/value.h4
-rw-r--r--src/xmlparse.cc10
-rw-r--r--src/xpath.cc16
5 files changed, 35 insertions, 17 deletions
diff --git a/src/balance.h b/src/balance.h
index 614bffc7..627c3ac6 100644
--- a/src/balance.h
+++ b/src/balance.h
@@ -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);
diff --git a/src/main.cc b/src/main.cc
index e664e8b8..a5ba3690 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -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);
diff --git a/src/value.h b/src/value.h
index eba9f6a0..4f5908b3 100644
--- a/src/value.h
+++ b/src/value.h
@@ -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;
}
diff --git a/src/xmlparse.cc b/src/xmlparse.cc
index 34a16124..ff724dfe 100644
--- a/src/xmlparse.cc
+++ b/src/xmlparse.cc
@@ -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";
diff --git a/src/xpath.cc b/src/xpath.cc
index d4a2fafd..a59126ae 100644
--- a/src/xpath.cc
+++ b/src/xpath.cc
@@ -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) {