Index: generic/schema.c ================================================================== --- generic/schema.c +++ generic/schema.c @@ -298,10 +298,11 @@ /* content/quant will be allocated, if the cp in fact has * constraints */ break; case SCHEMA_CTYPE_VIRTUAL: case SCHEMA_CTYPE_ANY: + case SCHEMA_CTYPE_KEYSPACE: /* Do nothing */ break; } return pattern; } @@ -925,10 +926,13 @@ break; case SCHEMA_CTYPE_VIRTUAL: Tcl_Panic ("Virtual constrain in MIXED or CHOICE"); + case SCHEMA_CTYPE_KEYSPACE: + Tcl_Panic ("Keyspace constrain in MIXED or CHOICE"); + } if (!mayskip && mayMiss (candidate->quants[i])) mayskip = 1; } break; @@ -953,10 +957,13 @@ updateStack (se, cp, ac); return 1; } popStack (sdata); + break; + case SCHEMA_CTYPE_KEYSPACE: + break; } if (!mayskip && mustMatch (cp->quants[ac], hm)) { if (recover (interp, sdata, S("MISSING_CP"))) { /* Skip the just opened element tag and the following @@ -978,10 +985,11 @@ } return 0; } return -1; + case SCHEMA_CTYPE_KEYSPACE: case SCHEMA_CTYPE_VIRTUAL: case SCHEMA_CTYPE_CHOICE: case SCHEMA_CTYPE_TEXT: case SCHEMA_CTYPE_ANY: /* Never pushed onto stack */ @@ -1037,10 +1045,15 @@ break; case SCHEMA_CTYPE_VIRTUAL: Tcl_Panic ("Virtual constraint child of INTERLEAVE"); break; + + case SCHEMA_CTYPE_KEYSPACE: + Tcl_Panic ("Keyspace constraint child of INTERLEAVE"); + break; + } } if (mayskip) break; @@ -1467,10 +1480,13 @@ if (mayMiss (cp->quants[ac])) { ac++; continue; } switch (cp->content[ac]->type) { + case SCHEMA_CTYPE_KEYSPACE: + break; + case SCHEMA_CTYPE_TEXT: if (cp->content[ac]->nc) { if (!checkText (interp, cp->content[ac], "")) { if (recover (interp, sdata, S("MISSING_TEXT"))) { break; @@ -1496,12 +1512,10 @@ } } mayMiss = 1; break; - case SCHEMA_CTYPE_CHOICE: - /* Can't happen */ case SCHEMA_CTYPE_NAME: case SCHEMA_CTYPE_ANY: continue; case SCHEMA_CTYPE_INTERLEAVE: @@ -1511,12 +1525,14 @@ mayMiss = 1; } popStack (sdata); break; + case SCHEMA_CTYPE_KEYSPACE: case SCHEMA_CTYPE_VIRTUAL: - Tcl_Panic ("Virtual constrain in MIXED or CHOICE"); + case SCHEMA_CTYPE_CHOICE: + Tcl_Panic ("Invalid CTYPE in MIXED or CHOICE"); } if (mayMiss) break; } if (mayMiss) break; @@ -1547,10 +1563,11 @@ ac++; } if (isName) return 1; return -1; + case SCHEMA_CTYPE_KEYSPACE: case SCHEMA_CTYPE_VIRTUAL: case SCHEMA_CTYPE_CHOICE: case SCHEMA_CTYPE_TEXT: case SCHEMA_CTYPE_ANY: /* Never pushed onto stack */ @@ -1759,10 +1776,13 @@ break; case SCHEMA_CTYPE_CHOICE: Tcl_Panic ("MIXED or CHOICE child of MIXED or CHOICE"); + case SCHEMA_CTYPE_KEYSPACE: + Tcl_Panic ("Keyspace constrain in MIXED or CHOICE"); + } } if (mustMatch (cp->quants[ac], hm)) { SetResult ("Unexpected text content"); return 0; @@ -1783,10 +1803,14 @@ } break; case SCHEMA_CTYPE_VIRTUAL: if (!evalVirtual (interp, sdata, candidate)) return 0; + break; + + case SCHEMA_CTYPE_KEYSPACE: + break; case SCHEMA_CTYPE_NAME: case SCHEMA_CTYPE_ANY: if (mustMatch (cp->quants[ac], hm)) { @@ -1840,15 +1864,22 @@ break; case SCHEMA_CTYPE_CHOICE: Tcl_Panic ("MIXED or CHOICE child of INTERLEAVE"); + case SCHEMA_CTYPE_KEYSPACE: + Tcl_Panic ("Keyspace child of INTERLEAVE"); + case SCHEMA_CTYPE_VIRTUAL: break; } } + + case SCHEMA_CTYPE_KEYSPACE: + + break; } break; } return 0; } @@ -3644,15 +3675,12 @@ if (objc < 2) { SetResult ("Expected: ?arg? ?arg? ..."); return TCL_ERROR; } - switch (sdata->cp->type) { - case SCHEMA_CTYPE_NAME: - case SCHEMA_CTYPE_PATTERN: - break; - default: + if (sdata->cp->type != SCHEMA_CTYPE_NAME + && sdata->cp->type != SCHEMA_CTYPE_PATTERN) { SetResult ("The \"tcl\" schema definition command is only " "allowed in sequential context (defelement, " "element or defpattern)"); return TCL_ERROR; } @@ -3670,11 +3698,11 @@ addToContent (sdata, pattern, SCHEMA_CQUANT_ONE, 0, 0); return TCL_OK; } static int -domuniquePatternCmd ( +domuniquePatternObjCmd ( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] ) @@ -3749,10 +3777,45 @@ if (objc == 4) { kc->name = tdomstrdup (Tcl_GetString (objv[3])); } kc->next = sdata->cp->domKeys; sdata->cp->domKeys = kc; + return TCL_OK; +} + +static int +keyspacePatternObjCmd ( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[] + ) +{ + SchemaData *sdata = GETASI; + SchemaCP *pattern; + int nrFlags; + + CHECK_SI + CHECK_TOPLEVEL + checkNrArgs (2, 3, "Expected: ?flags?"); + if (sdata->cp->type != SCHEMA_CTYPE_NAME + && sdata->cp->type != SCHEMA_CTYPE_PATTERN) { + SetResult ("The keyspace schema definition command is only " + "allowed in sequential context (defelement, " + "element or defpattern)"); + return TCL_ERROR; + } + if (objc == 3) { + if (Tcl_ListObjLength (interp, objv[2], &nrFlags) != TCL_OK) { + SetResult ("The optional argument must be a valid tcl " + "list"); + return TCL_ERROR; + } + } + pattern = initSchemaCP (SCHEMA_CTYPE_KEYSPACE, NULL, NULL); + REMEMBER_PATTERN (pattern); + return TCL_OK; } static int integerImpl ( @@ -5040,11 +5103,12 @@ Tcl_CreateObjCommand (interp, "tdom::schema::interleave", AnonPatternObjCmd, (ClientData) 2, NULL); Tcl_CreateObjCommand (interp, "tdom::schema::group", AnonPatternObjCmd, (ClientData) 3, NULL); - /* The "attribute", "nsattribute", "namespace" and "text" definition commands. */ + /* The "attribute", "nsattribute", "namespace" and "text" + * definition commands. */ Tcl_CreateObjCommand (interp, "tdom::schema::attribute", AttributePatternObjCmd, NULL, NULL); Tcl_CreateObjCommand (interp, "tdom::schema::nsattribute", AttributePatternObjCmd, (ClientData) 1, NULL); Tcl_CreateObjCommand (interp, "tdom::schema::namespace", @@ -5056,11 +5120,15 @@ Tcl_CreateObjCommand (interp, "tdom::schema::tcl", VirtualPatternObjCmd, NULL, NULL); /* XPath contraints for DOM validation */ Tcl_CreateObjCommand (interp,"tdom::schema::domunique", - domuniquePatternCmd, NULL, NULL); + domuniquePatternObjCmd, NULL, NULL); + + /* Local key constraints */ + Tcl_CreateObjCommand (interp, "tdom::schema::keyspace", + keyspacePatternObjCmd, NULL, NULL); /* The text constraint commands */ Tcl_CreateObjCommand (interp,"tdom::schema::text::integer", integerTCObjCmd, NULL, NULL); Tcl_CreateObjCommand (interp, "tdom::schema::text::tcl", Index: generic/schema.h ================================================================== --- generic/schema.h +++ generic/schema.h @@ -32,11 +32,12 @@ SCHEMA_CTYPE_NAME, SCHEMA_CTYPE_CHOICE, SCHEMA_CTYPE_INTERLEAVE, SCHEMA_CTYPE_PATTERN, SCHEMA_CTYPE_TEXT, - SCHEMA_CTYPE_VIRTUAL + SCHEMA_CTYPE_VIRTUAL, + SCHEMA_CTYPE_KEYSPACE } Schema_CP_Type; typedef enum { SCHEMA_CQUANT_ONE, SCHEMA_CQUANT_OPT,