diff options
author | John Wiegley <johnw@newartisans.com> | 2007-05-19 07:34:52 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 03:39:05 -0400 |
commit | 3e0f510b296c0b72353f146912bb0225af0a5647 (patch) | |
tree | 8ff4098ea790bbaf2b26a13d1b76487fe80b6041 | |
parent | 5a72d17d026aa6a1bb0cd32f413963ef9f24ab64 (diff) | |
download | fork-ledger-3e0f510b296c0b72353f146912bb0225af0a5647.tar.gz fork-ledger-3e0f510b296c0b72353f146912bb0225af0a5647.tar.bz2 fork-ledger-3e0f510b296c0b72353f146912bb0225af0a5647.zip |
More work on the compilation of nodes.
-rw-r--r-- | src/compile.cc | 222 | ||||
-rw-r--r-- | src/compile.h | 68 | ||||
-rw-r--r-- | src/document.cc | 2 | ||||
-rw-r--r-- | src/document.h | 2 | ||||
-rw-r--r-- | src/journal.cc | 38 | ||||
-rw-r--r-- | src/journal.h | 13 | ||||
-rw-r--r-- | src/main.cc | 3 | ||||
-rw-r--r-- | src/node.cc | 23 | ||||
-rw-r--r-- | src/node.h | 104 | ||||
-rw-r--r-- | src/session.h | 2 | ||||
-rw-r--r-- | src/value.cc | 10 | ||||
-rw-r--r-- | src/xpath.cc | 9 |
12 files changed, 362 insertions, 134 deletions
diff --git a/src/compile.cc b/src/compile.cc index b5d575a0..0b924418 100644 --- a/src/compile.cc +++ b/src/compile.cc @@ -30,31 +30,213 @@ */ #include "compile.h" +#include "parser.h" namespace ledger { namespace xml { -void entry_node_t::compile() +void compile_node(node_t& node, xpath_t::scope_t& scope) { - typedef std::list<attributes_t::iterator> iterator_list; - - iterator_list to_update; - - for (attributes_t::iterator i = attributes->begin(); - i != attributes->end(); - i++) - if (i->first == DATE_ATTR && i->second.is_string()) - //i->second = parse_datetime(i->second.as_string().c_str()); - to_update.push_back(i); - - for (iterator_list::iterator i = to_update.begin(); - i != to_update.end(); - i++) { - attr_pair attr_def = **i; - attributes->erase(*i); - - attr_def.second = parse_datetime(attr_def.second.as_string().c_str()); - attributes->push_back(attr_def); + switch (node.name_id()) { + case JOURNAL_NODE: + downcast<journal_node_t>(node).compile(scope); + break; + case ENTRY_NODE: + downcast<entry_node_t>(node).compile(scope); + break; + case TRANSACTION_NODE: + downcast<transaction_node_t>(node).compile(scope); + break; + + default: + break; + } + + node.compiled = true; + + if (node.is_parent_node()) + foreach (node_t * child, node.as_parent_node()) + compile_node(*child, scope); +} + +void journal_node_t::compile(xpath_t::scope_t& scope) +{ + if (! journal.get()) + journal.reset(new journal_t); +} + +void entry_node_t::compile(xpath_t::scope_t& scope) +{ + parent_node_t& parent_node(*parent()); + + assert(parent_node.name_id() == JOURNAL_NODE); + assert(parent_node.is_compiled()); + + journal_t * journal = downcast<journal_node_t>(parent_node).journal.get(); + + if (! entry.get()) { + entry.reset(new entry_t); +#if 0 + journal->add_entry(entry.get()); +#endif + } + entry->journal = journal; + + foreach (attr_pair& attr, *attributes) { + if (attr.first == DATE_ATTR && attr.second.is_string()) + entry->_date = parse_datetime(attr.second.as_string().c_str()); + else if (attr.first == EFF_DATE_ATTR && attr.second.is_string()) + entry->_date_eff = parse_datetime(attr.second.as_string().c_str()); + else if (attr.first == CODE_ATTR) + entry->code = attr.second.as_string(); + } +} + +void transaction_node_t::parse_amount_expr(xpath_t::scope_t& scope, + const char * amount_expr) +{ + value_t * amount; + + std::istringstream in(amount_expr); + + PUSH_CONTEXT(); + + // jww (2006-09-15): Make sure it doesn't gobble up the upcoming @ symbol + + unsigned long beg = (long)in.tellg(); + + amount_t temp; + temp.parse(in, AMOUNT_PARSE_NO_REDUCE); + + char c; + if (! in.eof() && (c = peek_next_nonws(in)) != '@' && + c != ';' && ! in.eof()) { + in.seekg(beg, std::ios::beg); + + xpath_t xpath(in, (XPATH_PARSE_NO_REDUCE | XPATH_PARSE_RELAXED | + XPATH_PARSE_PARTIAL)); + + xpath_t::context_scope_t node_scope(scope, this); + amount = &set_attr(AMOUNT_ATTR, xpath.calc(node_scope)); + + //unsigned long end = (long)in.tellg(); + } else { + amount = &set_attr(AMOUNT_ATTR, temp); + } + + // jww (2007-04-30): This should be a string context, or perhaps a + // file context + POP_CONTEXT(context("While parsing transaction amount")); + + // Parse the optional cost (@ PER-UNIT-COST, @@ TOTAL-COST) + + unsigned int linenum = -1; + + if (in.good() && ! in.eof()) { + char c = peek_next_nonws(in); + if (c == '@') { + DEBUG("ledger.textual.parse", "line " << linenum << ": " << + "Found a price indicator"); + bool per_unit = true; + in.get(c); + if (in.peek() == '@') { + in.get(c); + per_unit = false; + DEBUG("ledger.textual.parse", "line " << linenum << ": " << + "And it's for a total price"); + } + + if (in.good() && ! in.eof()) { + amount_t temp; + + PUSH_CONTEXT(); + + //unsigned long beg = (long)in.tellg(); + + temp.parse(in); + + if (temp.sign() < 0) + throw_(parse_error, "A transaction's cost may not be negative"); + + //unsigned long end = (long)in.tellg(); + + POP_CONTEXT(context("While parsing transaction cost")); + + amount_t per_unit_cost(temp); + amount_t& base_amount(amount->as_amount_lval()); + if (per_unit) + temp *= base_amount.number(); + else + per_unit_cost /= base_amount.number(); + + value_t& cost = set_attr(COST_ATTR, temp); + + if (base_amount.commodity() && ! base_amount.commodity().annotated) { + assert(transaction); + assert(transaction->entry); + base_amount.annotate_commodity + (annotation_t(per_unit_cost, transaction->entry->actual_date(), + transaction->entry->code)); + } + + DEBUG("ledger.textual.parse", "line " << linenum << ": " << + "Total cost is " << cost); + DEBUG("ledger.textual.parse", "line " << linenum << ": " << + "Per-unit cost is " << per_unit_cost); + DEBUG("ledger.textual.parse", "line " << linenum << ": " << + "Annotated amount is " << base_amount); + DEBUG("ledger.textual.parse", "line " << linenum << ": " << + "Bare amount is " << base_amount.number()); + } + } + } + + amount->in_place_reduce(); + + DEBUG("ledger.textual.parse", "line " << linenum << ": " << + "Reduced amount is " << *amount); +} + +void transaction_node_t::compile(xpath_t::scope_t& scope) +{ + parent_node_t& parent_node(*parent()); + + assert(parent_node.name_id() == ENTRY_NODE); + assert(parent_node.is_compiled()); + + entry_t * entry = downcast<entry_node_t>(parent_node).entry.get(); + + if (! transaction.get()) { + transaction.reset(new transaction_t); +#if 0 + entry->add_transaction(transaction.get()); +#endif + } + transaction->entry = entry; + + foreach (node_t * child, *this) { + switch (child->name_id()) { + case AMOUNT_EXPR_NODE: + parse_amount_expr(scope, child->as_terminal_node().text()); + break; + + case ACCOUNT_PATH_NODE: { + assert(entry); + + journal_t * journal = entry->journal; + assert(journal); + + transaction->account = + journal->find_account(child->as_terminal_node().text()); + + // jww (2007-05-18): Need to set an attribute that refers to the + // unique id of the account + break; + } + + default: + break; + } } } diff --git a/src/compile.h b/src/compile.h index 81319345..d8b9f536 100644 --- a/src/compile.h +++ b/src/compile.h @@ -38,6 +38,8 @@ namespace ledger { namespace xml { +void compile_node(node_t& node, xml::xpath_t::scope_t& scope); + #if 0 class commodity_node_t : public parent_node_t { @@ -82,6 +84,25 @@ public: }; #endif +class journal_node_t : public parent_node_t +{ +public: + shared_ptr<journal_t> journal; + + journal_node_t(nameid_t _name_id, + document_t& _document, + const optional<parent_node_t&>& _parent = none, + journal_t * _journal = NULL) + : parent_node_t(_name_id, _document, _parent), journal(_journal) { + TRACE_CTOR(journal_node_t, "document_t *, journal_t *, parent_node_t *"); + } + virtual ~journal_node_t() { + TRACE_DTOR(journal_node_t); + } + + void compile(xpath_t::scope_t& scope); +}; + class entry_node_t : public parent_node_t { public: @@ -99,7 +120,7 @@ public: TRACE_DTOR(entry_node_t); } - virtual void compile(); + void compile(xpath_t::scope_t& scope); }; class transaction_node_t : public parent_node_t @@ -120,30 +141,15 @@ public: virtual ~transaction_node_t() { TRACE_DTOR(transaction_node_t); } -}; -#if 0 -class entry_node_t : public parent_node_t -{ - entry_t * entry; + void compile(xpath_t::scope_t& scope); -public: - entry_node_t(document_t * _document, entry_t * _entry, - parent_node_t * _parent = NULL) - : parent_node_t(_document, _parent), entry(_entry) { - TRACE_CTOR(entry_node_t, "document_t *, entry_t *, parent_node_t *"); - set_name(document_t::ENTRY); - } - virtual ~entry_node_t() { - TRACE_DTOR(entry_node_t); - } - - virtual node_t * children() const; - virtual node_t * lookup_child(int _name_id) const; - - friend class transaction_node_t; +private: + void parse_amount_expr(xpath_t::scope_t& scope, + const char * amount_expr); }; +#if 0 class account_node_t : public parent_node_t { account_t * account; @@ -162,26 +168,6 @@ public: virtual node_t * children() const; }; -class journal_node_t : public parent_node_t -{ - journal_t * journal; - -public: - journal_node_t(document_t * _document, journal_t * _journal, - parent_node_t * _parent = NULL) - : parent_node_t(_document, _parent), journal(_journal) { - TRACE_CTOR(journal_node_t, "document_t *, journal_t *, parent_node_t *"); - set_name(document_t::JOURNAL); - } - virtual ~journal_node_t() { - TRACE_DTOR(journal_node_t); - } - - virtual node_t * children() const; - - friend class transaction_node_t; -}; - template <typename T> inline typename T::node_type * wrap_node(document_t * doc, T * item, void * parent_node = NULL) { diff --git a/src/document.cc b/src/document.cc index da7db95e..120440b0 100644 --- a/src/document.cc +++ b/src/document.cc @@ -40,6 +40,7 @@ namespace { "account", "account-path", "amount", + "amount", "amount-expr", "arg", "auto-entry", @@ -51,6 +52,7 @@ namespace { "commodity-conversion", "commodity-nomarket", "commodity-template", + "cost", "current-year", "date", "default-account", diff --git a/src/document.h b/src/document.h index 869c89af..c1dcf88e 100644 --- a/src/document.h +++ b/src/document.h @@ -41,6 +41,7 @@ namespace xml { enum ledger_builtins_t { ACCOUNT_ATTR = 10, ACCOUNT_PATH_NODE, + AMOUNT_ATTR, AMOUNT_NODE, AMOUNT_EXPR_NODE, ARG_ATTR, @@ -53,6 +54,7 @@ enum ledger_builtins_t { COMMODITY_CONVERSION_NODE, COMMODITY_NOMARKET_NODE, COMMODITY_TEMPLATE_NODE, + COST_ATTR, CURRENT_YEAR_NODE, DATE_ATTR, DEFAULT_ACCOUNT_NODE, diff --git a/src/journal.cc b/src/journal.cc index 295db452..32e45697 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -83,7 +83,7 @@ bool transaction_t::valid() const return false; } - if (amount && ! amount->valid()) { + if (! amount.valid()) { DEBUG("ledger.validate", "transaction_t: ! amount.valid()"); return false; } @@ -122,22 +122,22 @@ bool entry_base_t::finalize() x++) if (! (*x)->has_flags(TRANSACTION_VIRTUAL) || (*x)->has_flags(TRANSACTION_BALANCE)) { - optional<amount_t>& p((*x)->cost ? (*x)->cost : (*x)->amount); + amount_t& p((*x)->cost ? *(*x)->cost : (*x)->amount); if (p) { if (no_amounts) { - balance = *p; + balance = p; no_amounts = false; } else { - balance += *p; + balance += p; } assert((*x)->amount); - if ((*x)->cost && (*x)->amount->commodity().annotated) { + if ((*x)->cost && (*x)->amount.commodity().annotated) { annotated_commodity_t& ann_comm(static_cast<annotated_commodity_t&> - ((*x)->amount->commodity())); + ((*x)->amount.commodity())); if (ann_comm.details.price) - balance += (*ann_comm.details.price * (*x)->amount->number() - + balance += (*ann_comm.details.price * (*x)->amount.number() - *((*x)->cost)); } } else { @@ -170,7 +170,7 @@ bool entry_base_t::finalize() balance.as_balance().amounts.size() == 2) { transactions_list::const_iterator x = transactions.begin(); 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.as_balance().amounts.find(&this_comm); @@ -184,22 +184,21 @@ bool entry_base_t::finalize() for (; x != transactions.end(); x++) { if ((*x)->cost || (*x)->has_flags(TRANSACTION_VIRTUAL) || - ! (*x)->amount || (*x)->amount->commodity() != this_comm) + (*x)->amount.commodity() != this_comm) continue; - assert((*x)->amount); - balance -= *(*x)->amount; + balance -= (*x)->amount; entry_t * entry = dynamic_cast<entry_t *>(this); - if ((*x)->amount->commodity() && - ! (*x)->amount->commodity().annotated) - (*x)->amount->annotate_commodity + if ((*x)->amount.commodity() && + ! (*x)->amount.commodity().annotated) + (*x)->amount.annotate_commodity (annotation_t(per_unit_cost.abs(), entry ? entry->actual_date() : optional<moment_t>(), entry ? entry->code : optional<string>())); - (*x)->cost = - (per_unit_cost * (*x)->amount->number()); + (*x)->cost = - (per_unit_cost * (*x)->amount.number()); balance += *(*x)->cost; } } @@ -267,7 +266,7 @@ bool entry_base_t::finalize() (*x)->amount = balance.as_amount().negate(); (*x)->add_flags(TRANSACTION_CALCULATED); - balance += *(*x)->amount; + balance += (*x)->amount; break; default: @@ -378,7 +377,7 @@ void auto_entry_t::extend_entry(entry_base_t& entry, bool post) t++) { amount_t amt; assert((*t)->amount); - if (! (*t)->amount->commodity()) { + if (! (*t)->amount.commodity()) { if (! post) continue; assert((*i)->amount); @@ -590,9 +589,8 @@ bool journal_t::add_entry(entry_t * entry) i++) if ((*i)->cost) { assert((*i)->amount); - assert(*(*i)->amount); - (*i)->amount->commodity().add_price(entry->date(), - *(*i)->cost / (*i)->amount->number()); + (*i)->amount.commodity().add_price(entry->date(), + *(*i)->cost / (*i)->amount.number()); } return true; diff --git a/src/journal.h b/src/journal.h index bb987397..b32bdcaa 100644 --- a/src/journal.h +++ b/src/journal.h @@ -58,10 +58,8 @@ class transaction_t : public supports_flags<> account_t * account; optional<moment_t> _date; optional<moment_t> _date_eff; - optional<amount_t> amount; - optional<string> amount_expr; + amount_t amount; optional<amount_t> cost; - optional<string> cost_expr; optional<string> note; static bool use_effective_date; @@ -88,9 +86,7 @@ class transaction_t : public supports_flags<> _date(xact._date), _date_eff(xact._date_eff), amount(xact.amount), - amount_expr(xact.amount_expr), cost(xact.cost), - cost_expr(xact.cost_expr), note(xact.note) { TRACE_CTOR(transaction_t, "copy"); } @@ -368,12 +364,9 @@ typedef std::list<period_entry_t *> period_entries_list; typedef std::list<path> path_list; typedef std::list<string> strings_list; -class session_t; - class journal_t { public: - session_t * session; account_t * master; account_t * basket; entries_list entries; @@ -388,9 +381,7 @@ class journal_t std::list<entry_finalizer_t *> entry_finalize_hooks; - journal_t(session_t * _session) - : session(_session), basket(NULL), - item_pool(NULL), item_pool_end(NULL) { + journal_t() : basket(NULL), item_pool(NULL), item_pool_end(NULL) { TRACE_CTOR(journal_t, ""); master = new account_t(NULL, ""); master->journal = this; diff --git a/src/main.cc b/src/main.cc index a0bf035b..469bb5ee 100644 --- a/src/main.cc +++ b/src/main.cc @@ -37,6 +37,7 @@ //#include "qif.h" //#include "ofx.h" #include "jbuilder.h" +#include "compile.h" #include <ledger.h> @@ -300,7 +301,7 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[], *out << "Compiled results:" << std::endl; } - xml_document.compile(); + xml::compile_node(xml_document, report); foreach (const value_t& value, xpath.find_all(doc_scope)) { if (value.is_xml_node()) diff --git a/src/node.cc b/src/node.cc index b03f5f5a..0ca0a04c 100644 --- a/src/node.cc +++ b/src/node.cc @@ -40,7 +40,19 @@ const char * node_t::name() const return *document().lookup_name(name_id()); } -optional<value_t> node_t::get_attr(const string& _name) const +value_t& node_t::set_attr(const string& _name, const char * value) +{ + nameid_t name_id = document().register_name(_name); + return set_attr(name_id, value); +} + +value_t& node_t::set_attr(const string& _name, const value_t& value) +{ + nameid_t name_id = document().register_name(_name); + return set_attr(name_id, value); +} + +optional<value_t&> node_t::get_attr(const string& _name) { optional<nameid_t> name_id = document().lookup_name_id(_name); if (name_id) @@ -71,10 +83,17 @@ void output_xml_string(std::ostream& out, const string& str) void node_t::print_attributes(std::ostream& out) const { - if (attributes) + if (attributes) { +#if 1 + foreach (const attr_pair& attr, *attributes) + out << ' ' << *document().lookup_name(attr.first) + << "=\"" << attr.second << "\""; +#else foreach (const attr_pair& attr, attributes->get<0>()) out << ' ' << *document().lookup_name(attr.first) << "=\"" << attr.second << "\""; +#endif + } IF_VERIFY() out << " type=\"parent_node_t\""; @@ -33,7 +33,6 @@ #define _NODE_H #include "value.h" -//#include "parser.h" namespace ledger { namespace xml { @@ -42,8 +41,9 @@ namespace xml { DECLARE_EXCEPTION(conversion_error); -class parent_node_t; class document_t; +class parent_node_t; +class terminal_node_t; class node_t : public supports_flags<>, public noncopyable { @@ -58,6 +58,10 @@ protected: document_t& document_; optional<parent_node_t&> parent_; +#if 1 + typedef std::map<const nameid_t, value_t> attributes_t; + typedef std::pair<const nameid_t, value_t> attr_pair; +#else typedef std::pair<nameid_t, value_t> attr_pair; typedef multi_index_container< @@ -69,14 +73,15 @@ protected: > > attributes_t; - optional<attributes_t> attributes; - typedef attributes_t::nth_index<0>::type attributes_by_order; typedef attributes_t::nth_index<1>::type attributes_hashed; +#endif - bool compiled; + optional<attributes_t> attributes; public: + bool compiled; // so that compile_node() can access it + node_t(nameid_t _name_id, document_t& _document, const optional<parent_node_t&>& _parent = none, flags_t _flags = 0) : supports_flags<>(_flags), name_id_(_name_id), @@ -88,10 +93,11 @@ public: TRACE_DTOR(node_t); } + void extract(); + bool is_compiled() const { return compiled; } - virtual void compile() {} bool is_parent_node() const { return has_flags(XML_NODE_IS_PARENT); @@ -102,9 +108,19 @@ public: return downcast<parent_node_t>(*this); } const parent_node_t& as_parent_node() const { - if (! is_parent_node()) - throw_(std::logic_error, "Request to cast leaf node to a parent node"); - return downcast<const parent_node_t>(*this); + return const_cast<node_t *>(this)->as_parent_node(); + } + + bool is_terminal_node() const { + return ! has_flags(XML_NODE_IS_PARENT); + } + terminal_node_t& as_terminal_node() { + if (! is_terminal_node()) + throw_(std::logic_error, "Request to cast parent node to a leaf node"); + return downcast<terminal_node_t>(*this); + } + const terminal_node_t& as_terminal_node() const { + return const_cast<node_t *>(this)->as_terminal_node(); } virtual value_t to_value() const = 0; @@ -123,29 +139,61 @@ public: return parent_; } - void set_attr(const nameid_t _name_id, const char * value) { - if (! attributes) - attributes = attributes_t(); - attributes->push_back(attr_pair(_name_id, string_value(value))); + value_t& set_attr(const string& _name, const char * value); + value_t& set_attr(const string& _name, const value_t& value); + + value_t& set_attr(const nameid_t _name_id, const char * value) { + return set_attr(_name_id, string_value(value)); } - void set_attr(const nameid_t _name_id, const value_t& value) { + value_t& set_attr(const nameid_t _name_id, const value_t& value) { if (! attributes) attributes = attributes_t(); - attributes->push_back(attr_pair(_name_id, value)); + + attributes_t::iterator i = attributes->find(_name_id); + if (i == attributes->end()) { + std::pair<attributes_t::iterator, bool> result = + attributes->insert(attr_pair(_name_id, value)); + assert(result.second); + return (*result.first).second; + } else { + i->second = value; + return i->second; + } } - optional<value_t> get_attr(const string& _name) const; - optional<value_t> get_attr(const nameid_t _name_id) const { + optional<value_t&> get_attr(const string& _name); + optional<value_t&> get_attr(const nameid_t _name_id) { if (attributes) { +#if 1 + attributes_t::iterator i = attributes->find(_name_id); + if (i != attributes->end()) + return (*i).second; +#else typedef attributes_t::nth_index<1>::type attributes_by_name; const attributes_by_name& name_index = attributes->get<1>(); - attributes_by_name::const_iterator i = name_index.find(_name_id); + attributes_by_name::iterator i = name_index.find(_name_id); if (i != name_index.end()) return (*i).second; +#endif } return none; } + + optional<const value_t&> get_attr(const string& _name) const { + if (optional<value_t&> value = + const_cast<node_t *>(this)->get_attr(_name)) + return *value; + else + return none; + } + optional<const value_t&> get_attr(const nameid_t _name_id) const { + if (optional<value_t&> value = + const_cast<node_t *>(this)->get_attr(_name_id)) + return *value; + else + return none; + } }; class parent_node_t : public node_t @@ -177,11 +225,6 @@ public: clear_children(); } - virtual void compile() { - foreach (node_t * child, *this) - child->compile(); - } - template <typename T> T * create_child(nameid_t _name_id) { T * child = new T(_name_id, document(), *this); @@ -189,14 +232,17 @@ public: return child; } - void delete_child(node_t * child) { + void remove_child(node_t * child) { children_by_ptr& ptr_index = children.get<2>(); children_by_ptr::iterator i = ptr_index.find(child); if (i == ptr_index.end()) throw_(std::logic_error, "Request to delete node which is not a child"); - node_t * ptr = *i; ptr_index.erase(i); - checked_delete(ptr); + } + + void delete_child(node_t * child) { + remove_child(child); + checked_delete(child); } struct match_nameid { @@ -262,6 +308,12 @@ public: void print(std::ostream& out) const; }; +inline void node_t::extract() +{ + if (parent_) + parent_->remove_child(this); +} + class terminal_node_t : public node_t { string data; diff --git a/src/session.h b/src/session.h index 206144c6..43d7d722 100644 --- a/src/session.h +++ b/src/session.h @@ -85,7 +85,7 @@ class session_t : public xml::xpath_t::symbol_scope_t } journal_t * create_journal() { - journal_t * journal = new journal_t(this); + journal_t * journal = new journal_t; journals.push_back(journal); return journal; } diff --git a/src/value.cc b/src/value.cc index 25145695..2985df45 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1203,20 +1203,20 @@ void value_t::in_place_reduce() { switch (type()) { case INTEGER: - break; + return; case AMOUNT: as_amount_lval().in_place_reduce(); - break; + return; case BALANCE: as_balance_lval().in_place_reduce(); - break; + return; case BALANCE_PAIR: as_balance_pair_lval().in_place_reduce(); - break; + return; case XML_NODE: *this = as_xml_node()->to_value(); in_place_reduce(); // recurse - break; + return; default: break; } diff --git a/src/xpath.cc b/src/xpath.cc index 98988c64..f779ebc6 100644 --- a/src/xpath.cc +++ b/src/xpath.cc @@ -1208,16 +1208,11 @@ value_t xpath_t::op_t::calc(scope_t& scope) case ATTR_ID: case ATTR_NAME: - if (optional<value_t> value = + if (optional<value_t&> value = kind == ATTR_ID ? current_xml_node(scope).get_attr(as_name()) : current_xml_node(scope).get_attr(as_string())) return *value; - else - throw_(calc_error, "Attribute '" - << (kind == ATTR_ID ? - *current_xml_node(scope).document().lookup_name(as_long()) : - as_string().c_str()) - << "' was not found"); + break; case O_NEQ: |