Tcl Source Code

Changes On Branch internal-abstract-list
Login

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

Changes In Branch internal-abstract-list Excluding Merge-Ins

This is equivalent to a diff from f25757b233 to cd3c0a7242

2023-03-28
06:51
Merge trunk [f25757b233]: Remove knownProfileBug constraint: this is already fixed. check-in: eca2567c57 user: pooryorick tags: unchained
2023-03-23
07:28
Merge-mark check-in: 8c96c87de4 user: konrad.schwarz tags: trunk, main
2023-03-22
21:18
Merge 9.0 check-in: 7401abbdd3 user: jan.nijtmans tags: tip-657
21:17
Merge 9.0 check-in: 3be296f297 user: jan.nijtmans tags: tip-626
21:17
Merge 9.0 Closed-Leaf check-in: cd3c0a7242 user: jan.nijtmans tags: internal-abstract-list
21:15
Merge 9.0 check-in: f25757b233 user: jan.nijtmans tags: trunk, main
21:11
Remove knownProfileBug constraint: this is already fixed check-in: e4a6023a61 user: jan.nijtmans tags: core-8-branch
20:17
Merge 9.0 check-in: 38f7cdb888 user: jan.nijtmans tags: internal-abstract-list
20:13
Merge 9.0 check-in: 2157a49526 user: jan.nijtmans tags: trunk, main

Changes to generic/tclArithSeries.c.

40
41
42
43
44
45
46


47
48
49
50
51
52
53

static void		DupArithSeriesInternalRep (Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void		FreeArithSeriesInternalRep (Tcl_Obj *listPtr);
static int		SetArithSeriesFromAny (Tcl_Interp *interp, Tcl_Obj *objPtr);
static void		UpdateStringOfArithSeries (Tcl_Obj *arithSeriesObj);
static Tcl_Obj *ArithSeriesObjStep(Tcl_Obj *arithSeriesPtr);
static Tcl_Size ArithSeriesObjLength(Tcl_Obj *arithSeriesPtr);



/*
 * The structure below defines the arithmetic series Tcl object type by
 * means of procedures that can be invoked by generic object code.
 *
 * The arithmetic series object is a special case of Tcl list representing
 * an interval of an arithmetic series in constant space.







>
>







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

static void		DupArithSeriesInternalRep (Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void		FreeArithSeriesInternalRep (Tcl_Obj *listPtr);
static int		SetArithSeriesFromAny (Tcl_Interp *interp, Tcl_Obj *objPtr);
static void		UpdateStringOfArithSeries (Tcl_Obj *arithSeriesObj);
static Tcl_Obj *ArithSeriesObjStep(Tcl_Obj *arithSeriesPtr);
static Tcl_Size ArithSeriesObjLength(Tcl_Obj *arithSeriesPtr);
static void		ArithSeriesGetElements(Tcl_Obj *, Tcl_Obj **, size_t, size_t);


/*
 * The structure below defines the arithmetic series Tcl object type by
 * means of procedures that can be invoked by generic object code.
 *
 * The arithmetic series object is a special case of Tcl list representing
 * an interval of an arithmetic series in constant space.
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
const TclObjTypeWithAbstractList tclArithSeriesType = {
    {"arithseries",			/* name */
    FreeArithSeriesInternalRep,		/* freeIntRepProc */
    DupArithSeriesInternalRep,		/* dupIntRepProc */
    UpdateStringOfArithSeries,		/* updateStringProc */
    SetArithSeriesFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    ArithSeriesObjLength

    )}
};

/*
 *----------------------------------------------------------------------
 *
 * ArithSeriesLen --







|
>







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
const TclObjTypeWithAbstractList tclArithSeriesType = {
    {"arithseries",			/* name */
    FreeArithSeriesInternalRep,		/* freeIntRepProc */
    DupArithSeriesInternalRep,		/* dupIntRepProc */
    UpdateStringOfArithSeries,		/* updateStringProc */
    SetArithSeriesFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    ArithSeriesObjLength,
    ArithSeriesGetElements
    )}
};

/*
 *----------------------------------------------------------------------
 *
 * ArithSeriesLen --
833
834
835
836
837
838
839








840













841
842
843
844
845
846
847
848
849

850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */









int













TclArithSeriesGetElements(
    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
    Tcl_Obj *objPtr,		/* ArithSeries object for which an element
				 * array is to be returned. */
    Tcl_Size *objcPtr,		/* Where to store the count of objects
				 * referenced by objv. */
    Tcl_Obj ***objvPtr)		/* Where to store the pointer to an array of
				 * pointers to the list's objects. */
{

    if (TclHasInternalRep(objPtr,&tclArithSeriesType.objType)) {
	ArithSeries *arithSeriesRepPtr;
	Tcl_Obj **objv;
	int i, objc;

	ArithSeriesGetInternalRep(objPtr, arithSeriesRepPtr);
	objc = arithSeriesRepPtr->len;
	if (objc > 0) {
	    if (arithSeriesRepPtr->elements) {
		/* If this exists, it has already been populated */
		objv = arithSeriesRepPtr->elements;
	    } else {
		/* Construct the elements array */
		objv = (Tcl_Obj **)Tcl_Alloc(sizeof(Tcl_Obj*) * objc);
		if (objv == NULL) {
		    if (interp) {
			Tcl_SetObjResult(
			    interp,
			    Tcl_NewStringObj("max length of a Tcl list exceeded", TCL_INDEX_NONE));
			Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
		    }
		    return TCL_ERROR;
		}
		arithSeriesRepPtr->elements = objv;
		for (i = 0; i < objc; i++) {
		    objv[i] = TclArithSeriesObjIndex(interp, objPtr, i);
		    if (objv[i] == NULL) {
			return TCL_ERROR;
		    }
		    Tcl_IncrRefCount(objv[i]);
		}
	    }
	} else {
	    objv = NULL;
	}
	*objvPtr = objv;
	*objcPtr = objc;
    } else {
	if (interp != NULL) {
	    Tcl_SetObjResult(
		interp,
		Tcl_ObjPrintf("value is not an arithseries"));
	    Tcl_SetErrorCode(interp, "TCL", "VALUE", "UNKNOWN", NULL);
	}
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclArithSeriesObjReverse --
 *







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




|

<
<

>


<


















|





|




<
<

<








<

|







836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870


871
872
873
874

875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903


904

905
906
907
908
909
910
911
912

913
914
915
916
917
918
919
920
921
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
ArithSeriesGetElements(
    Tcl_Obj *arithSeriesPtr,
    Tcl_Obj **elemPtr,
    size_t start,
    size_t length)
{
    size_t i, objc;

    if (start + length < start) {
	Tcl_Panic("%s: length overflow", "ArithSeriesGetElements");
    }
    objc = ArithSeriesObjLength(arithSeriesPtr);
    while (length > 0 && start + length > objc) {
	elemPtr[--length] = NULL;
    }
    for (i = 0; i < length; i++) {
	elemPtr[i] = TclArithSeriesObjIndex(NULL, arithSeriesPtr, start + i);
    }
}

Tcl_Obj **
TclArithSeriesGetElements(
    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
    Tcl_Obj *objPtr,		/* ArithSeries object for which an element
				 * array is to be returned. */
    Tcl_Size *objcPtr)		/* Where to store the count of objects
				 * referenced by objv. */


{
    Tcl_Obj **objv = NULL;
    if (TclHasInternalRep(objPtr,&tclArithSeriesType.objType)) {
	ArithSeries *arithSeriesRepPtr;

	int i, objc;

	ArithSeriesGetInternalRep(objPtr, arithSeriesRepPtr);
	objc = arithSeriesRepPtr->len;
	if (objc > 0) {
	    if (arithSeriesRepPtr->elements) {
		/* If this exists, it has already been populated */
		objv = arithSeriesRepPtr->elements;
	    } else {
		/* Construct the elements array */
		objv = (Tcl_Obj **)Tcl_Alloc(sizeof(Tcl_Obj*) * objc);
		if (objv == NULL) {
		    if (interp) {
			Tcl_SetObjResult(
			    interp,
			    Tcl_NewStringObj("max length of a Tcl list exceeded", TCL_INDEX_NONE));
			Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
		    }
		    return NULL;
		}
		arithSeriesRepPtr->elements = objv;
		for (i = 0; i < objc; i++) {
		    objv[i] = TclArithSeriesObjIndex(interp, objPtr, i);
		    if (objv[i] == NULL) {
			return NULL;
		    }
		    Tcl_IncrRefCount(objv[i]);
		}
	    }


	}

	*objcPtr = objc;
    } else {
	if (interp != NULL) {
	    Tcl_SetObjResult(
		interp,
		Tcl_ObjPrintf("value is not an arithseries"));
	    Tcl_SetErrorCode(interp, "TCL", "VALUE", "UNKNOWN", NULL);
	}

    }
    return objv;
}

/*
 *----------------------------------------------------------------------
 *
 * TclArithSeriesObjReverse --
 *

Changes to generic/tclArithSeries.h.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
			    Tcl_Obj *arithSeriesPtr);
MODULE_SCOPE  Tcl_Obj *TclArithSeriesObjIndex(Tcl_Interp *, Tcl_Obj *,
			    Tcl_WideInt index);
MODULE_SCOPE Tcl_Obj *	TclArithSeriesObjRange(Tcl_Interp *interp,
			    Tcl_Obj *arithSeriesPtr, Tcl_Size fromIdx, Tcl_Size toIdx);
MODULE_SCOPE Tcl_Obj *	TclArithSeriesObjReverse(Tcl_Interp *interp,
			    Tcl_Obj *arithSeriesPtr);
MODULE_SCOPE int	TclArithSeriesGetElements(Tcl_Interp *interp,
			    Tcl_Obj *objPtr, Tcl_Size *objcPtr, Tcl_Obj ***objvPtr);
MODULE_SCOPE int 	TclNewArithSeriesObj(Tcl_Interp *interp,
			    Tcl_Obj **arithSeriesObj, int useDoubles,
			    Tcl_Obj *startObj, Tcl_Obj *endObj,
			    Tcl_Obj *stepObj, Tcl_Obj *lenObj);

/*
 * Local Variables:







|
|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
			    Tcl_Obj *arithSeriesPtr);
MODULE_SCOPE  Tcl_Obj *TclArithSeriesObjIndex(Tcl_Interp *, Tcl_Obj *,
			    Tcl_WideInt index);
MODULE_SCOPE Tcl_Obj *	TclArithSeriesObjRange(Tcl_Interp *interp,
			    Tcl_Obj *arithSeriesPtr, Tcl_Size fromIdx, Tcl_Size toIdx);
MODULE_SCOPE Tcl_Obj *	TclArithSeriesObjReverse(Tcl_Interp *interp,
			    Tcl_Obj *arithSeriesPtr);
MODULE_SCOPE Tcl_Obj **TclArithSeriesGetElements(Tcl_Interp *interp,
			    Tcl_Obj *objPtr, Tcl_Size *objcPtr);
MODULE_SCOPE int 	TclNewArithSeriesObj(Tcl_Interp *interp,
			    Tcl_Obj **arithSeriesObj, int useDoubles,
			    Tcl_Obj *startObj, Tcl_Obj *endObj,
			    Tcl_Obj *stepObj, Tcl_Obj *lenObj);

/*
 * Local Variables:

Changes to generic/tclCmdIL.c.

4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
	    goto done;
	}
	Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj());
	sortInfo.compareCmdPtr = newCommandPtr;
    }

    if (TclHasInternalRep(listObj,&tclArithSeriesType.objType)) {
	sortInfo.resultCode = TclArithSeriesGetElements(interp,
	    listObj, &length, &listObjPtrs);
    } else {
	sortInfo.resultCode = TclListObjGetElementsM(interp, listObj,
	    &length, &listObjPtrs);
    }
    if (sortInfo.resultCode != TCL_OK || length <= 0) {
	goto done;
    }







|
|







4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
	    goto done;
	}
	Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj());
	sortInfo.compareCmdPtr = newCommandPtr;
    }

    if (TclHasInternalRep(listObj,&tclArithSeriesType.objType)) {
	listObjPtrs = TclArithSeriesGetElements(interp, listObj, &length);
	sortInfo.resultCode = listObjPtrs ? TCL_OK : TCL_ERROR;
    } else {
	sortInfo.resultCode = TclListObjGetElementsM(interp, listObj,
	    &length, &listObjPtrs);
    }
    if (sortInfo.resultCode != TCL_OK || length <= 0) {
	goto done;
    }

Changes to generic/tclInt.h.

1091
1092
1093
1094
1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
1105
1106

1107
1108
1109
1110
1111
1112
1113
#define TCL_TRACE_ENTER_EXEC	1
#define TCL_TRACE_LEAVE_EXEC	2

typedef struct {  /* For internal core use only */
    Tcl_ObjType objType;
    struct {
	size_t (*lengthProc)(Tcl_Obj *obj);

    } abstractList;
} TclObjTypeWithAbstractList;
#define TCL_OBJTYPE_V0_1(lengthProc) (sizeof(TclObjTypeWithAbstractList)) \
	}, {lengthProc /* For internal core use only */
#define ABSTRACTLIST_PROC(objPtr, proc) (((objPtr)->typePtr \
	&& ((objPtr)->typePtr->version > offsetof(TclObjTypeWithAbstractList, abstractList.proc))) ? \
	((const TclObjTypeWithAbstractList *)(objPtr)->typePtr)->abstractList.proc : NULL)

MODULE_SCOPE size_t TclLengthOne(Tcl_Obj *);


/*
 * The structure below defines an entry in the assocData hash table which is
 * associated with an interpreter. The entry contains a pointer to a function
 * to call when the interpreter is deleted, and a pointer to a user-defined
 * piece of data.
 */







>


|
|





>







1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
#define TCL_TRACE_ENTER_EXEC	1
#define TCL_TRACE_LEAVE_EXEC	2

typedef struct {  /* For internal core use only */
    Tcl_ObjType objType;
    struct {
	size_t (*lengthProc)(Tcl_Obj *obj);
	void (*getElementsProc)(Tcl_Obj *obj, Tcl_Obj **elements, size_t start, size_t length);
    } abstractList;
} TclObjTypeWithAbstractList;
#define TCL_OBJTYPE_V0_1(lengthProc, getElementsProc) (sizeof(TclObjTypeWithAbstractList)) \
	}, {lengthProc, getElementsProc /* For internal core use only */
#define ABSTRACTLIST_PROC(objPtr, proc) (((objPtr)->typePtr \
	&& ((objPtr)->typePtr->version > offsetof(TclObjTypeWithAbstractList, abstractList.proc))) ? \
	((const TclObjTypeWithAbstractList *)(objPtr)->typePtr)->abstractList.proc : NULL)

MODULE_SCOPE size_t TclLengthOne(Tcl_Obj *);
MODULE_SCOPE void TclGetSingleElements(Tcl_Obj *, Tcl_Obj **, size_t, size_t);

/*
 * The structure below defines an entry in the assocData hash table which is
 * associated with an interpreter. The entry contains a pointer to a function
 * to call when the interpreter is deleted, and a pointer to a user-defined
 * piece of data.
 */

Changes to generic/tclListObj.c.

140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
static void	ListRepValidate(const ListRep *repPtr, const char *file,
		    int lineNum);
static void	DupListInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void	FreeListInternalRep(Tcl_Obj *listPtr);
static int	SetListFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void	UpdateStringOfList(Tcl_Obj *listPtr);
static size_t ListLength(Tcl_Obj *listPtr);


/*
 * The structure below defines the list Tcl object type by means of functions
 * that can be invoked by generic object code.
 *
 * The internal representation of a list object is ListRep defined in tcl.h.
 */

const TclObjTypeWithAbstractList tclListType = {
    {"list",			/* name */
    FreeListInternalRep,	/* freeIntRepProc */
    DupListInternalRep,		/* dupIntRepProc */
    UpdateStringOfList,		/* updateStringProc */
    SetListFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    ListLength

    )}
};

/* Macros to manipulate the List internal rep */
#define ListRepIncrRefs(repPtr_)            \
    do {                                    \
	(repPtr_)->storePtr->refCount++;    \







>















|
>







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
static void	ListRepValidate(const ListRep *repPtr, const char *file,
		    int lineNum);
static void	DupListInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void	FreeListInternalRep(Tcl_Obj *listPtr);
static int	SetListFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void	UpdateStringOfList(Tcl_Obj *listPtr);
static size_t ListLength(Tcl_Obj *listPtr);
static void ListGetElements(Tcl_Obj *, Tcl_Obj **, size_t, size_t);

/*
 * The structure below defines the list Tcl object type by means of functions
 * that can be invoked by generic object code.
 *
 * The internal representation of a list object is ListRep defined in tcl.h.
 */

const TclObjTypeWithAbstractList tclListType = {
    {"list",			/* name */
    FreeListInternalRep,	/* freeIntRepProc */
    DupListInternalRep,		/* dupIntRepProc */
    UpdateStringOfList,		/* updateStringProc */
    SetListFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    ListLength,
    ListGetElements
    )}
};

/* Macros to manipulate the List internal rep */
#define ListRepIncrRefs(repPtr_)            \
    do {                                    \
	(repPtr_)->storePtr->refCount++;    \
1664
1665
1666
1667
1668
1669
1670
1671


1672


1673
1674
1675
1676
1677
1678
1679
1680
				 * referenced by objv. */
    Tcl_Obj ***objvPtr)		/* Where to store the pointer to an array of
				 * pointers to the list's objects. */
{
    ListRep listRep;

    if (TclHasInternalRep(objPtr,&tclArithSeriesType.objType)) {
	return TclArithSeriesGetElements(interp, objPtr, objcPtr, objvPtr);


    }



    if (TclListObjGetRep(interp, objPtr, &listRep) != TCL_OK)
	return TCL_ERROR;
    ListRepElements(&listRep, *objcPtr, *objvPtr);
    return TCL_OK;
}

/*







|
>
>
|
>
>
|







1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
				 * referenced by objv. */
    Tcl_Obj ***objvPtr)		/* Where to store the pointer to an array of
				 * pointers to the list's objects. */
{
    ListRep listRep;

    if (TclHasInternalRep(objPtr,&tclArithSeriesType.objType)) {
	Tcl_Obj **objv = TclArithSeriesGetElements(interp, objPtr, objcPtr);
	if (!objv) {
	    return TCL_ERROR;
	}
	*objvPtr = objv;
	return TCL_OK;
    }
    if (TclListObjGetRep(interp, objPtr, &listRep) != TCL_OK)
	return TCL_ERROR;
    ListRepElements(&listRep, *objcPtr, *objvPtr);
    return TCL_OK;
}

/*
2021
2022
2023
2024
2025
2026
2027
























2028
2029
2030
2031
2032
2033
2034
    Tcl_Obj *listPtr)
{
	ListRep listRep;
	ListObjGetRep(listPtr, &listRep);

    return ListRepLength(&listRep);
}

























/*
 *----------------------------------------------------------------------
 *
 * Tcl_ListObjReplace --
 *
 *	This function replaces zero or more elements of the list referenced by







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







2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
    Tcl_Obj *listPtr)
{
	ListRep listRep;
	ListObjGetRep(listPtr, &listRep);

    return ListRepLength(&listRep);
}

static void ListGetElements(
    Tcl_Obj *listPtr,
    Tcl_Obj **elemPtr,
    size_t start,
    size_t length)
{
    ListRep listRep;
    size_t i, objc;
    Tcl_Obj **objv;

    if (start + length < start) {
	Tcl_Panic("%s: length overflow", "ListGetElements");
    }
    ListObjGetRep(listPtr, &listRep);
    ListRepElements(&listRep, objc, objv);
    while (length > 0 && start + length > objc) {
	elemPtr[--length] = NULL;
    }
    objv += start;
    for (i = 0; i < length; i++) {
	elemPtr[i] =  objv[i];
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ListObjReplace --
 *
 *	This function replaces zero or more elements of the list referenced by

Changes to generic/tclObj.c.

228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
const TclObjTypeWithAbstractList tclBooleanType= {
    {"boolean",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    NULL,			/* updateStringProc */
    TclSetBooleanFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne

    )}
};
const TclObjTypeWithAbstractList tclDoubleType= {
    {"double",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    UpdateStringOfDouble,	/* updateStringProc */
    SetDoubleFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne

    )}
};
const TclObjTypeWithAbstractList tclIntType = {
    {"int",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    UpdateStringOfInt,		/* updateStringProc */
    SetIntFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne

    )}
};
const TclObjTypeWithAbstractList tclBignumType = {
    {"bignum",			/* name */
    FreeBignum,			/* freeIntRepProc */
    DupBignum,			/* dupIntRepProc */
    UpdateStringOfBignum,	/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne

    )}
};

/*
 * The structure below defines the Tcl obj hash key type.
 */








|
>









|
>









|
>









|
>







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
const TclObjTypeWithAbstractList tclBooleanType= {
    {"boolean",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    NULL,			/* updateStringProc */
    TclSetBooleanFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne,
    TclGetSingleElements
    )}
};
const TclObjTypeWithAbstractList tclDoubleType= {
    {"double",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    UpdateStringOfDouble,	/* updateStringProc */
    SetDoubleFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne,
    TclGetSingleElements
    )}
};
const TclObjTypeWithAbstractList tclIntType = {
    {"int",			/* name */
    NULL,			/* freeIntRepProc */
    NULL,			/* dupIntRepProc */
    UpdateStringOfInt,		/* updateStringProc */
    SetIntFromAny,		/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne,
    TclGetSingleElements
    )}
};
const TclObjTypeWithAbstractList tclBignumType = {
    {"bignum",			/* name */
    FreeBignum,			/* freeIntRepProc */
    DupBignum,			/* dupIntRepProc */
    UpdateStringOfBignum,	/* updateStringProc */
    NULL,			/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne,
    TclGetSingleElements
    )}
};

/*
 * The structure below defines the Tcl obj hash key type.
 */

Changes to generic/tclUtil.c.

125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142


































143
144
145
146
147
148
149
static const TclObjTypeWithAbstractList endOffsetType = {
    {"end-offset",			/* name */
    NULL,				/* freeIntRepProc */
    NULL,				/* dupIntRepProc */
    NULL,				/* updateStringProc */
    NULL,				/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne

    )}
};

size_t
TclLengthOne(
    TCL_UNUSED(Tcl_Obj *))
{
    return 1;
}



































/*
 *	*	STRING REPRESENTATION OF LISTS	*	*	*
 *
 * The next several routines implement the conversions of strings to and from
 * Tcl lists. To understand their operation, the rules of parsing and
 * generating the string representation of lists must be known.  Here we
 * describe them in one place.







|
>










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







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
static const TclObjTypeWithAbstractList endOffsetType = {
    {"end-offset",			/* name */
    NULL,				/* freeIntRepProc */
    NULL,				/* dupIntRepProc */
    NULL,				/* updateStringProc */
    NULL,				/* setFromAnyProc */
    TCL_OBJTYPE_V0_1(
    TclLengthOne,
    TclGetSingleElements
    )}
};

size_t
TclLengthOne(
    TCL_UNUSED(Tcl_Obj *))
{
    return 1;
}

void
TclGetSingleElements(
    Tcl_Obj *endOffsetPtr,
    Tcl_Obj **elemPtr,
    size_t start,
    size_t length)
{
    if (start + length < start) {
	Tcl_Panic("%s: length overflow", "ListGetElements");
    }
    if (length > 0 && start == 0) {
	size_t len;
	const char *str = Tcl_GetStringFromObj(endOffsetPtr, &len);
	if (len == 0 || (!isspace(UCHAR(*str)) && !isspace(UCHAR(str[len-1])))) {
	    /* If the endOffset doesn't start or end with space, we can use the obj itself. */
	    *elemPtr++ = endOffsetPtr;
	} else {
	    /* otherwise, strip the spaces */
	    Tcl_Obj *obj;

	    while (len > 0 && isspace(UCHAR(str[len-1]))) {
		len--;
	    }
	    while (len > 0 && isspace(UCHAR(*str))) {
		str++; len--;
	    }
	    TclNewStringObj(obj, str, len);
	    *elemPtr++ = obj;
	    start++, length--;
	}
    }
    memset(elemPtr, 0, length * sizeof(Tcl_Obj *));
}

/*
 *	*	STRING REPRESENTATION OF LISTS	*	*	*
 *
 * The next several routines implement the conversions of strings to and from
 * Tcl lists. To understand their operation, the rules of parsing and
 * generating the string representation of lists must be known.  Here we
 * describe them in one place.