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
2771
2772
2773
2774
2775
2776




































2777
2778
2779
2780
2781
2782
2783
....
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
....
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860

2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
....
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
....
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966

2967
2968
2969
2970
2971
2972
2973
....
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
....
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084


3085
























3086
3087
3088
3089
3090
3091
3092
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewStringObj (cp->name, -1));
    if (cp->namespace) {
        Tcl_ListObjAppendElement (interp, rObj,
                                  Tcl_NewStringObj (cp->namespace, -1));
    }
    return rObj;
}





































static void
definedElements (
    SchemaData *sdata,
    Tcl_Interp *interp
    )
{
................................................................................
    Tcl_HashTable *seenCPs,
    Tcl_Obj *rObj
    )
{
    int ac, hm, i, hnew, mustMatch, mayskip, rc;
    SchemaCP *cp, *ic, *jc;
    SchemaValidationStack *se1;
    Tcl_Obj *thisObj;

    getContext (cp, ac, hm);
    if (hm && maxOne(cp->quants[ac])) ac++;
    switch (cp->type) {
    case SCHEMA_CTYPE_INTERLEAVE:
        ac = 0;
        mustMatch = 0;
................................................................................
                    mayskip = getNextExpected (sdata, se1, interp, seenCPs,
                                               rObj);
                    repoolStackElement (sdata, se1);
                }
                break;

            case SCHEMA_CTYPE_ANY:
                if (ic->namespace) {
                    thisObj = Tcl_NewObj();
                    Tcl_AppendStringsToObj (thisObj, ic->namespace,
                                            ":<any>", NULL);
                        
                    Tcl_ListObjAppendElement (interp, rObj, thisObj);
                } else {
                    Tcl_ListObjAppendElement (interp, rObj,
                                              Tcl_NewStringObj ("<any>", 5));
                }

                break;

            case SCHEMA_CTYPE_TEXT:
                Tcl_ListObjAppendElement (interp, rObj,
                                          Tcl_NewStringObj ("#text", 5));
                if (ic->nc == 0 || checkText (interp, ic, "")) {
                    mayskip = 1;
                }
                break;
                
            case SCHEMA_CTYPE_CHOICE:
                if (ic->flags & MIXED_CONTENT) {
                    Tcl_ListObjAppendElement (interp, rObj,
                                              Tcl_NewStringObj ("#text", 5));
                }
                for (i = 0; i < ic->nc; i++) {
                    jc = ic->content[i];
                    switch (jc->type) {
                    case SCHEMA_CTYPE_NAME:
                        Tcl_ListObjAppendElement (
                            interp, rObj, serializeElementName (interp, jc)
................................................................................
                            mayskip = getNextExpected (sdata, se1, interp,
                                                       seenCPs, rObj);
                            repoolStackElement (sdata, se1);
                        }
                        break;
                    case SCHEMA_CTYPE_ANY:
                        Tcl_ListObjAppendElement (
                            interp, rObj, Tcl_NewStringObj ("<any>", 5)
                            );
                        break;
                    case SCHEMA_CTYPE_TEXT:
                        Tcl_ListObjAppendElement (
                            interp, rObj, Tcl_NewStringObj ("#text", 5)
                            );
                        break;
                    case SCHEMA_CTYPE_CHOICE:
                        Tcl_Panic ("MIXED or CHOICE child of MIXED or CHOICE");

                    case SCHEMA_CTYPE_VIRTUAL:
                    case SCHEMA_CTYPE_KEYSPACE:
................................................................................
schemaInstanceInfoCmd (
    SchemaData *sdata,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]
    )
{
    int methodIndex;
    Tcl_HashEntry *h;
    SchemaCP *cp;
    SchemaValidationStack *se;
    Tcl_Obj *elmObj;
    void *ns;
    Tcl_Obj *rObj;
    Tcl_HashTable seenCPs;

    
    static const char *schemaInstanceInfoMethods[] = {
        "validationstate", "vstate", "definedElements", "stack", "toplevel",
        "pastexpected", "nextexpected", "definition", NULL
    };
    enum schemaInstanceInfoMethod {
        m_validationstate, m_vstate, m_definedElements, m_stack, m_toplevel,
................................................................................
                Tcl_ResetResult (interp);
                return TCL_OK;
            }
            se = sdata->stack;
            while (se->pattern->type != SCHEMA_CTYPE_NAME) {
                se = se->down;
            }
            elmObj = serializeElementName (interp, se->pattern);
            Tcl_SetObjResult (interp, elmObj);
            return TCL_OK;
            break;
        }
        
    case m_toplevel:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 1, objv, "no argument expected");
................................................................................
                    Tcl_AppendElement (interp, sdata->startNamespace);
                }
            } else {
                definedElements (sdata, interp);
            }
        } else {
            rObj = Tcl_NewObj();
            Tcl_InitHashTable (&seenCPs, TCL_ONE_WORD_KEYS);
            getNextExpected (sdata, sdata->stack, interp, &seenCPs, rObj);
            Tcl_DeleteHashTable (&seenCPs);


            Tcl_SetObjResult (interp, rObj);
























        }
        return TCL_OK;
        
    case m_pastexpected:
        break;
        
    case m_definition:







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







 







<







 







<
<
<
<
<
<
<
|
<
<
>




|








|







 







|




|







 







|



<

|
|
>







 







|
|







 







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







2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
....
2843
2844
2845
2846
2847
2848
2849

2850
2851
2852
2853
2854
2855
2856
....
2879
2880
2881
2882
2883
2884
2885







2886


2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
....
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
....
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989

2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
....
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
....
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewStringObj (cp->name, -1));
    if (cp->namespace) {
        Tcl_ListObjAppendElement (interp, rObj,
                                  Tcl_NewStringObj (cp->namespace, -1));
    }
    return rObj;
}

/* cp must be of type SCHEMA_CTYPE_ANY for useful results */
static Tcl_Obj*
serializeAnyCP (
    Tcl_Interp *interp,
    SchemaCP *cp
    )
{
    Tcl_Obj *rObj;

    rObj = Tcl_NewObj();
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewStringObj ("<any>", 5));
    if (cp->namespace) {
        Tcl_ListObjAppendElement (interp, rObj,
                                  Tcl_NewStringObj (cp->namespace, -1));
    } else {
        Tcl_ListObjAppendElement (interp, rObj, Tcl_NewObj());
    }
    return rObj;
}

/* The cp argument may be NULL. If it isn't NULL cp must be of type
 * SCHEMA_CTYPE_TEXT for useful results */
static Tcl_Obj*
serializeTextCP (
    Tcl_Interp *interp,
    SchemaCP *cp
    )
{
    Tcl_Obj *rObj;

    rObj = Tcl_NewObj();
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewStringObj ("#text", 5));
    Tcl_ListObjAppendElement (interp, rObj, Tcl_NewObj());
    return rObj;
}

static void
definedElements (
    SchemaData *sdata,
    Tcl_Interp *interp
    )
{
................................................................................
    Tcl_HashTable *seenCPs,
    Tcl_Obj *rObj
    )
{
    int ac, hm, i, hnew, mustMatch, mayskip, rc;
    SchemaCP *cp, *ic, *jc;
    SchemaValidationStack *se1;


    getContext (cp, ac, hm);
    if (hm && maxOne(cp->quants[ac])) ac++;
    switch (cp->type) {
    case SCHEMA_CTYPE_INTERLEAVE:
        ac = 0;
        mustMatch = 0;
................................................................................
                    mayskip = getNextExpected (sdata, se1, interp, seenCPs,
                                               rObj);
                    repoolStackElement (sdata, se1);
                }
                break;

            case SCHEMA_CTYPE_ANY:







                Tcl_ListObjAppendElement (interp, rObj,


                                          serializeAnyCP (interp, ic));
                break;

            case SCHEMA_CTYPE_TEXT:
                Tcl_ListObjAppendElement (interp, rObj,
                                          serializeTextCP (interp, ic));
                if (ic->nc == 0 || checkText (interp, ic, "")) {
                    mayskip = 1;
                }
                break;
                
            case SCHEMA_CTYPE_CHOICE:
                if (ic->flags & MIXED_CONTENT) {
                    Tcl_ListObjAppendElement (interp, rObj,
                                              serializeTextCP (interp, NULL));
                }
                for (i = 0; i < ic->nc; i++) {
                    jc = ic->content[i];
                    switch (jc->type) {
                    case SCHEMA_CTYPE_NAME:
                        Tcl_ListObjAppendElement (
                            interp, rObj, serializeElementName (interp, jc)
................................................................................
                            mayskip = getNextExpected (sdata, se1, interp,
                                                       seenCPs, rObj);
                            repoolStackElement (sdata, se1);
                        }
                        break;
                    case SCHEMA_CTYPE_ANY:
                        Tcl_ListObjAppendElement (
                            interp, rObj, serializeAnyCP (interp, jc)
                            );
                        break;
                    case SCHEMA_CTYPE_TEXT:
                        Tcl_ListObjAppendElement (
                            interp, rObj, serializeTextCP (interp, jc)
                            );
                        break;
                    case SCHEMA_CTYPE_CHOICE:
                        Tcl_Panic ("MIXED or CHOICE child of MIXED or CHOICE");

                    case SCHEMA_CTYPE_VIRTUAL:
                    case SCHEMA_CTYPE_KEYSPACE:
................................................................................
schemaInstanceInfoCmd (
    SchemaData *sdata,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]
    )
{
    int methodIndex, len, i, hnew;
    Tcl_HashEntry *h;
    SchemaCP *cp;
    SchemaValidationStack *se;

    void *ns;
    Tcl_Obj *rObj, *r2Obj, *thisObj;
    Tcl_HashTable localHash;
    Tcl_HashSearch search;
    
    static const char *schemaInstanceInfoMethods[] = {
        "validationstate", "vstate", "definedElements", "stack", "toplevel",
        "pastexpected", "nextexpected", "definition", NULL
    };
    enum schemaInstanceInfoMethod {
        m_validationstate, m_vstate, m_definedElements, m_stack, m_toplevel,
................................................................................
                Tcl_ResetResult (interp);
                return TCL_OK;
            }
            se = sdata->stack;
            while (se->pattern->type != SCHEMA_CTYPE_NAME) {
                se = se->down;
            }
            rObj = serializeElementName (interp, se->pattern);
            Tcl_SetObjResult (interp, rObj);
            return TCL_OK;
            break;
        }
        
    case m_toplevel:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 1, objv, "no argument expected");
................................................................................
                    Tcl_AppendElement (interp, sdata->startNamespace);
                }
            } else {
                definedElements (sdata, interp);
            }
        } else {
            rObj = Tcl_NewObj();
            Tcl_InitHashTable (&localHash, TCL_ONE_WORD_KEYS);
            getNextExpected (sdata, sdata->stack, interp, &localHash, rObj);
            Tcl_DeleteHashTable (&localHash);
            Tcl_ListObjLength (interp, rObj, &len);
            if (len <= 1) {
                Tcl_SetObjResult (interp, rObj);
            } else {
                Tcl_InitHashTable (&localHash, TCL_STRING_KEYS);
                for (i = 0; i < len; i++) {
                    Tcl_ListObjIndex (interp, rObj, i, &thisObj);
                    h = Tcl_CreateHashEntry (
                        &localHash, Tcl_GetString (thisObj), &hnew
                        );
                    if (hnew) {
                        Tcl_SetHashValue (h, thisObj);
                    }
                }
                r2Obj = Tcl_NewObj();
                len = 0;
                for (h = Tcl_FirstHashEntry (&localHash, &search);
                     h != NULL;
                     h = Tcl_NextHashEntry (&search)) {
                    Tcl_ListObjAppendElement (interp, r2Obj,
                                              Tcl_GetHashValue (h));
                    len++;
                }
                Tcl_DeleteHashTable (&localHash);
                Tcl_DecrRefCount (rObj);
                Tcl_SetObjResult (interp, r2Obj);
            }
        }
        return TCL_OK;
        
    case m_pastexpected:
        break;
        
    case m_definition:

Changes to tests/schema.test.

4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
....
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
....
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
....
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
....
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
....
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
            element musthave
            element aftermust
        }
    }
    s event start doc
    set result [s info nextexpected]
    s delete
    set result
} {a c b toplevel musthave}

test schema-17.6 {info nextexpected} {
    tdom::schema s
    s prefixns {foo http://foo.bar}
    s define {
        defelement doc {
            choice ? {
................................................................................
            }
            element aftermust
        }
    }
    s event start doc
    set result [s info nextexpected]
    s delete
    set result
} {a c b toplevel {musthave http://foo.bar}}

test schema-17.7 {info nextexpected} {
    tdom::schema s
    s prefixns {foo http://foo.bar}
    s define {
        defelement doc {
            mixed {
................................................................................
            }
            element aftermust
        }
    }
    s event start doc
    set result [s info nextexpected]
    s delete
    set result
} {{#text} a c b toplevel {musthave http://foo.bar}}

test schema-17.8 {info nextexpected} {
    tdom::schema s
    s defelement doc {
        choice ? {
            element a
            element c
................................................................................
    s define {
        foreach elm {a b c} {
            defelement $elm {}
        }
    }
    lappend result {*}[lsort [s info nextexpected]]
    s event start doc
    lappend result {*}[s info nextexpected]
    s event start c
    s event end
    lappend result {*}[s info nextexpected]    
    s delete
    set result
} {doc a b c doc a c b toplevel musthave toplevel musthave}

proc schema-17.9 {scmd} {
    global result
    set result [$scmd info nextexpected]
}
                  
test schema-17.9 {info nextexpected from scripted constrain} {
    tdom::schema s
    s define {
        defpattern some {
            element a ?
................................................................................
        }
    }
    set result [list]
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s event start doc
        lappend result {*}[s info nextexpected]
        s delete
    }
    set result
} {a b c a b c d a b c d}

test schema-17.11 {info nextexpected interleave} {
    set defs {
        {
            group + {
                element a ?
                element b ?
                element c ?
            }
            element d
        }
    }
    set result [list]
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s event start doc
        s event start b
        s event end
        set result [s info nextexpected]
        s delete
    }
    set result
} {c a b c d}

test schema-17.12 {info nextexpected interleave} {
    tdom::schema s
    s define {
        prefixns {ns1 http://foo.bar}
        defelement doc {
            element a
................................................................................
            any ns1 ?
            element b ?
        }
    }
    s event start doc
    s event start a
    s event end
    set result [s info nextexpected]
    s event start something
    s event end
    lappend result {*}[s info nextexpected]
    s delete
    set result
} {<any> http://foo.bar:<any> b}

proc schema-18 {args} {
    lappend ::result {*}$args
}
test schema-18.1 {reportcmd} {
    tdom::schema s
    s define {







|
|







 







|
|







 







|
|







 







|


|


|



|







 







|









|
|
|











|



|







 







|


|


|







4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
....
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
....
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
....
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
....
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
....
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
            element musthave
            element aftermust
        }
    }
    s event start doc
    set result [s info nextexpected]
    s delete
    lsort $result
} {a b c musthave toplevel}

test schema-17.6 {info nextexpected} {
    tdom::schema s
    s prefixns {foo http://foo.bar}
    s define {
        defelement doc {
            choice ? {
................................................................................
            }
            element aftermust
        }
    }
    s event start doc
    set result [s info nextexpected]
    s delete
    lsort $result
} {a b c {musthave http://foo.bar} toplevel}

test schema-17.7 {info nextexpected} {
    tdom::schema s
    s prefixns {foo http://foo.bar}
    s define {
        defelement doc {
            mixed {
................................................................................
            }
            element aftermust
        }
    }
    s event start doc
    set result [s info nextexpected]
    s delete
    lsort $result
} {a b c {musthave http://foo.bar} toplevel {{#text} {}}}

test schema-17.8 {info nextexpected} {
    tdom::schema s
    s defelement doc {
        choice ? {
            element a
            element c
................................................................................
    s define {
        foreach elm {a b c} {
            defelement $elm {}
        }
    }
    lappend result {*}[lsort [s info nextexpected]]
    s event start doc
    lappend result {*}[lsort [s info nextexpected]]
    s event start c
    s event end
    lappend result {*}[lsort [s info nextexpected]]
    s delete
    set result
} {doc a b c doc a b c musthave toplevel musthave toplevel}

proc schema-17.9 {scmd} {
    global result
    lappend result {*}[lsort [$scmd info nextexpected]]
}
                  
test schema-17.9 {info nextexpected from scripted constrain} {
    tdom::schema s
    s define {
        defpattern some {
            element a ?
................................................................................
        }
    }
    set result [list]
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s event start doc
        lappend result {*}[lsort [s info nextexpected]]
        s delete
    }
    set result
} {a b c a b c d a b c d}

test schema-17.11 {info nextexpected interleave} {
    set defs {
        {
            group + {
                element c ?
                element a ?
                element b ?
            }
            element d
        }
    }
    set result [list]
    foreach def $defs {
        tdom::schema s
        s defelement doc $def
        s event start doc
        s event start b
        s event end
        set result [lsort [s info nextexpected]]
        s delete
    }
    set result
} {a b c d}

test schema-17.12 {info nextexpected interleave} {
    tdom::schema s
    s define {
        prefixns {ns1 http://foo.bar}
        defelement doc {
            element a
................................................................................
            any ns1 ?
            element b ?
        }
    }
    s event start doc
    s event start a
    s event end
    set result [lsort [s info nextexpected]]
    s event start something
    s event end
    lappend result {*}[lsort [s info nextexpected]]
    s delete
    set result
} {{<any> {}} {<any> http://foo.bar} b}

proc schema-18 {args} {
    lappend ::result {*}$args
}
test schema-18.1 {reportcmd} {
    tdom::schema s
    s define {