more bug-hunting added --tree to dump the intermediate rng tree patch from
* relaxng.c: more bug-hunting
* testRelax.c include/libxml/relaxng.h: added --tree to dump the
intermediate rng tree
* python/generator.py: patch from Stephane Bidoul to fix the generator
on python < 2.2
Daniel
diff --git a/relaxng.c b/relaxng.c
index 229c816..36cec74 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -2312,6 +2312,89 @@
}
/**
+ * xmlRelaxNGProcessExternalRef:
+ * @ctxt: the parser context
+ * @node: the externlRef node
+ *
+ * Process and compile an externlRef node
+ *
+ * Returns the xmlRelaxNGDefinePtr or NULL in case of error
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
+ xmlRelaxNGDocumentPtr docu;
+ xmlNodePtr root, tmp;
+ xmlChar *ns;
+ int newNs = 0;
+ xmlRelaxNGDefinePtr def;
+
+ docu = node->_private;
+ if (docu != NULL) {
+ def = xmlRelaxNGNewDefine(ctxt, node);
+ if (def == NULL)
+ return(NULL);
+ def->type = XML_RELAXNG_EXTERNALREF;
+
+ if (docu->content == NULL) {
+ /*
+ * Then do the parsing for good
+ */
+ root = xmlDocGetRootElement(docu->doc);
+ if (root == NULL) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "xmlRelaxNGParse: %s is empty\n",
+ ctxt->URL);
+ ctxt->nbErrors++;
+ return (NULL);
+ }
+ /*
+ * ns transmission rules
+ */
+ ns = xmlGetProp(root, BAD_CAST "ns");
+ if (ns == NULL) {
+ tmp = node;
+ while ((tmp != NULL) &&
+ (tmp->type == XML_ELEMENT_NODE)) {
+ ns = xmlGetProp(tmp, BAD_CAST "ns");
+ if (ns != NULL) {
+ break;
+ }
+ tmp = tmp->parent;
+ }
+ if (ns != NULL) {
+ xmlSetProp(root, BAD_CAST "ns", ns);
+ newNs = 1;
+ xmlFree(ns);
+ }
+ } else {
+ xmlFree(ns);
+ }
+
+ /*
+ * Parsing to get a precompiled schemas.
+ */
+ docu->schema = xmlRelaxNGParseDocument(ctxt, root);
+ if ((docu->schema != NULL) &&
+ (docu->schema->topgrammar != NULL)) {
+ docu->content = docu->schema->topgrammar->start;
+ }
+
+ /*
+ * the externalRef may be reused in a different ns context
+ */
+ if (newNs == 1) {
+ xmlUnsetProp(root, BAD_CAST "ns");
+ }
+ }
+ def->content = docu->content;
+ } else {
+ def = NULL;
+ }
+ return(def);
+}
+
+/**
* xmlRelaxNGParsePattern:
* @ctxt: a Relax-NG parser context
* @node: the pattern node.
@@ -2470,10 +2553,16 @@
prev = (xmlRelaxNGDefinePtr)
xmlHashLookup(ctxt->grammar->refs, def->name);
if (prev == NULL) {
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Internal error refs definitions '%s'\n",
- def->name);
+ if (def->name != NULL) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Error refs definitions '%s'\n",
+ def->name);
+ } else {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Error refs definitions\n");
+ }
ctxt->nbErrors++;
def = NULL;
} else {
@@ -2507,39 +2596,7 @@
} else if (IS_RELAXNG(node, "interleave")) {
def = xmlRelaxNGParseInterleave(ctxt, node);
} else if (IS_RELAXNG(node, "externalRef")) {
- xmlRelaxNGDocumentPtr docu;
- xmlNodePtr root;
-
- docu = node->_private;
- if (docu != NULL) {
- def = xmlRelaxNGNewDefine(ctxt, node);
- if (def == NULL)
- return(NULL);
- def->type = XML_RELAXNG_EXTERNALREF;
-
- if (docu->content == NULL) {
- /*
- * Then do the parsing for good
- */
- root = xmlDocGetRootElement(docu->doc);
- if (root == NULL) {
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "xmlRelaxNGParse: %s is empty\n",
- ctxt->URL);
- ctxt->nbErrors++;
- return (NULL);
- }
- docu->schema = xmlRelaxNGParseDocument(ctxt, root);
- if ((docu->schema != NULL) &&
- (docu->schema->topgrammar != NULL)) {
- docu->content = docu->schema->topgrammar->start;
- }
- }
- def->content = docu->content;
- } else {
- def = NULL;
- }
+ def = xmlRelaxNGProcessExternalRef(ctxt, node);
} else if (IS_RELAXNG(node, "notAllowed")) {
def = xmlRelaxNGNewDefine(ctxt, node);
if (def == NULL)
@@ -3934,7 +3991,7 @@
cur->_private = incl;
} else if ((xmlStrEqual(cur->name, BAD_CAST "element")) ||
(xmlStrEqual(cur->name, BAD_CAST "attribute"))) {
- xmlChar *name;
+ xmlChar *name, *ns;
xmlNodePtr text = NULL;
/*
@@ -3956,20 +4013,23 @@
text = node;
}
}
+ if (text == NULL) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Failed to create a name %s element\n", name);
+ ctxt->nbErrors++;
+ }
xmlUnsetProp(cur, BAD_CAST "name");
xmlFree(name);
- }
- if (xmlStrEqual(cur->name, BAD_CAST "attribute")) {
- if (text == NULL) {
- text = cur->children;
- while (text != NULL) {
- if ((text->type == XML_ELEMENT_NODE) &&
- (xmlStrEqual(text->name, BAD_CAST "name")))
- break;
- text = text->next;
+ ns = xmlGetProp(cur, BAD_CAST "ns");
+ if (ns != NULL) {
+ if (text != NULL) {
+ xmlSetProp(text, BAD_CAST "ns", ns);
+ /* xmlUnsetProp(cur, BAD_CAST "ns"); */
}
- }
- if (text != NULL) {
+ xmlFree(ns);
+ } else if (xmlStrEqual(cur->name,
+ BAD_CAST "attribute")) {
xmlSetProp(text, BAD_CAST "ns", BAD_CAST "");
}
}
@@ -4453,6 +4513,27 @@
xmlRelaxNGDumpGrammar(output, schema->topgrammar, 1);
}
+/**
+ * xmlRelaxNGDumpTree:
+ * @output: the file output
+ * @schema: a schema structure
+ *
+ * Dump the transformed RelaxNG tree.
+ */
+void
+xmlRelaxNGDumpTree(FILE * output, xmlRelaxNGPtr schema)
+{
+ if (schema == NULL) {
+ fprintf(output, "RelaxNG empty or failed to compile\n");
+ return;
+ }
+ if (schema->doc == NULL) {
+ fprintf(output, "no document\n");
+ } else {
+ xmlDocDump(output, schema->doc);
+ }
+}
+
/************************************************************************
* *
* Validation implementation *