diff options
Diffstat (limited to 'generic/tclListObj.c')
-rw-r--r-- | generic/tclListObj.c | 772 |
1 files changed, 377 insertions, 395 deletions
diff --git a/generic/tclListObj.c b/generic/tclListObj.c index c66fd1e..0d5aad5 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -20,7 +20,7 @@ static List * AttemptNewList(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static List * NewListInternalRep(int objc, Tcl_Obj *const objv[], int p); +static List * NewListIntRep(int objc, Tcl_Obj *const objv[], int p); static void DupListInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static void FreeListInternalRep(Tcl_Obj *listPtr); static int SetListFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); @@ -49,7 +49,7 @@ const Tcl_ObjType tclListType = { /* Macros to manipulate the List internal rep */ -#define ListSetInternalRep(objPtr, listRepPtr) \ +#define ListSetIntRep(objPtr, listRepPtr) \ do { \ Tcl_ObjInternalRep ir; \ ir.twoPtrValue.ptr1 = (listRepPtr); \ @@ -58,14 +58,14 @@ const Tcl_ObjType tclListType = { Tcl_StoreInternalRep((objPtr), &tclListType, &ir); \ } while (0) -#define ListGetInternalRep(objPtr, listRepPtr) \ +#define ListGetIntRep(objPtr, listRepPtr) \ do { \ const Tcl_ObjInternalRep *irPtr; \ irPtr = TclFetchInternalRep((objPtr), &tclListType); \ (listRepPtr) = irPtr ? (List *)irPtr->twoPtrValue.ptr1 : NULL; \ } while (0) -#define ListResetInternalRep(objPtr, listRepPtr) \ +#define ListResetIntRep(objPtr, listRepPtr) \ TclFetchInternalRep((objPtr), &tclListType)->twoPtrValue.ptr1 = (listRepPtr) #ifndef TCL_MIN_ELEMENT_GROWTH @@ -75,28 +75,30 @@ const Tcl_ObjType tclListType = { /* *---------------------------------------------------------------------- * - * NewListInternalRep -- + * NewListIntRep -- * - * Creates a list internal rep with space for objc elements. objc - * must be > 0. If objv!=NULL, initializes with the first objc values - * in that array. If objv==NULL, initalize list internal rep to have - * 0 elements, with space to add objc more. Flag value "p" indicates + * Creates a 'List' structure with space for 'objc' elements. 'objc' must + * be > 0. If 'objv' is not NULL, The list is initialized with first + * 'objc' values in that array. Otherwise the list is initialized to have + * 0 elements, with space to add 'objc' more. Flag value 'p' indicates * how to behave on failure. * - * Results: - * A new List struct with refCount 0 is returned. If some failure - * prevents this then if p=0, NULL is returned and otherwise the - * routine panics. + * Value * - * Side effects: - * The ref counts of the elements in objv are incremented since the - * resulting list now refers to them. + * A new 'List' structure with refCount 0. If some failure + * prevents this NULL is returned if 'p' is 0 , and 'Tcl_Panic' + * is called if it is not. + * + * Effect + * + * The refCount of each value in 'objv' is incremented as it is added + * to the list. * *---------------------------------------------------------------------- */ static List * -NewListInternalRep( +NewListIntRep( int objc, Tcl_Obj *const objv[], int p) @@ -104,7 +106,7 @@ NewListInternalRep( List *listRepPtr; if (objc <= 0) { - Tcl_Panic("NewListInternalRep: expects postive element count"); + Tcl_Panic("NewListIntRep: expects postive element count"); } /* @@ -122,10 +124,10 @@ NewListInternalRep( return NULL; } - listRepPtr = (List *)attemptckalloc(LIST_SIZE(objc)); + listRepPtr = (List *)Tcl_AttemptAlloc(LIST_SIZE(objc)); if (listRepPtr == NULL) { if (p) { - Tcl_Panic("list creation failed: unable to alloc %u bytes", + Tcl_Panic("list creation failed: unable to alloc %" TCL_Z_MODIFIER "u bytes", LIST_SIZE(objc)); } return NULL; @@ -154,21 +156,9 @@ NewListInternalRep( /* *---------------------------------------------------------------------- * - * AttemptNewList -- + * AttemptNewList -- * - * Creates a list internal rep with space for objc elements. objc - * must be > 0. If objv!=NULL, initializes with the first objc values - * in that array. If objv==NULL, initalize list internal rep to have - * 0 elements, with space to add objc more. - * - * Results: - * A new List struct with refCount 0 is returned. If some failure - * prevents this then NULL is returned, and an error message is left - * in the interp result, unless interp is NULL. - * - * Side effects: - * The ref counts of the elements in objv are incremented since the - * resulting list now refers to them. + * Like NewListIntRep, but additionally sets an error message on failure. * *---------------------------------------------------------------------- */ @@ -179,7 +169,7 @@ AttemptNewList( int objc, Tcl_Obj *const objv[]) { - List *listRepPtr = NewListInternalRep(objc, objv, 0); + List *listRepPtr = NewListIntRep(objc, objv, 0); if (interp != NULL && listRepPtr == NULL) { if (objc > LIST_MAX) { @@ -188,7 +178,7 @@ AttemptNewList( LIST_MAX)); } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "list creation failed: unable to alloc %u bytes", + "list creation failed: unable to alloc %" TCL_Z_MODIFIER "u bytes", LIST_SIZE(objc))); } Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); @@ -201,23 +191,20 @@ AttemptNewList( * * Tcl_NewListObj -- * - * This function is normally called when not debugging: i.e., when - * TCL_MEM_DEBUG is not defined. It creates a new list object from an - * (objc,objv) array: that is, each of the objc elements of the array - * referenced by objv is inserted as an element into a new Tcl object. + * Creates a new list object and adds values to it. When TCL_MEM_DEBUG is + * defined, 'Tcl_DbNewListObj' is called instead. * - * When TCL_MEM_DEBUG is defined, this function just returns the result - * of calling the debugging version Tcl_DbNewListObj. + * Value * - * Results: - * A new list object is returned that is initialized from the object - * pointers in objv. If objc is less than or equal to zero, an empty - * object is returned. The new object's string representation is left - * NULL. The resulting new list object has ref count 0. + * A new list 'Tcl_Obj' to which is appended values from 'objv', or if + * 'objc' is less than or equal to zero, a list 'Tcl_Obj' having no + * elements. The string representation of the new 'Tcl_Obj' is set to + * NULL. The refCount of the list is 0. * - * Side effects: - * The ref counts of the elements in objv are incremented since the - * resulting list now refers to them. + * Effect + * + * The refCount of each elements in 'objv' is incremented as it is added + * to the list. * *---------------------------------------------------------------------- */ @@ -253,14 +240,14 @@ Tcl_NewListObj( * Create the internal rep. */ - listRepPtr = NewListInternalRep(objc, objv, 1); + listRepPtr = NewListIntRep(objc, objv, 1); /* * Now create the object. */ TclInvalidateStringRep(listPtr); - ListSetInternalRep(listPtr, listRepPtr); + ListSetIntRep(listPtr, listRepPtr); return listPtr; } #endif /* if TCL_MEM_DEBUG */ @@ -268,28 +255,14 @@ Tcl_NewListObj( /* *---------------------------------------------------------------------- * - * Tcl_DbNewListObj -- - * - * This function is normally called when debugging: i.e., when - * TCL_MEM_DEBUG is defined. It creates new list objects. It is the same - * as the Tcl_NewListObj function above except that it calls - * Tcl_DbCkalloc directly with the file name and line number from its - * caller. This simplifies debugging since then the [memory active] - * command will report the correct file name and line number when - * reporting objects that haven't been freed. + * Tcl_DbNewListObj -- * - * When TCL_MEM_DEBUG is not defined, this function just returns the - * result of calling Tcl_NewListObj. + * Like 'Tcl_NewListObj', but it calls Tcl_DbCkalloc directly with the + * file name and line number from its caller. This simplifies debugging + * since the [memory active] command will report the correct file + * name and line number when reporting objects that haven't been freed. * - * Results: - * A new list object is returned that is initialized from the object - * pointers in objv. If objc is less than or equal to zero, an empty - * object is returned. The new object's string representation is left - * NULL. The new list object has ref count 0. - * - * Side effects: - * The ref counts of the elements in objv are incremented since the - * resulting list now refers to them. + * When TCL_MEM_DEBUG is not defined, 'Tcl_NewListObj' is called instead. * *---------------------------------------------------------------------- */ @@ -318,14 +291,14 @@ Tcl_DbNewListObj( * Create the internal rep. */ - listRepPtr = NewListInternalRep(objc, objv, 1); + listRepPtr = NewListIntRep(objc, objv, 1); /* * Now create the object. */ TclInvalidateStringRep(listPtr); - ListSetInternalRep(listPtr, listRepPtr); + ListSetIntRep(listPtr, listRepPtr); return listPtr; } @@ -348,19 +321,8 @@ Tcl_DbNewListObj( * * Tcl_SetListObj -- * - * Modify an object to be a list containing each of the objc elements of - * the object array referenced by objv. - * - * Results: - * None. - * - * Side effects: - * The object is made a list object and is initialized from the object - * pointers in objv. If objc is less than or equal to zero, an empty - * object is returned. The new object's string representation is left - * NULL. The ref counts of the elements in objv are incremented since the - * list now refers to them. The object's old string and internal - * representations are freed and its type is set NULL. + * Like 'Tcl_NewListObj', but operates on an existing 'Tcl_Obj'instead of + * creating a new one. * *---------------------------------------------------------------------- */ @@ -391,8 +353,8 @@ Tcl_SetListObj( */ if (objc > 0) { - listRepPtr = NewListInternalRep(objc, objv, 1); - ListSetInternalRep(objPtr, listRepPtr); + listRepPtr = NewListIntRep(objc, objv, 1); + ListSetIntRep(objPtr, listRepPtr); } else { Tcl_InitStringRep(objPtr, NULL, 0); } @@ -403,18 +365,20 @@ Tcl_SetListObj( * * TclListObjCopy -- * - * Makes a "pure list" copy of a list value. This provides for the C - * level a counterpart of the [lrange $list 0 end] command, while using - * internals details to be as efficient as possible. + * Creates a new 'Tcl_Obj' which is a pure copy of a list value. This + * provides for the C level a counterpart of the [lrange $list 0 end] + * command, while using internals details to be as efficient as possible. * - * Results: - * Normally returns a pointer to a new Tcl_Obj, that contains the same - * list value as *listPtr does. The returned Tcl_Obj has a refCount of - * zero. If *listPtr does not hold a list, NULL is returned, and if - * interp is non-NULL, an error message is recorded there. + * Value * - * Side effects: - * None. + * The address of the new 'Tcl_Obj' which shares its internal + * representation with 'listPtr', and whose refCount is 0. If 'listPtr' + * is not actually a list, the value is NULL, and an error message is left + * in 'interp' if it is not NULL. + * + * Effect + * + * 'listPtr' is converted to a list if it isn't one already. * *---------------------------------------------------------------------- */ @@ -428,7 +392,7 @@ TclListObjCopy( Tcl_Obj *copyPtr; List *listRepPtr; - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); if (NULL == listRepPtr) { if (SetListFromAny(interp, listPtr) != TCL_OK) { return NULL; @@ -463,22 +427,23 @@ TclListObjCopy( Tcl_Obj * TclListObjRange( Tcl_Obj *listPtr, /* List object to take a range from. */ - int fromIdx, /* Index of first element to include. */ - int toIdx) /* Index of last element to include. */ + size_t fromIdx, /* Index of first element to include. */ + size_t toIdx) /* Index of last element to include. */ { Tcl_Obj **elemPtrs; - int listLen, i, newLen; + int listLen; + size_t i, newLen; List *listRepPtr; TclListObjGetElements(NULL, listPtr, &listLen, &elemPtrs); - if (fromIdx < 0) { + if (fromIdx == TCL_INDEX_NONE) { fromIdx = 0; } - if (toIdx >= listLen) { + if (toIdx + 1 >= (size_t)listLen + 1) { toIdx = listLen-1; } - if (fromIdx > toIdx) { + if (fromIdx + 1 > toIdx + 1) { Tcl_Obj *obj; TclNewObj(obj); return obj; @@ -509,7 +474,7 @@ TclListObjRange( for (i = 0; i < fromIdx; i++) { TclDecrRefCount(elemPtrs[i]); } - for (i = toIdx + 1; i < listLen; i++) { + for (i = toIdx + 1; i < (size_t)listLen; i++) { TclDecrRefCount(elemPtrs[i]); } @@ -529,27 +494,30 @@ TclListObjRange( * * Tcl_ListObjGetElements -- * - * This function returns an (objc,objv) array of the elements in a list - * object. + * Retreive the elements in a list 'Tcl_Obj'. * - * Results: - * The return value is normally TCL_OK; in this case *objcPtr is set to - * the count of list elements and *objvPtr is set to a pointer to an - * array of (*objcPtr) pointers to each list element. If listPtr does not - * refer to a list object and the object can not be converted to one, - * TCL_ERROR is returned and an error message will be left in the - * interpreter's result if interp is not NULL. - * - * The objects referenced by the returned array should be treated as - * readonly and their ref counts are _not_ incremented; the caller must - * do that if it holds on to a reference. Furthermore, the pointer and - * length returned by this function may change as soon as any function is - * called on the list object; be careful about retaining the pointer in a - * local data structure. + * Value * - * Side effects: - * The possible conversion of the object referenced by listPtr - * to a list object. + * TCL_OK + * + * A count of list elements is stored, 'objcPtr', And a pointer to the + * array of elements in the list is stored in 'objvPtr'. + * + * The elements accessible via 'objvPtr' should be treated as readonly + * and the refCount for each object is _not_ incremented; the caller + * must do that if it holds on to a reference. Furthermore, the + * pointer and length returned by this function may change as soon as + * any function is called on the list object. Be careful about + * retaining the pointer in a local data structure. + * + * TCL_ERROR + * + * 'listPtr' is not a valid list. An error message is left in the + * interpreter's result if 'interp' is not NULL. + * + * Effect + * + * 'listPtr' is converted to a list object if it isn't one already. * *---------------------------------------------------------------------- */ @@ -566,10 +534,11 @@ Tcl_ListObjGetElements( { List *listRepPtr; - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); if (listRepPtr == NULL) { - int result, length; + int result; + size_t length; (void) Tcl_GetStringFromObj(listPtr, &length); if (length == 0) { @@ -581,7 +550,7 @@ Tcl_ListObjGetElements( if (result != TCL_OK) { return result; } - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); } *objcPtr = listRepPtr->elemCount; *objvPtr = &listRepPtr->elements; @@ -593,20 +562,27 @@ Tcl_ListObjGetElements( * * Tcl_ListObjAppendList -- * - * This function appends the elements in the list value referenced by - * elemListPtr to the list value referenced by listPtr. + * Appends the elements of elemListPtr to those of listPtr. * - * Results: - * The return value is normally TCL_OK. If listPtr or elemListPtr do not - * refer to list values, TCL_ERROR is returned and an error message is - * left in the interpreter's result if interp is not NULL. + * Value * - * Side effects: - * The reference counts of the elements in elemListPtr are incremented - * since the list now refers to them. listPtr and elemListPtr are - * converted, if necessary, to list objects. Also, appending the new - * elements may cause listObj's array of element pointers to grow. - * listPtr's old string representation, if any, is invalidated. + * TCL_OK + * + * Success. + * + * TCL_ERROR + * + * 'listPtr' or 'elemListPtr' are not valid lists. An error + * message is left in the interpreter's result if 'interp' is not NULL. + * + * Effect + * + * The reference count of each element of 'elemListPtr' as it is added to + * 'listPtr'. 'listPtr' and 'elemListPtr' are converted to 'tclListType' + * if they are not already. Appending the new elements may cause the + * array of element pointers in 'listObj' to grow. If any objects are + * appended to 'listPtr'. Any preexisting string representation of + * 'listPtr' is invalidated. * *---------------------------------------------------------------------- */ @@ -645,24 +621,27 @@ Tcl_ListObjAppendList( * * Tcl_ListObjAppendElement -- * - * This function is a special purpose version of Tcl_ListObjAppendList: - * it appends a single object referenced by objPtr to the list object - * referenced by listPtr. If listPtr is not already a list object, an - * attempt will be made to convert it to one. + * Like 'Tcl_ListObjAppendList', but Appends a single value to a list. * - * Results: - * The return value is normally TCL_OK; in this case objPtr is added to - * the end of listPtr's list. If listPtr does not refer to a list object - * and the object can not be converted to one, TCL_ERROR is returned and - * an error message will be left in the interpreter's result if interp is - * not NULL. + * Value * - * Side effects: - * The ref count of objPtr is incremented since the list now refers to - * it. listPtr will be converted, if necessary, to a list object. Also, - * appending the new element may cause listObj's array of element - * pointers to grow. listPtr's old string representation, if any, is - * invalidated. + * TCL_OK + * + * 'objPtr' is appended to the elements of 'listPtr'. + * + * TCL_ERROR + * + * listPtr does not refer to a list object and the object can not be + * converted to one. An error message will be left in the + * interpreter's result if interp is not NULL. + * + * Effect + * + * If 'listPtr' is not already of type 'tclListType', it is converted. + * The 'refCount' of 'objPtr' is incremented as it is added to 'listPtr'. + * Appending the new element may cause the the array of element pointers + * in 'listObj' to grow. Any preexisting string representation of + * 'listPtr' is invalidated. * *---------------------------------------------------------------------- */ @@ -680,9 +659,10 @@ Tcl_ListObjAppendElement( Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement"); } - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); if (listRepPtr == NULL) { - int result, length; + int result; + size_t length; (void) Tcl_GetStringFromObj(listPtr, &length); if (length == 0) { @@ -693,7 +673,7 @@ Tcl_ListObjAppendElement( if (result != TCL_OK) { return result; } - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); } numElems = listRepPtr->elemCount; @@ -718,18 +698,18 @@ Tcl_ListObjAppendElement( attempt = 2 * numRequired; if (attempt <= LIST_MAX) { - newPtr = (List *)attemptckrealloc(listRepPtr, LIST_SIZE(attempt)); + newPtr = (List *)Tcl_AttemptRealloc(listRepPtr, LIST_SIZE(attempt)); } if (newPtr == NULL) { attempt = numRequired + 1 + TCL_MIN_ELEMENT_GROWTH; if (attempt > LIST_MAX) { attempt = LIST_MAX; } - newPtr = (List *)attemptckrealloc(listRepPtr, LIST_SIZE(attempt)); + newPtr = (List *)Tcl_AttemptRealloc(listRepPtr, LIST_SIZE(attempt)); } if (newPtr == NULL) { attempt = numRequired; - newPtr = (List *)attemptckrealloc(listRepPtr, LIST_SIZE(attempt)); + newPtr = (List *)Tcl_AttemptRealloc(listRepPtr, LIST_SIZE(attempt)); } if (newPtr) { listRepPtr = newPtr; @@ -787,14 +767,14 @@ Tcl_ListObjAppendElement( */ memcpy(dst, src, numElems * sizeof(Tcl_Obj *)); - ckfree(listRepPtr); + Tcl_Free(listRepPtr); } listRepPtr = newPtr; } - ListResetInternalRep(listPtr, listRepPtr); + ListResetIntRep(listPtr, listRepPtr); listRepPtr->refCount++; TclFreeInternalRep(listPtr); - ListSetInternalRep(listPtr, listRepPtr); + ListSetIntRep(listPtr, listRepPtr); listRepPtr->refCount--; /* @@ -820,23 +800,27 @@ Tcl_ListObjAppendElement( * * Tcl_ListObjIndex -- * - * This function returns a pointer to the index'th object from the list - * referenced by listPtr. The first element has index 0. If index is - * negative or greater than or equal to the number of elements in the - * list, a NULL is returned. If listPtr is not a list object, an attempt - * will be made to convert it to a list. + * Retrieve a pointer to the element of 'listPtr' at 'index'. The index + * of the first element is 0. * - * Results: - * The return value is normally TCL_OK; in this case objPtrPtr is set to - * the Tcl_Obj pointer for the index'th list element or NULL if index is - * out of range. This object should be treated as readonly and its ref - * count is _not_ incremented; the caller must do that if it holds on to - * the reference. If listPtr does not refer to a list and can't be - * converted to one, TCL_ERROR is returned and an error message is left - * in the interpreter's result if interp is not NULL. + * Value * - * Side effects: - * listPtr will be converted, if necessary, to a list object. + * TCL_OK + * + * A pointer to the element at 'index' is stored in 'objPtrPtr'. If + * 'index' is out of range, NULL is stored in 'objPtrPtr'. This + * object should be treated as readonly and its 'refCount' is _not_ + * incremented. The caller must do that if it holds on to the + * reference. + * + * TCL_ERROR + * + * 'listPtr' is not a valid list. An an error message is left in the + * interpreter's result if 'interp' is not NULL. + * + * Effect + * + * If 'listPtr' is not already of type 'tclListType', it is converted. * *---------------------------------------------------------------------- */ @@ -850,9 +834,10 @@ Tcl_ListObjIndex( { List *listRepPtr; - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); if (listRepPtr == NULL) { - int result, length; + int result; + size_t length; (void) Tcl_GetStringFromObj(listPtr, &length); if (length == 0) { @@ -863,7 +848,7 @@ Tcl_ListObjIndex( if (result != TCL_OK) { return result; } - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); } if ((index < 0) || (index >= listRepPtr->elemCount)) { @@ -880,19 +865,20 @@ Tcl_ListObjIndex( * * Tcl_ListObjLength -- * - * This function returns the number of elements in a list object. If the - * object is not already a list object, an attempt will be made to - * convert it to one. + * Retrieve the number of elements in a list. * - * Results: - * The return value is normally TCL_OK; in this case *intPtr will be set - * to the integer count of list elements. If listPtr does not refer to a - * list object and the object can not be converted to one, TCL_ERROR is - * returned and an error message will be left in the interpreter's result - * if interp is not NULL. + * Value * - * Side effects: - * The possible conversion of the argument object to a list object. + * TCL_OK + * + * A count of list elements is stored at the address provided by + * 'intPtr'. If 'listPtr' is not already of type 'tclListPtr', it is + * converted. + * + * TCL_ERROR + * + * 'listPtr' is not a valid list. An error message will be left in + * the interpreter's result if 'interp' is not NULL. * *---------------------------------------------------------------------- */ @@ -905,9 +891,10 @@ Tcl_ListObjLength( { List *listRepPtr; - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); if (listRepPtr == NULL) { - int result, length; + int result; + size_t length; (void) Tcl_GetStringFromObj(listPtr, &length); if (length == 0) { @@ -918,7 +905,7 @@ Tcl_ListObjLength( if (result != TCL_OK) { return result; } - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); } *intPtr = listRepPtr->elemCount; @@ -930,35 +917,36 @@ Tcl_ListObjLength( * * Tcl_ListObjReplace -- * - * This function replaces zero or more elements of the list referenced by - * listPtr with the objects from an (objc,objv) array. The objc elements - * of the array referenced by objv replace the count elements in listPtr - * starting at first. + * Replace values in a list. * - * If the argument first is zero or negative, it refers to the first - * element. If first is greater than or equal to the number of elements - * in the list, then no elements are deleted; the new elements are - * appended to the list. Count gives the number of elements to replace. - * If count is zero or negative then no elements are deleted; the new - * elements are simply inserted before first. + * If 'first' is zero or negative, it refers to the first element. If + * 'first' outside the range of elements in the list, no elements are + * deleted. * - * The argument objv refers to an array of objc pointers to the new - * elements to be added to listPtr in place of those that were deleted. - * If objv is NULL, no new elements are added. If listPtr is not a list - * object, an attempt will be made to convert it to one. + * If 'count' is zero or negative no elements are deleted, and any new + * elements are inserted at the beginning of the list. * - * Results: - * The return value is normally TCL_OK. If listPtr does not refer to a - * list object and can not be converted to one, TCL_ERROR is returned and - * an error message will be left in the interpreter's result if interp is - * not NULL. + * Value * - * Side effects: - * The ref counts of the objc elements in objv are incremented since the - * resulting list now refers to them. Similarly, the ref counts for - * replaced objects are decremented. listPtr is converted, if necessary, - * to a list object. listPtr's old string representation, if any, is - * freed. + * TCL_OK + * + * The first 'objc' values of 'objv' replaced 'count' elements in 'listPtr' + * starting at 'first'. If 'objc' 0, no new elements are added. + * + * TCL_ERROR + * + * 'listPtr' is not a valid list. An error message is left in the + * interpreter's result if 'interp' is not NULL. + * + * Effect + * + * If 'listPtr' is not of type 'tclListType', it is converted if possible. + * + * The 'refCount' of each element appended to the list is incremented. + * Similarly, the 'refCount' for each replaced element is decremented. + * + * If 'listPtr' is modified, any previous string representation is + * invalidated. * *---------------------------------------------------------------------- */ @@ -981,9 +969,9 @@ Tcl_ListObjReplace( Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace"); } - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); if (listRepPtr == NULL) { - int length; + size_t length; (void) Tcl_GetStringFromObj(listPtr, &length); if (length == 0) { @@ -998,7 +986,7 @@ Tcl_ListObjReplace( return result; } } - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); } /* @@ -1047,22 +1035,22 @@ Tcl_ListObjReplace( List *newPtr = NULL; int attempt = 2 * numRequired; if (attempt <= LIST_MAX) { - newPtr = (List *)attemptckrealloc(listRepPtr, LIST_SIZE(attempt)); + newPtr = (List *)Tcl_AttemptRealloc(listRepPtr, LIST_SIZE(attempt)); } if (newPtr == NULL) { attempt = numRequired + 1 + TCL_MIN_ELEMENT_GROWTH; if (attempt > LIST_MAX) { attempt = LIST_MAX; } - newPtr = (List *)attemptckrealloc(listRepPtr, LIST_SIZE(attempt)); + newPtr = (List *)Tcl_AttemptRealloc(listRepPtr, LIST_SIZE(attempt)); } if (newPtr == NULL) { attempt = numRequired; - newPtr = (List *)attemptckrealloc(listRepPtr, LIST_SIZE(attempt)); + newPtr = (List *)Tcl_AttemptRealloc(listRepPtr, LIST_SIZE(attempt)); } if (newPtr) { listRepPtr = newPtr; - ListResetInternalRep(listPtr, listRepPtr); + ListResetIntRep(listPtr, listRepPtr); elemPtrs = &listRepPtr->elements; listRepPtr->maxElemCount = attempt; needGrow = numRequired > listRepPtr->maxElemCount; @@ -1124,18 +1112,14 @@ Tcl_ListObjReplace( if (listRepPtr == NULL) { for (i = 0; i < objc; i++) { /* See bug 3598580 */ -#if TCL_MAJOR_VERSION > 8 Tcl_DecrRefCount(objv[i]); -#else - objv[i]->refCount--; -#endif } return TCL_ERROR; } } } - ListResetInternalRep(listPtr, listRepPtr); + ListResetIntRep(listPtr, listRepPtr); listRepPtr->refCount++; elemPtrs = &listRepPtr->elements; @@ -1189,7 +1173,7 @@ Tcl_ListObjReplace( (size_t) numAfterLast * sizeof(Tcl_Obj *)); } - ckfree(oldListRepPtr); + Tcl_Free(oldListRepPtr); } } @@ -1214,7 +1198,7 @@ Tcl_ListObjReplace( listRepPtr->refCount++; TclFreeInternalRep(listPtr); - ListSetInternalRep(listPtr, listRepPtr); + ListSetIntRep(listPtr, listRepPtr); listRepPtr->refCount--; TclInvalidateStringRep(listPtr); @@ -1226,22 +1210,19 @@ Tcl_ListObjReplace( * * TclLindexList -- * - * This procedure handles the 'lindex' command when objc==3. + * Implements the 'lindex' command when objc==3. * - * Results: - * Returns a pointer to the object extracted, or NULL if an error - * occurred. The returned object already includes one reference count for - * the pointer returned. + * Implemented entirely as a wrapper around 'TclLindexFlat'. Reconfigures + * the argument format into required form while taking care to manage + * shimmering so as to tend to keep the most useful internalreps + * and/or avoid the most expensive conversions. * - * Side effects: - * None. + * Value * - * Notes: - * This procedure is implemented entirely as a wrapper around - * TclLindexFlat. All it does is reconfigure the argument format into the - * form required by TclLindexFlat, while taking care to manage shimmering - * in such a way that we tend to keep the most useful internalreps and/or - * avoid the most expensive conversions. + * A pointer to the specified element, with its 'refCount' incremented, or + * NULL if an error occurred. + * + * Notes * *---------------------------------------------------------------------- */ @@ -1253,7 +1234,7 @@ TclLindexList( Tcl_Obj *argPtr) /* Index or index list. */ { - int index; /* Index into the list. */ + size_t index; /* Index into the list. */ Tcl_Obj *indexListCopy; List *listRepPtr; @@ -1263,9 +1244,9 @@ TclLindexList( * shimmering; see TIP#22 and TIP#33 for the details. */ - ListGetInternalRep(argPtr, listRepPtr); + ListGetIntRep(argPtr, listRepPtr); if ((listRepPtr == NULL) - && TclGetIntForIndexM(NULL , argPtr, INT_MAX - 1, &index) == TCL_OK) { + && TclGetIntForIndexM(NULL , argPtr, (size_t)WIDE_MAX - 1, &index) == TCL_OK) { /* * argPtr designates a single index. */ @@ -1295,7 +1276,7 @@ TclLindexList( return TclLindexFlat(interp, listPtr, 1, &argPtr); } - ListGetInternalRep(indexListCopy, listRepPtr); + ListGetIntRep(indexListCopy, listRepPtr); assert(listRepPtr != NULL); @@ -1308,25 +1289,20 @@ TclLindexList( /* *---------------------------------------------------------------------- * - * TclLindexFlat -- + * TclLindexFlat -- * - * This procedure is the core of the 'lindex' command, with all index - * arguments presented as a flat list. + * The core of the 'lindex' command, with all index + * arguments presented as a flat list. * - * Results: - * Returns a pointer to the object extracted, or NULL if an error - * occurred. The returned object already includes one reference count for - * the pointer returned. + * Value * - * Side effects: - * None. + * A pointer to the object extracted, with its 'refCount' incremented, or + * NULL if an error occurred. Thus, the calling code will usually do + * something like: + * + * Tcl_SetObjResult(interp, result); + * Tcl_DecrRefCount(result); * - * Notes: - * The reference count of the returned object includes one reference - * corresponding to the pointer returned. Thus, the calling code will - * usually do something like: - * Tcl_SetObjResult(interp, result); - * Tcl_DecrRefCount(result); * *---------------------------------------------------------------------- */ @@ -1344,7 +1320,8 @@ TclLindexFlat( Tcl_IncrRefCount(listPtr); for (i=0 ; i<indexCount && listPtr ; i++) { - int index, listLen = 0; + size_t index; + int listLen = 0; Tcl_Obj **elemPtrs = NULL, *sublistCopy; /* @@ -1368,14 +1345,14 @@ TclLindexFlat( if (TclGetIntForIndexM(interp, indexArray[i], /*endValue*/ listLen-1, &index) == TCL_OK) { - if (index<0 || index>=listLen) { + if (index >= (size_t)listLen) { /* * Index is out of range. Break out of loop with empty result. * First check remaining indices for validity */ while (++i < indexCount) { - if (TclGetIntForIndexM(interp, indexArray[i], INT_MAX - 1, &index) + if (TclGetIntForIndexM(interp, indexArray[i], (size_t)WIDE_MAX - 1, &index) != TCL_OK) { Tcl_DecrRefCount(sublistCopy); return NULL; @@ -1402,24 +1379,17 @@ TclLindexFlat( * * TclLsetList -- * - * Core of the 'lset' command when objc == 4. Objv[2] may be either a + * The core of [lset] when objc == 4. Objv[2] may be either a * scalar index or a list of indices. * It also handles 'lpop' when given a NULL value. * - * Results: - * Returns the new value of the list variable, or NULL if there was an - * error. The returned object includes one reference count for the - * pointer returned. + * Implemented entirely as a wrapper around 'TclLindexFlat', as described + * for 'TclLindexList'. * - * Side effects: - * None. + * Value * - * Notes: - * This procedure is implemented entirely as a wrapper around - * TclLsetFlat. All it does is reconfigure the argument format into the - * form required by TclLsetFlat, while taking care to manage shimmering - * in such a way that we tend to keep the most useful internalreps and/or - * avoid the most expensive conversions. + * The new list, with the 'refCount' of 'valuPtr' incremented, or NULL if + * there was an error. * *---------------------------------------------------------------------- */ @@ -1434,7 +1404,7 @@ TclLsetList( int indexCount = 0; /* Number of indices in the index list. */ Tcl_Obj **indices = NULL; /* Vector of indices in the index list. */ Tcl_Obj *retValuePtr; /* Pointer to the list to be returned. */ - int index; /* Current index in the list - discarded. */ + size_t index; /* Current index in the list - discarded. */ Tcl_Obj *indexListCopy; List *listRepPtr; @@ -1444,9 +1414,9 @@ TclLsetList( * shimmering; see TIP #22 and #23 for details. */ - ListGetInternalRep(indexArgPtr, listRepPtr); + ListGetIntRep(indexArgPtr, listRepPtr); if (listRepPtr == NULL - && TclGetIntForIndexM(NULL, indexArgPtr, INT_MAX - 1, &index) == TCL_OK) { + && TclGetIntForIndexM(NULL, indexArgPtr, (size_t)WIDE_MAX - 1, &index) == TCL_OK) { /* * indexArgPtr designates a single index. */ @@ -1484,36 +1454,39 @@ TclLsetList( * Core engine of the 'lset' command. * It also handles 'lpop' when given a NULL value. * - * Results: - * Returns the new value of the list variable, or NULL if an error - * occurred. The returned object includes one reference count for the - * pointer returned. + * Value * - * Side effects: - * On entry, the reference count of the variable value does not reflect - * any references held on the stack. The first action of this function is - * to determine whether the object is shared, and to duplicate it if it - * is. The reference count of the duplicate is incremented. At this - * point, the reference count will be 1 for either case, so that the - * object will appear to be unshared. - * - * If an error occurs, and the object has been duplicated, the reference - * count on the duplicate is decremented so that it is now 0: this - * dismisses any memory that was allocated by this function. - * - * If no error occurs, the reference count of the original object is - * incremented if the object has not been duplicated, and nothing is done - * to a reference count of the duplicate. Now the reference count of an - * unduplicated object is 2 (the returned pointer, plus the one stored in - * the variable). The reference count of a duplicate object is 1, - * reflecting that the returned pointer is the only active reference. The - * caller is expected to store the returned value back in the variable - * and decrement its reference count. (INST_STORE_* does exactly this.) - * - * Surgery is performed on the unshared list value to produce the result. - * TclLsetFlat maintains a linked list of Tcl_Obj's whose string + * The resulting list + * + * The 'refCount' of 'valuePtr' is incremented. If 'listPtr' was not + * duplicated, its 'refCount' is incremented. The reference count of + * an unduplicated object is therefore 2 (one for the returned pointer + * and one for the variable that holds it). The reference count of a + * duplicate object is 1, reflecting that result is the only active + * reference. The caller is expected to store the result in the + * variable and decrement its reference count. (INST_STORE_* does + * exactly this.) + * + * NULL + * + * An error occurred. If 'listPtr' was duplicated, the reference + * count on the duplicate is decremented so that it is 0, causing any + * memory allocated by this function to be freed. + * + * + * Effect + * + * On entry, the reference count of 'listPtr' does not reflect any + * references held on the stack. The first action of this function is to + * determine whether 'listPtr' is shared and to create a duplicate + * unshared copy if it is. The reference count of the duplicate is + * incremented. At this point, the reference count is 1 in either case so + * that the object is considered unshared. + * + * The unshared list is altered directly to produce the result. + * 'TclLsetFlat' maintains a linked list of 'Tcl_Obj' values whose string * representations must be spoilt by threading via 'ptr2' of the - * two-pointer internal representation. On entry to TclLsetFlat, the + * two-pointer internal representation. On entry to 'TclLsetFlat', the * values of 'ptr2' are immaterial; on exit, the 'ptr2' field of any * Tcl_Obj that has been modified is set to NULL. * @@ -1529,7 +1502,8 @@ TclLsetFlat( /* Index args. */ Tcl_Obj *valuePtr) /* Value arg to 'lset' or NULL to 'lpop'. */ { - int index, result, len; + size_t index; + int result, len; Tcl_Obj *subListPtr, *retValuePtr, *chainPtr; Tcl_ObjInternalRep *irPtr; @@ -1602,8 +1576,8 @@ TclLsetFlat( } indexArray++; - if (index < 0 || index > elemCount - || (valuePtr == NULL && index >= elemCount)) { + if (index > (size_t)elemCount + || (valuePtr == NULL && index >= (size_t)elemCount)) { /* ...the index points outside the sublist. */ if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -1624,7 +1598,7 @@ TclLsetFlat( if (--indexCount) { parentList = subListPtr; - if (index == elemCount) { + if (index == (size_t)elemCount) { TclNewObj(subListPtr); } else { subListPtr = elemPtrs[index]; @@ -1642,7 +1616,7 @@ TclLsetFlat( * and store another copy. */ - if (index == elemCount) { + if (index == (size_t)elemCount) { Tcl_ListObjAppendElement(NULL, parentList, subListPtr); } else { TclListObjSetElement(NULL, parentList, index, subListPtr); @@ -1700,7 +1674,7 @@ TclLsetFlat( listRepPtr->refCount++; TclFreeInternalRep(objPtr); - ListSetInternalRep(objPtr, listRepPtr); + ListSetIntRep(objPtr, listRepPtr); listRepPtr->refCount--; TclInvalidateStringRep(objPtr); @@ -1731,7 +1705,7 @@ TclLsetFlat( TclListObjLength(NULL, subListPtr, &len); if (valuePtr == NULL) { Tcl_ListObjReplace(NULL, subListPtr, index, 1, 0, NULL); - } else if (index == len) { + } else if (index == (size_t)len) { Tcl_ListObjAppendElement(NULL, subListPtr, valuePtr); } else { TclListObjSetElement(NULL, subListPtr, index, valuePtr); @@ -1746,26 +1720,38 @@ TclLsetFlat( * * TclListObjSetElement -- * - * Set a single element of a list to a specified value + * Set a single element of a list to a specified value. * - * Results: - * The return value is normally TCL_OK. If listPtr does not refer to a - * list object and cannot be converted to one, TCL_ERROR is returned and - * an error message will be left in the interpreter result if interp is - * not NULL. Similarly, if index designates an element outside the range - * [0..listLength-1], where listLength is the count of elements in the - * list object designated by listPtr, TCL_ERROR is returned and an error - * message is left in the interpreter result. + * It is the caller's responsibility to invalidate the string + * representation of the 'listPtr'. * - * Side effects: - * Tcl_Panic if listPtr designates a shared object. Otherwise, attempts - * to convert it to a list with a non-shared internal rep. Decrements the - * ref count of the object at the specified index within the list, - * replaces with the object designated by valuePtr, and increments the - * ref count of the replacement object. + * Value + * + * TCL_OK + * + * Success. + * + * TCL_ERROR + * + * 'listPtr' does not refer to a list object and cannot be converted + * to one. An error message will be left in the interpreter result if + * interp is not NULL. + * + * TCL_ERROR + * + * An index designates an element outside the range [0..listLength-1], + * where 'listLength' is the count of elements in the list object + * designated by 'listPtr'. An error message is left in the + * interpreter result. + * + * Effect + * + * If 'listPtr' designates a shared object, 'Tcl_Panic' is called. If + * 'listPtr' is not already of type 'tclListType', it is converted and the + * internal representation is unshared. The 'refCount' of the element at + * 'index' is decremented and replaced in the list with the 'valuePtr', + * whose 'refCount' in turn is incremented. * - * It is the caller's responsibility to invalidate the string - * representation of the object. * *---------------------------------------------------------------------- */ @@ -1793,9 +1779,10 @@ TclListObjSetElement( Tcl_Panic("%s called with shared object", "TclListObjSetElement"); } - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); if (listRepPtr == NULL) { - int result, length; + int result; + size_t length; (void) Tcl_GetStringFromObj(listPtr, &length); if (length == 0) { @@ -1811,7 +1798,7 @@ TclListObjSetElement( if (result != TCL_OK) { return result; } - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); } elemCount = listRepPtr->elemCount; @@ -1857,7 +1844,7 @@ TclListObjSetElement( listRepPtr->refCount--; listRepPtr = newPtr; - ListResetInternalRep(listPtr, listRepPtr); + ListResetIntRep(listPtr, listRepPtr); } elemPtrs = &listRepPtr->elements; @@ -1883,10 +1870,10 @@ TclListObjSetElement( * Invalidate outdated internalreps. */ - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); listRepPtr->refCount++; TclFreeInternalRep(listPtr); - ListSetInternalRep(listPtr, listRepPtr); + ListSetIntRep(listPtr, listRepPtr); listRepPtr->refCount--; TclInvalidateStringRep(listPtr); @@ -1899,13 +1886,11 @@ TclListObjSetElement( * * FreeListInternalRep -- * - * Deallocate the storage associated with a list object's internal - * representation. + * Deallocate the storage associated with the internal representation of a + * a list object. * - * Results: - * None. + * Effect * - * Side effects: * Frees listPtr's List* internal representation, if no longer shared. * May decrement the ref counts of element objects, which may free them. * @@ -1918,7 +1903,7 @@ FreeListInternalRep( { List *listRepPtr; - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); assert(listRepPtr != NULL); if (listRepPtr->refCount-- <= 1) { @@ -1928,7 +1913,7 @@ FreeListInternalRep( for (i = 0; i < numElems; i++) { Tcl_DecrRefCount(elemPtrs[i]); } - ckfree(listRepPtr); + Tcl_Free(listRepPtr); } } @@ -1937,14 +1922,12 @@ FreeListInternalRep( * * DupListInternalRep -- * - * Initialize the internal representation of a list Tcl_Obj to share the + * Initialize the internal representation of a list 'Tcl_Obj' to share the * internal representation of an existing list object. * - * Results: - * None. + * Effect * - * Side effects: - * The reference count of the List internal rep is incremented. + * The 'refCount' of the List internal rep is incremented. * *---------------------------------------------------------------------- */ @@ -1956,9 +1939,9 @@ DupListInternalRep( { List *listRepPtr; - ListGetInternalRep(srcPtr, listRepPtr); + ListGetIntRep(srcPtr, listRepPtr); assert(listRepPtr != NULL); - ListSetInternalRep(copyPtr, listRepPtr); + ListSetIntRep(copyPtr, listRepPtr); } /* @@ -1966,16 +1949,20 @@ DupListInternalRep( * * SetListFromAny -- * - * Attempt to generate a list internal form for the Tcl object "objPtr". + * Convert any object to a list. * - * Results: - * The return value is TCL_OK or TCL_ERROR. If an error occurs during - * conversion, an error message is left in the interpreter's result - * unless "interp" is NULL. + * Value + * + * TCL_OK + * + * Success. The internal representation of 'objPtr' is set, and the type + * of 'objPtr' is 'tclListType'. + * + * TCL_ERROR + * + * An error occured during conversion. An error message is left in the + * interpreter's result if 'interp' is not NULL. * - * Side effects: - * If no error occurs, a list is stored as "objPtr"s internal - * representation. * *---------------------------------------------------------------------- */ @@ -2031,8 +2018,9 @@ SetListFromAny( Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done); } } else { - int estCount, length; - const char *limit, *nextElem = TclGetStringFromObj(objPtr, &length); + int estCount; + size_t length; + const char *limit, *nextElem = Tcl_GetStringFromObj(objPtr, &length); /* * Allocate enough space to hold a (Tcl_Obj *) for each @@ -2055,7 +2043,8 @@ SetListFromAny( while (nextElem < limit) { const char *elemStart; char *check; - int elemSize, literal; + size_t elemSize; + int literal; if (TCL_OK != TclFindElement(interp, nextElem, limit - nextElem, &elemStart, &nextElem, &elemSize, &literal)) { @@ -2063,7 +2052,7 @@ SetListFromAny( while (--elemPtrs >= &listRepPtr->elements) { Tcl_DecrRefCount(*elemPtrs); } - ckfree(listRepPtr); + Tcl_Free(listRepPtr); return TCL_ERROR; } if (elemStart == limit) { @@ -2099,7 +2088,7 @@ SetListFromAny( * Tcl_GetStringFromObj, to use the old internalRep. */ - ListSetInternalRep(objPtr, listRepPtr); + ListSetIntRep(objPtr, listRepPtr); return TCL_OK; } @@ -2108,18 +2097,16 @@ SetListFromAny( * * UpdateStringOfList -- * - * Update the string representation for a list object. Note: This - * function does not invalidate an existing old string rep so storage - * will be lost if this has not already been done. + * Update the string representation for a list object. * - * Results: - * None. + * Any previously-exising string representation is not invalidated, so + * storage is lost if this has not been taken care of. * - * Side effects: - * The object's string is set to a valid string that results from the - * list-to-string conversion. This string will be empty if the list has - * no elements. The list internal representation should not be NULL and - * we assume it is not NULL. + * Effect + * + * The string representation of 'listPtr' is set to the resulting string. + * This string will be empty if the list has no elements. It is assumed + * that the list internal representation is not NULL. * *---------------------------------------------------------------------- */ @@ -2130,13 +2117,14 @@ UpdateStringOfList( { # define LOCAL_SIZE 64 char localFlags[LOCAL_SIZE], *flagPtr = NULL; - int numElems, i, length, bytesNeeded = 0; + int numElems, i; + size_t length, bytesNeeded = 0; const char *elem, *start; char *dst; Tcl_Obj **elemPtrs; List *listRepPtr; - ListGetInternalRep(listPtr, listRepPtr); + ListGetIntRep(listPtr, listRepPtr); assert(listRepPtr != NULL); @@ -2170,19 +2158,13 @@ UpdateStringOfList( * We know numElems <= LIST_MAX, so this is safe. */ - flagPtr = (char *)ckalloc(numElems); + flagPtr = (char *)Tcl_Alloc(numElems); } elemPtrs = &listRepPtr->elements; for (i = 0; i < numElems; i++) { flagPtr[i] = (i ? TCL_DONT_QUOTE_HASH : 0); - elem = TclGetStringFromObj(elemPtrs[i], &length); + elem = Tcl_GetStringFromObj(elemPtrs[i], &length); bytesNeeded += TclScanElement(elem, length, flagPtr+i); - if (bytesNeeded < 0) { - Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); - } - } - if (bytesNeeded > INT_MAX - numElems + 1) { - Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } bytesNeeded += numElems - 1; @@ -2194,7 +2176,7 @@ UpdateStringOfList( TclOOM(dst, bytesNeeded); for (i = 0; i < numElems; i++) { flagPtr[i] |= (i ? TCL_DONT_QUOTE_HASH : 0); - elem = TclGetStringFromObj(elemPtrs[i], &length); + elem = Tcl_GetStringFromObj(elemPtrs[i], &length); dst += TclConvertElement(elem, length, dst, flagPtr[i]); *dst++ = ' '; } @@ -2203,7 +2185,7 @@ UpdateStringOfList( (void) Tcl_InitStringRep(listPtr, NULL, dst - 1 - start); if (flagPtr != localFlags) { - ckfree(flagPtr); + Tcl_Free(flagPtr); } } |