Everything is working again except for predicates.
This commit is contained in:
parent
b6ab7deb63
commit
bf2c8c0f48
6 changed files with 149 additions and 159 deletions
22
src/main.cc
22
src/main.cc
|
|
@ -145,15 +145,27 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||||
xml::xpath_t expr(*arg);
|
xml::xpath_t expr(*arg);
|
||||||
xml::document_t temp(xml::LEDGER_NODE);
|
xml::document_t temp(xml::LEDGER_NODE);
|
||||||
|
|
||||||
xml::xpath_t::document_scope_t doc_scope(report, temp);
|
xml::xpath_t::context_scope_t doc_scope(report, temp);
|
||||||
|
|
||||||
IF_INFO() {
|
IF_INFO() {
|
||||||
std::cout << "Value expression tree:" << std::endl;
|
std::cout << "Value expression tree:" << std::endl;
|
||||||
expr.dump(std::cout);
|
expr.dump(std::cout);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::cout << "Value expression parsed was:" << std::endl;
|
std::cout << "Value expression parsed was:" << std::endl;
|
||||||
expr.print(std::cout, doc_scope);
|
expr.print(std::cout, doc_scope);
|
||||||
std::cout << std::endl << std::endl;
|
std::cout << std::endl << std::endl;
|
||||||
|
|
||||||
|
expr.compile(doc_scope);
|
||||||
|
|
||||||
|
std::cout << "Value expression after compiling:" << std::endl;
|
||||||
|
expr.dump(std::cout);
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
std::cout << "Value expression is now:" << std::endl;
|
||||||
|
expr.print(std::cout, doc_scope);
|
||||||
|
std::cout << std::endl << std::endl;
|
||||||
|
|
||||||
std::cout << "Result of calculation: ";
|
std::cout << "Result of calculation: ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,7 +260,7 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||||
|
|
||||||
// Are we handling the expr commands? Do so now.
|
// Are we handling the expr commands? Do so now.
|
||||||
|
|
||||||
xml::xpath_t::document_scope_t doc_scope(report, xml_document);
|
xml::xpath_t::context_scope_t doc_scope(report, xml_document);
|
||||||
|
|
||||||
if (verb == "expr") {
|
if (verb == "expr") {
|
||||||
xml::xpath_t expr(*arg);
|
xml::xpath_t expr(*arg);
|
||||||
|
|
@ -268,14 +280,13 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (verb == "xpath") {
|
else if (verb == "xpath") {
|
||||||
std::cout << "XPath parsed:" << std::endl;
|
std::cout << "XPath parsed:";
|
||||||
|
|
||||||
xml::xpath_t xpath(*arg);
|
xml::xpath_t xpath(*arg);
|
||||||
xpath.print(*out, doc_scope);
|
xpath.print(*out, doc_scope);
|
||||||
*out << std::endl;
|
*out << std::endl;
|
||||||
|
|
||||||
#if 0
|
foreach (const value_t& value, xpath.find_all(doc_scope)) {
|
||||||
foreach (const value_t& value, xpath.find_all(xml_document, report)) {
|
|
||||||
if (value.is_xml_node()) {
|
if (value.is_xml_node()) {
|
||||||
value.as_xml_node()->print(std::cout);
|
value.as_xml_node()->print(std::cout);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -283,7 +294,6 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ void trace_ctor_func(void * ptr, const char * cls_name, const char * args,
|
||||||
std::strcat(name, args);
|
std::strcat(name, args);
|
||||||
std::strcat(name, ")");
|
std::strcat(name, ")");
|
||||||
|
|
||||||
DEBUG("verify.memory", "TRACE_CTOR " << ptr << " " << name);
|
DEBUG("memory.debug", "TRACE_CTOR " << ptr << " " << name);
|
||||||
|
|
||||||
live_objects->insert
|
live_objects->insert
|
||||||
(live_objects_map::value_type(ptr, allocation_pair(cls_name, cls_size)));
|
(live_objects_map::value_type(ptr, allocation_pair(cls_name, cls_size)));
|
||||||
|
|
@ -303,7 +303,7 @@ void trace_dtor_func(void * ptr, const char * cls_name, std::size_t cls_size)
|
||||||
|
|
||||||
if (! live_objects) return;
|
if (! live_objects) return;
|
||||||
|
|
||||||
DEBUG("ledger.trace.debug", "TRACE_DTOR " << ptr << " " << cls_name);
|
DEBUG("memory.debug", "TRACE_DTOR " << ptr << " " << cls_name);
|
||||||
|
|
||||||
live_objects_map::iterator i = live_objects->find(ptr);
|
live_objects_map::iterator i = live_objects->find(ptr);
|
||||||
VERIFY(i != live_objects->end());
|
VERIFY(i != live_objects->end());
|
||||||
|
|
|
||||||
|
|
@ -1371,6 +1371,7 @@ value_t value_t::strip_annotations(const bool keep_price,
|
||||||
const bool keep_tag) const
|
const bool keep_tag) const
|
||||||
{
|
{
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
|
case VOID:
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
case DATETIME:
|
case DATETIME:
|
||||||
|
|
@ -1551,6 +1552,9 @@ void value_t::print(std::ostream& out, const int first_width,
|
||||||
std::ostream& operator<<(std::ostream& out, const value_t& val)
|
std::ostream& operator<<(std::ostream& out, const value_t& val)
|
||||||
{
|
{
|
||||||
switch (val.type()) {
|
switch (val.type()) {
|
||||||
|
case value_t::VOID:
|
||||||
|
out << "VOID";
|
||||||
|
break;
|
||||||
case value_t::BOOLEAN:
|
case value_t::BOOLEAN:
|
||||||
out << (val.as_boolean() ? "true" : "false");
|
out << (val.as_boolean() ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
22
src/value.h
22
src/value.h
|
|
@ -216,12 +216,12 @@ public:
|
||||||
TRACE_CTOR(value_t, "const sequence_t&");
|
TRACE_CTOR(value_t, "const sequence_t&");
|
||||||
set_sequence(val);
|
set_sequence(val);
|
||||||
}
|
}
|
||||||
value_t(xml::node_t * xml_node) {
|
value_t(xml::node_t * item) {
|
||||||
TRACE_CTOR(value_t, "xml::node_t *");
|
TRACE_CTOR(value_t, "xml::node_t *");
|
||||||
set_xml_node(xml_node);
|
set_xml_node(item);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
value_t(T * item) {
|
explicit value_t(T * item) {
|
||||||
TRACE_CTOR(value_t, "T *");
|
TRACE_CTOR(value_t, "T *");
|
||||||
set_pointer(item);
|
set_pointer(item);
|
||||||
}
|
}
|
||||||
|
|
@ -230,8 +230,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t& operator=(const value_t& val) {
|
value_t& operator=(const value_t& val) {
|
||||||
if (this == &val || storage == val.storage)
|
if (! (this == &val || storage == val.storage))
|
||||||
return *this;
|
|
||||||
storage = val.storage;
|
storage = val.storage;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -537,11 +536,14 @@ public:
|
||||||
if (! is_sequence())
|
if (! is_sequence())
|
||||||
in_place_cast(SEQUENCE);
|
in_place_cast(SEQUENCE);
|
||||||
|
|
||||||
if (! val.is_sequence())
|
value_t::sequence_t& seq(as_sequence_lval());
|
||||||
as_sequence_lval().push_back(val);
|
if (! val.is_sequence()) {
|
||||||
else
|
if (! val.is_null())
|
||||||
std::copy(val.as_sequence().begin(), val.as_sequence().end(),
|
seq.push_back(val);
|
||||||
as_sequence_lval().end());
|
} else {
|
||||||
|
const value_t::sequence_t& val_seq(val.as_sequence());
|
||||||
|
std::copy(val_seq.begin(), val_seq.end(), back_inserter(seq));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
139
src/xpath.cc
139
src/xpath.cc
|
|
@ -414,7 +414,6 @@ void xpath_t::symbol_scope_t::define(const string& name, ptr_op_t def)
|
||||||
if (! result.second) {
|
if (! result.second) {
|
||||||
symbol_map::iterator i = symbols.find(name);
|
symbol_map::iterator i = symbols.find(name);
|
||||||
assert(i != symbols.end());
|
assert(i != symbols.end());
|
||||||
(*i).second->release();
|
|
||||||
symbols.erase(i);
|
symbols.erase(i);
|
||||||
|
|
||||||
std::pair<symbol_map::iterator, bool> result2
|
std::pair<symbol_map::iterator, bool> result2
|
||||||
|
|
@ -423,7 +422,6 @@ void xpath_t::symbol_scope_t::define(const string& name, ptr_op_t def)
|
||||||
throw_(compile_error,
|
throw_(compile_error,
|
||||||
"Redefinition of '" << name << "' in same scope");
|
"Redefinition of '" << name << "' in same scope");
|
||||||
}
|
}
|
||||||
def->acquire();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xpath_t::scope_t::define(const string& name, const value_t& val) {
|
void xpath_t::scope_t::define(const string& name, const value_t& val) {
|
||||||
|
|
@ -432,21 +430,21 @@ void xpath_t::scope_t::define(const string& name, const value_t& val) {
|
||||||
|
|
||||||
value_t xpath_fn_last(xpath_t::call_scope_t& scope)
|
value_t xpath_fn_last(xpath_t::call_scope_t& scope)
|
||||||
{
|
{
|
||||||
xpath_t::context_scope_t& context(FIND_SCOPE(xpath_t::context_scope_t, scope));
|
xpath_t::context_scope_t& context(CONTEXT_SCOPE(scope));
|
||||||
|
|
||||||
return context.size();
|
return context.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t xpath_fn_position(xpath_t::call_scope_t& scope)
|
value_t xpath_fn_position(xpath_t::call_scope_t& scope)
|
||||||
{
|
{
|
||||||
xpath_t::context_scope_t& context(FIND_SCOPE(xpath_t::context_scope_t, scope));
|
xpath_t::context_scope_t& context(CONTEXT_SCOPE(scope));
|
||||||
|
|
||||||
return context.index();
|
return context.index();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t xpath_fn_text(xpath_t::call_scope_t& scope)
|
value_t xpath_fn_text(xpath_t::call_scope_t& scope)
|
||||||
{
|
{
|
||||||
xpath_t::context_scope_t& context(FIND_SCOPE(xpath_t::context_scope_t, scope));
|
xpath_t::context_scope_t& context(CONTEXT_SCOPE(scope));
|
||||||
|
|
||||||
return value_t(context.xml_node().to_value().to_string(), true);
|
return value_t(context.xml_node().to_value().to_string(), true);
|
||||||
}
|
}
|
||||||
|
|
@ -971,6 +969,9 @@ xpath_t::ptr_op_t xpath_t::op_t::compile(scope_t& scope)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kind < TERMINALS)
|
||||||
|
return this;
|
||||||
|
|
||||||
ptr_op_t lhs(left()->compile(scope));
|
ptr_op_t lhs(left()->compile(scope));
|
||||||
ptr_op_t rhs(right() ? right()->compile(scope) : ptr_op_t());
|
ptr_op_t rhs(right() ? right()->compile(scope) : ptr_op_t());
|
||||||
|
|
||||||
|
|
@ -987,16 +988,46 @@ xpath_t::ptr_op_t xpath_t::op_t::compile(scope_t& scope)
|
||||||
|
|
||||||
value_t xpath_t::op_t::current_value(scope_t& scope)
|
value_t xpath_t::op_t::current_value(scope_t& scope)
|
||||||
{
|
{
|
||||||
xpath_t::context_scope_t& context(FIND_SCOPE(xpath_t::context_scope_t, scope));
|
xpath_t::context_scope_t& context(CONTEXT_SCOPE(scope));
|
||||||
return context.value();
|
return context.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
node_t& xpath_t::op_t::current_xml_node(scope_t& scope)
|
node_t& xpath_t::op_t::current_xml_node(scope_t& scope)
|
||||||
{
|
{
|
||||||
xpath_t::context_scope_t& context(FIND_SCOPE(xpath_t::context_scope_t, scope));
|
xpath_t::context_scope_t& context(CONTEXT_SCOPE(scope));
|
||||||
return context.xml_node();
|
return context.xml_node();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
value_t search_nodes(value_t nodes, xpath_t::ptr_op_t find_op,
|
||||||
|
xpath_t::scope_t& scope, bool recurse)
|
||||||
|
{
|
||||||
|
value_t node_sequence = nodes.to_sequence();
|
||||||
|
value_t result;
|
||||||
|
|
||||||
|
foreach (value_t& node_value, node_sequence.as_sequence_lval()) {
|
||||||
|
if (! node_value.is_xml_node())
|
||||||
|
throw_(xpath_t::calc_error,
|
||||||
|
"Application of / operator to non-node value '"
|
||||||
|
<< node_value << "'");
|
||||||
|
|
||||||
|
node_t& node(*node_value.as_xml_node());
|
||||||
|
xpath_t::context_scope_t node_scope(scope, node, node_sequence);
|
||||||
|
|
||||||
|
result.push_back(find_op->calc(node_scope));
|
||||||
|
|
||||||
|
if (recurse && node.is_parent_node()) {
|
||||||
|
value_t children;
|
||||||
|
foreach (node_t * child, node.as_parent_node())
|
||||||
|
children.push_back(child);
|
||||||
|
|
||||||
|
result.push_back(search_nodes(children, find_op, scope, recurse));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
value_t xpath_t::op_t::calc(scope_t& scope)
|
value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
{
|
{
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
|
|
@ -1021,6 +1052,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
case O_CALL: {
|
case O_CALL: {
|
||||||
call_scope_t call_args(scope);
|
call_scope_t call_args(scope);
|
||||||
|
|
||||||
|
if (right())
|
||||||
call_args.set_args(right()->calc(scope));
|
call_args.set_args(right()->calc(scope));
|
||||||
|
|
||||||
ptr_op_t func = left();
|
ptr_op_t func = left();
|
||||||
|
|
@ -1045,36 +1077,13 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
if (as_long() >= 0 && as_long() < args.size())
|
if (as_long() >= 0 && as_long() < args.size())
|
||||||
return args[as_long()];
|
return args[as_long()];
|
||||||
else
|
else
|
||||||
throw_(compile_error, "Reference to a non-existing argument");
|
throw_(calc_error, "Reference to a non-existing argument");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case O_FIND:
|
case O_FIND:
|
||||||
case O_RFIND: {
|
case O_RFIND:
|
||||||
value_t result;
|
return search_nodes(left()->calc(scope), right(), scope, kind == O_RFIND);
|
||||||
|
|
||||||
if (value_t items = left()->calc(scope)) {
|
|
||||||
value_t sequence = items.to_sequence();
|
|
||||||
foreach (value_t& item, sequence.as_sequence_lval()) {
|
|
||||||
if (item.is_xml_node()) {
|
|
||||||
node_t& node(*item.as_xml_node());
|
|
||||||
node_scope_t node_scope(scope, node);
|
|
||||||
|
|
||||||
result.push_back(right()->calc(node_scope));
|
|
||||||
#if 0
|
|
||||||
// jww (2007-05-17): How do I get it to recurse down? I'll
|
|
||||||
// have to use a recursive helper function.
|
|
||||||
if (kind == O_RFIND && node.is_parent_node())
|
|
||||||
foreach (node_t * child, node.as_parent_node())
|
|
||||||
walk_elements(element->right(), scope, *child, NULL, func);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
throw_(compile_error, "Application of / operator to non-node value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
case NODE_ID:
|
case NODE_ID:
|
||||||
switch (as_name()) {
|
switch (as_name()) {
|
||||||
|
|
@ -1094,7 +1103,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
case document_t::ALL: {
|
case document_t::ALL: {
|
||||||
node_t& current_node(current_xml_node(scope));
|
node_t& current_node(current_xml_node(scope));
|
||||||
if (! current_node.is_parent_node())
|
if (! current_node.is_parent_node())
|
||||||
throw_(compile_error, "Referencing child nodes from a non-parent value");
|
throw_(calc_error, "Referencing child nodes from a non-parent value");
|
||||||
|
|
||||||
value_t result;
|
value_t result;
|
||||||
foreach (node_t * child, current_node.as_parent_node())
|
foreach (node_t * child, current_node.as_parent_node())
|
||||||
|
|
@ -1109,20 +1118,14 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
|
|
||||||
case NODE_NAME: {
|
case NODE_NAME: {
|
||||||
node_t& current_node(current_xml_node(scope));
|
node_t& current_node(current_xml_node(scope));
|
||||||
|
|
||||||
if (current_node.is_parent_node()) {
|
if (current_node.is_parent_node()) {
|
||||||
bool have_name_id = kind == NODE_ID;
|
bool have_name_id = kind == NODE_ID;
|
||||||
|
|
||||||
value_t result;
|
value_t result;
|
||||||
|
|
||||||
foreach (node_t * child, current_node.as_parent_node()) {
|
foreach (node_t * child, current_node.as_parent_node()) {
|
||||||
if (( have_name_id && as_name() == child->name_id()) ||
|
if (( have_name_id && as_name() == child->name_id()) ||
|
||||||
(! have_name_id && as_string() == child->name()))
|
(! have_name_id && as_string() == child->name()))
|
||||||
result.push_back(child);
|
result.push_back(child);
|
||||||
#if 0
|
|
||||||
else if (recurse)
|
|
||||||
/* ... */;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -1130,30 +1133,36 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
case O_PRED: {
|
case O_PRED: {
|
||||||
#if 0
|
value_t values = left()->calc(scope).to_sequence();
|
||||||
predicate_scope_t predicate_scope(scope, right());
|
value_t result;
|
||||||
return left()->calc(predicate_scope);
|
|
||||||
#endif
|
std::size_t index = 0;
|
||||||
break;
|
foreach (const value_t& value, values.as_sequence()) {
|
||||||
|
xpath_t::context_scope_t value_scope(scope, value);
|
||||||
|
|
||||||
|
value_t predval = right()->calc(value_scope);
|
||||||
|
if ((predval.is_long() &&
|
||||||
|
predval.as_long() == (long)index + 1) ||
|
||||||
|
predval.to_boolean())
|
||||||
|
result.push_back(value);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ATTR_ID:
|
case ATTR_ID:
|
||||||
case ATTR_NAME: {
|
case ATTR_NAME: {
|
||||||
context_scope_t& context(scope.find_scope<context_scope_t>());
|
node_t& current_node(current_xml_node(scope));
|
||||||
|
|
||||||
if (context.type() != scope_t::NODE_SCOPE)
|
|
||||||
throw_(calc_error, "Looking up attribute in a non-node context");
|
|
||||||
|
|
||||||
node_scope_t& node_scope(downcast<node_scope_t>(context));
|
|
||||||
|
|
||||||
if (optional<const string&> value =
|
if (optional<const string&> value =
|
||||||
kind == ATTR_ID ? node_scope.xml_node().get_attr(as_long()) :
|
kind == ATTR_ID ? current_node.get_attr(as_long()) :
|
||||||
node_scope.xml_node().get_attr(as_string()))
|
current_node.get_attr(as_string()))
|
||||||
return value_t(*value, true);
|
return value_t(*value, true);
|
||||||
else
|
else
|
||||||
throw_(calc_error, "Attribute '"
|
throw_(calc_error, "Attribute '"
|
||||||
<< (kind == ATTR_ID ?
|
<< (kind == ATTR_ID ?
|
||||||
*node_scope.xml_node().document().lookup_name(as_long()) :
|
*current_node.document().lookup_name(as_long()) :
|
||||||
as_string().c_str())
|
as_string().c_str())
|
||||||
<< "' was not found");
|
<< "' was not found");
|
||||||
break;
|
break;
|
||||||
|
|
@ -1243,6 +1252,8 @@ bool xpath_t::op_t::print(std::ostream& out, print_context_t& context) const
|
||||||
out << "0";
|
out << "0";
|
||||||
break;
|
break;
|
||||||
case value_t::INTEGER:
|
case value_t::INTEGER:
|
||||||
|
out << value;
|
||||||
|
break;
|
||||||
case value_t::AMOUNT:
|
case value_t::AMOUNT:
|
||||||
if (! context.relaxed)
|
if (! context.relaxed)
|
||||||
out << '{';
|
out << '{';
|
||||||
|
|
@ -1278,16 +1289,9 @@ bool xpath_t::op_t::print(std::ostream& out, print_context_t& context) const
|
||||||
out << '@';
|
out << '@';
|
||||||
// fall through...
|
// fall through...
|
||||||
case NODE_ID: {
|
case NODE_ID: {
|
||||||
context_scope_t& context_scope(context.scope.find_scope<context_scope_t>());
|
context_scope_t& node_scope(CONTEXT_SCOPE(context.scope));
|
||||||
|
if (optional<const char *> name =
|
||||||
if (context_scope.type() != scope_t::NODE_SCOPE)
|
node_scope.xml_node().document().lookup_name(as_name()))
|
||||||
throw_(calc_error, "Looking up node name in a non-node context");
|
|
||||||
|
|
||||||
node_scope_t& node_scope(downcast<node_scope_t>(context_scope));
|
|
||||||
|
|
||||||
optional<const char *> name =
|
|
||||||
node_scope.xml_node().document().lookup_name(as_name());
|
|
||||||
if (name)
|
|
||||||
out << *name;
|
out << *name;
|
||||||
else
|
else
|
||||||
out << '#' << as_name();
|
out << '#' << as_name();
|
||||||
|
|
@ -1308,7 +1312,7 @@ bool xpath_t::op_t::print(std::ostream& out, print_context_t& context) const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
out << as_function();
|
out << '<FUNCTION>';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_INDEX:
|
case ARG_INDEX:
|
||||||
|
|
@ -1544,7 +1548,7 @@ void xpath_t::op_t::dump(std::ostream& out, const int depth) const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
out << "FUNCTION - " << as_function();
|
out << "FUNCTION";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_CALL: out << "O_CALL"; break;
|
case O_CALL: out << "O_CALL"; break;
|
||||||
|
|
@ -1603,8 +1607,7 @@ value_t xml_command(xml::xpath_t::call_scope_t& args)
|
||||||
value_t ostream = args.resolve("ostream");
|
value_t ostream = args.resolve("ostream");
|
||||||
std::ostream& outs(ostream.as_ref_lval<std::ostream>());
|
std::ostream& outs(ostream.as_ref_lval<std::ostream>());
|
||||||
|
|
||||||
xml::xpath_t::node_scope_t& node_context
|
xml::xpath_t::context_scope_t& node_context(CONTEXT_SCOPE(args));
|
||||||
(FIND_SCOPE(xml::xpath_t::node_scope_t, args));
|
|
||||||
node_context.xml_node().print(outs);
|
node_context.xml_node().print(outs);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
109
src/xpath.h
109
src/xpath.h
|
|
@ -69,8 +69,9 @@ public:
|
||||||
SYMBOL_SCOPE,
|
SYMBOL_SCOPE,
|
||||||
CALL_SCOPE,
|
CALL_SCOPE,
|
||||||
CONTEXT_SCOPE,
|
CONTEXT_SCOPE,
|
||||||
NODE_SCOPE,
|
#if 0
|
||||||
PREDICATE_SCOPE
|
PREDICATE_SCOPE
|
||||||
|
#endif
|
||||||
} type_;
|
} type_;
|
||||||
|
|
||||||
explicit scope_t(type_t _type) : type_(_type) {
|
explicit scope_t(type_t _type) : type_(_type) {
|
||||||
|
|
@ -213,11 +214,30 @@ public:
|
||||||
explicit context_scope_t(scope_t& _parent,
|
explicit context_scope_t(scope_t& _parent,
|
||||||
const value_t& _element,
|
const value_t& _element,
|
||||||
const optional<value_t>& _sequence = none)
|
const optional<value_t>& _sequence = none)
|
||||||
: child_scope_t(_parent, CONTEXT_SCOPE),
|
: child_scope_t(_parent, CONTEXT_SCOPE)
|
||||||
element(_element), sequence(_sequence)
|
|
||||||
{
|
{
|
||||||
TRACE_CTOR(xpath_t::context_scope_t,
|
TRACE_CTOR(xpath_t::context_scope_t,
|
||||||
"scope_t&, const value_t&, const optional<value_t>&");
|
"scope_t&, const value_t&, const optional<value_t>&");
|
||||||
|
set_context(_element, _sequence);
|
||||||
|
}
|
||||||
|
explicit context_scope_t(scope_t& _parent,
|
||||||
|
node_t& _element,
|
||||||
|
const optional<value_t>& _sequence = none)
|
||||||
|
: child_scope_t(_parent, CONTEXT_SCOPE)
|
||||||
|
{
|
||||||
|
TRACE_CTOR(xpath_t::context_scope_t,
|
||||||
|
"scope_t&, const value_t&, const optional<value_t>&");
|
||||||
|
set_context(value_t(&_element), _sequence);
|
||||||
|
}
|
||||||
|
virtual ~context_scope_t() {
|
||||||
|
TRACE_DTOR(xpath_t::context_scope_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_context(const value_t& _element,
|
||||||
|
const optional<value_t>& _sequence) {
|
||||||
|
element = _element;
|
||||||
|
sequence = _sequence;
|
||||||
|
|
||||||
assert(! element.is_sequence());
|
assert(! element.is_sequence());
|
||||||
|
|
||||||
if (DO_VERIFY() && sequence) {
|
if (DO_VERIFY() && sequence) {
|
||||||
|
|
@ -230,9 +250,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual ~context_scope_t() {
|
|
||||||
TRACE_DTOR(xpath_t::context_scope_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::size_t index() const {
|
const std::size_t index() const {
|
||||||
if (! sequence) {
|
if (! sequence) {
|
||||||
|
|
@ -262,21 +279,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class node_scope_t : public context_scope_t
|
#if 0
|
||||||
{
|
|
||||||
public:
|
|
||||||
node_scope_t(scope_t& _parent, node_t& _node)
|
|
||||||
: context_scope_t(_parent, &_node) {
|
|
||||||
TRACE_CTOR(xpath_t::node_scope_t, "scope_t&, node_t&");
|
|
||||||
type_ = NODE_SCOPE;
|
|
||||||
}
|
|
||||||
virtual ~node_scope_t() {
|
|
||||||
TRACE_DTOR(xpath_t::node_scope_t);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef node_scope_t document_scope_t;
|
|
||||||
|
|
||||||
class predicate_scope_t : public child_scope_t
|
class predicate_scope_t : public child_scope_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -305,6 +308,7 @@ public:
|
||||||
return predicate->calc(context_scope).to_boolean();
|
return predicate->calc(context_scope).to_boolean();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#define XPATH_PARSE_NORMAL 0x00
|
#define XPATH_PARSE_NORMAL 0x00
|
||||||
#define XPATH_PARSE_PARTIAL 0x01
|
#define XPATH_PARSE_PARTIAL 0x01
|
||||||
|
|
@ -402,41 +406,27 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if 0
|
|
||||||
class path_iterator_t
|
class path_iterator_t
|
||||||
{
|
{
|
||||||
typedef NodeType * pointer;
|
typedef node_t * pointer;
|
||||||
typedef NodeType& reference;
|
typedef node_t& reference;
|
||||||
|
|
||||||
path_t path;
|
xpath_t& path_expr;
|
||||||
node_t& start;
|
|
||||||
scope_t& scope;
|
scope_t& scope;
|
||||||
|
|
||||||
mutable value_t::sequence_t sequence;
|
mutable value_t::sequence_t sequence;
|
||||||
mutable bool searched;
|
mutable bool searched;
|
||||||
|
|
||||||
struct node_appender_t {
|
|
||||||
value_t::sequence_t& sequence;
|
|
||||||
node_appender_t(value_t::sequence_t& _sequence)
|
|
||||||
: sequence(_sequence) {}
|
|
||||||
void operator()(const value_t& node) {
|
|
||||||
sequence.push_back(node);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef value_t::sequence_t::iterator iterator;
|
typedef value_t::sequence_t::iterator iterator;
|
||||||
typedef value_t::sequence_t::const_iterator const_iterator;
|
typedef value_t::sequence_t::const_iterator const_iterator;
|
||||||
|
|
||||||
path_iterator_t(const xpath_t& path_expr,
|
path_iterator_t(xpath_t& _path_expr, scope_t& _scope)
|
||||||
node_t& _start, scope_t& _scope)
|
: path_expr(_path_expr), scope(_scope), searched(false) {}
|
||||||
: path(path_expr), start(_start), scope(_scope),
|
|
||||||
searched(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() {
|
iterator begin() {
|
||||||
if (! searched) {
|
if (! searched) {
|
||||||
path.visit(start, scope, node_appender_t(sequence));
|
sequence = path_expr.calc(scope).to_sequence();
|
||||||
searched = true;
|
searched = true;
|
||||||
}
|
}
|
||||||
return sequence.begin();
|
return sequence.begin();
|
||||||
|
|
@ -448,7 +438,6 @@ public:
|
||||||
iterator end() { return sequence.end(); }
|
iterator end() { return sequence.end(); }
|
||||||
const_iterator end() const { return sequence.end(); }
|
const_iterator end() const { return sequence.end(); }
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
struct op_t : public noncopyable
|
struct op_t : public noncopyable
|
||||||
{
|
{
|
||||||
|
|
@ -857,24 +846,9 @@ public:
|
||||||
return xpath_t(_expr).calc(scope);
|
return xpath_t(_expr).calc(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
path_iterator_t find_all(scope_t& scope) {
|
||||||
path_iterator_t<node_t>
|
return path_iterator_t(*this, scope);
|
||||||
find_all(node_t& start, scope_t& scope) {
|
|
||||||
return path_iterator_t<node_t>(*this, start, scope);
|
|
||||||
}
|
}
|
||||||
path_iterator_t<const node_t>
|
|
||||||
find_all(const node_t& start, scope_t& scope) {
|
|
||||||
return path_iterator_t<const node_t>(*this, start, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
void visit(node_t& start, scope_t& scope, const path_t::visitor_t& func) {
|
|
||||||
path_t(*this).visit(start, scope, func);
|
|
||||||
}
|
|
||||||
void visit(const node_t& start, scope_t& scope, const
|
|
||||||
path_t::visitor_t& func) {
|
|
||||||
path_t(*this).visit(start, scope, func);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void print(std::ostream& out, scope_t& scope) const {
|
void print(std::ostream& out, scope_t& scope) const {
|
||||||
op_t::print_context_t context(scope);
|
op_t::print_context_t context(scope);
|
||||||
|
|
@ -890,9 +864,7 @@ public:
|
||||||
inline xpath_t::ptr_op_t
|
inline xpath_t::ptr_op_t
|
||||||
xpath_t::op_t::new_node(kind_t _kind, ptr_op_t _left, ptr_op_t _right) {
|
xpath_t::op_t::new_node(kind_t _kind, ptr_op_t _left, ptr_op_t _right) {
|
||||||
ptr_op_t node(new op_t(_kind));
|
ptr_op_t node(new op_t(_kind));
|
||||||
if (_left)
|
|
||||||
node->set_left(_left);
|
node->set_left(_left);
|
||||||
if (_right)
|
|
||||||
node->set_right(_right);
|
node->set_right(_right);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
@ -935,17 +907,16 @@ xpath_t::scope_t::find_scope<xpath_t::context_scope_t>(bool skip_this) {
|
||||||
return downcast<context_scope_t>(*scope);
|
return downcast<context_scope_t>(*scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
|
||||||
inline xpath_t::node_scope_t&
|
|
||||||
xpath_t::scope_t::find_scope<xpath_t::node_scope_t>(bool skip_this) {
|
|
||||||
optional<scope_t&> scope = find_scope(NODE_SCOPE, skip_this);
|
|
||||||
assert(scope);
|
|
||||||
return downcast<node_scope_t>(*scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FIND_SCOPE(scope_type, scope_ref) \
|
#define FIND_SCOPE(scope_type, scope_ref) \
|
||||||
downcast<xml::xpath_t::scope_t>(scope_ref).find_scope<scope_type>()
|
downcast<xml::xpath_t::scope_t>(scope_ref).find_scope<scope_type>()
|
||||||
|
|
||||||
|
#define CALL_SCOPE(scope_ref) \
|
||||||
|
FIND_SCOPE(xml::xpath_t::call_scope_t, scope_ref)
|
||||||
|
#define SYMBOL_SCOPE(scope_ref) \
|
||||||
|
FIND_SCOPE(xml::xpath_t::symbol_scope_t, scope_ref)
|
||||||
|
#define CONTEXT_SCOPE(scope_ref) \
|
||||||
|
FIND_SCOPE(xml::xpath_t::context_scope_t, scope_ref)
|
||||||
|
|
||||||
} // namespace xml
|
} // namespace xml
|
||||||
|
|
||||||
value_t xml_command(xml::xpath_t::call_scope_t& args);
|
value_t xml_command(xml::xpath_t::call_scope_t& args);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue