Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Save work.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip
Files: files | file ages | folders
SHA3-256: d2f12cc8d48945a37a8bee4b33889a564b00de4e7f3ca0d301045b5480770e9b
User & Date: rolf 2019-11-04 00:24:42
Context
2019-11-04
17:47
Fixes: Don't try to check attributes if in skip mode - it doesn't make sense to check attributes of an unknown element. Don't fumble with activeChild before calling out to virual matches. Report also element end as possible event (if that is possible, of course) for info expected. Closed-Leaf check-in: 65eff1573f user: rolf tags: wip
00:24
Save work. check-in: d2f12cc8d4 user: rolf tags: wip
2019-11-02
01:29
The SchemaValidationStack struct element activeChild (which turned into a misnomer by the last moves) - together with the hasMatched element - now gives the position of the last matched content particle (was the child to start look at for the next event). check-in: e795f2b9f0 user: rolf tags: wip
Changes

Changes to generic/schema.c.

861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
....
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
....
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
....
3209
3210
3211
3212
3213
3214
3215
3216
3217

3218
3219
3220
3221
3222
3223
3224
....
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
....
3307
3308
3309
3310
3311
3312
3313










































3314
3315
3316
3317
3318
3319
3320
....
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
....
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
....
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
....
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
    if (pattern->type == SCHEMA_CTYPE_INTERLEAVE) {
        se->interleaveState = MALLOC (sizeof (int) * pattern->nc);
        memset (se->interleaveState, 0, sizeof (int) * pattern->nc);
    }
    sdata->stack = se;
}

static void
savelastMatchse (
    SchemaData *sdata,
    int add
    )
{
    SchemaValidationStack *se, *nextse;
    
    if (!add) {
        se = sdata->lastMatchse;
        while (se) {
            nextse = se->down;
            repoolStackElement (sdata, se);
            se = nextse;
        }
    }
    se = getStackElement (sdata, sdata->stack->pattern);
    se->activeChild = sdata->stack->activeChild;
    se->hasMatched = sdata->stack->hasMatched;
    se->down = NULL;
    if (se->pattern->type == SCHEMA_CTYPE_INTERLEAVE) {
        se->interleaveState = MALLOC (sizeof (int) * se->pattern->nc);
        memcpy (se->interleaveState, sdata->stack->interleaveState,
                se->pattern->nc);
    }
    if (sdata->lastMatchse && add) {
        nextse = sdata->lastMatchse;
        while (nextse->down) {
            nextse = nextse->down;
        }
        nextse->down = se;
    } else {
        sdata->lastMatchse = se;
    }
}

static void
popFromStack (
    SchemaData *sdata,
    SchemaValidationStack **stack
    )
{
    SchemaValidationStack *se;
................................................................................
            || cp->flags & PLACEHOLDER_PATTERN_DEF) continue;
        elmObj = serializeElementName (interp, cp);
        Tcl_ListObjAppendElement (interp, rObj, elmObj);
    }
}

static int
getNextExpected (
    SchemaData *sdata,
    SchemaValidationStack *se,
    Tcl_Interp *interp,
    Tcl_HashTable *seenCPs,
    Tcl_Obj *rObj
    )
{
    int ac, hm, i, hnew, mustMatch, mayskip, rc;
    SchemaCP *cp, *ic, *jc;
    SchemaValidationStack *se1;

    getContext (cp, ac, hm);
    if (hm && maxOne(cp->quants[ac])) ac++;
    switch (cp->type) {
    case SCHEMA_CTYPE_INTERLEAVE:
................................................................................
                                          serializeElementName (interp, ic));
                break;
            case SCHEMA_CTYPE_INTERLEAVE:
            case SCHEMA_CTYPE_PATTERN:
                Tcl_CreateHashEntry (seenCPs, ic, &hnew);
                if (hnew) {
                    se1 = getStackElement (sdata, ic);
                    mayskip = getNextExpected (sdata, se1, interp, seenCPs,
                                               rObj);
                    repoolStackElement (sdata, se1);
                }
                break;

            case SCHEMA_CTYPE_ANY:
                Tcl_ListObjAppendElement (interp, rObj,
                                          serializeAnyCP (interp, ic));
................................................................................
                            );
                        break;
                    case SCHEMA_CTYPE_INTERLEAVE:
                    case SCHEMA_CTYPE_PATTERN:
                        Tcl_CreateHashEntry (seenCPs, jc, &hnew);
                        if (hnew) {
                            se1 = getStackElement (sdata, ic);
                            mayskip = getNextExpected (sdata, se1, interp,
                                                       seenCPs, rObj);

                            repoolStackElement (sdata, se1);
                        }
                        break;
                    case SCHEMA_CTYPE_ANY:
                        Tcl_ListObjAppendElement (
                            interp, rObj, serializeAnyCP (interp, jc)
                            );
................................................................................
    }
    if (cp->type == SCHEMA_CTYPE_NAME) {
        return 0;
    }
    if (cp->type == SCHEMA_CTYPE_INTERLEAVE && mustMatch) {
        return 0;
    }
    if (se->down) {
        hm = se->down->hasMatched;
        se->down->hasMatched = 1;
        rc = getNextExpected (sdata, se->down, interp, seenCPs, rObj);
        se->down->hasMatched = hm;
        return rc;
    }
    return 1;
}

static Tcl_Obj *
unifyMatchList (
    Tcl_Interp *interp,
    Tcl_HashTable *htable,
................................................................................
         h != NULL;
         h = Tcl_NextHashEntry (&search)) {
        Tcl_ListObjAppendElement (interp, rObj, Tcl_GetHashValue (h));
    }
    Tcl_DeleteHashTable (htable);
    return rObj;
}











































static int
schemaInstanceInfoCmd (
    SchemaData *sdata,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]
................................................................................
{
    int methodIndex;
    Tcl_HashEntry *h;
    SchemaCP *cp;
    SchemaValidationStack *se;
    void *ns;
    Tcl_Obj *rObj;
    Tcl_HashTable localHash;
    
    static const char *schemaInstanceInfoMethods[] = {
        "validationstate", "vstate", "definedElements", "stack", "toplevel",
        "pastexpected", "nextexpected", "definition", "validationaction",
        "vaction", NULL
    };
    enum schemaInstanceInfoMethod {
        m_validationstate, m_vstate, m_definedElements, m_stack, m_toplevel,
        m_pastexpected, m_nextexpected, m_definition, m_validationaction,
        m_vaction
    };

    static const char *schemaInstanceInfoStackMethods[] = {
        "top", "inside", NULL
    };
    enum schemaInstanceInfoStackMethod {
................................................................................
                    Tcl_ListObjAppendElement (interp, rObj,
                        serializeElementName (interp, se->pattern));
                }
                se = se->down;
            }
            Tcl_SetObjResult (interp, rObj);
            return TCL_OK;
            break;
            
        case m_top:
            if (!sdata->stack) {
                Tcl_ResetResult (interp);
                return TCL_OK;
            }
            se = sdata->stack;
            while (se->pattern->type != SCHEMA_CTYPE_NAME) {
                se = se->down;
            }
            rObj = serializeElementName (interp, se->pattern);
            Tcl_SetObjResult (interp, rObj);
            return TCL_OK;
            break;
        }
        
    case m_toplevel:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
................................................................................
        if (!sdata->defineToplevel && sdata->currentEvals > 1) {
            SetBooleanResult (0);
        } else {
            SetBooleanResult (1);
        }
        return TCL_OK;

    case m_nextexpected:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        if (sdata->validationState == VALIDATION_ERROR
            || sdata->validationState == VALIDATION_FINISHED) {
            return TCL_OK;
................................................................................
                if (sdata->startNamespace) {
                    Tcl_AppendElement (interp, sdata->startNamespace);
                }
            } else {
                definedElements (sdata, interp);
            }
        } else {
            rObj = Tcl_NewObj();
            Tcl_InitHashTable (&localHash, TCL_ONE_WORD_KEYS);
            getNextExpected (sdata, sdata->stack, interp, &localHash, rObj);
            Tcl_DeleteHashTable (&localHash);
            Tcl_SetObjResult (interp, unifyMatchList (interp, &localHash,
                                                      rObj));
            Tcl_DecrRefCount (rObj);
        }
        return TCL_OK;
        
    case m_pastexpected:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        if (sdata->validationState == VALIDATION_READY || !sdata->stack)
            return TCL_OK;
        se = sdata->lastMatchse;
        if (!se) se = sdata->stack;
        rObj = Tcl_NewObj();
        Tcl_InitHashTable (&localHash, TCL_ONE_WORD_KEYS);
        getNextExpected (sdata, se, interp, &localHash, rObj);
        Tcl_DeleteHashTable (&localHash);
        Tcl_SetObjResult (interp, unifyMatchList (interp, &localHash,
                                                  rObj));
        Tcl_DecrRefCount (rObj);
        
        
        break;
        
    case m_definition:
        if (objc < 3 && objc > 4) {
            Tcl_WrongNumArgs (interp, 1, objv, "name ?namespace?");
            return TCL_ERROR;
        }







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







|







 







|
|







 







|
|
>







 







<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<



|
<



|







 







<













<







 







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<







861
862
863
864
865
866
867




































868
869
870
871
872
873
874
....
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
....
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
....
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
....
3226
3227
3228
3229
3230
3231
3232







3233
3234
3235
3236
3237
3238
3239
....
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
....
3322
3323
3324
3325
3326
3327
3328

3329
3330
3331
3332

3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
....
3414
3415
3416
3417
3418
3419
3420

3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433

3434
3435
3436
3437
3438
3439
3440
....
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
....
3464
3465
3466
3467
3468
3469
3470





















3471




3472

3473
3474
3475
3476
3477
3478
3479
    if (pattern->type == SCHEMA_CTYPE_INTERLEAVE) {
        se->interleaveState = MALLOC (sizeof (int) * pattern->nc);
        memset (se->interleaveState, 0, sizeof (int) * pattern->nc);
    }
    sdata->stack = se;
}





































static void
popFromStack (
    SchemaData *sdata,
    SchemaValidationStack **stack
    )
{
    SchemaValidationStack *se;
................................................................................
            || cp->flags & PLACEHOLDER_PATTERN_DEF) continue;
        elmObj = serializeElementName (interp, cp);
        Tcl_ListObjAppendElement (interp, rObj, elmObj);
    }
}

static int
getNextExpectedWorker (
    SchemaData *sdata,
    SchemaValidationStack *se,
    Tcl_Interp *interp,
    Tcl_HashTable *seenCPs,
    Tcl_Obj *rObj
    )
{
    int ac, hm, i, hnew, mustMatch, mayskip;
    SchemaCP *cp, *ic, *jc;
    SchemaValidationStack *se1;

    getContext (cp, ac, hm);
    if (hm && maxOne(cp->quants[ac])) ac++;
    switch (cp->type) {
    case SCHEMA_CTYPE_INTERLEAVE:
................................................................................
                                          serializeElementName (interp, ic));
                break;
            case SCHEMA_CTYPE_INTERLEAVE:
            case SCHEMA_CTYPE_PATTERN:
                Tcl_CreateHashEntry (seenCPs, ic, &hnew);
                if (hnew) {
                    se1 = getStackElement (sdata, ic);
                    mayskip = getNextExpectedWorker (sdata, se1, interp,
                                                     seenCPs, rObj);
                    repoolStackElement (sdata, se1);
                }
                break;

            case SCHEMA_CTYPE_ANY:
                Tcl_ListObjAppendElement (interp, rObj,
                                          serializeAnyCP (interp, ic));
................................................................................
                            );
                        break;
                    case SCHEMA_CTYPE_INTERLEAVE:
                    case SCHEMA_CTYPE_PATTERN:
                        Tcl_CreateHashEntry (seenCPs, jc, &hnew);
                        if (hnew) {
                            se1 = getStackElement (sdata, ic);
                            mayskip = getNextExpectedWorker (
                                sdata, se1, interp, seenCPs, rObj
                                );
                            repoolStackElement (sdata, se1);
                        }
                        break;
                    case SCHEMA_CTYPE_ANY:
                        Tcl_ListObjAppendElement (
                            interp, rObj, serializeAnyCP (interp, jc)
                            );
................................................................................
    }
    if (cp->type == SCHEMA_CTYPE_NAME) {
        return 0;
    }
    if (cp->type == SCHEMA_CTYPE_INTERLEAVE && mustMatch) {
        return 0;
    }







    return 1;
}

static Tcl_Obj *
unifyMatchList (
    Tcl_Interp *interp,
    Tcl_HashTable *htable,
................................................................................
         h != NULL;
         h = Tcl_NextHashEntry (&search)) {
        Tcl_ListObjAppendElement (interp, rObj, Tcl_GetHashValue (h));
    }
    Tcl_DeleteHashTable (htable);
    return rObj;
}

static void
getNextExpected (
    SchemaData *sdata,
    Tcl_Interp *interp
    )
{
    int remainingLastMatch, count;
    Tcl_Obj *rObj;
    Tcl_HashTable localHash;
    SchemaValidationStack *se;

    remainingLastMatch = 0;
    if (sdata->lastMatchse) {
        se = sdata->lastMatchse;
        while (se->down) {
            remainingLastMatch++;
            se = se->down;
        }
    } else {
        se = sdata->stack;
    }
    rObj = Tcl_NewObj();
    Tcl_InitHashTable (&localHash, TCL_ONE_WORD_KEYS);
    while (getNextExpectedWorker (sdata, se, interp, &localHash, rObj)) {
        if (remainingLastMatch) {
            count = 0;
            se = sdata->lastMatchse;
            while (count < remainingLastMatch) {
                se = se->down;
                count++;
            }
            remainingLastMatch--;
        } else {
            se = se->down;
        }
    }
    Tcl_DeleteHashTable (&localHash);
    Tcl_SetObjResult (interp, unifyMatchList (interp, &localHash,
                                              rObj));
    Tcl_DecrRefCount (rObj);
}

static int
schemaInstanceInfoCmd (
    SchemaData *sdata,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]
................................................................................
{
    int methodIndex;
    Tcl_HashEntry *h;
    SchemaCP *cp;
    SchemaValidationStack *se;
    void *ns;
    Tcl_Obj *rObj;

    
    static const char *schemaInstanceInfoMethods[] = {
        "validationstate", "vstate", "definedElements", "stack", "toplevel",
        "expected", "definition", "validationaction", "vaction", NULL

    };
    enum schemaInstanceInfoMethod {
        m_validationstate, m_vstate, m_definedElements, m_stack, m_toplevel,
        m_expected, m_definition, m_validationaction,
        m_vaction
    };

    static const char *schemaInstanceInfoStackMethods[] = {
        "top", "inside", NULL
    };
    enum schemaInstanceInfoStackMethod {
................................................................................
                    Tcl_ListObjAppendElement (interp, rObj,
                        serializeElementName (interp, se->pattern));
                }
                se = se->down;
            }
            Tcl_SetObjResult (interp, rObj);
            return TCL_OK;

            
        case m_top:
            if (!sdata->stack) {
                Tcl_ResetResult (interp);
                return TCL_OK;
            }
            se = sdata->stack;
            while (se->pattern->type != SCHEMA_CTYPE_NAME) {
                se = se->down;
            }
            rObj = serializeElementName (interp, se->pattern);
            Tcl_SetObjResult (interp, rObj);
            return TCL_OK;

        }
        
    case m_toplevel:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
................................................................................
        if (!sdata->defineToplevel && sdata->currentEvals > 1) {
            SetBooleanResult (0);
        } else {
            SetBooleanResult (1);
        }
        return TCL_OK;

    case m_expected:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        if (sdata->validationState == VALIDATION_ERROR
            || sdata->validationState == VALIDATION_FINISHED) {
            return TCL_OK;
................................................................................
                if (sdata->startNamespace) {
                    Tcl_AppendElement (interp, sdata->startNamespace);
                }
            } else {
                definedElements (sdata, interp);
            }
        } else {





















            getNextExpected (sdata, interp);




        }

        break;
        
    case m_definition:
        if (objc < 3 && objc > 4) {
            Tcl_WrongNumArgs (interp, 1, objv, "name ?namespace?");
            return TCL_ERROR;
        }

Changes to tests/schema.test.

5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
....
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
....
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
....
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
....
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
....
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
....
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
....
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
    set result
} {defelement b {
            element b1 1 text
            element a
            element b2
        }}

test schema-17.5 {info nextexpected} {
    tdom::schema s
    s define {
        defelement doc {
            choice ? {
                element a
                element c
                element b
................................................................................
            }
            element toplevel ?
            element musthave
            element aftermust
        }
    }
    s event start doc
    set result [s info nextexpected]
    s delete
    lsort $result
} {a b c musthave toplevel}

test schema-17.6 {info nextexpected} {
    tdom::schema s
    s prefixns {foo http://foo.bar}
    s define {
        defelement doc {
            choice ? {
                element a
                element c
................................................................................
            namespace foo {
                element musthave
            }
            element aftermust
        }
    }
    s event start doc
    set result [s info nextexpected]
    s delete
    lsort $result
} {a b c {musthave http://foo.bar} toplevel}

test schema-17.7 {info nextexpected} {
    tdom::schema s
    s prefixns {foo http://foo.bar}
    s define {
        defelement doc {
            mixed {
                element a
                element c
................................................................................
            namespace foo {
                element musthave
            }
            element aftermust
        }
    }
    s event start doc
    set result [s info nextexpected]
    s delete
    lsort $result
} {a b c {musthave http://foo.bar} toplevel {{#text} {}}}

test schema-17.8 {info nextexpected} {
    tdom::schema s
    s defelement doc {
        choice ? {
            element a
            element c
            element b
        }
        element toplevel ?
        element musthave
        element aftermust
    }
    set result [s info nextexpected]
    s define {
        foreach elm {a b c} {
            defelement $elm {}
        }
    }
    lappend result {*}[lsort [s info nextexpected]]
    s event start doc
    lappend result {*}[lsort [s info nextexpected]]
    s event start c
    s event end
    lappend result {*}[lsort [s info nextexpected]]
    s delete
    set result
} {doc a b c doc a b c musthave toplevel musthave toplevel}

proc schema-17.9 {scmd} {
    global result
    lappend result {*}[lsort [$scmd info nextexpected]]
}
                  
test schema-17.9 {info nextexpected from scripted constrain} {
    tdom::schema s
    s define {
        defpattern some {
            element a ?
            group ? {
                element b ?
                tcl schema-17.9
................................................................................
    }
    set result ""
    lappend [s validate {<doc><must/></doc>}]
    s delete
    set result
} {c may must}

test schema-17.10 {info nextexpected interleave} {
    set defs {
        {
            interleave {
                element a ?
                element b
                element c ?
            }
................................................................................
        }
    }
    set result [list]
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s event start doc
        lappend result {*}[lsort [s info nextexpected]]
        s delete
    }
    set result
} {a b c a b c d a b c d}

test schema-17.11 {info nextexpected} {
    set defs {
        {
            group + {
                element c ?
                element a ?
                element b ?
            }
................................................................................
    set result [list]
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s event start doc
        s event start b
        s event end
        set result [lsort [s info nextexpected]]
        s delete
    }
    set result
} {a b c d}

test schema-17.12 {info nextexpected} {
    tdom::schema s
    s define {
        prefixns {ns1 http://foo.bar}
        defelement doc {
            element a
            any
            any ns1 ?
            element b ?
        }
    }
    s event start doc
    s event start a
    s event end
    set result [lsort [s info nextexpected]]
    s event start something
    s event end
    lappend result {*}[lsort [s info nextexpected]]
    s delete
    set result
} {{<any> {}} {<any> http://foo.bar} b}

proc schema-17.13 {scmd args} {
    global result
    lappend result {*}[lsort [$scmd info pastexpected]]
}
test schema-17.13 {info pastexpected} {
    set defs {
        {
            element a
            element b ?
        }
        {
            element a ?
................................................................................
        incr defnr
    }
    set result
} {}

proc schema-17.14 {scmd} {
    global result
    lappend result {*}[lsort [$scmd info pastexpected]]
}
test schema-17.14 {info pastexpected} {
    set defs {
        {
            group + {
                element c ?
                element a ?
                element b ?
            }







|







 







|




|







 







|




|







 







|




|











|





|

|


|






|


|







 







|







 







|





|







 







|





|













|


|






|

|







 







|

|







5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
....
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
....
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
....
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
....
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
....
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
....
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
....
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
    set result
} {defelement b {
            element b1 1 text
            element a
            element b2
        }}

test schema-17.5 {info expected} {
    tdom::schema s
    s define {
        defelement doc {
            choice ? {
                element a
                element c
                element b
................................................................................
            }
            element toplevel ?
            element musthave
            element aftermust
        }
    }
    s event start doc
    set result [s info expected]
    s delete
    lsort $result
} {a b c musthave toplevel}

test schema-17.6 {info expected} {
    tdom::schema s
    s prefixns {foo http://foo.bar}
    s define {
        defelement doc {
            choice ? {
                element a
                element c
................................................................................
            namespace foo {
                element musthave
            }
            element aftermust
        }
    }
    s event start doc
    set result [s info expected]
    s delete
    lsort $result
} {a b c {musthave http://foo.bar} toplevel}

test schema-17.7 {info expected} {
    tdom::schema s
    s prefixns {foo http://foo.bar}
    s define {
        defelement doc {
            mixed {
                element a
                element c
................................................................................
            namespace foo {
                element musthave
            }
            element aftermust
        }
    }
    s event start doc
    set result [s info expected]
    s delete
    lsort $result
} {a b c {musthave http://foo.bar} toplevel {{#text} {}}}

test schema-17.8 {info expected} {
    tdom::schema s
    s defelement doc {
        choice ? {
            element a
            element c
            element b
        }
        element toplevel ?
        element musthave
        element aftermust
    }
    set result [s info expected]
    s define {
        foreach elm {a b c} {
            defelement $elm {}
        }
    }
    lappend result {*}[lsort [s info expected]]
    s event start doc
    lappend result {*}[lsort [s info expected]]
    s event start c
    s event end
    lappend result {*}[lsort [s info expected]]
    s delete
    set result
} {doc a b c doc a b c musthave toplevel musthave toplevel}

proc schema-17.9 {scmd} {
    global result
    lappend result {*}[lsort [$scmd info expected]]
}
                  
test schema-17.9 {info expected from scripted constrain} {
    tdom::schema s
    s define {
        defpattern some {
            element a ?
            group ? {
                element b ?
                tcl schema-17.9
................................................................................
    }
    set result ""
    lappend [s validate {<doc><must/></doc>}]
    s delete
    set result
} {c may must}

test schema-17.10 {info expected interleave} {
    set defs {
        {
            interleave {
                element a ?
                element b
                element c ?
            }
................................................................................
        }
    }
    set result [list]
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s event start doc
        lappend result {*}[lsort [s info expected]]
        s delete
    }
    set result
} {a b c a b c d a b c d}

test schema-17.11 {info expected} {
    set defs {
        {
            group + {
                element c ?
                element a ?
                element b ?
            }
................................................................................
    set result [list]
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s event start doc
        s event start b
        s event end
        set result [lsort [s info expected]]
        s delete
    }
    set result
} {a b c d}

test schema-17.12 {info expected} {
    tdom::schema s
    s define {
        prefixns {ns1 http://foo.bar}
        defelement doc {
            element a
            any
            any ns1 ?
            element b ?
        }
    }
    s event start doc
    s event start a
    s event end
    set result [lsort [s info expected]]
    s event start something
    s event end
    lappend result {*}[lsort [s info expected]]
    s delete
    set result
} {{<any> {}} {<any> http://foo.bar} b}

proc schema-17.13 {scmd args} {
    global result
    lappend result {*}[lsort [$scmd info expected]]
}
test schema-17.13 {info expected} {
    set defs {
        {
            element a
            element b ?
        }
        {
            element a ?
................................................................................
        incr defnr
    }
    set result
} {}

proc schema-17.14 {scmd} {
    global result
    lappend result {*}[lsort [$scmd info expected]]
}
test schema-17.14 {info expected} {
    set defs {
        {
            group + {
                element c ?
                element a ?
                element b ?
            }