From 2fa8967c62a728986e69c0adfcc433c8da2d6dd4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Jan 2022 14:19:04 +0000 Subject: Proposed fix for [26f1328a86]: sizeof(int) < sizeof(void*) -> Crash --- generic/tclCompile.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 03b4a90..997f08e 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1509,22 +1509,22 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, # define TclGetInt1AtPtr(p) ((int) *((signed char *) p)) #else # define TclGetInt1AtPtr(p) \ - (((int) *((char *) p)) | ((*(p) & 0200) ? (-256) : 0)) + ((int) ((*((char *) p)) | ((*(p) & 0200) ? (-256) : 0))) #endif #define TclGetInt4AtPtr(p) \ - (((int) (TclGetUInt1AtPtr(p) << 24)) | \ - (*((p)+1) << 16) | \ - (*((p)+2) << 8) | \ - (*((p)+3))) + ((int) ((TclGetUInt1AtPtr(p) << 24) | \ + (*((p)+1) << 16) | \ + (*((p)+2) << 8) | \ + (*((p)+3)))) #define TclGetUInt1AtPtr(p) \ ((unsigned int) *(p)) #define TclGetUInt4AtPtr(p) \ - ((unsigned int) (*(p) << 24) | \ - (*((p)+1) << 16) | \ - (*((p)+2) << 8) | \ - (*((p)+3))) + ((unsigned int) ((*(p) << 24) | \ + (*((p)+1) << 16) | \ + (*((p)+2) << 8) | \ + (*((p)+3)))) /* * Macros used to compute the minimum and maximum of two integers. The ANSI C -- cgit v0.12 From 2171b321cf1ec2d7c671d02dfea59860bccc06f2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Jan 2022 15:50:30 +0000 Subject: Fix [69218ab7b]: TEBCResume(): buffer over-read in INST_STR_MAP --- generic/tclExecute.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 7e014d4..aa5730a 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5855,7 +5855,9 @@ TEBCresume( p = ustring1; end = ustring1 + length; for (; ustring1 < end; ustring1++) { - if ((*ustring1 == *ustring2) && (length2==1 || + if ((*ustring1 == *ustring2) && + /* Fix bug [69218ab7b]: restrict max compare length. */ + (end-ustring1 >= length2) && (length2==1 || memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length2) == 0)) { if (p != ustring1) { -- cgit v0.12 From 05dc6d00c28c40fef2b65cf96d5753927599c4d5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Jan 2022 16:33:51 +0000 Subject: Fix [da6f155ca4]: STRING_SIZE() macro: parenthesize numChars usage. Fix more macro's like this. --- generic/tclCkalloc.c | 2 +- generic/tclDate.c | 4 ++-- generic/tclExecute.c | 14 +++++++------- generic/tclGetDate.y | 4 ++-- generic/tclIORChan.c | 2 +- generic/tclIORTrans.c | 2 +- generic/tclInt.h | 2 +- generic/tclOOInt.h | 2 +- generic/tclStringRep.h | 2 +- generic/tclTrace.c | 4 ++-- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c index 48832d9..8c83aeb 100644 --- a/generic/tclCkalloc.c +++ b/generic/tclCkalloc.c @@ -41,7 +41,7 @@ typedef struct MemTag { * last field in the structure. */ } MemTag; -#define TAG_SIZE(bytesInString) ((unsigned) ((TclOffset(MemTag, string) + 1) + bytesInString)) +#define TAG_SIZE(bytesInString) ((unsigned) ((TclOffset(MemTag, string) + 1) + (bytesInString))) static MemTag *curTagPtr = NULL;/* Tag to use in all future mem_headers (set * by "memory tag" command). */ diff --git a/generic/tclDate.c b/generic/tclDate.c index aa199c3..23cf336 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -185,9 +185,9 @@ typedef struct DateInfo { #define TM_YEAR_BASE 1900 -#define HOUR(x) ((int) (60 * x)) +#define HOUR(x) ((int) (60 * (x))) #define SECSPERDAY (24L * 60L * 60L) -#define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0)) +#define IsLeapYear(x) (((x) % 4 == 0) && ((x) % 100 != 0 || (x) % 400 == 0)) /* * An entry in the lexical lookup table. diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 7e014d4..5dc506a 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -193,10 +193,10 @@ typedef struct TEBCdata { #define PUSH_TAUX_OBJ(objPtr) \ do { \ if (auxObjList) { \ - objPtr->length += auxObjList->length; \ + (objPtr)->length += auxObjList->length; \ } \ - objPtr->internalRep.twoPtrValue.ptr1 = auxObjList; \ - auxObjList = objPtr; \ + (objPtr)->internalRep.twoPtrValue.ptr1 = auxObjList; \ + auxObjList = (objPtr); \ } while (0) #define POP_TAUX_OBJ() \ @@ -8462,24 +8462,24 @@ ExecuteExtendedBinaryMathOp( { #define LONG_RESULT(l) \ if (Tcl_IsShared(valuePtr)) { \ - TclNewLongObj(objResultPtr, l); \ + TclNewLongObj(objResultPtr, (l)); \ return objResultPtr; \ } else { \ - Tcl_SetLongObj(valuePtr, l); \ + Tcl_SetLongObj(valuePtr, (l)); \ return NULL; \ } #define WIDE_RESULT(w) \ if (Tcl_IsShared(valuePtr)) { \ return Tcl_NewWideIntObj(w); \ } else { \ - Tcl_SetWideIntObj(valuePtr, w); \ + Tcl_SetWideIntObj(valuePtr, (w)); \ return NULL; \ } #define BIG_RESULT(b) \ if (Tcl_IsShared(valuePtr)) { \ return Tcl_NewBignumObj(b); \ } else { \ - Tcl_SetBignumObj(valuePtr, b); \ + Tcl_SetBignumObj(valuePtr, (b)); \ return NULL; \ } #define DOUBLE_RESULT(d) \ diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index e6748a4..7e26b37 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -136,9 +136,9 @@ typedef struct DateInfo { #define TM_YEAR_BASE 1900 -#define HOUR(x) ((int) (60 * x)) +#define HOUR(x) ((int) (60 * (x))) #define SECSPERDAY (24L * 60L * 60L) -#define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0)) +#define IsLeapYear(x) (((x) % 4 == 0) && ((x) % 100 != 0 || (x) % 400 == 0)) /* * An entry in the lexical lookup table. diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index c48c904..8e358e0 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -200,7 +200,7 @@ typedef enum { #define IMPLIES(a,b) ((!(a)) || (b)) #define NEGIMPL(a,b) -#define HAS(x,f) (x & FLAG(f)) +#define HAS(x,f) ((x) & FLAG(f)) #ifdef TCL_THREADS /* diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index 039b594..e0c39ad 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -216,7 +216,7 @@ typedef enum { #define IMPLIES(a,b) ((!(a)) || (b)) #define NEGIMPL(a,b) -#define HAS(x,f) (x & FLAG(f)) +#define HAS(x,f) ((x) & FLAG(f)) #ifdef TCL_THREADS /* diff --git a/generic/tclInt.h b/generic/tclInt.h index 491abe6..1954a13 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4958,7 +4958,7 @@ typedef struct NRE_callback { #define TCLNR_FREE(interp, ptr) TclSmallFreeEx((interp), (ptr)) #else #define TCLNR_ALLOC(interp, ptr) \ - (ptr = ((ClientData) ckalloc(sizeof(NRE_callback)))) + ((ptr) = ((void *)ckalloc(sizeof(NRE_callback)))) #define TCLNR_FREE(interp, ptr) ckfree((char *) (ptr)) #endif diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 44316ac..f061bc6 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -561,7 +561,7 @@ MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr); #define FOREACH(var,ary) \ for(i=0 ; i<(ary).num; i++) if ((ary).list[i] == NULL) { \ continue; \ - } else if (var = (ary).list[i], 1) + } else if ((var) = (ary).list[i], 1) /* * Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS diff --git a/generic/tclStringRep.h b/generic/tclStringRep.h index 25b854e..59e9499 100644 --- a/generic/tclStringRep.h +++ b/generic/tclStringRep.h @@ -67,7 +67,7 @@ typedef struct String { #define STRING_MAXCHARS \ (int)(((size_t)UINT_MAX - 1 - TclOffset(String, unicode))/sizeof(Tcl_UniChar)) #define STRING_SIZE(numChars) \ - (TclOffset(String, unicode) + ((numChars + 1) * sizeof(Tcl_UniChar))) + (TclOffset(String, unicode) + (((numChars) + 1) * sizeof(Tcl_UniChar))) #define stringCheckLimits(numChars) \ do { \ if ((numChars) < 0 || (numChars) > STRING_MAXCHARS) { \ diff --git a/generic/tclTrace.c b/generic/tclTrace.c index c82fc14..5ce4b95 100644 --- a/generic/tclTrace.c +++ b/generic/tclTrace.c @@ -160,8 +160,8 @@ typedef struct StringTraceData { #define FOREACH_COMMAND_TRACE(interp, name, clientData) \ (clientData) = NULL; \ - while ((clientData = Tcl_CommandTraceInfo(interp, name, 0, \ - TraceCommandProc, clientData)) != NULL) + while (((clientData) = Tcl_CommandTraceInfo((interp), (name), 0, \ + TraceCommandProc, (clientData))) != NULL) /* *---------------------------------------------------------------------- -- cgit v0.12 From 32ab46ae406d7fd3db0516dd45f38c7c48c6bd3c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Jan 2022 21:39:40 +0000 Subject: Fix [fba9c1fc12]: pointer arithmetic using NULL in PrintParse() --- generic/tclTest.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclTest.c b/generic/tclTest.c index 5774dfc..ed016fe 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -3596,8 +3596,9 @@ PrintParse( Tcl_NewIntObj(tokenPtr->numComponents)); } Tcl_ListObjAppendElement(NULL, objPtr, + parsePtr->commandStart ? Tcl_NewStringObj(parsePtr->commandStart + parsePtr->commandSize, - -1)); + -1) : Tcl_NewObj()); } /* -- cgit v0.12 From e874b759fc95fea19afd03d71388ed379872493f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Jan 2022 11:12:40 +0000 Subject: Suggested fix for [bca10e3790]: Undefined behavior in ResultAdd(). Make functions like ResultAdd() equal in tclIOGt.c and tclIOTrans.c --- generic/tclIOGT.c | 8 ++++---- generic/tclIORTrans.c | 30 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c index dadcb53..6b1c341 100644 --- a/generic/tclIOGT.c +++ b/generic/tclIOGT.c @@ -108,7 +108,7 @@ typedef struct ResultBuffer ResultBuffer; static inline void ResultClear(ResultBuffer *r); static inline void ResultInit(ResultBuffer *r); static inline int ResultEmpty(ResultBuffer *r); -static inline int ResultCopy(ResultBuffer *r, unsigned char *buf, +static inline size_t ResultCopy(ResultBuffer *r, unsigned char *buf, size_t toRead); static inline void ResultAdd(ResultBuffer *r, unsigned char *buf, size_t toWrite); @@ -1361,13 +1361,13 @@ ResultEmpty( *---------------------------------------------------------------------- */ -static inline int +static inline size_t ResultCopy( ResultBuffer *r, /* The buffer to read from. */ unsigned char *buf, /* The buffer to copy into. */ size_t toRead) /* Number of requested bytes. */ { - if (r->used == 0) { + if (ResultEmpty(r)) { /* * Nothing to copy in the case of an empty buffer. */ @@ -1424,7 +1424,7 @@ ResultAdd( unsigned char *buf, /* The buffer to read from. */ size_t toWrite) /* The number of bytes in 'buf'. */ { - if (r->used + toWrite > r->allocated) { + if ((r->used + toWrite + 1) > r->allocated) { /* * Extension of the internal buffer is required. */ diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index e0c39ad..eecd412 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -85,22 +85,22 @@ static const Tcl_ChannelType tclRTransformType = { * layers upon reading from the channel, plus the functions to manage such. */ -typedef struct _ResultBuffer_ { +typedef struct { unsigned char *buf; /* Reference to the buffer area. */ - int allocated; /* Allocated size of the buffer area. */ - int used; /* Number of bytes in the buffer, + size_t allocated; /* Allocated size of the buffer area. */ + size_t used; /* Number of bytes in the buffer, * <= allocated. */ } ResultBuffer; #define ResultLength(r) ((r)->used) /* static int ResultLength(ResultBuffer *r); */ -static void ResultClear(ResultBuffer *r); -static void ResultInit(ResultBuffer *r); -static void ResultAdd(ResultBuffer *r, unsigned char *buf, - int toWrite); -static int ResultCopy(ResultBuffer *r, unsigned char *buf, - int toRead); +static inline void ResultClear(ResultBuffer *r); +static inline void ResultInit(ResultBuffer *r); +static inline void ResultAdd(ResultBuffer *r, unsigned char *buf, + size_t toWrite); +static inline size_t ResultCopy(ResultBuffer *r, unsigned char *buf, + size_t toRead); #define RB_INCREMENT (512) @@ -2934,7 +2934,7 @@ TimerRun( *---------------------------------------------------------------------- */ -static void +static inline void ResultInit( ResultBuffer *rPtr) /* Reference to the structure to * initialize. */ @@ -2959,7 +2959,7 @@ ResultInit( *---------------------------------------------------------------------- */ -static void +static inline void ResultClear( ResultBuffer *rPtr) /* Reference to the buffer to clear out */ { @@ -2990,11 +2990,11 @@ ResultClear( *---------------------------------------------------------------------- */ -static void +static inline void ResultAdd( ResultBuffer *rPtr, /* The buffer to extend */ unsigned char *buf, /* The buffer to read from */ - int toWrite) /* The number of bytes in 'buf' */ + size_t toWrite) /* The number of bytes in 'buf' */ { if ((rPtr->used + toWrite + 1) > rPtr->allocated) { /* @@ -3038,11 +3038,11 @@ ResultAdd( *---------------------------------------------------------------------- */ -static int +static inline size_t ResultCopy( ResultBuffer *rPtr, /* The buffer to read from */ unsigned char *buf, /* The buffer to copy into */ - int toRead) /* Number of requested bytes */ + size_t toRead) /* Number of requested bytes */ { int copied; -- cgit v0.12 From d679a49bc0da1e368daa6af07fcf72af2e3dceb4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Jan 2022 11:46:50 +0000 Subject: Fix [6cb3db4965]: pointer arithmetic using NULL in InitArgsAndLocals() --- generic/tclProc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclProc.c b/generic/tclProc.c index 642294c..7921d38 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -1428,7 +1428,6 @@ InitArgsAndLocals( numArgs = procPtr->numArgs; argCt = framePtr->objc - skip; /* Set it to the number of args to the * procedure. */ - argObjs = framePtr->objv + skip; if (numArgs == 0) { if (argCt) { goto incorrectArgs; @@ -1436,6 +1435,7 @@ InitArgsAndLocals( goto correctArgs; } } + argObjs = framePtr->objv + skip; imax = ((argCt < numArgs-1) ? argCt : numArgs-1); for (i = 0; i < imax; i++, varPtr++, defPtr ? defPtr++ : defPtr) { /* -- cgit v0.12 From 1bc44ec32ab03ebaec021f52129ee1fefcac7850 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Jan 2022 12:22:51 +0000 Subject: Fix [816913a65e]: GrowStringBuffer(): signed integer overflow. And a few similar situations in other place --- generic/tclBinary.c | 2 +- generic/tclCkalloc.c | 2 +- generic/tclCompile.c | 2 +- generic/tclObj.c | 2 +- generic/tclProc.c | 2 +- generic/tclStringObj.c | 6 +++--- generic/tclStringRep.h | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 0296770..6f36d54 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -189,7 +189,7 @@ typedef struct ByteArray { } ByteArray; #define BYTEARRAY_SIZE(len) \ - ((unsigned) (TclOffset(ByteArray, bytes) + (len))) + (((unsigned)TclOffset(ByteArray, bytes) + (len))) #define GET_BYTEARRAY(objPtr) \ ((ByteArray *) (objPtr)->internalRep.twoPtrValue.ptr1) #define SET_BYTEARRAY(objPtr, baPtr) \ diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c index 8c83aeb..20285eb 100644 --- a/generic/tclCkalloc.c +++ b/generic/tclCkalloc.c @@ -41,7 +41,7 @@ typedef struct MemTag { * last field in the structure. */ } MemTag; -#define TAG_SIZE(bytesInString) ((unsigned) ((TclOffset(MemTag, string) + 1) + (bytesInString))) +#define TAG_SIZE(bytesInString) ((unsigned) ((TclOffset(MemTag, string) + 1U) + (bytesInString))) static MemTag *curTagPtr = NULL;/* Tag to use in all future mem_headers (set * by "memory tag" command). */ diff --git a/generic/tclCompile.c b/generic/tclCompile.c index eb2e16b..4a50089 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -3010,7 +3010,7 @@ TclFindCompiledLocal( if (create || (name == NULL)) { localVar = procPtr->numCompiledLocals; - localPtr = ckalloc(TclOffset(CompiledLocal, name) + nameBytes + 1); + localPtr = ckalloc(TclOffset(CompiledLocal, name) + 1U + nameBytes); if (procPtr->firstLocalPtr == NULL) { procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr; } else { diff --git a/generic/tclObj.c b/generic/tclObj.c index 0950dcd..1fd674f 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -576,7 +576,7 @@ TclContinuationsEnter( ThreadSpecificData *tsdPtr = TclGetContLineTable(); Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(tsdPtr->lineCLPtr, objPtr, &newEntry); - ContLineLoc *clLocPtr = (ContLineLoc *)ckalloc(TclOffset(ContLineLoc, loc) + (num + 1) *sizeof(int)); + ContLineLoc *clLocPtr = (ContLineLoc *)ckalloc(TclOffset(ContLineLoc, loc) + (num + 1U) *sizeof(int)); if (!newEntry) { /* diff --git a/generic/tclProc.c b/generic/tclProc.c index 7921d38..a533878 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -600,7 +600,7 @@ TclCreateProc( */ localPtr = (CompiledLocal *)ckalloc( - TclOffset(CompiledLocal, name) + fieldValues[0]->length + 1); + TclOffset(CompiledLocal, name) + 1U + fieldValues[0]->length); if (procPtr->firstLocalPtr == NULL) { procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr; } else { diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 75b449d..edfcb9f 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -151,7 +151,7 @@ GrowStringBuffer( if (flag == 0 || stringPtr->allocated > 0) { if (needed <= INT_MAX / 2) { attempt = 2 * needed; - ptr = (char *)attemptckrealloc(objPtr->bytes, attempt + 1); + ptr = (char *)attemptckrealloc(objPtr->bytes, attempt + 1U); } if (ptr == NULL) { /* @@ -164,7 +164,7 @@ GrowStringBuffer( int growth = (int) ((extra > limit) ? limit : extra); attempt = needed + growth; - ptr = (char *)attemptckrealloc(objPtr->bytes, attempt + 1); + ptr = (char *)attemptckrealloc(objPtr->bytes, attempt + 1U); } } if (ptr == NULL) { @@ -173,7 +173,7 @@ GrowStringBuffer( */ attempt = needed; - ptr = (char *)ckrealloc(objPtr->bytes, attempt + 1); + ptr = (char *)ckrealloc(objPtr->bytes, attempt + 1U); } objPtr->bytes = ptr; stringPtr->allocated = attempt; diff --git a/generic/tclStringRep.h b/generic/tclStringRep.h index 59e9499..c0adc10 100644 --- a/generic/tclStringRep.h +++ b/generic/tclStringRep.h @@ -67,7 +67,7 @@ typedef struct String { #define STRING_MAXCHARS \ (int)(((size_t)UINT_MAX - 1 - TclOffset(String, unicode))/sizeof(Tcl_UniChar)) #define STRING_SIZE(numChars) \ - (TclOffset(String, unicode) + (((numChars) + 1) * sizeof(Tcl_UniChar))) + (TclOffset(String, unicode) + (((numChars) + 1U) * sizeof(Tcl_UniChar))) #define stringCheckLimits(numChars) \ do { \ if ((numChars) < 0 || (numChars) > STRING_MAXCHARS) { \ -- cgit v0.12 From c513699e2c1d661da77c76813d7bdac494bfae91 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 14 Jan 2022 15:44:02 +0000 Subject: Fix [b241e4ccc0]: Error while building with Tcl 8.7a5... --- generic/tclTomMathDecls.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/generic/tclTomMathDecls.h b/generic/tclTomMathDecls.h index 1b2c05f..8d12adf 100644 --- a/generic/tclTomMathDecls.h +++ b/generic/tclTomMathDecls.h @@ -167,11 +167,11 @@ MODULE_SCOPE mp_err TclBN_mp_set_int(mp_int *a, unsigned long b); #define s_mp_toom_sqr TclBN_mp_toom_sqr #endif /* !TCL_WITH_EXTERNAL_TOMMATH */ -#define mp_init_set_int(a,b) (MP_DEPRECATED_PRAGMA("replaced by mp_init_ul") TclBN_mp_init_u64(a,(unsigned int)(b))) -#define mp_set_int(a,b) (MP_DEPRECATED_PRAGMA("replaced by mp_set_ul") (TclBN_mp_set_u64((a),((unsigned int)(b))),MP_OKAY)) -#define mp_set_long(a,b) (MP_DEPRECATED_PRAGMA("replaced by mp_set_ul") (TclBN_mp_set_u64((a),(long)(b)),MP_OKAY)) -#define mp_set_long_long(a,b) (MP_DEPRECATED_PRAGMA("replaced by mp_set_u64") (TclBN_mp_set_u64((a),(b)),MP_OKAY)) -#define mp_unsigned_bin_size(mp) (MP_DEPRECATED_PRAGMA("replaced by mp_ubin_size") (int)TclBN_mp_ubin_size(mp)) +#define mp_init_set_int(a,b) (MP_DEPRECATED_PRAGMA("replaced by mp_init_ul") mp_init_u64(a,(unsigned int)(b))) +#define mp_set_int(a,b) (MP_DEPRECATED_PRAGMA("replaced by mp_set_ul") (mp_set_u64((a),((unsigned int)(b))),MP_OKAY)) +#define mp_set_long(a,b) (MP_DEPRECATED_PRAGMA("replaced by mp_set_ul") (mp_set_u64((a),(long)(b)),MP_OKAY)) +#define mp_set_long_long(a,b) (MP_DEPRECATED_PRAGMA("replaced by mp_set_u64") (mp_set_u64((a),(b)),MP_OKAY)) +#define mp_unsigned_bin_size(mp) (MP_DEPRECATED_PRAGMA("replaced by mp_ubin_size") (int)mp_ubin_size(mp)) #undef TCL_STORAGE_CLASS #ifdef BUILD_tcl -- cgit v0.12 From 9bcfb6703d6eaa02bfcaad401aa83ce48309d4a1 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 14 Jan 2022 22:34:06 +0000 Subject: Proposed fix for [6474fbd934]: Tcl 8.7a5: why utf-8 is different? --- generic/tclEncoding.c | 3 --- tests/encoding.test | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 57c6148..037beed 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2323,9 +2323,6 @@ UtfToUtfProc( src = saveSrc; break; } - if (!(flags & TCL_ENCODING_MODIFIED)) { - ch = 0xFFFD; - } cesu8: *dst++ = (char) (((ch >> 12) | 0xE0) & 0xEF); *dst++ = (char) (((ch >> 6) | 0x80) & 0xBF); diff --git a/tests/encoding.test b/tests/encoding.test index c6f4e02..75e0dcc 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -349,61 +349,61 @@ test encoding-15.6 {UtfToUtfProc emoji character output} { set y [encoding convertto utf-8 \uDE02\uD83D\uDE02\uD83D] binary scan $y H* z list [string length $y] $z -} {10 efbfbdf09f9882efbfbd} +} {10 edb882f09f9882eda0bd} test encoding-15.7 {UtfToUtfProc emoji character output} { set x \uDE02\uD83D\uD83D set y [encoding convertto utf-8 \uDE02\uD83D\uD83D] binary scan $y H* z list [string length $x] [string length $y] $z -} {3 9 efbfbdefbfbdefbfbd} +} {3 9 edb882eda0bdeda0bd} test encoding-15.8 {UtfToUtfProc emoji character output} { set x \uDE02\uD83Dé set y [encoding convertto utf-8 \uDE02\uD83Dé] binary scan $y H* z list [string length $x] [string length $y] $z -} {3 8 efbfbdefbfbdc3a9} +} {3 8 edb882eda0bdc3a9} test encoding-15.9 {UtfToUtfProc emoji character output} { set x \uDE02\uD83DX set y [encoding convertto utf-8 \uDE02\uD83DX] binary scan $y H* z list [string length $x] [string length $y] $z -} {3 7 efbfbdefbfbd58} +} {3 7 edb882eda0bd58} test encoding-15.10 {UtfToUtfProc high surrogate character output} { set x \uDE02é set y [encoding convertto utf-8 \uDE02é] binary scan $y H* z list [string length $x] [string length $y] $z -} {2 5 efbfbdc3a9} +} {2 5 edb882c3a9} test encoding-15.11 {UtfToUtfProc low surrogate character output} { set x \uDA02é set y [encoding convertto utf-8 \uDA02é] binary scan $y H* z list [string length $x] [string length $y] $z -} {2 5 efbfbdc3a9} +} {2 5 eda882c3a9} test encoding-15.12 {UtfToUtfProc high surrogate character output} { set x \uDE02Y set y [encoding convertto utf-8 \uDE02Y] binary scan $y H* z list [string length $x] [string length $y] $z -} {2 4 efbfbd59} +} {2 4 edb88259} test encoding-15.13 {UtfToUtfProc low surrogate character output} { set x \uDA02Y set y [encoding convertto utf-8 \uDA02Y] binary scan $y H* z list [string length $x] [string length $y] $z -} {2 4 efbfbd59} +} {2 4 eda88259} test encoding-15.14 {UtfToUtfProc high surrogate character output} { set x \uDE02 set y [encoding convertto utf-8 \uDE02] binary scan $y H* z list [string length $x] [string length $y] $z -} {1 3 efbfbd} +} {1 3 edb882} test encoding-15.15 {UtfToUtfProc low surrogate character output} { set x \uDA02 set y [encoding convertto utf-8 \uDA02] binary scan $y H* z list [string length $x] [string length $y] $z -} {1 3 efbfbd} +} {1 3 eda882} test encoding-15.16 {UtfToUtfProc: Invalid 4-byte UTF-8, see [ed29806ba]} { set x \xF0\xA0\xA1\xC2 set y [encoding convertfrom utf-8 \xF0\xA0\xA1\xC2] -- cgit v0.12 From e5a2ebd71b2aa2b31ca5128eb47ae0a7fdd20bd5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 17 Jan 2022 10:35:18 +0000 Subject: Follow-up to [767e070d35]: Tcl_GetRange and Tcl_GetUniChar do not validate index inputs. Now that Tcl_GetRange() checks its arguments, the callers of this function don't have to do that any more. This also shows a off-by-one error in the Tcl_GetRange() check --- generic/tclCmdMZ.c | 10 +--------- generic/tclExecute.c | 33 ++++----------------------------- generic/tclStringObj.c | 7 +++---- 3 files changed, 8 insertions(+), 42 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index da3fc8b..5422b7f 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2183,15 +2183,7 @@ StringRangeCmd( return TCL_ERROR; } - if (first < 0) { - first = 0; - } - if (last >= length) { - last = length; - } - if (last >= first) { - Tcl_SetObjResult(interp, Tcl_GetRange(objv[1], first, last)); - } + Tcl_SetObjResult(interp, Tcl_GetRange(objv[1], first, last)); return TCL_OK; } diff --git a/generic/tclExecute.c b/generic/tclExecute.c index e5a6b71..c39bc21 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5609,17 +5609,7 @@ TEBCresume( goto gotError; } - if (fromIdx < 0) { - fromIdx = 0; - } - if (toIdx >= length) { - toIdx = length; - } - if (toIdx >= fromIdx) { - objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx); - } else { - TclNewObj(objResultPtr); - } + objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx); TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); NEXT_INST_V(1, 3, 1); @@ -5652,13 +5642,6 @@ TEBCresume( } toIdx = TclIndexDecode(toIdx, length - 1); - if (toIdx < 0) { - goto emptyRange; - } else if (toIdx >= length) { - toIdx = length - 1; - } - - assert ( toIdx >= 0 && toIdx < length ); /* assert ( fromIdx != TCL_INDEX_BEFORE ); @@ -5670,19 +5653,11 @@ TEBCresume( fromIdx = TCL_INDEX_START; } if (fromIdx == TCL_INDEX_AFTER) { - goto emptyRange; - } - - fromIdx = TclIndexDecode(fromIdx, length - 1); - if (fromIdx < 0) { - fromIdx = 0; - } - - if (fromIdx <= toIdx) { - objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx); - } else { emptyRange: TclNewObj(objResultPtr); + } else { + fromIdx = TclIndexDecode(fromIdx, length - 1); + objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx); } TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); NEXT_INST_F(9, 1, 1); diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index edfcb9f..fc675cf 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -739,8 +739,7 @@ Tcl_GetUnicodeFromObj( * * Create a Tcl Object that contains the chars between first and last of * the object indicated by "objPtr". If the object is not already a - * String object, convert it to one. The first and last indices are - * assumed to be in the appropriate range. + * String object, convert it to one. * * Results: * Returns a new Tcl Object of the String type. @@ -818,8 +817,8 @@ Tcl_GetRange( FillUnicodeRep(objPtr); stringPtr = GET_STRING(objPtr); } - if (last > stringPtr->numChars) { - last = stringPtr->numChars; + if (last >= stringPtr->numChars) { + last = stringPtr->numChars - 1; } if (last < first) { return Tcl_NewObj(); -- cgit v0.12 From 01a48e2369782044a30d922c5f8ed52262ef4fcd Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 17 Jan 2022 16:44:44 +0000 Subject: Tcl_NewObj() -> TclNewObj() --- generic/tclBasic.c | 10 +++++----- generic/tclBinary.c | 10 +++++----- generic/tclCompCmds.c | 35 ++++++++++++++++++----------------- generic/tclCompCmdsGR.c | 19 ++++++++++--------- generic/tclCompCmdsSZ.c | 14 ++++++++------ generic/tclCompExpr.c | 22 ++++++++++++++-------- generic/tclCompile.c | 5 +++-- generic/tclDisassemble.c | 29 ++++++++++++++++------------- generic/tclEncoding.c | 6 ++++-- generic/tclEnsemble.c | 8 +++++--- generic/tclIOCmd.c | 8 ++++---- generic/tclIORTrans.c | 2 +- generic/tclIOUtil.c | 11 ++++++----- generic/tclInterp.c | 10 ++++++---- generic/tclOO.c | 2 +- generic/tclOOBasic.c | 2 +- generic/tclOODefineCmds.c | 18 +++++++++--------- generic/tclOOInfo.c | 36 ++++++++++++++++++------------------ generic/tclOOMethod.c | 7 ++++--- generic/tclPathObj.c | 11 ++++++----- generic/tclPipe.c | 2 +- generic/tclPkg.c | 5 +++-- generic/tclRegexp.c | 2 +- generic/tclResult.c | 10 ++++++---- generic/tclStringObj.c | 11 +++++++---- generic/tclTimer.c | 18 ++++++++++-------- 26 files changed, 172 insertions(+), 141 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index aebcab7..5975fd3 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -517,7 +517,7 @@ Tcl_CreateInterp(void) iPtr->result = iPtr->resultSpace; iPtr->freeProc = NULL; iPtr->errorLine = 0; - iPtr->objResultPtr = Tcl_NewObj(); + TclNewObj(iPtr->objResultPtr); Tcl_IncrRefCount(iPtr->objResultPtr); iPtr->handle = TclHandleCreate(iPtr); iPtr->globalNsPtr = NULL; @@ -606,7 +606,7 @@ Tcl_CreateInterp(void) iPtr->activeInterpTracePtr = NULL; iPtr->assocData = NULL; iPtr->execEnvPtr = NULL; /* Set after namespaces initialized. */ - iPtr->emptyObjPtr = Tcl_NewObj(); + TclNewObj(iPtr->emptyObjPtr); /* Another empty object. */ Tcl_IncrRefCount(iPtr->emptyObjPtr); iPtr->resultSpace[0] = 0; @@ -671,7 +671,7 @@ Tcl_CreateInterp(void) * TIP #285, Script cancellation support. */ - iPtr->asyncCancelMsg = Tcl_NewObj(); + TclNewObj(iPtr->asyncCancelMsg); cancelInfo = (CancelInfo *)ckalloc(sizeof(CancelInfo)); cancelInfo->interp = interp; @@ -2652,7 +2652,7 @@ TclRenameCommand( } cmdNsPtr = cmdPtr->nsPtr; - oldFullName = Tcl_NewObj(); + TclNewObj(oldFullName); Tcl_IncrRefCount(oldFullName); Tcl_GetCommandFullName(interp, cmd, oldFullName); @@ -3857,7 +3857,7 @@ Tcl_ListMathFuncs( if (TCL_OK == Tcl_EvalObjEx(interp, script, 0)) { result = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); } else { - result = Tcl_NewObj(); + TclNewObj(result); } Tcl_DecrRefCount(script); Tcl_RestoreInterpState(interp, state); diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 6f36d54..5d317fa 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -927,7 +927,7 @@ BinaryFormatCmd( * bytes and filling with nulls. */ - resultPtr = Tcl_NewObj(); + TclNewObj(resultPtr); buffer = Tcl_SetByteArrayLength(resultPtr, length); memset(buffer, 0, length); @@ -1360,7 +1360,7 @@ BinaryScanCmd( } } src = buffer + offset; - valuePtr = Tcl_NewObj(); + TclNewObj(valuePtr); Tcl_SetObjLength(valuePtr, count); dest = TclGetString(valuePtr); @@ -1415,7 +1415,7 @@ BinaryScanCmd( } } src = buffer + offset; - valuePtr = Tcl_NewObj(); + TclNewObj(valuePtr); Tcl_SetObjLength(valuePtr, count); dest = TclGetString(valuePtr); @@ -1499,7 +1499,7 @@ BinaryScanCmd( if ((length - offset) < (count * size)) { goto done; } - valuePtr = Tcl_NewObj(); + TclNewObj(valuePtr); src = buffer + offset; for (i = 0; i < count; i++) { elementPtr = ScanNumber(src, cmd, flags, &numberCachePtr); @@ -2521,7 +2521,7 @@ BinaryEncode64( maxlen = 0; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count); if (count > 0) { unsigned char *cursor = NULL; diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index c8970ce..f28175b 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -311,7 +311,7 @@ TclCompileArraySetCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); dataTokenPtr = TokenAfter(varTokenPtr); - literalObj = Tcl_NewObj(); + TclNewObj(literalObj); isDataLiteral = TclWordKnownAtCompileTime(dataTokenPtr, literalObj); isDataValid = (isDataLiteral && Tcl_ListObjLength(NULL, literalObj, &len) == TCL_OK); @@ -890,10 +890,10 @@ TclCompileConcatCmd( * implement with a simple push. */ - listObj = Tcl_NewObj(); + TclNewObj(listObj); for (i = 1, tokenPtr = parsePtr->tokenPtr; i < parsePtr->numWords; i++) { tokenPtr = TokenAfter(tokenPtr); - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); if (!TclWordKnownAtCompileTime(tokenPtr, objPtr)) { Tcl_DecrRefCount(objPtr); Tcl_DecrRefCount(listObj); @@ -1288,10 +1288,10 @@ TclCompileDictCreateCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - dictObj = Tcl_NewObj(); + TclNewObj(dictObj); Tcl_IncrRefCount(dictObj); for (i=1 ; inumWords ; i+=2) { - keyObj = Tcl_NewObj(); + TclNewObj(keyObj); Tcl_IncrRefCount(keyObj); if (!TclWordKnownAtCompileTime(tokenPtr, keyObj)) { Tcl_DecrRefCount(keyObj); @@ -1299,7 +1299,7 @@ TclCompileDictCreateCmd( goto nonConstant; } tokenPtr = TokenAfter(tokenPtr); - valueObj = Tcl_NewObj(); + TclNewObj(valueObj); Tcl_IncrRefCount(valueObj); if (!TclWordKnownAtCompileTime(tokenPtr, valueObj)) { Tcl_DecrRefCount(keyObj); @@ -2298,8 +2298,9 @@ DisassembleDictUpdateInfo( { DictUpdateInfo *duiPtr = clientData; int i; - Tcl_Obj *variables = Tcl_NewObj(); + Tcl_Obj *variables; + TclNewObj(variables); for (i=0 ; ilength ; i++) { Tcl_ListObjAppendElement(NULL, variables, Tcl_NewIntObj(duiPtr->varIndices[i])); @@ -2722,7 +2723,7 @@ CompileEachloopCmd( * a scalar, or if any var list needs substitutions. */ - varListObj = Tcl_NewObj(); + TclNewObj(varListObj); for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { @@ -3041,7 +3042,7 @@ DisassembleForeachInfo( * Data stores. */ - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); for (i=0 ; inumLists ; i++) { Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(infoPtr->firstValueTemp + i)); @@ -3059,9 +3060,9 @@ DisassembleForeachInfo( * Assignment targets. */ - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); for (i=0 ; inumLists ; i++) { - innerPtr = Tcl_NewObj(); + TclNewObj(innerPtr); varsPtr = infoPtr->varLists[i]; for (j=0 ; jnumVars ; j++) { Tcl_ListObjAppendElement(NULL, innerPtr, @@ -3095,9 +3096,9 @@ DisassembleNewForeachInfo( * Assignment targets. */ - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); for (i=0 ; inumLists ; i++) { - innerPtr = Tcl_NewObj(); + TclNewObj(innerPtr); varsPtr = infoPtr->varLists[i]; for (j=0 ; jnumVars ; j++) { Tcl_ListObjAppendElement(NULL, innerPtr, @@ -3155,7 +3156,7 @@ TclCompileFormatCmd( * a case we can handle by compiling to a constant. */ - formatObj = Tcl_NewObj(); + TclNewObj(formatObj); Tcl_IncrRefCount(formatObj); tokenPtr = TokenAfter(tokenPtr); if (!TclWordKnownAtCompileTime(tokenPtr, formatObj)) { @@ -3166,7 +3167,7 @@ TclCompileFormatCmd( objv = ckalloc((parsePtr->numWords-2) * sizeof(Tcl_Obj *)); for (i=0 ; i+2 < parsePtr->numWords ; i++) { tokenPtr = TokenAfter(tokenPtr); - objv[i] = Tcl_NewObj(); + TclNewObj(objv[i]); Tcl_IncrRefCount(objv[i]); if (!TclWordKnownAtCompileTime(tokenPtr, objv[i])) { goto checkForStringConcatCase; @@ -3258,7 +3259,7 @@ TclCompileFormatCmd( start = Tcl_GetString(formatObj); /* The start of the currently-scanned literal * in the format string. */ - tmpObj = Tcl_NewObj(); /* The buffer used to accumulate the literal + TclNewObj(tmpObj); /* The buffer used to accumulate the literal * being built. */ for (bytes = start ; *bytes ; bytes++) { if (*bytes == '%') { @@ -3276,7 +3277,7 @@ TclCompileFormatCmd( if (len > 0) { PushLiteral(envPtr, b, len); Tcl_DecrRefCount(tmpObj); - tmpObj = Tcl_NewObj(); + TclNewObj(tmpObj); i++; } diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index c453878..a324706 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -54,9 +54,10 @@ TclGetIndexFromToken( int after, int *indexPtr) { - Tcl_Obj *tmpObj = Tcl_NewObj(); + Tcl_Obj *tmpObj; int result = TCL_ERROR; + TclNewObj(tmpObj); if (TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { result = TclIndexEncode(NULL, tmpObj, before, after, indexPtr); } @@ -599,7 +600,7 @@ TclCompileInfoCommandsCmd( return TCL_ERROR; } tokenPtr = TokenAfter(parsePtr->tokenPtr); - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); Tcl_IncrRefCount(objPtr); if (!TclWordKnownAtCompileTime(tokenPtr, objPtr)) { goto notCompilable; @@ -1180,9 +1181,9 @@ TclCompileListCmd( numWords = parsePtr->numWords; valueTokenPtr = TokenAfter(parsePtr->tokenPtr); - listObj = Tcl_NewObj(); + TclNewObj(listObj); for (i = 1; i < numWords && listObj != NULL; i++) { - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); if (TclWordKnownAtCompileTime(valueTokenPtr, objPtr)) { (void) Tcl_ListObjAppendElement(NULL, listObj, objPtr); } else { @@ -2289,7 +2290,7 @@ TclCompileRegsubCmd( Tcl_DStringInit(&pattern); tokenPtr = TokenAfter(tokenPtr); - patternObj = Tcl_NewObj(); + TclNewObj(patternObj); if (!TclWordKnownAtCompileTime(tokenPtr, patternObj)) { goto done; } @@ -2300,7 +2301,7 @@ TclCompileRegsubCmd( } tokenPtr = TokenAfter(tokenPtr); Tcl_DecrRefCount(patternObj); - patternObj = Tcl_NewObj(); + TclNewObj(patternObj); if (!TclWordKnownAtCompileTime(tokenPtr, patternObj)) { goto done; } @@ -2315,7 +2316,7 @@ TclCompileRegsubCmd( stringTokenPtr = TokenAfter(tokenPtr); tokenPtr = TokenAfter(stringTokenPtr); - replacementObj = Tcl_NewObj(); + TclNewObj(replacementObj); if (!TclWordKnownAtCompileTime(tokenPtr, replacementObj)) { goto done; } @@ -2466,7 +2467,7 @@ TclCompileReturnCmd( */ for (objc = 0; objc < numOptionWords; objc++) { - objv[objc] = Tcl_NewObj(); + TclNewObj(objv[objc]); Tcl_IncrRefCount(objv[objc]); if (!TclWordKnownAtCompileTime(wordTokenPtr, objv[objc])) { /* @@ -2686,7 +2687,7 @@ TclCompileUpvarCmd( * Push the frame index if it is known at compile time */ - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); tokenPtr = TokenAfter(parsePtr->tokenPtr); if (TclWordKnownAtCompileTime(tokenPtr, objPtr)) { CallFrame *framePtr; diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index ddfe0dc..862ebb5 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -248,7 +248,7 @@ TclCompileStringCatCmd( folded = NULL; wordTokenPtr = TokenAfter(parsePtr->tokenPtr); for (i = 1; i < numWords; i++) { - obj = Tcl_NewObj(); + TclNewObj(obj); if (TclWordKnownAtCompileTime(wordTokenPtr, obj)) { if (folded) { Tcl_AppendObjToObj(folded, obj); @@ -482,7 +482,7 @@ TclCompileStringIsCmd( if (parsePtr->numWords < 3 || parsePtr->numWords > 6) { return TCL_ERROR; } - isClass = Tcl_NewObj(); + TclNewObj(isClass); if (!TclWordKnownAtCompileTime(tokenPtr, isClass)) { Tcl_DecrRefCount(isClass); return TCL_ERROR; @@ -878,7 +878,7 @@ TclCompileStringMapCmd( } mapTokenPtr = TokenAfter(parsePtr->tokenPtr); stringTokenPtr = TokenAfter(mapTokenPtr); - mapObj = Tcl_NewObj(); + TclNewObj(mapObj); Tcl_IncrRefCount(mapObj); if (!TclWordKnownAtCompileTime(mapTokenPtr, mapObj)) { Tcl_DecrRefCount(mapObj); @@ -1418,7 +1418,7 @@ TclCompileSubstCmd( objv = TclStackAlloc(interp, /*numArgs*/ numOpts * sizeof(Tcl_Obj *)); for (objc = 0; objc < /*numArgs*/ numOpts; objc++) { - objv[objc] = Tcl_NewObj(); + TclNewObj(objv[objc]); Tcl_IncrRefCount(objv[objc]); if (!TclWordKnownAtCompileTime(wordTokenPtr, objv[objc])) { objc++; @@ -2570,12 +2570,13 @@ DisassembleJumptableInfo( unsigned int pcOffset) { JumptableInfo *jtPtr = clientData; - Tcl_Obj *mapping = Tcl_NewObj(); + Tcl_Obj *mapping; Tcl_HashEntry *hPtr; Tcl_HashSearch search; const char *keyPtr; int offset; + TclNewObj(mapping); hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search); for (; hPtr ; hPtr = Tcl_NextHashEntry(&search)) { keyPtr = Tcl_GetHashKey(&jtPtr->hashTable, hPtr); @@ -3587,8 +3588,9 @@ TclCompileUnsetCmd( */ for (i=1,varTokenPtr=parsePtr->tokenPtr ; inumWords ; i++) { - Tcl_Obj *leadingWord = Tcl_NewObj(); + Tcl_Obj *leadingWord; + TclNewObj(leadingWord); varTokenPtr = TokenAfter(varTokenPtr); if (!TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) { TclDecrRefCount(leadingWord); diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 52b62fc..ca9a21a 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1001,7 +1001,7 @@ ParseExpr( * later. */ - literal = Tcl_NewObj(); + TclNewObj(literal); if (TclWordKnownAtCompileTime(tokenPtr, literal)) { Tcl_ListObjAppendElement(NULL, litList, literal); complete = lastParsed = OT_LITERAL; @@ -1828,8 +1828,8 @@ Tcl_ParseExpr( { int code; OpNode *opTree = NULL; /* Will point to the tree of operators. */ - Tcl_Obj *litList = Tcl_NewObj(); /* List to hold the literals. */ - Tcl_Obj *funcList = Tcl_NewObj(); /* List to hold the functon names. */ + Tcl_Obj *litList; /* List to hold the literals. */ + Tcl_Obj *funcList; /* List to hold the functon names. */ Tcl_Parse *exprParsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse)); /* Holds the Tcl_Tokens of substitutions. */ @@ -1837,6 +1837,8 @@ Tcl_ParseExpr( numBytes = (start ? strlen(start) : 0); } + TclNewObj(litList); + TclNewObj(funcList); code = ParseExpr(interp, start, numBytes, &opTree, litList, funcList, exprParsePtr, 1 /* parseOnly */); Tcl_DecrRefCount(funcList); @@ -2003,7 +2005,7 @@ ParseLexeme( } } - literal = Tcl_NewObj(); + TclNewObj(literal); if (TclParseNumber(NULL, literal, NULL, start, numBytes, &end, TCL_PARSE_NO_WHITESPACE) == TCL_OK) { if (end < start + numBytes && !TclIsBareword(*end)) { @@ -2117,12 +2119,15 @@ TclCompileExpr( int optimize) /* 0 for one-off expressions. */ { OpNode *opTree = NULL; /* Will point to the tree of operators */ - Tcl_Obj *litList = Tcl_NewObj(); /* List to hold the literals */ - Tcl_Obj *funcList = Tcl_NewObj(); /* List to hold the functon names*/ + Tcl_Obj *litList; /* List to hold the literals */ + Tcl_Obj *funcList; /* List to hold the functon names*/ Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse)); /* Holds the Tcl_Tokens of substitutions */ + int code; - int code = ParseExpr(interp, script, numBytes, &opTree, litList, + TclNewObj(litList); + TclNewObj(funcList); + code = ParseExpr(interp, script, numBytes, &opTree, litList, funcList, parsePtr, 0 /* parseOnly */); if (code == TCL_OK) { @@ -2181,9 +2186,10 @@ ExecConstantExprTree( CompileEnv *envPtr; ByteCode *byteCodePtr; int code; - Tcl_Obj *byteCodeObj = Tcl_NewObj(); + Tcl_Obj *byteCodeObj; NRE_callback *rootPtr = TOP_CB(interp); + TclNewObj(byteCodeObj); /* * Note we are compiling an expression with literal arguments. This means * there can be no [info frame] calls when we execute the resulting diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 4a50089..9a59b71 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -1710,7 +1710,7 @@ TclWordKnownAtCompileTime( } tokenPtr++; if (valuePtr != NULL) { - tempPtr = Tcl_NewObj(); + TclNewObj(tempPtr); Tcl_IncrRefCount(tempPtr); } while (numComponents--) { @@ -1999,7 +1999,7 @@ CompileCommandTokens( Interp *iPtr = (Interp *) interp; Tcl_Token *tokenPtr = parsePtr->tokenPtr; ExtCmdLoc *eclPtr = envPtr->extCmdMapPtr; - Tcl_Obj *cmdObj = Tcl_NewObj(); + Tcl_Obj *cmdObj; Command *cmdPtr = NULL; int code = TCL_ERROR; int cmdKnown, expand = -1; @@ -2010,6 +2010,7 @@ CompileCommandTokens( int startCodeOffset = envPtr->codeNext - envPtr->codeStart; int depth = TclGetStackDepth(envPtr); + TclNewObj(cmdObj); assert (parsePtr->numWords > 0); /* Pre-Compile */ diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 8b137d4..3b03c42 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -798,8 +798,9 @@ Tcl_Obj * TclNewInstNameObj( unsigned char inst) { - Tcl_Obj *objPtr = Tcl_NewObj(); + Tcl_Obj *objPtr; + TclNewObj(objPtr); objPtr->typePtr = &tclInstNameType; objPtr->internalRep.longValue = (long) inst; objPtr->bytes = NULL; @@ -943,7 +944,7 @@ DisassembleByteCodeAsDicts( * Get the literals from the bytecode. */ - literals = Tcl_NewObj(); + TclNewObj(literals); for (i=0 ; inumLitObjects ; i++) { Tcl_ListObjAppendElement(NULL, literals, codePtr->objArrayPtr[i]); } @@ -952,7 +953,7 @@ DisassembleByteCodeAsDicts( * Get the variables from the bytecode. */ - variables = Tcl_NewObj(); + TclNewObj(variables); if (codePtr->procPtr) { int localCount = codePtr->procPtr->numCompiledLocals; CompiledLocal *localPtr = codePtr->procPtr->firstLocalPtr; @@ -960,7 +961,7 @@ DisassembleByteCodeAsDicts( for (i=0 ; inextPtr) { Tcl_Obj *descriptor[2]; - descriptor[0] = Tcl_NewObj(); + TclNewObj(descriptor[0]); if (!(localPtr->flags & (VAR_ARRAY|VAR_LINK))) { Tcl_ListObjAppendElement(NULL, descriptor[0], Tcl_NewStringObj("scalar", -1)); @@ -1000,12 +1001,12 @@ DisassembleByteCodeAsDicts( * Get the instructions from the bytecode. */ - instructions = Tcl_NewObj(); + TclNewObj(instructions); for (pc=codePtr->codeStart; pccodeStart+codePtr->numCodeBytes;){ const InstructionDesc *instDesc = &tclInstructionTable[*pc]; int address = pc - codePtr->codeStart; - inst = Tcl_NewObj(); + TclNewObj(inst); Tcl_ListObjAppendElement(NULL, inst, Tcl_NewStringObj( instDesc->name, -1)); opnd = pc + 1; @@ -1103,21 +1104,23 @@ DisassembleByteCodeAsDicts( * Get the auxiliary data from the bytecode. */ - aux = Tcl_NewObj(); + TclNewObj(aux); for (i=0 ; inumAuxDataItems ; i++) { AuxData *auxData = &codePtr->auxDataArrayPtr[i]; Tcl_Obj *auxDesc = Tcl_NewStringObj(auxData->type->name, -1); if (auxData->type->disassembleProc) { - Tcl_Obj *desc = Tcl_NewObj(); + Tcl_Obj *desc; + TclNewObj(desc); Tcl_DictObjPut(NULL, desc, Tcl_NewStringObj("name", -1), auxDesc); auxDesc = desc; auxData->type->disassembleProc(auxData->clientData, auxDesc, codePtr, 0); } else if (auxData->type->printProc) { - Tcl_Obj *desc = Tcl_NewObj(); + Tcl_Obj *desc; + TclNewObj(desc); auxData->type->printProc(auxData->clientData, desc, codePtr, 0); Tcl_ListObjAppendElement(NULL, auxDesc, desc); } @@ -1128,7 +1131,7 @@ DisassembleByteCodeAsDicts( * Get the exception ranges from the bytecode. */ - exn = Tcl_NewObj(); + TclNewObj(exn); for (i=0 ; inumExceptRanges ; i++) { ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i]; @@ -1163,7 +1166,7 @@ DisassembleByteCodeAsDicts( ? ((ptr)+=5 , TclGetInt4AtPtr((ptr)-4)) \ : ((ptr)+=1 , TclGetInt1AtPtr((ptr)-1))) - commands = Tcl_NewObj(); + TclNewObj(commands); codeOffPtr = codePtr->codeDeltaStart; codeLenPtr = codePtr->codeLengthStart; srcOffPtr = codePtr->srcDeltaStart; @@ -1176,7 +1179,7 @@ DisassembleByteCodeAsDicts( codeLength = Decode(codeLenPtr); sourceOffset += Decode(srcOffPtr); sourceLength = Decode(srcLenPtr); - cmd = Tcl_NewObj(); + TclNewObj(cmd); Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codefrom", -1), Tcl_NewIntObj(codeOffset)); Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codeto", -1), @@ -1211,7 +1214,7 @@ DisassembleByteCodeAsDicts( * Build the overall result. */ - description = Tcl_NewObj(); + TclNewObj(description); Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("literals", -1), literals); Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("variables", -1), diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 8fff493..4c59bc6 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -481,12 +481,13 @@ FillEncodingFileMap(void) */ int j, numFiles; - Tcl_Obj *directory, *matchFileList = Tcl_NewObj(); + Tcl_Obj *directory, *matchFileList; Tcl_Obj **filev; Tcl_GlobTypeData readableFiles = { TCL_GLOB_TYPE_FILE, TCL_GLOB_PERM_R, NULL, NULL }; + TclNewObj(matchFileList); Tcl_ListObjIndex(NULL, searchPath, i, &directory); Tcl_IncrRefCount(directory); Tcl_IncrRefCount(matchFileList); @@ -903,10 +904,11 @@ Tcl_GetEncodingNames( Tcl_HashTable table; Tcl_HashSearch search; Tcl_HashEntry *hPtr; - Tcl_Obj *map, *name, *result = Tcl_NewObj(); + Tcl_Obj *map, *name, *result; Tcl_DictSearch mapSearch; int dummy, done = 0; + TclNewObj(result); Tcl_InitObjHashTable(&table); /* diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 7f47510..bdf4d84 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -2913,7 +2913,7 @@ TclCompileEnsemble( DefineLineInformation; Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr); Tcl_Obj *mapObj, *subcmdObj, *targetCmdObj, *listObj, **elems; - Tcl_Obj *replaced = Tcl_NewObj(), *replacement; + Tcl_Obj *replaced, *replacement; Tcl_Command ensemble = (Tcl_Command) cmdPtr; Command *oldCmdPtr = cmdPtr, *newCmdPtr; int len, result, flags = 0, i, depth = 1, invokeAnyway = 0; @@ -2921,6 +2921,7 @@ TclCompileEnsemble( unsigned numBytes; const char *word; + TclNewObj(replaced); Tcl_IncrRefCount(replaced); if (parsePtr->numWords < depth + 1) { goto failed; @@ -3424,7 +3425,7 @@ CompileToInvokedCommand( * the implementation. */ - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr); bytes = Tcl_GetStringFromObj(objPtr, &length); if ((cmdPtr != NULL) && (cmdPtr->flags & CMD_VIA_RESOLVER)) { @@ -3463,8 +3464,9 @@ CompileBasicNArgCommand( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - Tcl_Obj *objPtr = Tcl_NewObj(); + Tcl_Obj *objPtr; + TclNewObj(objPtr); Tcl_IncrRefCount(objPtr); Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr); TclCompileInvocation(interp, parsePtr->tokenPtr, objPtr, diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index af1295f..f11a4ab 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -323,7 +323,7 @@ Tcl_GetsObjCmd( } TclChannelPreserve(chan); - linePtr = Tcl_NewObj(); + TclNewObj(linePtr); lineLen = Tcl_GetsObj(chan, linePtr); if (lineLen < 0) { if (!Tcl_Eof(chan) && !Tcl_InputBlocked(chan)) { @@ -463,7 +463,7 @@ Tcl_ReadObjCmd( } } - resultPtr = Tcl_NewObj(); + TclNewObj(resultPtr); Tcl_IncrRefCount(resultPtr); TclChannelPreserve(chan); charactersRead = Tcl_ReadChars(chan, resultPtr, toRead, 0); @@ -991,7 +991,7 @@ Tcl_ExecObjCmd( return TCL_OK; } - resultPtr = Tcl_NewObj(); + TclNewObj(resultPtr); if (Tcl_GetChannelHandle(chan, TCL_READABLE, NULL) == TCL_OK) { if (Tcl_ReadChars(chan, resultPtr, -1, 0) < 0) { /* @@ -1903,7 +1903,7 @@ ChanPipeObjCmd( channelNames[0] = Tcl_GetChannelName(rchan); channelNames[1] = Tcl_GetChannelName(wchan); - resultPtr = Tcl_NewObj(); + TclNewObj(resultPtr); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(channelNames[0], -1)); Tcl_ListObjAppendElement(NULL, resultPtr, diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index eecd412..97540a6 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -1224,7 +1224,7 @@ ReflectInput( } if (Tcl_IsShared(bufObj)) { Tcl_DecrRefCount(bufObj); - bufObj = Tcl_NewObj(); + TclNewObj(bufObj); Tcl_IncrRefCount(bufObj); } Tcl_SetByteArrayLength(bufObj, 0); diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 312fd08..1f8076a 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -1775,7 +1775,7 @@ Tcl_FSEvalFileEx( } } - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); Tcl_IncrRefCount(objPtr); /* @@ -1909,7 +1909,7 @@ TclNREvalFile( } } - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); Tcl_IncrRefCount(objPtr); /* @@ -3878,8 +3878,9 @@ Tcl_Obj * Tcl_FSListVolumes(void) { FilesystemRecord *fsRecPtr; - Tcl_Obj *resultPtr = Tcl_NewObj(); + Tcl_Obj *resultPtr; + TclNewObj(resultPtr); /* * Call each of the "listVolumes" function in succession. A non-NULL * return value indicates the particular function has succeeded. We call @@ -3945,7 +3946,7 @@ FsListMounts( if (fsRecPtr->fsPtr != &tclNativeFilesystem && fsRecPtr->fsPtr->matchInDirectoryProc != NULL) { if (resultPtr == NULL) { - resultPtr = Tcl_NewObj(); + TclNewObj(resultPtr); } fsRecPtr->fsPtr->matchInDirectoryProc(NULL, resultPtr, pathPtr, pattern, &mountsOnly); @@ -4021,7 +4022,7 @@ Tcl_FSSplitPath( * slashes (for example 'ftp://' is a valid vfs drive name) */ - result = Tcl_NewObj(); + TclNewObj(result); p = Tcl_GetString(pathPtr); Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(p, driveNameLength)); diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 4f5b300..271bbf2 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -1021,7 +1021,7 @@ NRInterpCmd( return TCL_ERROR; } iiPtr = (InterpInfo *) ((Interp *) childInterp)->interpInfo; - resultPtr = Tcl_NewObj(); + TclNewObj(resultPtr); hPtr = Tcl_FirstHashEntry(&iiPtr->parent.childTable, &hashSearch); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&hashSearch)) { string = Tcl_GetHashKey(&iiPtr->parent.childTable, hPtr); @@ -1748,10 +1748,11 @@ AliasList( { Tcl_HashEntry *entryPtr; Tcl_HashSearch hashSearch; - Tcl_Obj *resultPtr = Tcl_NewObj(); + Tcl_Obj *resultPtr; Alias *aliasPtr; Child *childPtr; + TclNewObj(resultPtr); childPtr = &((InterpInfo *) ((Interp *) childInterp)->interpInfo)->child; entryPtr = Tcl_FirstHashEntry(&childPtr->aliasTable, &hashSearch); @@ -2725,7 +2726,7 @@ ChildDebugCmd( iPtr = (Interp *) childInterp; if (objc == 0) { - resultPtr = Tcl_NewObj(); + TclNewObj(resultPtr); Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj("-frame", -1)); Tcl_ListObjAppendElement(NULL, resultPtr, @@ -2994,11 +2995,12 @@ ChildHidden( Tcl_Interp *interp, /* Interp for data return. */ Tcl_Interp *childInterp) /* Interp whose hidden commands to query. */ { - Tcl_Obj *listObjPtr = Tcl_NewObj(); /* Local object pointer. */ + Tcl_Obj *listObjPtr; /* Local object pointer. */ Tcl_HashTable *hTblPtr; /* For local searches. */ Tcl_HashEntry *hPtr; /* For local searches. */ Tcl_HashSearch hSearch; /* For local searches. */ + TclNewObj(listObjPtr); hTblPtr = ((Interp *) childInterp)->hiddenCmdTablePtr; if (hTblPtr != NULL) { for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); diff --git a/generic/tclOO.c b/generic/tclOO.c index 053abfe..9a32543 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -2925,7 +2925,7 @@ TclOOObjectName( if (oPtr->cachedNameObj) { return oPtr->cachedNameObj; } - namePtr = Tcl_NewObj(); + TclNewObj(namePtr); Tcl_GetCommandFullName(interp, oPtr->command, namePtr); Tcl_IncrRefCount(namePtr); oPtr->cachedNameObj = namePtr; diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index b7f70e7..e746b64 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -727,7 +727,7 @@ TclOO_Object_VarName( * (including traversing variable links), convert back to a name. */ - varNamePtr = Tcl_NewObj(); + TclNewObj(varNamePtr); if (aryVar != NULL) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index aeee165..c1115be 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -850,8 +850,8 @@ MagicDefinitionInvoke( * comments above for why these contortions are necessary. */ - objPtr = Tcl_NewObj(); - obj2Ptr = Tcl_NewObj(); + TclNewObj(objPtr); + TclNewObj(obj2Ptr); cmd = FindCommand(interp, objv[cmdIndex], nsPtr); if (cmd == NULL) { /* @@ -1874,7 +1874,7 @@ ClassFilterGet( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(filterObj, oPtr->classPtr->filters) { Tcl_ListObjAppendElement(NULL, resultObj, filterObj); } @@ -1954,7 +1954,7 @@ ClassMixinGet( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(mixinPtr, oPtr->classPtr->mixins) { Tcl_ListObjAppendElement(NULL, resultObj, TclOOObjectName(interp, mixinPtr->thisPtr)); @@ -2059,7 +2059,7 @@ ClassSuperGet( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(superPtr, oPtr->classPtr->superclasses) { Tcl_ListObjAppendElement(NULL, resultObj, TclOOObjectName(interp, superPtr->thisPtr)); @@ -2224,7 +2224,7 @@ ClassVarsGet( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(variableObj, oPtr->classPtr->variables) { Tcl_ListObjAppendElement(NULL, resultObj, variableObj); } @@ -2360,7 +2360,7 @@ ObjFilterGet( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(filterObj, oPtr->filters) { Tcl_ListObjAppendElement(NULL, resultObj, filterObj); } @@ -2428,7 +2428,7 @@ ObjMixinGet( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(mixinPtr, oPtr->mixins) { if (mixinPtr) { Tcl_ListObjAppendElement(NULL, resultObj, @@ -2512,7 +2512,7 @@ ObjVarsGet( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(variableObj, oPtr->variables) { Tcl_ListObjAppendElement(NULL, resultObj, variableObj); } diff --git a/generic/tclOOInfo.c b/generic/tclOOInfo.c index 4b25c1a..9f1233c 100644 --- a/generic/tclOOInfo.c +++ b/generic/tclOOInfo.c @@ -266,13 +266,13 @@ InfoObjectDefnCmd( return TCL_ERROR; } - resultObjs[0] = Tcl_NewObj(); + TclNewObj(resultObjs[0]); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_Obj *argObj; - argObj = Tcl_NewObj(); + TclNewObj(argObj); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, -1)); if (localPtr->defValuePtr != NULL) { @@ -316,7 +316,7 @@ InfoObjectFiltersCmd( if (oPtr == NULL) { return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(filterObj, oPtr->filters) { Tcl_ListObjAppendElement(NULL, resultObj, filterObj); @@ -560,7 +560,7 @@ InfoObjectMethodsCmd( } } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); if (recurse) { const char **names; int i, numNames = TclOOGetSortedMethodList(oPtr, flag, &names); @@ -671,7 +671,7 @@ InfoObjectMixinsCmd( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(mixinPtr, oPtr->mixins) { if (!mixinPtr) { continue; @@ -746,7 +746,7 @@ InfoObjectVariablesCmd( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(variableObj, oPtr->variables) { Tcl_ListObjAppendElement(NULL, resultObj, variableObj); } @@ -788,7 +788,7 @@ InfoObjectVarsCmd( if (objc == 3) { pattern = TclGetString(objv[2]); } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); /* * Extract the information we need from the object's namespace's table of @@ -856,13 +856,13 @@ InfoClassConstrCmd( return TCL_ERROR; } - resultObjs[0] = Tcl_NewObj(); + TclNewObj(resultObjs[0]); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_Obj *argObj; - argObj = Tcl_NewObj(); + TclNewObj(argObj); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, -1)); if (localPtr->defValuePtr != NULL) { @@ -924,13 +924,13 @@ InfoClassDefnCmd( return TCL_ERROR; } - resultObjs[0] = Tcl_NewObj(); + TclNewObj(resultObjs[0]); for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { Tcl_Obj *argObj; - argObj = Tcl_NewObj(); + TclNewObj(argObj); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, -1)); if (localPtr->defValuePtr != NULL) { @@ -1018,7 +1018,7 @@ InfoClassFiltersCmd( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(filterObj, clsPtr->filters) { Tcl_ListObjAppendElement(NULL, resultObj, filterObj); } @@ -1112,7 +1112,7 @@ InfoClassInstancesCmd( pattern = TclGetString(objv[2]); } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(oPtr, clsPtr->instances) { Tcl_Obj *tmpObj = TclOOObjectName(interp, oPtr); @@ -1183,7 +1183,7 @@ InfoClassMethodsCmd( } } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); if (recurse) { const char **names; int i, numNames = TclOOGetSortedClassMethodList(clsPtr, flag, &names); @@ -1290,7 +1290,7 @@ InfoClassMixinsCmd( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(mixinPtr, clsPtr->mixins) { if (!mixinPtr) { continue; @@ -1336,7 +1336,7 @@ InfoClassSubsCmd( pattern = TclGetString(objv[2]); } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(subclassPtr, clsPtr->subclasses) { Tcl_Obj *tmpObj = TclOOObjectName(interp, subclassPtr->thisPtr); @@ -1387,7 +1387,7 @@ InfoClassSupersCmd( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(superPtr, clsPtr->superclasses) { Tcl_ListObjAppendElement(NULL, resultObj, TclOOObjectName(interp, superPtr->thisPtr)); @@ -1426,7 +1426,7 @@ InfoClassVariablesCmd( return TCL_ERROR; } - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); FOREACH(variableObj, clsPtr->variables) { Tcl_ListObjAppendElement(NULL, resultObj, variableObj); } diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c index cd3c2c2..80e8478 100644 --- a/generic/tclOOMethod.c +++ b/generic/tclOOMethod.c @@ -394,7 +394,7 @@ TclOONewProcMethod( if (argsObj == NULL) { argsLen = -1; - argsObj = Tcl_NewObj(); + TclNewObj(argsObj); Tcl_IncrRefCount(argsObj); procName = ""; } else if (Tcl_ListObjLength(interp, argsObj, &argsLen) != TCL_OK) { @@ -1293,12 +1293,13 @@ CloneProcedureMethod( * Copy the argument list. */ - argsObj = Tcl_NewObj(); + TclNewObj(argsObj); for (localPtr=pmPtr->procPtr->firstLocalPtr; localPtr!=NULL; localPtr=localPtr->nextPtr) { if (TclIsVarArgument(localPtr)) { - Tcl_Obj *argObj = Tcl_NewObj(); + Tcl_Obj *argObj; + TclNewObj(argObj); Tcl_ListObjAppendElement(NULL, argObj, Tcl_NewStringObj(localPtr->name, -1)); if (localPtr->defValuePtr != NULL) { diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index d919c40..b69607a 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -743,7 +743,7 @@ TclPathPart( (Tcl_FSGetPathType(pathPtr) == TCL_PATH_RELATIVE))) { Tcl_ListObjIndex(NULL, splitPtr, splitElements-1, &resultPtr); } else { - resultPtr = Tcl_NewObj(); + TclNewObj(resultPtr); } } else { /* @@ -781,7 +781,7 @@ GetExtension( tail = TclGetString(pathPtr); extension = TclGetExtension(tail); if (extension == NULL) { - ret = Tcl_NewObj(); + TclNewObj(ret); } else { ret = Tcl_NewStringObj(extension, -1); } @@ -857,7 +857,8 @@ TclJoinPath( assert ( elements >= 0 ); if (elements == 0) { - return Tcl_NewObj(); + TclNewObj(res); + return res; } assert ( elements > 0 ); @@ -1056,7 +1057,7 @@ TclJoinPath( noQuickReturn: if (res == NULL) { - res = Tcl_NewObj(); + TclNewObj(res); ptr = Tcl_GetStringFromObj(res, &length); } else { ptr = Tcl_GetStringFromObj(res, &length); @@ -1317,7 +1318,7 @@ TclNewFSPathObj( return pathPtr; } - pathPtr = Tcl_NewObj(); + TclNewObj(pathPtr); fsPathPtr = ckalloc(sizeof(FsPath)); /* diff --git a/generic/tclPipe.c b/generic/tclPipe.c index 7d5fab0..f5c82f1 100644 --- a/generic/tclPipe.c +++ b/generic/tclPipe.c @@ -371,7 +371,7 @@ TclCleanupChildren( Tcl_Obj *objPtr; Tcl_Seek(errorChan, (Tcl_WideInt)0, SEEK_SET); - objPtr = Tcl_NewObj(); + TclNewObj(objPtr); count = Tcl_ReadChars(errorChan, objPtr, -1, 0); if (count < 0) { result = TCL_ERROR; diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 2150c31..67c91c4 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -1014,7 +1014,7 @@ TclNRPackageObjCmd( } else { Tcl_Obj *resultObj; - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); tablePtr = &iPtr->packageTable; for (hPtr = Tcl_FirstHashEntry(tablePtr, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { @@ -1257,8 +1257,9 @@ TclNRPackageObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "package"); return TCL_ERROR; } else { - Tcl_Obj *resultObj = Tcl_NewObj(); + Tcl_Obj *resultObj; + TclNewObj(resultObj); argv2 = TclGetString(objv[2]); hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2); if (hPtr != NULL) { diff --git a/generic/tclRegexp.c b/generic/tclRegexp.c index 2070956..bd923ba 100644 --- a/generic/tclRegexp.c +++ b/generic/tclRegexp.c @@ -677,7 +677,7 @@ TclRegAbout( * well and Tcl has other limits that constrain things as well... */ - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewIntObj((int) regexpPtr->re.re_nsub)); diff --git a/generic/tclResult.c b/generic/tclResult.c index b1cf9ee..be84a61 100644 --- a/generic/tclResult.c +++ b/generic/tclResult.c @@ -245,7 +245,7 @@ Tcl_SaveResult( */ statePtr->objResultPtr = iPtr->objResultPtr; - iPtr->objResultPtr = Tcl_NewObj(); + TclNewObj(iPtr->objResultPtr); Tcl_IncrRefCount(iPtr->objResultPtr); /* @@ -1026,13 +1026,14 @@ Tcl_SetErrorCodeVA( Tcl_Interp *interp, /* Interpreter in which to set errorCode */ va_list argList) /* Variable argument list. */ { - Tcl_Obj *errorObj = Tcl_NewObj(); + Tcl_Obj *errorObj; /* * Scan through the arguments one at a time, appending them to the * errorCode field as list elements. */ + TclNewObj(errorObj); while (1) { char *elem = va_arg(argList, char *); @@ -1387,9 +1388,10 @@ TclMergeReturnOptions( int code = TCL_OK; int level = 1; Tcl_Obj *valuePtr; - Tcl_Obj *returnOpts = Tcl_NewObj(); + Tcl_Obj *returnOpts; Tcl_Obj **keys = GetKeys(); + TclNewObj(returnOpts); for (; objc > 1; objv += 2, objc -= 2) { int optLen; const char *opt = TclGetStringFromObj(objv[0], &optLen); @@ -1585,7 +1587,7 @@ Tcl_GetReturnOptions( if (iPtr->returnOpts) { options = Tcl_DuplicateObj(iPtr->returnOpts); } else { - options = Tcl_NewObj(); + TclNewObj(options); } if (result == TCL_RETURN) { diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index fc675cf..756b948 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -776,7 +776,8 @@ Tcl_GetRange( last = length - 1; } if (last < first) { - return Tcl_NewObj(); + TclNewObj(newObjPtr); + return newObjPtr; } return Tcl_NewByteArrayObj(bytes + first, last - first + 1); } @@ -801,9 +802,10 @@ Tcl_GetRange( last = stringPtr->numChars - 1; } if (last < first) { - return Tcl_NewObj(); + TclNewObj(newObjPtr); + return newObjPtr; } - newObjPtr = Tcl_NewStringObj(objPtr->bytes + first, last-first+1); + newObjPtr = Tcl_NewStringObj(objPtr->bytes + first, last - first + 1); /* * Since we know the char length of the result, store it. @@ -821,7 +823,8 @@ Tcl_GetRange( last = stringPtr->numChars - 1; } if (last < first) { - return Tcl_NewObj(); + TclNewObj(newObjPtr); + return newObjPtr; } #if TCL_UTF_MAX == 4 /* See: bug [11ae2be95dac9417] */ diff --git a/generic/tclTimer.c b/generic/tclTimer.c index d30879f..500a75e 100644 --- a/generic/tclTimer.c +++ b/generic/tclTimer.c @@ -949,13 +949,14 @@ Tcl_AfterObjCmd( break; case AFTER_INFO: if (objc == 2) { - Tcl_Obj *resultObj = Tcl_NewObj(); + Tcl_Obj *resultObj; + TclNewObj(resultObj); for (afterPtr = assocPtr->firstAfterPtr; afterPtr != NULL; afterPtr = afterPtr->nextPtr) { if (assocPtr->interp == interp) { - Tcl_ListObjAppendElement(NULL, resultObj, Tcl_ObjPrintf( - "after#%d", afterPtr->id)); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_ObjPrintf( + "after#%d", afterPtr->id)); } } Tcl_SetObjResult(interp, resultObj); @@ -974,14 +975,15 @@ Tcl_AfterObjCmd( Tcl_SetErrorCode(interp, "TCL","LOOKUP","EVENT", eventStr, NULL); return TCL_ERROR; } else { - Tcl_Obj *resultListPtr = Tcl_NewObj(); + Tcl_Obj *resultListPtr; - Tcl_ListObjAppendElement(interp, resultListPtr, - afterPtr->commandPtr); - Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj( + TclNewObj(resultListPtr); + Tcl_ListObjAppendElement(interp, resultListPtr, + afterPtr->commandPtr); + Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj( (afterPtr->token == NULL) ? "idle" : "timer", -1)); Tcl_SetObjResult(interp, resultListPtr); - } + } break; default: Tcl_Panic("Tcl_AfterObjCmd: bad subcommand index to afterSubCmds"); -- cgit v0.12 From b563c159d7f63f0a4ca1e9190ec4111d5d4908d9 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 17 Jan 2022 17:07:14 +0000 Subject: Fix merge conflict previous commit --- generic/tclBasic.c | 3 +-- generic/tclCompExpr.c | 2 -- generic/tclCompile.c | 1 - generic/tclIOUtil.c | 1 - 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 35fd5a9..45a430f 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -901,8 +901,7 @@ Tcl_CreateInterp(void) iPtr->activeInterpTracePtr = NULL; iPtr->assocData = NULL; iPtr->execEnvPtr = NULL; /* Set after namespaces initialized. */ - TclNewObj(iPtr->emptyObjPtr); - /* Another empty object. */ + TclNewObj(iPtr->emptyObjPtr); /* Another empty object. */ Tcl_IncrRefCount(iPtr->emptyObjPtr); #ifndef TCL_NO_DEPRECATED iPtr->resultSpace[0] = 0; diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 8248770..23d8711 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1880,8 +1880,6 @@ Tcl_ParseExpr( numBytes = (start ? strlen(start) : 0); } - TclNewObj(litList); - TclNewObj(funcList); code = ParseExpr(interp, start, numBytes, &opTree, litList, funcList, exprParsePtr, 1 /* parseOnly */); Tcl_DecrRefCount(funcList); diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 650a6d4..f7479f0 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -2044,7 +2044,6 @@ CompileCommandTokens( int startCodeOffset = envPtr->codeNext - envPtr->codeStart; int depth = TclGetStackDepth(envPtr); - TclNewObj(cmdObj); assert (parsePtr->numWords > 0); /* Pre-Compile */ diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 6b1dc3c..87e60c3 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -3775,7 +3775,6 @@ Tcl_FSListVolumes(void) FilesystemRecord *fsRecPtr; Tcl_Obj *resultPtr; - TclNewObj(resultPtr); /* * Call each "listVolumes" function of each registered filesystem in * succession. A non-NULL return value indicates the particular function -- cgit v0.12 From c3bcd951b8dd8bf57202915b9d914bcddc73b9bb Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 17 Jan 2022 17:26:37 +0000 Subject: Possible fix for [e9a2715d91]: Tcl 8.6.11: Incompatible Tcl_GetRange() --- generic/tclCmdMZ.c | 14 ++++++++++---- generic/tclExecute.c | 15 +++++++++++---- generic/tclStringObj.c | 12 ++++++++---- generic/tclTest.c | 2 +- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 5422b7f..bf75d44 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -395,9 +395,13 @@ Tcl_RegexpObjCmd( newPtr = Tcl_NewListObj(2, objs); } else { if (i <= info.nsubs) { - newPtr = Tcl_GetRange(objPtr, - offset + info.matches[i].start, - offset + info.matches[i].end - 1); + if (info.matches[i].end <= 0) { + TclNewObj(newPtr); + } else { + newPtr = Tcl_GetRange(objPtr, + offset + info.matches[i].start, + offset + info.matches[i].end - 1); + } } else { TclNewObj(newPtr); } @@ -2183,7 +2187,9 @@ StringRangeCmd( return TCL_ERROR; } - Tcl_SetObjResult(interp, Tcl_GetRange(objv[1], first, last)); + if (last >= 0) { + Tcl_SetObjResult(interp, Tcl_GetRange(objv[1], first, last)); + } return TCL_OK; } diff --git a/generic/tclExecute.c b/generic/tclExecute.c index c39bc21..a3b0401 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5609,7 +5609,11 @@ TEBCresume( goto gotError; } - objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx); + if (toIdx < 0) { + TclNewObj(objResultPtr); + } else { + objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx); + } TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); NEXT_INST_V(1, 3, 1); @@ -5653,11 +5657,14 @@ TEBCresume( fromIdx = TCL_INDEX_START; } if (fromIdx == TCL_INDEX_AFTER) { + goto emptyRange; + } + fromIdx = TclIndexDecode(fromIdx, length - 1); + if (toIdx >= 0) { + objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx); + } else { emptyRange: TclNewObj(objResultPtr); - } else { - fromIdx = TclIndexDecode(fromIdx, length - 1); - objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx); } TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); NEXT_INST_F(9, 1, 1); diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 756b948..b4f05dd 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -772,7 +772,7 @@ Tcl_GetRange( if (TclIsPureByteArray(objPtr)) { unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &length); - if (last >= length) { + if (last < 0 || last >= length) { last = length - 1; } if (last < first) { @@ -798,7 +798,7 @@ Tcl_GetRange( TclNumUtfChars(stringPtr->numChars, objPtr->bytes, objPtr->length); } if (stringPtr->numChars == objPtr->length) { - if (last >= stringPtr->numChars) { + if (last < 0 || last >= stringPtr->numChars) { last = stringPtr->numChars - 1; } if (last < first) { @@ -819,7 +819,7 @@ Tcl_GetRange( FillUnicodeRep(objPtr); stringPtr = GET_STRING(objPtr); } - if (last >= stringPtr->numChars) { + if (last < 0 || last >= stringPtr->numChars) { last = stringPtr->numChars - 1; } if (last < first) { @@ -2116,7 +2116,11 @@ Tcl_AppendFormatToObj( if (gotPrecision) { numChars = Tcl_GetCharLength(segment); if (precision < numChars) { - segment = Tcl_GetRange(segment, 0, precision - 1); + if (precision < 1) { + TclNewObj(segment); + } else { + segment = Tcl_GetRange(segment, 0, precision - 1); + } numChars = precision; Tcl_IncrRefCount(segment); allocSegment = 1; diff --git a/generic/tclTest.c b/generic/tclTest.c index ed016fe..8d22edf 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -3918,7 +3918,7 @@ TestregexpObjCmd( if (ii == -1) { TclRegExpRangeUniChar(regExpr, ii, &start, &end); newPtr = Tcl_GetRange(objPtr, start, end); - } else if (ii > info.nsubs) { + } else if (ii > info.nsubs || info.matches[ii].end <= 0) { newPtr = Tcl_NewObj(); } else { newPtr = Tcl_GetRange(objPtr, info.matches[ii].start, -- cgit v0.12 From d0b286927306af8bde7031529ad180eaa07dcc73 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 18 Jan 2022 23:26:20 +0000 Subject: Update documentation for Tcl_GetRange() --- doc/StringObj.3 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/StringObj.3 b/doc/StringObj.3 index 772073e..90b53f2 100644 --- a/doc/StringObj.3 +++ b/doc/StringObj.3 @@ -111,10 +111,12 @@ If negative, all characters up to the first null character are used. The index of the Unicode character to return. .AP int first in The index of the first Unicode character in the Unicode range to be -returned as a new value. +returned as a new value. If negative, behave the same as if the +value was 0. .AP int last in The index of the last Unicode character in the Unicode range to be -returned as a new value. +returned as a new value. If negative, take all characters up to +the last one available. .AP Tcl_Obj *objPtr in/out Points to a value to manipulate. .AP Tcl_Obj *appendObjPtr in -- cgit v0.12