1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-03-03 08:58:17 +03:00

attempt to cope with ID/IDREF(S) declared both in the DTD and in the

* valid.c xmlschemastypes.c: attempt to cope with ID/IDREF(S)
  declared both in the DTD and in the Schemas <grin/>
* relaxng.c: more debug, added a big optimization for <mixed>
* test/relaxng/testsuite.xml: augmented the testsuite
* test/relaxng/ result/relaxng: added the RelaxNG spec and a
  DocBook example to the regression tests
Daniel
This commit is contained in:
Daniel Veillard 2003-03-19 21:02:29 +00:00
parent 798024a110
commit 249d7bbee2
21 changed files with 17540 additions and 39 deletions

View File

@ -1,3 +1,12 @@
Wed Mar 19 21:58:47 CET 2003 Daniel Veillard <daniel@veillard.com>
* valid.c xmlschemastypes.c: attempt to cope with ID/IDREF(S)
declared both in the DTD and in the Schemas <grin/>
* relaxng.c: more debug, added a big optimization for <mixed>
* test/relaxng/testsuite.xml: augmented the testsuite
* test/relaxng/ result/relaxng: added the RelaxNG spec and a
DocBook example to the regression tests
Wed Mar 19 11:34:10 CET 2003 Daniel Veillard <daniel@veillard.com> Wed Mar 19 11:34:10 CET 2003 Daniel Veillard <daniel@veillard.com>
* check-xsddata-test-suite.py: cosmetic change for output * check-xsddata-test-suite.py: cosmetic change for output

View File

@ -6,7 +6,6 @@
* Daniel Veillard <veillard@redhat.com> * Daniel Veillard <veillard@redhat.com>
*/ */
#define FS
/** /**
* TODO: * TODO:
* - error reporting * - error reporting
@ -131,6 +130,7 @@ typedef enum {
#define IS_NULLABLE 1 #define IS_NULLABLE 1
#define IS_NOT_NULLABLE 2 #define IS_NOT_NULLABLE 2
#define IS_INDETERMINIST 4 #define IS_INDETERMINIST 4
#define IS_MIXED 8
struct _xmlRelaxNGDefine { struct _xmlRelaxNGDefine {
xmlRelaxNGType type; /* the type of definition */ xmlRelaxNGType type; /* the type of definition */
@ -228,6 +228,7 @@ struct _xmlRelaxNGParserCtxt {
#define FLAGS_IGNORABLE 1 #define FLAGS_IGNORABLE 1
#define FLAGS_NEGATIVE 2 #define FLAGS_NEGATIVE 2
#define FLAGS_MIXED_CONTENT 4
/** /**
* xmlRelaxNGInterleaveGroup: * xmlRelaxNGInterleaveGroup:
@ -795,7 +796,6 @@ xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
{ {
xmlRelaxNGStatesPtr ret; xmlRelaxNGStatesPtr ret;
#ifdef FS
if ((ctxt != NULL) && if ((ctxt != NULL) &&
(ctxt->freeState != NULL) && (ctxt->freeState != NULL) &&
(ctxt->freeStatesNr > 0)) { (ctxt->freeStatesNr > 0)) {
@ -804,7 +804,6 @@ xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
ret->nbState = 0; ret->nbState = 0;
return(ret); return(ret);
} }
#endif
if (size < 16) size = 16; if (size < 16) size = 16;
ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) + ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) +
@ -922,7 +921,6 @@ xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
{ {
if (states == NULL) if (states == NULL)
return; return;
#ifdef FS
if ((ctxt != NULL) && (ctxt->freeStates == NULL)) { if ((ctxt != NULL) && (ctxt->freeStates == NULL)) {
ctxt->freeStatesMax = 40; ctxt->freeStatesMax = 40;
ctxt->freeStatesNr = 0; ctxt->freeStatesNr = 0;
@ -953,10 +951,6 @@ xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
} else { } else {
ctxt->freeStates[ctxt->freeStatesNr++] = states; ctxt->freeStates[ctxt->freeStatesNr++] = states;
} }
#else
xmlFree(states->tabState);
xmlFree(states);
#endif
} }
/** /**
@ -1555,7 +1549,7 @@ xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt, xmlRelaxNGValidErr err,
return (0); return (0);
} }
} }
if ((ctxt->err != NULL) && if ((ctxt->err != NULL) && (ctxt->state != NULL) &&
(ctxt->err->node == ctxt->state->node) && (ctxt->err->node == ctxt->state->node) &&
(ctxt->err->err == err)) (ctxt->err->err == err))
return(ctxt->errNr); return(ctxt->errNr);
@ -1601,9 +1595,11 @@ xmlRelaxNGValidErrorPop(xmlRelaxNGValidCtxtPtr ctxt)
ctxt->err = NULL; ctxt->err = NULL;
cur = &ctxt->errTab[ctxt->errNr]; cur = &ctxt->errTab[ctxt->errNr];
if (cur->flags & ERROR_IS_DUP) { if (cur->flags & ERROR_IS_DUP) {
xmlFree((xmlChar *)cur->arg1); if (cur->arg1 != NULL)
xmlFree((xmlChar *)cur->arg1);
cur->arg1 = NULL; cur->arg1 = NULL;
xmlFree((xmlChar *)cur->arg2); if (cur->arg2 != NULL)
xmlFree((xmlChar *)cur->arg2);
cur->arg2 = NULL; cur->arg2 = NULL;
cur->flags = 0; cur->flags = 0;
} }
@ -2625,10 +2621,7 @@ static int xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGDefinePtr define, xmlNodePtr elem); xmlRelaxNGDefinePtr define, xmlNodePtr elem);
#define IS_BLANK_NODE(n) \ #define IS_BLANK_NODE(n) (xmlRelaxNGIsBlank((n)->content))
((((n)->type == XML_TEXT_NODE) || \
((n)->type == XML_CDATA_SECTION_NODE)) && \
(xmlRelaxNGIsBlank((n)->content)))
/** /**
* xmlRelaxNGIsNullable: * xmlRelaxNGIsNullable:
@ -3455,6 +3448,7 @@ xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def,
int i,j,ret; int i,j,ret;
int nbgroups = 0; int nbgroups = 0;
int nbchild = 0; int nbchild = 0;
int is_mixed = 0;
/* /*
* Don't run that check in case of error. Infinite recursion * Don't run that check in case of error. Infinite recursion
@ -3487,6 +3481,8 @@ xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def,
xmlMalloc(sizeof(xmlRelaxNGInterleaveGroup)); xmlMalloc(sizeof(xmlRelaxNGInterleaveGroup));
if (groups[nbgroups] == NULL) if (groups[nbgroups] == NULL)
goto error; goto error;
if (cur->type == XML_RELAXNG_TEXT)
is_mixed++;
groups[nbgroups]->rule = cur; groups[nbgroups]->rule = cur;
groups[nbgroups]->defs = xmlRelaxNGGetElements(ctxt, cur, 0); groups[nbgroups]->defs = xmlRelaxNGGetElements(ctxt, cur, 0);
groups[nbgroups]->attrs = xmlRelaxNGGetElements(ctxt, cur, 1); groups[nbgroups]->attrs = xmlRelaxNGGetElements(ctxt, cur, 1);
@ -3534,6 +3530,8 @@ xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def,
* and save the partition list back in the def * and save the partition list back in the def
*/ */
def->data = partitions; def->data = partitions;
if (is_mixed != 0)
def->flags |= IS_MIXED;
return; return;
error: error:
@ -6836,7 +6834,8 @@ xmlRelaxNGSkipIgnored(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
(node->type == XML_PI_NODE) || (node->type == XML_PI_NODE) ||
(((node->type == XML_TEXT_NODE) || (((node->type == XML_TEXT_NODE) ||
(node->type == XML_CDATA_SECTION_NODE)) && (node->type == XML_CDATA_SECTION_NODE)) &&
(IS_BLANK_NODE(node))))) { ((ctxt->flags & FLAGS_MIXED_CONTENT) ||
(IS_BLANK_NODE(node)))))) {
node = node->next; node = node->next;
} }
return(node); return(node);
@ -7529,6 +7528,7 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGDefinePtr define) { xmlRelaxNGDefinePtr define) {
int ret = 0, i, nbgroups, left; int ret = 0, i, nbgroups, left;
int errNr = ctxt->errNr; int errNr = ctxt->errNr;
int oldflags;
xmlRelaxNGValidStatePtr oldstate; xmlRelaxNGValidStatePtr oldstate;
xmlRelaxNGPartitionPtr partitions; xmlRelaxNGPartitionPtr partitions;
@ -7544,6 +7544,34 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
VALID_ERR(XML_RELAXNG_ERR_INTERNODATA); VALID_ERR(XML_RELAXNG_ERR_INTERNODATA);
return(-1); return(-1);
} }
/*
* Optimizations for MIXED
*/
oldflags = ctxt->flags;
if (define->flags & IS_MIXED) {
ctxt->flags |= FLAGS_MIXED_CONTENT;
if (nbgroups == 2) {
/*
* this is a pure <mixed> case
*/
if (ctxt->state != NULL)
ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
ctxt->state->seq);
if (partitions->groups[0]->rule->type == XML_RELAXNG_TEXT)
ret = xmlRelaxNGValidateDefinition(ctxt,
partitions->groups[1]->rule);
else
ret = xmlRelaxNGValidateDefinition(ctxt,
partitions->groups[0]->rule);
if (ret == 0) {
if (ctxt->state != NULL)
ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
ctxt->state->seq);
}
ctxt->flags = oldflags;
return(ret);
}
}
/* /*
* Build arrays to store the first and last node of the chain * Build arrays to store the first and last node of the chain
@ -7673,6 +7701,7 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
} }
done: done:
ctxt->flags = oldflags;
/* /*
* builds the next links chain from the prev one * builds the next links chain from the prev one
*/ */
@ -7942,6 +7971,14 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
*/ */
if (node->_private == define) { if (node->_private == define) {
ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt, node->next); ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
if (ctxt->errNr != 0) {
while ((ctxt->err != NULL) &&
(((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME) &&
(xmlStrEqual(ctxt->err->arg2, node->name))) ||
(ctxt->err->err == XML_RELAXNG_ERR_NOELEM) ||
(ctxt->err->err == XML_RELAXNG_ERR_NOTELEM)))
xmlRelaxNGValidErrorPop(ctxt);
}
break; break;
} }
@ -7963,6 +8000,10 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
} }
errNr = ctxt->errNr; errNr = ctxt->errNr;
oldflags = ctxt->flags;
if (ctxt->flags & FLAGS_MIXED_CONTENT) {
ctxt->flags -= FLAGS_MIXED_CONTENT;
}
state = xmlRelaxNGNewValidState(ctxt, node); state = xmlRelaxNGNewValidState(ctxt, node);
if (state == NULL) { if (state == NULL) {
ret = -1; ret = -1;
@ -7990,7 +8031,6 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
if (ctxt->states != NULL) { if (ctxt->states != NULL) {
tmp = -1; tmp = -1;
oldflags = ctxt->flags;
ctxt->flags |= FLAGS_IGNORABLE; ctxt->flags |= FLAGS_IGNORABLE;
for (i = 0;i < ctxt->states->nbState;i++) { for (i = 0;i < ctxt->states->nbState;i++) {
@ -8012,6 +8052,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
ret = xmlRelaxNGValidateElementEnd(ctxt); ret = xmlRelaxNGValidateElementEnd(ctxt);
xmlRelaxNGFreeValidState(ctxt,state); xmlRelaxNGFreeValidState(ctxt,state);
} }
ctxt->flags = oldflags;
ctxt->state = oldstate; ctxt->state = oldstate;
if (oldstate != NULL) if (oldstate != NULL)
oldstate->seq = xmlRelaxNGSkipIgnored(ctxt, node->next); oldstate->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
@ -8695,14 +8736,12 @@ xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxtPtr ctxt) {
} }
xmlRelaxNGFreeStates(NULL, ctxt->freeState); xmlRelaxNGFreeStates(NULL, ctxt->freeState);
} }
#ifdef FS
if (ctxt->freeStates != NULL) { if (ctxt->freeStates != NULL) {
for (k = 0;k < ctxt->freeStatesNr;k++) { for (k = 0;k < ctxt->freeStatesNr;k++) {
xmlRelaxNGFreeStates(NULL, ctxt->freeStates[k]); xmlRelaxNGFreeStates(NULL, ctxt->freeStates[k]);
} }
xmlFree(ctxt->freeStates); xmlFree(ctxt->freeStates);
} }
#endif
if (ctxt->errTab != NULL) if (ctxt->errTab != NULL)
xmlFree(ctxt->errTab); xmlFree(ctxt->errTab);
xmlFree(ctxt); xmlFree(ctxt);

1
result/relaxng/docbook_0 Normal file
View File

@ -0,0 +1 @@
./test/relaxng/docbook_0.xml validates

View File

@ -0,0 +1,4 @@
./test/relaxng/docbook_0.xml:1864: error: Entity 'copy' not defined
<sgmltag>&amp;copy;</sgmltag> &mdash; copyright sign (&copy;)
^
Unimplemented block at xmlschemastypes.c:1636

View File

View File

@ -0,0 +1 @@
./test/relaxng/docbook.rng validates

1
result/relaxng/spec_0 Normal file
View File

@ -0,0 +1 @@
./test/relaxng/spec_0.xml validates

View File

0
result/relaxng/spec_err Normal file
View File

View File

@ -0,0 +1 @@
./test/relaxng/spec.rng validates

View File

@ -0,0 +1 @@
./test/relaxng/tutor8_1_2.xml validates

View File

9141
test/relaxng/docbook.rng Normal file

File diff suppressed because it is too large Load Diff

4448
test/relaxng/docbook_0.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
ns="http://relaxng.org/ns/proofsystem">
<start>
<element name="proofSystem">
<oneOrMore>
<element name="rule">
<attribute name="name"/>
<zeroOrMore>
<ref name="antecedent"/>
</zeroOrMore>
<ref name="consequent"/>
</element>
</oneOrMore>
</element>
</start>
<define name="formula">
<element name="formula">
<choice>
<ref name="judgement"/>
<ref name="expr"/>
</choice>
</element>
</define>
<define name="consequent">
<ref name="judgement"/>
</define>
<define name="antecedent">
<ref name="judgement"/>
</define>
<define name="judgement">
<choice>
<element name="judgement">
<attribute name="name"/>
<zeroOrMore>
<ref name="expr"/>
</zeroOrMore>
</element>
<element name="not">
<ref name="judgement"/>
</element>
</choice>
</define>
<define name="expr">
<choice>
<element name="var">
<attribute name="range"/>
<optional>
<attribute name="index"/>
</optional>
<optional>
<attribute name="sub"/>
</optional>
</element>
<element name="function">
<attribute name="name"/>
<zeroOrMore>
<ref name="expr"/>
</zeroOrMore>
</element>
<element name="element">
<attribute name="name"/>
<zeroOrMore>
<element name="attribute">
<attribute name="name"/>
<ref name="expr"/>
</element>
</zeroOrMore>
<optional>
<ref name="context"/>
</optional>
<zeroOrMore>
<ref name="expr"/>
</zeroOrMore>
</element>
<element name="group">
<zeroOrMore>
<ref name="expr"/>
</zeroOrMore>
</element>
<element name="string"><text/></element>
</choice>
</define>
<define name="context">
<element name="context">
<ref name="expr"/>
</element>
</define>
</grammar>

60
test/relaxng/spec.rng Normal file
View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Id: spec.rng,v 1.3 2001/10/23 05:54:24 jjc Exp $ -->
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
xmlns:p="http://relaxng.org/ns/proofsystem">
<start>
<grammar>
<include href="docbook.rng"/>
<define name="synop.class" combine="choice">
<choice>
<parentRef name="rngref"/>
<parentRef name="grammarref"/>
<grammar>
<include href="proofsystem.rng"/>
<start combine="choice">
<ref name="formula"/>
</start>
</grammar>
</choice>
</define>
<define name="tech.char.class" combine="choice">
<parentRef name="terms"/>
</define>
</grammar>
</start>
<define name="rngref">
<element name="rngref">
<attribute name="src">
<data type="anyURI"/>
</attribute>
</element>
</define>
<define name="grammarref">
<element name="grammarref">
<attribute name="src">
<data type="anyURI"/>
</attribute>
</element>
</define>
<define name="terms">
<grammar>
<include href="proofsystem.rng">
<start>
<choice>
<ref name="expr"/>
<ref name="judgement"/>
<ref name="context"/>
</choice>
</start>
</include>
</grammar>
</define>
</grammar>

3589
test/relaxng/spec_0.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1531,4 +1531,93 @@
</invalid> </invalid>
</testCase> </testCase>
</testSuite> </testSuite>
<testSuite>
<documentation>Test of Mixed</documentation>
<testCase>
<correct>
<element name="mix" xmlns="http://relaxng.org/ns/structure/1.0">
<mixed>
<zeroOrMore>
<choice>
<element name="a">
<empty/>
</element>
<element name="b">
<empty/>
</element>
<element name="c">
<empty/>
</element>
</choice>
</zeroOrMore>
</mixed>
<element name="d">
<empty/>
</element>
</element>
</correct>
<valid>
<mix>
<d/>
</mix>
</valid>
<valid>
<mix>
<b/>
<a/>
<c/>
<b/>
<d/>
</mix>
</valid>
<valid>
<mix>
mixed
<c/>
<d/>
</mix>
</valid>
<valid>
<mix>
<c/>
mixed
<d/>
</mix>
</valid>
<valid>
<mix>
<b/>
is
<a/>
inter
<c/>
mixed
<b/>
<d/>
</mix>
</valid>
<valid>
<mix>
mixed
<b/>
.
<d/>
</mix>
</valid>
<valid>
<mix>
this
<b/>
is
<a/>
inter
<c/>
mixed
<b/>
.
<d/>
</mix>
</valid>
</testCase>
</testSuite>
</testSuite> </testSuite>

View File

@ -0,0 +1,7 @@
<addressBook>
<card>
<name>b</name>
<email>b@b</email>
</card>
</addressBook>

View File

@ -2287,6 +2287,8 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
xmlFreeID(ret); xmlFreeID(ret);
return(NULL); return(NULL);
} }
if (attr != NULL)
attr->atype = XML_ATTRIBUTE_ID;
return(ret); return(ret);
} }

View File

@ -1526,15 +1526,22 @@ xmlSchemaValPredefTypeNode(xmlSchemaTypePtr type, const xmlChar *value,
if ((ret == 0) && (node != NULL) && if ((ret == 0) && (node != NULL) &&
(node->type == XML_ATTRIBUTE_NODE)) { (node->type == XML_ATTRIBUTE_NODE)) {
xmlAttrPtr attr = (xmlAttrPtr) node; xmlAttrPtr attr = (xmlAttrPtr) node;
xmlChar *strip;
strip = xmlSchemaStrip(value); /*
if (strip != NULL) { * NOTE: the REFness might have already be declared in the DTD
xmlAddRef(NULL, node->doc, strip, attr); */
xmlFree(strip); if ((attr->atype != XML_ATTRIBUTE_IDREF) &&
} else (attr->atype != XML_ATTRIBUTE_IDREFS)) {
xmlAddRef(NULL, node->doc, value, attr); xmlChar *strip;
attr->atype = XML_ATTRIBUTE_IDREF;
strip = xmlSchemaStrip(value);
if (strip != NULL) {
xmlAddRef(NULL, node->doc, strip, attr);
xmlFree(strip);
} else
xmlAddRef(NULL, node->doc, value, attr);
attr->atype = XML_ATTRIBUTE_IDREF;
}
} }
return(ret); return(ret);
} else if (type == xmlSchemaTypeIdrefsDef) { } else if (type == xmlSchemaTypeIdrefsDef) {
@ -1559,19 +1566,24 @@ xmlSchemaValPredefTypeNode(xmlSchemaTypePtr type, const xmlChar *value,
if ((ret == 0) && (node != NULL) && if ((ret == 0) && (node != NULL) &&
(node->type == XML_ATTRIBUTE_NODE)) { (node->type == XML_ATTRIBUTE_NODE)) {
xmlAttrPtr attr = (xmlAttrPtr) node; xmlAttrPtr attr = (xmlAttrPtr) node;
xmlIDPtr res; /*
xmlChar *strip; * NOTE: the IDness might have already be declared in the DTD
*/
if (attr->atype != XML_ATTRIBUTE_ID) {
xmlIDPtr res;
xmlChar *strip;
strip = xmlSchemaStrip(value); strip = xmlSchemaStrip(value);
if (strip != NULL) { if (strip != NULL) {
res = xmlAddID(NULL, node->doc, strip, attr); res = xmlAddID(NULL, node->doc, strip, attr);
xmlFree(strip); xmlFree(strip);
} else } else
res = xmlAddID(NULL, node->doc, value, attr); res = xmlAddID(NULL, node->doc, value, attr);
if (res == NULL) { if (res == NULL) {
ret = 2; ret = 2;
} else { } else {
attr->atype = XML_ATTRIBUTE_ID; attr->atype = XML_ATTRIBUTE_ID;
}
} }
} }
return(ret); return(ret);