summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2022-07-13 12:37:35 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2022-07-13 12:37:35 (GMT)
commit037f0d4f7e7b70aaa44f11a934ed52c0fabca0b3 (patch)
treef031bc4a5f2e633284d7bc7f933f8171d41722c2
parenta3eea6dc3f9b7ffcbcff6b1ee933f9ef1189df3f (diff)
downloadtcl-037f0d4f7e7b70aaa44f11a934ed52c0fabca0b3.zip
tcl-037f0d4f7e7b70aaa44f11a934ed52c0fabca0b3.tar.gz
tcl-037f0d4f7e7b70aaa44f11a934ed52c0fabca0b3.tar.bz2
Make List->elements a TCLFLEXARRAY. Improve documentation (backported from 9.0)
-rw-r--r--generic/tclCmdIL.c6
-rw-r--r--generic/tclInt.h8
-rw-r--r--generic/tclInterp.c2
-rw-r--r--generic/tclListObj.c647
4 files changed, 327 insertions, 336 deletions
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index f32fd98..1197b92 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -2901,7 +2901,7 @@ Tcl_LrepeatObjCmd(
List *listRepPtr = ListRepPtr(listPtr);
listRepPtr->elemCount = elementCount*objc;
- dataArray = &listRepPtr->elements;
+ dataArray = listRepPtr->elements;
}
/*
@@ -3088,7 +3088,7 @@ Tcl_LreverseObjCmd(
resultObj = Tcl_NewListObj(elemc, NULL);
listRepPtr = ListRepPtr(resultObj);
listRepPtr->elemCount = elemc;
- dataArray = &listRepPtr->elements;
+ dataArray = listRepPtr->elements;
for (i=0,j=elemc-1 ; i<elemc ; i++,j--) {
dataArray[j] = elemv[i];
@@ -4414,7 +4414,7 @@ Tcl_LsortObjCmd(
resultPtr = Tcl_NewListObj(sortInfo.numElements * groupSize, NULL);
listRepPtr = ListRepPtr(resultPtr);
- newArray = &listRepPtr->elements;
+ newArray = listRepPtr->elements;
if (group) {
for (i=0; elementPtr!=NULL ; elementPtr=elementPtr->nextPtr) {
idx = elementPtr->payload.index;
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 20c4c45..ac6fb54 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2440,14 +2440,14 @@ typedef struct List {
* derived from the list representation. May
* be ignored if there is no string rep at
* all.*/
- Tcl_Obj *elements; /* First list element; the struct is grown to
+ Tcl_Obj *elements[TCLFLEXARRAY]; /* First list element; the struct is grown to
* accommodate all elements. */
} List;
#define LIST_MAX \
- (1 + (int)(((size_t)UINT_MAX - sizeof(List))/sizeof(Tcl_Obj *)))
+ ((int)(((size_t)UINT_MAX - offsetof(List, elements))/sizeof(Tcl_Obj *)))
#define LIST_SIZE(numElems) \
- (unsigned)(sizeof(List) + (((numElems) - 1) * sizeof(Tcl_Obj *)))
+ (TCL_HASH_TYPE)(offsetof(List, elements) + ((numElems) * sizeof(Tcl_Obj *)))
/*
* Macro used to get the elements of a list object.
@@ -2457,7 +2457,7 @@ typedef struct List {
((List *) (listPtr)->internalRep.twoPtrValue.ptr1)
#define ListObjGetElements(listPtr, objc, objv) \
- ((objv) = &(ListRepPtr(listPtr)->elements), \
+ ((objv) = ListRepPtr(listPtr)->elements, \
(objc) = ListRepPtr(listPtr)->elemCount)
#define ListObjLength(listPtr, len) \
diff --git a/generic/tclInterp.c b/generic/tclInterp.c
index b87bf7c..4ce2f31 100644
--- a/generic/tclInterp.c
+++ b/generic/tclInterp.c
@@ -1837,7 +1837,7 @@ AliasNRCmd(
listPtr = Tcl_NewListObj(cmdc, NULL);
listRep = ListRepPtr(listPtr);
listRep->elemCount = cmdc;
- cmdv = &listRep->elements;
+ cmdv = listRep->elements;
prefv = &aliasPtr->objPtr;
memcpy(cmdv, prefv, prefc * sizeof(Tcl_Obj *));
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index a7f723d..c24809e 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -77,20 +77,22 @@ const Tcl_ObjType tclListType = {
*
* NewListInternalRep --
*
- * 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.
*
*----------------------------------------------------------------------
*/
@@ -140,7 +142,7 @@ NewListInternalRep(
int i;
listRepPtr->elemCount = objc;
- elemPtrs = &listRepPtr->elements;
+ elemPtrs = listRepPtr->elements;
for (i = 0; i < objc; i++) {
elemPtrs[i] = objv[i];
Tcl_IncrRefCount(elemPtrs[i]);
@@ -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 NewListInternalRep, but additionally sets an error message on failure.
*
*----------------------------------------------------------------------
*/
@@ -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.
*
*----------------------------------------------------------------------
*/
@@ -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.
*
*----------------------------------------------------------------------
*/
@@ -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.
*
*----------------------------------------------------------------------
*/
@@ -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.
*
*----------------------------------------------------------------------
*/
@@ -529,27 +493,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.
*
*----------------------------------------------------------------------
*/
@@ -570,7 +537,8 @@ Tcl_ListObjGetElements(
ListGetInternalRep(listPtr, listRepPtr);
if (listRepPtr == NULL) {
- int result, length;
+ int result;
+ int length;
(void) Tcl_GetStringFromObj(listPtr, &length);
if (length == 0) {
@@ -585,7 +553,7 @@ Tcl_ListObjGetElements(
ListGetInternalRep(listPtr, listRepPtr);
}
*objcPtr = listRepPtr->elemCount;
- *objvPtr = &listRepPtr->elements;
+ *objvPtr = listRepPtr->elements;
return TCL_OK;
}
@@ -594,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.
*
*----------------------------------------------------------------------
*/
@@ -646,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.
*
*----------------------------------------------------------------------
*/
@@ -675,7 +653,8 @@ Tcl_ListObjAppendElement(
Tcl_Obj *objPtr) /* Object to append to listPtr's list. */
{
List *listRepPtr, *newPtr = NULL;
- int numElems, numRequired, needGrow, isShared, attempt;
+ int numElems, numRequired;
+ int needGrow, isShared, attempt;
if (Tcl_IsShared(listPtr)) {
Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement");
@@ -683,7 +662,8 @@ Tcl_ListObjAppendElement(
ListGetInternalRep(listPtr, listRepPtr);
if (listRepPtr == NULL) {
- int result, length;
+ int result;
+ int length;
(void) Tcl_GetStringFromObj(listPtr, &length);
if (length == 0) {
@@ -739,7 +719,7 @@ Tcl_ListObjAppendElement(
}
}
if (isShared || needGrow) {
- Tcl_Obj **dst, **src = &listRepPtr->elements;
+ Tcl_Obj **dst, **src = listRepPtr->elements;
/*
* Either we have a shared internalrep and we must copy to write, or we
@@ -767,7 +747,7 @@ Tcl_ListObjAppendElement(
return TCL_ERROR;
}
- dst = &newPtr->elements;
+ dst = newPtr->elements;
newPtr->refCount++;
newPtr->canonicalFlag = listRepPtr->canonicalFlag;
newPtr->elemCount = listRepPtr->elemCount;
@@ -803,7 +783,7 @@ Tcl_ListObjAppendElement(
* the ref count for the (now shared) objPtr.
*/
- *(&listRepPtr->elements + listRepPtr->elemCount) = objPtr;
+ listRepPtr->elements[listRepPtr->elemCount] = objPtr;
Tcl_IncrRefCount(objPtr);
listRepPtr->elemCount++;
@@ -821,23 +801,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.
*
*----------------------------------------------------------------------
*/
@@ -853,7 +837,8 @@ Tcl_ListObjIndex(
ListGetInternalRep(listPtr, listRepPtr);
if (listRepPtr == NULL) {
- int result, length;
+ int result;
+ int length;
(void) Tcl_GetStringFromObj(listPtr, &length);
if (length == 0) {
@@ -870,7 +855,7 @@ Tcl_ListObjIndex(
if ((index < 0) || (index >= listRepPtr->elemCount)) {
*objPtrPtr = NULL;
} else {
- *objPtrPtr = (&listRepPtr->elements)[index];
+ *objPtrPtr = listRepPtr->elements[index];
}
return TCL_OK;
@@ -881,19 +866,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.
*
*----------------------------------------------------------------------
*/
@@ -903,13 +889,14 @@ int
Tcl_ListObjLength(
Tcl_Interp *interp, /* Used to report errors if not NULL. */
Tcl_Obj *listPtr, /* List object whose #elements to return. */
- int *intPtr) /* The resulting int is stored here. */
+ int *intPtr) /* The resulting length is stored here. */
{
List *listRepPtr;
ListGetInternalRep(listPtr, listRepPtr);
if (listRepPtr == NULL) {
- int result, length;
+ int result;
+ int length;
(void) Tcl_GetStringFromObj(listPtr, &length);
if (length == 0) {
@@ -932,35 +919,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 TCL_INDEX_NONE, 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 TCL_INDEX_NONE 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.
*
*----------------------------------------------------------------------
*/
@@ -977,7 +965,8 @@ Tcl_ListObjReplace(
{
List *listRepPtr;
Tcl_Obj **elemPtrs;
- int needGrow, numElems, numRequired, numAfterLast, start, i, j, isShared;
+ int numElems, numRequired, numAfterLast, start, i, j;
+ int needGrow, isShared;
if (Tcl_IsShared(listPtr)) {
Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace");
@@ -1011,7 +1000,7 @@ Tcl_ListObjReplace(
* Resist any temptation to optimize this case.
*/
- elemPtrs = &listRepPtr->elements;
+ elemPtrs = listRepPtr->elements;
numElems = listRepPtr->elemCount;
if (first < 0) {
@@ -1065,7 +1054,7 @@ Tcl_ListObjReplace(
if (newPtr) {
listRepPtr = newPtr;
ListResetInternalRep(listPtr, listRepPtr);
- elemPtrs = &listRepPtr->elements;
+ elemPtrs = listRepPtr->elements;
listRepPtr->maxElemCount = attempt;
needGrow = numRequired > listRepPtr->maxElemCount;
}
@@ -1140,7 +1129,7 @@ Tcl_ListObjReplace(
ListResetInternalRep(listPtr, listRepPtr);
listRepPtr->refCount++;
- elemPtrs = &listRepPtr->elements;
+ elemPtrs = listRepPtr->elements;
if (isShared) {
/*
@@ -1228,22 +1217,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
*
*----------------------------------------------------------------------
*/
@@ -1302,7 +1288,7 @@ TclLindexList(
assert(listRepPtr != NULL);
listPtr = TclLindexFlat(interp, listPtr, listRepPtr->elemCount,
- &listRepPtr->elements);
+ listRepPtr->elements);
Tcl_DecrRefCount(indexListCopy);
return listPtr;
}
@@ -1310,25 +1296,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);
*
*----------------------------------------------------------------------
*/
@@ -1404,24 +1385,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.
*
*----------------------------------------------------------------------
*/
@@ -1486,36 +1460,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.
*
@@ -1531,7 +1508,8 @@ TclLsetFlat(
/* Index args. */
Tcl_Obj *valuePtr) /* Value arg to 'lset' or NULL to 'lpop'. */
{
- int index, result, len;
+ int index, len;
+ int result;
Tcl_Obj *subListPtr, *retValuePtr, *chainPtr;
Tcl_ObjInternalRep *irPtr;
@@ -1724,12 +1702,12 @@ TclLsetFlat(
}
/*
- * Store valuePtr in proper sublist and return. The -1 is to avoid a
- * compiler warning (not a problem because we checked that we have a
- * proper list - or something convertible to one - above).
+ * Store valuePtr in proper sublist and return. The TCL_INDEX_NONE is
+ * to avoid a compiler warning (not a problem because we checked that
+ * we have a proper list - or something convertible to one - above).
*/
- len = -1;
+ len = TCL_INDEX_NONE;
TclListObjLengthM(NULL, subListPtr, &len);
if (valuePtr == NULL) {
Tcl_ListObjReplace(NULL, subListPtr, index, 1, 0, NULL);
@@ -1748,26 +1726,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.
*
*----------------------------------------------------------------------
*/
@@ -1797,7 +1787,8 @@ TclListObjSetElement(
ListGetInternalRep(listPtr, listRepPtr);
if (listRepPtr == NULL) {
- int result, length;
+ int result;
+ int length;
(void) Tcl_GetStringFromObj(listPtr, &length);
if (length == 0) {
@@ -1837,7 +1828,7 @@ TclListObjSetElement(
*/
if (listRepPtr->refCount > 1) {
- Tcl_Obj **dst, **src = &listRepPtr->elements;
+ Tcl_Obj **dst, **src = listRepPtr->elements;
List *newPtr = AttemptNewList(NULL, listRepPtr->maxElemCount, NULL);
if (newPtr == NULL) {
@@ -1850,7 +1841,7 @@ TclListObjSetElement(
newPtr->elemCount = elemCount;
newPtr->canonicalFlag = listRepPtr->canonicalFlag;
- dst = &newPtr->elements;
+ dst = newPtr->elements;
while (elemCount--) {
*dst = *src++;
Tcl_IncrRefCount(*dst++);
@@ -1861,7 +1852,7 @@ TclListObjSetElement(
listRepPtr = newPtr;
ListResetInternalRep(listPtr, listRepPtr);
}
- elemPtrs = &listRepPtr->elements;
+ elemPtrs = listRepPtr->elements;
/*
* Add a reference to the new list element.
@@ -1901,13 +1892,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.
*
@@ -1924,7 +1913,7 @@ FreeListInternalRep(
assert(listRepPtr != NULL);
if (listRepPtr->refCount-- <= 1) {
- Tcl_Obj **elemPtrs = &listRepPtr->elements;
+ Tcl_Obj **elemPtrs = listRepPtr->elements;
int i, numElems = listRepPtr->elemCount;
for (i = 0; i < numElems; i++) {
@@ -1939,14 +1928,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.
*
*----------------------------------------------------------------------
*/
@@ -1968,16 +1955,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.
*
*----------------------------------------------------------------------
*/
@@ -2001,7 +1992,8 @@ SetListFromAny(
if (!TclHasStringRep(objPtr) && TclHasInternalRep(objPtr, &tclDictType)) {
Tcl_Obj *keyPtr, *valuePtr;
Tcl_DictSearch search;
- int done, size;
+ int done;
+ int size;
/*
* Create the new list representation. Note that we do not need to do
@@ -2023,7 +2015,7 @@ SetListFromAny(
* Populate the list representation.
*/
- elemPtrs = &listRepPtr->elements;
+ elemPtrs = listRepPtr->elements;
Tcl_DictObjFirst(NULL, objPtr, &search, &keyPtr, &valuePtr, &done);
while (!done) {
*elemPtrs++ = keyPtr;
@@ -2048,7 +2040,7 @@ SetListFromAny(
if (listRepPtr == NULL) {
return TCL_ERROR;
}
- elemPtrs = &listRepPtr->elements;
+ elemPtrs = listRepPtr->elements;
/*
* Each iteration, parse and store a list element.
@@ -2057,12 +2049,13 @@ SetListFromAny(
while (nextElem < limit) {
const char *elemStart;
char *check;
- int elemSize, literal;
+ int elemSize;
+ int literal;
if (TCL_OK != TclFindElement(interp, nextElem, limit - nextElem,
&elemStart, &nextElem, &elemSize, &literal)) {
fail:
- while (--elemPtrs >= &listRepPtr->elements) {
+ while (--elemPtrs >= listRepPtr->elements) {
Tcl_DecrRefCount(*elemPtrs);
}
ckfree(listRepPtr);
@@ -2092,7 +2085,7 @@ SetListFromAny(
Tcl_IncrRefCount(*elemPtrs++);/* Since list now holds ref to it. */
}
- listRepPtr->elemCount = elemPtrs - &listRepPtr->elements;
+ listRepPtr->elemCount = elemPtrs - listRepPtr->elements;
}
/*
@@ -2110,18 +2103,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.
*
*----------------------------------------------------------------------
*/
@@ -2174,7 +2165,7 @@ UpdateStringOfList(
flagPtr = (char *)ckalloc(numElems);
}
- elemPtrs = &listRepPtr->elements;
+ elemPtrs = listRepPtr->elements;
for (i = 0; i < numElems; i++) {
flagPtr[i] = (i ? TCL_DONT_QUOTE_HASH : 0);
elem = TclGetStringFromObj(elemPtrs[i], &length);