diff options
author | John Wiegley <johnw@newartisans.com> | 2007-05-08 00:19:48 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 03:38:40 -0400 |
commit | ee4a16743960122bf2b626f62827b7332680ebf5 (patch) | |
tree | dab8682d742718a86f0529dd86a0c832ffeb0102 | |
parent | 30978b7fe5ee93413b2e05b54942f6550832b222 (diff) | |
download | fork-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.h | 20 | ||||
-rw-r--r-- | src/main.cc | 2 | ||||
-rw-r--r-- | src/value.h | 4 | ||||
-rw-r--r-- | src/xmlparse.cc | 10 | ||||
-rw-r--r-- | src/xpath.cc | 16 |
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) { |