From 8d076e6525835064d971940356ce83f9d7bd3d55 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Mon, 8 May 2023 14:08:44 +0000 Subject: Make TclLindexFlat() a litle more straightforward. --- generic/tclListObj.c | 55 ++++++++++++++++++++++++++++++++-------------------- generic/tclUtil.c | 4 ++-- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 6cc933c..170dd69 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -2656,6 +2656,7 @@ TclLindexFlat( Tcl_Obj *const indexArray[])/* Array of pointers to Tcl objects that * represent the indices in the list. */ { + int status; Tcl_Size i; /* Handle ArithSeries as special case */ @@ -2684,24 +2685,13 @@ TclLindexFlat( for (i=0 ; i error. */ - break; + status = Tcl_ListObjLength(interp, listObj, &listLen); + if (status != TCL_OK) { + Tcl_DecrRefCount(listObj); + return NULL; } - LIST_ASSERT_TYPE(sublistCopy); - ListObjGetElements(sublistCopy, listLen, elemPtrs); if (TclGetIntForIndexM(interp, indexArray[i], /*endValue*/ listLen-1, &index) == TCL_OK) { @@ -2715,20 +2705,43 @@ TclLindexFlat( if (TclGetIntForIndexM( interp, indexArray[i], TCL_SIZE_MAX - 1, &index) != TCL_OK) { - Tcl_DecrRefCount(sublistCopy); + Tcl_DecrRefCount(listObj); return NULL; } } + Tcl_DecrRefCount(listObj); TclNewObj(listObj); + Tcl_IncrRefCount(listObj); } else { + Tcl_Obj *itemObj; + /* + * Must set the internal rep again because it may have been + * changed by TclGetIntForIndexM. See test lindex-8.4. + */ + if (!TclHasInternalRep(listObj, &tclListType.objType)) { + status = SetListFromAny(interp, listObj); + if (status != TCL_OK) { + /* The list is not a list at all => error. */ + Tcl_DecrRefCount(listObj); + return NULL; + } + } + + ListObjGetElements(listObj, listLen, elemPtrs); + /* increment this reference count first before decrementing + * just in case they are the same Tcl_Obj + */ + itemObj = elemPtrs[index]; + Tcl_IncrRefCount(itemObj); + Tcl_DecrRefCount(listObj); /* Extract the pointer to the appropriate element. */ - listObj = elemPtrs[index]; + listObj = itemObj; } - Tcl_IncrRefCount(listObj); + } else { + Tcl_DecrRefCount(listObj); + listObj = NULL; } - Tcl_DecrRefCount(sublistCopy); } - return listObj; } diff --git a/generic/tclUtil.c b/generic/tclUtil.c index a5c1595..6112869 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3799,8 +3799,8 @@ TclIndexEncode( } /* * We passed 2*INT_MAX as the "end value" to GetWideForIndex. The computed - * index will in one of the following ranges that need to be distinguished - * for encoding purposes in the following code. + * index will be in one of the following ranges that need to be + * distinguished for encoding purposes in the following code. * (1) 0:INT_MAX when * (a) objPtr was a pure non-negative numeric value in that range * (b) objPtr was a numeric computation M+/-N with a result in that range -- cgit v0.12