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

Overview
Comment:Merged from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip
Files: files | file ages | folders
SHA3-256: c416325b0b873596ceae78aa81abac6ba940bb04024251932dd774668cead278
User & Date: rolf 2019-10-24 22:05:16
Context
2019-10-25
00:30
INVALID_DOM_KEYCONSTRAINT is really not a validation error but a validation script error (as a TCL_ERROR from a called script. Though, the evalError flag isn't respected anywhere, obviously. check-in: a77a3f3b23 user: rolf tags: wip
2019-10-24
22:05
Merged from trunk. check-in: c416325b0b user: rolf tags: wip
14:12
Added xsd as new format (and default) to the text constraint command "number". check-in: c2b6dd2267 user: rolf tags: schema
2019-10-23
09:25
Merged from schema. check-in: 3c16fd1ab1 user: rolf tags: wip
Changes

Changes to generic/schema.c.

1804
1805
1806
1807
1808
1809
1810




1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
....
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
....
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472

3473
3474
3475
3476
3477
3478
3479
....
3712
3713
3714
3715
3716
3717
3718
3719

3720
3721
3722
3723
3724
3725




3726
3727


3728
3729
3730
3731
3732

3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
....
5214
5215
5216
5217
5218
5219
5220
5221





















5222
5223
5224
5225
5226
5227
5228
....
5238
5239
5240
5241
5242
5243
5244








5245
5246
5247
5248








5249


5250





5251
5252
5253
5254
5255
5256
5257
    char *name, *ns;
    SchemaCP *cp;
    Tcl_HashEntry *h;
    Tcl_Obj *attname, *attns, *attvalue;

    cp = sdata->stack->pattern;
    for (i = 0; i < len; i += 2) {




        Tcl_ListObjIndex (interp, attr, i, &attname);
        Tcl_ListObjIndex (interp, attr, i+1, &attvalue);
        if (Tcl_ListObjLength (interp, attname, &len) == TCL_OK) {
            if (len == 2) {
                Tcl_ListObjIndex (interp, attname, 1, &attns);
                Tcl_ListObjIndex (interp, attname, 1, &attname);
            }
        }
        h = Tcl_FindHashEntry (&sdata->attrNames, Tcl_GetString (attname));
        if (!h) goto unknown;
        name = Tcl_GetHashKey (&sdata->attrNames, h);
        if (attns) {
            h = Tcl_FindHashEntry (&sdata->namespace, Tcl_GetString (attns));
................................................................................
                                Tcl_GetString (attvalue), &req);
        reqAttr += req;
    unknown:
        if (!found) {
            if (!recover (interp, sdata, S("UNKNOWN_ATTRIBUTE"), 0, 0)) {
                if (ns) {
                    SetResult ("Unknown attribute \"");
                    Tcl_AppendResult (interp, ns, ":", ns,
                                      "\"");
                } else {
                    SetResult3 ("Unknown attribute \"", name, "\"");
                }
                sdata->validationState = VALIDATION_ERROR;
                return TCL_ERROR;
            }
................................................................................
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]
    )
{
    int            methodIndex, keywordIndex, hnew, patternIndex;
    int            result = TCL_OK, forwardDef = 0, i = 0, j;
    int            savedDefineToplevel, type, len, checkAttr;
    unsigned int   savedNumPatternList;
    SchemaData    *savedsdata = NULL, *sdata = (SchemaData *) clientData;
    Tcl_HashTable *hashTable;
    Tcl_HashEntry *h, *h1;
    SchemaCP      *pattern, *current = NULL;
    void          *namespacePtr, *savedNamespacePtr;
    char          *xmlstr, *errMsg;
    domDocument   *doc;
    domNode       *node;


    static const char *schemaInstanceMethods[] = {
        "defelement",  "defpattern",  "start", "event",     "delete",
        "nrForwardDefinitions",       "reset", "define",    "validate",
        "domvalidate", "deftext",     "info",  "reportcmd", "prefixns",
        NULL
    };
................................................................................
        case k_elementstart:
            if (objc < 4 && objc > 6) {
                Tcl_WrongNumArgs (interp, 3, objv, "<elementname>"
                    "?<attInfo>? ?<namespace>?");
                return TCL_ERROR;
            }
            namespacePtr = NULL;
            checkAttr = 0;

            if (objc == 6) {
                namespacePtr = getNamespacePtr (sdata,
                                                Tcl_GetString (objv[5]));
            }
            if (objc >= 5) {
                if (Tcl_ListObjLength (interp, objv[4], &len) != TCL_OK) {




                    namespacePtr = getNamespacePtr (sdata,
                                                    Tcl_GetString (objv[4]));


                } else {
                    if (len == 1) {
                        namespacePtr = getNamespacePtr (
                            sdata, Tcl_GetString (objv[4])
                            );

                    } else if (len % 2 != 0) {
                        SetResult ("Invalid attribute information");
                        return TCL_ERROR;
                    } else {
                        checkAttr = 1;
                    }
                }
            }
            result = probeElement (interp, sdata, Tcl_GetString (objv[3]),
                                   namespacePtr);
            if (result == TCL_OK && checkAttr) {
                if (!probeEventAttribute (interp, sdata, objv[4], len)) {
                    return TCL_ERROR;
                }
            }
            break;
            
        case k_elementend:
            if (objc != 3) {
                Tcl_WrongNumArgs (interp, 3, objv, "No arguments expected.");
                return TCL_ERROR;
................................................................................
    checkNrArgs (1,1,"No arguments expected");
    ADD_CONSTRAINT (sdata, sc)
    sc->constraint = nmtokensImpl;
    return TCL_OK;
}

static int
numberImpl (





















    Tcl_Interp *interp,
    void *constraintData,
    char *text
    )
{
    double d;

................................................................................
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]
    )
{
    SchemaData *sdata = GETASI;
    SchemaConstraint *sc;









    CHECK_TI
    CHECK_TOPLEVEL
    checkNrArgs (1,1,"No arguments expected");








    ADD_CONSTRAINT (sdata, sc)


    sc->constraint = numberImpl;





    return TCL_OK;
}

static int
booleanImplXsd (
    Tcl_Interp *interp,
    void *constraintData,







>
>
>
>





|







 







|







 







|









>







 







|
>






>
>
>
>
|
|
>
>


|
|
<
>




|





|
|
<
<







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>



|
>
>
>
>
>
>
>
>

>
>
|
>
>
>
>
>







1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
....
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
....
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
....
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743

3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756


3757
3758
3759
3760
3761
3762
3763
....
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
....
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
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
    char *name, *ns;
    SchemaCP *cp;
    Tcl_HashEntry *h;
    Tcl_Obj *attname, *attns, *attvalue;

    cp = sdata->stack->pattern;
    for (i = 0; i < len; i += 2) {
        found = 0;
        ns = NULL;
        name = NULL;
        attns = NULL;
        Tcl_ListObjIndex (interp, attr, i, &attname);
        Tcl_ListObjIndex (interp, attr, i+1, &attvalue);
        if (Tcl_ListObjLength (interp, attname, &len) == TCL_OK) {
            if (len == 2) {
                Tcl_ListObjIndex (interp, attname, 1, &attns);
                Tcl_ListObjIndex (interp, attname, 0, &attname);
            }
        }
        h = Tcl_FindHashEntry (&sdata->attrNames, Tcl_GetString (attname));
        if (!h) goto unknown;
        name = Tcl_GetHashKey (&sdata->attrNames, h);
        if (attns) {
            h = Tcl_FindHashEntry (&sdata->namespace, Tcl_GetString (attns));
................................................................................
                                Tcl_GetString (attvalue), &req);
        reqAttr += req;
    unknown:
        if (!found) {
            if (!recover (interp, sdata, S("UNKNOWN_ATTRIBUTE"), 0, 0)) {
                if (ns) {
                    SetResult ("Unknown attribute \"");
                    Tcl_AppendResult (interp, ns, ":", name,
                                      "\"");
                } else {
                    SetResult3 ("Unknown attribute \"", name, "\"");
                }
                sdata->validationState = VALIDATION_ERROR;
                return TCL_ERROR;
            }
................................................................................
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]
    )
{
    int            methodIndex, keywordIndex, hnew, patternIndex;
    int            result = TCL_OK, forwardDef = 0, i = 0, j;
    int            savedDefineToplevel, type, len;
    unsigned int   savedNumPatternList;
    SchemaData    *savedsdata = NULL, *sdata = (SchemaData *) clientData;
    Tcl_HashTable *hashTable;
    Tcl_HashEntry *h, *h1;
    SchemaCP      *pattern, *current = NULL;
    void          *namespacePtr, *savedNamespacePtr;
    char          *xmlstr, *errMsg;
    domDocument   *doc;
    domNode       *node;
    Tcl_Obj       *attData;

    static const char *schemaInstanceMethods[] = {
        "defelement",  "defpattern",  "start", "event",     "delete",
        "nrForwardDefinitions",       "reset", "define",    "validate",
        "domvalidate", "deftext",     "info",  "reportcmd", "prefixns",
        NULL
    };
................................................................................
        case k_elementstart:
            if (objc < 4 && objc > 6) {
                Tcl_WrongNumArgs (interp, 3, objv, "<elementname>"
                    "?<attInfo>? ?<namespace>?");
                return TCL_ERROR;
            }
            namespacePtr = NULL;
            len = 0;
            attData = NULL;
            if (objc == 6) {
                namespacePtr = getNamespacePtr (sdata,
                                                Tcl_GetString (objv[5]));
            }
            if (objc >= 5) {
                if (Tcl_ListObjLength (interp, objv[4], &len) != TCL_OK) {
                    if (objc == 6) {
                        SetResult ("Invalid attribute information");
                        return TCL_ERROR;
                    } else {
                        namespacePtr =
                            getNamespacePtr (sdata, Tcl_GetString (objv[4]));
                        len = 0;
                    }
                } else {
                    if (len == 1) {
                        namespacePtr =
                            getNamespacePtr (sdata, Tcl_GetString (objv[4]));

                        len = 0;
                    } else if (len % 2 != 0) {
                        SetResult ("Invalid attribute information");
                        return TCL_ERROR;
                    } else {
                        attData = objv[4];
                    }
                }
            }
            result = probeElement (interp, sdata, Tcl_GetString (objv[3]),
                                   namespacePtr);
            if (result == TCL_OK) {
                result = probeEventAttribute (interp, sdata, attData, len);


            }
            break;
            
        case k_elementend:
            if (objc != 3) {
                Tcl_WrongNumArgs (interp, 3, objv, "No arguments expected.");
                return TCL_ERROR;
................................................................................
    checkNrArgs (1,1,"No arguments expected");
    ADD_CONSTRAINT (sdata, sc)
    sc->constraint = nmtokensImpl;
    return TCL_OK;
}

static int
numberImplXsd (
    Tcl_Interp *interp,
    void *constraintData,
    char *text
    )
{
    char *c = text;
    if (!*c) return 0;
    if (*c == '-' || *c == '+') c++;
    while (isdigit(*c)) {
        c++;
    }
    if (*c == '.') c++;
    while (isdigit(*c)) {
        c++;
    }
    if (*c) return 0;
    return 1;
}

static int
numberImplTcl (
    Tcl_Interp *interp,
    void *constraintData,
    char *text
    )
{
    double d;

................................................................................
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]
    )
{
    SchemaData *sdata = GETASI;
    SchemaConstraint *sc;
    int type;

    static const char *types[] = {
        "xsd", "tcl", NULL
    };
    enum typeSyms {
        t_xsd, t_tcl
    };

    CHECK_TI
    CHECK_TOPLEVEL
    checkNrArgs (1,2,"?xsd|tcl?");
    if (objc == 1) {
        type = t_xsd;
    } else {
        if (Tcl_GetIndexFromObj (interp, objv[1], types, "type", 0, &type)
            != TCL_OK) {
            return TCL_ERROR;
        }
    }
    ADD_CONSTRAINT (sdata, sc)
    switch ((enum typeSyms) type) {
    case t_xsd:
        sc->constraint = numberImplXsd;
        break;
    case t_tcl:
        sc->constraint = numberImplTcl;
        break;
    }
    return TCL_OK;
}

static int
booleanImplXsd (
    Tcl_Interp *interp,
    void *constraintData,

Changes to tests/schema.test.

927
928
929
930
931
932
933



























934
935
936
937
938
939
940
941
942
943













944
945
946
947
948
949
950
....
3393
3394
3395
3396
3397
3398
3399
3400




























3401
3402
3403
3404
3405
3406
3407
3408
3409
3410

3411
3412



3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
    }
    s delete
    set result
} {0 {error "This method is not allowed in nested evaluation" at line 1 character 6} 0 {error "This method is not allowed in nested evaluation" at line 1 character 15} 0 {error "This method is not allowed in nested evaluation" at line 1 character 13}}

test schema-4.6 {event start with namespace} {
    tdom::schema s



























    s defelement doc http://tdom.org/test {
        element a 1 {
            attribute att1
        }
    }
    s event start doc http://tdom.org/test
    s event start a http://tdom.org/test
    s event end
    s event end
    s delete













} {}

test schema-5.1 {dom parse -validateCmd} {
    set result [catch {
        [dom parse -validateCmd tdom::schema <doc/>]
    }]
} 1
................................................................................
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 1 0 1 1}

test schema-14.10 {text: number} {




























    tdom::schema s
    s define {
        defelement doc {
            text number
        }
    }
    set result [list]
    foreach xml {
        <doc/>
        <doc></doc>

        <doc>foo</doc>
        <doc>1</doc>



        <doc>12</doc>
        <doc>1234-12-31</doc>
        <doc>-14.23</doc>
        <doc>.777</doc>
        <doc>-1.2e5</doc>
        {<doc> -1.2e5 </doc>}
        {<doc> -1.2e5 e</doc>}
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 0 1 1 0 1 1 1 1 0}

test schema-14.11 {text: maxLength} {
    tdom::schema s
    s define {
        defelement doc {
            text {
                maxLength 6







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






|



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







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>


>
>
>












|







927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
....
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
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
    }
    s delete
    set result
} {0 {error "This method is not allowed in nested evaluation" at line 1 character 6} 0 {error "This method is not allowed in nested evaluation" at line 1 character 15} 0 {error "This method is not allowed in nested evaluation" at line 1 character 13}}

test schema-4.6 {event start with namespace} {
    tdom::schema s
    s defelement doc http://tdom.org/test {
        element a ! text
    }
    s event start doc http://tdom.org/test
    s event start a http://tdom.org/test
    s event text "some text"
    s event end
    s event end
    s delete
} {}

test schema-4.7 {event start with namespace} {
    tdom::schema s
    s defelement doc http://tdom.org/test {
        element a 1 {
            attribute att1
        }
    }
    s event start doc http://tdom.org/test
    set result [catch {s event start a http://tdom.org/test} errMsg]
    lappend result $errMsg
    s delete
    set result
} {1 {Missing mandatory attribute(s)}}

test schema-4.8 {event start with namespace} {
    tdom::schema s
    s defelement doc http://tdom.org/test {
        element a 1 {
            attribute att1
        }
    }
    s event start doc http://tdom.org/test
    s event start a {att1 "some data"} http://tdom.org/test
    s event end
    s event end
    s delete
} {}

test schema-4.9 {event start with namespace w/ namespaced attribute} {
    tdom::schema s
    s defelement doc http://tdom.org/test {
        element a 1 {
            nsattribute att1 http://tdom.org/test
        }
    }
    s event start doc http://tdom.org/test
    s event start a {{att1 http://tdom.org/test} "some data"} http://tdom.org/test
    s event end
    s event end
} {}

test schema-5.1 {dom parse -validateCmd} {
    set result [catch {
        [dom parse -validateCmd tdom::schema <doc/>]
    }]
} 1
................................................................................
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 0 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 1 0 1 1}

test schema-14.10 {text: number tcl} {
    tdom::schema s
    s define {
        defelement doc {
            text {number tcl}
        }
    }
    set result [list]
    foreach xml {
        <doc/>
        <doc></doc>
        {<doc> </doc>}
        <doc>foo</doc>
        <doc>1</doc>
        <doc>12</doc>
        <doc>1234-12-31</doc>
        <doc>-14.23</doc>
        <doc>.777</doc>
        <doc>-1.2e5</doc>
        {<doc> -1.2e5 </doc>}
        {<doc> -1.2e5 e</doc>}
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 0 0 1 1 0 1 1 1 1 0}

test schema-14.10a {text: number xsd} {
    tdom::schema s
    s define {
        defelement doc {
            text number
        }
    }
    set result [list]
    foreach xml {
        <doc/>
        <doc></doc>
        {<doc> </doc>}
        <doc>foo</doc>
        <doc>1</doc>
        {<doc> 1</doc>}
        {<doc>1 </doc>}
        {<doc> 1 </doc>}
        <doc>12</doc>
        <doc>1234-12-31</doc>
        <doc>-14.23</doc>
        <doc>.777</doc>
        <doc>-1.2e5</doc>
        {<doc> -1.2e5 </doc>}
        {<doc> -1.2e5 e</doc>}
    } {
        lappend result [s validate $xml]
    }
    s delete
    set result
} {0 0 0 0 1 0 0 0 1 0 1 1 0 0 0}

test schema-14.11 {text: maxLength} {
    tdom::schema s
    s define {
        defelement doc {
            text {
                maxLength 6