summaryrefslogtreecommitdiff
path: root/gnulib-local/lib/libxml/relaxng.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnulib-local/lib/libxml/relaxng.c')
-rw-r--r--gnulib-local/lib/libxml/relaxng.c428
1 files changed, 335 insertions, 93 deletions
diff --git a/gnulib-local/lib/libxml/relaxng.c b/gnulib-local/lib/libxml/relaxng.c
index 16527cc59..5779e7fc5 100644
--- a/gnulib-local/lib/libxml/relaxng.c
+++ b/gnulib-local/lib/libxml/relaxng.c
@@ -39,9 +39,10 @@
static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
"http://relaxng.org/ns/structure/1.0";
-#define IS_RELAXNG(node, type) \
+#define IS_RELAXNG(node, typ) \
((node != NULL) && (node->ns != NULL) && \
- (xmlStrEqual(node->name, (const xmlChar *) type)) && \
+ (node->type == XML_ELEMENT_NODE) && \
+ (xmlStrEqual(node->name, (const xmlChar *) typ)) && \
(xmlStrEqual(node->ns->href, xmlRelaxNGNs)))
@@ -60,7 +61,7 @@ static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
#define DEBUG_LIST 1
-#define DEBUG_INCLUDE 1
+#define DEBUG_INCLUDE 1
#define DEBUG_ERROR 1
@@ -71,7 +72,7 @@ static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
#define MAX_ERROR 5
-#define TODO \
+#define TODO \
xmlGenericError(xmlGenericErrorContext, \
"Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
@@ -149,6 +150,7 @@ typedef enum {
#define IS_PROCESSED (1 << 5)
#define IS_COMPILABLE (1 << 6)
#define IS_NOT_COMPILABLE (1 << 7)
+#define IS_EXTERNAL_REF (1 << 8)
struct _xmlRelaxNGDefine {
xmlRelaxNGType type; /* the type of definition */
@@ -414,12 +416,13 @@ struct _xmlRelaxNGDocument {
xmlDocPtr doc; /* the associated XML document */
xmlRelaxNGDefinePtr content; /* the definitions */
xmlRelaxNGPtr schema; /* the schema */
+ int externalRef; /* 1 if an external ref */
};
/************************************************************************
* *
- * Some factorized error routines *
+ * Some factorized error routines *
* *
************************************************************************/
@@ -562,9 +565,9 @@ xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
}
/************************************************************************
- * *
- * Preliminary type checking interfaces *
- * *
+ * *
+ * Preliminary type checking interfaces *
+ * *
************************************************************************/
/**
@@ -652,9 +655,9 @@ struct _xmlRelaxNGTypeLibrary {
};
/************************************************************************
- * *
- * Allocation functions *
- * *
+ * *
+ * Allocation functions *
+ * *
************************************************************************/
static void xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar);
static void xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define);
@@ -1006,7 +1009,7 @@ xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
xmlRelaxNGStatesPtr ret;
if ((ctxt != NULL) &&
- (ctxt->freeState != NULL) && (ctxt->freeStatesNr > 0)) {
+ (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) {
ctxt->freeStatesNr--;
ret = ctxt->freeStates[ctxt->freeStatesNr];
ret->nbState = 0;
@@ -1092,7 +1095,7 @@ xmlRelaxNGAddStates(xmlRelaxNGValidCtxtPtr ctxt,
{
int i;
- if (state == NULL) {
+ if (state == NULL || states == NULL) {
return (-1);
}
if (states->nbState >= states->maxState) {
@@ -1395,9 +1398,9 @@ xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
}
/************************************************************************
- * *
- * Semi internal functions *
- * *
+ * *
+ * Semi internal functions *
+ * *
************************************************************************/
/**
@@ -1427,9 +1430,9 @@ xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags)
}
/************************************************************************
- * *
- * Document functions *
- * *
+ * *
+ * Document functions *
+ * *
************************************************************************/
static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
xmlDocPtr doc);
@@ -1559,8 +1562,8 @@ xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
href = xmlGetProp(tmp, BAD_CAST "href");
#endif
if (xmlRelaxNGRemoveRedefine(ctxt, href,
- inc->doc->children->
- children, name) == 1) {
+ xmlDocGetRootElement(inc->doc)->children,
+ name) == 1) {
found = 1;
}
#ifdef DEBUG_INCLUDE
@@ -1970,6 +1973,7 @@ xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
ret->doc = doc;
ret->href = xmlStrdup(URL);
ret->next = ctxt->documents;
+ ret->externalRef = 1;
ctxt->documents = ret;
/*
@@ -2004,9 +2008,9 @@ xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
}
/************************************************************************
- * *
- * Error functions *
- * *
+ * *
+ * Error functions *
+ * *
************************************************************************/
#define VALID_ERR(a) xmlRelaxNGAddValidError(ctxt, a, NULL, NULL, 0);
@@ -2357,7 +2361,7 @@ xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
* generate the error directly
*/
if (((ctxt->flags & FLAGS_IGNORABLE) == 0) ||
- (ctxt->flags & FLAGS_NEGATIVE)) {
+ (ctxt->flags & FLAGS_NEGATIVE)) {
xmlNodePtr node, seq;
/*
@@ -2372,6 +2376,9 @@ xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
} else {
node = seq = NULL;
}
+ if ((node == NULL) && (seq == NULL)) {
+ node = ctxt->pnode;
+ }
xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
}
/*
@@ -2384,9 +2391,9 @@ xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
/************************************************************************
- * *
- * Type library hooks *
- * *
+ * *
+ * Type library hooks *
+ * *
************************************************************************/
static xmlChar *xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt,
const xmlChar * str);
@@ -2588,13 +2595,10 @@ xmlRelaxNGSchemaTypeCompare(void *data ATTRIBUTE_UNUSED,
}
ret = xmlSchemaValPredefTypeNode(typ, value2, &res2, ctxt2);
if (ret != 0) {
- if ((comp1 == NULL) && (res1 != NULL))
+ if (res1 != (xmlSchemaValPtr) comp1)
xmlSchemaFreeValue(res1);
return (-1);
}
- if (res1 == NULL) {
- return (-1);
- }
ret = xmlSchemaCompareValues(res1, res2);
if (res1 != (xmlSchemaValPtr) comp1)
xmlSchemaFreeValue(res1);
@@ -2841,14 +2845,18 @@ xmlRelaxNGCleanupTypes(void)
}
/************************************************************************
- * *
- * Compiling element content into regexp *
- * *
+ * *
+ * Compiling element content into regexp *
+ * *
* Sometime the element content can be compiled into a pure regexp, *
* This allows a faster execution and streamability at that level *
- * *
+ * *
************************************************************************/
+/* from automata.c but not exported */
+void xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
+
+
static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
xmlRelaxNGDefinePtr def);
@@ -3032,14 +3040,25 @@ xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
ctxt->am = xmlNewAutomata();
if (ctxt->am == NULL)
return (-1);
+
+ /*
+ * assume identical strings but not same pointer are different
+ * atoms, needed for non-determinism detection
+ * That way if 2 elements with the same name are in a choice
+ * branch the automata is found non-deterministic and
+ * we fallback to the normal validation which does the right
+ * thing of exploring both choices.
+ */
+ xmlAutomataSetFlags(ctxt->am, 1);
+
ctxt->state = xmlAutomataGetInitState(ctxt->am);
while (list != NULL) {
xmlRelaxNGCompile(ctxt, list);
list = list->next;
}
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
- def->contModel = xmlAutomataCompile(ctxt->am);
- xmlRegexpIsDeterminist(def->contModel);
+ if (xmlAutomataIsDeterminist(ctxt->am))
+ def->contModel = xmlAutomataCompile(ctxt->am);
xmlFreeAutomata(ctxt->am);
ctxt->state = oldstate;
@@ -3063,6 +3082,7 @@ xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
ctxt->am = xmlNewAutomata();
if (ctxt->am == NULL)
return (-1);
+ xmlAutomataSetFlags(ctxt->am, 1);
ctxt->state = xmlAutomataGetInitState(ctxt->am);
while (list != NULL) {
xmlRelaxNGCompile(ctxt, list);
@@ -3071,6 +3091,11 @@ xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
def->contModel = xmlAutomataCompile(ctxt->am);
if (!xmlRegexpIsDeterminist(def->contModel)) {
+#ifdef DEBUG_COMPILE
+ xmlGenericError(xmlGenericErrorContext,
+ "Content model not determinist %s\n",
+ def->name);
+#endif
/*
* we can only use the automata if it is determinist
*/
@@ -3098,7 +3123,11 @@ xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
case XML_RELAXNG_OPTIONAL:{
xmlAutomataStatePtr oldstate = ctxt->state;
- xmlRelaxNGCompile(ctxt, def->content);
+ list = def->content;
+ while (list != NULL) {
+ xmlRelaxNGCompile(ctxt, list);
+ list = list->next;
+ }
xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
break;
}
@@ -3294,9 +3323,9 @@ xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
}
/************************************************************************
- * *
- * Parsing functions *
- * *
+ * *
+ * Parsing functions *
+ * *
************************************************************************/
static xmlRelaxNGDefinePtr xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr
@@ -3440,6 +3469,9 @@ xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
{
xmlChar *ret, *escape;
+ if (node == NULL)
+ return(NULL);
+
if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) {
ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
if (ret != NULL) {
@@ -3787,7 +3819,11 @@ xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
return (0);
return (1);
} else if (def1->type == XML_RELAXNG_EXCEPT) {
- TODO ret = 0;
+ ret = xmlRelaxNGCompareNameClasses(def1->content, def2);
+ if (ret == 0)
+ ret = 1;
+ else if (ret == 1)
+ ret = 0;
} else {
TODO ret = 0;
}
@@ -4616,6 +4652,72 @@ xmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
}
/**
+ * xmlRelaxNGParseImportRef:
+ * @payload: the parser context
+ * @data: the current grammar
+ * @name: the reference name
+ *
+ * Import import one references into the current grammar
+ */
+static void
+xmlRelaxNGParseImportRef(void *payload, void *data, xmlChar *name) {
+ xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
+ xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
+ int tmp;
+
+ def->dflags |= IS_EXTERNAL_REF;
+
+ tmp = xmlHashAddEntry(ctxt->grammar->refs, name, def);
+ if (tmp < 0) {
+ xmlRelaxNGDefinePtr prev;
+
+ prev = (xmlRelaxNGDefinePtr)
+ xmlHashLookup(ctxt->grammar->refs, def->name);
+ if (prev == NULL) {
+ if (def->name != NULL) {
+ xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+ "Error refs definitions '%s'\n",
+ def->name, NULL);
+ } else {
+ xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+ "Error refs definitions\n",
+ NULL, NULL);
+ }
+ } else {
+ def->nextHash = prev->nextHash;
+ prev->nextHash = def;
+ }
+ }
+}
+
+/**
+ * xmlRelaxNGParseImportRefs:
+ * @ctxt: the parser context
+ * @grammar: the sub grammar
+ *
+ * Import references from the subgrammar into the current grammar
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt,
+ xmlRelaxNGGrammarPtr grammar) {
+ if ((ctxt == NULL) || (grammar == NULL) || (ctxt->grammar == NULL))
+ return(-1);
+ if (grammar->refs == NULL)
+ return(0);
+ if (ctxt->grammar->refs == NULL)
+ ctxt->grammar->refs = xmlHashCreate(10);
+ if (ctxt->grammar->refs == NULL) {
+ xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+ "Could not create references hash\n", NULL, NULL);
+ return(-1);
+ }
+ xmlHashScan(grammar->refs, xmlRelaxNGParseImportRef, ctxt);
+ return(0);
+}
+
+/**
* xmlRelaxNGProcessExternalRef:
* @ctxt: the parser context
* @node: the externlRef node
@@ -4683,6 +4785,8 @@ xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
if ((docu->schema != NULL) &&
(docu->schema->topgrammar != NULL)) {
docu->content = docu->schema->topgrammar->start;
+ if (docu->schema->topgrammar->refs)
+ xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar);
}
/*
@@ -5267,7 +5371,8 @@ xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
} else {
xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT,
"expecting name, anyName, nsName or choice : got %s\n",
- node->name, NULL);
+ (node == NULL ? (const xmlChar *) "nothing" : node->name),
+ NULL);
return (NULL);
}
if (ret != def) {
@@ -5569,6 +5674,12 @@ xmlRelaxNGCheckReference(xmlRelaxNGDefinePtr ref,
xmlRelaxNGGrammarPtr grammar;
xmlRelaxNGDefinePtr def, cur;
+ /*
+ * Those rules don't apply to imported ref from xmlRelaxNGParseImportRef
+ */
+ if (ref->dflags & IS_EXTERNAL_REF)
+ return;
+
grammar = ctxt->grammar;
if (grammar == NULL) {
xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
@@ -6133,7 +6244,7 @@ xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
xmlRelaxNGDefinePtr cur, int flags,
xmlRelaxNGType ptype)
{
- int nflags = flags;
+ int nflags;
xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY;
while (cur != NULL) {
@@ -6157,6 +6268,16 @@ xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
"Found forbidden pattern data/except//ref\n",
NULL, NULL);
}
+ if (cur->content == NULL) {
+ if (cur->type == XML_RELAXNG_PARENTREF)
+ xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
+ "Internal found no define for parent refs\n",
+ NULL, NULL);
+ else
+ xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
+ "Internal found no define for ref %s\n",
+ (cur->name ? cur->name: BAD_CAST "null"), NULL);
+ }
if (cur->depth > -4) {
cur->depth = -4;
ret = xmlRelaxNGCheckRules(ctxt, cur->content,
@@ -6408,6 +6529,10 @@ xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
if (ptype == XML_RELAXNG_GROUP) {
val = xmlRelaxNGGroupContentType(val, ret);
} else if (ptype == XML_RELAXNG_INTERLEAVE) {
+ /*
+ * TODO: scan complain that tmp is never used, seems on purpose
+ * need double-checking
+ */
tmp = xmlRelaxNGGroupContentType(val, ret);
if (tmp != XML_RELAXNG_CONTENT_ERROR)
tmp = xmlRelaxNGMaxContentType(val, ret);
@@ -6479,7 +6604,7 @@ xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
}
/*
- * Apply 4.17 mergingd rules to defines and starts
+ * Apply 4.17 merging rules to defines and starts
*/
xmlRelaxNGCombineStart(ctxt, ret);
if (ret->defs != NULL) {
@@ -6495,6 +6620,9 @@ xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
ctxt);
}
+
+ /* @@@@ */
+
ctxt->grammar = old;
return (ret);
}
@@ -6528,12 +6656,17 @@ xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
ctxt->define = NULL;
if (IS_RELAXNG(node, "grammar")) {
schema->topgrammar = xmlRelaxNGParseGrammar(ctxt, node->children);
+ if (schema->topgrammar == NULL) {
+ xmlRelaxNGFree(schema);
+ return (NULL);
+ }
} else {
xmlRelaxNGGrammarPtr tmp, ret;
schema->topgrammar = ret = xmlRelaxNGNewGrammar(ctxt);
if (schema->topgrammar == NULL) {
- return (schema);
+ xmlRelaxNGFree(schema);
+ return (NULL);
}
/*
* Link the new grammar in the tree
@@ -6579,9 +6712,9 @@ xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
}
/************************************************************************
- * *
- * Reading RelaxNGs *
- * *
+ * *
+ * Reading RelaxNGs *
+ * *
************************************************************************/
/**
@@ -7190,7 +7323,7 @@ xmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr root)
}
}
/*
- * Thisd is not an else since "include" is transformed
+ * This is not an else since "include" is transformed
* into a div
*/
if (xmlStrEqual(cur->name, BAD_CAST "div")) {
@@ -7219,13 +7352,13 @@ xmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr root)
if (ns != NULL)
xmlFree(ns);
/*
- * Since we are about to delete cur, if it's nsDef is non-NULL we
+ * Since we are about to delete cur, if its nsDef is non-NULL we
* need to preserve it (it contains the ns definitions for the
* children we just moved). We'll just stick it on to the end
* of cur->parent's list, since it's never going to be re-serialized
* (bug 143738).
*/
- if (cur->nsDef != NULL) {
+ if ((cur->nsDef != NULL) && (cur->parent != NULL)) {
xmlNsPtr parDef = (xmlNsPtr)&cur->parent->nsDef;
while (parDef->next != NULL)
parDef = parDef->next;
@@ -7243,7 +7376,8 @@ xmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr root)
else if ((cur->type == XML_TEXT_NODE) ||
(cur->type == XML_CDATA_SECTION_NODE)) {
if (IS_BLANK_NODE(cur)) {
- if (cur->parent->type == XML_ELEMENT_NODE) {
+ if ((cur->parent != NULL) &&
+ (cur->parent->type == XML_ELEMENT_NODE)) {
if ((!xmlStrEqual(cur->parent->name, BAD_CAST "value"))
&&
(!xmlStrEqual
@@ -7395,7 +7529,7 @@ xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
xmlRngPErr(ctxt, (xmlNodePtr) doc,
XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
(ctxt->URL ? ctxt->URL : BAD_CAST "schemas"), NULL);
-
+
xmlFreeDoc(ctxt->document);
ctxt->document = NULL;
return (NULL);
@@ -7537,9 +7671,9 @@ xmlRelaxNGSetParserStructuredErrors(xmlRelaxNGParserCtxtPtr ctxt,
#ifdef LIBXML_OUTPUT_ENABLED
/************************************************************************
- * *
- * Dump back a compiled form *
- * *
+ * *
+ * Dump back a compiled form *
+ * *
************************************************************************/
static void xmlRelaxNGDumpDefine(FILE * output,
xmlRelaxNGDefinePtr define);
@@ -7680,7 +7814,7 @@ xmlRelaxNGDumpDefine(FILE * output, xmlRelaxNGDefinePtr define)
* xmlRelaxNGDumpGrammar:
* @output: the file output
* @grammar: a grammar structure
- * @top: is this a top grammar
+ * @top: is this a top grammar
*
* Dump a RelaxNG structure back
*/
@@ -7773,9 +7907,9 @@ xmlRelaxNGDumpTree(FILE * output, xmlRelaxNGPtr schema)
#endif /* LIBXML_OUTPUT_ENABLED */
/************************************************************************
- * *
- * Validation of compiled content *
- * *
+ * *
+ * Validation of compiled content *
+ * *
************************************************************************/
static int xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGDefinePtr define);
@@ -7918,9 +8052,9 @@ xmlRelaxNGValidateCompiledContent(xmlRelaxNGValidCtxtPtr ctxt,
}
/************************************************************************
- * *
- * Progressive validation of when possible *
- * *
+ * *
+ * Progressive validation of when possible *
+ * *
************************************************************************/
static int xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGDefinePtr defines);
@@ -8220,7 +8354,7 @@ xmlRelaxNGValidatePushElement(xmlRelaxNGValidCtxtPtr ctxt,
* xmlRelaxNGValidatePushCData:
* @ctxt: the RelaxNG validation context
* @data: some character data read
- * @len: the lenght of the data
+ * @len: the length of the data
*
* check the CData parsed for validation in the current stack
*
@@ -8343,7 +8477,7 @@ xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
ret = -1;
else
ret = 1;
- xmlRelaxNGFreeValidState(ctxt, state);
+ xmlRelaxNGFreeValidState(ctxt, ctxt->state);
ctxt->state = NULL;
#ifdef DEBUG_PROGRESSIVE
if (ret < 0)
@@ -8354,9 +8488,9 @@ xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
}
/************************************************************************
- * *
- * Generic interpreted validation implementation *
- * *
+ * *
+ * Generic interpreted validation implementation *
+ * *
************************************************************************/
static int xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGDefinePtr define);
@@ -8758,6 +8892,11 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
case XML_RELAXNG_ZEROORMORE:{
xmlChar *cur, *temp;
+ if ((ctxt->state->value == NULL) ||
+ (*ctxt->state->value == 0)) {
+ ret = 0;
+ break;
+ }
oldflags = ctxt->flags;
ctxt->flags |= FLAGS_IGNORABLE;
cur = ctxt->state->value;
@@ -8779,6 +8918,30 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGPopErrors(ctxt, 0);
break;
}
+ case XML_RELAXNG_OPTIONAL:{
+ xmlChar *temp;
+
+ if ((ctxt->state->value == NULL) ||
+ (*ctxt->state->value == 0)) {
+ ret = 0;
+ break;
+ }
+ oldflags = ctxt->flags;
+ ctxt->flags |= FLAGS_IGNORABLE;
+ temp = ctxt->state->value;
+ ret = xmlRelaxNGValidateValue(ctxt, define->content);
+ ctxt->flags = oldflags;
+ if (ret != 0) {
+ ctxt->state->value = temp;
+ if (ctxt->errNr > 0)
+ xmlRelaxNGPopErrors(ctxt, 0);
+ ret = 0;
+ break;
+ }
+ if (ctxt->errNr > 0)
+ xmlRelaxNGPopErrors(ctxt, 0);
+ break;
+ }
case XML_RELAXNG_EXCEPT:{
xmlRelaxNGDefinePtr list;
@@ -8812,7 +8975,12 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
}
case XML_RELAXNG_REF:
case XML_RELAXNG_PARENTREF:
- ret = xmlRelaxNGValidateValue(ctxt, define->content);
+ if (define->content == NULL) {
+ VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
+ ret = -1;
+ } else {
+ ret = xmlRelaxNGValidateValue(ctxt, define->content);
+ }
break;
default:
TODO ret = -1;
@@ -8889,6 +9057,19 @@ xmlRelaxNGAttributeMatch(xmlRelaxNGValidCtxtPtr ctxt,
return (ret);
list = list->next;
}
+ } else if (define->type == XML_RELAXNG_CHOICE) {
+ xmlRelaxNGDefinePtr list;
+
+ list = define->nameClass;
+ while (list != NULL) {
+ ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
+ if (ret == 1)
+ return (1);
+ if (ret < 0)
+ return (ret);
+ list = list->next;
+ }
+ return (0);
} else {
TODO}
return (1);
@@ -9248,6 +9429,10 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
oldstate = ctxt->state;
for (i = 0; i < nbgroups; i++) {
ctxt->state = xmlRelaxNGCopyValidState(ctxt, oldstate);
+ if (ctxt->state == NULL) {
+ ret = -1;
+ break;
+ }
group = partitions->groups[i];
if (lasts[i] != NULL) {
last = lasts[i]->next;
@@ -9319,6 +9504,7 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
oldstate =
ctxt->states->tabState[ctxt->states->nbState - 1];
ctxt->states->tabState[ctxt->states->nbState - 1] = NULL;
+ ctxt->states->nbState--;
}
}
for (j = 0; j < ctxt->states->nbState ; j++) {
@@ -9327,7 +9513,12 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->states = NULL;
if (found == 0) {
- VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
+ if (cur == NULL) {
+ VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA,
+ (const xmlChar *) "noname");
+ } else {
+ VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
+ }
ret = -1;
ctxt->state = oldstate;
goto done;
@@ -9672,7 +9863,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
ctxt->depth++;
switch (define->type) {
case XML_RELAXNG_EMPTY:
- node = xmlRelaxNGSkipIgnored(ctxt, node);
+ xmlRelaxNGSkipIgnored(ctxt, node);
ret = 0;
break;
case XML_RELAXNG_NOT_ALLOWED:
@@ -9828,7 +10019,8 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
ret = -1;
} else {
state = ctxt->state;
- ctxt->state->seq = nseq;
+ if (ctxt->state != NULL)
+ ctxt->state->seq = nseq;
if (ret == 0)
ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
xmlRelaxNGFreeValidState(ctxt, state);
@@ -9873,8 +10065,8 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
}
for (i = 0; i < ctxt->states->nbState; i++) {
xmlRelaxNGFreeValidState(ctxt,
- ctxt->states->
- tabState[i]);
+ ctxt->states->tabState[i]);
+ ctxt->states->tabState[i] = NULL;
}
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->flags = oldflags;
@@ -9996,11 +10188,8 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
} else {
for (j = 0; j < ctxt->states->nbState; j++) {
xmlRelaxNGAddStates(ctxt, res,
- xmlRelaxNGCopyValidState(ctxt,
- ctxt->
- states->
- tabState
- [j]));
+ xmlRelaxNGCopyValidState(ctxt,
+ ctxt->states->tabState[j]));
}
}
oldflags = ctxt->flags;
@@ -10029,10 +10218,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
j++) {
tmp =
xmlRelaxNGAddStates(ctxt, res,
- ctxt->
- states->
- tabState
- [j]);
+ ctxt->states->tabState[j]);
if (tmp == 1)
progress = 1;
}
@@ -10066,9 +10252,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
} else if (ctxt->states != NULL) {
for (j = 0; j < ctxt->states->nbState; j++) {
tmp = xmlRelaxNGAddStates(ctxt, res,
- ctxt->
- states->
- tabState[j]);
+ ctxt->states->tabState[j]);
if (tmp == 1)
progress = 1;
}
@@ -10106,8 +10290,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
for (i = base; i < res->nbState; i++)
xmlRelaxNGAddStates(ctxt, states,
xmlRelaxNGCopyValidState
- (ctxt,
- res->tabState[i]));
+ (ctxt, res->tabState[i]));
ctxt->states = states;
}
}
@@ -10629,10 +10812,64 @@ xmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
return (ret);
}
+/**
+ * xmlRelaxNGCleanPSVI:
+ * @node: an input element or document
+ *
+ * Call this routine to speed up XPath computation on static documents.
+ * This stamps all the element nodes with the document order
+ * Like for line information, the order is kept in the element->content
+ * field, the value stored is actually - the node number (starting at -1)
+ * to be able to differentiate from line numbers.
+ *
+ * Returns the number of elements found in the document or -1 in case
+ * of error.
+ */
+static void
+xmlRelaxNGCleanPSVI(xmlNodePtr node) {
+ xmlNodePtr cur;
+
+ if ((node == NULL) ||
+ ((node->type != XML_ELEMENT_NODE) &&
+ (node->type != XML_DOCUMENT_NODE) &&
+ (node->type != XML_HTML_DOCUMENT_NODE)))
+ return;
+ if (node->type == XML_ELEMENT_NODE)
+ node->psvi = NULL;
+
+ cur = node->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE) {
+ cur->psvi = NULL;
+ if (cur->children != NULL) {
+ cur = cur->children;
+ continue;
+ }
+ }
+ if (cur->next != NULL) {
+ cur = cur->next;
+ continue;
+ }
+ do {
+ cur = cur->parent;
+ if (cur == NULL)
+ break;
+ if (cur == node) {
+ cur = NULL;
+ break;
+ }
+ if (cur->next != NULL) {
+ cur = cur->next;
+ break;
+ }
+ } while (cur != NULL);
+ }
+ return;
+}
/************************************************************************
- * *
- * Validation interfaces *
- * *
+ * *
+ * Validation interfaces *
+ * *
************************************************************************/
/**
@@ -10803,6 +11040,11 @@ xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
ret = xmlRelaxNGValidateDocument(ctxt, doc);
/*
+ * Remove all left PSVI
+ */
+ xmlRelaxNGCleanPSVI((xmlNodePtr) doc);
+
+ /*
* TODO: build error codes
*/
if (ret == -1)