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} {