tDOM

Check-in [4592100a23]
Login

Check-in [4592100a23]

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

Overview
Comment:Save work.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | localkey
Files: files | file ages | folders
SHA3-256: 4592100a2369fcc6522bc5420849281a24c5498a6efce5ecc3f0f10b23f10407
User & Date: rolf 2019-05-18 00:41:39.465
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
Unified Diff Ignore Whitespace Patch
Changes to generic/schema.c.
255
256
257
258
259
260
261








262
263
264
265
266
267
268
    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
    )







>
>
>
>
>
>
>
>







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
    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
    )
513
514
515
516
517
518
519

520
521
522
523
524
525
526
    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;







>







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
    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;
581
582
583
584
585
586
587
588





589
590
591
592
593
594
595
596
597
        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,







|
>
>
>
>
>
|
|







590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
        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,
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
757
758
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
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);
    }
    memset (stackElm, 0, sizeof (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;
        }
    }







|
>
















|

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



>
|
|
|

|
<

|
>
>
>







756
757
758
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
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
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);
    }
    memset (stackElm, 0, sizeof (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;
        }
    }
800
801
802
803
804
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
        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;







|
|
|
<
|

>







837
838
839
840
841
842
843
844
845
846

847
848
849
850
851
852
853
854
855
856
        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
    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;







>
>
>
>
>




>


>
|







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
    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;
188
189
190
191
192
193
194

195
196
197
198
199
200
201
    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;







>







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    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;