From 522f8027b2de092fb9684f8135dedc0aba75217c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 20 Mar 2020 08:31:04 +0000 Subject: More usage of (internal) TkGetIntForIndex() function, and give this function an additional parameter "lastOK". This way, "end" doesn't need to be handled especially in other code places, all is centralized in this single functions. Only Ttk's "treeview" not done yet, since that requires handling a linked list in stead of an array. --- generic/tkCanvLine.c | 2 +- generic/tkCanvPoly.c | 2 +- generic/tkCanvText.c | 2 +- generic/tkEntry.c | 2 +- generic/tkInt.h | 2 +- generic/tkListbox.c | 4 ++-- generic/tkMenu.c | 2 +- generic/tkObj.c | 11 ++++++++--- generic/ttk/ttkEntry.c | 4 ++-- generic/ttk/ttkManager.c | 6 ++++-- generic/ttk/ttkNotebook.c | 27 +++++++++++++++------------ generic/ttk/ttkPanedwindow.c | 8 +++++--- 12 files changed, 42 insertions(+), 30 deletions(-) diff --git a/generic/tkCanvLine.c b/generic/tkCanvLine.c index 647ddfa..7159fa1 100644 --- a/generic/tkCanvLine.c +++ b/generic/tkCanvLine.c @@ -1754,7 +1754,7 @@ GetLineIndex( const char *string; (void)canvas; - if (TCL_OK == TkGetIntForIndex(obj, 2*linePtr->numPoints - 1, &idx)) { + if (TCL_OK == TkGetIntForIndex(obj, 2*linePtr->numPoints - 1, 0, &idx)) { if (idx == TCL_INDEX_NONE) { idx = 0; } else if (idx > (2*(TkSizeT)linePtr->numPoints)) { diff --git a/generic/tkCanvPoly.c b/generic/tkCanvPoly.c index f2fef26..658bf23 100644 --- a/generic/tkCanvPoly.c +++ b/generic/tkCanvPoly.c @@ -1682,7 +1682,7 @@ GetPolygonIndex( const char *string; TkSizeT count = 2*(polyPtr->numPoints - polyPtr->autoClosed); - if (TCL_OK == TkGetIntForIndex(obj, (INT_MAX) - ((INT_MAX) % count), &idx)) { + if (TCL_OK == TkGetIntForIndex(obj, (INT_MAX - 1) - ((INT_MAX) % count), 1, &idx)) { if (idx == TCL_INDEX_NONE) { idx = 0; } else { diff --git a/generic/tkCanvText.c b/generic/tkCanvText.c index bf6befc..8ac0ea7 100644 --- a/generic/tkCanvText.c +++ b/generic/tkCanvText.c @@ -1386,7 +1386,7 @@ GetTextIndex( const char *string; (void)canvas; - if (TCL_OK == TkGetIntForIndex(obj, textPtr->numChars, &idx)) { + if (TCL_OK == TkGetIntForIndex(obj, textPtr->numChars - 1, 1, &idx)) { if (idx == TCL_INDEX_NONE) { idx = 0; } else if (idx > (TkSizeT)textPtr->numChars) { diff --git a/generic/tkEntry.c b/generic/tkEntry.c index 2281a61..3cd1d6f 100644 --- a/generic/tkEntry.c +++ b/generic/tkEntry.c @@ -2654,7 +2654,7 @@ GetEntryIndex( TkSizeT length, idx; const char *string; - if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->numChars, &idx)) { + if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->numChars - 1, 1, &idx)) { if (idx == TCL_INDEX_NONE) { idx = 0; } else if (idx > (TkSizeT)entryPtr->numChars) { diff --git a/generic/tkInt.h b/generic/tkInt.h index 5950757..97a0c69 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1347,7 +1347,7 @@ MODULE_SCOPE int TkListCreateFrame(ClientData clientData, MODULE_SCOPE void TkRotatePoint(double originX, double originY, double sine, double cosine, double *xPtr, double *yPtr); -MODULE_SCOPE int TkGetIntForIndex(Tcl_Obj *, TkSizeT, TkSizeT*); +MODULE_SCOPE int TkGetIntForIndex(Tcl_Obj *, TkSizeT, int lastOK, TkSizeT*); #ifdef _WIN32 diff --git a/generic/tkListbox.c b/generic/tkListbox.c index bdff469..1445f7a 100644 --- a/generic/tkListbox.c +++ b/generic/tkListbox.c @@ -2731,7 +2731,7 @@ GetListboxIndex( Listbox *listPtr, /* Listbox for which the index is being * specified. */ Tcl_Obj *indexObj, /* Specifies an element in the listbox. */ - int endIsSize, /* If 1, "end" refers to the number of entries + int lastOK, /* If 1, "end" refers to the number of entries * in the listbox. If 0, "end" refers to 1 * less than the number of entries. */ int *indexPtr) /* Where to store converted index. */ @@ -2740,7 +2740,7 @@ GetListboxIndex( TkSizeT idx; const char *stringRep; - result = TkGetIntForIndex(indexObj, listPtr->nElements - (endIsSize ? 0 : 1), &idx); + result = TkGetIntForIndex(indexObj, listPtr->nElements - 1, lastOK, &idx); if (result == TCL_OK) { if (idx + 1 > (TkSizeT)listPtr->nElements + 1) { idx = listPtr->nElements; diff --git a/generic/tkMenu.c b/generic/tkMenu.c index 7ffa066..33acc37 100644 --- a/generic/tkMenu.c +++ b/generic/tkMenu.c @@ -2128,7 +2128,7 @@ GetMenuIndex( int i; const char *string; - if (TkGetIntForIndex(objPtr, menuPtr->numEntries - ((lastOK) ? 0 : 1), indexPtr) == TCL_OK) { + if (TkGetIntForIndex(objPtr, menuPtr->numEntries - 1, lastOK, indexPtr) == TCL_OK) { if (*indexPtr != TCL_INDEX_NONE) { if (*indexPtr >= menuPtr->numEntries) { *indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1); diff --git a/generic/tkObj.c b/generic/tkObj.c index e3b1107..63c6db7 100644 --- a/generic/tkObj.c +++ b/generic/tkObj.c @@ -222,16 +222,21 @@ GetTypeCache(void) */ int -TkGetIntForIndex(Tcl_Obj *indexObj, TkSizeT end, TkSizeT *indexPtr) { +TkGetIntForIndex( + Tcl_Obj *indexObj, + TkSizeT end, + int lastOK, + TkSizeT *indexPtr) +{ ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - if (Tcl_GetIntForIndex(NULL, indexObj, end, indexPtr) != TCL_OK) { + if (Tcl_GetIntForIndex(NULL, indexObj, end + lastOK, indexPtr) != TCL_OK) { return TCL_ERROR; } if (indexObj->typePtr == tsdPtr->endTypePtr) { /* check for "end", but not "end-??" or "end+??" */ - return (*indexPtr == end) ? TCL_OK : TCL_ERROR; + return (*indexPtr == (end + lastOK)) ? TCL_OK : TCL_ERROR; } if (indexObj->typePtr != tsdPtr->intTypePtr) { /* Neither do we accept "??-??" or "??+??" */ diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c index 8abcd9b..12a0b57 100644 --- a/generic/ttk/ttkEntry.c +++ b/generic/ttk/ttkEntry.c @@ -1372,7 +1372,7 @@ EntryIndex( TkSizeT length, idx; const char *string; - if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->entry.numChars, &idx)) { + if (TCL_OK == TkGetIntForIndex(indexObj, entryPtr->entry.numChars - 1, 1, &idx)) { if (idx + 1 > (TkSizeT)entryPtr->entry.numChars + 1) { idx = (TkSizeT)entryPtr->entry.numChars; } @@ -1852,7 +1852,7 @@ static int ComboboxCurrentCommand( } else if (objc == 3) { TkSizeT idx; - if (TCL_OK == TkGetIntForIndex(objv[2], nValues - 1, &idx)) { + if (TCL_OK == TkGetIntForIndex(objv[2], nValues - 1, 0, &idx)) { if (idx == TCL_INDEX_NONE || idx > (TkSizeT)nValues) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "index \"%s\" out of range", Tcl_GetString(objv[2]))); diff --git a/generic/ttk/ttkManager.c b/generic/ttk/ttkManager.c index 5de14bd..b1e6cfd 100644 --- a/generic/ttk/ttkManager.c +++ b/generic/ttk/ttkManager.c @@ -448,12 +448,14 @@ int Ttk_GetSlaveIndexFromObj( { const char *string = Tcl_GetString(objPtr); int slaveIndex = 0; + TkSizeT idx; Tk_Window tkwin; /* Try interpreting as an integer first: */ - if (Tcl_GetIntFromObj(NULL, objPtr, &slaveIndex) == TCL_OK) { - if (slaveIndex < 0 || slaveIndex >= mgr->nSlaves) { + if (TkGetIntForIndex(objPtr, mgr->nSlaves - 1, 1, &idx) == TCL_OK) { + slaveIndex = idx; + if (slaveIndex < 0 || slaveIndex > mgr->nSlaves) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "Slave index %d out of bounds", slaveIndex)); Tcl_SetErrorCode(interp, "TTK", "SLAVE", "INDEX", NULL); diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c index 2ad900a..e8cd905 100644 --- a/generic/ttk/ttkNotebook.c +++ b/generic/ttk/ttkNotebook.c @@ -852,6 +852,12 @@ static int FindTabIndex( { return TCL_OK; } + if (*index_rtn == Ttk_NumberSlaves(nb->notebook.mgr)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Invalid slave specification %s", string)); + Tcl_SetErrorCode(interp, "TTK", "SLAVE", "SPEC", NULL); + return TCL_ERROR; + } /* Nothing matched; Ttk_GetSlaveIndexFromObj will have left error message. */ @@ -867,6 +873,12 @@ static int GetTabIndex( Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, int *index_rtn) { int status = FindTabIndex(interp, nb, objPtr, index_rtn); + if (status == TCL_OK && *index_rtn >= Ttk_NumberSlaves(nb->notebook.mgr)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Slave index %s out of bounds", Tcl_GetString(objPtr))); + Tcl_SetErrorCode(interp, "TTK", "SLAVE", "INDEX", NULL); + return TCL_ERROR; + } if (status == TCL_OK && *index_rtn < 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -936,9 +948,7 @@ static int NotebookInsertCommand( return TCL_ERROR; } - if (!strcmp(Tcl_GetString(objv[2]), "end")) { - destIndex = Ttk_NumberSlaves(nb->notebook.mgr); - } else if (TCL_OK != Ttk_GetSlaveIndexFromObj( + if (TCL_OK != Ttk_GetSlaveIndexFromObj( interp, nb->notebook.mgr, objv[2], &destIndex)) { return TCL_ERROR; } @@ -961,6 +971,8 @@ static int NotebookInsertCommand( interp, nb->notebook.mgr, objv[3], &srcIndex) != TCL_OK) { return TCL_ERROR; + } else if (srcIndex >= Ttk_NumberSlaves(nb->notebook.mgr)) { + srcIndex = Ttk_NumberSlaves(nb->notebook.mgr) - 1; } /* Move existing slave: @@ -1120,15 +1132,6 @@ static int NotebookIndexCommand( return TCL_ERROR; } - /* - * Special-case for "end": - */ - if (!strcmp("end", Tcl_GetString(objv[2]))) { - TkSizeT nSlaves = Ttk_NumberSlaves(nb->notebook.mgr); - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nSlaves)); - return TCL_OK; - } - status = FindTabIndex(interp, nb, objv[2], &index); if (status == TCL_OK && index != -1) { Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index)); diff --git a/generic/ttk/ttkPanedwindow.c b/generic/ttk/ttkPanedwindow.c index c8d0b99..2d494de 100644 --- a/generic/ttk/ttkPanedwindow.c +++ b/generic/ttk/ttkPanedwindow.c @@ -662,9 +662,7 @@ static int PanedInsertCommand( return TCL_ERROR; } - if (!strcmp(Tcl_GetString(objv[2]), "end")) { - destIndex = Ttk_NumberSlaves(pw->paned.mgr); - } else if (TCL_OK != Ttk_GetSlaveIndexFromObj( + if (TCL_OK != Ttk_GetSlaveIndexFromObj( interp,pw->paned.mgr,objv[2],&destIndex)) { return TCL_ERROR; @@ -703,6 +701,8 @@ static int PanedForgetCommand( interp, pw->paned.mgr, objv[2], &paneIndex)) { return TCL_ERROR; + } else if (paneIndex >= Ttk_NumberSlaves(pw->paned.mgr)) { + paneIndex = Ttk_NumberSlaves(pw->paned.mgr) - 1; } Ttk_ForgetSlave(pw->paned.mgr, paneIndex); @@ -783,6 +783,8 @@ static int PanedPaneCommand( interp,pw->paned.mgr,objv[2],&paneIndex)) { return TCL_ERROR; + } else if (paneIndex >= Ttk_NumberSlaves(pw->paned.mgr)) { + paneIndex = Ttk_NumberSlaves(pw->paned.mgr) - 1; } pane = (Pane *)Ttk_SlaveData(pw->paned.mgr, paneIndex); -- cgit v0.12