tDOM

Check-in [2596c19c35]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

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: 2596c19c35889c0d16dd9da7dc42371ca9217b991dad7bc6f3b6d59b1cde71d7
User & Date: rolf 2019-05-10 16:05:12
Context
2019-05-11
01:41
Save work. check-in: 3ce85f17a5 user: rolf tags: localkey
2019-05-10
16:05
Save work. check-in: 2596c19c35 user: rolf tags: localkey
13:41
Merge from schema. check-in: 4bf39f2571 user: rolf tags: localkey
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to generic/schema.c.

   368    368           se = se->down;
   369    369       }
   370    370       fprintf (stderr, "++++ Stack bottom\n");
   371    371   }
   372    372   )
   373    373   
   374    374   /* DBG end */
          375  +
          376  +static void freeKeyConstraints (
          377  +    KeyConstraint *kc
          378  +    )
          379  +{
          380  +    KeyConstraint *knext;
          381  +    KeyStep *step, *snext;
          382  +
          383  +    while (kc) {
          384  +        knext = kc->next;
          385  +        if (kc->name) FREE (kc->name);
          386  +        step = kc->selectSteps;
          387  +        while (step) {
          388  +            snext = step->next;
          389  +            FREE (step);
          390  +            step = snext;
          391  +        }
          392  +        step = kc->fieldSteps;
          393  +        while (step) {
          394  +            snext = step->next;
          395  +            FREE (step);
          396  +            step = snext;
          397  +        }
          398  +        FREE (kc);
          399  +        kc = knext;
          400  +    }
          401  +}
   375    402   
   376    403   static void freeSchemaCP (
   377    404       SchemaCP *pattern
   378    405       )
   379    406   {
   380    407       int i;
   381    408       SchemaConstraint *sc;
................................................................................
   404    431           FREE (pattern->quants);
   405    432           if (pattern->attrs) {
   406    433               for (i = 0; i < pattern->numAttr; i++) {
   407    434                   FREE (pattern->attrs[i]);
   408    435               }
   409    436               FREE (pattern->attrs);
   410    437           }
          438  +        freeKeyConstraints (pattern->localkeys);
   411    439           break;
   412    440       }
   413    441       FREE (pattern);
   414    442   }
   415    443   
   416    444   static SchemaData*
   417    445   initSchemaData (
................................................................................
  3340   3368       }
  3341   3369       pattern->nc = objc;
  3342   3370       addToContent (sdata, pattern, SCHEMA_CQUANT_ONE, 0, 0);
  3343   3371       return TCL_OK;
  3344   3372   }
  3345   3373   
  3346   3374   extern void printAst (int depth, ast t);
         3375  +
  3347   3376   static int
  3348   3377   processSchemaXPath (
  3349   3378       Tcl_Interp *interp,
         3379  +    KeyConstraint *kc,
         3380  +    KeyStep *lastStep,
         3381  +    StepType nextType,
  3350   3382       ast t,
  3351   3383       int field,
  3352   3384       int toplevel
  3353   3385       )
  3354   3386   {
  3355   3387       ast child;
         3388  +    KeyStep *step;
  3356   3389       
  3357   3390       printAst (0, t);
  3358   3391       while (t) {
  3359   3392           switch (t->type) {
  3360   3393           case GetContextNode:
  3361   3394               if (!toplevel) {
  3362   3395                   SetResult ("Not a reduced XPath expression.");
................................................................................
  3366   3399               continue;
  3367   3400           case CombineSets:
  3368   3401               if (!toplevel) {
  3369   3402                   SetResult ("Not a reduced XPath expression.");
  3370   3403                   return TCL_ERROR;
  3371   3404               }
  3372   3405               for (child = t->child; child != NULL; child = child->next) {
  3373         -                if (processSchemaXPath (interp, child, field, 0) != TCL_OK) {
         3406  +                if (processSchemaXPath (interp, kc, NULL, SCHEMA_STEP_NONE,
         3407  +                                        child, field, 0)
         3408  +                    != TCL_OK) {
  3374   3409                       return TCL_ERROR;
  3375   3410                   }
  3376   3411               }
  3377   3412               break;
  3378   3413           case AxisDescendant:
  3379   3414               if (!toplevel) {
  3380   3415                   SetResult ("Not a reduced XPath expression.");
  3381   3416                   return TCL_ERROR;
  3382   3417               }
         3418  +            nextType = SCHEMA_STEP_DESCENDANT_ELEMENT;
         3419  +            
  3383   3420               break;
  3384         -        case IsElement:
  3385         -        case IsFQElement:
  3386         -        case IsNSElement:
  3387         -        case AxisChild:
  3388         -            break;
  3389         -        case AxisAttribute:
  3390   3421           case IsNSAttr:
  3391   3422           case IsAttr:
  3392   3423               if (!field) {
  3393   3424                   SetResult ("Attribute selection is only possible in reduced "
  3394   3425                              "XPath expression for field selectors.");
  3395   3426                   return TCL_ERROR;
  3396   3427               }
  3397         -            if (t->type == AxisAttribute) {
  3398         -                break;
         3428  +            /* Fall through */
         3429  +        case IsElement:
         3430  +        case IsFQElement:
         3431  +        case IsNSElement:
         3432  +            step = TMALLOC (KeyStep);
         3433  +            memset (step, 0, sizeof (KeyStep));
         3434  +            step->type = nextType;
         3435  +            if (lastStep) {
         3436  +                lastStep->next = step;
         3437  +            } else {
         3438  +                if (field) kc->fieldSteps = step;
         3439  +                else kc->selectSteps = step;
  3399   3440               }
         3441  +            lastStep = step;
         3442  +            break;
         3443  +        case AxisChild:
         3444  +            nextType = SCHEMA_STEP_ELEMENT;
         3445  +            break;
         3446  +        case AxisAttribute:
         3447  +            nextType = SCHEMA_STEP_ATTRIBUTE;
  3400   3448               break;
  3401   3449           default:
  3402   3450               SetResult ("Not a reduced XPath expression.");
  3403   3451               return TCL_ERROR;
  3404   3452           }
  3405   3453           if (t->child) {
  3406         -            if (processSchemaXPath (interp, t->child, field, 0) != TCL_OK) {
         3454  +            if (processSchemaXPath (interp, kc, lastStep, nextType,
         3455  +                                    t->child, field, 0)
         3456  +                != TCL_OK) {
  3407   3457                   return TCL_ERROR;
  3408   3458               }
  3409   3459           }
  3410   3460           toplevel = 0;
  3411   3461           t = t->next;
  3412   3462       }
  3413   3463       return TCL_OK;
................................................................................
  3420   3470       int objc,
  3421   3471       Tcl_Obj *const objv[]
  3422   3472       )
  3423   3473   {
  3424   3474       SchemaData *sdata = GETASI;
  3425   3475       ast s, f;
  3426   3476       char *errMsg = NULL;
         3477  +    KeyConstraint *kc, *kc1;
  3427   3478   
  3428   3479       CHECK_SI
  3429   3480       CHECK_TOPLEVEL
  3430   3481       checkNrArgs (3,3,"Expected: <selector> <fieldlist>");
  3431   3482   
  3432   3483       if (xpathParse (Tcl_GetString (objv[1]), NULL, XPATH_EXPR,
  3433   3484                       sdata->prefixns, NULL, &s, &errMsg) < 0) {
  3434   3485           SetResult3 ("Error in selector xpath: '", errMsg, "");
  3435   3486           FREE (errMsg);
  3436   3487           return TCL_ERROR;
  3437   3488       }
  3438         -    if (processSchemaXPath (interp, s, 0, 1) != TCL_OK) {
         3489  +    if (xpathParse (Tcl_GetString (objv[2]), NULL, XPATH_EXPR,
         3490  +                    sdata->prefixns, NULL, &f, &errMsg) < 0) {
         3491  +        SetResult3 ("Error in field xpath: '", errMsg, "");
         3492  +        FREE (errMsg);
         3493  +        return TCL_ERROR;
         3494  +    }
         3495  +    kc = TMALLOC (KeyConstraint);
         3496  +    memset (kc, 0, sizeof (KeyConstraint));
         3497  +    if (processSchemaXPath (interp, kc, NULL, SCHEMA_STEP_NONE, s, 0, 1)
         3498  +        != TCL_OK) {
         3499  +        xpathFreeAst (s);
         3500  +        xpathFreeAst (f);
         3501  +        freeKeyConstraints (kc);
         3502  +        return TCL_ERROR;
         3503  +    }
         3504  +    if (processSchemaXPath (interp, kc, NULL, SCHEMA_STEP_NONE, f, 1, 1)
         3505  +        != TCL_OK) {
  3439   3506           xpathFreeAst (s);
         3507  +        xpathFreeAst (f);
         3508  +        freeKeyConstraints (kc);
  3440   3509           return TCL_ERROR;
  3441   3510       }
  3442         -    
  3443   3511       xpathFreeAst (s);
         3512  +    xpathFreeAst (f);
         3513  +    if (sdata->cp->localkeys) {
         3514  +        kc1 = sdata->cp->localkeys;
         3515  +        while (kc1->next) kc1 = kc1->next;
         3516  +        kc1->next = kc;
         3517  +    } else {
         3518  +        sdata->cp->localkeys = kc;
         3519  +    }
  3444   3520       return TCL_OK;
  3445   3521   }
  3446   3522   
  3447   3523   static int
  3448   3524   integerImpl (
  3449   3525       Tcl_Interp *interp,
  3450   3526       void *constraintData,

Changes to generic/schema.h.

    36     36   
    37     37   typedef enum {
    38     38     SCHEMA_CQUANT_ONE,
    39     39     SCHEMA_CQUANT_OPT,
    40     40     SCHEMA_CQUANT_REP,
    41     41     SCHEMA_CQUANT_PLUS,
    42     42     SCHEMA_CQUANT_NM,
    43         -  SCHEMA_CQUANT_ERROR,
           43  +  SCHEMA_CQUANT_ERROR
    44     44   } SchemaQuant;
    45     45   
    46     46   typedef int (*SchemaConstraintFunc) (Tcl_Interp *interp,
    47     47                                        void *constraintData, char *text);
    48     48   typedef void (*SchemaConstraintFreeFunc) (void *constraintData);
    49     49   
    50     50   typedef struct 
................................................................................
    68     68   #define FORWARD_PATTERN_DEF     1
    69     69   #define PLACEHOLDER_PATTERN_DEF 2
    70     70   #define AMBIGUOUS_PATTERN       4
    71     71   #define LOCAL_DEFINED_ELEMENT   8
    72     72   #define CONSTRAINT_TEXT_CHILD  16
    73     73   #define MIXED_CONTENT          32 
    74     74   
    75         -typedef struct keyConstraint {
    76         -    char           *name;
    77         -    char           *ns;
    78         -    struct keyConstraint *child;
    79         -    struct keyConstraint *next;
    80         -} keyConstraint;
           75  +
           76  +typedef enum {
           77  +  SCHEMA_KEY_UNIQUE,
           78  +  SCHEMA_KEY_KEY,
           79  +  SCHEMA_KEY_KEYREF
           80  +} KeyType;
           81  +
           82  +typedef enum {
           83  +  SCHEMA_STEP_NONE,
           84  +  SCHEMA_STEP_ELEMENT,
           85  +  SCHEMA_STEP_DESCENDANT_ELEMENT,
           86  +  SCHEMA_STEP_ATTRIBUTE,
           87  +} StepType;
           88  +
           89  +typedef struct KeyStep 
           90  +{
           91  +    StepType type;
           92  +    char    *name;
           93  +    char    *ns;
           94  +    struct KeyStep *next;
           95  +} KeyStep;
           96  +
           97  +typedef struct KeyConstraint {
           98  +    char    *name;
           99  +    KeyType  type;
          100  +    KeyStep *selectSteps;
          101  +    KeyStep *fieldSteps;
          102  +    struct KeyConstraint *next;
          103  +} KeyConstraint;
    81    104   
    82    105   typedef struct SchemaCP
    83    106   {
    84    107       Schema_CP_Type    type;
    85    108       char             *namespace;
    86    109       char             *name;
    87    110       struct SchemaCP  *next;
................................................................................
    88    111       SchemaFlags       flags;
    89    112       struct SchemaCP **content;
    90    113       SchemaQuant      *quants;
    91    114       unsigned int      nc;
    92    115       SchemaAttr      **attrs;
    93    116       unsigned int      numAttr;
    94    117       unsigned int      numReqAttr;
    95         -    keyConstraint    *localkeys;
          118  +    KeyConstraint    *localkeys;
          119  +    int               nrKeys;
    96    120   } SchemaCP;
    97    121   
    98    122   typedef struct SchemaValidationStack
    99    123   {
   100    124       SchemaCP *pattern;
   101    125       struct SchemaValidationStack *next;
   102    126       struct SchemaValidationStack *down;