diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-09-27 13:41:32 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-09-27 13:41:32 (GMT) |
commit | 14d10154ce3c224c66b3774c89a73af85b3481e9 (patch) | |
tree | 59cf7e301a1e7dda55bb845666f4f995f96a8882 /generic/tclCmdIL.c | |
parent | 6a2fb4641d4690a623b89e5999adb7b07e5f15ce (diff) | |
parent | f68a36c8bedfe75b570af667b2fec7a0d81e8f00 (diff) | |
download | tcl-14d10154ce3c224c66b3774c89a73af85b3481e9.zip tcl-14d10154ce3c224c66b3774c89a73af85b3481e9.tar.gz tcl-14d10154ce3c224c66b3774c89a73af85b3481e9.tar.bz2 |
Merge 9.0
Diffstat (limited to 'generic/tclCmdIL.c')
-rw-r--r-- | generic/tclCmdIL.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index f87541e..9c4312e 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -4973,6 +4973,124 @@ 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; + size_t first; + size_t last; + size_t listLen; + size_t 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; + } + + /* The +1 in comparisons are necessitated by indices being unsigned */ + if ((last + 1) > listLen) { + last = listLen - 1; + } + if ((first + 1) <= (last + 1)) { + 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 may 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 |