diff options
-rw-r--r-- | generic/tcl.h | 7 | ||||
-rwxr-xr-x | generic/tclArithSeries.c | 3 | ||||
-rw-r--r-- | generic/tclCmdIL.c | 31 | ||||
-rw-r--r-- | generic/tclInt.h | 2 | ||||
-rw-r--r-- | generic/tclListObj.c | 25 | ||||
-rw-r--r-- | tests/lseq.test | 2 |
6 files changed, 39 insertions, 31 deletions
diff --git a/generic/tcl.h b/generic/tcl.h index ae8ab05..535ae39 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -743,11 +743,14 @@ typedef int (Tcl_ALGetElements) (Tcl_Interp *interp, struct Tcl_Obj *listPtr int *objcptr, struct Tcl_Obj ***objvptr); typedef void (Tcl_ALFreeConcreteRep) (struct Tcl_Obj *listPtr); typedef void (Tcl_ALToStringRep) (struct Tcl_Obj *listPtr); +typedef int (Tcl_ALSetElement) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, + struct Tcl_Obj *indicies, + struct Tcl_Obj *valueObj); typedef enum { TCL_ABSL_NEW, TCL_ABSL_DUPREP, TCL_ABSL_LENGTH, TCL_ABSL_INDEX, TCL_ABSL_SLICE, TCL_ABSL_REVERSE, TCL_ABSL_GETELEMENTS, TCL_ABSL_FREEREP, - TCL_ABSL_TOSTRING + TCL_ABSL_TOSTRING, TCL_ABSL_SETELEMENT } Tcl_AbstractListProcType; typedef struct Tcl_AbstractListVersion_ *Tcl_AbstractListVersion; @@ -868,6 +871,8 @@ typedef struct Tcl_AbstractListType { ** necessary */ Tcl_ALToStringRep *toStringProc; /* Optimized "to-string" conversion ** for updating the string rep */ + Tcl_ALSetElement *setElementProc; /* Replace the element at the indicie + ** with the given valueObj. */ } Tcl_AbstractListType; /* diff --git a/generic/tclArithSeries.c b/generic/tclArithSeries.c index fcc147f..8530c17 100755 --- a/generic/tclArithSeries.c +++ b/generic/tclArithSeries.c @@ -79,7 +79,8 @@ static Tcl_AbstractListType arithSeriesType = { TclArithSeriesObjReverse, TclArithSeriesGetElements, FreeArithSeriesRep, - UpdateStringOfArithSeries + UpdateStringOfArithSeries, + NULL }; /* diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 72d5549..23fca3f 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -2216,11 +2216,14 @@ Tcl_JoinObjCmd( * pointer to its array of element pointers. */ - if (TclHasInternalRep(objv[1],&tclAbstractListType)) { + if (TclHasInternalRep(objv[1],&tclAbstractListType) && + TclAbstractListHasProc(objv[1], TCL_ABSL_GETELEMENTS)) { listLen = Tcl_AbstractListObjLength(objv[1]); isAbstractList = (listLen ? 1 : 0); - if (listLen > 1) { - Tcl_AbstractListObjGetElements(interp, objv[1], &listLen, &elemPtrs); + if (listLen > 1 && + Tcl_AbstractListObjGetElements(interp, objv[1], &listLen, &elemPtrs) + != TCL_OK) { + return TCL_ERROR; } } else if (TclListObjGetElementsM(interp, objv[1], &listLen, &elemPtrs) != TCL_OK) { @@ -2237,7 +2240,8 @@ Tcl_JoinObjCmd( Tcl_SetObjResult(interp, elemPtrs[0]); } else { Tcl_Obj *elemObj; - if (Tcl_AbstractListObjIndex(interp, objv[1], 0, &elemObj) != TCL_OK) { + if (Tcl_AbstractListObjIndex(interp, objv[1], 0, &elemObj) + != TCL_OK) { return TCL_ERROR; } Tcl_SetObjResult(interp, elemObj); @@ -3118,22 +3122,17 @@ Tcl_LreverseObjCmd( return TCL_ERROR; } /* - * Handle AbstractList special case - don't shimmer a into a list if it - * supports a private Reverse function just to reverse it. + * Handle AbstractList special case - do not shimmer into a list, if it + * supports a private Reverse function, just to reverse it. */ if (TclHasInternalRep(objv[1],&tclAbstractListType) && TclAbstractListHasProc(objv[1], TCL_ABSL_REVERSE)) { Tcl_Obj *resultObj; - int status; - status = Tcl_AbstractListObjReverse(interp, objv[1], &resultObj); - - if (status == TCL_OK) { + if (Tcl_AbstractListObjReverse(interp, objv[1], &resultObj) == TCL_OK) { Tcl_SetObjResult(interp, resultObj); + return TCL_OK; } - - return status; - } /* end Abstract List */ if (TclListObjGetElementsM(interp, objv[1], &elemc, &elemv) != TCL_OK) { @@ -4693,8 +4692,10 @@ Tcl_LsortObjCmd( sortInfo.compareCmdPtr = newCommandPtr; } - if (TclHasInternalRep(listObj,&tclAbstractListType)) { - sortInfo.resultCode = Tcl_AbstractListObjGetElements(interp, listObj, &length, &listObjPtrs); + if (TclHasInternalRep(listObj,&tclAbstractListType) && + TclAbstractListHasProc(objv[1], TCL_ABSL_GETELEMENTS)) { + sortInfo.resultCode = + Tcl_AbstractListObjGetElements(interp, listObj, &length, &listObjPtrs); } else { sortInfo.resultCode = TclListObjGetElementsM(interp, listObj, &length, &listObjPtrs); diff --git a/generic/tclInt.h b/generic/tclInt.h index 1446974..96356fe 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2678,6 +2678,8 @@ TclAbstractListHasProc(Tcl_Obj* abstractListObjPtr, Tcl_AbstractListProcType pty return (typePtr->freeRepProc != NULL); case TCL_ABSL_TOSTRING: return (typePtr->toStringProc != NULL); + case TCL_ABSL_SETELEMENT: + return (typePtr->setElementProc != NULL); } return 0; } diff --git a/generic/tclListObj.c b/generic/tclListObj.c index a1c53e6..24082ec 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -1667,20 +1667,19 @@ Tcl_ListObjGetElements( { ListRep listRep; - if (TclListObjGetRep(interp, objPtr, &listRep) != TCL_OK) { - if (TclHasInternalRep(objPtr,&tclAbstractListType)) { - // ? TODO: ?need error message here? - return (Tcl_AbstractListObjGetElements(interp, objPtr, objcPtr, objvPtr)); - } else { - int length; - (void) Tcl_GetStringFromObj(objPtr, &length); - if (length == 0) { - *objcPtr = 0; - *objvPtr = NULL; - return TCL_OK; - } + if (TclHasInternalRep(objPtr,&tclAbstractListType) && + TclAbstractListHasProc(objPtr, TCL_ABSL_GETELEMENTS) && + Tcl_AbstractListObjGetElements(interp, objPtr, objcPtr, objvPtr) == TCL_OK) { + return TCL_OK; + } else if (TclListObjGetRep(interp, objPtr, &listRep) != TCL_OK) { + int length; + (void) Tcl_GetStringFromObj(objPtr, &length); + if (length == 0) { + *objcPtr = 0; + *objvPtr = NULL; + return TCL_OK; } - return TCL_ERROR; + return TCL_ERROR; } ListRepElements(&listRep, *objcPtr, *objvPtr); return TCL_OK; diff --git a/tests/lseq.test b/tests/lseq.test index efbe633..2e5d7e1 100644 --- a/tests/lseq.test +++ b/tests/lseq.test @@ -269,7 +269,7 @@ test lseq-3.10 {lsearch lseq must shimmer?} arithSeriesShimmer { set r [lseq 15 0] set a [lsearch $r 9] list [lindex [tcl::unsupported::representation $r] 3] $a -} {list 6} +} {arithseries 6} test lseq-3.11 {lreverse lseq} { set r [lseq 15 0] |