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

Overview
Comment:Settled for a list of unique possible next content (which special entries for any and text) in unspecific order as result of the nextexpected subcommand of the info method.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip
Files: files | file ages | folders
SHA3-256: 35c7ad95de9bb94f968fe6a2251e27888d9160b16220f9471c2f0ce3ba755138
User & Date: rolf 2019-10-09 16:25:09
Context
2019-10-09
16:40
Added subcommand nextexpected to the info method of schema commands. check-in: c9fd675e9f user: rolf tags: schema
16:25
Settled for a list of unique possible next content (which special entries for any and text) in unspecific order as result of the nextexpected subcommand of the info method. Closed-Leaf check-in: 35c7ad95de user: rolf tags: wip
2019-10-08
06:22
Fixed content constrain command "any": respect prefix/ns mapping. More work on info nextexpected. check-in: 223307a111 user: rolf tags: wip
Changes

Changes to generic/schema.c.

  2770   2770       Tcl_ListObjAppendElement (interp, rObj, Tcl_NewStringObj (cp->name, -1));
  2771   2771       if (cp->namespace) {
  2772   2772           Tcl_ListObjAppendElement (interp, rObj,
  2773   2773                                     Tcl_NewStringObj (cp->namespace, -1));
  2774   2774       }
  2775   2775       return rObj;
  2776   2776   }
         2777  +
         2778  +/* cp must be of type SCHEMA_CTYPE_ANY for useful results */
         2779  +static Tcl_Obj*
         2780  +serializeAnyCP (
         2781  +    Tcl_Interp *interp,
         2782  +    SchemaCP *cp
         2783  +    )
         2784  +{
         2785  +    Tcl_Obj *rObj;
         2786  +
         2787  +    rObj = Tcl_NewObj();
         2788  +    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewStringObj ("<any>", 5));
         2789  +    if (cp->namespace) {
         2790  +        Tcl_ListObjAppendElement (interp, rObj,
         2791  +                                  Tcl_NewStringObj (cp->namespace, -1));
         2792  +    } else {
         2793  +        Tcl_ListObjAppendElement (interp, rObj, Tcl_NewObj());
         2794  +    }
         2795  +    return rObj;
         2796  +}
         2797  +
         2798  +/* The cp argument may be NULL. If it isn't NULL cp must be of type
         2799  + * SCHEMA_CTYPE_TEXT for useful results */
         2800  +static Tcl_Obj*
         2801  +serializeTextCP (
         2802  +    Tcl_Interp *interp,
         2803  +    SchemaCP *cp
         2804  +    )
         2805  +{
         2806  +    Tcl_Obj *rObj;
         2807  +
         2808  +    rObj = Tcl_NewObj();
         2809  +    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewStringObj ("#text", 5));
         2810  +    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewObj());
         2811  +    return rObj;
         2812  +}
  2777   2813   
  2778   2814   static void
  2779   2815   definedElements (
  2780   2816       SchemaData *sdata,
  2781   2817       Tcl_Interp *interp
  2782   2818       )
  2783   2819   {
................................................................................
  2807   2843       Tcl_HashTable *seenCPs,
  2808   2844       Tcl_Obj *rObj
  2809   2845       )
  2810   2846   {
  2811   2847       int ac, hm, i, hnew, mustMatch, mayskip, rc;
  2812   2848       SchemaCP *cp, *ic, *jc;
  2813   2849       SchemaValidationStack *se1;
  2814         -    Tcl_Obj *thisObj;
  2815   2850   
  2816   2851       getContext (cp, ac, hm);
  2817   2852       if (hm && maxOne(cp->quants[ac])) ac++;
  2818   2853       switch (cp->type) {
  2819   2854       case SCHEMA_CTYPE_INTERLEAVE:
  2820   2855           ac = 0;
  2821   2856           mustMatch = 0;
................................................................................
  2844   2879                       mayskip = getNextExpected (sdata, se1, interp, seenCPs,
  2845   2880                                                  rObj);
  2846   2881                       repoolStackElement (sdata, se1);
  2847   2882                   }
  2848   2883                   break;
  2849   2884   
  2850   2885               case SCHEMA_CTYPE_ANY:
  2851         -                if (ic->namespace) {
  2852         -                    thisObj = Tcl_NewObj();
  2853         -                    Tcl_AppendStringsToObj (thisObj, ic->namespace,
  2854         -                                            ":<any>", NULL);
  2855         -                        
  2856         -                    Tcl_ListObjAppendElement (interp, rObj, thisObj);
  2857         -                } else {
  2858         -                    Tcl_ListObjAppendElement (interp, rObj,
  2859         -                                              Tcl_NewStringObj ("<any>", 5));
  2860         -                }
         2886  +                Tcl_ListObjAppendElement (interp, rObj,
         2887  +                                          serializeAnyCP (interp, ic));
  2861   2888                   break;
  2862   2889   
  2863   2890               case SCHEMA_CTYPE_TEXT:
  2864   2891                   Tcl_ListObjAppendElement (interp, rObj,
  2865         -                                          Tcl_NewStringObj ("#text", 5));
         2892  +                                          serializeTextCP (interp, ic));
  2866   2893                   if (ic->nc == 0 || checkText (interp, ic, "")) {
  2867   2894                       mayskip = 1;
  2868   2895                   }
  2869   2896                   break;
  2870   2897                   
  2871   2898               case SCHEMA_CTYPE_CHOICE:
  2872   2899                   if (ic->flags & MIXED_CONTENT) {
  2873   2900                       Tcl_ListObjAppendElement (interp, rObj,
  2874         -                                              Tcl_NewStringObj ("#text", 5));
         2901  +                                              serializeTextCP (interp, NULL));
  2875   2902                   }
  2876   2903                   for (i = 0; i < ic->nc; i++) {
  2877   2904                       jc = ic->content[i];
  2878   2905                       switch (jc->type) {
  2879   2906                       case SCHEMA_CTYPE_NAME:
  2880   2907                           Tcl_ListObjAppendElement (
  2881   2908                               interp, rObj, serializeElementName (interp, jc)
................................................................................
  2889   2916                               mayskip = getNextExpected (sdata, se1, interp,
  2890   2917                                                          seenCPs, rObj);
  2891   2918                               repoolStackElement (sdata, se1);
  2892   2919                           }
  2893   2920                           break;
  2894   2921                       case SCHEMA_CTYPE_ANY:
  2895   2922                           Tcl_ListObjAppendElement (
  2896         -                            interp, rObj, Tcl_NewStringObj ("<any>", 5)
         2923  +                            interp, rObj, serializeAnyCP (interp, jc)
  2897   2924                               );
  2898   2925                           break;
  2899   2926                       case SCHEMA_CTYPE_TEXT:
  2900   2927                           Tcl_ListObjAppendElement (
  2901         -                            interp, rObj, Tcl_NewStringObj ("#text", 5)
         2928  +                            interp, rObj, serializeTextCP (interp, jc)
  2902   2929                               );
  2903   2930                           break;
  2904   2931                       case SCHEMA_CTYPE_CHOICE:
  2905   2932                           Tcl_Panic ("MIXED or CHOICE child of MIXED or CHOICE");
  2906   2933   
  2907   2934                       case SCHEMA_CTYPE_VIRTUAL:
  2908   2935                       case SCHEMA_CTYPE_KEYSPACE:
................................................................................
  2952   2979   schemaInstanceInfoCmd (
  2953   2980       SchemaData *sdata,
  2954   2981       Tcl_Interp *interp,
  2955   2982       int objc,
  2956   2983       Tcl_Obj *const objv[]
  2957   2984       )
  2958   2985   {
  2959         -    int methodIndex;
         2986  +    int methodIndex, len, i, hnew;
  2960   2987       Tcl_HashEntry *h;
  2961   2988       SchemaCP *cp;
  2962   2989       SchemaValidationStack *se;
  2963         -    Tcl_Obj *elmObj;
  2964   2990       void *ns;
  2965         -    Tcl_Obj *rObj;
  2966         -    Tcl_HashTable seenCPs;
         2991  +    Tcl_Obj *rObj, *r2Obj, *thisObj;
         2992  +    Tcl_HashTable localHash;
         2993  +    Tcl_HashSearch search;
  2967   2994       
  2968   2995       static const char *schemaInstanceInfoMethods[] = {
  2969   2996           "validationstate", "vstate", "definedElements", "stack", "toplevel",
  2970   2997           "pastexpected", "nextexpected", "definition", NULL
  2971   2998       };
  2972   2999       enum schemaInstanceInfoMethod {
  2973   3000           m_validationstate, m_vstate, m_definedElements, m_stack, m_toplevel,
................................................................................
  3035   3062                   Tcl_ResetResult (interp);
  3036   3063                   return TCL_OK;
  3037   3064               }
  3038   3065               se = sdata->stack;
  3039   3066               while (se->pattern->type != SCHEMA_CTYPE_NAME) {
  3040   3067                   se = se->down;
  3041   3068               }
  3042         -            elmObj = serializeElementName (interp, se->pattern);
  3043         -            Tcl_SetObjResult (interp, elmObj);
         3069  +            rObj = serializeElementName (interp, se->pattern);
         3070  +            Tcl_SetObjResult (interp, rObj);
  3044   3071               return TCL_OK;
  3045   3072               break;
  3046   3073           }
  3047   3074           
  3048   3075       case m_toplevel:
  3049   3076           if (objc != 2) {
  3050   3077               Tcl_WrongNumArgs (interp, 1, objv, "no argument expected");
................................................................................
  3075   3102                       Tcl_AppendElement (interp, sdata->startNamespace);
  3076   3103                   }
  3077   3104               } else {
  3078   3105                   definedElements (sdata, interp);
  3079   3106               }
  3080   3107           } else {
  3081   3108               rObj = Tcl_NewObj();
  3082         -            Tcl_InitHashTable (&seenCPs, TCL_ONE_WORD_KEYS);
  3083         -            getNextExpected (sdata, sdata->stack, interp, &seenCPs, rObj);
  3084         -            Tcl_DeleteHashTable (&seenCPs);
  3085         -            Tcl_SetObjResult (interp, rObj);
         3109  +            Tcl_InitHashTable (&localHash, TCL_ONE_WORD_KEYS);
         3110  +            getNextExpected (sdata, sdata->stack, interp, &localHash, rObj);
         3111  +            Tcl_DeleteHashTable (&localHash);
         3112  +            Tcl_ListObjLength (interp, rObj, &len);
         3113  +            if (len <= 1) {
         3114  +                Tcl_SetObjResult (interp, rObj);
         3115  +            } else {
         3116  +                Tcl_InitHashTable (&localHash, TCL_STRING_KEYS);
         3117  +                for (i = 0; i < len; i++) {
         3118  +                    Tcl_ListObjIndex (interp, rObj, i, &thisObj);
         3119  +                    h = Tcl_CreateHashEntry (
         3120  +                        &localHash, Tcl_GetString (thisObj), &hnew
         3121  +                        );
         3122  +                    if (hnew) {
         3123  +                        Tcl_SetHashValue (h, thisObj);
         3124  +                    }
         3125  +                }
         3126  +                r2Obj = Tcl_NewObj();
         3127  +                len = 0;
         3128  +                for (h = Tcl_FirstHashEntry (&localHash, &search);
         3129  +                     h != NULL;
         3130  +                     h = Tcl_NextHashEntry (&search)) {
         3131  +                    Tcl_ListObjAppendElement (interp, r2Obj,
         3132  +                                              Tcl_GetHashValue (h));
         3133  +                    len++;
         3134  +                }
         3135  +                Tcl_DeleteHashTable (&localHash);
         3136  +                Tcl_DecrRefCount (rObj);
         3137  +                Tcl_SetObjResult (interp, r2Obj);
         3138  +            }
  3086   3139           }
  3087   3140           return TCL_OK;
  3088   3141           
  3089   3142       case m_pastexpected:
  3090   3143           break;
  3091   3144           
  3092   3145       case m_definition:

Changes to tests/schema.test.

  4833   4833               element musthave
  4834   4834               element aftermust
  4835   4835           }
  4836   4836       }
  4837   4837       s event start doc
  4838   4838       set result [s info nextexpected]
  4839   4839       s delete
  4840         -    set result
  4841         -} {a c b toplevel musthave}
         4840  +    lsort $result
         4841  +} {a b c musthave toplevel}
  4842   4842   
  4843   4843   test schema-17.6 {info nextexpected} {
  4844   4844       tdom::schema s
  4845   4845       s prefixns {foo http://foo.bar}
  4846   4846       s define {
  4847   4847           defelement doc {
  4848   4848               choice ? {
................................................................................
  4856   4856               }
  4857   4857               element aftermust
  4858   4858           }
  4859   4859       }
  4860   4860       s event start doc
  4861   4861       set result [s info nextexpected]
  4862   4862       s delete
  4863         -    set result
  4864         -} {a c b toplevel {musthave http://foo.bar}}
         4863  +    lsort $result
         4864  +} {a b c {musthave http://foo.bar} toplevel}
  4865   4865   
  4866   4866   test schema-17.7 {info nextexpected} {
  4867   4867       tdom::schema s
  4868   4868       s prefixns {foo http://foo.bar}
  4869   4869       s define {
  4870   4870           defelement doc {
  4871   4871               mixed {
................................................................................
  4879   4879               }
  4880   4880               element aftermust
  4881   4881           }
  4882   4882       }
  4883   4883       s event start doc
  4884   4884       set result [s info nextexpected]
  4885   4885       s delete
  4886         -    set result
  4887         -} {{#text} a c b toplevel {musthave http://foo.bar}}
         4886  +    lsort $result
         4887  +} {a b c {musthave http://foo.bar} toplevel {{#text} {}}}
  4888   4888   
  4889   4889   test schema-17.8 {info nextexpected} {
  4890   4890       tdom::schema s
  4891   4891       s defelement doc {
  4892   4892           choice ? {
  4893   4893               element a
  4894   4894               element c
................................................................................
  4902   4902       s define {
  4903   4903           foreach elm {a b c} {
  4904   4904               defelement $elm {}
  4905   4905           }
  4906   4906       }
  4907   4907       lappend result {*}[lsort [s info nextexpected]]
  4908   4908       s event start doc
  4909         -    lappend result {*}[s info nextexpected]
         4909  +    lappend result {*}[lsort [s info nextexpected]]
  4910   4910       s event start c
  4911   4911       s event end
  4912         -    lappend result {*}[s info nextexpected]    
         4912  +    lappend result {*}[lsort [s info nextexpected]]
  4913   4913       s delete
  4914   4914       set result
  4915         -} {doc a b c doc a c b toplevel musthave toplevel musthave}
         4915  +} {doc a b c doc a b c musthave toplevel musthave toplevel}
  4916   4916   
  4917   4917   proc schema-17.9 {scmd} {
  4918   4918       global result
  4919         -    set result [$scmd info nextexpected]
         4919  +    lappend result {*}[lsort [$scmd info nextexpected]]
  4920   4920   }
  4921   4921                     
  4922   4922   test schema-17.9 {info nextexpected from scripted constrain} {
  4923   4923       tdom::schema s
  4924   4924       s define {
  4925   4925           defpattern some {
  4926   4926               element a ?
................................................................................
  4970   4970           }
  4971   4971       }
  4972   4972       set result [list]
  4973   4973       foreach def $defs {
  4974   4974           tdom::schema s
  4975   4975           s defelement doc $def
  4976   4976           s event start doc
  4977         -        lappend result {*}[s info nextexpected]
         4977  +        lappend result {*}[lsort [s info nextexpected]]
  4978   4978           s delete
  4979   4979       }
  4980   4980       set result
  4981   4981   } {a b c a b c d a b c d}
  4982   4982   
  4983   4983   test schema-17.11 {info nextexpected interleave} {
  4984   4984       set defs {
  4985   4985           {
  4986   4986               group + {
         4987  +                element c ?
  4987   4988                   element a ?
  4988   4989                   element b ?
  4989         -                element c ?
  4990   4990               }
  4991   4991               element d
  4992   4992           }
  4993   4993       }
  4994   4994       set result [list]
  4995   4995       foreach def $defs {
  4996   4996           tdom::schema s
  4997   4997           s defelement doc $def
  4998   4998           s event start doc
  4999   4999           s event start b
  5000   5000           s event end
  5001         -        set result [s info nextexpected]
         5001  +        set result [lsort [s info nextexpected]]
  5002   5002           s delete
  5003   5003       }
  5004   5004       set result
  5005         -} {c a b c d}
         5005  +} {a b c d}
  5006   5006   
  5007   5007   test schema-17.12 {info nextexpected interleave} {
  5008   5008       tdom::schema s
  5009   5009       s define {
  5010   5010           prefixns {ns1 http://foo.bar}
  5011   5011           defelement doc {
  5012   5012               element a
................................................................................
  5014   5014               any ns1 ?
  5015   5015               element b ?
  5016   5016           }
  5017   5017       }
  5018   5018       s event start doc
  5019   5019       s event start a
  5020   5020       s event end
  5021         -    set result [s info nextexpected]
         5021  +    set result [lsort [s info nextexpected]]
  5022   5022       s event start something
  5023   5023       s event end
  5024         -    lappend result {*}[s info nextexpected]
         5024  +    lappend result {*}[lsort [s info nextexpected]]
  5025   5025       s delete
  5026   5026       set result
  5027         -} {<any> http://foo.bar:<any> b}
         5027  +} {{<any> {}} {<any> http://foo.bar} b}
  5028   5028   
  5029   5029   proc schema-18 {args} {
  5030   5030       lappend ::result {*}$args
  5031   5031   }
  5032   5032   test schema-18.1 {reportcmd} {
  5033   5033       tdom::schema s
  5034   5034       s define {