tDOM

Check-in [4592100a23]
Login
Bounty program for improvements to Tcl and certain Tcl packages.

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 | localkey
Files: files | file ages | folders
SHA3-256: 4592100a2369fcc6522bc5420849281a24c5498a6efce5ecc3f0f10b23f10407
User & Date: rolf 2019-05-18 00:41:39
Context
2019-05-21
22:37
Merged from schema. check-in: 72ce7820c1 user: rolf tags: localkey
2019-05-18
00:41
Save work. check-in: 4592100a23 user: rolf tags: localkey
2019-05-17
00:02
Now start to actually use the local key constraint info. check-in: 120c8294a0 user: rolf tags: localkey
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/schema.c.

255
256
257
258
259
260
261








262
263
264
265
266
267
268
...
513
514
515
516
517
518
519

520
521
522
523
524
525
526
...
581
582
583
584
585
586
587
588
589
590






591
592
593
594
595
596
597
...
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
...
759
760
761
762
763
764
765
766
767











768








769
770
771

772
773
774

775
776
777
778
779



780
781
782
783
784
785
786
...
800
801
802
803
804
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
    if (cp->namespace) {                                \
        Tcl_SetStringObj (rObj, cp->namespace, -1);     \
        Tcl_AppendToObj (rObj, ":", 1);                 \
    }                                                   \
    Tcl_AppendToObj (rObj, cp->name, -1);

#define S(str)  str, sizeof (str) -1









static SchemaCP*
initSchemaCP (
    Schema_CP_Type type,
    void *namespace,
    char *name
    )
................................................................................
    SchemaData *sdata = (SchemaData *) clientData;
    unsigned int i;
    SchemaValidationStack *down;
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    SchemaDocKey *dk;
    KeyState *ks, *nextks;


    /* Protect the clientData to be freed inside (even nested)
     * Tcl_Eval*() calls to avoid invalid mem access and postpone the
     * cleanup until the Tcl_Eval*() calls are finished (done in
     * schemaInstanceCmd(). */
    if (sdata->currentEvals) {
        sdata->cleanupAfterEval = 1;
................................................................................
        Tcl_DeleteHashTable (&dk->ids);
        FREE (dk);
    }
    Tcl_DeleteHashTable (&sdata->idTables);
    ks = sdata->keyStatePool;
    while (ks) {
        nextks = ks->next;
        FREE (ks->values);
        FREE (ks);
        ks = nextks;






    }
    FREE (sdata);
}

static void
cleanupLastPattern (
    SchemaData *sdata,
................................................................................
pushToStack (
    SchemaData *sdata,
    SchemaCP *pattern
    )
{
    SchemaValidationStack *stackElm, *se;
    KeyConstraint *kc;
    KeyState *ks;

    
    DBG(fprintf(stderr, "push to Stack:\n");serializeCP(pattern));
    if (sdata->stackPool) {
        stackElm = sdata->stackPool;
        sdata->stackPool = stackElm->down;
    } else {
        stackElm = TMALLOC (SchemaValidationStack);
................................................................................
    se = sdata->stack;
    stackElm->down = se;
    stackElm->pattern = pattern;
    if (pattern->type == SCHEMA_CTYPE_INTERLEAVE) {
        stackElm->interleaveState = MALLOC (sizeof (int) * pattern->nc);
        memset (stackElm->interleaveState, 0, sizeof (int) * pattern->nc);
    }
    if (pattern->type == SCHEMA_CTYPE_NAME) {
        /* Handle local key contraint matches */




















        /* And open new local key contraints, if necessary. */
        kc = pattern->localkeys;
        while (kc) {

            if (sdata->keyStatePool) {
                ks = sdata->keyStatePool;
                sdata->keyStatePool = ks->next;

            } else {
                ks = TMALLOC (KeyState);
                ks->values = TMALLOC (Tcl_HashTable);
            }
            Tcl_InitHashTable (ks->values, TCL_STRING_KEYS);



            ks->selector = kc->selector;
            ks->fields = kc->fields;
            ks->next = stackElm->keyState;
            stackElm->keyState = ks;
            kc = kc->next;
        }
    }
................................................................................
        sdata->stack->interleaveState = NULL;
    }
    if (sdata->stack->pattern->type == SCHEMA_CTYPE_NAME) {
        /* Check and cleanup local key contraints */
        ks = sdata->stack->keyState;
        while (ks) {
            nextks = ks->next;
            Tcl_DeleteHashTable (ks->values);
            if (sdata->keyStatePool) {
                ks->next = sdata->keyStatePool;
            } else {
                ks->next = NULL;
            }

            sdata->keyStatePool = ks;
            ks = nextks;
        }
    }
    se = sdata->stack->down;
    sdata->stack->down = sdata->stackPool;
    sdata->stackPool = sdata->stack;






>
>
>
>
>
>
>
>







 







>







 







<


>
>
>
>
>
>







 







|
>







 







|

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



>
|
|
<
>

|
<

|
>
>
>







 







|
|
|
|
<

>







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
...
590
591
592
593
594
595
596

597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
...
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
...
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808

809
810
811

812
813
814
815
816
817
818
819
820
821
822
823
...
837
838
839
840
841
842
843
844
845
846
847

848
849
850
851
852
853
854
855
856
    if (cp->namespace) {                                \
        Tcl_SetStringObj (rObj, cp->namespace, -1);     \
        Tcl_AppendToObj (rObj, ":", 1);                 \
    }                                                   \
    Tcl_AppendToObj (rObj, cp->name, -1);

#define S(str)  str, sizeof (str) -1

#define getKeyState(ks) \
    if (sdata->keyStatePool) { \
        ks = sdata->keyStatePool; \
        sdata->keyStatePool = ks->next; \
    } else { \
        ks = TMALLOC (KeyState); \
    }

static SchemaCP*
initSchemaCP (
    Schema_CP_Type type,
    void *namespace,
    char *name
    )
................................................................................
    SchemaData *sdata = (SchemaData *) clientData;
    unsigned int i;
    SchemaValidationStack *down;
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    SchemaDocKey *dk;
    KeyState *ks, *nextks;
    KeyTable *kt, *nextkt;

    /* Protect the clientData to be freed inside (even nested)
     * Tcl_Eval*() calls to avoid invalid mem access and postpone the
     * cleanup until the Tcl_Eval*() calls are finished (done in
     * schemaInstanceCmd(). */
    if (sdata->currentEvals) {
        sdata->cleanupAfterEval = 1;
................................................................................
        Tcl_DeleteHashTable (&dk->ids);
        FREE (dk);
    }
    Tcl_DeleteHashTable (&sdata->idTables);
    ks = sdata->keyStatePool;
    while (ks) {
        nextks = ks->next;

        FREE (ks);
        ks = nextks;
    }
    kt = sdata->keyTablePool;
    while (kt) {
        nextkt = kt->next;
        FREE (kt);
        kt = nextkt;
    }
    FREE (sdata);
}

static void
cleanupLastPattern (
    SchemaData *sdata,
................................................................................
pushToStack (
    SchemaData *sdata,
    SchemaCP *pattern
    )
{
    SchemaValidationStack *stackElm, *se;
    KeyConstraint *kc;
    KeyState *ks, *newks;
    KeyTable *kt;
    
    DBG(fprintf(stderr, "push to Stack:\n");serializeCP(pattern));
    if (sdata->stackPool) {
        stackElm = sdata->stackPool;
        sdata->stackPool = stackElm->down;
    } else {
        stackElm = TMALLOC (SchemaValidationStack);
................................................................................
    se = sdata->stack;
    stackElm->down = se;
    stackElm->pattern = pattern;
    if (pattern->type == SCHEMA_CTYPE_INTERLEAVE) {
        stackElm->interleaveState = MALLOC (sizeof (int) * pattern->nc);
        memset (stackElm->interleaveState, 0, sizeof (int) * pattern->nc);
    }
    if (pattern->type == SCHEMA_CTYPE_NAME && se) {
        /* Handle local key contraint matches */
        ks = se->keyState;
        while (ks) {
            if (ks->selector->name != pattern->name
                || ks->selector->ns == pattern->namespace) continue;
            if (ks->selector->child) {
                getKeyState(newks);
                newks->keyTable = ks->keyTable;
                newks->ownTable = 0;
                newks->selector = ks->selector->child;
                newks->fields = ks->fields;
                if (ks->type == SCHEMA_STEP_DESCENDANT_ELEMENT) {
                    
                }
                newks->next = stackElm->keyState;
                stackElm->keyState = newks;
            } else {
                /* Selector has matched, grab the fields */
            }
        }
        
        /* And open new local key contraints, if necessary. */
        kc = pattern->localkeys;
        while (kc) {
            getKeyState (ks);
            if (sdata->keyTablePool) {
                kt = sdata->keyTablePool;

                sdata->keyTablePool = kt->next;
            } else {
                kt = TMALLOC (KeyTable);

            }
            Tcl_InitHashTable (&kt->values, TCL_STRING_KEYS);
            ks->keyTable = kt;
            ks->ownTable = 1;
            ks->type = kc->type;
            ks->selector = kc->selector;
            ks->fields = kc->fields;
            ks->next = stackElm->keyState;
            stackElm->keyState = ks;
            kc = kc->next;
        }
    }
................................................................................
        sdata->stack->interleaveState = NULL;
    }
    if (sdata->stack->pattern->type == SCHEMA_CTYPE_NAME) {
        /* Check and cleanup local key contraints */
        ks = sdata->stack->keyState;
        while (ks) {
            nextks = ks->next;
            if (ks->ownTable) {
                ks->keyTable->next = sdata->keyTablePool;
                sdata->keyTablePool = ks->keyTable;
                Tcl_DeleteHashTable (&ks->keyTable->values);

            }
            ks->next = sdata->keyStatePool;
            sdata->keyStatePool = ks;
            ks = nextks;
        }
    }
    se = sdata->stack->down;
    sdata->stack->down = sdata->stackPool;
    sdata->stackPool = sdata->stack;

Changes to generic/schema.h.

99
100
101
102
103
104
105





106
107
108
109

110
111
112


113
114
115
116
117
118
119
...
188
189
190
191
192
193
194

195
196
197
198
199
200
201
    char     *name;
    KeyType   type;
    KeyStep  *selector;
    KeyStep **fields;
    int       nrFields;
    struct KeyConstraint *next;
} KeyConstraint;






typedef struct KeyState 
{
    struct KeyState *next;

    KeyStep         *selector;
    KeyStep        **fields;
    Tcl_HashTable   *values;


} KeyState;

typedef struct SchemaCP
{
    Schema_CP_Type    type;
    char             *namespace;
    char             *name;
................................................................................
    SchemaAttr **currentAttrs;
    unsigned int numAttr;
    unsigned int numReqAttr;
    unsigned int attrSize;
    SchemaValidationStack *stack;
    SchemaValidationStack *stackPool;
    KeyState *keyStatePool;

    ValidationState validationState;
    unsigned int skipDeep;
    Tcl_DString *cdata;
    Tcl_HashTable ids;
    int unknownIDrefs;
    Tcl_HashTable idTables;
} SchemaData;






>
>
>
>
>




>


<
>
>







 







>







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    char     *name;
    KeyType   type;
    KeyStep  *selector;
    KeyStep **fields;
    int       nrFields;
    struct KeyConstraint *next;
} KeyConstraint;

typedef struct KeyTable {
    struct KeyTable *next;
    Tcl_HashTable    values;
} KeyTable;

typedef struct KeyState 
{
    struct KeyState *next;
    StepType         type;
    KeyStep         *selector;
    KeyStep        **fields;

    int              ownTable;
    KeyTable        *keyTable;
} KeyState;

typedef struct SchemaCP
{
    Schema_CP_Type    type;
    char             *namespace;
    char             *name;
................................................................................
    SchemaAttr **currentAttrs;
    unsigned int numAttr;
    unsigned int numReqAttr;
    unsigned int attrSize;
    SchemaValidationStack *stack;
    SchemaValidationStack *stackPool;
    KeyState *keyStatePool;
    KeyTable *keyTablePool;
    ValidationState validationState;
    unsigned int skipDeep;
    Tcl_DString *cdata;
    Tcl_HashTable ids;
    int unknownIDrefs;
    Tcl_HashTable idTables;
} SchemaData;