diff options
| author | dkf <donal.k.fellows@manchester.ac.uk> | 2023-05-19 12:02:49 (GMT) |
|---|---|---|
| committer | dkf <donal.k.fellows@manchester.ac.uk> | 2023-05-19 12:02:49 (GMT) |
| commit | b0f19e41f2c3e29950af3fb586b0f7a7f9112b2c (patch) | |
| tree | b744be174ece6b694da314852f5e1143ba086c48 /generic | |
| parent | fea912c676a71b362b8c7d77e3f4242e374de1bb (diff) | |
| parent | e47cbdc798e9744e9a89840e9ace30186872a762 (diff) | |
| download | tcl-b0f19e41f2c3e29950af3fb586b0f7a7f9112b2c.zip tcl-b0f19e41f2c3e29950af3fb586b0f7a7f9112b2c.tar.gz tcl-b0f19e41f2c3e29950af3fb586b0f7a7f9112b2c.tar.bz2 | |
merge core-8-branch
Diffstat (limited to 'generic')
| -rw-r--r-- | generic/tcl.h | 6 | ||||
| -rw-r--r-- | generic/tclCmdAH.c | 2 | ||||
| -rw-r--r-- | generic/tclCompCmdsSZ.c | 2 | ||||
| -rw-r--r-- | generic/tclCompExpr.c | 4 | ||||
| -rw-r--r-- | generic/tclEncoding.c | 13 | ||||
| -rw-r--r-- | generic/tclHistory.c | 5 | ||||
| -rw-r--r-- | generic/tclIO.c | 24 | ||||
| -rw-r--r-- | generic/tclIO.h | 7 | ||||
| -rw-r--r-- | generic/tclInt.h | 162 | ||||
| -rw-r--r-- | generic/tclOOInt.h | 6 | ||||
| -rw-r--r-- | generic/tclScan.c | 15 | ||||
| -rw-r--r-- | generic/tclStringObj.c | 103 | ||||
| -rw-r--r-- | generic/tclStringRep.h | 44 | ||||
| -rw-r--r-- | generic/tclStubInit.c | 2 | ||||
| -rw-r--r-- | generic/tclTest.c | 189 | ||||
| -rw-r--r-- | generic/tclTestObj.c | 56 | ||||
| -rw-r--r-- | generic/tclTestProcBodyObj.c | 6 | ||||
| -rw-r--r-- | generic/tclThreadTest.c | 8 | ||||
| -rw-r--r-- | generic/tclTomMathDecls.h | 12 |
19 files changed, 353 insertions, 313 deletions
diff --git a/generic/tcl.h b/generic/tcl.h index f8a34c0..2b6c947 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2176,7 +2176,11 @@ typedef struct Tcl_EncodingType { #define TCL_ENCODING_CHAR_LIMIT 0x10 /* Internal use bits, do not define bits in this space. See above comment */ #define TCL_ENCODING_INTERNAL_USE_MASK 0xFF00 -/* Reserve top byte for profile values (disjoint, not a mask) */ +/* + * Reserve top byte for profile values (disjoint, not a mask). In case of + * changes, ensure ENCODING_PROFILE_* macros in tclInt.h are modified if + * necessary. + */ #define TCL_ENCODING_PROFILE_TCL8 0x01000000 #define TCL_ENCODING_PROFILE_STRICT 0x02000000 #define TCL_ENCODING_PROFILE_REPLACE 0x03000000 diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 2f50959..aa7a9b0 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -675,7 +675,7 @@ EncodingConvertfromObjCmd( * Convert the string into a byte array in 'ds'. */ #if !defined(TCL_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9) - if (CHANNEL_PROFILE_GET(flags) == TCL_ENCODING_PROFILE_TCL8) { + if (ENCODING_PROFILE_GET(flags) == TCL_ENCODING_PROFILE_TCL8) { /* Permits high bits to be non-0 in byte array (Tcl 8 style) */ bytesPtr = (char *) Tcl_GetByteArrayFromObj(data, &length); } else diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 5146b33..5d190a1 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -2661,7 +2661,7 @@ TclCompileTailcallCmd( Tcl_Token *tokenPtr = parsePtr->tokenPtr; int i; - if (parsePtr->numWords < 2 || parsePtr->numWords > 256 + if (parsePtr->numWords < 2 || parsePtr->numWords >= 256 || envPtr->procPtr == NULL) { return TCL_ERROR; } diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 9791cb3..a295e41 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -2091,9 +2091,9 @@ ParseLexeme( if (end < start + numBytes && !TclIsBareword(*end)) { number: - TclInitStringRep(literal, start, end-start); *lexemePtr = NUMBER; if (literalPtr) { + TclInitStringRep(literal, start, end-start); *literalPtr = literal; } else { Tcl_DecrRefCount(literal); @@ -2165,7 +2165,7 @@ ParseLexeme( } *lexemePtr = BAREWORD; if (literalPtr) { - Tcl_SetStringObj(literal, start, (int) (end-start)); + Tcl_SetStringObj(literal, start, end-start); *literalPtr = literal; } else { Tcl_DecrRefCount(literal); diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 647ed68..32878b0 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -10,7 +10,6 @@ */ #include "tclInt.h" -#include "tclIO.h" typedef size_t (LengthProc)(const char *src); @@ -200,10 +199,10 @@ static struct TclEncodingProfiles { {"tcl8", TCL_ENCODING_PROFILE_TCL8}, }; #define PROFILE_STRICT(flags_) \ - (CHANNEL_PROFILE_GET(flags_) == TCL_ENCODING_PROFILE_STRICT) + (ENCODING_PROFILE_GET(flags_) == TCL_ENCODING_PROFILE_STRICT) #define PROFILE_REPLACE(flags_) \ - (CHANNEL_PROFILE_GET(flags_) == TCL_ENCODING_PROFILE_REPLACE) + (ENCODING_PROFILE_GET(flags_) == TCL_ENCODING_PROFILE_REPLACE) #define UNICODE_REPLACE_CHAR ((Tcl_UniChar)0xFFFD) #define SURROGATE(c_) (((c_) & ~0x7FF) == 0xD800) @@ -2527,7 +2526,7 @@ UtfToUtfProc( flags |= PTR2INT(clientData); dstEnd = dst + dstLen - ((flags & ENCODING_UTF) ? TCL_UTF_MAX : 6); - profile = CHANNEL_PROFILE_GET(flags); + profile = ENCODING_PROFILE_GET(flags); for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) { if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { @@ -4545,9 +4544,9 @@ TclEncodingProfileIdToName( int TclEncodingSetProfileFlags(int flags) { if (flags & TCL_ENCODING_STOPONERROR) { - CHANNEL_PROFILE_SET(flags, TCL_ENCODING_PROFILE_STRICT); + ENCODING_PROFILE_SET(flags, TCL_ENCODING_PROFILE_STRICT); } else { - int profile = CHANNEL_PROFILE_GET(flags); + int profile = ENCODING_PROFILE_GET(flags); switch (profile) { case TCL_ENCODING_PROFILE_TCL8: case TCL_ENCODING_PROFILE_STRICT: @@ -4555,7 +4554,7 @@ int TclEncodingSetProfileFlags(int flags) break; case 0: /* Unspecified by caller */ default: - CHANNEL_PROFILE_SET(flags, TCL_ENCODING_PROFILE_TCL8); + ENCODING_PROFILE_SET(flags, TCL_ENCODING_PROFILE_TCL8); break; } } diff --git a/generic/tclHistory.c b/generic/tclHistory.c index 02e15a0..f7d9ec8 100644 --- a/generic/tclHistory.c +++ b/generic/tclHistory.c @@ -58,8 +58,9 @@ Tcl_RecordAndEval( const char *cmd, /* Command to record. */ int flags) /* Additional flags. TCL_NO_EVAL means only * record: don't execute command. - * TCL_EVAL_GLOBAL means use Tcl_GlobalEval - * instead of Tcl_Eval. */ + * TCL_EVAL_GLOBAL means evaluate the script + * in global variable context instead of the + * current procedure. */ { Tcl_Obj *cmdPtr; int result; diff --git a/generic/tclIO.c b/generic/tclIO.c index 92ad97e..57c1554 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1702,11 +1702,11 @@ Tcl_CreateChannel( } statePtr->inputEncodingState = NULL; statePtr->inputEncodingFlags = TCL_ENCODING_START; - CHANNEL_PROFILE_SET(statePtr->inputEncodingFlags, + ENCODING_PROFILE_SET(statePtr->inputEncodingFlags, TCL_ENCODING_PROFILE_TCL8); statePtr->outputEncodingState = NULL; statePtr->outputEncodingFlags = TCL_ENCODING_START; - CHANNEL_PROFILE_SET(statePtr->outputEncodingFlags, + ENCODING_PROFILE_SET(statePtr->outputEncodingFlags, TCL_ENCODING_PROFILE_TCL8); /* @@ -8067,7 +8067,7 @@ Tcl_GetChannelOption( Tcl_DStringAppendElement(dsPtr, "-profile"); } /* Note currently input and output profiles are same */ - profile = CHANNEL_PROFILE_GET(statePtr->inputEncodingFlags); + profile = ENCODING_PROFILE_GET(statePtr->inputEncodingFlags); profileName = TclEncodingProfileIdToName(interp, profile); if (profileName == NULL) { return TCL_ERROR; @@ -8273,12 +8273,12 @@ Tcl_SetChannelOption( Tcl_FreeEncoding(statePtr->encoding); statePtr->encoding = encoding; statePtr->inputEncodingState = NULL; - profile = CHANNEL_PROFILE_GET(statePtr->inputEncodingFlags); + profile = ENCODING_PROFILE_GET(statePtr->inputEncodingFlags); statePtr->inputEncodingFlags = TCL_ENCODING_START; - CHANNEL_PROFILE_SET(statePtr->inputEncodingFlags, profile); + ENCODING_PROFILE_SET(statePtr->inputEncodingFlags, profile); statePtr->outputEncodingState = NULL; statePtr->outputEncodingFlags = TCL_ENCODING_START; - CHANNEL_PROFILE_SET(statePtr->outputEncodingFlags, profile); /* Same as input */ + ENCODING_PROFILE_SET(statePtr->outputEncodingFlags, profile); /* Same as input */ ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA|CHANNEL_ENCODING_ERROR); UpdateInterest(chanPtr); return TCL_OK; @@ -8342,8 +8342,8 @@ Tcl_SetChannelOption( if (TclEncodingProfileNameToId(interp, newValue, &profile) != TCL_OK) { return TCL_ERROR; } - CHANNEL_PROFILE_SET(statePtr->inputEncodingFlags, profile); - CHANNEL_PROFILE_SET(statePtr->outputEncodingFlags, profile); + ENCODING_PROFILE_SET(statePtr->inputEncodingFlags, profile); + ENCODING_PROFILE_SET(statePtr->outputEncodingFlags, profile); ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA|CHANNEL_ENCODING_ERROR); return TCL_OK; } else if (HaveOpt(1, "-translation")) { @@ -9470,8 +9470,8 @@ TclCopyChannel( && inStatePtr->inputTranslation == TCL_TRANSLATE_LF && outStatePtr->outputTranslation == TCL_TRANSLATE_LF && inStatePtr->encoding == outStatePtr->encoding - && CHANNEL_PROFILE_GET(inStatePtr->inputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8 - && CHANNEL_PROFILE_GET(outStatePtr->outputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8; + && ENCODING_PROFILE_GET(inStatePtr->inputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8 + && ENCODING_PROFILE_GET(outStatePtr->outputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8; /* * Allocate a new CopyState to maintain info about the current copy in @@ -9799,8 +9799,8 @@ CopyData( inBinary = (inStatePtr->encoding == NULL); outBinary = (outStatePtr->encoding == NULL); sameEncoding = inStatePtr->encoding == outStatePtr->encoding - && CHANNEL_PROFILE_GET(inStatePtr->inputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8 - && CHANNEL_PROFILE_GET(outStatePtr->outputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8; + && ENCODING_PROFILE_GET(inStatePtr->inputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8 + && ENCODING_PROFILE_GET(outStatePtr->outputEncodingFlags) == TCL_ENCODING_PROFILE_TCL8; if (!(inBinary || sameEncoding)) { TclNewObj(bufObj); diff --git a/generic/tclIO.h b/generic/tclIO.h index 399acdb..729db5d 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -286,13 +286,6 @@ typedef struct ChannelState { #define CHANNEL_CLOSEDWRITE (1<<21) /* Channel write side has been closed. * No further Tcl-level write IO on * the channel is allowed. */ -#define CHANNEL_PROFILE_MASK 0xFF000000 -#define CHANNEL_PROFILE_GET(flags_) ((flags_) & CHANNEL_PROFILE_MASK) -#define CHANNEL_PROFILE_SET(flags_, profile_) \ - do { \ - (flags_) &= ~CHANNEL_PROFILE_MASK; \ - (flags_) |= profile_; \ - } while (0) /* * The length of time to wait between synthetic timer events. Must be zero or diff --git a/generic/tclInt.h b/generic/tclInt.h index 2d3a0fc..bc16cb2 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -232,9 +232,9 @@ typedef struct Tcl_Ensemble Tcl_Ensemble; typedef struct NamespacePathEntry NamespacePathEntry; /* - * Special hash table for variables: this is just a Tcl_HashTable with an nsPtr - * field added at the end: in this way variables can find their namespace - * without having to copy a pointer in their struct: they can access it via + * Special hashtable for variables: This is just a Tcl_HashTable with a nsPtr + * field added at the end, so that variables can find their namespace + * without having to copy a pointer in their struct by accessing them via * their hPtr->tablePtr. */ @@ -881,19 +881,22 @@ typedef struct VarInHash { * Macros for direct variable access by TEBC. */ -#define TclIsVarDirectReadable(varPtr) \ - ( !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ)) \ - && (varPtr)->value.objPtr) +#define TclIsVarTricky(varPtr,trickyFlags) \ + ((varPtr)->flags & (VAR_ARRAY|VAR_LINK|trickyFlags)) + +#define TclIsVarDirectReadable(varPtr) \ + ( (!TclIsVarTricky(varPtr,VAR_TRACED_READ)) \ + && (varPtr)->value.objPtr) #define TclIsVarDirectWritable(varPtr) \ - !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_WRITE|VAR_DEAD_HASH)) + (!TclIsVarTricky(varPtr,VAR_TRACED_WRITE|VAR_DEAD_HASH)) #define TclIsVarDirectUnsettable(varPtr) \ - !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ|VAR_TRACED_WRITE|VAR_TRACED_UNSET|VAR_DEAD_HASH)) + (!TclIsVarTricky(varPtr,VAR_TRACED_READ|VAR_TRACED_WRITE|VAR_TRACED_UNSET|VAR_DEAD_HASH)) #define TclIsVarDirectModifyable(varPtr) \ - ( !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ|VAR_TRACED_WRITE)) \ - && (varPtr)->value.objPtr) + ( (!TclIsVarTricky(varPtr,VAR_TRACED_READ|VAR_TRACED_WRITE)) \ + && (varPtr)->value.objPtr) #define TclIsVarDirectReadable2(varPtr, arrayPtr) \ (TclIsVarDirectReadable(varPtr) &&\ @@ -2484,7 +2487,7 @@ typedef struct ListStore { / sizeof(Tcl_Obj *))) /* Memory size needed for a ListStore to hold numSlots_ elements */ #define LIST_SIZE(numSlots_) \ - ((int)(offsetof(ListStore, slots) + ((numSlots_) * sizeof(Tcl_Obj *)))) + ((Tcl_Size)(offsetof(ListStore, slots) + ((numSlots_) * sizeof(Tcl_Obj *)))) /* * ListSpan -- @@ -2573,6 +2576,7 @@ typedef struct ListRep { (((objv_) = &ListObjStorePtr(listObj_)->slots[ListObjStart(listObj_)]), \ (ListObjLength(listObj_, (objc_)))) + /* * Returns 1/0 whether the internal representation (not the Tcl_Obj itself) * is shared. Note by intent this only checks for sharing of ListStore, @@ -2859,6 +2863,22 @@ typedef struct ProcessGlobalValue { #define TCL_PARSE_NO_UNDERSCORE 128 /* Reject underscore digit separator */ + +/* + *---------------------------------------------------------------------- + * Internal convenience macros for manipulating encoding flags. See + * TCL_ENCODING_PROFILE_* in tcl.h + *---------------------------------------------------------------------- + */ + +#define ENCODING_PROFILE_MASK 0xFF000000 +#define ENCODING_PROFILE_GET(flags_) ((flags_) & ENCODING_PROFILE_MASK) +#define ENCODING_PROFILE_SET(flags_, profile_) \ + do { \ + (flags_) &= ~ENCODING_PROFILE_MASK; \ + (flags_) |= profile_; \ + } while (0) + /* *---------------------------------------------------------------- * Variables shared among Tcl modules but not used by the outside world. @@ -3049,12 +3069,12 @@ struct Tcl_LoadHandle_ { */ MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr, - const unsigned char *bytes, int len); + const unsigned char *bytes, Tcl_Size len); MODULE_SCOPE int TclNREvalCmd(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); -MODULE_SCOPE void TclAdvanceContinuations(int *line, int **next, +MODULE_SCOPE void TclAdvanceContinuations(Tcl_Size *line, int **next, int loc); -MODULE_SCOPE void TclAdvanceLines(int *line, const char *start, +MODULE_SCOPE void TclAdvanceLines(Tcl_Size *line, const char *start, const char *end); MODULE_SCOPE void TclArgumentEnter(Tcl_Interp *interp, Tcl_Obj *objv[], int objc, CmdFrame *cf); @@ -3062,7 +3082,7 @@ MODULE_SCOPE void TclArgumentRelease(Tcl_Interp *interp, Tcl_Obj *objv[], int objc); MODULE_SCOPE void TclArgumentBCEnter(Tcl_Interp *interp, Tcl_Obj *objv[], int objc, - void *codePtr, CmdFrame *cfPtr, int cmd, int pc); + void *codePtr, CmdFrame *cfPtr, int cmd, Tcl_Size pc); MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp, CmdFrame *cfPtr); MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj, @@ -3072,8 +3092,8 @@ MODULE_SCOPE int TclAsyncNotifier(int sigNumber, Tcl_ThreadId threadId, MODULE_SCOPE void TclAsyncMarkFromNotifier(void); MODULE_SCOPE double TclBignumToDouble(const void *bignum); MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string, - int strLen, const unsigned char *pattern, - int ptnLen, int flags); + Tcl_Size strLen, const unsigned char *pattern, + Tcl_Size ptnLen, int flags); MODULE_SCOPE double TclCeil(const void *a); MODULE_SCOPE void TclChannelPreserve(Tcl_Channel chan); MODULE_SCOPE void TclChannelRelease(Tcl_Channel chan); @@ -3088,14 +3108,14 @@ MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd; MODULE_SCOPE Tcl_NRPostProc TclClearRootEnsemble; MODULE_SCOPE int TclCompareTwoNumbers(Tcl_Obj *valuePtr, Tcl_Obj *value2Ptr); -MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num, +MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, Tcl_Size num, int *loc); MODULE_SCOPE void TclContinuationsEnterDerived(Tcl_Obj *objPtr, int start, int *clNext); MODULE_SCOPE ContLineLoc *TclContinuationsGet(Tcl_Obj *objPtr); MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr, Tcl_Obj *originObjPtr); -MODULE_SCOPE int TclConvertElement(const char *src, int length, +MODULE_SCOPE Tcl_Size TclConvertElement(const char *src, Tcl_Size length, char *dst, int flags); MODULE_SCOPE Tcl_Command TclCreateObjCommandInNs(Tcl_Interp *interp, const char *cmdName, Tcl_Namespace *nsPtr, @@ -3107,12 +3127,12 @@ MODULE_SCOPE Tcl_Command TclCreateEnsembleInNs(Tcl_Interp *interp, MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); MODULE_SCOPE void TclDeleteNamespaceChildren(Namespace *nsPtr); MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, - const char *dict, int dictLength, + const char *dict, Tcl_Size dictLength, const char **elementPtr, const char **nextPtr, - int *sizePtr, int *literalPtr); + Tcl_Size *sizePtr, int *literalPtr); /* TIP #280 - Modified token based evaluation, with line information. */ MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script, - int numBytes, int flags, int line, + Tcl_Size numBytes, int flags, Tcl_Size line, int *clNextOuter, const char *outerScript); MODULE_SCOPE Tcl_ObjCmdProc TclFileAttrsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileCopyCmd; @@ -3134,7 +3154,7 @@ MODULE_SCOPE char * TclDStringAppendObj(Tcl_DString *dsPtr, MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr, Tcl_DString *toAppendPtr); MODULE_SCOPE Tcl_Obj *const *TclFetchEnsembleRoot(Tcl_Interp *interp, - Tcl_Obj *const *objv, int objc, int *objcPtr); + Tcl_Obj *const *objv, Tcl_Size objc, Tcl_Size *objcPtr); MODULE_SCOPE Tcl_Obj *const *TclEnsembleGetRewriteValues(Tcl_Interp *interp); MODULE_SCOPE Tcl_Namespace *TclEnsureNamespace(Tcl_Interp *interp, Tcl_Namespace *namespacePtr); @@ -3218,7 +3238,7 @@ MODULE_SCOPE void TclInitObjSubsystem(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); MODULE_SCOPE int TclIsDigitProc(int byte); MODULE_SCOPE int TclIsBareword(int byte); -MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[], +MODULE_SCOPE Tcl_Obj * TclJoinPath(Tcl_Size elements, Tcl_Obj * const objv[], int forceRelative); MODULE_SCOPE int MakeTildeRelativePath(Tcl_Interp *interp, const char *user, const char *subPath, Tcl_DString *dsPtr); @@ -3231,25 +3251,25 @@ MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *argPtr); MODULE_SCOPE Tcl_Obj * TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, - int indexCount, Tcl_Obj *const indexArray[]); + Tcl_Size indexCount, Tcl_Obj *const indexArray[]); /* TIP #280 */ -MODULE_SCOPE void TclListLines(Tcl_Obj *listObj, int line, int n, +MODULE_SCOPE void TclListLines(Tcl_Obj *listObj, Tcl_Size line, int n, int *lines, Tcl_Obj *const *elems); MODULE_SCOPE Tcl_Obj * TclListObjCopy(Tcl_Interp *interp, Tcl_Obj *listPtr); MODULE_SCOPE int TclListObjAppendElements(Tcl_Interp *interp, - Tcl_Obj *toObj, int elemCount, + Tcl_Obj *toObj, Tcl_Size elemCount, Tcl_Obj *const elemObjv[]); MODULE_SCOPE Tcl_Obj * TclListObjRange(Tcl_Interp *interp, Tcl_Obj *listPtr, - int fromIdx, int toIdx); + Tcl_Size fromIdx, Tcl_Size toIdx); MODULE_SCOPE Tcl_Obj * TclLsetList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *indexPtr, Tcl_Obj *valuePtr); MODULE_SCOPE Tcl_Obj * TclLsetFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, - int indexCount, Tcl_Obj *const indexArray[], + Tcl_Size indexCount, Tcl_Obj *const indexArray[], Tcl_Obj *valuePtr); MODULE_SCOPE Tcl_Command TclMakeEnsemble(Tcl_Interp *interp, const char *name, const EnsembleImplMap map[]); MODULE_SCOPE int TclMakeSafe(Tcl_Interp *interp); -MODULE_SCOPE int TclMaxListLength(const char *bytes, int numBytes, +MODULE_SCOPE Tcl_Size TclMaxListLength(const char *bytes, Tcl_Size numBytes, const char **endPtr); MODULE_SCOPE int TclMergeReturnOptions(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Tcl_Obj **optionsPtrPtr, @@ -3267,15 +3287,15 @@ MODULE_SCOPE int TclObjInvokeNamespace(Tcl_Interp *interp, MODULE_SCOPE int TclObjUnsetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags); MODULE_SCOPE int TclParseBackslash(const char *src, - int numBytes, int *readPtr, char *dst); -MODULE_SCOPE int TclParseHex(const char *src, int numBytes, + Tcl_Size numBytes, Tcl_Size *readPtr, char *dst); +MODULE_SCOPE int TclParseHex(const char *src, Tcl_Size numBytes, int *resultPtr); MODULE_SCOPE int TclParseNumber(Tcl_Interp *interp, Tcl_Obj *objPtr, const char *expected, const char *bytes, - int numBytes, const char **endPtrPtr, int flags); + Tcl_Size numBytes, const char **endPtrPtr, int flags); MODULE_SCOPE void TclParseInit(Tcl_Interp *interp, const char *string, - int numBytes, Tcl_Parse *parsePtr); -MODULE_SCOPE int TclParseAllWhiteSpace(const char *src, int numBytes); + Tcl_Size numBytes, Tcl_Parse *parsePtr); +MODULE_SCOPE Tcl_Size TclParseAllWhiteSpace(const char *src, Tcl_Size numBytes); MODULE_SCOPE int TclProcessReturn(Tcl_Interp *interp, int code, int level, Tcl_Obj *returnOpts); MODULE_SCOPE int TclpObjLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); @@ -3283,7 +3303,7 @@ MODULE_SCOPE Tcl_Obj * TclpTempFileName(void); MODULE_SCOPE Tcl_Obj * TclpTempFileNameForLibrary(Tcl_Interp *interp, Tcl_Obj* pathPtr); MODULE_SCOPE Tcl_Obj * TclNewFSPathObj(Tcl_Obj *dirPtr, const char *addStrRep, - int len); + Tcl_Size len); MODULE_SCOPE void TclpAlertNotifier(void *clientData); MODULE_SCOPE void *TclpNotifierData(void); MODULE_SCOPE void TclpServiceModeHook(int mode); @@ -3310,7 +3330,7 @@ MODULE_SCOPE int TclCreateSocketAddress(Tcl_Interp *interp, MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, void *clientData, int stackSize, int flags); -MODULE_SCOPE int TclpFindVariable(const char *name, int *lengthPtr); +MODULE_SCOPE Tcl_Size TclpFindVariable(const char *name, Tcl_Size *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, TCL_HASH_TYPE *lengthPtr, Tcl_Encoding *encodingPtr); MODULE_SCOPE void TclpInitLock(void); @@ -3325,15 +3345,15 @@ MODULE_SCOPE int TclpMatchFiles(Tcl_Interp *interp, char *separators, MODULE_SCOPE int TclpObjNormalizePath(Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); MODULE_SCOPE void TclpNativeJoinPath(Tcl_Obj *prefix, const char *joining); -MODULE_SCOPE Tcl_Obj * TclpNativeSplitPath(Tcl_Obj *pathPtr, int *lenPtr); +MODULE_SCOPE Tcl_Obj * TclpNativeSplitPath(Tcl_Obj *pathPtr, Tcl_Size *lenPtr); MODULE_SCOPE Tcl_PathType TclpGetNativePathType(Tcl_Obj *pathPtr, - int *driveNameLengthPtr, Tcl_Obj **driveNameRef); + Tcl_Size *driveNameLengthPtr, Tcl_Obj **driveNameRef); MODULE_SCOPE int TclCrossFilesystemCopy(Tcl_Interp *interp, Tcl_Obj *source, Tcl_Obj *target); MODULE_SCOPE int TclpMatchInDirectory(Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); -MODULE_SCOPE void *TclpGetNativeCwd(void *clientData); +MODULE_SCOPE void *TclpGetNativeCwd(void *clientData); MODULE_SCOPE Tcl_FSDupInternalRepProc TclNativeDupInternalRep; MODULE_SCOPE Tcl_Obj * TclpObjLink(Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkType); @@ -3358,9 +3378,9 @@ MODULE_SCOPE void TclRememberJoinableThread(Tcl_ThreadId id); MODULE_SCOPE void TclRememberMutex(Tcl_Mutex *mutex); MODULE_SCOPE void TclRemoveScriptLimitCallbacks(Tcl_Interp *interp); MODULE_SCOPE int TclReToGlob(Tcl_Interp *interp, const char *reStr, - int reStrLen, Tcl_DString *dsPtr, int *flagsPtr, + Tcl_Size reStrLen, Tcl_DString *dsPtr, int *flagsPtr, int *quantifiersFoundPtr); -MODULE_SCOPE TCL_HASH_TYPE TclScanElement(const char *string, int length, +MODULE_SCOPE TCL_HASH_TYPE TclScanElement(const char *string, Tcl_Size length, char *flagPtr); MODULE_SCOPE void TclSetBgErrorHandler(Tcl_Interp *interp, Tcl_Obj *cmdPrefix); @@ -3375,37 +3395,37 @@ MODULE_SCOPE void TclSetProcessGlobalValue(ProcessGlobalValue *pgvPtr, Tcl_Obj *newValue, Tcl_Encoding encoding); MODULE_SCOPE void TclSignalExitThread(Tcl_ThreadId id, int result); MODULE_SCOPE void TclSpellFix(Tcl_Interp *interp, - Tcl_Obj *const *objv, int objc, int subIdx, + Tcl_Obj *const *objv, Tcl_Size objc, Tcl_Size subIdx, Tcl_Obj *bad, Tcl_Obj *fix); MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr, - int numBytes); + Tcl_Size numBytes); typedef int (*memCmpFn_t)(const void*, const void*, size_t); MODULE_SCOPE int TclStringCmp(Tcl_Obj *value1Ptr, Tcl_Obj *value2Ptr, - int checkEq, int nocase, int reqlength); + int checkEq, int nocase, Tcl_Size reqlength); MODULE_SCOPE int TclStringCmpOpts(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int *nocase, - int *reqlength); -MODULE_SCOPE int TclStringMatch(const char *str, int strLen, + Tcl_Size *reqlength); +MODULE_SCOPE int TclStringMatch(const char *str, Tcl_Size strLen, const char *pattern, int ptnLen, int flags); MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj, Tcl_Obj *patternObj, int flags); MODULE_SCOPE void TclSubstCompile(Tcl_Interp *interp, const char *bytes, - int numBytes, int flags, int line, + Tcl_Size numBytes, int flags, Tcl_Size line, struct CompileEnv *envPtr); -MODULE_SCOPE int TclSubstOptions(Tcl_Interp *interp, int numOpts, +MODULE_SCOPE int TclSubstOptions(Tcl_Interp *interp, Tcl_Size numOpts, Tcl_Obj *const opts[], int *flagPtr); MODULE_SCOPE void TclSubstParse(Tcl_Interp *interp, const char *bytes, - int numBytes, int flags, Tcl_Parse *parsePtr, + Tcl_Size numBytes, int flags, Tcl_Parse *parsePtr, Tcl_InterpState *statePtr); MODULE_SCOPE int TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, - int count, int *tokensLeftPtr, int line, + Tcl_Size count, int *tokensLeftPtr, Tcl_Size line, int *clNextOuter, const char *outerScript); -MODULE_SCOPE int TclTrim(const char *bytes, int numBytes, - const char *trim, int numTrim, int *trimRight); -MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes, - const char *trim, int numTrim); -MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes, - const char *trim, int numTrim); +MODULE_SCOPE Tcl_Size TclTrim(const char *bytes, Tcl_Size numBytes, + const char *trim, Tcl_Size numTrim, Tcl_Size *trimRight); +MODULE_SCOPE Tcl_Size TclTrimLeft(const char *bytes, Tcl_Size numBytes, + const char *trim, Tcl_Size numTrim); +MODULE_SCOPE Tcl_Size TclTrimRight(const char *bytes, Tcl_Size numBytes, + const char *trim, Tcl_Size numTrim); MODULE_SCOPE const char*TclGetCommandTypeName(Tcl_Command command); MODULE_SCOPE void TclRegisterCommandTypeName( Tcl_ObjCmdProc *implementationProc, @@ -3459,7 +3479,7 @@ MODULE_SCOPE void TclpThreadDeleteKey(void *keyPtr); MODULE_SCOPE void TclpThreadSetGlobalTSD(void *tsdKeyPtr, void *ptr); MODULE_SCOPE void * TclpThreadGetGlobalTSD(void *tsdKeyPtr); MODULE_SCOPE void TclErrorStackResetIf(Tcl_Interp *interp, - const char *msg, int length); + const char *msg, Tcl_Size length); /* Tip 430 */ MODULE_SCOPE int TclZipfs_Init(Tcl_Interp *interp); @@ -3549,7 +3569,7 @@ MODULE_SCOPE int TclDictWithFinish(Tcl_Interp *interp, Var *varPtr, Tcl_Obj *part2Ptr, int index, int pathc, Tcl_Obj *const pathv[], Tcl_Obj *keysPtr); MODULE_SCOPE Tcl_Obj * TclDictWithInit(Tcl_Interp *interp, Tcl_Obj *dictPtr, - int pathc, Tcl_Obj *const pathv[]); + Tcl_Size pathc, Tcl_Obj *const pathv[]); MODULE_SCOPE Tcl_ObjCmdProc Tcl_DisassembleObjCmd; /* Assemble command function */ @@ -4072,16 +4092,16 @@ MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp, * candidates for public interface. */ -MODULE_SCOPE Tcl_Obj * TclStringCat(Tcl_Interp *interp, int objc, +MODULE_SCOPE Tcl_Obj * TclStringCat(Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[], int flags); MODULE_SCOPE Tcl_Obj * TclStringFirst(Tcl_Obj *needle, Tcl_Obj *haystack, - int start); + Tcl_Size start); MODULE_SCOPE Tcl_Obj * TclStringLast(Tcl_Obj *needle, Tcl_Obj *haystack, - int last); + Tcl_Size last); MODULE_SCOPE Tcl_Obj * TclStringRepeat(Tcl_Interp *interp, Tcl_Obj *objPtr, - int count, int flags); + Tcl_Size count, int flags); MODULE_SCOPE Tcl_Obj * TclStringReplace(Tcl_Interp *interp, Tcl_Obj *objPtr, - int first, int count, Tcl_Obj *insertPtr, + Tcl_Size first, Tcl_Size count, Tcl_Obj *insertPtr, int flags); MODULE_SCOPE Tcl_Obj * TclStringReverse(Tcl_Obj *objPtr, int flags); @@ -4196,7 +4216,7 @@ MODULE_SCOPE Tcl_Obj * TclGetArrayDefault(Var *arrayPtr); MODULE_SCOPE int TclIndexEncode(Tcl_Interp *interp, Tcl_Obj *objPtr, int before, int after, int *indexPtr); -MODULE_SCOPE int TclIndexDecode(int encoded, int endValue); +MODULE_SCOPE Tcl_Size TclIndexDecode(int encoded, Tcl_Size endValue); /* Constants used in index value encoding routines. */ #define TCL_INDEX_END ((Tcl_Size)-2) @@ -4449,9 +4469,6 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, # define TclDecrRefCount(objPtr) \ Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__) -# define TclNewListObjDirect(objc, objv) \ - TclDbNewListObjDirect(objc, objv, __FILE__, __LINE__) - #undef USE_THREAD_ALLOC #endif /* TCL_MEM_DEBUG */ @@ -5176,7 +5193,7 @@ typedef struct NRE_callback { #define TCLNR_FREE(interp, ptr) TclSmallFreeEx((interp), (ptr)) #else #define TCLNR_ALLOC(interp, ptr) \ - ((ptr) = ((void *)ckalloc(sizeof(NRE_callback)))) + ((ptr) = (void *)ckalloc(sizeof(NRE_callback))) #define TCLNR_FREE(interp, ptr) ckfree(ptr) #endif @@ -5189,11 +5206,10 @@ typedef struct NRE_callback { #include "tclIntDecls.h" #include "tclIntPlatDecls.h" - #if !defined(USE_TCL_STUBS) && !defined(TCL_MEM_DEBUG) -#define Tcl_AttemptAlloc(size) TclpAlloc(size) -#define Tcl_AttemptRealloc(ptr, size) TclpRealloc((ptr), (size)) -#define Tcl_Free(ptr) TclpFree(ptr) +#define Tcl_AttemptAlloc TclpAlloc +#define Tcl_AttemptRealloc TclpRealloc +#define Tcl_Free TclpFree #endif /* diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index ed98af7..851623d 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -619,12 +619,12 @@ MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr); /* * A variation where the array is an array of structs. There's no issue with * possible NULLs; every element of the array will be iterated over and the - * varable set to a pointer to each of those elements in turn. - * REQUIRES DECLARATION: int i; + * variable set to a pointer to each of those elements in turn. + * REQUIRES DECLARATION: int i; See [96551aca55] for more FOREACH_STRUCT details. */ #define FOREACH_STRUCT(var,ary) \ - for(i=0 ; var=&((ary).list[i]), i<(ary).num; i++) + if (i=0, (ary).num>0) for(; var=&((ary).list[i]), i<(ary).num; i++) /* * Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS diff --git a/generic/tclScan.c b/generic/tclScan.c index c200fa0..f332d24 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -306,7 +306,7 @@ ValidateFormat( * format string. */ - value = strtoul(format-1, &end, 10); /* INTL: "C" locale. */ + unsigned long ul = strtoul(format-1, &end, 10); /* INTL: "C" locale. */ if (*end != '$') { goto notXpg; } @@ -316,17 +316,20 @@ ValidateFormat( if (gotSequential) { goto mixedXPG; } - objIndex = value - 1; - if ((objIndex < 0) || (numVars && (objIndex >= numVars))) { + if (ul == 0 || ul >= INT_MAX) { + goto badIndex; + } + objIndex = (int) ul - 1; + if (numVars && (objIndex >= numVars)) { goto badIndex; } else if (numVars == 0) { /* * In the case where no vars are specified, the user can * specify %9999$ legally, so we have to consider special - * rules for growing the assign array. 'value' is guaranteed - * to be > 0. + * rules for growing the assign array. 'ul' is guaranteed + * to be > 0 and < INT_MAX as per checks above. */ - xpgSize = (xpgSize > value) ? xpgSize : value; + xpgSize = (xpgSize > (int)ul) ? xpgSize : (int)ul; } goto xpgCheckDone; } diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index d3a17d1..0e47487 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1,29 +1,27 @@ /* * tclStringObj.c -- * - * This file contains functions that implement string operations on Tcl - * objects. Some string operations work with UTF strings and others - * require Unicode format. Functions that require knowledge of the width - * of each character, such as indexing, operate on Unicode data. - * - * A Unicode string is an internationalized string. Conceptually, a - * Unicode string is an array of 16-bit quantities organized as a - * sequence of properly formed UTF-8 characters. There is a one-to-one - * map between Unicode and UTF characters. Because Unicode characters - * have a fixed width, operations such as indexing operate on Unicode - * data. The String object is optimized for the case where each UTF char + * This file contains functions that implement string operations on Tcl + * objects. Some string operations work with UTF-8 encoding forms. + * Functions that require knowledge of the width of each character, + * such as indexing, operate on fixed width encoding forms such as UTF-32. + * + * Conceptually, a string is a sequence of Unicode code points. Internally + * it may be stored in an encoding form such as a modified version of + * UTF-8 or UTF-16 (when TCL_UTF_MAX=3) or UTF-32. + * + * The String object is optimized for the case where each UTF char * in a string is only one byte. In this case, we store the value of - * numChars, but we don't store the Unicode data (unless Tcl_GetUnicode - * is explicitly called). + * numChars, but we don't store the fixed form encoding (unless + * Tcl_GetUnicode is explicitly called). * - * The String object type stores one or both formats. The default - * behavior is to store UTF. Once Unicode is calculated by a function, it - * is stored in the internal rep for future access (without an additional - * O(n) cost). + * The String object type stores one or both formats. The default + * behavior is to store UTF-8. Once UTF-16/UTF32 is calculated, it is + * stored in the internal rep for future access (without an additional + * O(n) cost). * * To allow many appends to be done to an object without constantly - * reallocating the space for the string or Unicode representation, we - * allocate double the space for the string or Unicode and use the + * reallocating space, we allocate double the space and use the * internal representation to keep track of how much space is used vs. * allocated. * @@ -37,7 +35,6 @@ #include "tclInt.h" #include "tclTomMath.h" #include "tclStringRep.h" - #include "assert.h" /* * Prototypes for functions defined later in this file: @@ -252,7 +249,7 @@ UpdateStringOfUTF16String( #endif #endif - + /* * TCL STRING GROWTH ALGORITHM * @@ -631,10 +628,8 @@ TclGetCharLength( */ if (TclIsPureByteArray(objPtr)) { - int length; - - (void) Tcl_GetByteArrayFromObj(objPtr, &length); - return length; + (void) Tcl_GetByteArrayFromObj(objPtr, &numChars); + return numChars; } /* @@ -675,10 +670,10 @@ Tcl_GetCharLength( } /* - * Optimize BytArray case: No need to convert to a string to perform the - * get-length operation. + * Optimize the case where we're really dealing with a bytearray object; + * we don't need to convert to a string to perform the get-length operation. * - * Starting in Tcl 8.7, check for a "pure" bytearray, because the + * Starting in Tcl 8.7, we check for a "pure" bytearray, because the * machinery behind that test is using a proper bytearray ObjType. We * could also compute length of an improper bytearray without shimmering * but there's no value in that. We *want* to shimmer an improper bytearray @@ -686,16 +681,17 @@ Tcl_GetCharLength( */ if (TclIsPureByteArray(objPtr)) { - (void) Tcl_GetByteArrayFromObj(objPtr, &numChars); } else { Tcl_GetString(objPtr); numChars = Tcl_NumUtfChars(objPtr->bytes, objPtr->length); } + return numChars; } #endif + /* *---------------------------------------------------------------------- * @@ -722,6 +718,11 @@ TclCheckEmptyString( return TCL_EMPTYSTRING_YES; } + if (TclIsPureByteArray(objPtr) + && Tcl_GetCharLength(objPtr) == 0) { + return TCL_EMPTYSTRING_YES; + } + if (TclListObjIsCanonical(objPtr)) { TclListObjLengthM(NULL, objPtr, &length); return length == 0; @@ -2383,12 +2384,16 @@ Tcl_AppendFormatToObj( width = 0; if (isdigit(UCHAR(ch))) { - width = strtoul(format, &end, 10); - if (width < 0) { + /* Note ull will be >= 0 because of isdigit check above */ + unsigned long long ull; + ull = strtoull(format, &end, 10); + /* Comparison is >=, not >, to leave room for nul */ + if (ull >= WIDE_MAX) { msg = overflow; errCode = "OVERFLOW"; goto errorMsg; } + width = (Tcl_WideInt)ull; format = end; step = TclUtfToUniChar(format, &ch); } else if (ch == '*') { @@ -2425,7 +2430,16 @@ Tcl_AppendFormatToObj( step = TclUtfToUniChar(format, &ch); } if (isdigit(UCHAR(ch))) { - precision = strtoul(format, &end, 10); + /* Note ull will be >= 0 because of isdigit check above */ + unsigned long long ull; + ull = strtoull(format, &end, 10); + /* Comparison is >=, not >, to leave room for nul */ + if (ull >= WIDE_MAX) { + msg = overflow; + errCode = "OVERFLOW"; + goto errorMsg; + } + precision = (Tcl_WideInt)ull; format = end; step = TclUtfToUniChar(format, &ch); } else if (ch == '*') { @@ -2531,6 +2545,9 @@ Tcl_AppendFormatToObj( if (TclGetIntFromObj(interp, segment, &code) != TCL_OK) { goto error; } + if ((unsigned)code > 0x10FFFF) { + code = 0xFFFD; + } length = Tcl_UniCharToUtf(code, buf); if ((code >= 0xD800) && (length < 3)) { /* Special case for handling high surrogates. */ @@ -3113,12 +3130,16 @@ AppendPrintfToObjVA( break; } + case 'p': + if (sizeof(size_t) == sizeof(Tcl_WideInt)) { + size = 2; + } + /* FALLTHRU */ case 'c': case 'i': case 'u': case 'd': case 'o': - case 'p': case 'x': case 'X': seekingConversion = 0; @@ -3875,6 +3896,7 @@ TclStringCmp( if ((reqlength == 0) || (value1Ptr == value2Ptr)) { /* * Always match at 0 chars of if it is the same obj. + * Note: as documented reqlength negative means it is ignored */ match = 0; } else { @@ -4006,15 +4028,15 @@ TclStringCmp( * comparison function. */ length = (s1len < s2len) ? s1len : s2len; - if (reqlength > 0 && reqlength < length) { - length = reqlength; - } else if (reqlength < 0) { + if (reqlength < 0) { /* * The requested length is negative, so ignore it by setting it * to length + 1 to correct the match var. */ reqlength = length + 1; + } else if (reqlength > 0 && reqlength < length) { + length = reqlength; } if (checkEq && reqlength < 0 && (s1len != s2len)) { @@ -4452,18 +4474,17 @@ TclStringReplace( int inPlace = flags & TCL_STRING_IN_PLACE; Tcl_Obj *result; - /* Caller is expected to pass sensible arguments */ - assert ( count >= 0 ) ; - assert ( first >= 0 ) ; - /* Replace nothing with nothing */ - if ((insertPtr == NULL) && (count == 0)) { + if ((insertPtr == NULL) && (count <= 0)) { if (inPlace) { return objPtr; } else { return Tcl_DuplicateObj(objPtr); } } + if (first < 0) { + first = 0; + } /* * The caller very likely had to call Tcl_GetCharLength() or similar diff --git a/generic/tclStringRep.h b/generic/tclStringRep.h index 0219a00..d1863fb 100644 --- a/generic/tclStringRep.h +++ b/generic/tclStringRep.h @@ -1,29 +1,12 @@ /* * tclStringRep.h -- * - * This file contains the definition of the Unicode string internal - * representation and macros to access it. + * This file contains the definition of internal representations of a string + * and macros to access it. * - * A Unicode string is an internationalized string. Conceptually, a - * Unicode string is an array of 16-bit quantities organized as a - * sequence of properly formed UTF-8 characters. There is a one-to-one - * map between Unicode and UTF characters. Because Unicode characters - * have a fixed width, operations such as indexing operate on Unicode - * data. The String object is optimized for the case where each UTF char - * in a string is only one byte. In this case, we store the value of - * numChars, but we don't store the Unicode data (unless Tcl_GetUnicode - * is explicitly called). - * - * The String object type stores one or both formats. The default - * behavior is to store UTF. Once Unicode is calculated by a function, it - * is stored in the internal rep for future access (without an additional - * O(n) cost). - * - * To allow many appends to be done to an object without constantly - * reallocating the space for the string or Unicode representation, we - * allocate double the space for the string or Unicode and use the - * internal representation to keep track of how much space is used vs. - * allocated. + * Conceptually, a string is a sequence of Unicode code points. Internally + * it may be stored in an encoding form such as a modified version of UTF-8 + * or UTF-16 (when TCL_UTF_MAX=3) or UTF-32. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright (c) 1999 by Scriptics Corporation. @@ -39,10 +22,10 @@ /* * The following structure is the internal rep for a String object. It keeps * track of how much memory has been used and how much has been allocated for - * the Unicode and UTF string to enable growing and shrinking of the UTF and - * Unicode reps of the String object with fewer mallocs. To optimize string + * the various representations to enable growing and shrinking of + * the String object with fewer mallocs. To optimize string * length and indexing operations, this structure also stores the number of - * characters (same of UTF and Unicode!) once that value has been computed. + * code points (independent of encoding form) once that value has been computed. */ typedef struct { @@ -52,17 +35,18 @@ typedef struct { * Unicode rep, or that the number of UTF bytes == * the number of chars. */ Tcl_Size allocated; /* The amount of space actually allocated for - * the UTF string (minus 1 byte for the + * the UTF-8 string (minus 1 byte for the * termination char). */ Tcl_Size maxChars; /* Max number of chars that can fit in the * space allocated for the Unicode array. */ int hasUnicode; /* Boolean determining whether the string has - * a Unicode representation. */ - unsigned short unicode[TCLFLEXARRAY]; /* The array of Unicode chars. The actual size - * of this field depends on the 'maxChars' - * field above. */ + * a Tcl_UniChar representation. */ + unsigned short unicode[TCLFLEXARRAY]; /* The array of Tcl_UniChar units. + * The actual size of this field depends on + * the maxChars field above. */ } String; +/* Limit on string lengths. The -1 because limit does not include the nul */ #define STRING_MAXCHARS \ (int)(((size_t)UINT_MAX - offsetof(String, unicode))/sizeof(unsigned short) - 1) #define STRING_SIZE(numChars) \ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index e2d52b9..c567736 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -28,6 +28,8 @@ */ #undef Tcl_Alloc +#undef Tcl_AttemptAlloc +#undef Tcl_AttemptRealloc #undef Tcl_Free #undef Tcl_Realloc #undef Tcl_NewBooleanObj diff --git a/generic/tclTest.c b/generic/tclTest.c index 893f073..ef9997a 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -251,7 +251,7 @@ static Tcl_ObjCmdProc TestsetbytearraylengthObjCmd; static Tcl_ObjCmdProc TestpurebytesobjObjCmd; static Tcl_ObjCmdProc TeststringbytesObjCmd; static Tcl_ObjCmdProc Testutf16stringObjCmd; -static Tcl_CmdProc TestcmdinfoCmd; +static Tcl_ObjCmdProc TestcmdinfoObjCmd; static Tcl_CmdProc TestcmdtokenCmd; static Tcl_CmdProc TestcmdtraceCmd; static Tcl_CmdProc TestconcatobjCmd; @@ -617,7 +617,7 @@ Tcltest_Init( NULL, NULL); Tcl_CreateCommand(interp, "testcmdtoken", TestcmdtokenCmd, NULL, NULL); - Tcl_CreateCommand(interp, "testcmdinfo", TestcmdinfoCmd, NULL, + Tcl_CreateObjCommand(interp, "testcmdinfo", TestcmdinfoObjCmd, NULL, NULL); Tcl_CreateCommand(interp, "testcmdtrace", TestcmdtraceCmd, NULL, NULL); @@ -956,7 +956,7 @@ TestasyncCmd( break; } } - Tcl_SetObjResult(interp, Tcl_NewStringObj(argv[3], TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(argv[3], -1)); Tcl_MutexUnlock(&asyncTestMutex); return code; } else if (strcmp(argv[1], "marklater") == 0) { @@ -1000,7 +1000,8 @@ AsyncHandlerProc( { TestAsyncHandler *asyncPtr; int id = PTR2INT(clientData); - const char *listArgv[4], *cmd; + const char *listArgv[4]; + char *cmd; char string[TCL_INTEGER_SPACE]; Tcl_MutexLock(&asyncTestMutex); @@ -1019,7 +1020,7 @@ AsyncHandlerProc( TclFormatInt(string, code); listArgv[0] = asyncPtr->command; - listArgv[1] = Tcl_GetString(Tcl_GetObjResult(interp)); + listArgv[1] = Tcl_GetStringResult(interp); listArgv[2] = string; listArgv[3] = NULL; cmd = Tcl_Merge(3, listArgv); @@ -1093,7 +1094,7 @@ TestbumpinterpepochObjCmd( /* *---------------------------------------------------------------------- * - * TestcmdinfoCmd -- + * TestcmdinfoObjCmd -- * * This procedure implements the "testcmdinfo" command. It is used to * test Tcl_GetCommandInfo, Tcl_SetCommandInfo, and command creation and @@ -1109,28 +1110,40 @@ TestbumpinterpepochObjCmd( */ static int -TestcmdinfoCmd( +TestcmdinfoObjCmd( TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { + static const char *const subcmds[] = { + "create", "delete", "get", "modify", NULL + }; + enum options { + CMDINFO_CREATE, CMDINFO_DELETE, CMDINFO_GET, CMDINFO_MODIFY + } idx; Tcl_CmdInfo info; - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " option cmdName\"", NULL); + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "command arg"); return TCL_ERROR; } - if (strcmp(argv[1], "create") == 0) { - Tcl_CreateCommand(interp, argv[2], CmdProc1, (void *) "original", - CmdDelProc1); - } else if (strcmp(argv[1], "delete") == 0) { + if (Tcl_GetIndexFromObj(interp, objv[1], subcmds, "option", 0, + &idx) != TCL_OK) { + return TCL_ERROR; + } + switch (idx) { + case CMDINFO_CREATE: + Tcl_CreateCommand(interp, Tcl_GetString(objv[2]), CmdProc1, + (void *)"original", CmdDelProc1); + break; + case CMDINFO_DELETE: Tcl_DStringInit(&delString); - Tcl_DeleteCommand(interp, argv[2]); + Tcl_DeleteCommand(interp, Tcl_GetString(objv[2])); Tcl_DStringResult(interp, &delString); - } else if (strcmp(argv[1], "get") == 0) { - if (Tcl_GetCommandInfo(interp, argv[2], &info) ==0) { + break; + case CMDINFO_GET: + if (Tcl_GetCommandInfo(interp, Tcl_GetString(objv[2]), &info) ==0) { Tcl_AppendResult(interp, "??", NULL); return TCL_OK; } @@ -1153,28 +1166,31 @@ TestcmdinfoCmd( Tcl_AppendResult(interp, " unknown", NULL); } Tcl_AppendResult(interp, " ", info.namespacePtr->fullName, NULL); - if (info.isNativeObjectProc) { + if (info.isNativeObjectProc == 0) { + Tcl_AppendResult(interp, " stringProc", NULL); + } else if (info.isNativeObjectProc == 1) { Tcl_AppendResult(interp, " nativeObjectProc", NULL); } else { - Tcl_AppendResult(interp, " stringProc", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("Invalid isNativeObjectProc value %d", + info.isNativeObjectProc)); + return TCL_ERROR; } - } else if (strcmp(argv[1], "modify") == 0) { + break; + case CMDINFO_MODIFY: info.proc = CmdProc2; info.clientData = (void *) "new_command_data"; info.objProc = NULL; info.objClientData = NULL; info.deleteProc = CmdDelProc2; info.deleteData = (void *) "new_delete_data"; - if (Tcl_SetCommandInfo(interp, argv[2], &info) == 0) { + if (Tcl_SetCommandInfo(interp, Tcl_GetString(objv[2]), &info) == 0) { Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0)); } else { Tcl_SetObjResult(interp, Tcl_NewWideIntObj(1)); } - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be create, delete, get, or modify", NULL); - return TCL_ERROR; + break; } + return TCL_OK; } @@ -1239,8 +1255,8 @@ CmdDelProc1( void *clientData) /* String to save. */ { Tcl_DStringInit(&delString); - Tcl_DStringAppend(&delString, "CmdDelProc1 ", TCL_INDEX_NONE); - Tcl_DStringAppend(&delString, (char *) clientData, TCL_INDEX_NONE); + Tcl_DStringAppend(&delString, "CmdDelProc1 ", -1); + Tcl_DStringAppend(&delString, (char *) clientData, -1); } static void @@ -1248,8 +1264,8 @@ CmdDelProc2( void *clientData) /* String to save. */ { Tcl_DStringInit(&delString); - Tcl_DStringAppend(&delString, "CmdDelProc2 ", TCL_INDEX_NONE); - Tcl_DStringAppend(&delString, (char *) clientData, TCL_INDEX_NONE); + Tcl_DStringAppend(&delString, "CmdDelProc2 ", -1); + Tcl_DStringAppend(&delString, (char *) clientData, -1); } /* @@ -1502,7 +1518,7 @@ ObjTraceProc( const char *word = Tcl_GetString(objv[0]); if (!strcmp(word, "Error")) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(command, TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1)); return TCL_ERROR; } else if (!strcmp(word, "Break")) { return TCL_BREAK; @@ -1866,7 +1882,7 @@ TestdoubledigitsObjCmd( type = types[type]; if (objc > 4) { if (strcmp(Tcl_GetString(objv[4]), "shorten")) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("bad flag", TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj("bad flag", -1)); return TCL_ERROR; } type |= TCL_DD_SHORTEST; @@ -2174,10 +2190,10 @@ static int UtfExtWrapper( memmove(bufPtr + dstLen, "\xAB\xCD\xEF\xAB", 4); /* overflow detection */ bytes = Tcl_GetByteArrayFromObj(objv[3], &srcLen); /* Last! to avoid shimmering */ result = (*transformer)(interp, encoding, (const char *)bytes, srcLen, flags, - encStatePtr, (char *) bufPtr, dstLen, - srcReadVar ? &srcRead : NULL, - &dstWrote, - dstCharsVar ? &dstChars : NULL); + encStatePtr, (char *) bufPtr, dstLen, + srcReadVar ? &srcRead : NULL, + &dstWrote, + dstCharsVar ? &dstChars : NULL); if (memcmp(bufPtr + bufLen - 4, "\xAB\xCD\xEF\xAB", 4)) { Tcl_SetResult(interp, "Tcl_ExternalToUtf wrote past output buffer", @@ -2269,7 +2285,7 @@ TestencodingObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Encoding encoding; - int index, length; + Tcl_Size length; const char *string; TclEncoding *encodingPtr; static const char *const optionStrings[] = { @@ -2278,6 +2294,7 @@ TestencodingObjCmd( enum options { ENC_CREATE, ENC_DELETE, ENC_NULLENGTH, ENC_EXTTOUTF, ENC_UTFTOEXT }; + int index; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "command ?args?"); @@ -3460,7 +3477,7 @@ TestlinkCmd( } } if (argv[6][0] != 0) { - tmp = Tcl_NewStringObj(argv[6], TCL_INDEX_NONE); + tmp = Tcl_NewStringObj(argv[6], -1); if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; @@ -3518,7 +3535,7 @@ TestlinkCmd( } if (argv[15][0]) { Tcl_WideInt w; - tmp = Tcl_NewStringObj(argv[15], TCL_INDEX_NONE); + tmp = Tcl_NewStringObj(argv[15], -1); if (Tcl_GetWideIntFromObj(interp, tmp, &w) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; @@ -3568,7 +3585,7 @@ TestlinkCmd( Tcl_UpdateLinkedVar(interp, "string"); } if (argv[6][0] != 0) { - tmp = Tcl_NewStringObj(argv[6], TCL_INDEX_NONE); + tmp = Tcl_NewStringObj(argv[6], -1); if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; @@ -3635,7 +3652,7 @@ TestlinkCmd( } if (argv[15][0]) { Tcl_WideInt w; - tmp = Tcl_NewStringObj(argv[15], TCL_INDEX_NONE); + tmp = Tcl_NewStringObj(argv[15], -1); if (Tcl_GetWideIntFromObj(interp, tmp, &w) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; @@ -3743,7 +3760,7 @@ TestlinkarrayCmd( return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[i++], &size) == TCL_ERROR) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong size value", TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong size value", -1)); return TCL_ERROR; } name = Tcl_GetString(objv[i++]); @@ -3755,7 +3772,7 @@ TestlinkarrayCmd( if (i < objc) { if (Tcl_GetWideIntFromObj(interp, objv[i], &addr) == TCL_ERROR) { Tcl_SetObjResult(interp, Tcl_NewStringObj( - "wrong address value", TCL_INDEX_NONE)); + "wrong address value", -1)); return TCL_ERROR; } } else { @@ -3855,7 +3872,7 @@ TestlistrepCmd( #define APPEND_FIELD(targetObj_, structPtr_, fld_) \ do { \ Tcl_ListObjAppendElement( \ - interp, (targetObj_), Tcl_NewStringObj(#fld_, TCL_INDEX_NONE)); \ + interp, (targetObj_), Tcl_NewStringObj(#fld_, -1)); \ Tcl_ListObjAppendElement( \ interp, (targetObj_), Tcl_NewWideIntObj((structPtr_)->fld_)); \ } while (0) @@ -3873,10 +3890,10 @@ TestlistrepCmd( return TCL_ERROR; } ListObjGetRep(objv[2], &listRep); - listRepObjs[0] = Tcl_NewStringObj("store", TCL_INDEX_NONE); + listRepObjs[0] = Tcl_NewStringObj("store", -1); listRepObjs[1] = Tcl_NewListObj(12, NULL); Tcl_ListObjAppendElement( - interp, listRepObjs[1], Tcl_NewStringObj("memoryAddress", TCL_INDEX_NONE)); + interp, listRepObjs[1], Tcl_NewStringObj("memoryAddress", -1)); Tcl_ListObjAppendElement( interp, listRepObjs[1], Tcl_ObjPrintf("%p", listRep.storePtr)); APPEND_FIELD(listRepObjs[1], listRep.storePtr, firstUsed); @@ -3885,11 +3902,11 @@ TestlistrepCmd( APPEND_FIELD(listRepObjs[1], listRep.storePtr, refCount); APPEND_FIELD(listRepObjs[1], listRep.storePtr, flags); if (listRep.spanPtr) { - listRepObjs[2] = Tcl_NewStringObj("span", TCL_INDEX_NONE); + listRepObjs[2] = Tcl_NewStringObj("span", -1); listRepObjs[3] = Tcl_NewListObj(8, NULL); Tcl_ListObjAppendElement(interp, listRepObjs[3], - Tcl_NewStringObj("memoryAddress", TCL_INDEX_NONE)); + Tcl_NewStringObj("memoryAddress", -1)); Tcl_ListObjAppendElement( interp, listRepObjs[3], Tcl_ObjPrintf("%p", listRep.spanPtr)); APPEND_FIELD(listRepObjs[3], listRep.spanPtr, spanStart); @@ -3909,7 +3926,7 @@ TestlistrepCmd( } resultObj = Tcl_NewListObj(2, NULL); Tcl_ListObjAppendElement( - NULL, resultObj, Tcl_NewStringObj("LIST_SPAN_THRESHOLD", TCL_INDEX_NONE)); + NULL, resultObj, Tcl_NewStringObj("LIST_SPAN_THRESHOLD", -1)); Tcl_ListObjAppendElement( NULL, resultObj, Tcl_NewWideIntObj(LIST_SPAN_THRESHOLD)); break; @@ -3983,7 +4000,7 @@ TestlocaleCmd( } locale = setlocale(lcTypes[index], locale); if (locale) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), locale, TCL_INDEX_NONE); + Tcl_SetStringObj(Tcl_GetObjResult(interp), locale, -1); } return TCL_OK; } @@ -4158,7 +4175,7 @@ PrintParse( Tcl_Obj *objPtr; const char *typeString; Tcl_Token *tokenPtr; - int i; + Tcl_Size i; objPtr = Tcl_GetObjResult(interp); if (parsePtr->commentSize > 0) { @@ -4207,7 +4224,7 @@ PrintParse( break; } Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewStringObj(typeString, TCL_INDEX_NONE)); + Tcl_NewStringObj(typeString, -1)); Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(tokenPtr->start, tokenPtr->size)); Tcl_ListObjAppendElement(NULL, objPtr, @@ -4438,6 +4455,7 @@ TestregexpObjCmd( REGEXP_XFLAGS, REGEXP_LAST }; + int index; indices = 0; about = 0; @@ -4447,7 +4465,6 @@ TestregexpObjCmd( for (i = 1; i < objc; i++) { const char *name; - int index; name = Tcl_GetString(objv[i]); if (name[0] != '-') { @@ -5407,7 +5424,7 @@ GetTimesObjCmd( /* TclGetString 100000 times */ fprintf(stderr, "Tcl_GetStringFromObj of \"12345\" 100000 times\n"); - objPtr = Tcl_NewStringObj("12345", TCL_INDEX_NONE); + objPtr = Tcl_NewStringObj("12345", -1); Tcl_GetTime(&start); for (i = 0; i < 100000; i++) { (void) TclGetString(objPtr); @@ -5710,7 +5727,7 @@ TestbytestringObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { - size_t n = 0; + Tcl_Size n = 0; const char *p; if (objc != 2) { @@ -6180,7 +6197,7 @@ TestChannelCmd( if ((cmdName[0] == 's') && (strncmp(cmdName, "setchannelerror", len) == 0)) { - Tcl_Obj *msg = Tcl_NewStringObj(argv[3], TCL_INDEX_NONE); + Tcl_Obj *msg = Tcl_NewStringObj(argv[3], -1); Tcl_IncrRefCount(msg); Tcl_SetChannelError(chan, msg); @@ -6193,7 +6210,7 @@ TestChannelCmd( } if ((cmdName[0] == 's') && (strncmp(cmdName, "setchannelerrorinterp", len) == 0)) { - Tcl_Obj *msg = Tcl_NewStringObj(argv[3], TCL_INDEX_NONE); + Tcl_Obj *msg = Tcl_NewStringObj(argv[3], -1); Tcl_IncrRefCount(msg); Tcl_SetChannelErrorInterp(interp, msg); @@ -6580,7 +6597,7 @@ TestChannelCmd( } return TclChannelTransform(interp, chan, - Tcl_NewStringObj(argv[4], TCL_INDEX_NONE)); + Tcl_NewStringObj(argv[4], -1)); } if ((cmdName[0] == 'u') && (strncmp(cmdName, "unstack", len) == 0)) { @@ -6671,7 +6688,7 @@ TestChannelEventCmd( esPtr->chanPtr = chanPtr; esPtr->interp = interp; esPtr->mask = mask; - esPtr->scriptPtr = Tcl_NewStringObj(argv[4], TCL_INDEX_NONE); + esPtr->scriptPtr = Tcl_NewStringObj(argv[4], -1); Tcl_IncrRefCount(esPtr->scriptPtr); Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask, @@ -6738,10 +6755,10 @@ TestChannelEventCmd( esPtr = esPtr->nextPtr) { if (esPtr->mask) { Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj( - (esPtr->mask == TCL_READABLE) ? "readable" : "writable", TCL_INDEX_NONE)); + (esPtr->mask == TCL_READABLE) ? "readable" : "writable", -1)); } else { Tcl_ListObjAppendElement(interp, resultListPtr, - Tcl_NewStringObj("none", TCL_INDEX_NONE)); + Tcl_NewStringObj("none", -1)); } Tcl_ListObjAppendElement(interp, resultListPtr, esPtr->scriptPtr); } @@ -7096,7 +7113,7 @@ TestFilesystemObjCmd( res = Tcl_FSUnregister(&testReportingFilesystem); msg = (res == TCL_OK) ? "unregistered" : "failed"; } - Tcl_SetObjResult(interp, Tcl_NewStringObj(msg , TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(msg , -1)); return res; } @@ -7178,7 +7195,7 @@ TestReport( Tcl_DString ds; Tcl_DStringInit(&ds); - Tcl_DStringAppend(&ds, "lappend filesystemReport ", TCL_INDEX_NONE); + Tcl_DStringAppend(&ds, "lappend filesystemReport ", -1); Tcl_DStringStartSublist(&ds); Tcl_DStringAppendElement(&ds, cmd); if (path != NULL) { @@ -7467,7 +7484,7 @@ TestSimpleFilesystemObjCmd( res = Tcl_FSUnregister(&simpleFilesystem); msg = (res == TCL_OK) ? "unregistered" : "failed"; } - Tcl_SetObjResult(interp, Tcl_NewStringObj(msg , TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(msg , -1)); return res; } @@ -7494,7 +7511,7 @@ SimpleRedirect( Tcl_IncrRefCount(pathPtr); return pathPtr; } - origPtr = Tcl_NewStringObj(str+10, TCL_INDEX_NONE); + origPtr = Tcl_NewStringObj(str+10, -1); Tcl_IncrRefCount(origPtr); return origPtr; } @@ -7526,7 +7543,7 @@ SimpleMatchInDirectory( origPtr = SimpleRedirect(dirPtr); res = Tcl_FSMatchInDirectory(interp, resPtr, origPtr, pattern, types); if (res == TCL_OK) { - size_t gLength, j; + Tcl_Size gLength, j; Tcl_ListObjLength(NULL, resPtr, &gLength); for (j = 0; j < gLength; j++) { Tcl_Obj *gElt, *nElt; @@ -7594,7 +7611,7 @@ SimpleListVolumes(void) /* Add one new volume */ Tcl_Obj *retVal; - retVal = Tcl_NewStringObj("simplefs:/", TCL_INDEX_NONE); + retVal = Tcl_NewStringObj("simplefs:/", -1); Tcl_IncrRefCount(retVal); return retVal; } @@ -7612,7 +7629,7 @@ TestUtfNextCmd( int objc, Tcl_Obj *const objv[]) { - int numBytes; + Tcl_Size numBytes; char *bytes; const char *result, *first; char buffer[32]; @@ -7625,7 +7642,7 @@ TestUtfNextCmd( } bytes = Tcl_GetStringFromObj(objv[1], &numBytes); - if (numBytes + 4U > sizeof(buffer)) { + if ((size_t)numBytes > sizeof(buffer) - 4) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"testutfnext\" can only handle %" TCL_Z_MODIFIER "u bytes", sizeof(buffer) - 4)); @@ -7748,7 +7765,7 @@ TestFindFirstCmd( if (objc > 2) { (void) Tcl_GetIntFromObj(interp, objv[2], &len); } - Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_UtfFindFirst(Tcl_GetString(objv[1]), len), TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_UtfFindFirst(Tcl_GetString(objv[1]), len), -1)); } return TCL_OK; } @@ -7770,7 +7787,7 @@ TestFindLastCmd( if (objc > 2) { (void) Tcl_GetIntFromObj(interp, objv[2], &len); } - Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_UtfFindLast(Tcl_GetString(objv[1]), len), TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_UtfFindLast(Tcl_GetString(objv[1]), len), -1)); } return TCL_OK; } @@ -7796,7 +7813,7 @@ TestGetIntForIndexCmd( if (Tcl_GetIntForIndex(interp, objv[1], endvalue, &result) != TCL_OK) { return TCL_ERROR; } - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result)); return TCL_OK; } @@ -7847,7 +7864,7 @@ TestcpuidCmd( status = TclWinCPUID(index, regs); if (status != TCL_OK) { Tcl_SetObjResult(interp, - Tcl_NewStringObj("operation not available", TCL_INDEX_NONE)); + Tcl_NewStringObj("operation not available", -1)); return status; } for (i=0 ; i<4 ; ++i) { @@ -7893,7 +7910,7 @@ TestHashSystemHashCmd( hPtr = Tcl_CreateHashEntry(&hash, INT2PTR(i), &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_NewWideIntObj(i)); - Tcl_AppendToObj(Tcl_GetObjResult(interp)," creation problem", TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp)," creation problem", -1); Tcl_DeleteHashTable(&hash); return TCL_ERROR; } @@ -7910,13 +7927,13 @@ TestHashSystemHashCmd( hPtr = Tcl_FindHashEntry(&hash, (char *) INT2PTR(i)); if (hPtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewWideIntObj(i)); - Tcl_AppendToObj(Tcl_GetObjResult(interp)," lookup problem", TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp)," lookup problem", -1); Tcl_DeleteHashTable(&hash); return TCL_ERROR; } if (PTR2INT(Tcl_GetHashValue(hPtr)) != i+42) { Tcl_SetObjResult(interp, Tcl_NewWideIntObj(i)); - Tcl_AppendToObj(Tcl_GetObjResult(interp)," value problem", TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp)," value problem", -1); Tcl_DeleteHashTable(&hash); return TCL_ERROR; } @@ -8036,7 +8053,7 @@ TestNRELevels( static ptrdiff_t *refDepth = NULL; ptrdiff_t depth; Tcl_Obj *levels[6]; - int i = 0; + Tcl_Size i = 0; NRE_callback *cbPtr = iPtr->execEnvPtr->callbackPtr; if (refDepth == NULL) { @@ -8090,7 +8107,7 @@ TestconcatobjCmd( { Tcl_Obj *list1Ptr, *list2Ptr, *emptyPtr, *concatPtr, *tmpPtr; int result = TCL_OK; - size_t len; + Tcl_Size len; Tcl_Obj *objv[3]; /* @@ -8099,15 +8116,15 @@ TestconcatobjCmd( */ Tcl_SetObjResult(interp, - Tcl_NewStringObj("Tcl_ConcatObj is unsafe:", TCL_INDEX_NONE)); + Tcl_NewStringObj("Tcl_ConcatObj is unsafe:", -1)); emptyPtr = Tcl_NewObj(); - list1Ptr = Tcl_NewStringObj("foo bar sum", TCL_INDEX_NONE); + list1Ptr = Tcl_NewStringObj("foo bar sum", -1); Tcl_ListObjLength(NULL, list1Ptr, &len); Tcl_InvalidateStringRep(list1Ptr); - list2Ptr = Tcl_NewStringObj("eeny meeny", TCL_INDEX_NONE); + list2Ptr = Tcl_NewStringObj("eeny meeny", -1); Tcl_ListObjLength(NULL, list2Ptr, &len); Tcl_InvalidateStringRep(list2Ptr); @@ -8447,7 +8464,7 @@ TestparseargsCmd( Tcl_Obj *const objv[]) /* Arguments. */ { static int foo = 0; - size_t count = objc; + Tcl_Size count = objc; Tcl_Obj **remObjv, *result[3]; Tcl_ArgvInfo argTable[] = { {TCL_ARGV_CONSTANT, "-bool", INT2PTR(1), &foo, "booltest", NULL}, @@ -8670,7 +8687,7 @@ InterpCompiledVarResolver( resVarInfo->vInfo.fetchProc = MyCompiledVarFetch; resVarInfo->vInfo.deleteProc = MyCompiledVarFree; resVarInfo->var = NULL; - resVarInfo->nameObj = Tcl_NewStringObj(name, TCL_INDEX_NONE); + resVarInfo->nameObj = Tcl_NewStringObj(name, -1); Tcl_IncrRefCount(resVarInfo->nameObj); *rPtr = &resVarInfo->vInfo; return TCL_OK; @@ -8754,12 +8771,12 @@ int TestApplyLambdaObjCmd ( /* Create a lambda {{} {set a 42}} */ lambdaObjs[0] = Tcl_NewObj(); /* No parameters */ - lambdaObjs[1] = Tcl_NewStringObj("set a 42", TCL_INDEX_NONE); /* Body */ + lambdaObjs[1] = Tcl_NewStringObj("set a 42", -1); /* Body */ lambdaObj = Tcl_NewListObj(2, lambdaObjs); Tcl_IncrRefCount(lambdaObj); /* Create the command "apply {{} {set a 42}" */ - evalObjs[0] = Tcl_NewStringObj("apply", TCL_INDEX_NONE); + evalObjs[0] = Tcl_NewStringObj("apply", -1); Tcl_IncrRefCount(evalObjs[0]); /* * NOTE: IMPORTANT TO EXHIBIT THE BUG. We duplicate the lambda because diff --git a/generic/tclTestObj.c b/generic/tclTestObj.c index 0f5f21f..3b21eaf 100644 --- a/generic/tclTestObj.c +++ b/generic/tclTestObj.c @@ -188,13 +188,13 @@ TestbignumobjCmd( string = Tcl_GetString(objv[3]); if (mp_init(&bignumValue) != MP_OKAY) { Tcl_SetObjResult(interp, - Tcl_NewStringObj("error in mp_init", TCL_INDEX_NONE)); + Tcl_NewStringObj("error in mp_init", -1)); return TCL_ERROR; } if (mp_read_radix(&bignumValue, string, 10) != MP_OKAY) { mp_clear(&bignumValue); Tcl_SetObjResult(interp, - Tcl_NewStringObj("error in mp_read_radix", TCL_INDEX_NONE)); + Tcl_NewStringObj("error in mp_read_radix", -1)); return TCL_ERROR; } @@ -238,7 +238,7 @@ TestbignumobjCmd( if (mp_mul_d(&bignumValue, 10, &bignumValue) != MP_OKAY) { mp_clear(&bignumValue); Tcl_SetObjResult(interp, - Tcl_NewStringObj("error in mp_mul_d", TCL_INDEX_NONE)); + Tcl_NewStringObj("error in mp_mul_d", -1)); return TCL_ERROR; } if (!Tcl_IsShared(varPtr[varIndex])) { @@ -263,7 +263,7 @@ TestbignumobjCmd( if (mp_div_d(&bignumValue, 10, &bignumValue, NULL) != MP_OKAY) { mp_clear(&bignumValue); Tcl_SetObjResult(interp, - Tcl_NewStringObj("error in mp_div_d", TCL_INDEX_NONE)); + Tcl_NewStringObj("error in mp_div_d", -1)); return TCL_ERROR; } if (!Tcl_IsShared(varPtr[varIndex])) { @@ -288,7 +288,7 @@ TestbignumobjCmd( if (mp_mod_2d(&bignumValue, 1, &bignumValue) != MP_OKAY) { mp_clear(&bignumValue); Tcl_SetObjResult(interp, - Tcl_NewStringObj("error in mp_mod_2d", TCL_INDEX_NONE)); + Tcl_NewStringObj("error in mp_mod_2d", -1)); return TCL_ERROR; } if (!Tcl_IsShared(varPtr[varIndex])) { @@ -606,7 +606,7 @@ TestindexobjCmd( } if (objc < 5) { - Tcl_AppendToObj(Tcl_GetObjResult(interp), "wrong # args", TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp), "wrong # args", -1); return TCL_ERROR; } @@ -617,7 +617,7 @@ TestindexobjCmd( return TCL_ERROR; } - argv = (const char **)ckalloc(((unsigned)objc-3) * sizeof(char *)); + argv = (const char **)ckalloc((objc-3) * sizeof(char *)); for (i = 4; i < objc; i++) { argv[i-4] = Tcl_GetString(objv[i]); } @@ -746,7 +746,7 @@ TestintobjCmd( return TCL_ERROR; } Tcl_AppendToObj(Tcl_GetObjResult(interp), - ((wideValue == WIDE_MAX)? "1" : "0"), TCL_INDEX_NONE); + ((wideValue == WIDE_MAX)? "1" : "0"), -1); } else if (strcmp(subCmd, "get") == 0) { if (objc != 3) { goto wrongNumArgs; @@ -762,7 +762,7 @@ TestintobjCmd( if (CheckIfVarUnset(interp, varPtr,varIndex)) { return TCL_ERROR; } - Tcl_AppendToObj(Tcl_GetObjResult(interp), Tcl_GetString(varPtr[varIndex]), TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp), Tcl_GetString(varPtr[varIndex]), -1); } else if (strcmp(subCmd, "inttoobigtest") == 0) { /* * If long ints have more bits than ints on this platform, verify that @@ -775,7 +775,7 @@ TestintobjCmd( goto wrongNumArgs; } #if (INT_MAX == LONG_MAX) /* int is same size as long int */ - Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", -1); #else if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) { Tcl_SetWideIntObj(varPtr[varIndex], LONG_MAX); @@ -784,10 +784,10 @@ TestintobjCmd( } if (Tcl_GetIntFromObj(interp, varPtr[varIndex], &i) != TCL_OK) { Tcl_ResetResult(interp); - Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", -1); return TCL_OK; } - Tcl_AppendToObj(Tcl_GetObjResult(interp), "0", TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp), "0", -1); #endif } else if (strcmp(subCmd, "mult10") == 0) { if (objc != 3) { @@ -1112,7 +1112,7 @@ TestobjCmd( const char *typeName; if (objv[2]->typePtr == NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("none", TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1)); } else { typeName = objv[2]->typePtr->name; if (!strcmp(typeName, "utf32string")) @@ -1120,7 +1120,7 @@ TestobjCmd( #ifndef TCL_WIDE_INT_IS_LONG else if (!strcmp(typeName, "wideInt")) typeName = "int"; #endif - Tcl_SetObjResult(interp, Tcl_NewStringObj(typeName, TCL_INDEX_NONE)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(typeName, -1)); } } return TCL_OK; @@ -1214,15 +1214,15 @@ TestobjCmd( goto wrongNumArgs; } if (varPtr[varIndex]->typePtr == NULL) { /* a string! */ - Tcl_AppendToObj(Tcl_GetObjResult(interp), "string", TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp), "string", -1); #ifndef TCL_WIDE_INT_IS_LONG } else if (!strcmp(varPtr[varIndex]->typePtr->name, "wideInt")) { Tcl_AppendToObj(Tcl_GetObjResult(interp), - "int", TCL_INDEX_NONE); + "int", -1); #endif } else { Tcl_AppendToObj(Tcl_GetObjResult(interp), - varPtr[varIndex]->typePtr->name, TCL_INDEX_NONE); + varPtr[varIndex]->typePtr->name, -1); } break; default: @@ -1353,7 +1353,7 @@ TeststringobjCmd( if (CheckIfVarUnset(interp, varPtr, varIndex)) { return TCL_ERROR; } - Tcl_AppendToObj(Tcl_GetObjResult(interp), Tcl_GetString(varPtr[varIndex]), TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp), Tcl_GetString(varPtr[varIndex]), -1); break; case 4: /* length */ if (objc != 3) { @@ -1373,10 +1373,10 @@ TeststringobjCmd( strPtr = (String *)varPtr[varIndex]->internalRep.twoPtrValue.ptr1; length = (int) strPtr->allocated; } else { - length = -1; + length = TCL_INDEX_NONE; } } else { - length = -1; + length = TCL_INDEX_NONE; } Tcl_SetWideIntObj(Tcl_GetObjResult(interp), length); break; @@ -1431,10 +1431,10 @@ TeststringobjCmd( strPtr = (String *)varPtr[varIndex]->internalRep.twoPtrValue.ptr1; length = strPtr->maxChars; } else { - length = -1; + length = TCL_INDEX_NONE; } } else { - length = -1; + length = TCL_INDEX_NONE; } Tcl_SetWideIntObj(Tcl_GetObjResult(interp), length); break; @@ -1474,7 +1474,7 @@ TeststringobjCmd( } if (length == TCL_INDEX_NONE) { Tcl_SetObjResult(interp, Tcl_NewStringObj( - "index value out of range", TCL_INDEX_NONE)); + "index value out of range", -1)); return TCL_ERROR; } @@ -1505,7 +1505,7 @@ TeststringobjCmd( } if (length == TCL_INDEX_NONE) { Tcl_SetObjResult(interp, Tcl_NewStringObj( - "index value out of range", TCL_INDEX_NONE)); + "index value out of range", -1)); return TCL_ERROR; } @@ -1599,7 +1599,7 @@ GetVariableIndex( } if (index == TCL_INDEX_NONE) { Tcl_ResetResult(interp); - Tcl_AppendToObj(Tcl_GetObjResult(interp), "bad variable index", TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp), "bad variable index", -1); return TCL_ERROR; } @@ -1631,12 +1631,12 @@ CheckIfVarUnset( Tcl_Obj ** varPtr, Tcl_Size varIndex) /* Index of the test variable to check. */ { - if (varPtr[varIndex] == NULL) { + if (varIndex < 0 || varPtr[varIndex] == NULL) { char buf[32 + TCL_INTEGER_SPACE]; - snprintf(buf, sizeof(buf), "variable %d is unset (NULL)", varIndex); + snprintf(buf, sizeof(buf), "variable %" TCL_SIZE_MODIFIER "d is unset (NULL)", varIndex); Tcl_ResetResult(interp); - Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, TCL_INDEX_NONE); + Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1); return 1; } return 0; diff --git a/generic/tclTestProcBodyObj.c b/generic/tclTestProcBodyObj.c index b6dbc3f..07800ca 100644 --- a/generic/tclTestProcBodyObj.c +++ b/generic/tclTestProcBodyObj.c @@ -35,7 +35,7 @@ static const char checkCommand[] = "check"; * procs */ -typedef struct CmdTable { +typedef struct { const char *cmdName; /* command name */ Tcl_ObjCmdProc *proc; /* command proc */ int exportIt; /* if 1, export the command */ @@ -188,7 +188,7 @@ ProcBodyTestInitInternal( } } - return Tcl_PkgProvide(interp, packageName, packageVersion); + return Tcl_PkgProvideEx(interp, packageName, packageVersion, NULL); } /* @@ -337,7 +337,7 @@ ProcBodyTestCheckObjCmd( return TCL_ERROR; } - version = Tcl_PkgPresent(interp, packageName, packageVersion, 1); + version = Tcl_PkgPresentEx(interp, packageName, packageVersion, 1, NULL); Tcl_SetObjResult(interp, Tcl_NewBooleanObj( strcmp(version, packageVersion) == 0)); return TCL_OK; diff --git a/generic/tclThreadTest.c b/generic/tclThreadTest.c index 44d2b0e..99f9838 100644 --- a/generic/tclThreadTest.c +++ b/generic/tclThreadTest.c @@ -656,10 +656,10 @@ ThreadErrorProc( errorInfo = Tcl_GetVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY); if (errorProcString == NULL) { errChannel = Tcl_GetStdChannel(TCL_STDERR); - Tcl_WriteChars(errChannel, "Error from thread ", TCL_INDEX_NONE); - Tcl_WriteChars(errChannel, buf, TCL_INDEX_NONE); + Tcl_WriteChars(errChannel, "Error from thread ", -1); + Tcl_WriteChars(errChannel, buf, -1); Tcl_WriteChars(errChannel, "\n", 1); - Tcl_WriteChars(errChannel, errorInfo, TCL_INDEX_NONE); + Tcl_WriteChars(errChannel, errorInfo, -1); Tcl_WriteChars(errChannel, "\n", 1); } else { argv[0] = errorProcString; @@ -984,7 +984,7 @@ ThreadCancel( Tcl_MutexUnlock(&threadMutex); Tcl_ResetResult(interp); return Tcl_CancelEval(tsdPtr->interp, - (result != NULL) ? Tcl_NewStringObj(result, TCL_INDEX_NONE) : NULL, 0, flags); + (result != NULL) ? Tcl_NewStringObj(result, -1) : NULL, 0, flags); } /* diff --git a/generic/tclTomMathDecls.h b/generic/tclTomMathDecls.h index 009f914..b4ab607 100644 --- a/generic/tclTomMathDecls.h +++ b/generic/tclTomMathDecls.h @@ -35,11 +35,11 @@ /* Define custom memory allocation for libtommath */ /* MODULE_SCOPE void* TclBNAlloc( size_t ); */ -#define TclBNAlloc(s) ((void*)ckalloc((size_t)(s))) +#define TclBNAlloc(s) ((void*)attemptckalloc((size_t)(s))) /* MODULE_SCOPE void* TclBNCalloc( size_t, size_t ); */ -#define TclBNCalloc(m,s) memset(ckalloc((size_t)(m)*(size_t)(s)),0,(size_t)(m)*(size_t)(s)) +#define TclBNCalloc(m,s) memset(attemptckalloc((size_t)(m)*(size_t)(s)),0,(size_t)(m)*(size_t)(s)) /* MODULE_SCOPE void* TclBNRealloc( void*, size_t ); */ -#define TclBNRealloc(x,s) ((void*)ckrealloc((char*)(x),(size_t)(s))) +#define TclBNRealloc(x,s) ((void*)attemptckrealloc((char*)(x),(size_t)(s))) /* MODULE_SCOPE void TclBNFree( void* ); */ #define TclBNFree(x) (ckfree((char*)(x))) @@ -48,9 +48,9 @@ #undef MP_REALLOC #undef MP_FREE #define MP_MALLOC(size) TclBNAlloc(size) -#define MP_CALLOC(nmemb, size) TclBNCalloc(nmemb, size) -#define MP_REALLOC(mem, oldsize, newsize) TclBNRealloc(mem, newsize) -#define MP_FREE(mem, size) TclBNFree(mem) +#define MP_CALLOC(nmemb, size) TclBNCalloc((nmemb), (size)) +#define MP_REALLOC(mem, oldsize, newsize) TclBNRealloc((mem), ((void)(oldsize), (newsize))) +#define MP_FREE(mem, size) TclBNFree(((void)(size), (mem))) #ifndef MODULE_SCOPE # ifdef __cplusplus |
