Changed xpath to use the new copy-on-write value_t.
This commit is contained in:
parent
5282260471
commit
023f28630f
11 changed files with 148 additions and 206 deletions
|
|
@ -301,8 +301,7 @@ static int read_and_report(ledger::report_t * report, int argc, char * argv[],
|
||||||
|
|
||||||
INFO_START(command, "Did user command '" << verb << "'");
|
INFO_START(command, "Did user command '" << verb << "'");
|
||||||
|
|
||||||
value_t temp;
|
command(locals.get());
|
||||||
command(temp, locals.get());
|
|
||||||
|
|
||||||
INFO_FINISH(command);
|
INFO_FINISH(command);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,12 +116,12 @@ public:
|
||||||
attributes = attributes_t();
|
attributes = attributes_t();
|
||||||
attributes->push_back(attr_pair(_name_id, value));
|
attributes->push_back(attr_pair(_name_id, value));
|
||||||
}
|
}
|
||||||
optional<const string&> get_attr(const nameid_t _name_id) {
|
optional<const string&> get_attr(const nameid_t _name_id) const {
|
||||||
if (attributes) {
|
if (attributes) {
|
||||||
typedef attributes_t::nth_index<1>::type attributes_by_name;
|
typedef attributes_t::nth_index<1>::type attributes_by_name;
|
||||||
|
|
||||||
attributes_by_name& name_index = attributes->get<1>();
|
const attributes_by_name& name_index = attributes->get<1>();
|
||||||
attributes_by_name::iterator i = name_index.find(_name_id);
|
attributes_by_name::const_iterator i = name_index.find(_name_id);
|
||||||
if (i != name_index.end())
|
if (i != name_index.end())
|
||||||
return (*i).second;
|
return (*i).second;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,11 +85,9 @@ namespace {
|
||||||
scoped_ptr<xml::xpath_t::scope_t> args;
|
scoped_ptr<xml::xpath_t::scope_t> args;
|
||||||
if (arg) {
|
if (arg) {
|
||||||
args.reset(new xml::xpath_t::scope_t(scope, xml::xpath_t::scope_t::ARGUMENT));
|
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));
|
||||||
}
|
}
|
||||||
|
opt(args.get());
|
||||||
value_t temp;
|
|
||||||
opt(temp, args.get());
|
|
||||||
#if 0
|
#if 0
|
||||||
}
|
}
|
||||||
catch (error * err) {
|
catch (error * err) {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
value_t python_interpreter_t::functor_t::operator()(xml::xpath_t::scope_t * locals)
|
||||||
xml::xpath_t::scope_t * locals)
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (! PyCallable_Check(func.ptr())) {
|
if (! PyCallable_Check(func.ptr())) {
|
||||||
result = static_cast<const value_t&>(extract<value_t>(func.ptr()));
|
return extract<value_t>(func.ptr());
|
||||||
} else {
|
} else {
|
||||||
assert(locals->args.is_type(value_t::SEQUENCE));
|
if (locals->args.size() > 0) {
|
||||||
if (locals->args.as_sequence().size() > 0) {
|
|
||||||
list arglist;
|
list arglist;
|
||||||
for (value_t::sequence_t::const_iterator
|
foreach (const value_t& value, locals->args)
|
||||||
i = locals->args.as_sequence().begin();
|
arglist.append(value);
|
||||||
i != locals->args.as_sequence().end();
|
|
||||||
i++)
|
|
||||||
arglist.append(*i);
|
|
||||||
|
|
||||||
if (PyObject * val =
|
if (PyObject * val =
|
||||||
PyObject_CallObject(func.ptr(),
|
PyObject_CallObject(func.ptr(),
|
||||||
boost::python::tuple(arglist).ptr())) {
|
boost::python::tuple(arglist).ptr())) {
|
||||||
result = extract<value_t>(val)();
|
value_t result = extract<value_t>(val)();
|
||||||
Py_DECREF(val);
|
Py_DECREF(val);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
else if (PyObject * err = PyErr_Occurred()) {
|
else if (PyObject * err = PyErr_Occurred()) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
|
@ -203,7 +199,7 @@ void python_interpreter_t::functor_t::operator()(value_t& result,
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = call<value_t>(func.ptr());
|
return call<value_t>(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,
|
value_t python_interpreter_t::lambda_t::operator()
|
||||||
xml::xpath_t::scope_t * locals)
|
(xml::xpath_t::scope_t * locals)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
assert(locals->args.is_type(value_t::SEQUENCE));
|
assert(locals->args.size() == 1);
|
||||||
assert(locals->args.as_sequence().size() == 1);
|
|
||||||
value_t item = locals->args[0];
|
value_t item = locals->args[0];
|
||||||
assert(item.is_type(value_t::POINTER));
|
assert(item.is_type(value_t::XML_NODE));
|
||||||
result = call<value_t>(func.ptr(), item.as_xml_node());
|
return call<value_t>(func.ptr(), item.as_xml_node());
|
||||||
}
|
}
|
||||||
catch (const error_already_set&) {
|
catch (const error_already_set&) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ class python_interpreter_t : public xml::xpath_t::scope_t
|
||||||
boost::python::object func;
|
boost::python::object func;
|
||||||
public:
|
public:
|
||||||
functor_t(const string& name, boost::python::object _func) : func(_func) {}
|
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) {
|
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 {
|
class lambda_t : public functor_t {
|
||||||
public:
|
public:
|
||||||
lambda_t(boost::python::object code) : functor_t("<lambda>", code) {}
|
lambda_t(boost::python::object code) : functor_t("<lambda>", code) {}
|
||||||
virtual void operator()(value_t& result, xml::xpath_t::scope_t * locals);
|
virtual value_t operator()(xml::xpath_t::scope_t * locals);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ void report_t::apply_transforms(xml::document_t& document)
|
||||||
transform.execute(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)
|
if (locals->args.size() < 2)
|
||||||
throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
|
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)
|
if (locals->args.size() == 4)
|
||||||
abbrev_len = locals->args[3].as_long();
|
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)
|
if (locals->args.size() < 1)
|
||||||
throw_(std::logic_error, "usage: ftime(DATE [, DATE_FORMAT])");
|
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
|
else
|
||||||
date_format = moment_t::output_format;
|
date_format = moment_t::output_format;
|
||||||
|
|
||||||
result.set_string(date.as_string(date_format));
|
return value_t(date.as_string(date_format), true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,14 +89,14 @@ bool report_t::resolve(const string& name, value_t& result,
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case 'a':
|
case 'a':
|
||||||
if (name == "abbrev") {
|
if (name == "abbrev") {
|
||||||
abbrev(result, locals);
|
result = abbrev(locals);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
if (name == "ftime") {
|
if (name == "ftime") {
|
||||||
ftime(result, locals);
|
result = ftime(locals);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -116,7 +116,7 @@ xml::xpath_t::ptr_op_t report_t::lookup(const string& name)
|
||||||
case 'a':
|
case 'a':
|
||||||
#if 0
|
#if 0
|
||||||
if (std::strcmp(p, "accounts") == 0)
|
if (std::strcmp(p, "accounts") == 0)
|
||||||
return MAKE_FUNCTOR(report_t, option_accounts);
|
return MAKE_FUNCTOR(report_t::option_accounts);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (std::strcmp(p, "amount") == 0)
|
if (std::strcmp(p, "amount") == 0)
|
||||||
|
|
|
||||||
36
src/report.h
36
src/report.h
|
|
@ -80,8 +80,8 @@ class report_t : public xml::xpath_t::scope_t
|
||||||
// Utility functions for value expressions
|
// Utility functions for value expressions
|
||||||
//
|
//
|
||||||
|
|
||||||
void ftime(value_t& result, xml::xpath_t::scope_t * locals);
|
value_t ftime(xml::xpath_t::scope_t * locals);
|
||||||
void abbrev(value_t& result, xml::xpath_t::scope_t * locals);
|
value_t abbrev(xml::xpath_t::scope_t * locals);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Config options
|
// 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);
|
xml::xpath_t(expr).compile((xml::document_t *)NULL, this);
|
||||||
#endif
|
#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());
|
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());
|
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());
|
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();
|
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;
|
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;
|
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;
|
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
|
#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()));
|
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[") +
|
string expr = (string("//xact[") +
|
||||||
locals->args[0].as_string() + "]");
|
locals->args[0].as_string() + "]");
|
||||||
transforms.push_back(new select_transform(expr));
|
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()));
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
transforms.push_back(new merge_transform);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -188,11 +188,11 @@ class session_t : public xml::xpath_t::scope_t
|
||||||
// Debug options
|
// Debug options
|
||||||
//
|
//
|
||||||
|
|
||||||
void option_trace_(value_t&, xml::xpath_t::scope_t * locals) {}
|
value_t option_trace_(xml::xpath_t::scope_t * locals) {}
|
||||||
void option_debug_(value_t&, 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 *) {}
|
value_t option_verify(xml::xpath_t::scope_t *) {}
|
||||||
void option_verbose(value_t&, xml::xpath_t::scope_t *) {
|
value_t option_verbose(xml::xpath_t::scope_t *) {
|
||||||
#if defined(LOGGING_ON)
|
#if defined(LOGGING_ON)
|
||||||
if (_log_level < LOG_INFO)
|
if (_log_level < LOG_INFO)
|
||||||
_log_level = LOG_INFO;
|
_log_level = LOG_INFO;
|
||||||
|
|
@ -203,16 +203,17 @@ class session_t : public xml::xpath_t::scope_t
|
||||||
// Option handlers
|
// Option handlers
|
||||||
//
|
//
|
||||||
|
|
||||||
void option_file_(value_t&, xml::xpath_t::scope_t * locals) {
|
value_t option_file_(xml::xpath_t::scope_t * locals) {
|
||||||
data_file = locals->args.as_string();
|
assert(locals->args.size() == 1);
|
||||||
|
data_file = locals->args[0].as_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#if defined(USE_BOOST_PYTHON)
|
#if defined(USE_BOOST_PYTHON)
|
||||||
void option_import_(value_t&) {
|
value_t option_import_(xml::xpath_t::scope_t * locals) {
|
||||||
python_import(optarg);
|
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);
|
python_eval(std::cin, PY_EVAL_MULTI);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -967,7 +967,8 @@ void value_t::in_place_cast(type_t cast_type)
|
||||||
}
|
}
|
||||||
else if (cast_type == SEQUENCE) {
|
else if (cast_type == SEQUENCE) {
|
||||||
sequence_t temp;
|
sequence_t temp;
|
||||||
temp.push_back(*this);
|
if (! is_null())
|
||||||
|
temp.push_back(*this);
|
||||||
set_sequence(temp);
|
set_sequence(temp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
156
src/xpath.cc
156
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 xpath_t::wrap_value(const value_t& val)
|
||||||
{
|
{
|
||||||
xpath_t::ptr_op_t temp(new xpath_t::op_t(xpath_t::op_t::VALUE));
|
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;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -522,7 +522,7 @@ xpath_t::parse_value_term(std::istream& in, flags_t tflags) const
|
||||||
switch (tok.kind) {
|
switch (tok.kind) {
|
||||||
case token_t::VALUE:
|
case token_t::VALUE:
|
||||||
node = new op_t(op_t::VALUE);
|
node = new op_t(op_t::VALUE);
|
||||||
node->set_value(new value_t(tok.value));
|
node->set_value(tok.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case token_t::IDENT: {
|
case token_t::IDENT: {
|
||||||
|
|
@ -1050,7 +1050,7 @@ xpath_t::op_t::copy(ptr_op_t tleft, ptr_op_t tright) const
|
||||||
return node;
|
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,
|
value_t::sequence_t& result_seq,
|
||||||
bool recursive)
|
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() &&
|
if (expr.ptr->is_value() &&
|
||||||
(expr.ptr->as_value().is_xml_node() ||
|
(expr.ptr->as_value().is_xml_node() ||
|
||||||
expr.ptr->as_value().is_sequence()))
|
expr.ptr->as_value().is_sequence()))
|
||||||
append_value(expr.ptr->as_value(), result_seq);
|
append_value(result_seq, expr.ptr->as_value());
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive && context.is_parent_node())
|
||||||
if (context.is_type(value_t::XML_NODE)) {
|
foreach (node_t * node, context.as_parent_node())
|
||||||
node_t * ptr = context.as_xml_node();
|
find_values(*node, scope, result_seq, recursive);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
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;
|
return lit_seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xpath_t::op_t::append_value(value_t& val,
|
void xpath_t::op_t::append_value(value_t::sequence_t& result_seq, value_t& val)
|
||||||
value_t::sequence_t& result_seq)
|
|
||||||
{
|
{
|
||||||
if (val.is_type(value_t::SEQUENCE))
|
if (val.is_type(value_t::SEQUENCE))
|
||||||
std::for_each(val.as_sequence().begin(), val.as_sequence().end(),
|
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::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
|
#if 0
|
||||||
try {
|
try {
|
||||||
|
|
@ -1153,28 +1143,20 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve)
|
||||||
case NODE_ID:
|
case NODE_ID:
|
||||||
switch (as_name()) {
|
switch (as_name()) {
|
||||||
case document_t::CURRENT:
|
case document_t::CURRENT:
|
||||||
return wrap_value(context);
|
return wrap_value(&context);
|
||||||
|
|
||||||
case document_t::PARENT:
|
case document_t::PARENT:
|
||||||
if (! context.is_type(value_t::XML_NODE))
|
if (context.parent())
|
||||||
throw_(compile_error, "Referencing parent node from a non-node value");
|
return wrap_value(&*context.parent());
|
||||||
else if (context.as_xml_node()->parent())
|
|
||||||
return wrap_value(&*context.as_xml_node()->parent());
|
|
||||||
else
|
else
|
||||||
throw_(compile_error, "Referencing parent node from the root node");
|
throw_(compile_error, "Referencing parent node from the root node");
|
||||||
|
|
||||||
case document_t::ROOT:
|
case document_t::ROOT:
|
||||||
if (! context.is_type(value_t::XML_NODE))
|
return wrap_value(&context.document());
|
||||||
throw_(compile_error, "Referencing root node from a non-node value");
|
|
||||||
else
|
|
||||||
return wrap_value(&context.as_xml_node()->document());
|
|
||||||
|
|
||||||
case document_t::ALL: {
|
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;
|
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);
|
nodes.push_back(node);
|
||||||
return wrap_value(nodes);
|
return wrap_value(nodes);
|
||||||
}
|
}
|
||||||
|
|
@ -1185,42 +1167,39 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve)
|
||||||
// fall through...
|
// fall through...
|
||||||
|
|
||||||
case NODE_NAME:
|
case NODE_NAME:
|
||||||
if (context.is_xml_node()) {
|
if (resolve) {
|
||||||
node_t * ptr = context.as_xml_node();
|
// First, look up the symbol as a node name within the current
|
||||||
if (resolve) {
|
// context. If any exist, then return the set of names.
|
||||||
// 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()) {
|
if (context.is_parent_node()) {
|
||||||
value_t::sequence_t nodes;
|
value_t::sequence_t nodes;
|
||||||
|
|
||||||
foreach (node_t * node, ptr->as_parent_node()) {
|
foreach (node_t * node, context.as_parent_node()) {
|
||||||
if ((kind == NODE_NAME &&
|
if ((kind == NODE_NAME &&
|
||||||
std::strcmp(as_string().c_str(), node->name()) == 0) ||
|
std::strcmp(as_string().c_str(), node->name()) == 0) ||
|
||||||
(kind == NODE_ID && as_name() == node->name_id()))
|
(kind == NODE_ID && as_name() == node->name_id()))
|
||||||
nodes.push_back(node);
|
nodes.push_back(node);
|
||||||
}
|
|
||||||
return wrap_value(nodes);
|
|
||||||
}
|
}
|
||||||
|
return wrap_value(nodes);
|
||||||
}
|
}
|
||||||
else if (optional<node_t::nameid_t> id =
|
}
|
||||||
ptr->document().lookup_name_id(as_string())) {
|
else if (optional<node_t::nameid_t> id =
|
||||||
ptr_op_t node = new_node(NODE_ID);
|
context.document().lookup_name_id(as_string())) {
|
||||||
node->set_name(*id);
|
ptr_op_t node = new_node(NODE_ID);
|
||||||
return node;
|
node->set_name(*id);
|
||||||
}
|
return node;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
case ATTR_ID:
|
case ATTR_ID:
|
||||||
if (optional<const string&> value = context.as_xml_node()->get_attr(as_long()))
|
if (optional<const string&> value = context.get_attr(as_long()))
|
||||||
return wrap_value(*value);
|
return wrap_value(*value);
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
case ATTR_NAME:
|
case ATTR_NAME:
|
||||||
if (optional<node_t::nameid_t> id =
|
if (optional<node_t::nameid_t> id =
|
||||||
context.as_xml_node()->document().lookup_name_id(as_string())) {
|
context.document().lookup_name_id(as_string())) {
|
||||||
if (optional<const string&> value = context.as_xml_node()->get_attr(*id))
|
if (optional<const string&> value = context.get_attr(*id))
|
||||||
return wrap_value(*value);
|
return wrap_value(*value);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -1240,9 +1219,8 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve)
|
||||||
|
|
||||||
case ARG_INDEX:
|
case ARG_INDEX:
|
||||||
if (scope && scope->kind == scope_t::ARGUMENT) {
|
if (scope && scope->kind == scope_t::ARGUMENT) {
|
||||||
assert(scope->args.is_type(value_t::SEQUENCE));
|
if (as_long() < scope->args.size())
|
||||||
if (as_long() < scope->args.as_sequence().size())
|
return wrap_value(scope->args[as_long()]);
|
||||||
return wrap_value(scope->args.as_sequence()[as_long()]);
|
|
||||||
else
|
else
|
||||||
throw_(compile_error, "Reference to non-existing argument");
|
throw_(compile_error, "Reference to non-existing argument");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1250,13 +1228,10 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve)
|
||||||
}
|
}
|
||||||
|
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
if (resolve) {
|
if (resolve)
|
||||||
value_t temp;
|
return wrap_value(as_function()(scope));
|
||||||
as_function()(temp, scope);
|
else
|
||||||
return wrap_value(temp);
|
|
||||||
} else {
|
|
||||||
return this;
|
return this;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_NOT: {
|
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);
|
return wrap_value(true);
|
||||||
} else {
|
} else {
|
||||||
if (expr.ptr->as_value().strip_annotations())
|
if (expr.ptr->as_value().strip_annotations())
|
||||||
expr.ptr->set_value(new value_t(false));
|
expr.ptr->set_value(false);
|
||||||
else
|
else
|
||||||
expr.ptr->set_value(new value_t(true));
|
expr.ptr->set_value(true);
|
||||||
|
|
||||||
return expr.ptr;
|
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;
|
value_t::sequence_t result_seq;
|
||||||
|
|
||||||
append_value(lexpr.ptr->as_value(), result_seq);
|
append_value(result_seq, lexpr.ptr->as_value());
|
||||||
append_value(rexpr.ptr->as_value(), result_seq);
|
append_value(result_seq, rexpr.ptr->as_value());
|
||||||
|
|
||||||
return wrap_value(result_seq);
|
return wrap_value(result_seq);
|
||||||
}
|
}
|
||||||
|
|
@ -1393,22 +1368,22 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve)
|
||||||
} else {
|
} else {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case O_NEQ:
|
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;
|
break;
|
||||||
case O_EQ:
|
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;
|
break;
|
||||||
case O_LT:
|
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;
|
break;
|
||||||
case O_LTE:
|
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;
|
break;
|
||||||
case O_GT:
|
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;
|
break;
|
||||||
case O_GTE:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -1421,7 +1396,7 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve)
|
||||||
case O_AND: {
|
case O_AND: {
|
||||||
xpath_t lexpr(left()->compile(context, scope, resolve));
|
xpath_t lexpr(left()->compile(context, scope, resolve));
|
||||||
if (lexpr.ptr->is_value() && ! lexpr.ptr->as_value().strip_annotations()) {
|
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;
|
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) {
|
if (left() == lexpr.ptr) {
|
||||||
return wrap_value(false);
|
return wrap_value(false);
|
||||||
} else {
|
} else {
|
||||||
lexpr.ptr->set_value(new value_t(false));
|
lexpr.ptr->set_value(false);
|
||||||
return lexpr.ptr;
|
return lexpr.ptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1464,7 +1439,7 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve)
|
||||||
if (left() == lexpr.ptr) {
|
if (left() == lexpr.ptr) {
|
||||||
return wrap_value(false);
|
return wrap_value(false);
|
||||||
} else {
|
} else {
|
||||||
lexpr.ptr->set_value(new value_t(false));
|
lexpr.ptr->set_value(false);
|
||||||
return lexpr.ptr;
|
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
|
// get resolved before we have a chance to call it
|
||||||
xpath_t func(left()->compile(context, scope, false));
|
xpath_t func(left()->compile(context, scope, false));
|
||||||
if (func.ptr->kind == FUNCTION) {
|
if (func.ptr->kind == FUNCTION) {
|
||||||
value_t temp;
|
return wrap_value(func.ptr->as_function()(call_args.get()));
|
||||||
func.ptr->as_function()(temp, call_args.get());
|
|
||||||
return wrap_value(temp);
|
|
||||||
}
|
}
|
||||||
else if (! resolve) {
|
else if (! resolve) {
|
||||||
return func.ptr->compile(context, call_args.get(), 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) {
|
else if (left()->kind == FUNCTION) {
|
||||||
value_t temp;
|
return wrap_value(left()->as_function()(call_args.get()));
|
||||||
left()->as_function()(temp, call_args.get());
|
|
||||||
return wrap_value(temp);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(false);
|
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());
|
value_t& value(lexpr.ptr->as_value());
|
||||||
function_scope_t xpath_fscope(*value.as_xml_node(), 0, 1, scope);
|
function_scope_t xpath_fscope(*value.as_xml_node(), 0, 1, scope);
|
||||||
if (kind == O_PRED) {
|
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);
|
result_seq.push_back(value);
|
||||||
} else {
|
} else {
|
||||||
rexpr.ptr->find_values(value, &xpath_fscope, result_seq,
|
rexpr.ptr->find_values(*value.as_xml_node(), &xpath_fscope,
|
||||||
kind == O_RFIND);
|
result_seq, kind == O_RFIND);
|
||||||
}
|
}
|
||||||
break;
|
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);
|
function_scope_t xpath_fscope(seq, *(*i).as_xml_node(), index, scope);
|
||||||
if (kind == O_PRED) {
|
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);
|
result_seq.push_back(*i);
|
||||||
} else {
|
} 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);
|
kind == O_RFIND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1684,16 +1655,15 @@ xpath_t::op_t::compile(const value_t& context, scope_t * scope, bool resolve)
|
||||||
return NULL;
|
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
|
#if 0
|
||||||
try {
|
try {
|
||||||
#endif
|
#endif
|
||||||
value_t context_node(&node);
|
xpath_t final(ptr->compile(context, scope, true));
|
||||||
xpath_t final(ptr->compile(context_node, scope, true));
|
|
||||||
// jww (2006-09-09): Give a better error here if this is not
|
// jww (2006-09-09): Give a better error here if this is not
|
||||||
// actually a value
|
// actually a value
|
||||||
result = final.ptr->as_value();
|
return final.ptr->as_value();
|
||||||
#if 0
|
#if 0
|
||||||
}
|
}
|
||||||
catch (error * err) {
|
catch (error * err) {
|
||||||
|
|
|
||||||
78
src/xpath.h
78
src/xpath.h
|
|
@ -53,10 +53,10 @@ public:
|
||||||
public:
|
public:
|
||||||
class scope_t;
|
class scope_t;
|
||||||
|
|
||||||
typedef function<void (value_t&, scope_t *)> function_t;
|
typedef function<value_t (scope_t *)> function_t;
|
||||||
|
|
||||||
#define MAKE_FUNCTOR(x) \
|
#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_value(const value_t& val);
|
||||||
static ptr_op_t wrap_functor(const function_t& fobj);
|
static ptr_op_t wrap_functor(const function_t& fobj);
|
||||||
|
|
@ -68,8 +68,8 @@ public:
|
||||||
symbol_map symbols;
|
symbol_map symbols;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
scope_t * parent;
|
scope_t * parent;
|
||||||
value_t args;
|
value_t::sequence_t args;
|
||||||
|
|
||||||
enum kind_t { NORMAL, STATIC, ARGUMENT } kind;
|
enum kind_t { NORMAL, STATIC, ARGUMENT } kind;
|
||||||
|
|
||||||
|
|
@ -84,6 +84,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void define(const string& name, ptr_op_t def);
|
virtual void define(const string& name, ptr_op_t def);
|
||||||
|
// jww (2007-05-15): ??
|
||||||
virtual bool resolve(const string& name, value_t& result,
|
virtual bool resolve(const string& name, value_t& result,
|
||||||
scope_t * locals = NULL) {
|
scope_t * locals = NULL) {
|
||||||
if (parent)
|
if (parent)
|
||||||
|
|
@ -244,9 +245,11 @@ public:
|
||||||
public:
|
public:
|
||||||
path_t(const xpath_t& path_expr);
|
path_t(const xpath_t& path_expr);
|
||||||
|
|
||||||
void find_all(value_t::sequence_t& result,
|
value_t find_all(node_t& start, scope_t * scope) {
|
||||||
node_t& start, scope_t * scope) {
|
value_t result = value_t::sequence_t();
|
||||||
visit(start, scope, value_node_appender_t(result));
|
visit(start, scope,
|
||||||
|
value_node_appender_t(result.as_sequence_lval()));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(node_t& start, scope_t * scope,
|
void visit(node_t& start, scope_t * scope,
|
||||||
|
|
@ -374,7 +377,7 @@ public:
|
||||||
ptr_op_t left_;
|
ptr_op_t left_;
|
||||||
|
|
||||||
variant<unsigned int, // used by ARG_INDEX and O_ARG
|
variant<unsigned int, // used by ARG_INDEX and O_ARG
|
||||||
shared_ptr<value_t>, // used by constant VALUE
|
value_t, // used by constant VALUE
|
||||||
string, // used by constant SYMBOL
|
string, // used by constant SYMBOL
|
||||||
function_t, // used by terminal FUNCTION
|
function_t, // used by terminal FUNCTION
|
||||||
node_t::nameid_t, // used by NODE_NAME and ATTR_NAME
|
node_t::nameid_t, // used by NODE_NAME and ATTR_NAME
|
||||||
|
|
@ -412,16 +415,13 @@ public:
|
||||||
}
|
}
|
||||||
value_t& as_value() {
|
value_t& as_value() {
|
||||||
assert(kind == VALUE);
|
assert(kind == VALUE);
|
||||||
value_t * val = boost::get<shared_ptr<value_t> >(data).get();
|
return boost::get<value_t>(data);
|
||||||
assert(val);
|
|
||||||
return *val;
|
|
||||||
}
|
}
|
||||||
const value_t& as_value() const {
|
const value_t& as_value() const {
|
||||||
return const_cast<op_t *>(this)->as_value();
|
return const_cast<op_t *>(this)->as_value();
|
||||||
}
|
}
|
||||||
void set_value(value_t * val) {
|
void set_value(const value_t& val) {
|
||||||
// jww (2007-05-14): Ugh, fix this
|
data = val;
|
||||||
data = shared_ptr<value_t>(val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_string() const {
|
bool is_string() const {
|
||||||
|
|
@ -533,13 +533,13 @@ public:
|
||||||
ptr_op_t right = NULL);
|
ptr_op_t right = NULL);
|
||||||
|
|
||||||
ptr_op_t copy(ptr_op_t left = NULL, ptr_op_t right = NULL) const;
|
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);
|
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);
|
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) {}
|
op_predicate(ptr_op_t _op) : op(_op) {}
|
||||||
|
|
||||||
bool operator()(node_t& node, scope_t * scope) {
|
bool operator()(node_t& node, scope_t * scope) {
|
||||||
value_t context_node(&node);
|
xpath_t result(op->compile(node, scope, true));
|
||||||
xpath_t result(op->compile(context_node, scope, true));
|
|
||||||
return result.ptr->as_value().to_boolean();
|
return result.ptr->as_value().to_boolean();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -727,47 +726,25 @@ public:
|
||||||
ptr = parse_expr(in, _flags);
|
ptr = parse_expr(in, _flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile(node_t& top_node, scope_t * scope = NULL) {
|
void compile(const node_t& context, scope_t * scope = NULL) {
|
||||||
if (ptr.get()) {
|
if (ptr.get())
|
||||||
value_t noderef(&top_node);
|
ptr = ptr->compile(context, scope);
|
||||||
ptr = ptr->compile(noderef, scope);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void calc(value_t& result, node_t& node,
|
virtual value_t calc(const node_t& context, scope_t * scope = NULL) const;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void eval(value_t& result, 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);
|
|
||||||
temp.calc(result, top, scope);
|
|
||||||
}
|
|
||||||
static value_t eval(const string& _expr, node_t& top,
|
|
||||||
scope_t * scope = NULL) {
|
scope_t * scope = NULL) {
|
||||||
xpath_t temp(_expr);
|
return xpath_t(_expr).calc(context, scope);
|
||||||
return temp.calc(top, 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) {
|
path_iterator_t find_all(node_t& start, scope_t * scope) {
|
||||||
return path_iterator_t(*this, start, scope);
|
return path_iterator_t(*this, start, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(node_t& start, scope_t * scope,
|
void visit(node_t& start, scope_t * scope,
|
||||||
const function<void (node_t&)>& func) {
|
const function<void (node_t&)>& func) {
|
||||||
path_t path(*this);
|
path_t(*this).visit(start, scope, func);
|
||||||
path.visit(start, scope, func);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(std::ostream& out, xml::document_t& document) const {
|
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
|
class xml_command
|
||||||
{
|
{
|
||||||
public:
|
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<std::ostream>(locals, 0);
|
std::ostream * out = get_ptr<std::ostream>(locals, 0);
|
||||||
xml::document_t * doc = get_node_ptr<xml::document_t>(locals, 1);
|
xml::document_t * doc = get_node_ptr<xml::document_t>(locals, 1);
|
||||||
doc->print(*out);
|
doc->print(*out);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue