diff options
| author | apnadkarni <apnmbx-wits@yahoo.com> | 2022-09-27 03:02:16 (GMT) |
|---|---|---|
| committer | apnadkarni <apnmbx-wits@yahoo.com> | 2022-09-27 03:02:16 (GMT) |
| commit | b9209ab689797e5b663cde94d13a41a42243fa2d (patch) | |
| tree | 5b3f1b1f776ea2444cc7e13451e634b3ba4c6cf6 /generic/tclCmdIL.c | |
| parent | 3636d805fcf6da495f444297a7159347ff1ed3a0 (diff) | |
| parent | 04723a6f3ec693a032d5a4d211a2c8d55df6e8b3 (diff) | |
| download | tcl-b9209ab689797e5b663cde94d13a41a42243fa2d.zip tcl-b9209ab689797e5b663cde94d13a41a42243fa2d.tar.gz tcl-b9209ab689797e5b663cde94d13a41a42243fa2d.tar.bz2 | |
TIP 631
Diffstat (limited to 'generic/tclCmdIL.c')
| -rw-r--r-- | generic/tclCmdIL.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 9430eb5..5e13754 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -4961,6 +4961,123 @@ Tcl_LsortObjCmd( /* *---------------------------------------------------------------------- * + * Tcl_LeditObjCmd -- + * + * This procedure is invoked to process the "ledit" Tcl command. See the + * user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_LeditObjCmd( + TCL_UNUSED(ClientData), + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument values. */ +{ + Tcl_Obj *listPtr; /* Pointer to the list being altered. */ + Tcl_Obj *finalValuePtr; /* Value finally assigned to the variable. */ + int createdNewObj; + int result; + int first; + int last; + int listLen; + int numToDelete; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 1, objv, + "listVar first last ?element ...?"); + return TCL_ERROR; + } + + listPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG); + if (listPtr == NULL) { + return TCL_ERROR; + } + + /* + * TODO - refactor the index extraction into a common function shared + * by Tcl_{Lrange,Lreplace,Ledit}ObjCmd + */ + + result = TclListObjLengthM(interp, listPtr, &listLen); + if (result != TCL_OK) { + return result; + } + + result = TclGetIntForIndexM(interp, objv[2], /*end*/ listLen-1, &first); + if (result != TCL_OK) { + return result; + } + + result = TclGetIntForIndexM(interp, objv[3], /*end*/ listLen-1, &last); + if (result != TCL_OK) { + return result; + } + + if (first == TCL_INDEX_NONE) { + first = 0; + } else if (first > listLen) { + first = listLen; + } + + if (last >= listLen) { + last = listLen - 1; + } + if (first <= last) { + numToDelete = last - first + 1; + } else { + numToDelete = 0; + } + + if (Tcl_IsShared(listPtr)) { + listPtr = TclListObjCopy(NULL, listPtr); + createdNewObj = 1; + } else { + createdNewObj = 0; + } + + result = + Tcl_ListObjReplace(interp, listPtr, first, numToDelete, objc - 4, objv + 4); + if (result != TCL_OK) { + if (createdNewObj) { + Tcl_DecrRefCount(listPtr); + } + return result; + } + + /* + * Tcl_ObjSetVar2 mau return a value different from listPtr in the + * presence of traces etc.. Note that finalValuePtr will always have a + * reference count of at least 1 corresponding to the reference from the + * var. If it is same as listPtr, then ref count will be at least 2 + * since we are incr'ing the latter below (safer when calling + * Tcl_ObjSetVar2 which can release it in some cases). Note that we + * leave the incrref of listPtr this late because we want to pass it as + * unshared to Tcl_ListObjReplace above if possible. + */ + Tcl_IncrRefCount(listPtr); + finalValuePtr = + Tcl_ObjSetVar2(interp, objv[1], NULL, listPtr, TCL_LEAVE_ERR_MSG); + Tcl_DecrRefCount(listPtr); /* safe irrespective of createdNewObj */ + if (finalValuePtr == NULL) { + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, finalValuePtr); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * MergeLists - * * This procedure combines two sorted lists of SortElement structures |
