summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgriffin <briang42@easystreet.net>2022-10-18 01:03:19 (GMT)
committergriffin <briang42@easystreet.net>2022-10-18 01:03:19 (GMT)
commitfb722eca5699fe89d2738fd6fc79f57ce9959026 (patch)
tree6cca55396a9e2dc62589b67ac6e13a62d0f8503a
parent699ec9db36aee1d3bbba1ed943f6c33ca06b084a (diff)
downloadtcl-fb722eca5699fe89d2738fd6fc79f57ce9959026.zip
tcl-fb722eca5699fe89d2738fd6fc79f57ce9959026.tar.gz
tcl-fb722eca5699fe89d2738fd6fc79f57ce9959026.tar.bz2
Add SetElement function to abstract lists. Fix a few bugs.
-rw-r--r--generic/tcl.h7
-rwxr-xr-xgeneric/tclArithSeries.c3
-rw-r--r--generic/tclCmdIL.c31
-rw-r--r--generic/tclInt.h2
-rw-r--r--generic/tclListObj.c25
-rw-r--r--tests/lseq.test2
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]