Index: generic/schema.c
==================================================================
--- generic/schema.c
+++ generic/schema.c
@@ -121,21 +121,22 @@
"ANY",
"NAME",
"CHOICE",
"INTERLEAVE",
"PATTERN",
- "TEXT"
+ "TEXT",
"VIRTUAL",
"KEYSPACE_START",
"KEYSPACE_END"
};
static char *Schema_Quant_Type2str[] = {
"ONE",
"OPT",
"REP",
"PLUS",
- "NM"
+ "NM",
+ "ERROR"
};
#endif
#ifndef TCL_THREADS
@@ -963,11 +964,11 @@
char *name,
char *namespace
)
{
SchemaCP *cp, *candidate, *icp;
- int hm, ac, i, mayskip, rc;
+ int hm, ac, i, rc, missing;
int isName = 0;
SchemaValidationStack *se;
if (!sdata->stack) return 0;
se = sdata->stack;
@@ -978,11 +979,10 @@
isName = 1;
/* fall through */
case SCHEMA_CTYPE_PATTERN:
while (ac < cp->nc) {
candidate = cp->content[ac];
- mayskip = 0;
switch (candidate->type) {
case SCHEMA_CTYPE_TEXT:
if (candidate->nc) {
if (!checkText (interp, candidate, "")) {
if (recover (interp, sdata, S("MISSING_TEXT"),
@@ -1049,11 +1049,10 @@
if (rc == 1) {
updateStack (se, cp, ac);
return 1;
}
popStack (sdata);
- if (rc == -1) mayskip = 1;
break;
case SCHEMA_CTYPE_VIRTUAL:
Tcl_Panic ("Virtual constrain in MIXED or CHOICE");
@@ -1060,23 +1059,16 @@
case SCHEMA_CTYPE_KEYSPACE_END:
case SCHEMA_CTYPE_KEYSPACE:
Tcl_Panic ("Keyspace constrain in MIXED or CHOICE");
}
- if (!mayskip && mayMiss (candidate->quants[i]))
- mayskip = 1;
}
break;
case SCHEMA_CTYPE_VIRTUAL:
if (evalVirtual (interp, sdata, ac)) {
- /* Virtual contraints are always quant ONE, so
- * that the virtual constraints are called while
- * looking if an element can end. Therefor we use
- * here the already present mayskip mechanism to
- * try further, after calling the tcl script. */
- mayskip = 1;
+ hm = 1;
break;
}
else return 0;
case SCHEMA_CTYPE_INTERLEAVE:
@@ -1117,11 +1109,11 @@
}
ac++;
hm = 0;
continue;
}
- if (!mayskip && mustMatch (cp->quants[ac], hm)) {
+ if (mustMatch (cp->quants[ac], hm)) {
if (recover (interp, sdata, S("MISSING_CP"), 1, ac)) {
/* Skip the just opened element tag and the following
* content of the current. */
return 1;
}
@@ -1148,33 +1140,24 @@
case SCHEMA_CTYPE_ANY:
/* Never pushed onto stack */
Tcl_Panic ("Invalid CTYPE onto the validation stack!");
case SCHEMA_CTYPE_INTERLEAVE:
- mayskip = 1;
+ missing = 0;
for (i = 0; i < cp->nc; i++) {
- if (se->interleaveState[i]) {
- if (maxOne (cp->quants[i])) continue;
- } else {
- if (minOne (cp->quants[i])) mayskip = 0;
- }
+ if (se->interleaveState[i] && maxOne (cp->quants[i]))
+ continue;
icp = cp->content[i];
switch (icp->type) {
case SCHEMA_CTYPE_TEXT:
- if (icp->nc) {
- if (!checkText (interp, icp, "")) {
- mayskip = 0;
- }
- }
break;
case SCHEMA_CTYPE_ANY:
- if (icp->namespace && icp->namespace == namespace) {
+ if (icp->namespace && icp->namespace != namespace) {
break;
}
sdata->skipDeep = 1;
- if (mayskip && minOne (cp->quants[i])) mayskip = 0;
se->hasMatched = 1;
se->interleaveState[i] = 1;
return 1;
case SCHEMA_CTYPE_NAME:
@@ -1198,11 +1181,10 @@
se->hasMatched = 1;
se->interleaveState[i] = 1;
return 1;
}
popStack (sdata);
- if (mayskip && rc != -1) mayskip = 0;
break;
case SCHEMA_CTYPE_VIRTUAL:
Tcl_Panic ("Virtual constraint child of INTERLEAVE");
break;
@@ -1211,16 +1193,18 @@
case SCHEMA_CTYPE_KEYSPACE:
Tcl_Panic ("Keyspace constraint child of INTERLEAVE");
break;
}
+ if (!missing && minOne (cp->quants[i])) missing = 1;
}
- if (mayskip) break;
- if (recover (interp, sdata, S("MISSING_ONE_OF_INTERLEAVE"), 1, ac)) {
- return 1;
+ if (missing) {
+ if (recover (interp, sdata, S("MISSING_ONE_OF_INTERLEAVE"), 1, ac)) {
+ return 1;
+ }
+ return 0;
}
- return 0;
}
return -1;
}
static void *
@@ -1660,11 +1644,10 @@
DBG(fprintf (stderr, "ac %d hm %d mayMiss: %d\n",
ac, hm, mayMiss (cp->quants[ac])));
if (mayMiss (cp->quants[ac])) {
ac++; continue;
}
-
switch (cp->content[ac]->type) {
case SCHEMA_CTYPE_KEYSPACE_END:
cp->content[ac]->keySpace->active--;
if (!cp->content[ac]->keySpace->active) {
if (cp->content[ac]->keySpace->unknownIDrefs) {
@@ -4204,11 +4187,11 @@
for (i = 1; i < objc; i++) {
pattern->content[i-1] = (SchemaCP *) objv[i];
Tcl_IncrRefCount (objv[i]);
}
pattern->nc = objc;
- addToContent (sdata, pattern, SCHEMA_CQUANT_OPT, 0, 0);
+ addToContent (sdata, pattern, SCHEMA_CQUANT_ONE, 0, 0);
return TCL_OK;
}
static int
domuniquePatternObjCmd (
Index: tests/schema.test
==================================================================
--- tests/schema.test
+++ tests/schema.test
@@ -1526,11 +1526,11 @@
} {
lappend result [s validate $xml]
}
set result
-} {0 0 1 0 1 1 1}
+} {0 0 1 0 1 1 0}
test schema-7.15a {choice with optional choices} {
tdom::schema create s
s define {
defelement doc {
@@ -1616,11 +1616,11 @@
} {
lappend result [s validate $xml]
}
set result
-} {0 0 1 0 1 1 1 1 1}
+} {0 0 1 0 1 1 1 1 0}
test schema-7.17 {choice with optional choices} {
tdom::schema create s
s define {
defelement doc {
@@ -1650,11 +1650,11 @@
} {
lappend result [s validate $xml]
}
set result
-} {0 0 1 0 1 1 0 0 1}
+} {0 0 1 0 1 1 0 0 0}
test schema-7.18 {choice} {
tdom::schema create s
s define {
defelement doc {
@@ -1732,11 +1732,11 @@
} {
lappend result [s validate $xml]
}
set result
-} {0 0 1 1 0 0 0 1 0 0 1}
+} {0 0 1 1 0 0 0 1 0 0 0}
test schema-7.20 {group with only optional content} {
tdom::schema create s
s define {
defelement doc {
@@ -4662,11 +4662,10 @@
lappend result [s validate $xml]
}
s delete
set result
} {0 1 0 1 0 1 1 0}
-
test schema-16.16 {interleave} {
tdom::schema s
s define {
foreach e {a b1 b11 b2 c} {