From 023f28630f7ed8f845eab00b137d58cc79b4445b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 16 May 2007 05:37:37 +0000 Subject: Changed xpath to use the new copy-on-write value_t. --- src/main.cc | 3 +- src/node.h | 6 +-- src/option.cc | 6 +-- src/pyinterp.cc | 31 +++++------ src/pyinterp.h | 4 +- src/report.cc | 14 ++--- src/report.h | 36 ++++++------- src/session.h | 17 +++--- src/value.cc | 3 +- src/xpath.cc | 162 +++++++++++++++++++++++--------------------------------- src/xpath.h | 78 ++++++++++----------------- 11 files changed, 151 insertions(+), 209 deletions(-) (limited to 'src') diff --git a/src/main.cc b/src/main.cc index 13b02290..d50137b6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -301,8 +301,7 @@ static int read_and_report(ledger::report_t * report, int argc, char * argv[], INFO_START(command, "Did user command '" << verb << "'"); - value_t temp; - command(temp, locals.get()); + command(locals.get()); INFO_FINISH(command); diff --git a/src/node.h b/src/node.h index cfd027fc..d394e7ee 100644 --- a/src/node.h +++ b/src/node.h @@ -116,12 +116,12 @@ public: attributes = attributes_t(); attributes->push_back(attr_pair(_name_id, value)); } - optional get_attr(const nameid_t _name_id) { + optional get_attr(const nameid_t _name_id) const { if (attributes) { typedef attributes_t::nth_index<1>::type attributes_by_name; - attributes_by_name& name_index = attributes->get<1>(); - attributes_by_name::iterator i = name_index.find(_name_id); + const attributes_by_name& name_index = attributes->get<1>(); + attributes_by_name::const_iterator i = name_index.find(_name_id); if (i != name_index.end()) return (*i).second; } diff --git a/src/option.cc b/src/option.cc index d56eb0ff..607e22bd 100644 --- a/src/option.cc +++ b/src/option.cc @@ -85,11 +85,9 @@ namespace { scoped_ptr args; if (arg) { args.reset(new xml::xpath_t::scope_t(scope, xml::xpath_t::scope_t::ARGUMENT)); - args->args.set_string(arg); + args->args.push_back(value_t(arg, true)); } - - value_t temp; - opt(temp, args.get()); + opt(args.get()); #if 0 } catch (error * err) { diff --git a/src/pyinterp.cc b/src/pyinterp.cc index 4a2f1e75..cd0576bf 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -173,27 +173,23 @@ object python_interpreter_t::eval(const string& str, py_eval_mode_t mode) } } -void python_interpreter_t::functor_t::operator()(value_t& result, - xml::xpath_t::scope_t * locals) +value_t python_interpreter_t::functor_t::operator()(xml::xpath_t::scope_t * locals) { try { if (! PyCallable_Check(func.ptr())) { - result = static_cast(extract(func.ptr())); + return extract(func.ptr()); } else { - assert(locals->args.is_type(value_t::SEQUENCE)); - if (locals->args.as_sequence().size() > 0) { + if (locals->args.size() > 0) { list arglist; - for (value_t::sequence_t::const_iterator - i = locals->args.as_sequence().begin(); - i != locals->args.as_sequence().end(); - i++) - arglist.append(*i); + foreach (const value_t& value, locals->args) + arglist.append(value); if (PyObject * val = PyObject_CallObject(func.ptr(), boost::python::tuple(arglist).ptr())) { - result = extract(val)(); + value_t result = extract(val)(); Py_DECREF(val); + return result; } else if (PyObject * err = PyErr_Occurred()) { PyErr_Print(); @@ -203,7 +199,7 @@ void python_interpreter_t::functor_t::operator()(value_t& result, assert(false); } } else { - result = call(func.ptr()); + return call(func.ptr()); } } } @@ -214,15 +210,14 @@ void python_interpreter_t::functor_t::operator()(value_t& result, } } -void python_interpreter_t::lambda_t::operator()(value_t& result, - xml::xpath_t::scope_t * locals) +value_t python_interpreter_t::lambda_t::operator() + (xml::xpath_t::scope_t * locals) { try { - assert(locals->args.is_type(value_t::SEQUENCE)); - assert(locals->args.as_sequence().size() == 1); + assert(locals->args.size() == 1); value_t item = locals->args[0]; - assert(item.is_type(value_t::POINTER)); - result = call(func.ptr(), item.as_xml_node()); + assert(item.is_type(value_t::XML_NODE)); + return call(func.ptr(), item.as_xml_node()); } catch (const error_already_set&) { PyErr_Print(); diff --git a/src/pyinterp.h b/src/pyinterp.h index aee002f9..a8f4784f 100644 --- a/src/pyinterp.h +++ b/src/pyinterp.h @@ -75,7 +75,7 @@ class python_interpreter_t : public xml::xpath_t::scope_t boost::python::object func; public: functor_t(const string& name, boost::python::object _func) : func(_func) {} - virtual void operator()(value_t& result, xml::xpath_t::scope_t * locals); + virtual value_t operator()(xml::xpath_t::scope_t * locals); }; virtual void define(const string& name, xml::xpath_t::ptr_op_t def) { @@ -93,7 +93,7 @@ class python_interpreter_t : public xml::xpath_t::scope_t class lambda_t : public functor_t { public: lambda_t(boost::python::object code) : functor_t("", code) {} - virtual void operator()(value_t& result, xml::xpath_t::scope_t * locals); + virtual value_t operator()(xml::xpath_t::scope_t * locals); }; }; diff --git a/src/report.cc b/src/report.cc index 31acfde0..5f52d37e 100644 --- a/src/report.cc +++ b/src/report.cc @@ -44,7 +44,7 @@ void report_t::apply_transforms(xml::document_t& document) transform.execute(document); } -void report_t::abbrev(value_t& result, xml::xpath_t::scope_t * locals) +value_t report_t::abbrev(xml::xpath_t::scope_t * locals) { if (locals->args.size() < 2) throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])"); @@ -60,10 +60,10 @@ void report_t::abbrev(value_t& result, xml::xpath_t::scope_t * locals) if (locals->args.size() == 4) abbrev_len = locals->args[3].as_long(); - result.set_string(abbreviate(str, wid, style, true, (int)abbrev_len)); + return value_t(abbreviate(str, wid, style, true, (int)abbrev_len), true); } -void report_t::ftime(value_t&, xml::xpath_t::scope_t * locals) +value_t report_t::ftime(xml::xpath_t::scope_t * locals) { if (locals->args.size() < 1) throw_(std::logic_error, "usage: ftime(DATE [, DATE_FORMAT])"); @@ -78,7 +78,7 @@ void report_t::ftime(value_t&, xml::xpath_t::scope_t * locals) else date_format = moment_t::output_format; - result.set_string(date.as_string(date_format)); + return value_t(date.as_string(date_format), true); #endif } @@ -89,14 +89,14 @@ bool report_t::resolve(const string& name, value_t& result, switch (*p) { case 'a': if (name == "abbrev") { - abbrev(result, locals); + result = abbrev(locals); return true; } break; case 'f': if (name == "ftime") { - ftime(result, locals); + result = ftime(locals); return true; } break; @@ -116,7 +116,7 @@ xml::xpath_t::ptr_op_t report_t::lookup(const string& name) case 'a': #if 0 if (std::strcmp(p, "accounts") == 0) - return MAKE_FUNCTOR(report_t, option_accounts); + return MAKE_FUNCTOR(report_t::option_accounts); else #endif if (std::strcmp(p, "amount") == 0) diff --git a/src/report.h b/src/report.h index 0e0c30ad..de5773d1 100644 --- a/src/report.h +++ b/src/report.h @@ -80,8 +80,8 @@ class report_t : public xml::xpath_t::scope_t // Utility functions for value expressions // - void ftime(value_t& result, xml::xpath_t::scope_t * locals); - void abbrev(value_t& result, xml::xpath_t::scope_t * locals); + value_t ftime(xml::xpath_t::scope_t * locals); + value_t abbrev(xml::xpath_t::scope_t * locals); // // Config options @@ -92,29 +92,29 @@ class report_t : public xml::xpath_t::scope_t xml::xpath_t(expr).compile((xml::document_t *)NULL, this); #endif } - void option_eval(value_t&, xml::xpath_t::scope_t * locals) { + value_t option_eval(xml::xpath_t::scope_t * locals) { eval(locals->args[0].as_string()); } - void option_amount(value_t&, xml::xpath_t::scope_t * locals) { + value_t option_amount(xml::xpath_t::scope_t * locals) { eval(string("t=") + locals->args[0].as_string()); } - void option_total(value_t&, xml::xpath_t::scope_t * locals) { + value_t option_total(xml::xpath_t::scope_t * locals) { eval(string("T()=") + locals->args[0].as_string()); } - void option_format(value_t&, xml::xpath_t::scope_t * locals) { + value_t option_format(xml::xpath_t::scope_t * locals) { format_string = locals->args[0].as_string(); } - void option_raw(value_t&) { + value_t option_raw(xml::xpath_t::scope_t * locals) { raw_mode = true; } - void option_foo(value_t&) { + value_t option_foo(xml::xpath_t::scope_t * locals) { std::cout << "This is foo" << std::endl; } - void option_bar(value_t&, xml::xpath_t::scope_t * locals) { + value_t option_bar(xml::xpath_t::scope_t * locals) { std::cout << "This is bar: " << locals->args[0] << std::endl; } @@ -123,36 +123,36 @@ class report_t : public xml::xpath_t::scope_t // #if 0 - void option_select(value_t&, xml::xpath_t::scope_t * locals) { + value_t option_select(xml::xpath_t::scope_t * locals) { transforms.push_back(new select_transform(locals->args[0].as_string())); } - void option_limit(value_t&, xml::xpath_t::scope_t * locals) { + value_t option_limit(xml::xpath_t::scope_t * locals) { string expr = (string("//xact[") + locals->args[0].as_string() + "]"); transforms.push_back(new select_transform(expr)); } - void option_remove(value_t&, xml::xpath_t::scope_t * locals) { + value_t option_remove(xml::xpath_t::scope_t * locals) { transforms.push_back(new remove_transform(locals->args[0].as_string())); } - void option_accounts(value_t&) { + value_t option_accounts(xml::xpath_t::scope_t * locals) { transforms.push_back(new accounts_transform); } - void option_compact(value_t&) { + value_t option_compact(xml::xpath_t::scope_t * locals) { transforms.push_back(new compact_transform); } - void option_clean(value_t&) { + value_t option_clean(xml::xpath_t::scope_t * locals) { transforms.push_back(new clean_transform); } - void option_entries(value_t&) { + value_t option_entries(xml::xpath_t::scope_t * locals) { transforms.push_back(new entries_transform); } - void option_split(value_t&) { + value_t option_split(xml::xpath_t::scope_t * locals) { transforms.push_back(new split_transform); } - void option_merge(value_t&) { + value_t option_merge(xml::xpath_t::scope_t * locals) { transforms.push_back(new merge_transform); } #endif diff --git a/src/session.h b/src/session.h index 7658fc24..8db9faf1 100644 --- a/src/session.h +++ b/src/session.h @@ -188,11 +188,11 @@ class session_t : public xml::xpath_t::scope_t // Debug options // - void option_trace_(value_t&, xml::xpath_t::scope_t * locals) {} - void option_debug_(value_t&, xml::xpath_t::scope_t * locals) {} + value_t option_trace_(xml::xpath_t::scope_t * locals) {} + value_t option_debug_(xml::xpath_t::scope_t * locals) {} - void option_verify(value_t&, xml::xpath_t::scope_t *) {} - void option_verbose(value_t&, xml::xpath_t::scope_t *) { + value_t option_verify(xml::xpath_t::scope_t *) {} + value_t option_verbose(xml::xpath_t::scope_t *) { #if defined(LOGGING_ON) if (_log_level < LOG_INFO) _log_level = LOG_INFO; @@ -203,16 +203,17 @@ class session_t : public xml::xpath_t::scope_t // Option handlers // - void option_file_(value_t&, xml::xpath_t::scope_t * locals) { - data_file = locals->args.as_string(); + value_t option_file_(xml::xpath_t::scope_t * locals) { + assert(locals->args.size() == 1); + data_file = locals->args[0].as_string(); } #if 0 #if defined(USE_BOOST_PYTHON) - void option_import_(value_t&) { + value_t option_import_(xml::xpath_t::scope_t * locals) { python_import(optarg); } - void option_import_stdin(value_t&) { + value_t option_import_stdin(xml::xpath_t::scope_t * locals) { python_eval(std::cin, PY_EVAL_MULTI); } #endif diff --git a/src/value.cc b/src/value.cc index 4089e0c3..9c50f830 100644 --- a/src/value.cc +++ b/src/value.cc @@ -967,7 +967,8 @@ void value_t::in_place_cast(type_t cast_type) } else if (cast_type == SEQUENCE) { sequence_t temp; - temp.push_back(*this); + if (! is_null()) + temp.push_back(*this); set_sequence(temp); return; } diff --git a/src/xpath.cc b/src/xpath.cc index 623aa8c4..80749d72 100644 --- a/src/xpath.cc +++ b/src/xpath.cc @@ -436,7 +436,7 @@ void xpath_t::token_t::unexpected(char c, char wanted) xpath_t::ptr_op_t xpath_t::wrap_value(const value_t& val) { xpath_t::ptr_op_t temp(new xpath_t::op_t(xpath_t::op_t::VALUE)); - temp->set_value(new value_t(val)); + temp->set_value(val); return temp; } @@ -522,7 +522,7 @@ xpath_t::parse_value_term(std::istream& in, flags_t tflags) const switch (tok.kind) { case token_t::VALUE: node = new op_t(op_t::VALUE); - node->set_value(new value_t(tok.value)); + node->set_value(tok.value); break; case token_t::IDENT: { @@ -1050,7 +1050,7 @@ xpath_t::op_t::copy(ptr_op_t tleft, ptr_op_t tright) const return node; } -void xpath_t::op_t::find_values(const value_t& context, scope_t * scope, +void xpath_t::op_t::find_values(const node_t& context, scope_t * scope, value_t::sequence_t& result_seq, bool recursive) { @@ -1059,23 +1059,14 @@ void xpath_t::op_t::find_values(const value_t& context, scope_t * scope, if (expr.ptr->is_value() && (expr.ptr->as_value().is_xml_node() || expr.ptr->as_value().is_sequence())) - append_value(expr.ptr->as_value(), result_seq); - - if (recursive) { - if (context.is_type(value_t::XML_NODE)) { - node_t * ptr = context.as_xml_node(); - if (ptr->is_parent_node()) - foreach (node_t * node, ptr->as_parent_node()) { - value_t temp(node); - find_values(temp, scope, result_seq, recursive); - } - } else { - throw_(calc_error, "Recursive path selection on a non-node value"); - } - } + append_value(result_seq, expr.ptr->as_value()); + + if (recursive && context.is_parent_node()) + foreach (node_t * node, context.as_parent_node()) + find_values(*node, scope, result_seq, recursive); } -bool xpath_t::op_t::test_value(const value_t& context, scope_t * scope, int index) +bool xpath_t::op_t::test_value(const node_t& context, scope_t * scope, int index) { xpath_t expr(compile(context, scope, true)); @@ -1130,8 +1121,7 @@ xpath_t::ptr_op_t xpath_t::op_t::defer_sequence(value_t::sequence_t& result_seq) return lit_seq; } -void xpath_t::op_t::append_value(value_t& val, - value_t::sequence_t& result_seq) +void xpath_t::op_t::append_value(value_t::sequence_t& result_seq, value_t& val) { if (val.is_type(value_t::SEQUENCE)) std::for_each(val.as_sequence().begin(), val.as_sequence().end(), @@ -1141,7 +1131,7 @@ void xpath_t::op_t::append_value(value_t& val, } xpath_t::ptr_op_t -xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) +xpath_t::op_t::compile(const node_t& context, scope_t * scope, bool resolve) { #if 0 try { @@ -1153,28 +1143,20 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) case NODE_ID: switch (as_name()) { case document_t::CURRENT: - return wrap_value(context); + return wrap_value(&context); case document_t::PARENT: - if (! context.is_type(value_t::XML_NODE)) - throw_(compile_error, "Referencing parent node from a non-node value"); - else if (context.as_xml_node()->parent()) - return wrap_value(&*context.as_xml_node()->parent()); + if (context.parent()) + return wrap_value(&*context.parent()); else throw_(compile_error, "Referencing parent node from the root node"); case document_t::ROOT: - if (! context.is_type(value_t::XML_NODE)) - throw_(compile_error, "Referencing root node from a non-node value"); - else - return wrap_value(&context.as_xml_node()->document()); + return wrap_value(&context.document()); case document_t::ALL: { - if (! context.is_type(value_t::XML_NODE)) - throw_(compile_error, "Referencing child nodes from a non-node value"); - value_t::sequence_t nodes; - foreach (node_t * node, context.as_xml_node()->as_parent_node()) + foreach (node_t * node, context.as_parent_node()) nodes.push_back(node); return wrap_value(nodes); } @@ -1185,42 +1167,39 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) // fall through... case NODE_NAME: - if (context.is_xml_node()) { - node_t * ptr = context.as_xml_node(); - if (resolve) { - // First, look up the symbol as a node name within the current - // context. If any exist, then return the set of names. - - if (ptr->is_parent_node()) { - value_t::sequence_t nodes; - - foreach (node_t * node, ptr->as_parent_node()) { - if ((kind == NODE_NAME && - std::strcmp(as_string().c_str(), node->name()) == 0) || - (kind == NODE_ID && as_name() == node->name_id())) - nodes.push_back(node); - } - return wrap_value(nodes); + if (resolve) { + // First, look up the symbol as a node name within the current + // context. If any exist, then return the set of names. + + if (context.is_parent_node()) { + value_t::sequence_t nodes; + + foreach (node_t * node, context.as_parent_node()) { + if ((kind == NODE_NAME && + std::strcmp(as_string().c_str(), node->name()) == 0) || + (kind == NODE_ID && as_name() == node->name_id())) + nodes.push_back(node); } + return wrap_value(nodes); } - else if (optional id = - ptr->document().lookup_name_id(as_string())) { - ptr_op_t node = new_node(NODE_ID); - node->set_name(*id); - return node; - } + } + else if (optional id = + context.document().lookup_name_id(as_string())) { + ptr_op_t node = new_node(NODE_ID); + node->set_name(*id); + return node; } return this; case ATTR_ID: - if (optional value = context.as_xml_node()->get_attr(as_long())) + if (optional value = context.get_attr(as_long())) return wrap_value(*value); return this; case ATTR_NAME: if (optional id = - context.as_xml_node()->document().lookup_name_id(as_string())) { - if (optional value = context.as_xml_node()->get_attr(*id)) + context.document().lookup_name_id(as_string())) { + if (optional value = context.get_attr(*id)) return wrap_value(*value); } return this; @@ -1240,9 +1219,8 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) case ARG_INDEX: if (scope && scope->kind == scope_t::ARGUMENT) { - assert(scope->args.is_type(value_t::SEQUENCE)); - if (as_long() < scope->args.as_sequence().size()) - return wrap_value(scope->args.as_sequence()[as_long()]); + if (as_long() < scope->args.size()) + return wrap_value(scope->args[as_long()]); else throw_(compile_error, "Reference to non-existing argument"); } else { @@ -1250,13 +1228,10 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) } case FUNCTION: - if (resolve) { - value_t temp; - as_function()(temp, scope); - return wrap_value(temp); - } else { + if (resolve) + return wrap_value(as_function()(scope)); + else return this; - } break; case O_NOT: { @@ -1275,9 +1250,9 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) return wrap_value(true); } else { if (expr.ptr->as_value().strip_annotations()) - expr.ptr->set_value(new value_t(false)); + expr.ptr->set_value(false); else - expr.ptr->set_value(new value_t(true)); + expr.ptr->set_value(true); return expr.ptr; } @@ -1312,8 +1287,8 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) value_t::sequence_t result_seq; - append_value(lexpr.ptr->as_value(), result_seq); - append_value(rexpr.ptr->as_value(), result_seq); + append_value(result_seq, lexpr.ptr->as_value()); + append_value(result_seq, rexpr.ptr->as_value()); return wrap_value(result_seq); } @@ -1393,22 +1368,22 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) } else { switch (kind) { case O_NEQ: - lexpr.ptr->set_value(new value_t(lexpr.ptr->as_value() != rexpr.ptr->as_value())); + lexpr.ptr->set_value(lexpr.ptr->as_value() != rexpr.ptr->as_value()); break; case O_EQ: - lexpr.ptr->set_value(new value_t(lexpr.ptr->as_value() == rexpr.ptr->as_value())); + lexpr.ptr->set_value(lexpr.ptr->as_value() == rexpr.ptr->as_value()); break; case O_LT: - lexpr.ptr->set_value(new value_t(lexpr.ptr->as_value() < rexpr.ptr->as_value())); + lexpr.ptr->set_value(lexpr.ptr->as_value() < rexpr.ptr->as_value()); break; case O_LTE: - lexpr.ptr->set_value(new value_t(lexpr.ptr->as_value() <= rexpr.ptr->as_value())); + lexpr.ptr->set_value(lexpr.ptr->as_value() <= rexpr.ptr->as_value()); break; case O_GT: - lexpr.ptr->set_value(new value_t(lexpr.ptr->as_value() > rexpr.ptr->as_value())); + lexpr.ptr->set_value(lexpr.ptr->as_value() > rexpr.ptr->as_value()); break; case O_GTE: - lexpr.ptr->set_value(new value_t(lexpr.ptr->as_value() >= rexpr.ptr->as_value())); + lexpr.ptr->set_value(lexpr.ptr->as_value() >= rexpr.ptr->as_value()); break; default: assert(false); @@ -1421,7 +1396,7 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) case O_AND: { xpath_t lexpr(left()->compile(context, scope, resolve)); if (lexpr.ptr->is_value() && ! lexpr.ptr->as_value().strip_annotations()) { - lexpr.ptr->set_value(new value_t(false)); + lexpr.ptr->set_value(false); return lexpr.ptr; } @@ -1437,7 +1412,7 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) if (left() == lexpr.ptr) { return wrap_value(false); } else { - lexpr.ptr->set_value(new value_t(false)); + lexpr.ptr->set_value(false); return lexpr.ptr; } } else { @@ -1464,7 +1439,7 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) if (left() == lexpr.ptr) { return wrap_value(false); } else { - lexpr.ptr->set_value(new value_t(false)); + lexpr.ptr->set_value(false); return lexpr.ptr; } } @@ -1578,9 +1553,7 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) // get resolved before we have a chance to call it xpath_t func(left()->compile(context, scope, false)); if (func.ptr->kind == FUNCTION) { - value_t temp; - func.ptr->as_function()(temp, call_args.get()); - return wrap_value(temp); + return wrap_value(func.ptr->as_function()(call_args.get())); } else if (! resolve) { return func.ptr->compile(context, call_args.get(), resolve); @@ -1591,9 +1564,7 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) } } else if (left()->kind == FUNCTION) { - value_t temp; - left()->as_function()(temp, call_args.get()); - return wrap_value(temp); + return wrap_value(left()->as_function()(call_args.get())); } else { assert(false); @@ -1622,11 +1593,11 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) value_t& value(lexpr.ptr->as_value()); function_scope_t xpath_fscope(*value.as_xml_node(), 0, 1, scope); if (kind == O_PRED) { - if (rexpr.ptr->test_value(value, &xpath_fscope)) + if (rexpr.ptr->test_value(*value.as_xml_node(), &xpath_fscope)) result_seq.push_back(value); } else { - rexpr.ptr->find_values(value, &xpath_fscope, result_seq, - kind == O_RFIND); + rexpr.ptr->find_values(*value.as_xml_node(), &xpath_fscope, + result_seq, kind == O_RFIND); } break; } @@ -1645,10 +1616,10 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) function_scope_t xpath_fscope(seq, *(*i).as_xml_node(), index, scope); if (kind == O_PRED) { - if (rexpr.ptr->test_value(*i, &xpath_fscope, index)) + if (rexpr.ptr->test_value(*(*i).as_xml_node(), &xpath_fscope, index)) result_seq.push_back(*i); } else { - rexpr.ptr->find_values(*i, &xpath_fscope, result_seq, + rexpr.ptr->find_values(*(*i).as_xml_node(), &xpath_fscope, result_seq, kind == O_RFIND); } } @@ -1684,16 +1655,15 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve) return NULL; } -void xpath_t::calc(value_t& result, node_t& node, scope_t * scope) const +value_t xpath_t::calc(const node_t& context, scope_t * scope) const { #if 0 try { #endif - value_t context_node(&node); - xpath_t final(ptr->compile(context_node, scope, true)); + xpath_t final(ptr->compile(context, scope, true)); // jww (2006-09-09): Give a better error here if this is not // actually a value - result = final.ptr->as_value(); + return final.ptr->as_value(); #if 0 } catch (error * err) { diff --git a/src/xpath.h b/src/xpath.h index 6d2ffcd2..5433223d 100644 --- a/src/xpath.h +++ b/src/xpath.h @@ -53,10 +53,10 @@ public: public: class scope_t; - typedef function function_t; + typedef function function_t; #define MAKE_FUNCTOR(x) \ - xml::xpath_t::wrap_functor(bind(&x, this, _1, _2)) + xml::xpath_t::wrap_functor(bind(&x, this, _1)) static ptr_op_t wrap_value(const value_t& val); static ptr_op_t wrap_functor(const function_t& fobj); @@ -68,8 +68,8 @@ public: symbol_map symbols; public: - scope_t * parent; - value_t args; + scope_t * parent; + value_t::sequence_t args; enum kind_t { NORMAL, STATIC, ARGUMENT } kind; @@ -84,6 +84,7 @@ public: public: virtual void define(const string& name, ptr_op_t def); + // jww (2007-05-15): ?? virtual bool resolve(const string& name, value_t& result, scope_t * locals = NULL) { if (parent) @@ -244,9 +245,11 @@ public: public: path_t(const xpath_t& path_expr); - void find_all(value_t::sequence_t& result, - node_t& start, scope_t * scope) { - visit(start, scope, value_node_appender_t(result)); + value_t find_all(node_t& start, scope_t * scope) { + value_t result = value_t::sequence_t(); + visit(start, scope, + value_node_appender_t(result.as_sequence_lval())); + return result; } void visit(node_t& start, scope_t * scope, @@ -374,7 +377,7 @@ public: ptr_op_t left_; variant, // used by constant VALUE + value_t, // used by constant VALUE string, // used by constant SYMBOL function_t, // used by terminal FUNCTION node_t::nameid_t, // used by NODE_NAME and ATTR_NAME @@ -412,16 +415,13 @@ public: } value_t& as_value() { assert(kind == VALUE); - value_t * val = boost::get >(data).get(); - assert(val); - return *val; + return boost::get(data); } const value_t& as_value() const { return const_cast(this)->as_value(); } - void set_value(value_t * val) { - // jww (2007-05-14): Ugh, fix this - data = shared_ptr(val); + void set_value(const value_t& val) { + data = val; } bool is_string() const { @@ -533,13 +533,13 @@ public: ptr_op_t right = NULL); ptr_op_t copy(ptr_op_t left = NULL, ptr_op_t right = NULL) const; - ptr_op_t compile(const value_t& context, scope_t * scope, bool resolve = false); + ptr_op_t compile(const node_t& context, scope_t * scope, bool resolve = false); - void find_values(const value_t& context, scope_t * scope, + void find_values(const node_t& context, scope_t * scope, value_t::sequence_t& result_seq, bool recursive); - bool test_value(const value_t& context, scope_t * scope, int index = 0); + bool test_value(const node_t& context, scope_t * scope, int index = 0); - void append_value(value_t& value, value_t::sequence_t& result_seq); + void append_value(value_t::sequence_t& result_seq, value_t& value); static ptr_op_t defer_sequence(value_t::sequence_t& result_seq); @@ -561,8 +561,7 @@ public: op_predicate(ptr_op_t _op) : op(_op) {} bool operator()(node_t& node, scope_t * scope) { - value_t context_node(&node); - xpath_t result(op->compile(context_node, scope, true)); + xpath_t result(op->compile(node, scope, true)); return result.ptr->as_value().to_boolean(); } }; @@ -727,47 +726,25 @@ public: ptr = parse_expr(in, _flags); } - void compile(node_t& top_node, scope_t * scope = NULL) { - if (ptr.get()) { - value_t noderef(&top_node); - ptr = ptr->compile(noderef, scope); - } + void compile(const node_t& context, scope_t * scope = NULL) { + if (ptr.get()) + ptr = ptr->compile(context, scope); } - virtual void calc(value_t& result, node_t& node, - scope_t * scope = NULL) const; - virtual value_t calc(node_t& tcontext, scope_t * scope = NULL) const { - if (! ptr) - return 0L; - value_t temp; - calc(temp, tcontext, scope); - return temp; - } + virtual value_t calc(const node_t& context, scope_t * scope = NULL) const; - static void eval(value_t& result, const string& _expr, node_t& top, - scope_t * scope = NULL) { - xpath_t temp(_expr); - temp.calc(result, top, scope); - } - static value_t eval(const string& _expr, node_t& top, + static value_t eval(const string& _expr, const node_t& context, scope_t * scope = NULL) { - xpath_t temp(_expr); - return temp.calc(top, scope); + return xpath_t(_expr).calc(context, scope); } - void find_all(value_t::sequence_t& result, - node_t& start, scope_t * scope) { - path_t path(*this); - path.find_all(result, start, scope); - } path_iterator_t find_all(node_t& start, scope_t * scope) { return path_iterator_t(*this, start, scope); } void visit(node_t& start, scope_t * scope, const function& func) { - path_t path(*this); - path.visit(start, scope, func); + path_t(*this).visit(start, scope, func); } void print(std::ostream& out, xml::document_t& document) const { @@ -809,10 +786,11 @@ inline T * get_node_ptr(xml::xpath_t::scope_t * locals, unsigned int idx) { class xml_command { public: - void operator()(value_t&, xml::xpath_t::scope_t * locals) { + value_t operator()(xml::xpath_t::scope_t * locals) { std::ostream * out = get_ptr(locals, 0); xml::document_t * doc = get_node_ptr(locals, 1); doc->print(*out); + return true; } }; -- cgit v1.2.3