diff options
author | griffin <briang42@easystreet.net> | 2022-08-16 18:33:47 (GMT) |
---|---|---|
committer | griffin <briang42@easystreet.net> | 2022-08-16 18:33:47 (GMT) |
commit | 2439b064ea3e521e50f6c7bd43ef0a69d183bff9 (patch) | |
tree | 1f796e5d3ede5434f99570ffa0d81f82d87dff8b | |
parent | cb579a693a31557eda69872f9f9275372d020afe (diff) | |
download | tcl-2439b064ea3e521e50f6c7bd43ef0a69d183bff9.zip tcl-2439b064ea3e521e50f6c7bd43ef0a69d183bff9.tar.gz tcl-2439b064ea3e521e50f6c7bd43ef0a69d183bff9.tar.bz2 |
Implement lrange for arithseries. Code cleanup.
-rw-r--r-- | generic/tclCmdIL.c | 41 | ||||
-rw-r--r-- | generic/tclCmdMZ.c | 1 | ||||
-rw-r--r-- | generic/tclInt.h | 1 | ||||
-rw-r--r-- | generic/tclListObj.c | 63 |
4 files changed, 71 insertions, 35 deletions
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 065bc2a..669f34b 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -3129,33 +3129,7 @@ Tcl_LreverseObjCmd( * just to reverse it. */ if (TclHasInternalRep(objv[1],&tclArithSeriesType)) { - ArithSeries *arithSeriesPtr = ArithSeriesRepPtr(objv[1]); - Tcl_WideInt rstart, rend, rstep, len; - - len = TclArithSeriesObjLength(objv[1]); - if (TclArithSeriesObjIndex(objv[1], 0, &rend) != TCL_OK) { - return TCL_ERROR; - } - if (TclArithSeriesObjIndex(objv[1], (len-1), &rstart) != TCL_OK) { - return TCL_ERROR; - } - rstep = -arithSeriesPtr->step; - - if (Tcl_IsShared(objv[1])) { - Tcl_Obj *resultObj = TclNewArithSeriesObj(rstart, rend, rstep, len); - Tcl_SetObjResult(interp, resultObj); - } else { - - /* - * Not shared, so swap in place. - */ - - arithSeriesPtr->start = rstart; - arithSeriesPtr->end = rend; - arithSeriesPtr->step = rstep; - TclInvalidateStringRep(objv[1]); - Tcl_SetObjResult(interp, objv[1]); - } + Tcl_SetObjResult(interp, TclArithSeriesObjReverse(objv[1])); return TCL_OK; } /* end ArithSeries */ @@ -4127,8 +4101,8 @@ SequenceIdentifyArgument( * * Tcl_LseqObjCmd -- * - * This procedure is invoked to process the "range" Tcl command. See - * the user documentation for details on what it does. + * This procedure is invoked to process the "lseq" Tcl command. + * See the user documentation for details on what it does. * * Enumerated possible argument patterns: * @@ -4347,10 +4321,13 @@ Tcl_LseqObjCmd( goto done; break; } - if (start <= end) { - elementCount = step ? (end-start+step)/step : 0; // 0 step -> empty list + if (step == 0) { + // 0 step -> empty list + elementCount = 0; + } else if (start <= end) { + elementCount = (end-start+step)/step; } else { - elementCount = step ? (start-end-step)/(-step) : 0; // 0 step -> empty list + elementCount = (start-end-step)/(-step); } break; diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index cff182d..a9d1f11 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -62,7 +62,6 @@ const char tclDefaultTrimSet[] = "\xE3\x80\x80" /* ideographic space (U+3000) */ "\xEF\xBB\xBF" /* zero width no-break space (U+feff) */ ; - /* *---------------------------------------------------------------------- diff --git a/generic/tclInt.h b/generic/tclInt.h index bfbf1bc..f66814e 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2949,6 +2949,7 @@ MODULE_SCOPE int TclArithSeriesObjIndex(Tcl_Obj *arithSeriesPtr, MODULE_SCOPE Tcl_WideInt TclArithSeriesObjLength(Tcl_Obj *arithSeriesPtr); MODULE_SCOPE Tcl_Obj * TclArithSeriesObjRange(Tcl_Obj *arithSeriesPtr, int fromIdx, int toIdx); +MODULE_SCOPE Tcl_Obj * TclArithSeriesObjReverse(Tcl_Obj *arithSeriesPtr); MODULE_SCOPE int TclArithSeriesGetElements(Tcl_Interp *interp, Tcl_Obj *objPtr, int *objcPtr, Tcl_Obj ***objvPtr); MODULE_SCOPE Tcl_Obj * TclNewArithSeriesObj(Tcl_WideInt start, diff --git a/generic/tclListObj.c b/generic/tclListObj.c index d62583a..37d941d 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -2554,7 +2554,7 @@ UpdateStringOfArithSeries(Tcl_Obj *arithSeriesPtr) * Pass 1: estimate space. */ for (i = 0; i < arithSeriesRepPtr->len; i++) { - ele = arithSeriesRepPtr->start + (i*arithSeriesRepPtr->step); + ele = ArithSeriesIndexM(arithSeriesRepPtr, i); /* * Note that sprintf will generate a compiler warning under * Mingw claiming %I64 is an unknown format specifier. @@ -2572,7 +2572,7 @@ UpdateStringOfArithSeries(Tcl_Obj *arithSeriesPtr) p = Tcl_InitStringRep(arithSeriesPtr, NULL, length); for (i = 0; i < arithSeriesRepPtr->len; i++) { - ele = arithSeriesRepPtr->start + (i*arithSeriesRepPtr->step); + ele = ArithSeriesIndexM(arithSeriesRepPtr, i); sprintf(buffer, "%" TCL_LL_MODIFIER "d", ele); slen = strlen(buffer); strcpy(p, buffer); @@ -2816,6 +2816,65 @@ TclArithSeriesGetElements( } return TCL_OK; } + +/* + *---------------------------------------------------------------------- + * + * TclArithSeriesObjReverse -- + * + * Reverse the order of the ArithSeries value. + * *arithSeriesPtr must be known to be a valid list. + * + * Results: + * Returns a pointer to the reordered series. + * This may be a new object or the same object if not shared. + * + * Side effects: + * ?The possible conversion of the object referenced by listPtr? + * ?to a list object.? + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TclArithSeriesObjReverse( + Tcl_Obj *arithSeriesPtr) /* List object to reverse. */ +{ + ArithSeries *arithSeriesRepPtr; + Tcl_WideInt start = -1, end = -1, step, len; + + ArithSeriesGetInternalRep(arithSeriesPtr, arithSeriesRepPtr); + + len = arithSeriesRepPtr->len; + TclArithSeriesObjIndex(arithSeriesPtr, (len-1), &start); + TclArithSeriesObjIndex(arithSeriesPtr, 0, &end); + step = -arithSeriesRepPtr->step; + + if (Tcl_IsShared(arithSeriesPtr) || + ((arithSeriesPtr->refCount > 1))) { + return TclNewArithSeriesObj(start, end, step, len); + } + + /* + * In-place is possible. + */ + + TclInvalidateStringRep(arithSeriesPtr); + + arithSeriesRepPtr->start = start; + arithSeriesRepPtr->end = end; + arithSeriesRepPtr->step = step; + if (arithSeriesRepPtr->elements) { + Tcl_WideInt i; + for (i=0; i<len; i++) { + Tcl_DecrRefCount(arithSeriesRepPtr->elements[i]); + } + ckfree((char*)arithSeriesRepPtr->elements); + } + arithSeriesRepPtr->elements = NULL; + + return arithSeriesPtr; +} /* |