From 8997eb06b951e71416f99c512ebed977f8cb61fb Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 24 Jan 2022 11:53:34 +0000 Subject: Tcl Dicts > 2^31 elements too --- doc/DictObj.3 | 2 +- doc/ListObj.3 | 8 ++++---- generic/tcl.decls | 7 +++++-- generic/tclCmdMZ.c | 4 ++-- generic/tclCompCmdsGR.c | 2 +- generic/tclConfig.c | 2 +- generic/tclDecls.h | 18 ++++++++++++++---- generic/tclDictObj.c | 16 +++++++++------- generic/tclEnsemble.c | 2 +- generic/tclExecute.c | 4 ++-- generic/tclListObj.c | 3 ++- generic/tclStringObj.c | 4 ++-- generic/tclStubInit.c | 12 +++++++++++- generic/tclVar.c | 2 +- generic/tclZlib.c | 2 +- 15 files changed, 57 insertions(+), 31 deletions(-) diff --git a/doc/DictObj.3 b/doc/DictObj.3 index 0b4c1ca..73b0da8 100644 --- a/doc/DictObj.3 +++ b/doc/DictObj.3 @@ -70,7 +70,7 @@ Points to a variable that will have the value from a key/value pair placed within it. For \fBTcl_DictObjFirst\fR and \fBTcl_DictObjNext\fR, this may be NULL to indicate that the caller is not interested in the value. -.AP int *sizePtr out +.AP size_t | int *sizePtr out Points to a variable that will have the number of key/value pairs contained within the dictionary placed within it. .AP Tcl_DictSearch *searchPtr in/out diff --git a/doc/ListObj.3 b/doc/ListObj.3 index 948be49..09ab3b7 100644 --- a/doc/ListObj.3 +++ b/doc/ListObj.3 @@ -28,7 +28,7 @@ int \fBTcl_ListObjGetElements\fR(\fIinterp, listPtr, objcPtr, objvPtr\fR) .sp int -\fBTcl_ListObjLength\fR(\fIinterp, listPtr, intPtr\fR) +\fBTcl_ListObjLength\fR(\fIinterp, listPtr, lengthPtr\fR) .sp int \fBTcl_ListObjIndex\fR(\fIinterp, listPtr, index, objPtrPtr\fR) @@ -59,7 +59,7 @@ points to the Tcl value that will be appended to \fIlistPtr\fR. For \fBTcl_SetListObj\fR, this points to the Tcl value that will be converted to a list value containing the \fIobjc\fR elements of the array referenced by \fIobjv\fR. -.AP int|size_t *objcPtr in +.AP size_t | int *objcPtr in Points to location where \fBTcl_ListObjGetElements\fR stores the number of element values in \fIlistPtr\fR. .AP Tcl_Obj ***objvPtr out @@ -76,7 +76,7 @@ An array of pointers to values. \fBTcl_NewListObj\fR will insert these values into a new list value and \fBTcl_ListObjReplace\fR will insert them into an existing \fIlistPtr\fR. Each value will become a separate list element. -.AP int|size_t *intPtr out +.AP size_t | int *lengthPtr out Points to location where \fBTcl_ListObjLength\fR stores the length of the list. .AP size_t index in @@ -162,7 +162,7 @@ Otherwise it returns \fBTCL_OK\fR after storing the count and array pointer. .PP \fBTcl_ListObjLength\fR returns the number of elements in the list value referenced by \fIlistPtr\fR. -It returns this count by storing an integer in the address \fIintPtr\fR. +It returns this count by storing a value in the address \fIlengthPtr\fR. If the value is not already a list value, \fBTcl_ListObjLength\fR will attempt to convert it to one; if the conversion fails, it returns \fBTCL_ERROR\fR diff --git a/generic/tcl.decls b/generic/tcl.decls index 033d506..9b572ff 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -1841,7 +1841,7 @@ declare 496 { Tcl_Obj *keyPtr) } declare 497 { - int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr, int *sizePtr) + int TclDictObjSize_(Tcl_Interp *interp, Tcl_Obj *dictPtr, int *sizePtr) } declare 498 { int Tcl_DictObjFirst(Tcl_Interp *interp, Tcl_Obj *dictPtr, @@ -2505,7 +2505,7 @@ declare 660 { int Tcl_AsyncMarkFromSignal(Tcl_AsyncHandler async, int sigNumber) } -# TIP #??? +# TIP #616 declare 661 { int Tcl_ListObjGetElements(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *objcPtr, Tcl_Obj ***objvPtr) @@ -2514,6 +2514,9 @@ declare 662 { int Tcl_ListObjLength(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *lengthPtr) } +declare 663 { + int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t *sizePtr) +} # ----- BASELINE -- FOR -- 8.7.0 ----- # diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index bff2998..573d653 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -1633,7 +1633,7 @@ StringIsCmd( case STR_IS_DICT: { int dresult, dsize; - dresult = Tcl_DictObjSize(interp, objPtr, &dsize); + dresult = TclDictObjSize_(interp, objPtr, &dsize); Tcl_ResetResult(interp); result = (dresult == TCL_OK) ? 1 : 0; if (dresult != TCL_OK && failVarObj != NULL) { @@ -2002,7 +2002,7 @@ StringMapCmd( * sure. This shortens this code quite a bit. */ - Tcl_DictObjSize(interp, objv[objc-2], &i); + TclDictObjSize_(interp, objv[objc-2], &i); if (i == 0) { /* * Empty charMap, just return whatever string was given. diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index ecd087e..46d39be 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -2529,7 +2529,7 @@ TclCompileReturnCmd( } /* Optimize [return -level 0 $x]. */ - Tcl_DictObjSize(NULL, returnOpts, &size); + TclDictObjSize_(NULL, returnOpts, &size); if (size == 0 && level == 0 && code == TCL_OK) { Tcl_DecrRefCount(returnOpts); return TCL_OK; diff --git a/generic/tclConfig.c b/generic/tclConfig.c index 09b1b27..9d41a45 100644 --- a/generic/tclConfig.c +++ b/generic/tclConfig.c @@ -272,7 +272,7 @@ QueryConfigObjCmd( return TCL_ERROR; } - Tcl_DictObjSize(interp, pkgDict, &m); + TclDictObjSize_(interp, pkgDict, &m); listPtr = Tcl_NewListObj(m, NULL); if (!listPtr) { diff --git a/generic/tclDecls.h b/generic/tclDecls.h index b7d88df..d354969 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1293,7 +1293,7 @@ EXTERN int Tcl_DictObjGet(Tcl_Interp *interp, Tcl_Obj *dictPtr, EXTERN int Tcl_DictObjRemove(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr); /* 497 */ -EXTERN int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr, +EXTERN int TclDictObjSize_(Tcl_Interp *interp, Tcl_Obj *dictPtr, int *sizePtr); /* 498 */ EXTERN int Tcl_DictObjFirst(Tcl_Interp *interp, @@ -1764,6 +1764,9 @@ EXTERN int Tcl_ListObjGetElements(Tcl_Interp *interp, /* 662 */ EXTERN int Tcl_ListObjLength(Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *lengthPtr); +/* 663 */ +EXTERN int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr, + size_t *sizePtr); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2272,7 +2275,7 @@ typedef struct TclStubs { int (*tcl_DictObjPut) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj *valuePtr); /* 494 */ int (*tcl_DictObjGet) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj **valuePtrPtr); /* 495 */ int (*tcl_DictObjRemove) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr); /* 496 */ - int (*tcl_DictObjSize) (Tcl_Interp *interp, Tcl_Obj *dictPtr, int *sizePtr); /* 497 */ + int (*tclDictObjSize_) (Tcl_Interp *interp, Tcl_Obj *dictPtr, int *sizePtr); /* 497 */ int (*tcl_DictObjFirst) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 498 */ void (*tcl_DictObjNext) (Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 499 */ void (*tcl_DictObjDone) (Tcl_DictSearch *searchPtr); /* 500 */ @@ -2438,6 +2441,7 @@ typedef struct TclStubs { int (*tcl_AsyncMarkFromSignal) (Tcl_AsyncHandler async, int sigNumber); /* 660 */ int (*tcl_ListObjGetElements) (Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *objcPtr, Tcl_Obj ***objvPtr); /* 661 */ int (*tcl_ListObjLength) (Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *lengthPtr); /* 662 */ + int (*tcl_DictObjSize) (Tcl_Interp *interp, Tcl_Obj *dictPtr, size_t *sizePtr); /* 663 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3383,8 +3387,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_DictObjGet) /* 495 */ #define Tcl_DictObjRemove \ (tclStubsPtr->tcl_DictObjRemove) /* 496 */ -#define Tcl_DictObjSize \ - (tclStubsPtr->tcl_DictObjSize) /* 497 */ +#define TclDictObjSize_ \ + (tclStubsPtr->tclDictObjSize_) /* 497 */ #define Tcl_DictObjFirst \ (tclStubsPtr->tcl_DictObjFirst) /* 498 */ #define Tcl_DictObjNext \ @@ -3712,6 +3716,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_ListObjGetElements) /* 661 */ #define Tcl_ListObjLength \ (tclStubsPtr->tcl_ListObjLength) /* 662 */ +#define Tcl_DictObjSize \ + (tclStubsPtr->tcl_DictObjSize) /* 663 */ #endif /* defined(USE_TCL_STUBS) */ @@ -3917,6 +3923,10 @@ extern const TclStubs *tclStubsPtr; # define Tcl_ListObjLength(interp, listPtr, lengthPtr) (sizeof(*lengthPtr) != sizeof(int) \ ? tclStubsPtr->tcl_ListObjLength((interp), (listPtr), (int *)(void *)(lengthPtr)) \ : tclStubsPtr->tclListObjLength_((interp), (listPtr), (size_t *)(void *)(lengthPtr))) +# undef Tcl_DictObjSize +# define Tcl_DictObjSize(interp, dictPtr, sizePtr) (sizeof(*sizePtr) != sizeof(int) \ + ? tclStubsPtr->tcl_DictObjSize((interp), (dictPtr), (int *)(void *)(sizePtr)) \ + : tclStubsPtr->tclDictObjSize_((interp), (dictPtr), (size_t *)(void *)(sizePtr))) #endif /* TCL_NO_DEPRECATED */ #else # define Tcl_WCharToUtfDString (sizeof(wchar_t) != sizeof(short) \ diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index cf82ac8..a124a32 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -1065,7 +1065,7 @@ int Tcl_DictObjSize( Tcl_Interp *interp, Tcl_Obj *dictPtr, - int *sizePtr) + size_t *sizePtr) { Dict *dict; @@ -2021,7 +2021,8 @@ DictSizeCmd( int objc, Tcl_Obj *const *objv) { - int result, size; + int result; + size_t size; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary"); @@ -3268,7 +3269,8 @@ DictUpdateCmd( { Interp *iPtr = (Interp *) interp; Tcl_Obj *dictPtr, *objPtr; - int i, dummy; + int i; + size_t dummy; if (objc < 5 || !(objc & 1)) { Tcl_WrongNumArgs(interp, 1, objv, @@ -3321,7 +3323,7 @@ FinalizeDictUpdate( { Tcl_Obj *dictPtr, *objPtr, **objv; Tcl_InterpState state; - int i, objc; + size_t i, objc; Tcl_Obj *varName = (Tcl_Obj *)data[0]; Tcl_Obj *argsObj = (Tcl_Obj *)data[1]; @@ -3365,7 +3367,7 @@ FinalizeDictUpdate( * an instruction to remove the key. */ - TclListObjGetElements_(NULL, argsObj, &objc, &objv); + Tcl_ListObjGetElements(NULL, argsObj, &objc, &objv); for (i=0 ; i ", O2S(dictPtr))); - if (Tcl_DictObjSize(interp, dictPtr, &done) != TCL_OK) { + if (TclDictObjSize_(interp, dictPtr, &done) != TCL_OK) { TRACE_APPEND(("ERROR verifying dictionary nature of \"%.30s\": %s\n", O2S(dictPtr), O2S(Tcl_GetObjResult(interp)))); goto gotError; @@ -6996,7 +6996,7 @@ TEBCresume( TRACE_APPEND(("storage was unset\n")); NEXT_INST_F(9, 1, 0); } - if (Tcl_DictObjSize(interp, dictPtr, &length) != TCL_OK + if (TclDictObjSize_(interp, dictPtr, &length) != TCL_OK || TclListObjGetElements_(interp, OBJ_AT_TOS, &length, &keyPtrPtr) != TCL_OK) { TRACE_ERROR(interp); diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 747cf0d..37392e4 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -1961,7 +1961,8 @@ SetListFromAny( if (!TclHasStringRep(objPtr) && TclHasInternalRep(objPtr, &tclDictType)) { Tcl_Obj *keyPtr, *valuePtr; Tcl_DictSearch search; - int done, size; + int done; + size_t size; /* * Create the new list representation. Note that we do not need to do diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index b52e33c..65c9983 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -466,14 +466,14 @@ int TclCheckEmptyString( Tcl_Obj *objPtr) { - int length = -1; + size_t length = TCL_INDEX_NONE; if (objPtr->bytes == &tclEmptyString) { return TCL_EMPTYSTRING_YES; } if (TclListObjIsCanonical(objPtr)) { - TclListObjLength_(NULL, objPtr, &length); + Tcl_ListObjLength(NULL, objPtr, &length); return length == 0; } diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 6885e07..98d0d21 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -104,6 +104,15 @@ int TclListObjLength_(Tcl_Interp *interp, Tcl_Obj *listPtr, } return result; } +int TclDictObjSize_(Tcl_Interp *interp, Tcl_Obj *dictPtr, + int *sizePtr) { + size_t n; + int result = Tcl_DictObjSize(interp, dictPtr, &n); + if (sizePtr) { + *sizePtr = n; + } + return result; +} #define TclBN_mp_add mp_add #define TclBN_mp_add_d mp_add_d @@ -1206,7 +1215,7 @@ const TclStubs tclStubs = { Tcl_DictObjPut, /* 494 */ Tcl_DictObjGet, /* 495 */ Tcl_DictObjRemove, /* 496 */ - Tcl_DictObjSize, /* 497 */ + TclDictObjSize_, /* 497 */ Tcl_DictObjFirst, /* 498 */ Tcl_DictObjNext, /* 499 */ Tcl_DictObjDone, /* 500 */ @@ -1372,6 +1381,7 @@ const TclStubs tclStubs = { Tcl_AsyncMarkFromSignal, /* 660 */ Tcl_ListObjGetElements, /* 661 */ Tcl_ListObjLength, /* 662 */ + Tcl_DictObjSize, /* 663 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclVar.c b/generic/tclVar.c index e9c0134..fe6fda3 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -3974,7 +3974,7 @@ ArraySetCmd( Tcl_DictSearch search; int done; - if (Tcl_DictObjSize(interp, arrayElemObj, &done) != TCL_OK) { + if (TclDictObjSize_(interp, arrayElemObj, &done) != TCL_OK) { return TCL_ERROR; } if (done == 0) { diff --git a/generic/tclZlib.c b/generic/tclZlib.c index b874750..89ffc47 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -2492,7 +2492,7 @@ ZlibPushSubcmd( switch ((enum pushOptionsEnum) option) { case poHeader: headerObj = objv[i]; - if (Tcl_DictObjSize(interp, headerObj, &dummy) != TCL_OK) { + if (TclDictObjSize_(interp, headerObj, &dummy) != TCL_OK) { goto genericOptionError; } break; -- cgit v0.12