From 648162204d4c9bd80cde739b4cad361de6ebe6f1 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 12 May 2020 18:59:04 +0000 Subject: First, experimental implementation of TIP #575. Barely tested, will fail. WIP --- generic/tcl.decls | 17 ++++++++++++++--- generic/tclCmdMZ.c | 2 +- generic/tclCompExpr.c | 8 ++++---- generic/tclDecls.h | 51 +++++++++++++++++++++++++++++++++++--------------- generic/tclEncoding.c | 4 ++-- generic/tclInt.h | 14 -------------- generic/tclParse.c | 8 ++++---- generic/tclStringObj.c | 6 +++--- generic/tclStubInit.c | 34 ++++++++++++++++++++++++++++++--- generic/tclTest.c | 8 ++++---- generic/tclUtf.c | 14 ++++---------- generic/tclUtil.c | 4 ++-- 12 files changed, 105 insertions(+), 65 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index a550411..4ccedd1 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -1163,7 +1163,7 @@ declare 325 { const char *Tcl_UtfAtIndex(const char *src, int index) } declare 326 { - int Tcl_UtfCharComplete(const char *src, int length) + int TclUtfCharComplete(const char *src, int length) } declare 327 { int Tcl_UtfBackslash(const char *src, int *readPtr, char *dst) @@ -1175,10 +1175,10 @@ declare 329 { const char *Tcl_UtfFindLast(const char *src, int ch) } declare 330 { - const char *Tcl_UtfNext(const char *src) + const char *TclUtfNext(const char *src) } declare 331 { - const char *Tcl_UtfPrev(const char *src, const char *start) + const char *TclUtfPrev(const char *src, const char *start) } declare 332 { int Tcl_UtfToExternal(Tcl_Interp *interp, Tcl_Encoding encoding, @@ -2402,6 +2402,17 @@ declare 648 { int length, Tcl_DString *dsPtr) } +# TIP #575 +declare 649 { + int Tcl_UtfCharComplete(const char *src, int length) +} +declare 650 { + const char *Tcl_UtfNext(const char *src) +} +declare 651 { + const char *Tcl_UtfPrev(const char *src, const char *start) +} + # ----- BASELINE -- FOR -- 8.7.0 ----- # ############################################################################## diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 56df0dd..8f0465d 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2529,7 +2529,7 @@ StringStartCmd( break; } - next = TclUtfPrev(p, string); + next = Tcl_UtfPrev(p, string); do { next += delta; delta = TclUtfToUCS4(next, &ch); diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 4fb41fc..4d448b9 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1893,7 +1893,7 @@ ParseLexeme( { const char *end; int scanned; - Tcl_UniChar ch = 0; + int ch; Tcl_Obj *literal = NULL; unsigned char byte; @@ -2101,13 +2101,13 @@ ParseLexeme( if (!TclIsBareword(*start) || *start == '_') { if (Tcl_UtfCharComplete(start, numBytes)) { - scanned = TclUtfToUniChar(start, &ch); + scanned = TclUtfToUCS4(start, &ch); } else { - char utfBytes[4]; + char utfBytes[8]; memcpy(utfBytes, start, numBytes); utfBytes[numBytes] = '\0'; - scanned = TclUtfToUniChar(utfBytes, &ch); + scanned = TclUtfToUCS4(utfBytes, &ch); } *lexemePtr = INVALID; Tcl_DecrRefCount(literal); diff --git a/generic/tclDecls.h b/generic/tclDecls.h index c713469..7c1b22b 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1000,7 +1000,7 @@ EXTERN int Tcl_UniCharToUtf(int ch, char *buf); /* 325 */ EXTERN const char * Tcl_UtfAtIndex(const char *src, int index); /* 326 */ -EXTERN int Tcl_UtfCharComplete(const char *src, int length); +EXTERN int TclUtfCharComplete(const char *src, int length); /* 327 */ EXTERN int Tcl_UtfBackslash(const char *src, int *readPtr, char *dst); @@ -1009,9 +1009,9 @@ EXTERN const char * Tcl_UtfFindFirst(const char *src, int ch); /* 329 */ EXTERN const char * Tcl_UtfFindLast(const char *src, int ch); /* 330 */ -EXTERN const char * Tcl_UtfNext(const char *src); +EXTERN const char * TclUtfNext(const char *src); /* 331 */ -EXTERN const char * Tcl_UtfPrev(const char *src, const char *start); +EXTERN const char * TclUtfPrev(const char *src, const char *start); /* 332 */ EXTERN int Tcl_UtfToExternal(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, @@ -1921,6 +1921,12 @@ EXTERN char * Tcl_UniCharToUtfDString(const int *uniStr, /* 648 */ EXTERN int * Tcl_UtfToUniCharDString(const char *src, int length, Tcl_DString *dsPtr); +/* 649 */ +EXTERN int Tcl_UtfCharComplete(const char *src, int length); +/* 650 */ +EXTERN const char * Tcl_UtfNext(const char *src); +/* 651 */ +EXTERN const char * Tcl_UtfPrev(const char *src, const char *start); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2282,12 +2288,12 @@ typedef struct TclStubs { int (*tcl_UniCharToUpper) (int ch); /* 323 */ int (*tcl_UniCharToUtf) (int ch, char *buf); /* 324 */ const char * (*tcl_UtfAtIndex) (const char *src, int index); /* 325 */ - int (*tcl_UtfCharComplete) (const char *src, int length); /* 326 */ + int (*tclUtfCharComplete) (const char *src, int length); /* 326 */ int (*tcl_UtfBackslash) (const char *src, int *readPtr, char *dst); /* 327 */ const char * (*tcl_UtfFindFirst) (const char *src, int ch); /* 328 */ const char * (*tcl_UtfFindLast) (const char *src, int ch); /* 329 */ - const char * (*tcl_UtfNext) (const char *src); /* 330 */ - const char * (*tcl_UtfPrev) (const char *src, const char *start); /* 331 */ + const char * (*tclUtfNext) (const char *src); /* 330 */ + const char * (*tclUtfPrev) (const char *src, const char *start); /* 331 */ int (*tcl_UtfToExternal) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); /* 332 */ char * (*tcl_UtfToExternalDString) (Tcl_Encoding encoding, const char *src, int srcLen, Tcl_DString *dsPtr); /* 333 */ int (*tcl_UtfToLower) (char *src); /* 334 */ @@ -2605,6 +2611,9 @@ typedef struct TclStubs { int (*tcl_UtfToUniChar) (const char *src, int *chPtr); /* 646 */ char * (*tcl_UniCharToUtfDString) (const int *uniStr, int uniLength, Tcl_DString *dsPtr); /* 647 */ int * (*tcl_UtfToUniCharDString) (const char *src, int length, Tcl_DString *dsPtr); /* 648 */ + int (*tcl_UtfCharComplete) (const char *src, int length); /* 649 */ + const char * (*tcl_UtfNext) (const char *src); /* 650 */ + const char * (*tcl_UtfPrev) (const char *src, const char *start); /* 651 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3287,18 +3296,18 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_UniCharToUtf) /* 324 */ #define Tcl_UtfAtIndex \ (tclStubsPtr->tcl_UtfAtIndex) /* 325 */ -#define Tcl_UtfCharComplete \ - (tclStubsPtr->tcl_UtfCharComplete) /* 326 */ +#define TclUtfCharComplete \ + (tclStubsPtr->tclUtfCharComplete) /* 326 */ #define Tcl_UtfBackslash \ (tclStubsPtr->tcl_UtfBackslash) /* 327 */ #define Tcl_UtfFindFirst \ (tclStubsPtr->tcl_UtfFindFirst) /* 328 */ #define Tcl_UtfFindLast \ (tclStubsPtr->tcl_UtfFindLast) /* 329 */ -#define Tcl_UtfNext \ - (tclStubsPtr->tcl_UtfNext) /* 330 */ -#define Tcl_UtfPrev \ - (tclStubsPtr->tcl_UtfPrev) /* 331 */ +#define TclUtfNext \ + (tclStubsPtr->tclUtfNext) /* 330 */ +#define TclUtfPrev \ + (tclStubsPtr->tclUtfPrev) /* 331 */ #define Tcl_UtfToExternal \ (tclStubsPtr->tcl_UtfToExternal) /* 332 */ #define Tcl_UtfToExternalDString \ @@ -3933,6 +3942,12 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_UniCharToUtfDString) /* 647 */ #define Tcl_UtfToUniCharDString \ (tclStubsPtr->tcl_UtfToUniCharDString) /* 648 */ +#define Tcl_UtfCharComplete \ + (tclStubsPtr->tcl_UtfCharComplete) /* 649 */ +#define Tcl_UtfNext \ + (tclStubsPtr->tcl_UtfNext) /* 650 */ +#define Tcl_UtfPrev \ + (tclStubsPtr->tcl_UtfPrev) /* 651 */ #endif /* defined(USE_TCL_STUBS) */ @@ -4178,10 +4193,16 @@ extern const TclStubs *tclStubsPtr; #define Tcl_Close(interp, chan) Tcl_CloseEx(interp, chan, 0) #endif -#if defined(USE_TCL_STUBS) && (TCL_UTF_MAX > 3) +#undef TclUtfCharComplete +#undef TclUtfNext +#undef TclUtfPrev +#if defined(USE_TCL_STUBS) && (TCL_UTF_MAX < 4) && !defined(TCL_NO_DEPRECATED) # undef Tcl_UtfCharComplete -# define Tcl_UtfCharComplete(src, length) (((unsigned)((unsigned char)*(src) - 0xF0) < 5) \ - ? ((length) >= 4) : tclStubsPtr->tcl_UtfCharComplete((src), (length))) +# undef Tcl_UtfNext +# undef Tcl_UtfPrev +# define Tcl_UtfCharComplete (tclStubsPtr->tclUtfCharComplete) +# define Tcl_UtfNext (tclStubsPtr->tclUtfNext) +# define Tcl_UtfPrev (tclStubsPtr->tclUtfPrev) #endif #endif /* _TCLDECLS */ diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index ae02821..784d8d6 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2321,7 +2321,7 @@ UtfToUtfProc( dstEnd = dst + dstLen - TCL_UTF_MAX; for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) { - if ((src > srcClose) && (!TclUCS4Complete(src, srcEnd - src))) { + if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { /* * If there is more string to follow, this will ensure that the * last UTF-8 character in the source buffer hasn't been cut off. @@ -2351,7 +2351,7 @@ UtfToUtfProc( *dst++ = 0; *chPtr = 0; /* reset surrogate handling */ src += 2; - } else if (!TclUCS4Complete(src, srcEnd - src)) { + } else if (!Tcl_UtfCharComplete(src, srcEnd - src)) { /* * Always check before using TclUtfToUCS4. Not doing can so * cause it run beyond the end of the buffer! If we happen such an diff --git a/generic/tclInt.h b/generic/tclInt.h index 78d9f93..1b95754 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3252,14 +3252,8 @@ MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct); MODULE_SCOPE int TclUtfCount(int ch); #if TCL_UTF_MAX > 3 # define TclUtfToUCS4 Tcl_UtfToUniChar -# define TclUCS4Complete Tcl_UtfCharComplete -# define TclChar16Complete(src, length) (((unsigned)((unsigned char)*(src) - 0xF0) < 5) \ - ? ((length) >= 3) : Tcl_UtfCharComplete((src), (length))) #else MODULE_SCOPE int TclUtfToUCS4(const char *src, int *ucs4Ptr); -# define TclUCS4Complete(src, length) (((unsigned)((unsigned char)*(src) - 0xF0) < 5) \ - ? ((length) >= 4) : Tcl_UtfCharComplete((src), (length))) -# define TclChar16Complete Tcl_UtfCharComplete #endif MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData); MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr); @@ -4695,14 +4689,6 @@ MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; (numChars) = _count; \ } while (0); -#define TclUtfPrev(src, start) \ - (((src) < (start) + 2) ? (start) : \ - ((unsigned char) *((src) - 1)) < 0x80 ? (src) - 1 : \ - Tcl_UtfPrev(src, start)) - -#define TclUtfNext(src) \ - ((((unsigned char) *(src)) < 0x80) ? (src) + 1 : Tcl_UtfNext(src)) - /* *---------------------------------------------------------------- * Macro that encapsulates the logic that determines when it is safe to diff --git a/generic/tclParse.c b/generic/tclParse.c index 132e804..49ee348 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -789,7 +789,7 @@ TclParseBackslash( * written. At most 4 bytes will be written there. */ { const char *p = src+1; - Tcl_UniChar unichar = 0; + int unichar; int result; int count; char buf[4] = ""; @@ -936,13 +936,13 @@ TclParseBackslash( */ if (Tcl_UtfCharComplete(p, numBytes - 1)) { - count = TclUtfToUniChar(p, &unichar) + 1; /* +1 for '\' */ + count = TclUtfToUCS4(p, &unichar) + 1; /* +1 for '\' */ } else { - char utfBytes[4]; + char utfBytes[8]; memcpy(utfBytes, p, numBytes - 1); utfBytes[numBytes - 1] = '\0'; - count = TclUtfToUniChar(utfBytes, &unichar) + 1; + count = TclUtfToUCS4(utfBytes, &unichar) + 1; } result = unichar; break; diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 78e49f9..2025674 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1171,10 +1171,10 @@ Tcl_AppendLimitedToObj( } eLen = strlen(ellipsis); while (eLen > limit) { - eLen = TclUtfPrev(ellipsis+eLen, ellipsis) - ellipsis; + eLen = Tcl_UtfPrev(ellipsis+eLen, ellipsis) - ellipsis; } - toCopy = TclUtfPrev(bytes+limit+1-eLen, bytes) - bytes; + toCopy = Tcl_UtfPrev(bytes+limit+1-eLen, bytes) - bytes; } /* @@ -2614,7 +2614,7 @@ AppendPrintfToObjVA( * multi-byte characters. */ - q = TclUtfPrev(end, bytes); + q = Tcl_UtfPrev(end, bytes); if (!Tcl_UtfCharComplete(q, (int)(end - q))) { end = q; } diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 2d2bc63..ae9a4e3 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -88,6 +88,31 @@ static void uniCodePanic(void) { # define Tcl_UniCharNcmp (int(*)(const Tcl_UniChar *, const Tcl_UniChar *, unsigned long))(void *)uniCodePanic #endif +#define TclUtfCharComplete UtfCharComplete +#define TclUtfNext UtfNext +#define TclUtfPrev UtfPrev + +static int TclUtfCharComplete(const char *src, int length) { + if ((unsigned)((unsigned char)*(src) - 0xF0) < 5) { + return length < 5; + } + return Tcl_UtfCharComplete(src, length); +} + +static const char *TclUtfNext(const char *src) { + if ((unsigned)((unsigned char)*(src) - 0xF0) < 5) { + return src + 1; + } + return Tcl_UtfNext(src); +} + +static const char *TclUtfPrev(const char *src, const char *start) { + if (((unsigned)((unsigned char)*(src) - 0xF0) < 5) && (src >= start)) { + return src - 1; + } + return Tcl_UtfPrev(src, start); +} + #define TclBN_mp_add mp_add #define TclBN_mp_and mp_and #define TclBN_mp_clamp mp_clamp @@ -1549,12 +1574,12 @@ const TclStubs tclStubs = { Tcl_UniCharToUpper, /* 323 */ Tcl_UniCharToUtf, /* 324 */ Tcl_UtfAtIndex, /* 325 */ - Tcl_UtfCharComplete, /* 326 */ + TclUtfCharComplete, /* 326 */ Tcl_UtfBackslash, /* 327 */ Tcl_UtfFindFirst, /* 328 */ Tcl_UtfFindLast, /* 329 */ - Tcl_UtfNext, /* 330 */ - Tcl_UtfPrev, /* 331 */ + TclUtfNext, /* 330 */ + TclUtfPrev, /* 331 */ Tcl_UtfToExternal, /* 332 */ Tcl_UtfToExternalDString, /* 333 */ Tcl_UtfToLower, /* 334 */ @@ -1872,6 +1897,9 @@ const TclStubs tclStubs = { Tcl_UtfToUniChar, /* 646 */ Tcl_UniCharToUtfDString, /* 647 */ Tcl_UtfToUniCharDString, /* 648 */ + Tcl_UtfCharComplete, /* 649 */ + Tcl_UtfNext, /* 650 */ + Tcl_UtfPrev, /* 651 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclTest.c b/generic/tclTest.c index 1f6882f..78645b6 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -6844,10 +6844,10 @@ TestUtfNextCmd( memcpy(buffer + 1, bytes, numBytes); buffer[0] = buffer[numBytes + 1] = buffer[numBytes + 2] = buffer[numBytes + 3] = '\xA0'; - first = result = TclUtfNext(buffer + 1); + first = result = Tcl_UtfNext(buffer + 1); while ((buffer[0] = *p++) != '\0') { /* Run Tcl_UtfNext with many more possible bytes at src[-1], all should give the same result */ - result = TclUtfNext(buffer + 1); + result = Tcl_UtfNext(buffer + 1); if (first != result) { Tcl_AppendResult(interp, "Tcl_UtfNext is not supposed to read src[-1]", NULL); return TCL_ERROR; @@ -6856,7 +6856,7 @@ TestUtfNextCmd( p = tobetested; while ((buffer[numBytes + 1] = *p++) != '\0') { /* Run Tcl_UtfNext with many more possible bytes at src[end], all should give the same result */ - result = TclUtfNext(buffer + 1); + result = Tcl_UtfNext(buffer + 1); if (first != result) { first = buffer; break; @@ -6904,7 +6904,7 @@ TestUtfPrevCmd( } else { offset = numBytes; } - result = TclUtfPrev(bytes + offset, bytes); + result = Tcl_UtfPrev(bytes + offset, bytes); Tcl_SetObjResult(interp, Tcl_NewIntObj(result - bytes)); return TCL_OK; } diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 7c09283..6f03053 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -88,13 +88,7 @@ static const unsigned char complete[256] = { 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, /* End of "continuation byte section" */ 2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, -#if TCL_UTF_MAX > 3 - 4,4,4,4,4, -#else - 3,3,3,3,3, -#endif - 1,1,1,1,1,1,1,1,1,1,1 + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1 }; /* @@ -694,7 +688,7 @@ Tcl_UtfToUniCharDString( p += TclUtfToUCS4(p, &ch); *w++ = ch; } - while ((p < endPtr) && TclUCS4Complete(p, endPtr-p)) { + while ((p < endPtr) && Tcl_UtfCharComplete(p, endPtr-p)) { p += TclUtfToUCS4(p, &ch); *w++ = ch; } @@ -752,7 +746,7 @@ Tcl_UtfToChar16DString( *w++ = ch; } while (p < endPtr) { - if (TclChar16Complete(p, endPtr-p)) { + if (Tcl_UtfCharComplete(p, endPtr-p)) { p += Tcl_UtfToChar16(p, &ch); *w++ = ch; } else { @@ -833,7 +827,7 @@ Tcl_NumUtfChars( /* Pointer to the end of string. Never read endPtr[0] */ const char *endPtr = src + length; /* Pointer to last byte where optimization still can be used */ - const char *optPtr = endPtr - TCL_UTF_MAX; + const char *optPtr = endPtr - 4; /* * Optimize away the call in this loop. Justified because... diff --git a/generic/tclUtil.c b/generic/tclUtil.c index ebc8656..40b249d 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1707,7 +1707,7 @@ TclTrimRight( const char *q = trim; int pInc = 0, bytesLeft = numTrim; - pp = TclUtfPrev(p, bytes); + pp = Tcl_UtfPrev(p, bytes); do { pp += pInc; pInc = TclUtfToUCS4(pp, &ch1); @@ -1858,7 +1858,7 @@ TclTrim( * that we will not trim. Skip over it. */ if (numBytes > 0) { const char *first = bytes + trimLeft; - bytes = TclUtfNext(first); + bytes = Tcl_UtfNext(first); numBytes -= (bytes - first); if (numBytes > 0) { -- cgit v0.12 From d6deb4d6d99f3ea3b0f50de0fdf0f06903f41956 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 22 May 2020 15:27:43 +0000 Subject: New "string" subcommands: "nextchar", "nextword", "prevchar", "prevword". Not implemented yet (for now same as "wordstart"/"wordend"). Deprecate "string bytelength". --- generic/tclCmdMZ.c | 8 ++++++++ tests/info.test | 4 ++-- tests/regexp.test | 4 ++-- tests/regexpComp.test | 4 ++-- tests/string.test | 19 ++++++++++--------- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 8efdb27..0da143e 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2831,6 +2831,7 @@ StringCatCmd( * *---------------------------------------------------------------------- */ +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 static int StringBytesCmd( TCL_UNUSED(ClientData), @@ -2849,6 +2850,7 @@ StringBytesCmd( Tcl_SetObjResult(interp, Tcl_NewWideIntObj(length)); return TCL_OK; } +#endif /* *---------------------------------------------------------------------- @@ -3305,7 +3307,9 @@ TclInitStringCmd( Tcl_Interp *interp) /* Current interpreter. */ { static const EnsembleImplMap stringImplMap[] = { +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 {"bytelength", StringBytesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, +#endif {"cat", StringCatCmd, TclCompileStringCatCmd, NULL, NULL, 0}, {"compare", StringCmpCmd, TclCompileStringCmpCmd, NULL, NULL, 0}, {"equal", StringEqualCmd, TclCompileStringEqualCmd, NULL, NULL, 0}, @@ -3317,6 +3321,10 @@ TclInitStringCmd( {"length", StringLenCmd, TclCompileStringLenCmd, NULL, NULL, 0}, {"map", StringMapCmd, TclCompileStringMapCmd, NULL, NULL, 0}, {"match", StringMatchCmd, TclCompileStringMatchCmd, NULL, NULL, 0}, + {"nextchar", StringEndCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, + {"nextword", StringEndCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, + {"prevchar", StringStartCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, + {"prevword", StringStartCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, {"range", StringRangeCmd, TclCompileStringRangeCmd, NULL, NULL, 0}, {"repeat", StringReptCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, {"replace", StringRplcCmd, TclCompileStringReplaceCmd, NULL, NULL, 0}, diff --git a/tests/info.test b/tests/info.test index ce51523..18f5c7a 100644 --- a/tests/info.test +++ b/tests/info.test @@ -103,8 +103,8 @@ test info-2.5 {info body option, returning bytecompiled bodies} -body { # causing an empty string to be returned [Bug #545644] test info-2.6 {info body option, returning list bodies} { proc foo args [list subst bar] - list [string bytelength [info body foo]] \ - [foo; string bytelength [info body foo]] + list [string length [info body foo]] \ + [foo; string length [info body foo]] } {9 9} proc testinfocmdcount {} { diff --git a/tests/regexp.test b/tests/regexp.test index bae1217..03c55b7 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -760,8 +760,8 @@ test regexp-20.1 {regsub shared object shimmering} -body { set b $a set c abcdefghijklmnopqurstuvwxyz0123456789 regsub $a $c $b d - list $d [string length $d] [string bytelength $d] -} -result [list abcdefghijklmnopqurstuvwxyz0123456789 37 37] + list $d [string length $d] +} -result [list abcdefghijklmnopqurstuvwxyz0123456789 37] test regexp-20.2 {regsub shared object shimmering with -about} -body { eval regexp -about abc } -result {0 {}} diff --git a/tests/regexpComp.test b/tests/regexpComp.test index 8819dd2..390b003 100644 --- a/tests/regexpComp.test +++ b/tests/regexpComp.test @@ -798,9 +798,9 @@ test regexpComp-20.1 {regsub shared object shimmering} { set b $a set c abcdefghijklmnopqurstuvwxyz0123456789 regsub $a $c $b d - list $d [string length $d] [string bytelength $d] + list $d [string length $d] } -} [list abcdefghijklmnopqurstuvwxyz0123456789 37 37] +} [list abcdefghijklmnopqurstuvwxyz0123456789 37] test regexpComp-20.2 {regsub shared object shimmering with -about} { evalInProc { eval regexp -about abc diff --git a/tests/string.test b/tests/string.test index 12821c0..e68bbe3 100644 --- a/tests/string.test +++ b/tests/string.test @@ -33,6 +33,7 @@ testConstraint testindexobj [expr {[info commands testindexobj] ne {}}] testConstraint testevalex [expr {[info commands testevalex] ne {}}] testConstraint utf16 [expr {[string length \U010000] == 2}] testConstraint testbytestring [llength [info commands testbytestring]] +testConstraint nodep [info exists tcl_precision] # Used for constraining memory leak tests testConstraint memory [llength [info commands memory]] @@ -72,9 +73,9 @@ if {$noComp} { } -test string-1.1.$noComp {error conditions} { +test string-1.1.$noComp {error conditions} -body { list [catch {run {string gorp a b}} msg] $msg -} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, cat, compare, equal, first, index, insert, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} -match regexp -result {1 {unknown or ambiguous subcommand "gorp": must be (bytelength, |)cat, compare, equal, first, index, insert, is, last, length, map, match, nextchar, nextword, prevchar, prevword, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test string-1.2.$noComp {error conditions} { list [catch {run {string}} msg] $msg } {1 {wrong # args: should be "string subcommand ?arg ...?"}} @@ -1024,16 +1025,16 @@ test string-7.16.$noComp {string last, start index} { run {string last \334a \334ad\334ad end-1} } 3 -test string-8.1.$noComp {string bytelength} { +test string-8.1.$noComp {string bytelength} nodep { list [catch {run {string bytelength}} msg] $msg } {1 {wrong # args: should be "string bytelength string"}} -test string-8.2.$noComp {string bytelength} { +test string-8.2.$noComp {string bytelength} nodep { list [catch {run {string bytelength a b}} msg] $msg } {1 {wrong # args: should be "string bytelength string"}} -test string-8.3.$noComp {string bytelength} { +test string-8.3.$noComp {string bytelength} nodep { run {string bytelength "\xC7"} } 2 -test string-8.4.$noComp {string bytelength} { +test string-8.4.$noComp {string bytelength} nodep { run {string b ""} } 0 @@ -1799,9 +1800,9 @@ test string-19.3.$noComp {string trimleft, unicode default} { test string-20.1.$noComp {string trimright errors} { list [catch {run {string trimright}} msg] $msg } {1 {wrong # args: should be "string trimright string ?chars?"}} -test string-20.2.$noComp {string trimright errors} { +test string-20.2.$noComp {string trimright errors} -body { list [catch {run {string trimg a}} msg] $msg -} {1 {unknown or ambiguous subcommand "trimg": must be bytelength, cat, compare, equal, first, index, insert, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} -match regexp -result {1 {unknown or ambiguous subcommand "trimg": must be (bytelength, |)cat, compare, equal, first, index, insert, is, last, length, map, match, nextchar, nextword, prevchar, prevword, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test string-20.3.$noComp {string trimright} { run {string trimright " XYZ "} } { XYZ} @@ -1894,7 +1895,7 @@ test string-21.16.$noComp {string wordend, unicode} -constraints utf16 -body { test string-22.1.$noComp {string wordstart} -body { list [catch {run {string word a}} msg] $msg -} -result {1 {unknown or ambiguous subcommand "word": must be bytelength, cat, compare, equal, first, index, insert, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} -match regexp -result {1 {unknown or ambiguous subcommand "word": must be (bytelength, |)cat, compare, equal, first, index, insert, is, last, length, map, match, nextchar, nextword, prevchar, prevword, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test string-22.2.$noComp {string wordstart} -body { list [catch {run {string wordstart a}} msg] $msg } -result {1 {wrong # args: should be "string wordstart string index"}} -- cgit v0.12 From 0a2c1e30b152c1fcbd3180aadaf6b27039f07421 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 22 May 2020 21:28:16 +0000 Subject: Split more "string" functions. New helper function TclUniCharToUCS4(), not used yet but that's the next step. --- generic/tclCmdMZ.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++++- generic/tclInt.h | 2 + generic/tclUtf.c | 14 +++ 3 files changed, 284 insertions(+), 4 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 0da143e..0e624c6 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2547,6 +2547,146 @@ StringStartCmd( /* *---------------------------------------------------------------------- * + * StringPrevCharCmd -- + * + * This procedure is invoked to process the "string prevchar" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +static int +StringPrevCharCmd( + TCL_UNUSED(ClientData), + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + int ch; + const char *p, *string; + int cur, index, length, numChars; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "string index"); + return TCL_ERROR; + } + + string = TclGetStringFromObj(objv[1], &length); + numChars = Tcl_NumUtfChars(string, length); + if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + return TCL_ERROR; + } + string = TclGetStringFromObj(objv[1], &length); + if (index >= numChars) { + index = numChars - 1; + } + cur = 0; + if (index > 0) { + p = Tcl_UtfAtIndex(string, index); + + TclUtfToUCS4(p, &ch); + for (cur = index; cur >= 0; cur--) { + int delta = 0; + const char *next; + + if (!Tcl_UniCharIsWordChar(ch)) { + break; + } + + next = Tcl_UtfPrev(p, string); + do { + next += delta; + delta = TclUtfToUCS4(next, &ch); + } while (next + delta < p); + p = next; + } + if (cur != index) { + cur += 1; + } + } + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * StringPrevWordCmd -- + * + * This procedure is invoked to process the "string prevword" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +static int +StringPrevWordCmd( + TCL_UNUSED(ClientData), + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + int ch; + const char *p, *string; + int cur, index, length, numChars; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "string index"); + return TCL_ERROR; + } + + string = TclGetStringFromObj(objv[1], &length); + numChars = Tcl_NumUtfChars(string, length); + if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + return TCL_ERROR; + } + string = TclGetStringFromObj(objv[1], &length); + if (index >= numChars) { + index = numChars - 1; + } + cur = 0; + if (index > 0) { + p = Tcl_UtfAtIndex(string, index); + + TclUtfToUCS4(p, &ch); + for (cur = index; cur >= 0; cur--) { + int delta = 0; + const char *next; + + if (!Tcl_UniCharIsWordChar(ch)) { + break; + } + + next = Tcl_UtfPrev(p, string); + do { + next += delta; + delta = TclUtfToUCS4(next, &ch); + } while (next + delta < p); + p = next; + } + if (cur != index) { + cur += 1; + } + } + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * StringEndCmd -- * * This procedure is invoked to process the "string wordend" Tcl command. @@ -2605,6 +2745,130 @@ StringEndCmd( return TCL_OK; } + +/* + *---------------------------------------------------------------------- + * + * StringNextCharCmd -- + * + * This procedure is invoked to process the "string nextchar" Tcl command. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +static int +StringNextCharCmd( + TCL_UNUSED(ClientData), + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + int ch; + const char *p, *end, *string; + int cur, index, length, numChars; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "string index"); + return TCL_ERROR; + } + + string = TclGetStringFromObj(objv[1], &length); + numChars = Tcl_NumUtfChars(string, length); + if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + return TCL_ERROR; + } + string = TclGetStringFromObj(objv[1], &length); + if (index < 0) { + index = 0; + } + if (index < numChars) { + p = Tcl_UtfAtIndex(string, index); + end = string+length; + for (cur = index; p < end; cur++) { + p += TclUtfToUCS4(p, &ch); + if (!Tcl_UniCharIsWordChar(ch)) { + break; + } + } + if (cur == index) { + cur++; + } + } else { + cur = numChars; + } + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); + return TCL_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * StringNextWordCmd -- + * + * This procedure is invoked to process the "string nextword" Tcl command. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +static int +StringNextWordCmd( + TCL_UNUSED(ClientData), + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + int ch; + const char *p, *end, *string; + int cur, index, length, numChars; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "string index"); + return TCL_ERROR; + } + + string = TclGetStringFromObj(objv[1], &length); + numChars = Tcl_NumUtfChars(string, length); + if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + return TCL_ERROR; + } + string = TclGetStringFromObj(objv[1], &length); + if (index < 0) { + index = 0; + } + if (index < numChars) { + p = Tcl_UtfAtIndex(string, index); + end = string+length; + for (cur = index; p < end; cur++) { + p += TclUtfToUCS4(p, &ch); + if (!Tcl_UniCharIsWordChar(ch)) { + break; + } + } + if (cur == index) { + cur++; + } + } else { + cur = numChars; + } + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); + return TCL_OK; +} + /* *---------------------------------------------------------------------- * @@ -3321,10 +3585,10 @@ TclInitStringCmd( {"length", StringLenCmd, TclCompileStringLenCmd, NULL, NULL, 0}, {"map", StringMapCmd, TclCompileStringMapCmd, NULL, NULL, 0}, {"match", StringMatchCmd, TclCompileStringMatchCmd, NULL, NULL, 0}, - {"nextchar", StringEndCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, - {"nextword", StringEndCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, - {"prevchar", StringStartCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, - {"prevword", StringStartCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, + {"nextchar", StringNextCharCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, + {"nextword", StringNextWordCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, + {"prevchar", StringPrevCharCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, + {"prevword", StringPrevWordCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, {"range", StringRangeCmd, TclCompileStringRangeCmd, NULL, NULL, 0}, {"repeat", StringReptCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, {"replace", StringRplcCmd, TclCompileStringReplaceCmd, NULL, NULL, 0}, diff --git a/generic/tclInt.h b/generic/tclInt.h index 1b95754..ef7411a 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3252,8 +3252,10 @@ MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct); MODULE_SCOPE int TclUtfCount(int ch); #if TCL_UTF_MAX > 3 # define TclUtfToUCS4 Tcl_UtfToUniChar +# define TclUniCharToUCS4(src, ptr) (*ptr = *(src),1) #else MODULE_SCOPE int TclUtfToUCS4(const char *src, int *ucs4Ptr); + MODULE_SCOPE int TclUniCharToUCS4(const Tcl_UniChar *src, int *ucs4Ptr); #endif MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData); MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr); diff --git a/generic/tclUtf.c b/generic/tclUtf.c index fd6ec1b..db2fc02 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -2634,6 +2634,20 @@ TclUtfToUCS4( /* Make use of the #undef Tcl_UtfToUniChar above, which already handles UCS4. */ return Tcl_UtfToUniChar(src, ucs4Ptr); } + +int +TclUniCharToUCS4( + const Tcl_UniChar *src, /* The Tcl_UniChar string. */ + int *ucs4Ptr) /* Filled with the UCS4 codepoint represented + * by the Tcl_UniChar string. */ +{ + if (((src[0] & 0xFC00) == 0xD800) && ((src[1] & 0xFC00) == 0xDC00)) { + *ucs4Ptr = (((src[0] & 0x3FF) << 10) | (src[01] & 0x3FF)) + 0x10000; + return 2; + } + *ucs4Ptr = src[0]; + return 1; +} #endif /* -- cgit v0.12 From 1075137cfc201f4c0aee86f118ed0b7e44febc24 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 23 May 2020 21:51:12 +0000 Subject: Fix testsuite when "string bytelength" doesn't exist. --- library/init.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/init.tcl b/library/init.tcl index 4ea22d8..8ebd29e6 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -209,9 +209,9 @@ proc unknown args { set errInfo [dict get $opts -errorinfo] set errCode [dict get $opts -errorcode] set cinfo $args - if {[string bytelength $cinfo] > 150} { + if {[string length $cinfo] > 150} { set cinfo [string range $cinfo 0 150] - while {[string bytelength $cinfo] > 150} { + while {[string length $cinfo] > 150} { set cinfo [string range $cinfo 0 end-1] } append cinfo ... -- cgit v0.12 From 017257e0ef3f20643166931986ea36eeee97f049 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 23 May 2020 22:07:53 +0000 Subject: Rewrite "string wordend" to use the Tcl_UniChar array. --- generic/tclCmdMZ.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 0e624c6..88bf2ec 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2709,28 +2709,26 @@ StringEndCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int ch; - const char *p, *end, *string; - int cur, index, length, numChars; + const Tcl_UniChar *p, *end, *string; + int cur, index, length; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string index"); return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); - numChars = Tcl_NumUtfChars(string, length); - if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + string = Tcl_GetUnicodeFromObj(objv[1], &length); + if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) { return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); if (index < 0) { index = 0; } - if (index < numChars) { - p = Tcl_UtfAtIndex(string, index); + if (index < length) { + p = &string[index]; end = string+length; for (cur = index; p < end; cur++) { - p += TclUtfToUCS4(p, &ch); + p += TclUniCharToUCS4(p, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } @@ -2739,7 +2737,7 @@ StringEndCmd( cur++; } } else { - cur = numChars; + cur = length; } Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); return TCL_OK; -- cgit v0.12 From 2b1daf9bb29fdba966f86c054d96d564b7539684 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 24 May 2020 22:29:07 +0000 Subject: Put back "string bytelength", not _that_ important for this TIP. Document that Tcl_UtfCharComplete() can be used now to protect Tcl_UtfNext() --- doc/Utf.3 | 11 ++++++----- generic/tclCmdMZ.c | 4 ---- library/init.tcl | 4 ++-- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/doc/Utf.3 b/doc/Utf.3 index 4b5b162..6ebf57d 100644 --- a/doc/Utf.3 +++ b/doc/Utf.3 @@ -233,10 +233,10 @@ characters. .PP \fBTcl_UtfCharComplete\fR returns 1 if the source UTF-8 string \fIsrc\fR of \fIlength\fR bytes is long enough to be decoded by -\fBTcl_UtfToUniChar\fR, or 0 otherwise. This function does not guarantee -that the UTF-8 string is properly formed. This routine is used by -procedures that are operating on a byte at a time and need to know if a -full Unicode character has been seen. +\fBTcl_UtfToUniChar\fR/\fBTcl_UtfNext\fR, or 0 otherwise. This function +does not guarantee that the UTF-8 string is properly formed. This routine +is used by procedures that are operating on a byte at a time and need to +know if a full Unicode character has been seen. .PP \fBTcl_NumUtfChars\fR corresponds to \fBstrlen\fR for UTF-8 strings. It returns the number of Tcl_UniChars that are represented by the UTF-8 string @@ -257,7 +257,8 @@ Given \fIsrc\fR, a pointer to some location in a UTF-8 string, \fBTcl_UtfNext\fR returns a pointer to the next UTF-8 character in the string. The caller must not ask for the next character after the last character in the string if the string is not terminated by a null -character. +character. \fBTcl_UtfCharComplete\fR can be used in that case to +make sure enough bytes are available before calling \fBTcl_UtfNext\fR. .PP \fBTcl_UtfPrev\fR is used to step backward through but not beyond the UTF-8 string that begins at \fIstart\fR. If the UTF-8 string is made diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 88bf2ec..bbd03d8 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -3093,7 +3093,6 @@ StringCatCmd( * *---------------------------------------------------------------------- */ -#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 static int StringBytesCmd( TCL_UNUSED(ClientData), @@ -3112,7 +3111,6 @@ StringBytesCmd( Tcl_SetObjResult(interp, Tcl_NewWideIntObj(length)); return TCL_OK; } -#endif /* *---------------------------------------------------------------------- @@ -3569,9 +3567,7 @@ TclInitStringCmd( Tcl_Interp *interp) /* Current interpreter. */ { static const EnsembleImplMap stringImplMap[] = { -#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 {"bytelength", StringBytesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, -#endif {"cat", StringCatCmd, TclCompileStringCatCmd, NULL, NULL, 0}, {"compare", StringCmpCmd, TclCompileStringCmpCmd, NULL, NULL, 0}, {"equal", StringEqualCmd, TclCompileStringEqualCmd, NULL, NULL, 0}, diff --git a/library/init.tcl b/library/init.tcl index 8ebd29e6..4ea22d8 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -209,9 +209,9 @@ proc unknown args { set errInfo [dict get $opts -errorinfo] set errCode [dict get $opts -errorcode] set cinfo $args - if {[string length $cinfo] > 150} { + if {[string bytelength $cinfo] > 150} { set cinfo [string range $cinfo 0 150] - while {[string length $cinfo] > 150} { + while {[string bytelength $cinfo] > 150} { set cinfo [string range $cinfo 0 end-1] } append cinfo ... -- cgit v0.12 From 2d7e36f00618d7f309c3970366b10fb888b83eea Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 25 May 2020 07:48:15 +0000 Subject: Fix "string is wordchar" in compiled case handling characters > U+FFFF. Adapt testcase exposing the problem. --- generic/tclExecute.c | 6 ++++-- tests/string.test | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 5708772..cc366e7 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5543,9 +5543,11 @@ TEBCresume( ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length); match = 1; if (length > 0) { + int ch; end = ustring1 + length; - for (p=ustring1 ; p Date: Mon, 25 May 2020 11:53:11 +0000 Subject: Finish implementation of "string nextchar|nextword|prevchar|prevword". Not thourougly test yet, but seems OK at first sight. --- generic/tclCmdMZ.c | 163 ++++++++++++++++++----------------------- generic/tclExecute.c | 2 +- generic/tclInt.h | 6 +- generic/tclUtf.c | 15 +++- tests/string.test | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 290 insertions(+), 96 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index bbd03d8..36b2443 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2499,40 +2499,38 @@ StringStartCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int ch; - const char *p, *string; - int cur, index, length, numChars; + const Tcl_UniChar *p, *string; + int cur, index, length; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string index"); return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); - numChars = Tcl_NumUtfChars(string, length); - if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + string = Tcl_GetUnicodeFromObj(objv[1], &length); + if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) { return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); - if (index >= numChars) { - index = numChars - 1; + if (index >= length) { + index = length - 1; } cur = 0; if (index > 0) { - p = Tcl_UtfAtIndex(string, index); + p = &string[index]; - TclUtfToUCS4(p, &ch); + TclUniCharToUCS4(p, &ch); for (cur = index; cur >= 0; cur--) { int delta = 0; - const char *next; + const Tcl_UniChar *next; if (!Tcl_UniCharIsWordChar(ch)) { break; } - next = Tcl_UtfPrev(p, string); + next = TclUCS4Prev(p, string); do { next += delta; - delta = TclUtfToUCS4(next, &ch); + delta = TclUniCharToUCS4(next, &ch); } while (next + delta < p); p = next; } @@ -2568,49 +2566,28 @@ StringPrevCharCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - int ch; - const char *p, *string; - int cur, index, length, numChars; + const Tcl_UniChar *p, *string; + int index, length; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string index"); return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); - numChars = Tcl_NumUtfChars(string, length); - if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + string = Tcl_GetUnicodeFromObj(objv[1], &length); + if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) { return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); - if (index >= numChars) { - index = numChars - 1; + if (index > length) { + index = length; } - cur = 0; if (index > 0) { - p = Tcl_UtfAtIndex(string, index); - - TclUtfToUCS4(p, &ch); - for (cur = index; cur >= 0; cur--) { - int delta = 0; - const char *next; - - if (!Tcl_UniCharIsWordChar(ch)) { - break; - } - - next = Tcl_UtfPrev(p, string); - do { - next += delta; - delta = TclUtfToUCS4(next, &ch); - } while (next + delta < p); - p = next; - } - if (cur != index) { - cur += 1; - } + p = &string[index]; + index = TclUCS4Prev(p, string) - string; + } else { + index = 0; } - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index)); return TCL_OK; } @@ -2639,40 +2616,53 @@ StringPrevWordCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int ch; - const char *p, *string; - int cur, index, length, numChars; + const Tcl_UniChar *p, *string; + int cur, index, length; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string index"); return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); - numChars = Tcl_NumUtfChars(string, length); - if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + string = Tcl_GetUnicodeFromObj(objv[1], &length); + if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) { return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); - if (index >= numChars) { - index = numChars - 1; + if (index >= length) { + index = length - 1; } cur = 0; if (index > 0) { - p = Tcl_UtfAtIndex(string, index); + p = &string[index]; - TclUtfToUCS4(p, &ch); + TclUniCharToUCS4(p, &ch); for (cur = index; cur >= 0; cur--) { int delta = 0; - const char *next; + const Tcl_UniChar *next; if (!Tcl_UniCharIsWordChar(ch)) { break; } - next = Tcl_UtfPrev(p, string); + next = TclUCS4Prev(p, string); do { next += delta; - delta = TclUtfToUCS4(next, &ch); + delta = TclUniCharToUCS4(next, &ch); + } while (next + delta < p); + p = next; + } + for (; cur >= 0; cur--) { + int delta = 0; + const Tcl_UniChar *next; + + if (Tcl_UniCharIsWordChar(ch)) { + break; + } + + next = TclUCS4Prev(p, string); + do { + next += delta; + delta = TclUniCharToUCS4(next, &ch); } while (next + delta < p); p = next; } @@ -2769,39 +2759,27 @@ StringNextCharCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int ch; - const char *p, *end, *string; - int cur, index, length, numChars; + const Tcl_UniChar *string; + int index, length; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string index"); return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); - numChars = Tcl_NumUtfChars(string, length); - if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + string = Tcl_GetUnicodeFromObj(objv[1], &length); + if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) { return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); if (index < 0) { index = 0; } - if (index < numChars) { - p = Tcl_UtfAtIndex(string, index); - end = string+length; - for (cur = index; p < end; cur++) { - p += TclUtfToUCS4(p, &ch); - if (!Tcl_UniCharIsWordChar(ch)) { - break; - } - } - if (cur == index) { - cur++; - } + if (index < length) { + index += TclUniCharToUCS4(&string[index], &ch); } else { - cur = numChars; + index = length; } - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index)); return TCL_OK; } @@ -2831,39 +2809,40 @@ StringNextWordCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int ch; - const char *p, *end, *string; - int cur, index, length, numChars; + const Tcl_UniChar *p, *end, *string; + int index, length; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "string index"); return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); - numChars = Tcl_NumUtfChars(string, length); - if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) { + string = Tcl_GetUnicodeFromObj(objv[1], &length); + if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) { return TCL_ERROR; } - string = TclGetStringFromObj(objv[1], &length); if (index < 0) { index = 0; } - if (index < numChars) { - p = Tcl_UtfAtIndex(string, index); + if (index < length) { + p = &string[index]; end = string+length; - for (cur = index; p < end; cur++) { - p += TclUtfToUCS4(p, &ch); + while (index++, p < end) { + p += TclUniCharToUCS4(p, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } } - if (cur == index) { - cur++; + for (; p < end; index++) { + p += TclUniCharToUCS4(p, &ch); + if (Tcl_UniCharIsWordChar(ch)) { + break; + } } } else { - cur = numChars; + index = length; } - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index)); return TCL_OK; } diff --git a/generic/tclExecute.c b/generic/tclExecute.c index cc366e7..c80e12b 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5292,7 +5292,7 @@ TEBCresume( } else if (TclIsPureByteArray(valuePtr)) { objResultPtr = Tcl_NewByteArrayObj( Tcl_GetByteArrayFromObj(valuePtr, NULL)+index, 1); - } else if (valuePtr->bytes && length == valuePtr->length) { + } else if (valuePtr->bytes && length == valuePtr->length && !(valuePtr->bytes[index] & 0x80)) { objResultPtr = Tcl_NewStringObj((const char *) valuePtr->bytes+index, 1); } else { diff --git a/generic/tclInt.h b/generic/tclInt.h index ef7411a..e1dedda 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3253,9 +3253,11 @@ MODULE_SCOPE int TclUtfCount(int ch); #if TCL_UTF_MAX > 3 # define TclUtfToUCS4 Tcl_UtfToUniChar # define TclUniCharToUCS4(src, ptr) (*ptr = *(src),1) +# define TclUCS4Prev(src, ptr) (((src) > (ptr)) ? ((src) - 1) : (src)) #else - MODULE_SCOPE int TclUtfToUCS4(const char *src, int *ucs4Ptr); - MODULE_SCOPE int TclUniCharToUCS4(const Tcl_UniChar *src, int *ucs4Ptr); + MODULE_SCOPE int TclUtfToUCS4(const char *, int *); + MODULE_SCOPE int TclUniCharToUCS4(const Tcl_UniChar *, int *); + MODULE_SCOPE const Tcl_UniChar *TclUCS4Prev(const Tcl_UniChar *, const Tcl_UniChar *); #endif MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData); MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr); diff --git a/generic/tclUtf.c b/generic/tclUtf.c index db2fc02..807e087 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -2642,12 +2642,25 @@ TclUniCharToUCS4( * by the Tcl_UniChar string. */ { if (((src[0] & 0xFC00) == 0xD800) && ((src[1] & 0xFC00) == 0xDC00)) { - *ucs4Ptr = (((src[0] & 0x3FF) << 10) | (src[01] & 0x3FF)) + 0x10000; + *ucs4Ptr = (((src[0] & 0x3FF) << 10) | (src[1] & 0x3FF)) + 0x10000; return 2; } *ucs4Ptr = src[0]; return 1; } + +const Tcl_UniChar *TclUCS4Prev(const Tcl_UniChar *src, const Tcl_UniChar *ptr) { + if (src <= ptr + 1) { + return ptr; + } + if (((src[-1] & 0xFC00) == 0xDC00) && ((src[-2] & 0xFC00) == 0xD800)) { + return src - 2; + } + return src - 1; +} + + + #endif /* diff --git a/tests/string.test b/tests/string.test index 184a555..17a6d3c 100644 --- a/tests/string.test +++ b/tests/string.test @@ -2534,6 +2534,206 @@ test string-32.17.$noComp {string is dict, valid dict packed in invalid dict} { string is dict {{a b c d e f g h}} } 0 +test string-33.1.$noComp {string nextchar} -body { + list [catch {run {string nextchar a}} msg] $msg +} -result {1 {wrong # args: should be "string nextchar string index"}} +test string-33.2.$noComp {string nextchar} -body { + list [catch {run {string nextchar a b c}} msg] $msg +} -result {1 {wrong # args: should be "string nextchar string index"}} +test string-33.3.$noComp {string nextchar} -body { + list [catch {run {string nextchar a gorp}} msg] $msg +} -result {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}} +test string-33.4.$noComp {string nextchar} -body { + run {string nextchar abc. -1} +} -result 1 +test string-33.5.$noComp {string nextchar} -body { + run {string nextchar abc. 100} +} -result 4 +test string-33.6.$noComp {string nextchar} -body { + run {string nextchar "word_one two three" 2} +} -result 3 +test string-33.7.$noComp {string nextchar} -body { + run {string nextchar "one .&# three" 5} +} -result 6 +test string-33.8.$noComp {string nextchar} -body { + run {string worde "x.y" 0} +} -result 1 +test string-33.9.$noComp {string nextchar} -body { + run {string worde "x.y" end-1} +} -result 2 +test string-33.10.$noComp {string nextchar, unicode} -body { + run {string nextchar "xyz\xC7de fg" 0} +} -result 1 +test string-33.11.$noComp {string nextchar, unicode} -body { + run {string nextchar "xyz\uC700de fg" 0} +} -result 1 +test string-33.12.$noComp {string nextchar, unicode} -body { + run {string nextchar "xyz\u203Fde fg" 0} +} -result 1 +test string-33.13.$noComp {string nextchar, unicode} -body { + run {string nextchar "xyz\u2045de fg" 0} +} -result 1 +test string-33.14.$noComp {string nextchar, unicode} -body { + run {string nextchar "\uC700\uC700 abc" 8} +} -result 6 +test string-33.15.$noComp {string nextchar, unicode} -constraints utf16 -body { + run {string nextchar "\U1D7CA\U1D7CA abc" 0} +} -result 2 +test string-33.16.$noComp {string nextchar, unicode} -constraints utf16 -body { + run {string nextchar "\U1D7CA\U1D7CA abc" 10} +} -result 8 + +test string-34.1.$noComp {string nextword} -body { + list [catch {run {string nextword a}} msg] $msg +} -result {1 {wrong # args: should be "string nextword string index"}} +test string-34.2.$noComp {string nextword} -body { + list [catch {run {string nextword a b c}} msg] $msg +} -result {1 {wrong # args: should be "string nextword string index"}} +test string-34.3.$noComp {string nextword} -body { + list [catch {run {string nextword a gorp}} msg] $msg +} -result {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}} +test string-34.4.$noComp {string nextword} -body { + run {string nextword abc. -1} +} -result 4 +test string-34.5.$noComp {string nextword} -body { + run {string nextword abc. 100} +} -result 4 +test string-34.6.$noComp {string nextword} -body { + run {string nextword "word_one two three" 2} +} -result 9 +test string-34.7.$noComp {string nextword} -body { + run {string nextword "one .&# three" 5} +} -result 8 +test string-34.8.$noComp {string nextword} -body { + run {string worde "x.y" 0} +} -result 1 +test string-34.9.$noComp {string nextword} -body { + run {string worde "x.y" end-1} +} -result 2 +test string-34.10.$noComp {string nextword, unicode} -body { + run {string nextword "xyz\xC7de fg" 0} +} -result 7 +test string-34.11.$noComp {string nextword, unicode} -body { + run {string nextword "xyz\uC700de fg" 0} +} -result 7 +test string-34.12.$noComp {string nextword, unicode} -body { + run {string nextword "xyz\u203Fde fg" 0} +} -result 7 +test string-34.13.$noComp {string nextword, unicode} -body { + run {string nextword "xyz\u2045\u2045de fg" 0} +} -result 5 +test string-34.14.$noComp {string nextword, unicode} -body { + run {string nextword "\uC700\uC700 abc" 8} +} -result 6 +test string-34.15.$noComp {string nextword, unicode} -body { + run {string nextword "\U1D7CA\U1D7CA abc" 0} +} -result 3 +test string-34.16.$noComp {string nextword, unicode} -constraints utf16 -body { + run {string nextword "\U1D7CA\U1D7CA abc" 10} +} -result 8 + +test string-35.1.$noComp {string prevchar} -body { + list [catch {run {string word a}} msg] $msg +} -match regexp -result {1 {unknown or ambiguous subcommand "word": must be (bytelength, |)cat, compare, equal, first, index, insert, is, last, length, map, match, nextchar, nextword, prevchar, prevword, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +test string-35.2.$noComp {string prevchar} -body { + list [catch {run {string prevchar a}} msg] $msg +} -result {1 {wrong # args: should be "string prevchar string index"}} +test string-35.3.$noComp {string prevchar} -body { + list [catch {run {string prevchar a b c}} msg] $msg +} -result {1 {wrong # args: should be "string prevchar string index"}} +test string-35.4.$noComp {string prevchar} -body { + list [catch {run {string prevchar a gorp}} msg] $msg +} -result {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}} +test string-35.5.$noComp {string prevchar} -body { + run {string prevchar "one two three_words" 400} +} -result 18 +test string-35.6.$noComp {string prevchar} -body { + run {string prevchar "one two three_words" 2} +} -result 1 +test string-35.7.$noComp {string prevchar} -body { + run {string prevchar "one two three_words" -2} +} -result 0 +test string-35.8.$noComp {string prevchar} -body { + run {string prevchar "one .*&^ three" 6} +} -result 5 +test string-35.9.$noComp {string prevchar} -body { + run {string prevchar "one two three" 4} +} -result 3 +test string-35.10.$noComp {string prevchar} -body { + run {string prevchar "one two three" end-5} +} -result 6 +test string-35.11.$noComp {string prevchar, unicode} -body { + run {string prevchar "one tw\xC7o three" 7} +} -result 6 +test string-35.12.$noComp {string prevchar, unicode} -body { + run {string prevchar "ab\uC700\uC700 cdef ghi" 12} +} -result 11 +test string-35.13.$noComp {string prevchar, unicode} -body { + run {string prevchar "\uC700\uC700 abc" 8} +} -result 5 +test string-35.14.$noComp {string prevchar, invalid UTF-8} -constraints testbytestring -body { + # See Bug c61818e4c9 + set demo [testbytestring "abc def\xE0\xA9ghi"] + run {string index $demo [string prevchar $demo 10]} +} -result g +test string-35.15.$noComp {string prevchar, unicode} -body { + run {string prevchar "\U1D7CA\U1D7CA abc" 0} +} -result 0 +test string-35.16.$noComp {string prevchar, unicode} -constraints utf16 -body { + run {string prevchar "\U1D7CA\U1D7CA abc" 10} +} -result 7 + +test string-36.1.$noComp {string prevword} -body { + list [catch {run {string word a}} msg] $msg +} -match regexp -result {1 {unknown or ambiguous subcommand "word": must be (bytelength, |)cat, compare, equal, first, index, insert, is, last, length, map, match, nextchar, nextword, prevchar, prevword, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +test string-36.2.$noComp {string prevword} -body { + list [catch {run {string prevword a}} msg] $msg +} -result {1 {wrong # args: should be "string prevword string index"}} +test string-36.3.$noComp {string prevword} -body { + list [catch {run {string prevword a b c}} msg] $msg +} -result {1 {wrong # args: should be "string prevword string index"}} +test string-36.4.$noComp {string prevword} -body { + list [catch {run {string prevword a gorp}} msg] $msg +} -result {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}} +test string-36.5.$noComp {string prevword} -body { + run {string prevword "one two three_words" 400} +} -result 7 +test string-36.6.$noComp {string prevword} -body { + run {string prevword "one two three_words" 2} +} -result 0 +test string-36.7.$noComp {string prevword} -body { + run {string prevword "one two three_words" -2} +} -result 0 +test string-36.8.$noComp {string prevword} -body { + run {string prevword "one .*&^ three" 6} +} -result 3 +test string-36.9.$noComp {string prevword} -body { + run {string prevword "one two three" 4} +} -result 3 +test string-36.10.$noComp {string prevword} -body { + run {string prevword "one two three" end-5} +} -result 7 +test string-36.11.$noComp {string prevword, unicode} -body { + run {string prevword "one tw\xC7o three" 7} +} -result 3 +test string-36.12.$noComp {string prevword, unicode} -body { + run {string prevword "ab\uC700\uC700 cdef ghi" 12} +} -result 9 +test string-36.13.$noComp {string prevword, unicode} -body { + run {string prevword "\uC700\uC700 abc" 8} +} -result 2 +test string-36.14.$noComp {string prevword, invalid UTF-8} -constraints testbytestring -body { + # See Bug c61818e4c9 + set demo [testbytestring "abc def\xE0\xA9ghi"] + run {string index $demo [string prevword $demo 10]} +} -result \xA9 +test string-36.15.$noComp {string prevword, unicode} -body { + run {string prevword "\U1D7CA\U1D7CA abc" 0} +} -result 0 +test string-36.16.$noComp {string prevword, unicode} -constraints utf16 -body { + run {string prevword "\U1D7CA\U1D7CA abc" 10} +} -result 4 + }; # foreach noComp {0 1} # cleanup -- cgit v0.12 From a09671a0a00f2d3e4abf4747a072da94b0320459 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 29 May 2020 13:36:58 +0000 Subject: Change implementation "charstart", not behaving as "prevchar" any more. Also optimize charend/charstart for TCL_UTF_MAX>3 (not need to do actual conversion then). --- generic/tclCmdMZ.c | 59 +++++++++++++++++++++++++++++++++++------------------- tests/string.test | 59 +++++++++++++++++++++++++++--------------------------- 2 files changed, 67 insertions(+), 51 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index e15e5c8..63268a4 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2518,7 +2518,7 @@ StringStartCmd( if (index > 0) { p = &string[index]; - TclUniCharToUCS4(p, &ch); + (void)TclUniCharToUCS4(p, &ch); for (cur = index; cur >= 0; cur--) { int delta = 0; const Tcl_UniChar *next; @@ -2537,8 +2537,6 @@ StringStartCmd( if (cur != index) { cur += 1; } - } else { - cur = -1; } Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); return TCL_OK; @@ -2568,7 +2566,11 @@ StringCharStartCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - const Tcl_UniChar *p, *string; +#if TCL_UTF_MAX <= 3 + const Tcl_UniChar *src; +#else + const char *src; +#endif int index, length; if (objc != 3) { @@ -2576,18 +2578,23 @@ StringCharStartCmd( return TCL_ERROR; } - string = Tcl_GetUnicodeFromObj(objv[1], &length); +#if TCL_UTF_MAX <= 3 + src = Tcl_GetUnicodeFromObj(objv[1], &length); +#else + src = Tcl_GetStringFromObj(objv[1], &length); + length = Tcl_NumUtfChars(src, length); +#endif if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) { return TCL_ERROR; } - if (index > length) { + if (index >= length) { index = length; - } - if (index > 0) { - p = &string[index]; - index = TclUCS4Prev(p, string) - string; - } else { - index = 0; + } else if (index < 0) { + index = -1; +#if TCL_UTF_MAX <= 3 + } else if ((index > 0) && ((src[index-1] & 0xFC00) == 0xD800) && ((src[index] & 0xFC00) == 0xDC00)) { + index--; +#endif } Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index)); return TCL_OK; @@ -2646,7 +2653,7 @@ StringEndCmd( cur++; } } else { - cur = -1; + cur = length; } Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur)); return TCL_OK; @@ -2676,8 +2683,11 @@ StringCharEndCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - int ch; - const Tcl_UniChar *string; +#if TCL_UTF_MAX <= 3 + const Tcl_UniChar *src; +#else + const char *src; +#endif int index, length; if (objc != 3) { @@ -2685,17 +2695,24 @@ StringCharEndCmd( return TCL_ERROR; } - string = Tcl_GetUnicodeFromObj(objv[1], &length); +#if TCL_UTF_MAX <= 3 + src = Tcl_GetUnicodeFromObj(objv[1], &length); +#else + src = Tcl_GetStringFromObj(objv[1], &length); + length = Tcl_NumUtfChars(src, length); +#endif if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) { return TCL_ERROR; } - if (index < 0) { + if (++index < 0) { index = 0; } - if (index < length) { - index += TclUniCharToUCS4(&string[index], &ch); - } else { - index = -1; + if (index >= length) { + index = length; +#if TCL_UTF_MAX <= 3 + } else if ((index > 0) && ((src[index-1] & 0xFC00) == 0xD800) && ((src[index] & 0xFC00) == 0xDC00)) { + index++; +#endif } Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index)); return TCL_OK; diff --git a/tests/string.test b/tests/string.test index d868610..cddd506 100644 --- a/tests/string.test +++ b/tests/string.test @@ -33,7 +33,6 @@ testConstraint testindexobj [expr {[info commands testindexobj] ne {}}] testConstraint testevalex [expr {[info commands testevalex] ne {}}] testConstraint utf16 [expr {[string length \U010000] == 2}] testConstraint testbytestring [llength [info commands testbytestring]] -testConstraint nodep [info exists tcl_precision] # Used for constraining memory leak tests testConstraint memory [llength [info commands memory]] @@ -73,9 +72,9 @@ if {$noComp} { } -test string-1.1.$noComp {error conditions} -body { +test string-1.1.$noComp {error conditions} { list [catch {run {string gorp a b}} msg] $msg -} -match regexp -result {1 {unknown or ambiguous subcommand "gorp": must be (bytelength, |)cat, charend, charstart, compare, equal, first, index, insert, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, cat, charend, charstart, compare, equal, first, index, insert, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test string-1.2.$noComp {error conditions} { list [catch {run {string}} msg] $msg } {1 {wrong # args: should be "string subcommand ?arg ...?"}} @@ -1025,16 +1024,16 @@ test string-7.16.$noComp {string last, start index} { run {string last \334a \334ad\334ad end-1} } 3 -test string-8.1.$noComp {string bytelength} nodep { +test string-8.1.$noComp {string bytelength} { list [catch {run {string bytelength}} msg] $msg } {1 {wrong # args: should be "string bytelength string"}} -test string-8.2.$noComp {string bytelength} nodep { +test string-8.2.$noComp {string bytelength} { list [catch {run {string bytelength a b}} msg] $msg } {1 {wrong # args: should be "string bytelength string"}} -test string-8.3.$noComp {string bytelength} nodep { +test string-8.3.$noComp {string bytelength} { run {string bytelength "\xC7"} } 2 -test string-8.4.$noComp {string bytelength} nodep { +test string-8.4.$noComp {string bytelength} { run {string b ""} } 0 @@ -1800,9 +1799,9 @@ test string-19.3.$noComp {string trimleft, unicode default} { test string-20.1.$noComp {string trimright errors} { list [catch {run {string trimright}} msg] $msg } {1 {wrong # args: should be "string trimright string ?chars?"}} -test string-20.2.$noComp {string trimright errors} -body { +test string-20.2.$noComp {string trimright errors} { list [catch {run {string trimg a}} msg] $msg -} -match regexp -result {1 {unknown or ambiguous subcommand "trimg": must be (bytelength, |)cat, charend, charstart, compare, equal, first, index, insert, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} {1 {unknown or ambiguous subcommand "trimg": must be bytelength, cat, charend, charstart, compare, equal, first, index, insert, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test string-20.3.$noComp {string trimright} { run {string trimright " XYZ "} } { XYZ} @@ -1858,7 +1857,7 @@ test string-21.4.$noComp {string wordend} -body { } -result 3 test string-21.5.$noComp {string wordend} -body { run {string wordend abc. 100} -} -result -1 +} -result 4 test string-21.6.$noComp {string wordend} -body { run {string wordend "word_one two three" 2} } -result 8 @@ -1885,17 +1884,17 @@ test string-21.13.$noComp {string wordend, unicode} -body { } -result 3 test string-21.14.$noComp {string wordend, unicode} -body { run {string wordend "\uC700\uC700 abc" 8} -} -result -1 +} -result 6 test string-21.15.$noComp {string wordend, unicode} -body { run {string wordend "\U1D7CA\U1D7CA abc" 0} } -result 2 test string-21.16.$noComp {string wordend, unicode} -constraints utf16 -body { run {string wordend "\U1D7CA\U1D7CA abc" 10} -} -result -1 +} -result 8 test string-22.1.$noComp {string wordstart} -body { list [catch {run {string word a}} msg] $msg -} -match regexp -result {1 {unknown or ambiguous subcommand "word": must be (bytelength, |)cat, charend, charstart, compare, equal, first, index, insert, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} -result {1 {unknown or ambiguous subcommand "word": must be bytelength, cat, charend, charstart, compare, equal, first, index, insert, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test string-22.2.$noComp {string wordstart} -body { list [catch {run {string wordstart a}} msg] $msg } -result {1 {wrong # args: should be "string wordstart string index"}} @@ -1913,7 +1912,7 @@ test string-22.6.$noComp {string wordstart} -body { } -result 0 test string-22.7.$noComp {string wordstart} -body { run {string wordstart "one two three_words" -2} -} -result -1 +} -result 0 test string-22.8.$noComp {string wordstart} -body { run {string wordstart "one .*&^ three" 6} } -result 6 @@ -1939,7 +1938,7 @@ test string-22.14.$noComp {string wordstart, invalid UTF-8} -constraints testbyt } -result g test string-22.15.$noComp {string wordstart, unicode} -body { run {string wordstart "\U1D7CA\U1D7CA abc" 0} -} -result -1 +} -result 0 test string-22.16.$noComp {string wordstart, unicode} -constraints utf16 -body { run {string wordstart "\U1D7CA\U1D7CA abc" 10} } -result 5 @@ -2545,10 +2544,10 @@ test string-33.3.$noComp {string charend} -body { } -result {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}} test string-33.4.$noComp {string charend} -body { run {string charend abc. -1} -} -result 1 +} -result 0 test string-33.5.$noComp {string charend} -body { run {string charend abc. 100} -} -result -1 +} -result 4 test string-33.6.$noComp {string charend} -body { run {string charend "word_one two three" 2} } -result 3 @@ -2575,13 +2574,13 @@ test string-33.13.$noComp {string charend, unicode} -body { } -result 1 test string-33.14.$noComp {string charend, unicode} -body { run {string charend "\uC700\uC700 abc" 8} -} -result -1 +} -result 6 test string-33.15.$noComp {string charend, unicode} -constraints utf16 -body { run {string charend "\U1D7CA\U1D7CA abc" 0} } -result 2 test string-33.16.$noComp {string charend, unicode} -constraints utf16 -body { run {string charend "\U1D7CA\U1D7CA abc" 10} -} -result -1 +} -result 8 test string-34.1.$noComp {string charstart} -body { list [catch {run {string word a}} msg] $msg @@ -2597,42 +2596,42 @@ test string-34.4.$noComp {string charstart} -body { } -result {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}} test string-34.5.$noComp {string charstart} -body { run {string charstart "one two three_words" 400} -} -result 18 +} -result 19 test string-34.6.$noComp {string charstart} -body { run {string charstart "one two three_words" 2} -} -result 1 +} -result 2 test string-34.7.$noComp {string charstart} -body { run {string charstart "one two three_words" -2} -} -result 0 +} -result -1 test string-34.8.$noComp {string charstart} -body { run {string charstart "one .*&^ three" 6} -} -result 5 +} -result 6 test string-34.9.$noComp {string charstart} -body { run {string charstart "one two three" 4} -} -result 3 +} -result 4 test string-34.10.$noComp {string charstart} -body { run {string charstart "one two three" end-5} -} -result 6 +} -result 7 test string-34.11.$noComp {string charstart, unicode} -body { run {string charstart "one tw\xC7o three" 7} -} -result 6 +} -result 7 test string-34.12.$noComp {string charstart, unicode} -body { run {string charstart "ab\uC700\uC700 cdef ghi" 12} -} -result 11 +} -result 12 test string-34.13.$noComp {string charstart, unicode} -body { run {string charstart "\uC700\uC700 abc" 8} -} -result 5 +} -result 6 test string-34.14.$noComp {string charstart, invalid UTF-8} -constraints testbytestring -body { # See Bug c61818e4c9 set demo [testbytestring "abc def\xE0\xA9ghi"] run {string index $demo [string charstart $demo 10]} -} -result g +} -result h test string-34.15.$noComp {string charstart, unicode} -body { run {string charstart "\U1D7CA\U1D7CA abc" 0} } -result 0 test string-34.16.$noComp {string charstart, unicode} -constraints utf16 -body { run {string charstart "\U1D7CA\U1D7CA abc" 10} -} -result 7 +} -result 8 }; # foreach noComp {0 1} -- cgit v0.12 From 9d4d81102579f655e9220ef0f705bb2a058d6ce3 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 9 Nov 2020 16:12:37 +0000 Subject: Possible solution for [ea39ab591e], making simply everything case-insensitive. TODO: TIP, documentation, code cleanup --- generic/tclLoad.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 5090493..36c7457 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -226,8 +226,6 @@ Tcl_LoadObjCmd( Tcl_DStringAppend(&pkgName, packageName, -1); TclDStringClear(&tmp); Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1); - Tcl_UtfToLower(Tcl_DStringValue(&pkgName)); - Tcl_UtfToLower(Tcl_DStringValue(&tmp)); if (strcmp(Tcl_DStringValue(&tmp), Tcl_DStringValue(&pkgName)) == 0) { namesMatch = 1; @@ -321,6 +319,12 @@ Tcl_LoadObjCmd( splitPtr = Tcl_FSSplitPath(objv[1], &pElements); Tcl_ListObjIndex(NULL, splitPtr, pElements -1, &pkgGuessPtr); pkgGuess = TclGetString(pkgGuessPtr); +#if defined(_WIN32) || defined(__CYGWIN__) + if ((pkgGuess[0] == 'w') && (pkgGuess[1] == 'i') + && (pkgGuess[2] == 'n')) { + pkgGuess += 3; + } else +#endif /* __CYGWIN__ */ if ((pkgGuess[0] == 'l') && (pkgGuess[1] == 'i') && (pkgGuess[2] == 'b')) { pkgGuess += 3; @@ -351,16 +355,17 @@ Tcl_LoadObjCmd( } Tcl_DStringAppend(&pkgName, pkgGuess, p - pkgGuess); Tcl_DecrRefCount(splitPtr); - } - /* - * Fix the capitalization in the package name so that the first - * character is in caps (or title case) but the others are all - * lower-case. - */ + /* + * Fix the capitalization in the package name so that the first + * character is in caps (or title case) but the others are all + * lower-case. + */ - Tcl_DStringSetLength(&pkgName, - Tcl_UtfToTitle(Tcl_DStringValue(&pkgName))); + Tcl_DStringSetLength(&pkgName, + Tcl_UtfToTitle(Tcl_DStringValue(&pkgName))); + + } /* * Compute the names of the two initialization functions, based on the @@ -656,8 +661,6 @@ Tcl_UnloadObjCmd( Tcl_DStringAppend(&pkgName, packageName, -1); TclDStringClear(&tmp); Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1); - Tcl_UtfToLower(Tcl_DStringValue(&pkgName)); - Tcl_UtfToLower(Tcl_DStringValue(&tmp)); if (strcmp(Tcl_DStringValue(&tmp), Tcl_DStringValue(&pkgName)) == 0) { namesMatch = 1; -- cgit v0.12 From 062875b88e20fd9dea45ddd120f20df6a307ba3e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 10 Nov 2020 14:51:44 +0000 Subject: Merge 9.0. Code/documentation cleanup --- .travis.yml | 2 +- doc/PkgRequire.3 | 2 +- doc/StaticLibrary.3 | 73 ++++++++ doc/StaticPkg.3 | 73 -------- doc/load.n | 75 ++++---- generic/tcl.decls | 4 +- generic/tcl.h | 3 +- generic/tclCmdIL.c | 2 +- generic/tclInt.decls | 2 +- generic/tclInt.h | 2 +- generic/tclIntDecls.h | 16 +- generic/tclLoad.c | 354 +++++++++++++++++------------------ generic/tclStubInit.c | 6 +- generic/tclTest.c | 16 +- macosx/Tcl.xcode/project.pbxproj | 4 +- macosx/Tcl.xcodeproj/project.pbxproj | 4 +- tests/load.test | 98 +++++----- tests/safe.test | 2 +- tests/unload.test | 22 +-- unix/tclAppInit.c | 2 +- win/tcl.dsp | 2 +- win/tclAppInit.c | 6 +- 22 files changed, 381 insertions(+), 389 deletions(-) create mode 100644 doc/StaticLibrary.3 delete mode 100644 doc/StaticPkg.3 diff --git a/.travis.yml b/.travis.yml index a7c1d2f..5c5ae80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -243,7 +243,7 @@ jobs: script: - cmd.exe //C vcvarsall.bat x64 '&&' nmake 'OPTS=static,msvcrt' '-f' makefile.vc all tcltest - cmd.exe //C vcvarsall.bat x64 '&&' nmake 'OPTS=static,msvcrt' '-f' makefile.vc test - - name: "Windows/MSVC/StaticPackage" + - name: "Windows/MSVC/StaticPkg" os: windows compiler: cl env: *vcenv diff --git a/doc/PkgRequire.3 b/doc/PkgRequire.3 index 71f3acf..f32c936 100644 --- a/doc/PkgRequire.3 +++ b/doc/PkgRequire.3 @@ -94,4 +94,4 @@ compatibility and translate their invocations to this form. .SH KEYWORDS package, present, provide, require, version .SH "SEE ALSO" -package(n), Tcl_StaticPackage(3) +package(n), Tcl_StaticLibrary(3) diff --git a/doc/StaticLibrary.3 b/doc/StaticLibrary.3 new file mode 100644 index 0000000..ecd064c --- /dev/null +++ b/doc/StaticLibrary.3 @@ -0,0 +1,73 @@ +'\" +'\" Copyright (c) 1995-1996 Sun Microsystems, Inc. +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH Tcl_StaticLibrary 3 7.5 Tcl "Tcl Library Procedures" +.so man.macros +.BS +.SH NAME +Tcl_StaticLibrary \- make a statically linked package available via the 'load' command +.SH SYNOPSIS +.nf +\fB#include \fR +.sp +\fBTcl_StaticLibrary\fR(\fIinterp, pkgName, initProc, safeInitProc\fR) +.SH ARGUMENTS +.AS Tcl_PackageInitProc *safeInitProc +.AP Tcl_Interp *interp in +If not NULL, points to an interpreter into which the package has +already been loaded (i.e., the caller has already invoked the +appropriate initialization procedure). NULL means the package +has not yet been incorporated into any interpreter. +.AP "const char" *pkgName in +Name of the package; should be properly capitalized (first letter +upper-case, all others lower-case). +.AP Tcl_PackageInitProc *initProc in +Procedure to invoke to incorporate this package into a trusted +interpreter. +.AP Tcl_PackageInitProc *safeInitProc in +Procedure to call to incorporate this package into a safe interpreter +(one that will execute untrusted scripts). NULL means the package +cannot be used in safe interpreters. +.BE +.SH DESCRIPTION +.PP +This procedure may be invoked to announce that a package has been +linked statically with a Tcl application and, optionally, that it +has already been loaded into an interpreter. +Once \fBTcl_StaticLibrary\fR has been invoked for a package, it +may be loaded into interpreters using the \fBload\fR command. +\fBTcl_StaticLibrary\fR is normally invoked only by the \fBTcl_AppInit\fR +procedure for the application, not by packages for themselves +(\fBTcl_StaticLibrary\fR should only be invoked for statically +loaded packages, and code in the package itself should not need +to know whether the package is dynamically or statically loaded). +.PP +When the \fBload\fR command is used later to load the package into +an interpreter, one of \fIinitProc\fR and \fIsafeInitProc\fR will +be invoked, depending on whether the target interpreter is safe +or not. +\fIinitProc\fR and \fIsafeInitProc\fR must both match the +following prototype: +.PP +.CS +typedef int \fBTcl_PackageInitProc\fR( + Tcl_Interp *\fIinterp\fR); +.CE +.PP +The \fIinterp\fR argument identifies the interpreter in which the package +is to be loaded. The initialization procedure must return \fBTCL_OK\fR or +\fBTCL_ERROR\fR to indicate whether or not it completed successfully; in +the event of an error it should set the interpreter's result to point to an +error message. The result or error from the initialization procedure will +be returned as the result of the \fBload\fR command that caused the +initialization procedure to be invoked. +.PP +\fBTcl_StaticLibrary\fR can not be safely used by stub-enabled extensions, +so its symbol is not included in the stub table. +.SH KEYWORDS +initialization procedure, package, static linking +.SH "SEE ALSO" +load(n), package(n), Tcl_PkgRequire(3) diff --git a/doc/StaticPkg.3 b/doc/StaticPkg.3 deleted file mode 100644 index a28652e..0000000 --- a/doc/StaticPkg.3 +++ /dev/null @@ -1,73 +0,0 @@ -'\" -'\" Copyright (c) 1995-1996 Sun Microsystems, Inc. -'\" -'\" See the file "license.terms" for information on usage and redistribution -'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" -.TH Tcl_StaticPackage 3 7.5 Tcl "Tcl Library Procedures" -.so man.macros -.BS -.SH NAME -Tcl_StaticPackage \- make a statically linked package available via the 'load' command -.SH SYNOPSIS -.nf -\fB#include \fR -.sp -\fBTcl_StaticPackage\fR(\fIinterp, pkgName, initProc, safeInitProc\fR) -.SH ARGUMENTS -.AS Tcl_PackageInitProc *safeInitProc -.AP Tcl_Interp *interp in -If not NULL, points to an interpreter into which the package has -already been loaded (i.e., the caller has already invoked the -appropriate initialization procedure). NULL means the package -has not yet been incorporated into any interpreter. -.AP "const char" *pkgName in -Name of the package; should be properly capitalized (first letter -upper-case, all others lower-case). -.AP Tcl_PackageInitProc *initProc in -Procedure to invoke to incorporate this package into a trusted -interpreter. -.AP Tcl_PackageInitProc *safeInitProc in -Procedure to call to incorporate this package into a safe interpreter -(one that will execute untrusted scripts). NULL means the package -cannot be used in safe interpreters. -.BE -.SH DESCRIPTION -.PP -This procedure may be invoked to announce that a package has been -linked statically with a Tcl application and, optionally, that it -has already been loaded into an interpreter. -Once \fBTcl_StaticPackage\fR has been invoked for a package, it -may be loaded into interpreters using the \fBload\fR command. -\fBTcl_StaticPackage\fR is normally invoked only by the \fBTcl_AppInit\fR -procedure for the application, not by packages for themselves -(\fBTcl_StaticPackage\fR should only be invoked for statically -loaded packages, and code in the package itself should not need -to know whether the package is dynamically or statically loaded). -.PP -When the \fBload\fR command is used later to load the package into -an interpreter, one of \fIinitProc\fR and \fIsafeInitProc\fR will -be invoked, depending on whether the target interpreter is safe -or not. -\fIinitProc\fR and \fIsafeInitProc\fR must both match the -following prototype: -.PP -.CS -typedef int \fBTcl_PackageInitProc\fR( - Tcl_Interp *\fIinterp\fR); -.CE -.PP -The \fIinterp\fR argument identifies the interpreter in which the package -is to be loaded. The initialization procedure must return \fBTCL_OK\fR or -\fBTCL_ERROR\fR to indicate whether or not it completed successfully; in -the event of an error it should set the interpreter's result to point to an -error message. The result or error from the initialization procedure will -be returned as the result of the \fBload\fR command that caused the -initialization procedure to be invoked. -.PP -\fBTcl_StaticPackage\fR can not be safely used by stub-enabled extensions, -so its symbol is not included in the stub table. -.SH KEYWORDS -initialization procedure, package, static linking -.SH "SEE ALSO" -load(n), package(n), Tcl_PkgRequire(3) diff --git a/doc/load.n b/doc/load.n index 03b4f4e..b8a26ae 100644 --- a/doc/load.n +++ b/doc/load.n @@ -13,22 +13,21 @@ load \- Load machine code and initialize new commands .SH SYNOPSIS \fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName\fR .br -\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName\fR +\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName prefix\fR .br -\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName interp\fR +\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName prefix interp\fR .BE .SH DESCRIPTION .PP This command loads binary code from a file into the application's address space and calls an initialization procedure -in the package to incorporate it into an interpreter. \fIfileName\fR +in the library to incorporate it into an interpreter. \fIfileName\fR is the name of the file containing the code; its exact form varies from system to system but on most systems it is a shared library, such as a \fB.so\fR file under Solaris or a DLL under Windows. -\fIpackageName\fR is the name of the package, and is used to -compute the name of an initialization procedure. +\fIprefix\fR is used to compute the name of an initialization procedure. \fIinterp\fR is the path name of the interpreter into which to load -the package (see the \fBinterp\fR manual entry for details); +the library (see the \fBinterp\fR manual entry for details); if \fIinterp\fR is omitted, it defaults to the interpreter in which the \fBload\fR command was invoked. .PP @@ -37,21 +36,19 @@ one of two initialization procedures will be invoked in the new code. Typically the initialization procedure will add new commands to a Tcl interpreter. The name of the initialization procedure is determined by -\fIpackageName\fR and whether or not the target interpreter +\fIprefix\fR and whether or not the target interpreter is a safe one. For normal interpreters the name of the initialization -procedure will have the form \fIpkg\fB_Init\fR, where \fIpkg\fR -is the same as \fIpackageName\fR except that the first letter is -converted to upper case and all other letters -are converted to lower case. For example, if \fIpackageName\fR is -\fBfoo\fR or \fBFOo\fR, the initialization procedure's name will +procedure will have the form \fIprefix\fB_Init\fR, where \fIprefix\fR +is the same as \fIprefix\fR. For example, if \fIprefix\fR is +\fBFoo\fR, the initialization procedure's name will be \fBFoo_Init\fR. .PP If the target interpreter is a safe interpreter, then the name -of the initialization procedure will be \fIpkg\fB_SafeInit\fR -instead of \fIpkg\fB_Init\fR. -The \fIpkg\fB_SafeInit\fR function should be written carefully, so that it +of the initialization procedure will be \fIprefix\fB_SafeInit\fR +instead of \fIprefix\fB_Init\fR. +The \fIprefix\fB_SafeInit\fR function should be written carefully, so that it initializes the safe interpreter only with partial functionality provided -by the package that is safe for use by untrusted code. For more information +by the library that is safe for use by untrusted code. For more information on Safe\-Tcl, see the \fBsafe\fR manual entry. .PP The initialization procedure must match the following prototype: @@ -62,7 +59,7 @@ typedef int \fBTcl_PackageInitProc\fR( .CE .PP The \fIinterp\fR argument identifies the interpreter in which the -package is to be loaded. The initialization procedure must return +library is to be loaded. The initialization procedure must return \fBTCL_OK\fR or \fBTCL_ERROR\fR to indicate whether or not it completed successfully; in the event of an error it should set the interpreter's result to point to an error message. The result of the \fBload\fR command @@ -74,36 +71,34 @@ interpreters, then the first \fBload\fR will load the code and call the initialization procedure; subsequent \fBload\fRs will call the initialization procedure without loading the code again. For Tcl versions lower than 8.5, it is not possible to unload or reload a -package. From version 8.5 however, the \fBunload\fR command allows the unloading +library. From version 8.5 however, the \fBunload\fR command allows the unloading of libraries loaded with \fBload\fR, for libraries that are aware of the Tcl's unloading mechanism. .PP -The \fBload\fR command also supports packages that are statically -linked with the application, if those packages have been registered -by calling the \fBTcl_StaticPackage\fR procedure. -If \fIfileName\fR is an empty string, then \fIpackageName\fR must +The \fBload\fR command also supports libraries that are statically +linked with the application, if those libraries have been registered +by calling the \fBTcl_StaticLibrary\fR procedure. +If \fIfileName\fR is an empty string, then \fIprefix\fR must be specified. .PP -If \fIpackageName\fR is omitted or specified as an empty string, -Tcl tries to guess the name of the package. -This may be done differently on different platforms. -The default guess, which is used on most UNIX platforms, is to -take the last element of \fIfileName\fR, strip off the first -three characters if they are \fBlib\fR, and use any following -alphabetic and underline characters as the module name. -For example, the command \fBload libxyz4.2.so\fR uses the module -name \fBxyz\fR and the command \fBload bin/last.so {}\fR uses the -module name \fBlast\fR. -.PP -If \fIfileName\fR is an empty string, then \fIpackageName\fR must +If \fIprefix\fR is omitted or specified as an empty string, +Tcl tries to guess the prefix by taking the last element of +\fIfileName\fR, strip off the first three characters if they +are \fBlib\fR, and use any following alphabetic and underline +characters, converted to titlecase as the prefix. +For example, the command \fBload libxyz4.2.so\fR uses the prefix +\fBxyz\fR and the command \fBload bin/last.so {}\fR uses the +prefix \fBlast\fR. +.PP +If \fIfileName\fR is an empty string, then \fIprefix\fR must be specified. -The \fBload\fR command first searches for a statically loaded package -(one that has been registered by calling the \fBTcl_StaticPackage\fR +The \fBload\fR command first searches for a statically loaded library +(one that has been registered by calling the \fBTcl_StaticLibrary\fR procedure) by that name; if one is found, it is used. Otherwise, the \fBload\fR command searches for a dynamically loaded -package by that name, and uses it if it is found. If several +library by that name, and uses it if it is found. If several different files have been \fBload\fRed with different versions of -the package, Tcl picks the file that was loaded first. +the library, Tcl picks the file that was loaded first. .PP If \fB\-global\fR is specified preceding the filename, all symbols found in the shared library are exported for global use by other @@ -111,7 +106,7 @@ libraries. The option \fB\-lazy\fR delays the actual loading of symbols until their first actual use. The options may be abbreviated. The option \fB\-\-\fR indicates the end of the options, and should be used if you wish to use a filename which starts with \fB\-\fR -and you provide a packageName to the \fBload\fR command. +and you provide a prefix to the \fBload\fR command. .PP On platforms which do not support the \fB\-global\fR or \fB\-lazy\fR options, the options still exist but have no effect. Note that use @@ -188,7 +183,7 @@ switch $tcl_platform(platform) { foo .CE .SH "SEE ALSO" -info sharedlibextension, package(n), Tcl_StaticPackage(3), safe(n) +info sharedlibextension, package(n), Tcl_StaticLibrary(3), safe(n) .SH KEYWORDS binary code, dynamic library, load, safe interpreter, shared library '\"Local Variables: diff --git a/generic/tcl.decls b/generic/tcl.decls index 4a58a20..ff97dfc 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -888,7 +888,7 @@ declare 243 { } # Removed in 9.0 (stub entry only) #declare 244 { -# void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName, +# void Tcl_StaticLibrary(Tcl_Interp *interp, const char *prefix, # Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) #} # Removed in 9.0 (stub entry only) @@ -2514,7 +2514,7 @@ export { Tcl_Interp *interp) } export { - void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName, + void Tcl_StaticLibrary(Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } export { diff --git a/generic/tcl.h b/generic/tcl.h index eb6d2fe..a87c5d4 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2189,10 +2189,11 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); EXTERN void Tcl_FindExecutable(const char *argv0); EXTERN void Tcl_SetPanicProc( TCL_NORETURN1 Tcl_PanicProc *panicProc); -EXTERN void Tcl_StaticPackage(Tcl_Interp *interp, +EXTERN void Tcl_StaticLibrary(Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); +#define Tcl_StaticPackage Tcl_StaticLibrary EXTERN Tcl_ExitProc *Tcl_SetExitProc(TCL_NORETURN1 Tcl_ExitProc *proc); #ifdef _WIN32 EXTERN int TclZipfs_AppHook(int *argc, wchar_t ***argv); diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 5a8ef22..4536d18 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -1699,7 +1699,7 @@ InfoLoadedCmd( } else { /* Get pkgs just in specified interp. */ packageName = TclGetString(objv[2]); } - return TclGetLoadedPackagesEx(interp, interpName, packageName); + return TclGetLoadedLibraries(interp, interpName, packageName); } /* diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 5b02fb4..e764bc4 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -1058,7 +1058,7 @@ declare 256 { Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags) } declare 257 { - void TclStaticPackage(Tcl_Interp *interp, const char *pkgName, + void TclStaticLibrary(Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } diff --git a/generic/tclInt.h b/generic/tclInt.h index 2a0dfa6..cd0f148 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2975,7 +2975,7 @@ MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE char * TclGetStringStorage(Tcl_Obj *objPtr, size_t *sizePtr); -MODULE_SCOPE int TclGetLoadedPackagesEx(Tcl_Interp *interp, +MODULE_SCOPE int TclGetLoadedLibraries(Tcl_Interp *interp, const char *targetName, const char *packageName); MODULE_SCOPE int TclGetWideBitsFromObj(Tcl_Interp *, Tcl_Obj *, diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index e870aac..cf8d660 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -570,8 +570,8 @@ EXTERN int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 257 */ -EXTERN void TclStaticPackage(Tcl_Interp *interp, - const char *pkgName, +EXTERN void TclStaticLibrary(Tcl_Interp *interp, + const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 258 */ @@ -845,7 +845,7 @@ typedef struct TclIntStubs { Tcl_Obj * (*tclPtrIncrObjVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, const int flags); /* 254 */ int (*tclPtrObjMakeUpvar) (Tcl_Interp *interp, Tcl_Var otherPtr, Tcl_Obj *myNamePtr, int myFlags); /* 255 */ int (*tclPtrUnsetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 256 */ - void (*tclStaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ + void (*tclStaticLibrary) (Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ Tcl_Obj * (*tclpCreateTemporaryDirectory) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj); /* 258 */ void (*tclAppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t length); /* 259 */ unsigned char * (*tclGetBytesFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, size_t *lengthPtr); /* 260 */ @@ -1260,8 +1260,8 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclPtrObjMakeUpvar) /* 255 */ #define TclPtrUnsetVar \ (tclIntStubsPtr->tclPtrUnsetVar) /* 256 */ -#define TclStaticPackage \ - (tclIntStubsPtr->tclStaticPackage) /* 257 */ +#define TclStaticLibrary \ + (tclIntStubsPtr->tclStaticLibrary) /* 257 */ #define TclpCreateTemporaryDirectory \ (tclIntStubsPtr->tclpCreateTemporaryDirectory) /* 258 */ #define TclAppendUnicodeToObj \ @@ -1274,9 +1274,9 @@ extern const TclIntStubs *tclIntStubsPtr; /* !END!: Do not edit above this line. */ #if defined(USE_TCL_STUBS) -#undef Tcl_StaticPackage -#define Tcl_StaticPackage \ - (tclIntStubsPtr->tclStaticPackage) +#undef Tcl_StaticLibrary +#define Tcl_StaticLibrary \ + (tclIntStubsPtr->tclStaticLibrary) #endif /* defined(USE_TCL_STUBS) */ #undef TCL_STORAGE_CLASS diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 36c7457..67bc2cc 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -15,19 +15,17 @@ /* * The following structure describes a package that has been loaded either * dynamically (with the "load" command) or statically (as indicated by a call - * to TclGetLoadedPackages). All such packages are linked together into a + * to TclGetLoadedLibraries). All such packages are linked together into a * single list for the process. Packages are never unloaded, until the * application exits, when TclFinalizeLoad is called, and these structures are * freed. */ -typedef struct LoadedPackage { +typedef struct LoadedLibrary { char *fileName; /* Name of the file from which the package was * loaded. An empty string means the package * is loaded statically. Malloc-ed. */ - char *packageName; /* Name of package prefix for the package, - * properly capitalized (first letter UC, - * others LC), no "_", as in "Net". + char *prefix; /* Prefix for the library. * Malloc-ed. */ Tcl_LoadHandle loadHandle; /* Token for the loaded file which should be * passed to (*unLoadProcPtr)() when the file @@ -55,23 +53,23 @@ typedef struct LoadedPackage { * in trusted interpreters. */ int safeInterpRefCount; /* How many times the package has been loaded * in safe interpreters. */ - struct LoadedPackage *nextPtr; + struct LoadedLibrary *nextPtr; /* Next in list of all packages loaded into * this application process. NULL means end of * list. */ -} LoadedPackage; +} LoadedLibrary; /* * TCL_THREADS - * There is a global list of packages that is anchored at firstPackagePtr. + * There is a global list of packages that is anchored at firstLibraryPtr. * Access to this list is governed by a mutex. */ -static LoadedPackage *firstPackagePtr = NULL; +static LoadedLibrary *firstLibraryPtr = NULL; /* First in list of all packages loaded into * this process. */ -TCL_DECLARE_MUTEX(packageMutex) +TCL_DECLARE_MUTEX(libraryMutex) /* * The following structure represents a particular package that has been @@ -82,7 +80,7 @@ TCL_DECLARE_MUTEX(packageMutex) */ typedef struct InterpPackage { - LoadedPackage *pkgPtr; /* Points to detailed information about + LoadedLibrary *libraryPtr; /* Points to detailed information about * package. */ struct InterpPackage *nextPtr; /* Next package in this interpreter, or NULL @@ -121,14 +119,14 @@ Tcl_LoadObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *target; - LoadedPackage *pkgPtr, *defaultPtr; + LoadedLibrary *libraryPtr, *defaultPtr; Tcl_DString pkgName, tmp, initName, safeInitName; Tcl_DString unloadName, safeUnloadName; InterpPackage *ipFirstPtr, *ipPtr; int code, namesMatch, filesMatch, offset; const char *symbols[2]; Tcl_PackageInitProc *initProc; - const char *p, *fullFileName, *packageName; + const char *p, *fullFileName, *prefix; Tcl_LoadHandle loadHandle; Tcl_UniChar ch = 0; size_t len; @@ -159,7 +157,7 @@ Tcl_LoadObjCmd( } } if ((objc < 2) || (objc > 4)) { - Tcl_WrongNumArgs(interp, 1, savedobjv, "?-global? ?-lazy? ?--? fileName ?packageName? ?interp?"); + Tcl_WrongNumArgs(interp, 1, savedobjv, "?-global? ?-lazy? ?--? fileName ?prefix? ?interp?"); return TCL_ERROR; } if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) { @@ -174,14 +172,14 @@ Tcl_LoadObjCmd( Tcl_DStringInit(&safeUnloadName); Tcl_DStringInit(&tmp); - packageName = NULL; + prefix = NULL; if (objc >= 3) { - packageName = TclGetString(objv[2]); - if (packageName[0] == '\0') { - packageName = NULL; + prefix = TclGetString(objv[2]); + if (prefix[0] == '\0') { + prefix = NULL; } } - if ((fullFileName[0] == 0) && (packageName == NULL)) { + if ((fullFileName[0] == 0) && (prefix == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "must specify either file name or package name", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOLIBRARY", @@ -215,17 +213,17 @@ Tcl_LoadObjCmd( * only no statically loaded package with the same name. */ - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); defaultPtr = NULL; - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { - if (packageName == NULL) { + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; libraryPtr = libraryPtr->nextPtr) { + if (prefix == NULL) { namesMatch = 0; } else { TclDStringClear(&pkgName); - Tcl_DStringAppend(&pkgName, packageName, -1); + Tcl_DStringAppend(&pkgName, prefix, -1); TclDStringClear(&tmp); - Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1); + Tcl_DStringAppend(&tmp, libraryPtr->prefix, -1); if (strcmp(Tcl_DStringValue(&tmp), Tcl_DStringValue(&pkgName)) == 0) { namesMatch = 1; @@ -235,12 +233,12 @@ Tcl_LoadObjCmd( } TclDStringClear(&pkgName); - filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0); - if (filesMatch && (namesMatch || (packageName == NULL))) { + filesMatch = (strcmp(libraryPtr->fileName, fullFileName) == 0); + if (filesMatch && (namesMatch || (prefix == NULL))) { break; } if (namesMatch && (fullFileName[0] == 0)) { - defaultPtr = pkgPtr; + defaultPtr = libraryPtr; } if (filesMatch && !namesMatch && (fullFileName[0] != 0)) { /* @@ -249,17 +247,17 @@ Tcl_LoadObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" is already loaded for package \"%s\"", - fullFileName, pkgPtr->packageName)); + fullFileName, libraryPtr->prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "SPLITPERSONALITY", NULL); code = TCL_ERROR; - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); goto done; } } - Tcl_MutexUnlock(&packageMutex); - if (pkgPtr == NULL) { - pkgPtr = defaultPtr; + Tcl_MutexUnlock(&libraryMutex); + if (libraryPtr == NULL) { + libraryPtr = defaultPtr; } /* @@ -268,17 +266,17 @@ Tcl_LoadObjCmd( * there's nothing for us to do. */ - if (pkgPtr != NULL) { + if (libraryPtr != NULL) { ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - if (ipPtr->pkgPtr == pkgPtr) { + if (ipPtr->libraryPtr == libraryPtr) { code = TCL_OK; goto done; } } } - if (pkgPtr == NULL) { + if (libraryPtr == NULL) { /* * The desired file isn't currently loaded, so load it. It's an error * if the desired package is a static one. @@ -286,7 +284,7 @@ Tcl_LoadObjCmd( if (fullFileName[0] == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "package \"%s\" isn't loaded statically", packageName)); + "no library with prefix \"%s\" is loaded statically", prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOTSTATIC", NULL); code = TCL_ERROR; @@ -297,8 +295,8 @@ Tcl_LoadObjCmd( * Figure out the module name if it wasn't provided explicitly. */ - if (packageName != NULL) { - Tcl_DStringAppend(&pkgName, packageName, -1); + if (prefix != NULL) { + Tcl_DStringAppend(&pkgName, prefix, -1); } else { Tcl_Obj *splitPtr, *pkgGuessPtr; int pElements; @@ -389,10 +387,10 @@ Tcl_LoadObjCmd( symbols[0] = Tcl_DStringValue(&initName); symbols[1] = NULL; - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); code = Tcl_LoadFile(interp, objv[1], symbols, flags, &initProc, &loadHandle); - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); if (code != TCL_OK) { goto done; } @@ -401,31 +399,31 @@ Tcl_LoadObjCmd( * Create a new record to describe this package. */ - pkgPtr = (LoadedPackage *)Tcl_Alloc(sizeof(LoadedPackage)); + libraryPtr = (LoadedLibrary *)Tcl_Alloc(sizeof(LoadedLibrary)); len = strlen(fullFileName) + 1; - pkgPtr->fileName = (char *)Tcl_Alloc(len); - memcpy(pkgPtr->fileName, fullFileName, len); + libraryPtr->fileName = (char *)Tcl_Alloc(len); + memcpy(libraryPtr->fileName, fullFileName, len); len = Tcl_DStringLength(&pkgName) + 1; - pkgPtr->packageName = (char *)Tcl_Alloc(len); - memcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName), len); - pkgPtr->loadHandle = loadHandle; - pkgPtr->initProc = initProc; - pkgPtr->safeInitProc = (Tcl_PackageInitProc *) + libraryPtr->prefix = (char *)Tcl_Alloc(len); + memcpy(libraryPtr->prefix, Tcl_DStringValue(&pkgName), len); + libraryPtr->loadHandle = loadHandle; + libraryPtr->initProc = initProc; + libraryPtr->safeInitProc = (Tcl_PackageInitProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&safeInitName)); - pkgPtr->unloadProc = (Tcl_PackageUnloadProc *) + libraryPtr->unloadProc = (Tcl_PackageUnloadProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&unloadName)); - pkgPtr->safeUnloadProc = (Tcl_PackageUnloadProc *) + libraryPtr->safeUnloadProc = (Tcl_PackageUnloadProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&safeUnloadName)); - pkgPtr->interpRefCount = 0; - pkgPtr->safeInterpRefCount = 0; + libraryPtr->interpRefCount = 0; + libraryPtr->safeInterpRefCount = 0; - Tcl_MutexLock(&packageMutex); - pkgPtr->nextPtr = firstPackagePtr; - firstPackagePtr = pkgPtr; - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexLock(&libraryMutex); + libraryPtr->nextPtr = firstLibraryPtr; + firstLibraryPtr = libraryPtr; + Tcl_MutexUnlock(&libraryMutex); /* * The Tcl_FindSymbol calls may have left a spurious error message in @@ -441,27 +439,27 @@ Tcl_LoadObjCmd( */ if (Tcl_IsSafe(target)) { - if (pkgPtr->safeInitProc == NULL) { + if (libraryPtr->safeInitProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't use package in a safe interpreter: no" - " %s_SafeInit procedure", pkgPtr->packageName)); + " %s_SafeInit procedure", libraryPtr->prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "UNSAFE", NULL); code = TCL_ERROR; goto done; } - code = pkgPtr->safeInitProc(target); + code = libraryPtr->safeInitProc(target); } else { - if (pkgPtr->initProc == NULL) { + if (libraryPtr->initProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't attach package to interpreter: no %s_Init procedure", - pkgPtr->packageName)); + libraryPtr->prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "ENTRYPOINT", NULL); code = TCL_ERROR; goto done; } - code = pkgPtr->initProc(target); + code = libraryPtr->initProc(target); } /* @@ -492,13 +490,13 @@ Tcl_LoadObjCmd( * Update the proper reference count. */ - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); if (Tcl_IsSafe(target)) { - pkgPtr->safeInterpRefCount++; + libraryPtr->safeInterpRefCount++; } else { - pkgPtr->interpRefCount++; + libraryPtr->interpRefCount++; } - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); /* * Refetch ipFirstPtr: loading the package may have introduced additional @@ -507,7 +505,7 @@ Tcl_LoadObjCmd( ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); ipPtr = (InterpPackage *)Tcl_Alloc(sizeof(InterpPackage)); - ipPtr->pkgPtr = pkgPtr; + ipPtr->libraryPtr = libraryPtr; ipPtr->nextPtr = ipFirstPtr; Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipPtr); @@ -546,14 +544,14 @@ Tcl_UnloadObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *target; /* Which interpreter to unload from. */ - LoadedPackage *pkgPtr, *defaultPtr; + LoadedLibrary *libraryPtr, *defaultPtr; Tcl_DString pkgName, tmp; Tcl_PackageUnloadProc *unloadProc; InterpPackage *ipFirstPtr, *ipPtr; int i, index, code, complain = 1, keepLibrary = 0; int trustedRefCount = -1, safeRefCount = -1; const char *fullFileName = ""; - const char *packageName; + const char *prefix; static const char *const options[] = { "-nocomplain", "-keeplibrary", "--", NULL }; @@ -597,7 +595,7 @@ Tcl_UnloadObjCmd( endOfForLoop: if ((objc-i < 1) || (objc-i > 3)) { Tcl_WrongNumArgs(interp, 1, objv, - "?-switch ...? fileName ?packageName? ?interp?"); + "?-switch ...? fileName ?prefix? ?interp?"); return TCL_ERROR; } if (Tcl_FSConvertToPathType(interp, objv[i]) != TCL_OK) { @@ -608,14 +606,14 @@ Tcl_UnloadObjCmd( Tcl_DStringInit(&pkgName); Tcl_DStringInit(&tmp); - packageName = NULL; + prefix = NULL; if (objc - i >= 2) { - packageName = TclGetString(objv[i+1]); - if (packageName[0] == '\0') { - packageName = NULL; + prefix = TclGetString(objv[i+1]); + if (prefix[0] == '\0') { + prefix = NULL; } } - if ((fullFileName[0] == 0) && (packageName == NULL)) { + if ((fullFileName[0] == 0) && (prefix == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "must specify either file name or package name", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NOLIBRARY", @@ -648,19 +646,19 @@ Tcl_UnloadObjCmd( * only no statically loaded package with the same name. */ - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); defaultPtr = NULL; - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; libraryPtr = libraryPtr->nextPtr) { int namesMatch, filesMatch; - if (packageName == NULL) { + if (prefix == NULL) { namesMatch = 0; } else { TclDStringClear(&pkgName); - Tcl_DStringAppend(&pkgName, packageName, -1); + Tcl_DStringAppend(&pkgName, prefix, -1); TclDStringClear(&tmp); - Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1); + Tcl_DStringAppend(&tmp, libraryPtr->prefix, -1); if (strcmp(Tcl_DStringValue(&tmp), Tcl_DStringValue(&pkgName)) == 0) { namesMatch = 1; @@ -670,32 +668,32 @@ Tcl_UnloadObjCmd( } TclDStringClear(&pkgName); - filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0); - if (filesMatch && (namesMatch || (packageName == NULL))) { + filesMatch = (strcmp(libraryPtr->fileName, fullFileName) == 0); + if (filesMatch && (namesMatch || (prefix == NULL))) { break; } if (namesMatch && (fullFileName[0] == 0)) { - defaultPtr = pkgPtr; + defaultPtr = libraryPtr; } if (filesMatch && !namesMatch && (fullFileName[0] != 0)) { break; } } - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); if (fullFileName[0] == 0) { /* * It's an error to try unload a static package. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "package \"%s\" is loaded statically and cannot be unloaded", - packageName)); + "library with prefix \"%s\" is loaded statically and cannot be unloaded", + prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "STATIC", NULL); code = TCL_ERROR; goto done; } - if (pkgPtr == NULL) { + if (libraryPtr == NULL) { /* * The DLL pointed by the provided filename has never been loaded. */ @@ -715,10 +713,10 @@ Tcl_UnloadObjCmd( */ code = TCL_ERROR; - if (pkgPtr != NULL) { + if (libraryPtr != NULL) { ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - if (ipPtr->pkgPtr == pkgPtr) { + if (ipPtr->libraryPtr == libraryPtr) { code = TCL_OK; break; } @@ -740,12 +738,12 @@ Tcl_UnloadObjCmd( /* * Ensure that the DLL can be unloaded. If it is a trusted interpreter, - * pkgPtr->unloadProc must not be NULL for the DLL to be unloadable. If - * the interpreter is a safe one, pkgPtr->safeUnloadProc must be non-NULL. + * libraryPtr->unloadProc must not be NULL for the DLL to be unloadable. If + * the interpreter is a safe one, libraryPtr->safeUnloadProc must be non-NULL. */ if (Tcl_IsSafe(target)) { - if (pkgPtr->safeUnloadProc == NULL) { + if (libraryPtr->safeUnloadProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" cannot be unloaded under a safe interpreter", fullFileName)); @@ -754,9 +752,9 @@ Tcl_UnloadObjCmd( code = TCL_ERROR; goto done; } - unloadProc = pkgPtr->safeUnloadProc; + unloadProc = libraryPtr->safeUnloadProc; } else { - if (pkgPtr->unloadProc == NULL) { + if (libraryPtr->unloadProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" cannot be unloaded under a trusted interpreter", fullFileName)); @@ -765,7 +763,7 @@ Tcl_UnloadObjCmd( code = TCL_ERROR; goto done; } - unloadProc = pkgPtr->unloadProc; + unloadProc = libraryPtr->unloadProc; } /* @@ -780,10 +778,10 @@ Tcl_UnloadObjCmd( code = TCL_UNLOAD_DETACH_FROM_INTERPRETER; if (!keepLibrary) { - Tcl_MutexLock(&packageMutex); - trustedRefCount = pkgPtr->interpRefCount; - safeRefCount = pkgPtr->safeInterpRefCount; - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexLock(&libraryMutex); + trustedRefCount = libraryPtr->interpRefCount; + safeRefCount = libraryPtr->safeInterpRefCount; + Tcl_MutexUnlock(&libraryMutex); if (Tcl_IsSafe(target)) { safeRefCount--; @@ -806,34 +804,34 @@ Tcl_UnloadObjCmd( * if we unload the DLL. */ - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); if (Tcl_IsSafe(target)) { - pkgPtr->safeInterpRefCount--; + libraryPtr->safeInterpRefCount--; /* * Do not let counter get negative. */ - if (pkgPtr->safeInterpRefCount < 0) { - pkgPtr->safeInterpRefCount = 0; + if (libraryPtr->safeInterpRefCount < 0) { + libraryPtr->safeInterpRefCount = 0; } } else { - pkgPtr->interpRefCount--; + libraryPtr->interpRefCount--; /* * Do not let counter get negative. */ - if (pkgPtr->interpRefCount < 0) { - pkgPtr->interpRefCount = 0; + if (libraryPtr->interpRefCount < 0) { + libraryPtr->interpRefCount = 0; } } - trustedRefCount = pkgPtr->interpRefCount; - safeRefCount = pkgPtr->safeInterpRefCount; - Tcl_MutexUnlock(&packageMutex); + trustedRefCount = libraryPtr->interpRefCount; + safeRefCount = libraryPtr->safeInterpRefCount; + Tcl_MutexUnlock(&libraryMutex); code = TCL_OK; - if (pkgPtr->safeInterpRefCount <= 0 && pkgPtr->interpRefCount <= 0 + if (libraryPtr->safeInterpRefCount <= 0 && libraryPtr->interpRefCount <= 0 && !keepLibrary) { /* * Unload the shared library from the application memory... @@ -847,21 +845,21 @@ Tcl_UnloadObjCmd( * it's been unloaded. */ - if (pkgPtr->fileName[0] != '\0') { - Tcl_MutexLock(&packageMutex); - if (Tcl_FSUnloadFile(interp, pkgPtr->loadHandle) == TCL_OK) { + if (libraryPtr->fileName[0] != '\0') { + Tcl_MutexLock(&libraryMutex); + if (Tcl_FSUnloadFile(interp, libraryPtr->loadHandle) == TCL_OK) { /* * Remove this library from the loaded library cache. */ - defaultPtr = pkgPtr; - if (defaultPtr == firstPackagePtr) { - firstPackagePtr = pkgPtr->nextPtr; + defaultPtr = libraryPtr; + if (defaultPtr == firstLibraryPtr) { + firstLibraryPtr = libraryPtr->nextPtr; } else { - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; - pkgPtr = pkgPtr->nextPtr) { - if (pkgPtr->nextPtr == defaultPtr) { - pkgPtr->nextPtr = defaultPtr->nextPtr; + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; + libraryPtr = libraryPtr->nextPtr) { + if (libraryPtr->nextPtr == defaultPtr) { + libraryPtr->nextPtr = defaultPtr->nextPtr; break; } } @@ -873,14 +871,14 @@ Tcl_UnloadObjCmd( ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); ipPtr = ipFirstPtr; - if (ipPtr->pkgPtr == defaultPtr) { + if (ipPtr->libraryPtr == defaultPtr) { ipFirstPtr = ipFirstPtr->nextPtr; } else { InterpPackage *ipPrevPtr; for (ipPrevPtr = ipPtr; ipPtr != NULL; ipPrevPtr = ipPtr, ipPtr = ipPtr->nextPtr) { - if (ipPtr->pkgPtr == defaultPtr) { + if (ipPtr->libraryPtr == defaultPtr) { ipPrevPtr->nextPtr = ipPtr->nextPtr; break; } @@ -889,10 +887,10 @@ Tcl_UnloadObjCmd( Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipFirstPtr); Tcl_Free(defaultPtr->fileName); - Tcl_Free(defaultPtr->packageName); + Tcl_Free(defaultPtr->prefix); Tcl_Free(defaultPtr); Tcl_Free(ipPtr); - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); } else { code = TCL_ERROR; } @@ -920,7 +918,7 @@ Tcl_UnloadObjCmd( /* *---------------------------------------------------------------------- * - * Tcl_StaticPackage -- + * Tcl_StaticLibrary -- * * This function is invoked to indicate that a particular package has * been linked statically with an application. @@ -936,14 +934,12 @@ Tcl_UnloadObjCmd( */ void -Tcl_StaticPackage( +Tcl_StaticLibrary( Tcl_Interp *interp, /* If not NULL, it means that the package has * already been loaded into the given * interpreter by calling the appropriate init * proc. */ - const char *pkgName, /* Name of package (must be properly - * capitalized: first letter upper case, - * others lower case). */ + const char *prefix, /* Prefix. */ Tcl_PackageInitProc *initProc, /* Function to call to incorporate this * package into a trusted interpreter. */ @@ -954,7 +950,7 @@ Tcl_StaticPackage( * the package can't be used in safe * interpreters. */ { - LoadedPackage *pkgPtr; + LoadedLibrary *libraryPtr; InterpPackage *ipPtr, *ipFirstPtr; /* @@ -962,34 +958,34 @@ Tcl_StaticPackage( * statically loaded in the process. */ - Tcl_MutexLock(&packageMutex); - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { - if ((pkgPtr->initProc == initProc) - && (pkgPtr->safeInitProc == safeInitProc) - && (strcmp(pkgPtr->packageName, pkgName) == 0)) { + Tcl_MutexLock(&libraryMutex); + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; libraryPtr = libraryPtr->nextPtr) { + if ((libraryPtr->initProc == initProc) + && (libraryPtr->safeInitProc == safeInitProc) + && (strcmp(libraryPtr->prefix, prefix) == 0)) { break; } } - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); /* * If the package is not yet recorded as being loaded statically, add it * to the list now. */ - if (pkgPtr == NULL) { - pkgPtr = (LoadedPackage *)Tcl_Alloc(sizeof(LoadedPackage)); - pkgPtr->fileName = (char *)Tcl_Alloc(1); - pkgPtr->fileName[0] = 0; - pkgPtr->packageName = (char *)Tcl_Alloc(strlen(pkgName) + 1); - strcpy(pkgPtr->packageName, pkgName); - pkgPtr->loadHandle = NULL; - pkgPtr->initProc = initProc; - pkgPtr->safeInitProc = safeInitProc; - Tcl_MutexLock(&packageMutex); - pkgPtr->nextPtr = firstPackagePtr; - firstPackagePtr = pkgPtr; - Tcl_MutexUnlock(&packageMutex); + if (libraryPtr == NULL) { + libraryPtr = (LoadedLibrary *)Tcl_Alloc(sizeof(LoadedLibrary)); + libraryPtr->fileName = (char *)Tcl_Alloc(1); + libraryPtr->fileName[0] = 0; + libraryPtr->prefix = (char *)Tcl_Alloc(strlen(prefix) + 1); + strcpy(libraryPtr->prefix, prefix); + libraryPtr->loadHandle = NULL; + libraryPtr->initProc = initProc; + libraryPtr->safeInitProc = safeInitProc; + Tcl_MutexLock(&libraryMutex); + libraryPtr->nextPtr = firstLibraryPtr; + firstLibraryPtr = libraryPtr; + Tcl_MutexUnlock(&libraryMutex); } if (interp != NULL) { @@ -1001,7 +997,7 @@ Tcl_StaticPackage( ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(interp, "tclLoad", NULL); for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - if (ipPtr->pkgPtr == pkgPtr) { + if (ipPtr->libraryPtr == libraryPtr) { return; } } @@ -1012,7 +1008,7 @@ Tcl_StaticPackage( */ ipPtr = (InterpPackage *)Tcl_Alloc(sizeof(InterpPackage)); - ipPtr->pkgPtr = pkgPtr; + ipPtr->libraryPtr = libraryPtr; ipPtr->nextPtr = ipFirstPtr; Tcl_SetAssocData(interp, "tclLoad", LoadCleanupProc, ipPtr); } @@ -1021,7 +1017,7 @@ Tcl_StaticPackage( /* *---------------------------------------------------------------------- * - * TclGetLoadedPackagesEx -- + * TclGetLoadedLibraries -- * * This function returns information about all of the files that are * loaded (either in a particular interpreter, or for all interpreters). @@ -1040,33 +1036,33 @@ Tcl_StaticPackage( */ int -TclGetLoadedPackagesEx( +TclGetLoadedLibraries( Tcl_Interp *interp, /* Interpreter in which to return information * or error message. */ const char *targetName, /* Name of target interpreter or NULL. If * NULL, return info about all interps; * otherwise, just return info about this * interpreter. */ - const char *packageName) /* Package name or NULL. If NULL, return info + const char *prefix) /* Package name or NULL. If NULL, return info * for all packages. */ { Tcl_Interp *target; - LoadedPackage *pkgPtr; + LoadedLibrary *libraryPtr; InterpPackage *ipPtr; Tcl_Obj *resultObj, *pkgDesc[2]; if (targetName == NULL) { TclNewObj(resultObj); - Tcl_MutexLock(&packageMutex); - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; - pkgPtr = pkgPtr->nextPtr) { - pkgDesc[0] = Tcl_NewStringObj(pkgPtr->fileName, -1); - pkgDesc[1] = Tcl_NewStringObj(pkgPtr->packageName, -1); + Tcl_MutexLock(&libraryMutex); + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; + libraryPtr = libraryPtr->nextPtr) { + pkgDesc[0] = Tcl_NewStringObj(libraryPtr->fileName, -1); + pkgDesc[1] = Tcl_NewStringObj(libraryPtr->prefix, -1); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewListObj(2, pkgDesc)); } - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); Tcl_SetObjResult(interp, resultObj); return TCL_OK; } @@ -1080,14 +1076,14 @@ TclGetLoadedPackagesEx( /* * Return information about all of the available packages. */ - if (packageName) { + if (prefix) { resultObj = NULL; for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - pkgPtr = ipPtr->pkgPtr; + libraryPtr = ipPtr->libraryPtr; - if (!strcmp(packageName, pkgPtr->packageName)) { - resultObj = Tcl_NewStringObj(pkgPtr->fileName, -1); + if (!strcmp(prefix, libraryPtr->prefix)) { + resultObj = Tcl_NewStringObj(libraryPtr->fileName, -1); break; } } @@ -1105,9 +1101,9 @@ TclGetLoadedPackagesEx( TclNewObj(resultObj); for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - pkgPtr = ipPtr->pkgPtr; - pkgDesc[0] = Tcl_NewStringObj(pkgPtr->fileName, -1); - pkgDesc[1] = Tcl_NewStringObj(pkgPtr->packageName, -1); + libraryPtr = ipPtr->libraryPtr; + pkgDesc[0] = Tcl_NewStringObj(libraryPtr->fileName, -1); + pkgDesc[1] = Tcl_NewStringObj(libraryPtr->prefix, -1); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewListObj(2, pkgDesc)); } Tcl_SetObjResult(interp, resultObj); @@ -1154,7 +1150,7 @@ LoadCleanupProc( * TclFinalizeLoad -- * * This function is invoked just before the application exits. It frees - * all of the LoadedPackage structures. + * all of the LoadedLibrary structures. * * Results: * None. @@ -1168,18 +1164,18 @@ LoadCleanupProc( void TclFinalizeLoad(void) { - LoadedPackage *pkgPtr; + LoadedLibrary *libraryPtr; /* * No synchronization here because there should just be one thread alive - * at this point. Logically, packageMutex should be grabbed at this point, + * at this point. Logically, libraryMutex should be grabbed at this point, * but the Mutexes get finalized before the call to this routine. The only * subsystem left alive at this point is the memory allocator. */ - while (firstPackagePtr != NULL) { - pkgPtr = firstPackagePtr; - firstPackagePtr = pkgPtr->nextPtr; + while (firstLibraryPtr != NULL) { + libraryPtr = firstLibraryPtr; + firstLibraryPtr = libraryPtr->nextPtr; #if defined(TCL_UNLOAD_DLLS) || defined(_WIN32) /* @@ -1189,14 +1185,14 @@ TclFinalizeLoad(void) * it has been unloaded. */ - if (pkgPtr->fileName[0] != '\0') { - Tcl_FSUnloadFile(NULL, pkgPtr->loadHandle); + if (libraryPtr->fileName[0] != '\0') { + Tcl_FSUnloadFile(NULL, libraryPtr->loadHandle); } #endif - Tcl_Free(pkgPtr->fileName); - Tcl_Free(pkgPtr->packageName); - Tcl_Free(pkgPtr); + Tcl_Free(libraryPtr->fileName); + Tcl_Free(libraryPtr->prefix); + Tcl_Free(libraryPtr); } } diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 93529d1..12e0272 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -60,9 +60,9 @@ #undef TclWinGetSockOpt #undef TclWinSetSockOpt #undef TclWinNToHS -#undef TclStaticPackage +#undef TclStaticLibrary #undef Tcl_BackgroundError -#define TclStaticPackage Tcl_StaticPackage +#define TclStaticLibrary Tcl_StaticLibrary #undef Tcl_UniCharToUtfDString #undef Tcl_UtfToUniCharDString #undef Tcl_UtfToUniChar @@ -528,7 +528,7 @@ static const TclIntStubs tclIntStubs = { TclPtrIncrObjVar, /* 254 */ TclPtrObjMakeUpvar, /* 255 */ TclPtrUnsetVar, /* 256 */ - TclStaticPackage, /* 257 */ + TclStaticLibrary, /* 257 */ TclpCreateTemporaryDirectory, /* 258 */ TclAppendUnicodeToObj, /* 259 */ TclGetBytesFromObj, /* 260 */ diff --git a/generic/tclTest.c b/generic/tclTest.c index 91e3b49..502d9c9 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -274,7 +274,7 @@ static Tcl_CmdProc Testset2Cmd; static Tcl_CmdProc TestseterrorcodeCmd; static Tcl_ObjCmdProc TestsetobjerrorcodeCmd; static Tcl_CmdProc TestsetplatformCmd; -static Tcl_CmdProc TeststaticpkgCmd; +static Tcl_CmdProc TeststaticlibraryCmd; static Tcl_CmdProc TesttranslatefilenameCmd; static Tcl_CmdProc TestupvarCmd; static Tcl_ObjCmdProc TestWrongNumArgsObjCmd; @@ -601,7 +601,7 @@ Tcltest_Init( NULL, NULL); Tcl_CreateCommand(interp, "testsocket", TestSocketCmd, NULL, NULL); - Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd, + Tcl_CreateCommand(interp, "teststaticlibrary", TeststaticlibraryCmd, NULL, NULL); Tcl_CreateCommand(interp, "testtranslatefilename", TesttranslatefilenameCmd, NULL, NULL); @@ -4217,10 +4217,10 @@ TestsetplatformCmd( /* *---------------------------------------------------------------------- * - * TeststaticpkgCmd -- + * TeststaticlibraryCmd -- * - * This procedure implements the "teststaticpkg" command. - * It is used to test the procedure Tcl_StaticPackage. + * This procedure implements the "teststaticlibrary" command. + * It is used to test the procedure Tcl_StaticLibrary. * * Results: * A standard Tcl result. @@ -4233,7 +4233,7 @@ TestsetplatformCmd( */ static int -TeststaticpkgCmd( +TeststaticlibraryCmd( TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ @@ -4243,7 +4243,7 @@ TeststaticpkgCmd( if (argc != 4) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", - argv[0], " pkgName safe loaded\"", NULL); + argv[0], " prefix safe loaded\"", NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &safe) != TCL_OK) { @@ -4252,7 +4252,7 @@ TeststaticpkgCmd( if (Tcl_GetInt(interp, argv[3], &loaded) != TCL_OK) { return TCL_ERROR; } - Tcl_StaticPackage((loaded) ? interp : NULL, argv[1], + Tcl_StaticLibrary((loaded) ? interp : NULL, argv[1], StaticInitProc, (safe) ? StaticInitProc : NULL); return TCL_OK; } diff --git a/macosx/Tcl.xcode/project.pbxproj b/macosx/Tcl.xcode/project.pbxproj index 8004ffe..6a3b921 100644 --- a/macosx/Tcl.xcode/project.pbxproj +++ b/macosx/Tcl.xcode/project.pbxproj @@ -394,7 +394,7 @@ F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = ""; }; F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = ""; }; F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = ""; }; - F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = ""; }; + F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticLibrary.3; sourceTree = ""; }; F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = ""; }; F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = ""; }; F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = ""; }; @@ -1149,7 +1149,7 @@ F96D3EA208F272A7004A47F5 /* split.n */, F96D3EA308F272A7004A47F5 /* SplitList.3 */, F96D3EA408F272A7004A47F5 /* SplitPath.3 */, - F96D3EA508F272A7004A47F5 /* StaticPkg.3 */, + F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */, F96D3EA608F272A7004A47F5 /* StdChannels.3 */, F96D3EA708F272A7004A47F5 /* string.n */, F96D3EA808F272A7004A47F5 /* StringObj.3 */, diff --git a/macosx/Tcl.xcodeproj/project.pbxproj b/macosx/Tcl.xcodeproj/project.pbxproj index 6528616..47f522c 100644 --- a/macosx/Tcl.xcodeproj/project.pbxproj +++ b/macosx/Tcl.xcodeproj/project.pbxproj @@ -393,7 +393,7 @@ F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = ""; }; F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = ""; }; F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = ""; }; - F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = ""; }; + F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticLibrary.3; sourceTree = ""; }; F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = ""; }; F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = ""; }; F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = ""; }; @@ -1149,7 +1149,7 @@ F96D3EA208F272A7004A47F5 /* split.n */, F96D3EA308F272A7004A47F5 /* SplitList.3 */, F96D3EA408F272A7004A47F5 /* SplitPath.3 */, - F96D3EA508F272A7004A47F5 /* StaticPkg.3 */, + F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */, F96D3EA608F272A7004A47F5 /* StdChannels.3 */, F96D3EA708F272A7004A47F5 /* string.n */, F96D3EA808F272A7004A47F5 /* StringObj.3 */, diff --git a/tests/load.test b/tests/load.test index c79ddf4..eaaf7a7 100644 --- a/tests/load.test +++ b/tests/load.test @@ -36,9 +36,9 @@ testConstraint $loaded [expr {![string match *pkga* $alreadyLoaded]}] set alreadyTotalLoaded [info loaded] -# Certain tests require the 'teststaticpkg' command from tcltest +# Certain tests require the 'teststaticlibrary' command from tcltest -testConstraint teststaticpkg [llength [info commands teststaticpkg]] +testConstraint teststaticlibrary [llength [info commands teststaticlibrary]] # Test load-10.1 requires the 'testsimplefilesystem' command from tcltest @@ -47,10 +47,10 @@ testConstraint testsimplefilesystem \ test load-1.1 {basic errors} -returnCodes error -body { load -} -result {wrong # args: should be "load ?-global? ?-lazy? ?--? fileName ?packageName? ?interp?"} +} -result {wrong # args: should be "load ?-global? ?-lazy? ?--? fileName ?prefix? ?interp?"} test load-1.2 {basic errors} -returnCodes error -body { load a b c d -} -result {wrong # args: should be "load ?-global? ?-lazy? ?--? fileName ?packageName? ?interp?"} +} -result {wrong # args: should be "load ?-global? ?-lazy? ?--? fileName ?prefix? ?interp?"} test load-1.3 {basic errors} -returnCodes error -body { load a b foobar } -result {could not find interpreter "foobar"} @@ -62,7 +62,7 @@ test load-1.5 {basic errors} -returnCodes error -body { } -result {must specify either file name or package name} test load-1.6 {basic errors} -returnCodes error -body { load {} Unknown -} -result {package "Unknown" isn't loaded statically} +} -result {no library with prefix "Unknown" is loaded statically} test load-1.7 {basic errors} -returnCodes error -body { load -abc foo } -result {bad option "-abc": must be -global, -lazy, or --} @@ -78,13 +78,13 @@ test load-2.1 {basic loading, with guess for package name} \ interp create -safe child test load-2.2 {loading into a safe interpreter, with package name conversion} \ [list $dll $loaded] { - load -lazy [file join $testDir pkgb$ext] pKgB child + load -lazy [file join $testDir pkgb$ext] Pkgb child list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \ [catch {pkgb_sub 12 10} msg2] $msg2 } {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}} test load-2.3 {loading with no _Init procedure} -constraints [list $dll $loaded] \ -body { - list [catch {load [file join $testDir pkgc$ext] foo} msg] $msg $errorCode + list [catch {load [file join $testDir pkgc$ext] Foo} msg] $msg $errorCode } -match glob \ -result [list 1 {cannot find symbol "Foo_Init"*} \ {TCL LOOKUP LOAD_SYMBOL *Foo_Init}] @@ -94,7 +94,7 @@ test load-2.4 {loading with no _SafeInit procedure} [list $dll $loaded] { test load-3.1 {error in _Init procedure, same interpreter} \ [list $dll $loaded] { - list [catch {load [file join $testDir pkge$ext] pkge} msg] \ + list [catch {load [file join $testDir pkge$ext] Pkge} msg] \ $msg $::errorInfo $::errorCode } {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory while executing @@ -102,14 +102,14 @@ test load-3.1 {error in _Init procedure, same interpreter} \ invoked from within "if 44 {open non_existent}" invoked from within -"load [file join $testDir pkge$ext] pkge"} {POSIX ENOENT {no such file or directory}}} +"load [file join $testDir pkge$ext] Pkge"} {POSIX ENOENT {no such file or directory}}} test load-3.2 {error in _Init procedure, child interpreter} \ [list $dll $loaded] { catch {interp delete x} interp create x set ::errorCode foo set ::errorInfo bar - set result [list [catch {load [file join $testDir pkge$ext] pkge x} msg] \ + set result [list [catch {load [file join $testDir pkge$ext] Pkge x} msg] \ $msg $::errorInfo $::errorCode] interp delete x set result @@ -119,23 +119,23 @@ test load-3.2 {error in _Init procedure, child interpreter} \ invoked from within "if 44 {open non_existent}" invoked from within -"load [file join $testDir pkge$ext] pkge x"} {POSIX ENOENT {no such file or directory}}} +"load [file join $testDir pkge$ext] Pkge x"} {POSIX ENOENT {no such file or directory}}} test load-4.1 {reloading package into same interpreter} [list $dll $loaded] { - list [catch {load [file join $testDir pkga$ext] pkga} msg] $msg + list [catch {load [file join $testDir pkga$ext] Pkga} msg] $msg } {0 {}} test load-4.2 {reloading package into same interpreter} -setup { catch {load [file join $testDir pkga$ext] pkga} } -constraints [list $dll $loaded] -returnCodes error -body { - load [file join $testDir pkga$ext] pkgb + load [file join $testDir pkga$ext] Pkgb } -result "file \"[file join $testDir pkga$ext]\" is already loaded for package \"Pkga\"" test load-5.1 {file name not specified and no static package: pick default} -setup { catch {interp delete x} interp create x } -constraints [list $dll $loaded] -body { - load -global [file join $testDir pkga$ext] pkga - load {} pkga x + load -global [file join $testDir pkga$ext] Pkga + load {} Pkga x info loaded x } -cleanup { interp delete x @@ -150,78 +150,78 @@ test load-6.1 {errors loading file} [list $dll $loaded] { catch {load foo foo} } {1} -test load-7.1 {Tcl_StaticPackage procedure} [list teststaticpkg] { +test load-7.1 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { set x "not loaded" - teststaticpkg Test 1 0 + teststaticlibrary Test 1 0 load {} Test load {} Test child list [set x] [child eval set x] } {loaded loaded} -test load-7.2 {Tcl_StaticPackage procedure} [list teststaticpkg] { +test load-7.2 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { set x "not loaded" - teststaticpkg Another 0 0 + teststaticlibrary Another 0 0 load {} Another child eval {set x "not loaded"} list [catch {load {} Another child} msg] $msg \ [child eval set x] [set x] } {1 {can't use package in a safe interpreter: no Another_SafeInit procedure} {not loaded} loaded} -test load-7.3 {Tcl_StaticPackage procedure} [list teststaticpkg] { +test load-7.3 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { set x "not loaded" - teststaticpkg More 0 1 + teststaticlibrary More 0 1 load {} More set x } {not loaded} -catch {load [file join $testDir pkga$ext] pkga} -catch {load [file join $testDir pkgb$ext] pkgb} -catch {load [file join $testDir pkge$ext] pkge} +catch {load [file join $testDir pkga$ext] Pkga} +catch {load [file join $testDir pkgb$ext] Pkgb} +catch {load [file join $testDir pkge$ext] Pkge} set currentRealPackages [list [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] -test load-7.4 {Tcl_StaticPackage procedure, redundant calls} -setup { - teststaticpkg Test 1 0 - teststaticpkg Another 0 0 - teststaticpkg More 0 1 -} -constraints [list teststaticpkg $dll $loaded] -body { - teststaticpkg Double 0 1 - teststaticpkg Double 0 1 +test load-7.4 {Tcl_StaticLibrary procedure, redundant calls} -setup { + teststaticlibrary Test 1 0 + teststaticlibrary Another 0 0 + teststaticlibrary More 0 1 +} -constraints [list teststaticlibrary $dll $loaded] -body { + teststaticlibrary Double 0 1 + teststaticlibrary Double 0 1 info loaded } -result [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded] -testConstraint teststaticpkg_8.x 0 -if {[testConstraint teststaticpkg]} { +testConstraint teststaticlibrary_8.x 0 +if {[testConstraint teststaticlibrary]} { catch { - teststaticpkg Test 1 1 - teststaticpkg Another 0 1 - teststaticpkg More 0 1 - teststaticpkg Double 0 1 - testConstraint teststaticpkg_8.x 1 + teststaticlibrary Test 1 1 + teststaticlibrary Another 0 1 + teststaticlibrary More 0 1 + teststaticlibrary Double 0 1 + testConstraint teststaticlibrary_8.x 1 } } -test load-8.1 {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { +test load-8.1 {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded] } [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded]] -test load-8.2 {TclGetLoadedPackages procedure} -constraints {teststaticpkg_8.x} -body { +test load-8.2 {TclGetLoadedPackages procedure} -constraints {teststaticlibrary_8.x} -body { info loaded gorp } -returnCodes error -result {could not find interpreter "gorp"} -test load-8.3a {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { +test load-8.3a {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded {}] } [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga] [list [file join $testDir pkgb$ext] Pkgb] {*}$alreadyLoaded]] -test load-8.3b {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { +test load-8.3b {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded child] } [lsort -index 1 [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]] -test load-8.4 {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { - load [file join $testDir pkgb$ext] pkgb +test load-8.4 {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { + load [file join $testDir pkgb$ext] Pkgb list [lsort -index 1 [info loaded {}]] [lsort [info commands pkgb_*]] } [list [lsort -index 1 [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded]] {pkgb_demo pkgb_sub pkgb_unsafe}] interp delete child -test load-9.1 {Tcl_StaticPackage, load already-loaded package into another interp} -setup { +test load-9.1 {Tcl_StaticLibrary, load already-loaded package into another interp} -setup { interp create child1 interp create child2 load {} Tcltest child1 load {} Tcltest child2 -} -constraints {teststaticpkg} -body { - child1 eval { teststaticpkg Loadninepointone 0 1 } - child2 eval { teststaticpkg Loadninepointone 0 1 } +} -constraints {teststaticlibrary} -body { + child1 eval { teststaticlibrary Loadninepointone 0 1 } + child2 eval { teststaticlibrary Loadninepointone 0 1 } list [child1 eval { info loaded {} }] \ [child2 eval { info loaded {} }] } -match glob -cleanup { @@ -234,7 +234,7 @@ test load-10.1 {load from vfs} -setup { cd $testDir testsimplefilesystem 1 } -constraints [list $dll $loaded testsimplefilesystem] -body { - list [catch {load simplefs:/pkgd$ext pkgd} msg] $msg + list [catch {load simplefs:/pkgd$ext Pkgd} msg] $msg } -result {0 {}} -cleanup { testsimplefilesystem 0 cd $dir diff --git a/tests/safe.test b/tests/safe.test index 1177e19..0394eb9 100644 --- a/tests/safe.test +++ b/tests/safe.test @@ -1157,7 +1157,7 @@ test safe-9.24 {interpConfigure change the access path; check module loading; st res0 res1 res2} # See comments on lsort after test safe-9.20. -catch {teststaticpkg Safepkg1 0 0} +catch {teststaticlibrary Safepkg1 0 0} test safe-10.1 {testing statics loading} -constraints TcltestPackage -setup { set i [safe::interpCreate] } -body { diff --git a/tests/unload.test b/tests/unload.test index 32767fa..f1f4580 100644 --- a/tests/unload.test +++ b/tests/unload.test @@ -53,10 +53,10 @@ proc loadIfNotPresent {pkg args} { # Basic tests: parameter testing... test unload-1.1 {basic errors} -returnCodes error -body { unload -} -result {wrong # args: should be "unload ?-switch ...? fileName ?packageName? ?interp?"} +} -result {wrong # args: should be "unload ?-switch ...? fileName ?prefix? ?interp?"} test unload-1.2 {basic errors} -returnCodes error -body { unload a b c d -} -result {wrong # args: should be "unload ?-switch ...? fileName ?packageName? ?interp?"} +} -result {wrong # args: should be "unload ?-switch ...? fileName ?prefix? ?interp?"} test unload-1.3 {basic errors} -returnCodes error -body { unload a b foobar } -result {could not find interpreter "foobar"} @@ -68,7 +68,7 @@ test unload-1.5 {basic errors} -returnCodes error -body { } -result {must specify either file name or package name} test unload-1.6 {basic errors} -returnCodes error -body { unload {} Unknown -} -result {package "Unknown" is loaded statically and cannot be unloaded} +} -result {library with prefix "Unknown" is loaded statically and cannot be unloaded} test unload-1.7 {-nocomplain switch} { unload -nocomplain {} Unknown } {} @@ -135,14 +135,14 @@ child eval { test unload-3.1 {basic loading of non-unloadable package in a safe interpreter, with package name conversion} \ [list $dll $loaded] { catch {rename pkgb_sub {}} - load [file join $testDir pkgb$ext] pKgB child + load [file join $testDir pkgb$ext] Pkgb child list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \ [catch {pkgb_sub 12 10} msg2] $msg2 } {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}} test unload-3.2 {basic loading of unloadable package in a safe interpreter, with package name conversion} \ [list $dll $loaded] { list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \ - [load [file join $testDir pkgua$ext] pKgUA child] \ + [load [file join $testDir pkgua$ext] Pkgua child] \ [child eval pkgua_eq abc def] \ [lsort [child eval info commands pkgua_*]] \ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] @@ -154,14 +154,14 @@ test unload-3.3 {unloading of a package that has never been loaded from a safe i } -result {file "*" has never been loaded in this interpreter} test unload-3.4 {basic unloading of a non-unloadable package from a safe interpreter, with guess for package name} -setup { if {[lsearch -index 1 [info loaded child] Pkgb] < 0} { - load [file join $testDir pkgb$ext] pKgB child + load [file join $testDir pkgb$ext] Pkgb child } } -constraints [list $dll $loaded] -returnCodes error -match glob -body { unload [file join $testDir pkgb$ext] {} child } -result {file "*" cannot be unloaded under a safe interpreter} test unload-3.5 {basic unloading of an unloadable package from a safe interpreter, with guess for package name} -setup { if {[lsearch -index 1 [info loaded child] Pkgua] < 0} { - load [file join $testDir pkgua$ext] pkgua child + load [file join $testDir pkgua$ext] Pkgua child } } -constraints [list $dll $loaded] -body { list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \ @@ -189,7 +189,7 @@ test unload-3.7 {basic unloading of re-loaded package from a safe interpreter, w } } -constraints [list $dll $loaded] -body { list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \ - [unload [file join $testDir pkgua$ext] pKgUa child] \ + [unload [file join $testDir pkgua$ext] Pkgua child] \ [child eval info commands pkgua_*] \ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] } -result {{.. . .} {} {} {.. .. ..}} @@ -224,7 +224,7 @@ test unload-4.2 {basic loading of unloadable package in a safe interpreter, with incr load(C) } -constraints [list $dll $loaded] -body { list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \ - [load [file join $testDir pkgua$ext] pKgUA child] \ + [load [file join $testDir pkgua$ext] Pkgua child] \ [child eval pkgua_eq abc def] \ [lsort [child eval info commands pkgua_*]] \ [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] @@ -234,7 +234,7 @@ test unload-4.3 {basic loading of unloadable package in a second trusted interpr incr load(T) } -constraints [list $dll $loaded] -body { list [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \ - [load [file join $testDir pkgua$ext] pkguA child-trusted] \ + [load [file join $testDir pkgua$ext] Pkgua child-trusted] \ [child-trusted eval pkgua_eq abc def] \ [lsort [child-trusted eval info commands pkgua_*]] \ [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] @@ -291,7 +291,7 @@ test unload-5.1 {unload a module loaded from vfs} \ set dir [pwd] cd $testDir testsimplefilesystem 1 - load simplefs:/pkgua$ext pkgua + load simplefs:/pkgua$ext Pkgua } \ -body { list [catch {unload simplefs:/pkgua$ext} msg] $msg diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 3587f35..0b03d5d 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -124,7 +124,7 @@ Tcl_AppInit( if (Tcltest_Init(interp) == TCL_ERROR) { return TCL_ERROR; } - Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); + Tcl_StaticLibrary(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); #endif /* TCL_TEST */ /* diff --git a/win/tcl.dsp b/win/tcl.dsp index 8b20d66..02dcf32 100644 --- a/win/tcl.dsp +++ b/win/tcl.dsp @@ -824,7 +824,7 @@ SOURCE=..\doc\SplitPath.3 # End Source File # Begin Source File -SOURCE=..\doc\StaticPkg.3 +SOURCE=..\doc\StaticLibrary.3 # End Source File # Begin Source File diff --git a/win/tclAppInit.c b/win/tclAppInit.c index a9fb3bd..5c479f9 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -168,19 +168,19 @@ Tcl_AppInit( if (Registry_Init(interp) == TCL_ERROR) { return TCL_ERROR; } - Tcl_StaticPackage(interp, "Registry", Registry_Init, NULL); + Tcl_StaticLibrary(interp, "Registry", Registry_Init, NULL); if (Dde_Init(interp) == TCL_ERROR) { return TCL_ERROR; } - Tcl_StaticPackage(interp, "Dde", Dde_Init, Dde_SafeInit); + Tcl_StaticLibrary(interp, "Dde", Dde_Init, Dde_SafeInit); #endif #ifdef TCL_TEST if (Tcltest_Init(interp) == TCL_ERROR) { return TCL_ERROR; } - Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); + Tcl_StaticLibrary(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); #endif /* TCL_TEST */ /* -- cgit v0.12 From bf23a021385451ff52770191acec3f55d5c8575a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 10 Nov 2020 15:38:52 +0000 Subject: more cleanup/error-messages --- generic/tclLoad.c | 186 +++++++++++++++++++++++++++--------------------------- tests/load.test | 12 ++-- tests/safe.test | 8 +-- tests/unload.test | 4 +- 4 files changed, 104 insertions(+), 106 deletions(-) diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 67bc2cc..fe86622 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -13,17 +13,15 @@ #include "tclInt.h" /* - * The following structure describes a package that has been loaded either + * The following structure describes a library that has been loaded either * dynamically (with the "load" command) or statically (as indicated by a call - * to TclGetLoadedLibraries). All such packages are linked together into a - * single list for the process. Packages are never unloaded, until the - * application exits, when TclFinalizeLoad is called, and these structures are - * freed. + * to Tcl_StaticLibrary). All such libraries are linked together into a + * single list for the process. */ typedef struct LoadedLibrary { - char *fileName; /* Name of the file from which the package was - * loaded. An empty string means the package + char *fileName; /* Name of the file from which the library was + * loaded. An empty string means the library * is loaded statically. Malloc-ed. */ char *prefix; /* Prefix for the library. * Malloc-ed. */ @@ -33,59 +31,59 @@ typedef struct LoadedLibrary { * then this field is irrelevant. */ Tcl_PackageInitProc *initProc; /* Initialization function to call to - * incorporate this package into a trusted + * incorporate this library into a trusted * interpreter. */ Tcl_PackageInitProc *safeInitProc; /* Initialization function to call to - * incorporate this package into a safe + * incorporate this library into a safe * interpreter (one that will execute - * untrusted scripts). NULL means the package + * untrusted scripts). NULL means the library * can't be used in unsafe interpreters. */ Tcl_PackageUnloadProc *unloadProc; - /* Finalisation function to unload a package + /* Finalization function to unload a library * from a trusted interpreter. NULL means that - * the package cannot be unloaded. */ + * the library cannot be unloaded. */ Tcl_PackageUnloadProc *safeUnloadProc; - /* Finalisation function to unload a package + /* Finalization function to unload a library * from a safe interpreter. NULL means that - * the package cannot be unloaded. */ - int interpRefCount; /* How many times the package has been loaded + * the library cannot be unloaded. */ + int interpRefCount; /* How many times the library has been loaded * in trusted interpreters. */ - int safeInterpRefCount; /* How many times the package has been loaded + int safeInterpRefCount; /* How many times the library has been loaded * in safe interpreters. */ struct LoadedLibrary *nextPtr; - /* Next in list of all packages loaded into + /* Next in list of all libraries loaded into * this application process. NULL means end of * list. */ } LoadedLibrary; /* * TCL_THREADS - * There is a global list of packages that is anchored at firstLibraryPtr. + * There is a global list of libraries that is anchored at firstLibraryPtr. * Access to this list is governed by a mutex. */ static LoadedLibrary *firstLibraryPtr = NULL; - /* First in list of all packages loaded into + /* First in list of all libraries loaded into * this process. */ TCL_DECLARE_MUTEX(libraryMutex) /* - * The following structure represents a particular package that has been + * The following structure represents a particular library that has been * incorporated into a particular interpreter (by calling its initialization * function). There is a list of these structures for each interpreter, with * an AssocData value (key "load") for the interpreter that points to the - * first package (if any). + * first library (if any). */ -typedef struct InterpPackage { +typedef struct InterpLibrary { LoadedLibrary *libraryPtr; /* Points to detailed information about - * package. */ - struct InterpPackage *nextPtr; - /* Next package in this interpreter, or NULL + * library. */ + struct InterpLibrary *nextPtr; + /* Next lirary in this interpreter, or NULL * for end of list. */ -} InterpPackage; +} InterpLibrary; /* * Prototypes for functions that are private to this file: @@ -122,7 +120,7 @@ Tcl_LoadObjCmd( LoadedLibrary *libraryPtr, *defaultPtr; Tcl_DString pkgName, tmp, initName, safeInitName; Tcl_DString unloadName, safeUnloadName; - InterpPackage *ipFirstPtr, *ipPtr; + InterpLibrary *ipFirstPtr, *ipPtr; int code, namesMatch, filesMatch, offset; const char *symbols[2]; Tcl_PackageInitProc *initProc; @@ -181,7 +179,7 @@ Tcl_LoadObjCmd( } if ((fullFileName[0] == 0) && (prefix == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( - "must specify either file name or package name", -1)); + "must specify either file name or prefix", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOLIBRARY", NULL); code = TCL_ERROR; @@ -189,7 +187,7 @@ Tcl_LoadObjCmd( } /* - * Figure out which interpreter we're going to load the package into. + * Figure out which interpreter we're going to load the library into. */ target = interp; @@ -204,13 +202,13 @@ Tcl_LoadObjCmd( } /* - * Scan through the packages that are currently loaded to see if the - * package we want is already loaded. We'll use a loaded package if it + * Scan through the libraries that are currently loaded to see if the + * library we want is already loaded. We'll use a loaded library if it * meets any of the following conditions: * - Its name and file match the once we're looking for. * - Its file matches, and we weren't given a name. * - Its name matches, the file name was specified as empty, and there is - * only no statically loaded package with the same name. + * only no statically loaded library with the same prefix. */ Tcl_MutexLock(&libraryMutex); @@ -242,11 +240,11 @@ Tcl_LoadObjCmd( } if (filesMatch && !namesMatch && (fullFileName[0] != 0)) { /* - * Can't have two different packages loaded from the same file. + * Can't have two different libraries loaded from the same file. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "file \"%s\" is already loaded for package \"%s\"", + "file \"%s\" is already loaded for prefix \"%s\"", fullFileName, libraryPtr->prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "SPLITPERSONALITY", NULL); @@ -261,13 +259,13 @@ Tcl_LoadObjCmd( } /* - * Scan through the list of packages already loaded in the target - * interpreter. If the package we want is already loaded there, then + * Scan through the list of libraries already loaded in the target + * interpreter. If the library we want is already loaded there, then * there's nothing for us to do. */ if (libraryPtr != NULL) { - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { if (ipPtr->libraryPtr == libraryPtr) { code = TCL_OK; @@ -279,7 +277,7 @@ Tcl_LoadObjCmd( if (libraryPtr == NULL) { /* * The desired file isn't currently loaded, so load it. It's an error - * if the desired package is a static one. + * if the desired library is a static one. */ if (fullFileName[0] == 0) { @@ -344,10 +342,10 @@ Tcl_LoadObjCmd( if (p == pkgGuess) { Tcl_DecrRefCount(splitPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "couldn't figure out package name for %s", + "couldn't figure out prefix for %s", fullFileName)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", - "WHATPACKAGE", NULL); + "WHATLIBRARY", NULL); code = TCL_ERROR; goto done; } @@ -355,7 +353,7 @@ Tcl_LoadObjCmd( Tcl_DecrRefCount(splitPtr); /* - * Fix the capitalization in the package name so that the first + * Fix the capitalization in the prefix so that the first * character is in caps (or title case) but the others are all * lower-case. */ @@ -367,7 +365,7 @@ Tcl_LoadObjCmd( /* * Compute the names of the two initialization functions, based on the - * package name. + * prefix. */ TclDStringAppendDString(&initName, &pkgName); @@ -380,7 +378,7 @@ Tcl_LoadObjCmd( TclDStringAppendLiteral(&safeUnloadName, "_SafeUnload"); /* - * Call platform-specific code to load the package and find the two + * Call platform-specific code to load the library and find the two * initialization functions. */ @@ -396,7 +394,7 @@ Tcl_LoadObjCmd( } /* - * Create a new record to describe this package. + * Create a new record to describe this library. */ libraryPtr = (LoadedLibrary *)Tcl_Alloc(sizeof(LoadedLibrary)); @@ -434,14 +432,14 @@ Tcl_LoadObjCmd( } /* - * Invoke the package's initialization function (either the normal one or + * Invoke the library's initialization function (either the normal one or * the safe one, depending on whether or not the interpreter is safe). */ if (Tcl_IsSafe(target)) { if (libraryPtr->safeInitProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't use package in a safe interpreter: no" + "can't use library in a safe interpreter: no" " %s_SafeInit procedure", libraryPtr->prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "UNSAFE", NULL); @@ -452,7 +450,7 @@ Tcl_LoadObjCmd( } else { if (libraryPtr->initProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't attach package to interpreter: no %s_Init procedure", + "can't attach library to interpreter: no %s_Init procedure", libraryPtr->prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "ENTRYPOINT", NULL); @@ -484,7 +482,7 @@ Tcl_LoadObjCmd( } /* - * Record the fact that the package has been loaded in the target + * Record the fact that the library has been loaded in the target * interpreter. * * Update the proper reference count. @@ -499,12 +497,12 @@ Tcl_LoadObjCmd( Tcl_MutexUnlock(&libraryMutex); /* - * Refetch ipFirstPtr: loading the package may have introduced additional - * static packages at the head of the linked list! + * Refetch ipFirstPtr: loading the library may have introduced additional + * static libraries at the head of the linked list! */ - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); - ipPtr = (InterpPackage *)Tcl_Alloc(sizeof(InterpPackage)); + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); + ipPtr = (InterpLibrary *)Tcl_Alloc(sizeof(InterpLibrary)); ipPtr->libraryPtr = libraryPtr; ipPtr->nextPtr = ipFirstPtr; Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipPtr); @@ -547,7 +545,7 @@ Tcl_UnloadObjCmd( LoadedLibrary *libraryPtr, *defaultPtr; Tcl_DString pkgName, tmp; Tcl_PackageUnloadProc *unloadProc; - InterpPackage *ipFirstPtr, *ipPtr; + InterpLibrary *ipFirstPtr, *ipPtr; int i, index, code, complain = 1, keepLibrary = 0; int trustedRefCount = -1, safeRefCount = -1; const char *fullFileName = ""; @@ -615,7 +613,7 @@ Tcl_UnloadObjCmd( } if ((fullFileName[0] == 0) && (prefix == NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( - "must specify either file name or package name", -1)); + "must specify either file name or prefix", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NOLIBRARY", NULL); code = TCL_ERROR; @@ -623,7 +621,7 @@ Tcl_UnloadObjCmd( } /* - * Figure out which interpreter we're going to load the package into. + * Figure out which interpreter we're going to load the library into. */ target = interp; @@ -637,13 +635,13 @@ Tcl_UnloadObjCmd( } /* - * Scan through the packages that are currently loaded to see if the - * package we want is already loaded. We'll use a loaded package if it + * Scan through the libraries that are currently loaded to see if the + * library we want is already loaded. We'll use a loaded library if it * meets any of the following conditions: - * - Its name and file match the once we're looking for. - * - Its file matches, and we weren't given a name. - * - Its name matches, the file name was specified as empty, and there is - * only no statically loaded package with the same name. + * - Its prefix and file match the once we're looking for. + * - Its file matches, and we weren't given a prefix. + * - Its prefix matches, the file name was specified as empty, and there is + * only no statically loaded library with the same prefix. */ Tcl_MutexLock(&libraryMutex); @@ -682,7 +680,7 @@ Tcl_UnloadObjCmd( Tcl_MutexUnlock(&libraryMutex); if (fullFileName[0] == 0) { /* - * It's an error to try unload a static package. + * It's an error to try unload a static library. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -707,14 +705,14 @@ Tcl_UnloadObjCmd( } /* - * Scan through the list of packages already loaded in the target - * interpreter. If the package we want is already loaded there, then we + * Scan through the list of libraries already loaded in the target + * interpreter. If the library we want is already loaded there, then we * should proceed with unloading. */ code = TCL_ERROR; if (libraryPtr != NULL) { - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { if (ipPtr->libraryPtr == libraryPtr) { code = TCL_OK; @@ -724,7 +722,7 @@ Tcl_UnloadObjCmd( } if (code != TCL_OK) { /* - * The package has not been loaded in this interpreter. + * The library has not been loaded in this interpreter. */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -767,7 +765,7 @@ Tcl_UnloadObjCmd( } /* - * We are ready to unload the package. First, evaluate the unload + * We are ready to unload the library. First, evaluate the unload * function. If this fails, we cannot proceed with unload. Also, we must * specify the proper flag to pass to the unload callback. * TCL_UNLOAD_DETACH_FROM_INTERPRETER is defined when the callback should @@ -869,12 +867,12 @@ Tcl_UnloadObjCmd( * Remove this library from the interpreter's library cache. */ - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); ipPtr = ipFirstPtr; if (ipPtr->libraryPtr == defaultPtr) { ipFirstPtr = ipFirstPtr->nextPtr; } else { - InterpPackage *ipPrevPtr; + InterpLibrary *ipPrevPtr; for (ipPrevPtr = ipPtr; ipPtr != NULL; ipPrevPtr = ipPtr, ipPtr = ipPtr->nextPtr) { @@ -920,14 +918,14 @@ Tcl_UnloadObjCmd( * * Tcl_StaticLibrary -- * - * This function is invoked to indicate that a particular package has + * This function is invoked to indicate that a particular library has * been linked statically with an application. * * Results: * None. * * Side effects: - * Once this function completes, the package becomes loadable via the + * Once this function completes, the library becomes loadable via the * "load" command with an empty file name. * *---------------------------------------------------------------------- @@ -935,26 +933,26 @@ Tcl_UnloadObjCmd( void Tcl_StaticLibrary( - Tcl_Interp *interp, /* If not NULL, it means that the package has + Tcl_Interp *interp, /* If not NULL, it means that the library has * already been loaded into the given * interpreter by calling the appropriate init * proc. */ const char *prefix, /* Prefix. */ Tcl_PackageInitProc *initProc, /* Function to call to incorporate this - * package into a trusted interpreter. */ + * library into a trusted interpreter. */ Tcl_PackageInitProc *safeInitProc) /* Function to call to incorporate this - * package into a safe interpreter (one that + * library into a safe interpreter (one that * will execute untrusted scripts). NULL means - * the package can't be used in safe + * the library can't be used in safe * interpreters. */ { LoadedLibrary *libraryPtr; - InterpPackage *ipPtr, *ipFirstPtr; + InterpLibrary *ipPtr, *ipFirstPtr; /* - * Check to see if someone else has already reported this package as + * Check to see if someone else has already reported this library as * statically loaded in the process. */ @@ -969,7 +967,7 @@ Tcl_StaticLibrary( Tcl_MutexUnlock(&libraryMutex); /* - * If the package is not yet recorded as being loaded statically, add it + * If the library is not yet recorded as being loaded statically, add it * to the list now. */ @@ -991,11 +989,11 @@ Tcl_StaticLibrary( if (interp != NULL) { /* - * If we're loading the package into an interpreter, determine whether + * If we're loading the library into an interpreter, determine whether * it's already loaded. */ - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(interp, "tclLoad", NULL); + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(interp, "tclLoad", NULL); for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { if (ipPtr->libraryPtr == libraryPtr) { return; @@ -1003,11 +1001,11 @@ Tcl_StaticLibrary( } /* - * Package isn't loaded in the current interp yet. Mark it as now being + * Lirary isn't loaded in the current interp yet. Mark it as now being * loaded. */ - ipPtr = (InterpPackage *)Tcl_Alloc(sizeof(InterpPackage)); + ipPtr = (InterpLibrary *)Tcl_Alloc(sizeof(InterpLibrary)); ipPtr->libraryPtr = libraryPtr; ipPtr->nextPtr = ipFirstPtr; Tcl_SetAssocData(interp, "tclLoad", LoadCleanupProc, ipPtr); @@ -1027,7 +1025,7 @@ Tcl_StaticLibrary( * list of lists is placed in the interp's result. Each sublist * corresponds to one loaded file; its first element is the name of the * file (or an empty string for something that's statically loaded) and - * the second element is the name of the package in that file. + * the second element is the prefix of the library in that file. * * Side effects: * None. @@ -1043,13 +1041,13 @@ TclGetLoadedLibraries( * NULL, return info about all interps; * otherwise, just return info about this * interpreter. */ - const char *prefix) /* Package name or NULL. If NULL, return info - * for all packages. + const char *prefix) /* Prefix or NULL. If NULL, return info + * for all prefixes. */ { Tcl_Interp *target; LoadedLibrary *libraryPtr; - InterpPackage *ipPtr; + InterpLibrary *ipPtr; Tcl_Obj *resultObj, *pkgDesc[2]; if (targetName == NULL) { @@ -1071,10 +1069,10 @@ TclGetLoadedLibraries( if (target == NULL) { return TCL_ERROR; } - ipPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); + ipPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); /* - * Return information about all of the available packages. + * Return information about all of the available libraries. */ if (prefix) { resultObj = NULL; @@ -1095,7 +1093,7 @@ TclGetLoadedLibraries( } /* - * Return information about only the packages that are loaded in a given + * Return information about only the libraries that are loaded in a given * interpreter. */ @@ -1115,7 +1113,7 @@ TclGetLoadedLibraries( * * LoadCleanupProc -- * - * This function is called to delete all of the InterpPackage structures + * This function is called to delete all of the InterpLibrary structures * for an interpreter when the interpreter is deleted. It gets invoked * via the Tcl AssocData mechanism. * @@ -1123,20 +1121,20 @@ TclGetLoadedLibraries( * None. * * Side effects: - * Storage for all of the InterpPackage functions for interp get deleted. + * Storage for all of the InterpLibrary functions for interp get deleted. * *---------------------------------------------------------------------- */ static void LoadCleanupProc( - ClientData clientData, /* Pointer to first InterpPackage structure + ClientData clientData, /* Pointer to first InterpLibrary structure * for interp. */ TCL_UNUSED(Tcl_Interp *)) { - InterpPackage *ipPtr, *nextPtr; + InterpLibrary *ipPtr, *nextPtr; - ipPtr = (InterpPackage *)clientData; + ipPtr = (InterpLibrary *)clientData; while (ipPtr != NULL) { nextPtr = ipPtr->nextPtr; Tcl_Free(ipPtr); diff --git a/tests/load.test b/tests/load.test index eaaf7a7..9bbd510 100644 --- a/tests/load.test +++ b/tests/load.test @@ -56,10 +56,10 @@ test load-1.3 {basic errors} -returnCodes error -body { } -result {could not find interpreter "foobar"} test load-1.4 {basic errors} -returnCodes error -body { load -global {} -} -result {must specify either file name or package name} +} -result {must specify either file name or prefix} test load-1.5 {basic errors} -returnCodes error -body { load -lazy {} {} -} -result {must specify either file name or package name} +} -result {must specify either file name or prefix} test load-1.6 {basic errors} -returnCodes error -body { load {} Unknown } -result {no library with prefix "Unknown" is loaded statically} @@ -68,7 +68,7 @@ test load-1.7 {basic errors} -returnCodes error -body { } -result {bad option "-abc": must be -global, -lazy, or --} test load-1.8 {basic errors} -returnCodes error -body { load -global -} -result {couldn't figure out package name for -global} +} -result {couldn't figure out prefix for -global} test load-2.1 {basic loading, with guess for package name} \ [list $dll $loaded] { @@ -90,7 +90,7 @@ test load-2.3 {loading with no _Init procedure} -constraints [list $dll $loaded] {TCL LOOKUP LOAD_SYMBOL *Foo_Init}] test load-2.4 {loading with no _SafeInit procedure} [list $dll $loaded] { list [catch {load [file join $testDir pkga$ext] {} child} msg] $msg -} {1 {can't use package in a safe interpreter: no Pkga_SafeInit procedure}} +} {1 {can't use library in a safe interpreter: no Pkga_SafeInit procedure}} test load-3.1 {error in _Init procedure, same interpreter} \ [list $dll $loaded] { @@ -128,7 +128,7 @@ test load-4.2 {reloading package into same interpreter} -setup { catch {load [file join $testDir pkga$ext] pkga} } -constraints [list $dll $loaded] -returnCodes error -body { load [file join $testDir pkga$ext] Pkgb -} -result "file \"[file join $testDir pkga$ext]\" is already loaded for package \"Pkga\"" +} -result "file \"[file join $testDir pkga$ext]\" is already loaded for prefix \"Pkga\"" test load-5.1 {file name not specified and no static package: pick default} -setup { catch {interp delete x} @@ -164,7 +164,7 @@ test load-7.2 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { child eval {set x "not loaded"} list [catch {load {} Another child} msg] $msg \ [child eval set x] [set x] -} {1 {can't use package in a safe interpreter: no Another_SafeInit procedure} {not loaded} loaded} +} {1 {can't use library in a safe interpreter: no Another_SafeInit procedure} {not loaded} loaded} test load-7.3 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { set x "not loaded" teststaticlibrary More 0 1 diff --git a/tests/safe.test b/tests/safe.test index 0394eb9..45a0177 100644 --- a/tests/safe.test +++ b/tests/safe.test @@ -1164,7 +1164,7 @@ test safe-10.1 {testing statics loading} -constraints TcltestPackage -setup { interp eval $i {load {} Safepkg1} } -returnCodes error -cleanup { safe::interpDelete $i -} -result {load of binary library for package Safepkg1 failed: can't use package in a safe interpreter: no Safepkg1_SafeInit procedure} +} -result {load of binary library for package Safepkg1 failed: can't use library in a safe interpreter: no Safepkg1_SafeInit procedure} test safe-10.1.1 {testing statics loading} -constraints TcltestPackage -setup { set i [safe::interpCreate] } -body { @@ -1173,7 +1173,7 @@ test safe-10.1.1 {testing statics loading} -constraints TcltestPackage -setup { } -returnCodes ok -cleanup { unset -nocomplain m o safe::interpDelete $i -} -result {load of binary library for package Safepkg1 failed: can't use package in a safe interpreter: no Safepkg1_SafeInit procedure +} -result {load of binary library for package Safepkg1 failed: can't use library in a safe interpreter: no Safepkg1_SafeInit procedure invoked from within "load {} Safepkg1" invoked from within @@ -1196,7 +1196,7 @@ test safe-10.4 {testing nested statics loading / -nestedloadok} -constraints Tcl interp eval $i {interp create x; load {} Safepkg1 x} } -returnCodes error -cleanup { safe::interpDelete $i -} -result {load of binary library for package Safepkg1 failed: can't use package in a safe interpreter: no Safepkg1_SafeInit procedure} +} -result {load of binary library for package Safepkg1 failed: can't use library in a safe interpreter: no Safepkg1_SafeInit procedure} test safe-10.4.1 {testing nested statics loading / -nestedloadok} -constraints TcltestPackage -body { set i [safe::interpCreate -nestedloadok] catch {interp eval $i {interp create x; load {} Safepkg1 x}} m o @@ -1204,7 +1204,7 @@ test safe-10.4.1 {testing nested statics loading / -nestedloadok} -constraints T } -returnCodes ok -cleanup { unset -nocomplain m o safe::interpDelete $i -} -result {load of binary library for package Safepkg1 failed: can't use package in a safe interpreter: no Safepkg1_SafeInit procedure +} -result {load of binary library for package Safepkg1 failed: can't use library in a safe interpreter: no Safepkg1_SafeInit procedure invoked from within "load {} Safepkg1 x" invoked from within diff --git a/tests/unload.test b/tests/unload.test index f1f4580..68cdd13 100644 --- a/tests/unload.test +++ b/tests/unload.test @@ -62,10 +62,10 @@ test unload-1.3 {basic errors} -returnCodes error -body { } -result {could not find interpreter "foobar"} test unload-1.4 {basic errors} -returnCodes error -body { unload {} -} -result {must specify either file name or package name} +} -result {must specify either file name or prefix} test unload-1.5 {basic errors} -returnCodes error -body { unload {} {} -} -result {must specify either file name or package name} +} -result {must specify either file name or prefix} test unload-1.6 {basic errors} -returnCodes error -body { unload {} Unknown } -result {library with prefix "Unknown" is loaded statically and cannot be unloaded} -- cgit v0.12 From cc7d39873fa40c42eeca9a655fa579c3feb54ab5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 5 Dec 2020 11:28:33 +0000 Subject: Add -fextended-identifiers option to unix/dltest makefile --- unix/dltest/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/dltest/Makefile.in b/unix/dltest/Makefile.in index 09b496d..fdd3e98 100644 --- a/unix/dltest/Makefile.in +++ b/unix/dltest/Makefile.in @@ -33,7 +33,7 @@ dltest_suffix: pkgπ${DLTEST_SUFFIX} pkga${DLTEST_SUFFIX} pkgb${DLTEST_SUFFIX} p @touch ../dltest.marker pkgπ.o: $(SRC_DIR)/pkgπ.c - $(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgπ.c + $(CC) -c $(CC_SWITCHES) -fextended-identifiers $(SRC_DIR)/pkgπ.c pkga.o: $(SRC_DIR)/pkga.c $(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkga.c -- cgit v0.12 From 3f62bdc438a97dd70b557b9c95c73ad9cddac1f6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 6 Dec 2020 13:47:42 +0000 Subject: Add -finput-charset=UTF-8 to CFLAGS --- unix/configure | 4 ++-- unix/dltest/Makefile.in | 2 +- unix/tcl.m4 | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/unix/configure b/unix/configure index 3dc88a1..4a91811 100755 --- a/unix/configure +++ b/unix/configure @@ -5027,12 +5027,12 @@ fi if test "$GCC" = yes; then : CFLAGS_OPTIMIZE=-O2 - CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith" + CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8" case "${CC}" in *++|*++-*) ;; *) - CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement" + CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -fextended-identifiers -Wdeclaration-after-statement" ;; esac diff --git a/unix/dltest/Makefile.in b/unix/dltest/Makefile.in index fdd3e98..09b496d 100644 --- a/unix/dltest/Makefile.in +++ b/unix/dltest/Makefile.in @@ -33,7 +33,7 @@ dltest_suffix: pkgπ${DLTEST_SUFFIX} pkga${DLTEST_SUFFIX} pkgb${DLTEST_SUFFIX} p @touch ../dltest.marker pkgπ.o: $(SRC_DIR)/pkgπ.c - $(CC) -c $(CC_SWITCHES) -fextended-identifiers $(SRC_DIR)/pkgπ.c + $(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgπ.c pkga.o: $(SRC_DIR)/pkga.c $(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkga.c diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 930f381..695588d 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -958,12 +958,12 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CFLAGS_DEBUG=-g AS_IF([test "$GCC" = yes], [ CFLAGS_OPTIMIZE=-O2 - CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith" + CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8" case "${CC}" in *++|*++-*) ;; *) - CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement" + CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -fextended-identifiers -Wdeclaration-after-statement" ;; esac -- cgit v0.12 From 567b79ea315fea66d4c49ecae05c9d37f9cdf175 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 7 Dec 2020 09:16:19 +0000 Subject: Use \u???? syntax in identifiers, to make it work with gcc too --- "unix/dltest/pkg\317\200.c" | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git "a/unix/dltest/pkg\317\200.c" "b/unix/dltest/pkg\317\200.c" index faeaa46..81078fa 100644 --- "a/unix/dltest/pkg\317\200.c" +++ "b/unix/dltest/pkg\317\200.c" @@ -17,7 +17,7 @@ * Prototypes for procedures defined later in this file: */ -static int Pkgπ_ΠObjCmd(ClientData clientData, +static int Pkg\u03C0_\u03A0ObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* @@ -39,7 +39,7 @@ static int Pkgπ_ΠObjCmd(ClientData clientData, */ static int -Pkgπ_ΠObjCmd( +Pkg\u03C0_\u03A0ObjCmd( void *dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ @@ -77,7 +77,7 @@ Pkgπ_ΠObjCmd( */ DLLEXPORT int -Pkgπ_Init( +Pkg\u03C0_Init( Tcl_Interp *interp) /* Interpreter in which the package is to be * made available. */ { @@ -90,6 +90,6 @@ Pkgπ_Init( if (code != TCL_OK) { return code; } - Tcl_CreateObjCommand(interp, "π", Pkgπ_ΠObjCmd, NULL, NULL); + Tcl_CreateObjCommand(interp, "π", Pkg\u03C0_\u03A0ObjCmd, NULL, NULL); return TCL_OK; } -- cgit v0.12 From c42695035ce9433fed4856709e9acb518a4979ac Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 7 Dec 2020 09:21:31 +0000 Subject: =?UTF-8?q?=C2=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- unix/dltest/pkga.c | 2 +- unix/dltest/pkgb.c | 2 +- unix/dltest/pkgc.c | 2 +- unix/dltest/pkgd.c | 2 +- unix/dltest/pkge.c | 2 +- unix/dltest/pkgooa.c | 2 +- unix/dltest/pkgua.c | 4 ++-- "unix/dltest/pkg\317\200.c" | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/unix/dltest/pkga.c b/unix/dltest/pkga.c index c2d814f..e00f996 100644 --- a/unix/dltest/pkga.c +++ b/unix/dltest/pkga.c @@ -4,7 +4,7 @@ * This file contains a simple Tcl package "pkga" that is intended for * testing the Tcl dynamic loading facilities. * - * Copyright (c) 1995 Sun Microsystems, Inc. + * Copyright © 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/unix/dltest/pkgb.c b/unix/dltest/pkgb.c index 741b2a1..3210669 100644 --- a/unix/dltest/pkgb.c +++ b/unix/dltest/pkgb.c @@ -5,7 +5,7 @@ * testing the Tcl dynamic loading facilities. It can be used in both * safe and unsafe interpreters. * - * Copyright (c) 1995 Sun Microsystems, Inc. + * Copyright © 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/unix/dltest/pkgc.c b/unix/dltest/pkgc.c index 46f6e86..2b46986 100644 --- a/unix/dltest/pkgc.c +++ b/unix/dltest/pkgc.c @@ -5,7 +5,7 @@ * testing the Tcl dynamic loading facilities. It can be used in both * safe and unsafe interpreters. * - * Copyright (c) 1995 Sun Microsystems, Inc. + * Copyright © 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/unix/dltest/pkgd.c b/unix/dltest/pkgd.c index d3af83f..5c799f5 100644 --- a/unix/dltest/pkgd.c +++ b/unix/dltest/pkgd.c @@ -5,7 +5,7 @@ * testing the Tcl dynamic loading facilities. It can be used in both * safe and unsafe interpreters. * - * Copyright (c) 1995 Sun Microsystems, Inc. + * Copyright © 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/unix/dltest/pkge.c b/unix/dltest/pkge.c index f46ca74..26a4b79 100644 --- a/unix/dltest/pkge.c +++ b/unix/dltest/pkge.c @@ -5,7 +5,7 @@ * testing the Tcl dynamic loading facilities. Its Init procedure returns * an error in order to test how this is handled. * - * Copyright (c) 1995 Sun Microsystems, Inc. + * Copyright © 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/unix/dltest/pkgooa.c b/unix/dltest/pkgooa.c index 7d0c98b..ff1cf1f 100644 --- a/unix/dltest/pkgooa.c +++ b/unix/dltest/pkgooa.c @@ -4,7 +4,7 @@ * This file contains a simple Tcl package "pkgooa" that is intended for * testing the Tcl dynamic loading facilities. * - * Copyright (c) 1995 Sun Microsystems, Inc. + * Copyright © 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/unix/dltest/pkgua.c b/unix/dltest/pkgua.c index c5102a8..0ab3e23 100644 --- a/unix/dltest/pkgua.c +++ b/unix/dltest/pkgua.c @@ -4,8 +4,8 @@ * This file contains a simple Tcl package "pkgua" that is intended for * testing the Tcl dynamic unloading facilities. * - * Copyright (c) 1995 Sun Microsystems, Inc. - * Copyright (c) 2004 Georgios Petasis + * Copyright © 1995 Sun Microsystems, Inc. + * Copyright © 2004 Georgios Petasis * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git "a/unix/dltest/pkg\317\200.c" "b/unix/dltest/pkg\317\200.c" index 81078fa..1cf95cf 100644 --- "a/unix/dltest/pkg\317\200.c" +++ "b/unix/dltest/pkg\317\200.c" @@ -4,7 +4,7 @@ * This file contains a simple Tcl package "pkgπ" that is intended for * testing the Tcl dynamic loading facilities. * - * Copyright (c) 1995 Sun Microsystems, Inc. + * Copyright © 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. -- cgit v0.12 From ec714e1d4fe3c39ba19520dbf55debd3ac26cbae Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 10 Dec 2020 10:33:41 +0000 Subject: Tweak error-message --- library/safe.tcl | 24 ++++++++++++------------ tests/safe.test | 32 ++++++++++++++++---------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/library/safe.tcl b/library/safe.tcl index e7760f8..9f2d007 100644 --- a/library/safe.tcl +++ b/library/safe.tcl @@ -1009,8 +1009,8 @@ proc ::safe::AliasLoad {child file args} { return -code error $msg } - # package name (can be empty if file is not). - set package [lindex $args 0] + # prefix (can be empty if file is not). + set prefix [lindex $args 0] namespace upvar ::safe [VarName $child] state @@ -1022,23 +1022,23 @@ proc ::safe::AliasLoad {child file args} { # authorize that. if {!$state(nestedok)} { Log $child "loading to a sub interp (nestedok)\ - disabled (trying to load $package to $target)" + disabled (trying to load $prefix to $target)" return -code error "permission denied (nested load)" } } # Determine what kind of load is requested if {$file eq ""} { - # static package loading - if {$package eq ""} { - set msg "load error: empty filename and no package name" + # static loading + if {$prefix eq ""} { + set msg "load error: empty filename and no prefix" Log $child $msg return -code error $msg } if {!$state(staticsok)} { - Log $child "static packages loading disabled\ - (trying to load $package to $target)" - return -code error "permission denied (static package)" + Log $child "static library loading disabled\ + (trying to load $prefix to $target)" + return -code error "permission denied (static library)" } } else { # file loading @@ -1061,10 +1061,10 @@ proc ::safe::AliasLoad {child file args} { } try { - return [::interp invokehidden $child load $file $package $target] + return [::interp invokehidden $child load $file $prefix $target] } on error msg { - # Some packages return no error message. - set msg0 "load of binary library for package $package failed" + # Some libraries return no error message. + set msg0 "load of binary library with prefix $prefix failed" if {$msg eq {}} { set msg $msg0 } else { diff --git a/tests/safe.test b/tests/safe.test index 454d670..ffc005c 100644 --- a/tests/safe.test +++ b/tests/safe.test @@ -1157,58 +1157,58 @@ test safe-9.24 {interpConfigure change the access path; check module loading; st res0 res1 res2} # See comments on lsort after test safe-9.20. -catch {teststaticlibrary Safepkg1 0 0} +catch {teststaticlibrary Safe1 0 0} test safe-10.1 {testing statics loading} -constraints tcl::test -setup { set i [safe::interpCreate] } -body { - interp eval $i {load {} Safepkg1} + interp eval $i {load {} Safe1} } -returnCodes error -cleanup { safe::interpDelete $i -} -result {load of binary library for package Safepkg1 failed: can't use library in a safe interpreter: no Safepkg1_SafeInit procedure} +} -result {load of binary library with prefix Safe1 failed: can't use library in a safe interpreter: no Safe1_SafeInit procedure} test safe-10.1.1 {testing statics loading} -constraints tcl::test -setup { set i [safe::interpCreate] } -body { - catch {interp eval $i {load {} Safepkg1}} m o + catch {interp eval $i {load {} Safe1}} m o dict get $o -errorinfo } -returnCodes ok -cleanup { unset -nocomplain m o safe::interpDelete $i -} -result {load of binary library for package Safepkg1 failed: can't use library in a safe interpreter: no Safepkg1_SafeInit procedure +} -result {load of binary library with prefix Safe1 failed: can't use library in a safe interpreter: no Safe1_SafeInit procedure invoked from within -"load {} Safepkg1" +"load {} Safe1" invoked from within -"interp eval $i {load {} Safepkg1}"} +"interp eval $i {load {} Safe1}"} test safe-10.2 {testing statics loading / -nostatics} -constraints tcl::test -body { set i [safe::interpCreate -nostatics] - interp eval $i {load {} Safepkg1} + interp eval $i {load {} Safe1} } -returnCodes error -cleanup { safe::interpDelete $i -} -result {permission denied (static package)} +} -result {permission denied (static library)} test safe-10.3 {testing nested statics loading / no nested by default} -setup { set i [safe::interpCreate] } -constraints tcl::test -body { - interp eval $i {interp create x; load {} Safepkg1 x} + interp eval $i {interp create x; load {} Safe1 x} } -returnCodes error -cleanup { safe::interpDelete $i } -result {permission denied (nested load)} test safe-10.4 {testing nested statics loading / -nestedloadok} -constraints tcl::test -body { set i [safe::interpCreate -nestedloadok] - interp eval $i {interp create x; load {} Safepkg1 x} + interp eval $i {interp create x; load {} Safe1 x} } -returnCodes error -cleanup { safe::interpDelete $i -} -result {load of binary library for package Safepkg1 failed: can't use library in a safe interpreter: no Safepkg1_SafeInit procedure} +} -result {load of binary library with prefix Safe1 failed: can't use library in a safe interpreter: no Safe1_SafeInit procedure} test safe-10.4.1 {testing nested statics loading / -nestedloadok} -constraints tcl::test -body { set i [safe::interpCreate -nestedloadok] - catch {interp eval $i {interp create x; load {} Safepkg1 x}} m o + catch {interp eval $i {interp create x; load {} Safe1 x}} m o dict get $o -errorinfo } -returnCodes ok -cleanup { unset -nocomplain m o safe::interpDelete $i -} -result {load of binary library for package Safepkg1 failed: can't use library in a safe interpreter: no Safepkg1_SafeInit procedure +} -result {load of binary library with prefix Safe1 failed: can't use library in a safe interpreter: no Safe1_SafeInit procedure invoked from within -"load {} Safepkg1 x" +"load {} Safe1 x" invoked from within -"interp eval $i {interp create x; load {} Safepkg1 x}"} +"interp eval $i {interp create x; load {} Safe1 x}"} test safe-11.1 {testing safe encoding} -setup { set i [safe::interpCreate] -- cgit v0.12 From 0c788cde5c30f347307f287a08c708dec79c91e6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 10 Dec 2020 15:45:44 +0000 Subject: publicize TclWinConvertError --- generic/tcl.decls | 3 +++ generic/tclIntPlatDecls.h | 5 +++++ generic/tclPlatDecls.h | 5 +++++ generic/tclStubInit.c | 8 ++++++++ win/tclWinError.c | 6 +++--- win/tclWinTest.c | 2 +- 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index c4af7cc..88efc8b 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2426,6 +2426,9 @@ declare 0 win { declare 1 win { char *Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr) } +declare 2 win { + void Tcl_WinConvertError(unsigned errCode) +} ################################ # Mac OS X specific functions diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index de308de..ab534aa 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -569,7 +569,12 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; #undef TclpLocaltime_unix #undef TclpGmtime_unix #undef TclWinConvertWSAError +#undef TclWinConvertError #define TclWinConvertWSAError TclWinConvertError +#if !defined(TCL_USE_STUBS) && !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 +# define TclWinConvertError Tcl_WinConvertError +#endif + #undef TclpInetNtoa #define TclpInetNtoa inet_ntoa diff --git a/generic/tclPlatDecls.h b/generic/tclPlatDecls.h index 4b06148..c0ff12f 100644 --- a/generic/tclPlatDecls.h +++ b/generic/tclPlatDecls.h @@ -57,6 +57,8 @@ EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len, /* 1 */ EXTERN char * Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr); +/* 2 */ +EXTERN void Tcl_WinConvertError(unsigned errCode); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ /* 0 */ @@ -78,6 +80,7 @@ typedef struct TclPlatStubs { #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */ char * (*tcl_WinTCharToUtf) (const TCHAR *str, int len, Tcl_DString *dsPtr); /* 1 */ + void (*tcl_WinConvertError) (unsigned errCode); /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ int (*tcl_MacOSXOpenBundleResources) (Tcl_Interp *interp, const char *bundleName, int hasResourceFile, int maxPathLen, char *libraryPath); /* 0 */ @@ -102,6 +105,8 @@ extern const TclPlatStubs *tclPlatStubsPtr; (tclPlatStubsPtr->tcl_WinUtfToTChar) /* 0 */ #define Tcl_WinTCharToUtf \ (tclPlatStubsPtr->tcl_WinTCharToUtf) /* 1 */ +#define Tcl_WinConvertError \ + (tclPlatStubsPtr->tcl_WinConvertError) /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ #define Tcl_MacOSXOpenBundleResources \ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 4b0e968..aab3aa7 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -74,6 +74,13 @@ #undef Tcl_UtfToUniCharDString #undef Tcl_UtfToUniChar #undef Tcl_MacOSXOpenBundleResources +#undef TclWinConvertWSAError +#undef TclWinConvertError +#if defined(_WIN32) || defined(__CYGWIN__) +#define TclWinConvertWSAError (void (*)(DWORD))(void *)Tcl_WinConvertError +#define TclWinConvertError (void (*)(DWORD))(void *)Tcl_WinConvertError +#endif + #if TCL_UTF_MAX > 3 static void uniCodePanic(void) { @@ -1119,6 +1126,7 @@ static const TclPlatStubs tclPlatStubs = { #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ Tcl_WinUtfToTChar, /* 0 */ Tcl_WinTCharToUtf, /* 1 */ + Tcl_WinConvertError, /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ Tcl_MacOSXOpenBundleResources, /* 0 */ diff --git a/win/tclWinError.c b/win/tclWinError.c index e85becc..7e5898b 100644 --- a/win/tclWinError.c +++ b/win/tclWinError.c @@ -334,7 +334,7 @@ static const unsigned char wsaErrorTable[] = { /* *---------------------------------------------------------------------- * - * TclWinConvertError -- + * Tcl_WinConvertError -- * * This routine converts a Win32 error into an errno value. * @@ -348,8 +348,8 @@ static const unsigned char wsaErrorTable[] = { */ void -TclWinConvertError( - DWORD errCode) /* Win32 error code. */ +Tcl_WinConvertError( + unsigned errCode) /* Win32 error code. */ { if (errCode >= sizeof(errorTable)/sizeof(errorTable[0])) { errCode -= WSAEWOULDBLOCK; diff --git a/win/tclWinTest.c b/win/tclWinTest.c index e924b1a..f45b557 100644 --- a/win/tclWinTest.c +++ b/win/tclWinTest.c @@ -208,7 +208,7 @@ TestvolumetypeCmd( if (found == 0) { Tcl_AppendResult(interp, "could not get volume type for \"", (path?path:""), "\"", NULL); - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return TCL_ERROR; } Tcl_AppendResult(interp, volType, NULL); -- cgit v0.12 From 2ff814556189426b5aaac1392705441dea064c5c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 27 Jan 2021 09:32:44 +0000 Subject: When generating stubs, always read *.decls and *Decls.h files in UTF-8. This corrects possible invalid UTF-8. --- tools/genStubs.tcl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/genStubs.tcl b/tools/genStubs.tcl index bc0d700..5b7278c 100644 --- a/tools/genStubs.tcl +++ b/tools/genStubs.tcl @@ -257,8 +257,9 @@ proc genStubs::rewriteFile {file text} { return } set in [open ${file} r] + fconfigure $in -eofchar "\032 {}" -encoding utf-8 set out [open ${file}.new w] - fconfigure $out -translation lf + fconfigure $out -translation lf -encoding utf-8 while {![eof $in]} { set line [gets $in] @@ -1191,7 +1192,7 @@ proc genStubs::init {} { set outDir [lindex $argv 0] foreach file [lrange $argv 1 end] { - source $file + source -encoding utf-8 $file } foreach name [lsort [array names interfaces]] { -- cgit v0.12 From 6b29884385ff5fa383bd25b84ae1184db4f8811c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 27 Jan 2021 10:13:51 +0000 Subject: *.decls files are now in UTF-8. Use "in" operator in stead of "lsearch -exact". --- generic/tcl.decls | 6 +++--- generic/tclInt.decls | 6 +++--- generic/tclOO.decls | 2 +- generic/tclTomMath.decls | 2 +- tools/genStubs.tcl | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 23e8f6a..13e7326 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -5,9 +5,9 @@ # This file is used to generate the tclDecls.h, tclPlatDecls.h # and tclStubInit.c files. # -# Copyright (c) 1998-1999 by Scriptics Corporation. -# Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved. -# Copyright (c) 2007 Daniel A. Steffen +# Copyright © 1998-1999 Scriptics Corporation. +# Copyright © 2001, 2002 Kevin B. Kenny. All rights reserved. +# Copyright © 2007 Daniel A. Steffen # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/generic/tclInt.decls b/generic/tclInt.decls index b858dfa..b6f7b75 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -5,9 +5,9 @@ # is used to generate the tclIntDecls.h, tclIntPlatDecls.h # and tclStubInit.c files # -# Copyright (c) 1998-1999 by Scriptics Corporation. -# Copyright (c) 2001 by Kevin B. Kenny. All rights reserved. -# Copyright (c) 2007 Daniel A. Steffen +# Copyright © 1998-1999 Scriptics Corporation. +# Copyright © 2001 Kevin B. Kenny. All rights reserved. +# Copyright © 2007 Daniel A. Steffen # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/generic/tclOO.decls b/generic/tclOO.decls index 265ba88..5d37994 100644 --- a/generic/tclOO.decls +++ b/generic/tclOO.decls @@ -5,7 +5,7 @@ # library via the stubs table. This file is used to generate the # tclOODecls.h, tclOOIntDecls.h and tclOOStubInit.c files. # -# Copyright (c) 2008-2013 by Donal K. Fellows. +# Copyright © 2008-2013 Donal K. Fellows. # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/generic/tclTomMath.decls b/generic/tclTomMath.decls index 2511e3a..02d3581 100644 --- a/generic/tclTomMath.decls +++ b/generic/tclTomMath.decls @@ -7,7 +7,7 @@ # If you edit this file, advance the revision number (and the epoch # if the new stubs are not backward compatible) in tclTomMathDecls.h # -# Copyright (c) 2005 by Kevin B. Kenny. All rights reserved. +# Copyright © 2005 Kevin B. Kenny. All rights reserved. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/tools/genStubs.tcl b/tools/genStubs.tcl index 5b7278c..47b8ad4 100644 --- a/tools/genStubs.tcl +++ b/tools/genStubs.tcl @@ -1101,7 +1101,7 @@ proc genStubs::emitInit {name textVar} { } foreach intf [array names interfaces] { if {[info exists hooks($intf)]} { - if {[lsearch -exact $hooks($intf) $name] >= 0} { + if {$name in $hooks($intf)} { set root 0 break } -- cgit v0.12 From 9c024d9d3bfcd6cee7c0a39492f7e1fd4f80192d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 28 Jan 2021 10:38:44 +0000 Subject: Use "in" operator in stead of "lsearch -exact" when possible --- library/opt/optparse.tcl | 2 +- library/tcltest/tcltest.tcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/opt/optparse.tcl b/library/opt/optparse.tcl index 1639379..454b923 100644 --- a/library/opt/optparse.tcl +++ b/library/opt/optparse.tcl @@ -601,7 +601,7 @@ proc ::tcl::OptCheckType {arg type {typeArgs ""}} { return [expr {$arg ? 1 : 0}] } choice { - if {[lsearch -exact $typeArgs $arg] < 0} { + if {$arg ni $typeArgs} { error "invalid choice" } return $arg diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl index 7dc75d7..dedcd7a 100644 --- a/library/tcltest/tcltest.tcl +++ b/library/tcltest/tcltest.tcl @@ -642,7 +642,7 @@ namespace eval tcltest { proc IsVerbose {level} { variable Option - return [expr {[lsearch -exact $Option(-verbose) $level] >= 0}] + return [expr {$level in $Option(-verbose)}] } # Default verbosity is to show bodies of failed tests -- cgit v0.12 From 8d49123e73e1b0bbbf97cd212e88960772a9e166 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 28 Jan 2021 10:42:05 +0000 Subject: Use {} braces in more "expr" expressions. --- tests/exec.test | 2 +- tests/expr-old.test | 8 +- tests/expr.test | 18 +- tests/fileSystem.test | 6 +- tests/fileSystemEncoding.test | 2 +- tests/foreach.test | 2 +- tests/format.test | 12 +- tests/httpold.test | 4 +- tests/info.test | 2 +- tests/io.test | 36 +- tests/lmap.test | 8 +- tests/parse.test | 18 +- tests/parseOld.test | 4 +- tests/string.test | 14 +- tests/util.test | 1300 ++++++++++++++++++++--------------------- 15 files changed, 718 insertions(+), 718 deletions(-) diff --git a/tests/exec.test b/tests/exec.test index af7aae5..0f5db76 100644 --- a/tests/exec.test +++ b/tests/exec.test @@ -111,7 +111,7 @@ set path(sh2) [makeFile { exit } sh2] set path(sleep) [makeFile { - after [expr $argv*1000] + after [expr {$argv*1000}] exit } sleep] set path(exit) [makeFile { diff --git a/tests/expr-old.test b/tests/expr-old.test index 28ec346..6f85748 100644 --- a/tests/expr-old.test +++ b/tests/expr-old.test @@ -420,13 +420,13 @@ test expr-old-21.3 {parenthesization} {expr +(3-4)} -1 # Embedded commands and variable names. -set a 16 -test expr-old-22.1 {embedded variables} {expr {2*$a}} 32 +set a 16 +test expr-old-22.1 {embedded variables} {expr {2*$a}} 32 test expr-old-22.2 {embedded variables} { set x -5 set y 10 expr {$x + $y} -} {5} +} {5} test expr-old-22.3 {embedded variables} { set x " -5" set y " +10" @@ -1120,7 +1120,7 @@ test expr-old-37.25 {Tcl_ExprDouble and NaN} \ {ieeeFloatingPoint testexprdouble} { list [catch {testexprdouble 0.0/0.0} result] $result } {1 {domain error: argument not in valid range}} - + test expr-old-38.1 {Verify Tcl_ExprString's basic operation} -constraints {testexprstring} -body { list [testexprstring "1+4"] [testexprstring "2*3+4.2"] \ [catch {testexprstring "1+"} msg] $msg diff --git a/tests/expr.test b/tests/expr.test index 37d8fe3..b81c4a7 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -19,7 +19,7 @@ if {"::tcltest" ni [namespace children]} { catch [list package require -exact Tcltest [info patchlevel]] testConstraint testmathfunctions [expr { - ([catch {expr T1()} msg] != 1) || ($msg ne {invalid command name "tcl::mathfunc::T1"}) + ([catch {expr {T1()}} msg] != 1) || ($msg ne {invalid command name "tcl::mathfunc::T1"}) }] # Determine if "long int" type is a 32 bit number and if the wide @@ -1438,7 +1438,7 @@ test expr-23.74.3 {INST_EXPON: Bug 2798543} { expr {(-14)**17 == (-14)**65553} } 0 - + # Some compilers get this wrong; ensure that we work around it correctly test expr-24.1 {expr edge cases; shifting} {expr int(5)>>32} 0 test expr-24.2 {expr edge cases; shifting} {expr int(5)>>63} 0 @@ -5786,7 +5786,7 @@ test expr-32.1 {expr mod basics} { 0 1 0 3 3 \ 0 -1 0 -1 -2 \ ] - + test expr-32.2 {expr div basics} { set mod_nums [list \ {-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \ @@ -6794,7 +6794,7 @@ test expr-39.16 {Tcl_ExprLongObj handles overflows} \ list [catch {testexprlongobj 4294967296.} result] $result } \ -result {1 {integer value too large to represent*}} - + test expr-39.17 {Check that Tcl_ExprDoubleObj doesn't modify interpreter result if no error} testexprdoubleobj { testexprdoubleobj 4.+1. } {This is a result: 5.0} @@ -6881,19 +6881,19 @@ test expr-41.13 {exponent overflow} { } 0.0 test expr-41.14 {exponent overflow} { expr 100e-2147483651 -} 0.0 +} 0.0 test expr-41.15 {exponent overflow} { expr 1.0e-2147483648 -} 0.0 +} 0.0 test expr-41.16 {exponent overflow} { expr 1.0e-2147483649 -} 0.0 +} 0.0 test expr-41.17 {exponent overflow} { expr 1.23e-2147483646 } 0.0 test expr-41.18 {exponent overflow} { expr 1.23e-2147483647 -} 0.0 +} 0.0 test expr-41.19 {numSigDigs == 0} { expr 0e309 @@ -7269,7 +7269,7 @@ test expr-52.1 { list [expr {$a eq {}}] [expr {$a < {}}] [expr {$a > {}}] [ string match {*no string representation*} [ ::tcl::unsupported::representation $a]] -} {0 0 1 1} +} {0 0 1 1} diff --git a/tests/fileSystem.test b/tests/fileSystem.test index 8af4f53..f363d86 100644 --- a/tests/fileSystem.test +++ b/tests/fileSystem.test @@ -153,7 +153,7 @@ test filesystem-1.10 {link normalisation: double link} -constraints { [file normalize [file join dir2.link inside.file foo]] } -cleanup { file delete dir2.link -} -result ok +} -result ok makeDirectory dir2.file test filesystem-1.11 {link normalisation: double link, back in tree} {unix hasLinks} { file link dir2.link dir.link @@ -168,7 +168,7 @@ test filesystem-1.12 {file new native path} {} { } } # If we reach here we've succeeded. We used to crash above. - expr 1 + expr {1} } {1} test filesystem-1.13 {file normalisation} {win} { # This used to be broken @@ -913,7 +913,7 @@ test filesystem-9.5 {path objects and file tail and object rep} -setup { } return $res } -cleanup { - file delete -force dgp + file delete -force dgp cd $origdir } -result {test test} test filesystem-9.6 {path objects and file tail and object rep} win { diff --git a/tests/fileSystemEncoding.test b/tests/fileSystemEncoding.test index 40a0090..6561bef 100644 --- a/tests/fileSystemEncoding.test +++ b/tests/fileSystemEncoding.test @@ -42,7 +42,7 @@ namespace eval ::tcl::test::fileSystemEncoding { set globbed [lindex [glob -directory $dir *] 0] encoding system utf-8 set res [file exists $globbed] - encoding system iso8859-1 + encoding system iso8859-1 lappend res [file exists $globbed] return $res } -cleanup { diff --git a/tests/foreach.test b/tests/foreach.test index cdbfc85..bb06b80 100644 --- a/tests/foreach.test +++ b/tests/foreach.test @@ -165,7 +165,7 @@ test foreach-4.1 {noncompiled foreach and shared variable or value list objects catch {unset x} foreach {12.0} {a b c} { set x 12.0 - set x [expr $x + 1] + set x [expr {$x + 1}] } set x } 13.0 diff --git a/tests/format.test b/tests/format.test index 11cb4b7..20006ef 100644 --- a/tests/format.test +++ b/tests/format.test @@ -460,7 +460,7 @@ test format-13.1 {tcl_precision fuzzy comparison} { set a 0.0000000000001 set b 0.00000000000001 set c 0.00000000000000001 - set d [expr $a + $b + $c] + set d [expr {$a + $b + $c}] format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d } {0.0000000000 0.000000000000 0.000000000000110 0.00000000000011001} test format-13.2 {tcl_precision fuzzy comparison} { @@ -471,7 +471,7 @@ test format-13.2 {tcl_precision fuzzy comparison} { set a 0.000000000001 set b 0.000000000000005 set c 0.0000000000000008 - set d [expr $a + $b + $c] + set d [expr {$a + $b + $c}] format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d } {0.0000000000 0.000000000001 0.000000000001006 0.00000000000100580} test format-13.3 {tcl_precision fuzzy comparison} { @@ -480,7 +480,7 @@ test format-13.3 {tcl_precision fuzzy comparison} { catch {unset c} set a 0.00000000000099 set b 0.000000000000011 - set c [expr $a + $b] + set c [expr {$a + $b}] format {%0.10f %0.12f %0.15f %0.17f} $c $c $c $c } {0.0000000000 0.000000000001 0.000000000001001 0.00000000000100100} test format-13.4 {tcl_precision fuzzy comparison} { @@ -489,7 +489,7 @@ test format-13.4 {tcl_precision fuzzy comparison} { catch {unset c} set a 0.444444444444 set b 0.33333333333333 - set c [expr $a + $b] + set c [expr {$a + $b}] format {%0.10f %0.12f %0.15f %0.16f} $c $c $c $c } {0.7777777778 0.777777777777 0.777777777777330 0.7777777777773300} test format-13.5 {tcl_precision fuzzy comparison} { @@ -498,7 +498,7 @@ test format-13.5 {tcl_precision fuzzy comparison} { catch {unset c} set a 0.444444444444 set b 0.99999999999999 - set c [expr $a + $b] + set c [expr {$a + $b}] format {%0.10f %0.12f %0.15f} $c $c $c } {1.4444444444 1.444444444444 1.444444444443990} @@ -534,7 +534,7 @@ for {set i 0} {$i < 290} {incr i} { append b $a } for {set i 290} {$i < 400} {incr i} { - test format-16.[expr $i -289] {testing MAX_FLOAT_SIZE} { + test format-16.[expr {$i -289}] {testing MAX_FLOAT_SIZE} { format {%s} $b } $b append b "x" diff --git a/tests/httpold.test b/tests/httpold.test index e5d974c..67ab119 100644 --- a/tests/httpold.test +++ b/tests/httpold.test @@ -167,7 +167,7 @@ test httpold-4.1 {httpEvent} { set token [http_get $url] upvar #0 $token data array set meta $data(meta) - expr ($data(totalsize) == $meta(Content-Length)) + expr {$data(totalsize) == $meta(Content-Length)} } 1 test httpold-4.2 {httpEvent} { @@ -204,7 +204,7 @@ test httpold-4.5 {httpEvent} { close $out upvar #0 $token data removeFile $testfile - expr $data(currentsize) == $data(totalsize) + expr {$data(currentsize) == $data(totalsize)} } 1 test httpold-4.6 {httpEvent} { diff --git a/tests/info.test b/tests/info.test index fb9e0de..69be6a3 100644 --- a/tests/info.test +++ b/tests/info.test @@ -657,7 +657,7 @@ test info-19.6 {info vars: Bug 1072654} -setup { set functions {abs acos asin atan atan2 bool ceil cos cosh double entier exp floor fmod hypot int isqrt log log10 max min pow rand round sin sinh sqrt srand tan tanh wide} # Check whether the extra testing functions are defined... -if {!([catch {expr T1()} msg] && ($msg eq {invalid command name "tcl::mathfunc::T1"}))} { +if {!([catch {expr {T1()}} msg] && ($msg eq {invalid command name "tcl::mathfunc::T1"}))} { set functions "T1 T2 T3 $functions" ;# A lazy way of prepending! } test info-20.1 {info functions option} {info functions sin} sin diff --git a/tests/io.test b/tests/io.test index 8bf3303..a86527b 100644 --- a/tests/io.test +++ b/tests/io.test @@ -1943,11 +1943,11 @@ test io-17.1 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} eof stdin interp create x set l "" - lappend l [expr [testchannel refcount stdin] - $l1] + lappend l [expr {[testchannel refcount stdin] - $l1}] x eval {eof stdin} - lappend l [expr [testchannel refcount stdin] - $l1] + lappend l [expr {[testchannel refcount stdin] - $l1}] interp delete x - lappend l [expr [testchannel refcount stdin] - $l1] + lappend l [expr {[testchannel refcount stdin] - $l1}] set l } {0 1 0} test io-17.2 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} { @@ -1955,11 +1955,11 @@ test io-17.2 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} eof stdin interp create x set l "" - lappend l [expr [testchannel refcount stdout] - $l1] + lappend l [expr {[testchannel refcount stdout] - $l1}] x eval {eof stdout} - lappend l [expr [testchannel refcount stdout] - $l1] + lappend l [expr {[testchannel refcount stdout] - $l1}] interp delete x - lappend l [expr [testchannel refcount stdout] - $l1] + lappend l [expr {[testchannel refcount stdout] - $l1}] set l } {0 1 0} test io-17.3 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} { @@ -1967,11 +1967,11 @@ test io-17.3 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} eof stdin interp create x set l "" - lappend l [expr [testchannel refcount stderr] - $l1] + lappend l [expr {[testchannel refcount stderr] - $l1}] x eval {eof stderr} - lappend l [expr [testchannel refcount stderr] - $l1] + lappend l [expr {[testchannel refcount stderr] - $l1}] interp delete x - lappend l [expr [testchannel refcount stderr] - $l1] + lappend l [expr {[testchannel refcount stderr] - $l1}] set l } {0 1 0} @@ -2161,7 +2161,7 @@ test io-26.1 {Tcl_GetChannelInstanceData} stdio { # Don't care what pid is (but must be a number), just want to exercise it. set f [open "|[list [interpreter] << exit]"] - expr [pid $f] + expr {[pid $f]} close $f } {} @@ -3162,7 +3162,7 @@ test io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} { set c [read $f] close $f string length $c -} [expr 700*15+1] +} [expr {700*15+1}] test io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} { file delete $path(test1) set f [open $path(test1) w] @@ -3178,7 +3178,7 @@ test io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} { set c [read $f] close $f string length $c -} [expr 700*15+1] +} [expr {700*15+1}] test io-30.15 {Tcl_Write mixed, Tcl_Read auto} { file delete $path(test1) set f [open $path(test1) w] @@ -3996,7 +3996,7 @@ test io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} { } close $f string length $c -} [expr 700*15+1] +} [expr {700*15+1}] test io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} { file delete $path(test1) set f [open $path(test1) w] @@ -4015,7 +4015,7 @@ test io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} { } close $f string length $c -} [expr 700*15+1] +} [expr {700*15+1}] # Test Tcl_Read and buffering. @@ -5641,7 +5641,7 @@ test io-40.2 {POSIX open access modes: CREAT} {unix} { file delete $path(test3) set f [open $path(test3) {WRONLY CREAT} 0o600] file stat $path(test3) stats - set x [format "0o%o" [expr $stats(mode)&0o777]] + set x [format "0o%o" [expr {$stats(mode)&0o777}]] puts $f "line 1" close $f set f [open $path(test3) r] @@ -5655,7 +5655,7 @@ test io-40.3 {POSIX open access modes: CREAT} {unix umask} { set f [open $path(test3) {WRONLY CREAT}] close $f file stat $path(test3) stats - format "0o%03o" [expr $stats(mode)&0o777] + format "0o%03o" [expr {$stats(mode)&0o777}] } [format "0o%03o" [expr {0o666 & ~ $umaskValue}]] test io-40.4 {POSIX open access modes: CREAT} { file delete $path(test3) @@ -7093,7 +7093,7 @@ test io-52.6 {TclCopyChannel} {fcopy} { set f2 [open $path(test1) w] fconfigure $f1 -translation lf -blocking 0 fconfigure $f2 -translation lf -blocking 0 - set s0 [fcopy $f1 $f2 -size [expr [file size $thisScript] + 5]] + set s0 [fcopy $f1 $f2 -size [expr {[file size $thisScript] + 5}]] set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]] close $f1 close $f2 @@ -7589,7 +7589,7 @@ test io-53.7 {CopyData: Flooding fcopy from pipe} {stdio fcopy} { catch {close $in} close $out # -1=error 0=script error N=number of bytes - expr ($fcopyTestDone == 0) ? $fcopyTestCount : -1 + expr {($fcopyTestDone == 0) ? $fcopyTestCount : -1} } {3450} test io-53.8 {CopyData: async callback and error handling, Bug 1932639} -setup { # copy progress callback. errors out intentionally diff --git a/tests/lmap.test b/tests/lmap.test index 432e195..d986ee2 100644 --- a/tests/lmap.test +++ b/tests/lmap.test @@ -220,10 +220,10 @@ test lmap-4.14 {lmap errors} -returnCodes error -body { } -result {list element in braces followed by "3" instead of space} unset -nocomplain a test lmap-4.15 {lmap errors} { - apply {{} { + apply {{} { set a(0) 44 - list [catch {lmap a {1 2 3} {}} msg o] $msg $::errorInfo - }} + list [catch {lmap a {1 2 3} {}} msg o] $msg $::errorInfo + }} } {1 {can't set "a": variable is array} {can't set "a": variable is array while executing "lmap a {1 2 3} {}"}} @@ -357,7 +357,7 @@ test lmap-7.2 {noncompiled lmap and shared variable or value list objects that a } -body { lmap {12.0} {a b c} { set x 12.0 - set x [expr $x + 1] + set x [expr {$x + 1}] } } -result {13.0 13.0 13.0} # Test for incorrect "double evaluation" semantics diff --git a/tests/parse.test b/tests/parse.test index 4370acb..39f3d1e 100644 --- a/tests/parse.test +++ b/tests/parse.test @@ -278,7 +278,7 @@ test parse-6.9 {ParseTokens procedure, error in command substitution} { } {0} test parse-6.10 {ParseTokens procedure, incomplete sub-command} { info complete {puts [ - expr 1+1 + expr {1+1} #this is a comment ]} } {0} test parse-6.11 {ParseTokens procedure, memory allocation for big nested command} testparser { @@ -485,7 +485,7 @@ test parse-10.3 {Tcl_EvalTokens, nested commands} testevalex { } {8} test parse-10.4 {Tcl_EvalTokens, nested commands} testevalex { unset -nocomplain a - list [catch {testevalex {concat xxx[expr $a]}} msg] $msg + list [catch {testevalex {concat xxx[expr {$a}]}} msg] $msg } {1 {can't read "a": no such variable}} test parse-10.5 {Tcl_EvalTokens, simple variables} testevalex { set a hello @@ -518,7 +518,7 @@ test parse-10.11 {Tcl_EvalTokens, object values} testevalex { testevalex {concat $a$a$a} } {123123123} test parse-10.12 {Tcl_EvalTokens, object values} testevalex { - testevalex {concat [expr 2][expr 4][expr 6]} + testevalex {concat [expr {2}][expr {4}][expr {6}]} } {246} test parse-10.13 {Tcl_EvalTokens, string values} testevalex { testevalex {concat {a" b"}} @@ -984,26 +984,26 @@ test parse-18.14 {Tcl_SubstObj, exception handling} { subst {abc,[break],def} } {abc,} test parse-18.15 {Tcl_SubstObj, exception handling} { - subst {abc,[continue; expr 1+2],def} + subst {abc,[continue; expr {1+2}],def} } {abc,,def} test parse-18.16 {Tcl_SubstObj, exception handling} { - subst {abc,[return foo; expr 1+2],def} + subst {abc,[return foo; expr {1+2}],def} } {abc,foo,def} test parse-18.17 {Tcl_SubstObj, exception handling} { - subst {abc,[return -code 10 foo; expr 1+2],def} + subst {abc,[return -code 10 foo; expr {1+2}],def} } {abc,foo,def} test parse-18.18 {Tcl_SubstObj, exception handling} { subst {abc,[break; set {} {}{}],def} } {abc,} test parse-18.19 {Tcl_SubstObj, exception handling} { - list [catch {subst {abc,[continue; expr 1+2; set {} {}{}],def}} msg] $msg + list [catch {subst {abc,[continue; expr {1+2}; set {} {}{}],def}} msg] $msg } [list 1 "extra characters after close-brace"] test parse-18.20 {Tcl_SubstObj, exception handling} { - list [catch {subst {abc,[return foo; expr 1+2; set {} {}{}],def}} msg] $msg + list [catch {subst {abc,[return foo; expr {1+2}; set {} {}{}],def}} msg] $msg } [list 1 "extra characters after close-brace"] test parse-18.21 {Tcl_SubstObj, exception handling} { list [catch { - subst {abc,[return -code 10 foo; expr 1+2; set {} {}{}],def} + subst {abc,[return -code 10 foo; expr {1+2}; set {} {}{}],def} } msg] $msg } [list 1 "extra characters after close-brace"] diff --git a/tests/parseOld.test b/tests/parseOld.test index c2d7c23..0ac036b 100644 --- a/tests/parseOld.test +++ b/tests/parseOld.test @@ -455,14 +455,14 @@ test parseOld-12.4 {comments} { test parseOld-13.1 {comments at the end of a bracketed script} { set x "[ -expr 1+1 +expr {1+1} # skip this! ]" } {2} test parseOld-15.1 {TclScriptEnd procedure} { info complete {puts [ - expr 1+1 + expr {1+1} #this is a comment ]} } {0} test parseOld-15.2 {TclScriptEnd procedure} { diff --git a/tests/string.test b/tests/string.test index 46eb6fd..b1f9dc3 100644 --- a/tests/string.test +++ b/tests/string.test @@ -414,7 +414,7 @@ test string-6.27 {string is double, true} { string is double 1 } 1 test string-6.28 {string is double, true} { - string is double [expr double(1)] + string is double [expr {double(1)}] } 1 test string-6.29 {string is double, true} { string is double 1.0 @@ -489,7 +489,7 @@ test string-6.48 {string is integer, true} { string is integer +1234567890 } 1 test string-6.49 {string is integer, true on type} { - string is integer [expr int(50.0)] + string is integer [expr {int(50.0)}] } 1 test string-6.50 {string is integer, true} { string is integer [list -10] @@ -510,7 +510,7 @@ test string-6.55 {string is integer, false on overflow} { list [string is integer -fail var +[largest_int]0] $var } {0 -1} test string-6.56 {string is integer, false} { - list [string is integer -fail var [expr double(1)]] $var + list [string is integer -fail var [expr {double(1)}]] $var } {0 1} test string-6.57 {string is integer, false} { list [string is integer -fail var " "] $var @@ -659,7 +659,7 @@ test string-6.95 {string is wideinteger, true} { string is wideinteger +1234567890 } 1 test string-6.96 {string is wideinteger, true on type} { - string is wideinteger [expr wide(50.0)] + string is wideinteger [expr {wide(50.0)}] } 1 test string-6.97 {string is wideinteger, true} { string is wideinteger [list -10] @@ -680,7 +680,7 @@ test string-6.102 {string is wideinteger, false on overflow} { list [string is wideinteger -fail var +[largest_int]0] $var } {0 -1} test string-6.103 {string is wideinteger, false} { - list [string is wideinteger -fail var [expr double(1)]] $var + list [string is wideinteger -fail var [expr {double(1)}]] $var } {0 1} test string-6.104 {string is wideinteger, false} { list [string is wideinteger -fail var " "] $var @@ -715,7 +715,7 @@ test string-6.110 {string is entier, true} { string is entier +1234567890 } 1 test string-6.111 {string is entier, true on type} { - string is entier [expr wide(50.0)] + string is entier [expr {wide(50.0)}] } 1 test string-6.112 {string is entier, true} { string is entier [list -10] @@ -736,7 +736,7 @@ test string-6.117 {string is entier, false} { list [string is entier -fail var 123123123123123123123123123123123123123123123123123123123123123123123123123123123123abc] $var } {0 84} test string-6.118 {string is entier, false} { - list [string is entier -fail var [expr double(1)]] $var + list [string is entier -fail var [expr {double(1)}]] $var } {0 1} test string-6.119 {string is entier, false} { list [string is entier -fail var " "] $var diff --git a/tests/util.test b/tests/util.test index c8a081b..052e7d3 100644 --- a/tests/util.test +++ b/tests/util.test @@ -101,7 +101,7 @@ proc verdonk_test {sig binexp shouldbe exp} { regexp {([-+]?)([0-9a-f]+)} $sig -> signum sig scan $sig %llx sig if {$signum eq {-}} { - set signum [expr 1<<63] + set signum [expr {1<<63}] } else { set signum 0 } @@ -392,7 +392,7 @@ test util-6.1 {Tcl_PrintDouble - using tcl_precision} -setup { set old_precision $::tcl_precision set ::tcl_precision 12 } -body { - concat x[expr 1.4] + concat x[expr {1.4}] } -cleanup { set ::tcl_precision $old_precision } -result {x1.4} @@ -400,7 +400,7 @@ test util-6.2 {Tcl_PrintDouble - using tcl_precision} -setup { set old_precision $::tcl_precision set ::tcl_precision 12 } -body { - concat x[expr 1.39999999999] + concat x[expr {1.39999999999}] } -cleanup { set ::tcl_precision $old_precision } -result {x1.39999999999} @@ -408,7 +408,7 @@ test util-6.3 {Tcl_PrintDouble - using tcl_precision} -setup { set old_precision $::tcl_precision set ::tcl_precision 12 } -body { - concat x[expr 1.399999999999] + concat x[expr {1.399999999999}] } -cleanup { set ::tcl_precision $old_precision } -result {x1.4} @@ -416,15 +416,15 @@ test util-6.4 {Tcl_PrintDouble - using tcl_precision} -setup { set old_precision $::tcl_precision set ::tcl_precision 5 } -body { - concat x[expr 1.123412341234] + concat x[expr {1.123412341234}] } -cleanup { set tcl_precision $old_precision } -result {x1.1234} test util-6.5 {Tcl_PrintDouble - make sure there's a decimal point} { - concat x[expr 2.0] + concat x[expr {2.0}] } {x2.0} test util-6.6 {Tcl_PrintDouble - make sure there's a decimal point} { - concat x[expr 3.0e98] + concat x[expr {3.0e98}] } {x3e+98} test util-7.1 {TclPrecTraceProc - unset callbacks} -setup { @@ -1122,73 +1122,73 @@ test util-10.122 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} { } {5.20831059055e+36} test util-11.1 {Tcl_PrintDouble - scaling} { - expr 1.1e-5 + expr {1.1e-5} } {1.1e-5} test util-11.2 {Tcl_PrintDouble - scaling} { - expr 1.1e-4 + expr {1.1e-4} } {0.00011} test util-11.3 {Tcl_PrintDouble - scaling} { - expr 1.1e-3 + expr {1.1e-3} } {0.0011} test util-11.4 {Tcl_PrintDouble - scaling} { - expr 1.1e-2 + expr {1.1e-2} } {0.011} test util-11.5 {Tcl_PrintDouble - scaling} { - expr 1.1e-1 + expr {1.1e-1} } {0.11} test util-11.6 {Tcl_PrintDouble - scaling} { - expr 1.1e0 + expr {1.1e0} } {1.1} test util-11.7 {Tcl_PrintDouble - scaling} { - expr 1.1e1 + expr {1.1e1} } {11.0} test util-11.8 {Tcl_PrintDouble - scaling} { - expr 1.1e2 + expr {1.1e2} } {110.0} test util-11.9 {Tcl_PrintDouble - scaling} { - expr 1.1e3 + expr {1.1e3} } {1100.0} test util-11.10 {Tcl_PrintDouble - scaling} { - expr 1.1e4 + expr {1.1e4} } {11000.0} test util-11.11 {Tcl_PrintDouble - scaling} { - expr 1.1e5 + expr {1.1e5} } {110000.0} test util-11.12 {Tcl_PrintDouble - scaling} { - expr 1.1e6 + expr {1.1e6} } {1100000.0} test util-11.13 {Tcl_PrintDouble - scaling} { - expr 1.1e7 + expr {1.1e7} } {11000000.0} test util-11.14 {Tcl_PrintDouble - scaling} { - expr 1.1e8 + expr {1.1e8} } {110000000.0} test util-11.15 {Tcl_PrintDouble - scaling} { - expr 1.1e9 + expr {1.1e9} } {1100000000.0} test util-11.16 {Tcl_PrintDouble - scaling} { - expr 1.1e10 + expr {1.1e10} } {11000000000.0} test util-11.17 {Tcl_PrintDouble - scaling} { - expr 1.1e11 + expr {1.1e11} } {110000000000.0} test util-11.18 {Tcl_PrintDouble - scaling} { - expr 1.1e12 + expr {1.1e12} } {1100000000000.0} test util-11.19 {Tcl_PrintDouble - scaling} { - expr 1.1e13 + expr {1.1e13} } {11000000000000.0} test util-11.20 {Tcl_PrintDouble - scaling} { - expr 1.1e14 + expr {1.1e14} } {110000000000000.0} test util-11.21 {Tcl_PrintDouble - scaling} { - expr 1.1e15 + expr {1.1e15} } {1100000000000000.0} test util-11.22 {Tcl_PrintDouble - scaling} { - expr 1.1e16 + expr {1.1e16} } {11000000000000000.0} test util-11.23 {Tcl_PrintDouble - scaling} { - expr 1.1e17 + expr {1.1e17} } {1.1e+17} test util-12.1 {TclDoubleDigits - Inf} {testdoubledigits ieeeFloatingPoint} { @@ -2166,1869 +2166,1869 @@ set saved_precision $::tcl_precision foreach ::tcl_precision {0 12} { for {set e -312} {$e < -9} {incr e} { test util-16.1.$::tcl_precision.$e {shortening of numbers} \ - "expr 1.1e$e" 1.1e$e + "expr {1.1e$e}" 1.1e$e } } set tcl_precision 0 for {set e -9} {$e < -4} {incr e} { test util-16.1.$::tcl_precision.$e {shortening of numbers} \ - "expr 1.1e$e" 1.1e$e + "expr {1.1e$e}" 1.1e$e } set tcl_precision 12 for {set e -9} {$e < -4} {incr e} { test util-16.1.$::tcl_precision.$e {8.4 compatible formatting of doubles} \ - "expr 1.1e$e" 1.1e[format %+03d $e] + "expr {1.1e$e}" 1.1e[format %+03d $e] } foreach ::tcl_precision {0 12} { test util-16.1.$::tcl_precision.-4 {shortening of numbers} \ - {expr 1.1e-4} \ + {expr {1.1e-4}} \ 0.00011 test util-16.1.$::tcl_precision.-3 {shortening of numbers} \ - {expr 1.1e-3} \ + {expr {1.1e-3}} \ 0.0011 test util-16.1.$::tcl_precision.-2 {shortening of numbers} \ - {expr 1.1e-2} \ + {expr {1.1e-2}} \ 0.011 test util-16.1.$::tcl_precision.-1 {shortening of numbers} \ - {expr 1.1e-1} \ + {expr {1.1e-1}} \ 0.11 test util-16.1.$::tcl_precision.0 {shortening of numbers} \ - {expr 1.1} \ + {expr {1.1}} \ 1.1 for {set e 1} {$e < 17} {incr e} { test util-16.1.$::tcl_precision.$e {shortening of numbers} \ - "expr 11[string repeat 0 [expr {$e-1}]].0" \ + "expr {11[string repeat 0 [expr {$e-1}]].0}" \ 11[string repeat 0 [expr {$e-1}]].0 } for {set e 17} {$e < 309} {incr e} { test util-16.1.$::tcl_precision.$e {shortening of numbers} \ - "expr 1.1e$e" 1.1e+$e + "expr {1.1e$e}" 1.1e+$e } } set tcl_precision 17 test util-16.1.17.-300 {8.4 compatible formatting of doubles} \ - {expr 1e-300} \ + {expr {1e-300}} \ 1e-300 test util-16.1.17.-299 {8.4 compatible formatting of doubles} \ - {expr 1e-299} \ + {expr {1e-299}} \ 9.9999999999999999e-300 test util-16.1.17.-298 {8.4 compatible formatting of doubles} \ - {expr 1e-298} \ + {expr {1e-298}} \ 9.9999999999999991e-299 test util-16.1.17.-297 {8.4 compatible formatting of doubles} \ - {expr 1e-297} \ + {expr {1e-297}} \ 1e-297 test util-16.1.17.-296 {8.4 compatible formatting of doubles} \ - {expr 1e-296} \ + {expr {1e-296}} \ 1e-296 test util-16.1.17.-295 {8.4 compatible formatting of doubles} \ - {expr 1e-295} \ + {expr {1e-295}} \ 1.0000000000000001e-295 test util-16.1.17.-294 {8.4 compatible formatting of doubles} \ - {expr 1e-294} \ + {expr {1e-294}} \ 1e-294 test util-16.1.17.-293 {8.4 compatible formatting of doubles} \ - {expr 1e-293} \ + {expr {1e-293}} \ 1.0000000000000001e-293 test util-16.1.17.-292 {8.4 compatible formatting of doubles} \ - {expr 1e-292} \ + {expr {1e-292}} \ 1.0000000000000001e-292 test util-16.1.17.-291 {8.4 compatible formatting of doubles} \ - {expr 1e-291} \ + {expr {1e-291}} \ 9.9999999999999996e-292 test util-16.1.17.-290 {8.4 compatible formatting of doubles} \ - {expr 1e-290} \ + {expr {1e-290}} \ 1.0000000000000001e-290 test util-16.1.17.-289 {8.4 compatible formatting of doubles} \ - {expr 1e-289} \ + {expr {1e-289}} \ 1e-289 test util-16.1.17.-288 {8.4 compatible formatting of doubles} \ - {expr 1e-288} \ + {expr {1e-288}} \ 1.0000000000000001e-288 test util-16.1.17.-287 {8.4 compatible formatting of doubles} \ - {expr 1e-287} \ + {expr {1e-287}} \ 1e-287 test util-16.1.17.-286 {8.4 compatible formatting of doubles} \ - {expr 1e-286} \ + {expr {1e-286}} \ 1.0000000000000001e-286 test util-16.1.17.-285 {8.4 compatible formatting of doubles} \ - {expr 1e-285} \ + {expr {1e-285}} \ 1.0000000000000001e-285 test util-16.1.17.-284 {8.4 compatible formatting of doubles} \ - {expr 1e-284} \ + {expr {1e-284}} \ 1e-284 test util-16.1.17.-283 {8.4 compatible formatting of doubles} \ - {expr 1e-283} \ + {expr {1e-283}} \ 9.9999999999999995e-284 test util-16.1.17.-282 {8.4 compatible formatting of doubles} \ - {expr 1e-282} \ + {expr {1e-282}} \ 1e-282 test util-16.1.17.-281 {8.4 compatible formatting of doubles} \ - {expr 1e-281} \ + {expr {1e-281}} \ 1e-281 test util-16.1.17.-280 {8.4 compatible formatting of doubles} \ - {expr 1e-280} \ + {expr {1e-280}} \ 9.9999999999999996e-281 test util-16.1.17.-279 {8.4 compatible formatting of doubles} \ - {expr 1e-279} \ + {expr {1e-279}} \ 1.0000000000000001e-279 test util-16.1.17.-278 {8.4 compatible formatting of doubles} \ - {expr 1e-278} \ + {expr {1e-278}} \ 9.9999999999999994e-279 test util-16.1.17.-277 {8.4 compatible formatting of doubles} \ - {expr 1e-277} \ + {expr {1e-277}} \ 9.9999999999999997e-278 test util-16.1.17.-276 {8.4 compatible formatting of doubles} \ - {expr 1e-276} \ + {expr {1e-276}} \ 1.0000000000000001e-276 test util-16.1.17.-275 {8.4 compatible formatting of doubles} \ - {expr 1e-275} \ + {expr {1e-275}} \ 9.9999999999999993e-276 test util-16.1.17.-274 {8.4 compatible formatting of doubles} \ - {expr 1e-274} \ + {expr {1e-274}} \ 9.9999999999999997e-275 test util-16.1.17.-273 {8.4 compatible formatting of doubles} \ - {expr 1e-273} \ + {expr {1e-273}} \ 1.0000000000000001e-273 test util-16.1.17.-272 {8.4 compatible formatting of doubles} \ - {expr 1e-272} \ + {expr {1e-272}} \ 9.9999999999999993e-273 test util-16.1.17.-271 {8.4 compatible formatting of doubles} \ - {expr 1e-271} \ + {expr {1e-271}} \ 9.9999999999999996e-272 test util-16.1.17.-270 {8.4 compatible formatting of doubles} \ - {expr 1e-270} \ + {expr {1e-270}} \ 1e-270 test util-16.1.17.-269 {8.4 compatible formatting of doubles} \ - {expr 1e-269} \ + {expr {1e-269}} \ 9.9999999999999996e-270 test util-16.1.17.-268 {8.4 compatible formatting of doubles} \ - {expr 1e-268} \ + {expr {1e-268}} \ 9.9999999999999996e-269 test util-16.1.17.-267 {8.4 compatible formatting of doubles} \ - {expr 1e-267} \ + {expr {1e-267}} \ 9.9999999999999998e-268 test util-16.1.17.-266 {8.4 compatible formatting of doubles} \ - {expr 1e-266} \ + {expr {1e-266}} \ 9.9999999999999998e-267 test util-16.1.17.-265 {8.4 compatible formatting of doubles} \ - {expr 1e-265} \ + {expr {1e-265}} \ 9.9999999999999998e-266 test util-16.1.17.-264 {8.4 compatible formatting of doubles} \ - {expr 1e-264} \ + {expr {1e-264}} \ 1e-264 test util-16.1.17.-263 {8.4 compatible formatting of doubles} \ - {expr 1e-263} \ + {expr {1e-263}} \ 1e-263 test util-16.1.17.-262 {8.4 compatible formatting of doubles} \ - {expr 1e-262} \ + {expr {1e-262}} \ 1e-262 test util-16.1.17.-261 {8.4 compatible formatting of doubles} \ - {expr 1e-261} \ + {expr {1e-261}} \ 9.9999999999999998e-262 test util-16.1.17.-260 {8.4 compatible formatting of doubles} \ - {expr 1e-260} \ + {expr {1e-260}} \ 9.9999999999999996e-261 test util-16.1.17.-259 {8.4 compatible formatting of doubles} \ - {expr 1e-259} \ + {expr {1e-259}} \ 1.0000000000000001e-259 test util-16.1.17.-258 {8.4 compatible formatting of doubles} \ - {expr 1e-258} \ + {expr {1e-258}} \ 9.9999999999999995e-259 test util-16.1.17.-257 {8.4 compatible formatting of doubles} \ - {expr 1e-257} \ + {expr {1e-257}} \ 9.9999999999999998e-258 test util-16.1.17.-256 {8.4 compatible formatting of doubles} \ - {expr 1e-256} \ + {expr {1e-256}} \ 9.9999999999999998e-257 test util-16.1.17.-255 {8.4 compatible formatting of doubles} \ - {expr 1e-255} \ + {expr {1e-255}} \ 1e-255 test util-16.1.17.-254 {8.4 compatible formatting of doubles} \ - {expr 1e-254} \ + {expr {1e-254}} \ 9.9999999999999991e-255 test util-16.1.17.-253 {8.4 compatible formatting of doubles} \ - {expr 1e-253} \ + {expr {1e-253}} \ 1.0000000000000001e-253 test util-16.1.17.-252 {8.4 compatible formatting of doubles} \ - {expr 1e-252} \ + {expr {1e-252}} \ 9.9999999999999994e-253 test util-16.1.17.-251 {8.4 compatible formatting of doubles} \ - {expr 1e-251} \ + {expr {1e-251}} \ 1e-251 test util-16.1.17.-250 {8.4 compatible formatting of doubles} \ - {expr 1e-250} \ + {expr {1e-250}} \ 1.0000000000000001e-250 test util-16.1.17.-249 {8.4 compatible formatting of doubles} \ - {expr 1e-249} \ + {expr {1e-249}} \ 1.0000000000000001e-249 test util-16.1.17.-248 {8.4 compatible formatting of doubles} \ - {expr 1e-248} \ + {expr {1e-248}} \ 9.9999999999999998e-249 test util-16.1.17.-247 {8.4 compatible formatting of doubles} \ - {expr 1e-247} \ + {expr {1e-247}} \ 1e-247 test util-16.1.17.-246 {8.4 compatible formatting of doubles} \ - {expr 1e-246} \ + {expr {1e-246}} \ 9.9999999999999996e-247 test util-16.1.17.-245 {8.4 compatible formatting of doubles} \ - {expr 1e-245} \ + {expr {1e-245}} \ 9.9999999999999993e-246 test util-16.1.17.-244 {8.4 compatible formatting of doubles} \ - {expr 1e-244} \ + {expr {1e-244}} \ 9.9999999999999993e-245 test util-16.1.17.-243 {8.4 compatible formatting of doubles} \ - {expr 1e-243} \ + {expr {1e-243}} \ 1e-243 test util-16.1.17.-242 {8.4 compatible formatting of doubles} \ - {expr 1e-242} \ + {expr {1e-242}} \ 9.9999999999999997e-243 test util-16.1.17.-241 {8.4 compatible formatting of doubles} \ - {expr 1e-241} \ + {expr {1e-241}} \ 9.9999999999999997e-242 test util-16.1.17.-240 {8.4 compatible formatting of doubles} \ - {expr 1e-240} \ + {expr {1e-240}} \ 9.9999999999999997e-241 test util-16.1.17.-239 {8.4 compatible formatting of doubles} \ - {expr 1e-239} \ + {expr {1e-239}} \ 1.0000000000000001e-239 test util-16.1.17.-238 {8.4 compatible formatting of doubles} \ - {expr 1e-238} \ + {expr {1e-238}} \ 9.9999999999999999e-239 test util-16.1.17.-237 {8.4 compatible formatting of doubles} \ - {expr 1e-237} \ + {expr {1e-237}} \ 9.9999999999999999e-238 test util-16.1.17.-236 {8.4 compatible formatting of doubles} \ - {expr 1e-236} \ + {expr {1e-236}} \ 1e-236 test util-16.1.17.-235 {8.4 compatible formatting of doubles} \ - {expr 1e-235} \ + {expr {1e-235}} \ 9.9999999999999996e-236 test util-16.1.17.-234 {8.4 compatible formatting of doubles} \ - {expr 1e-234} \ + {expr {1e-234}} \ 9.9999999999999996e-235 test util-16.1.17.-233 {8.4 compatible formatting of doubles} \ - {expr 1e-233} \ + {expr {1e-233}} \ 9.9999999999999996e-234 test util-16.1.17.-232 {8.4 compatible formatting of doubles} \ - {expr 1e-232} \ + {expr {1e-232}} \ 1e-232 test util-16.1.17.-231 {8.4 compatible formatting of doubles} \ - {expr 1e-231} \ + {expr {1e-231}} \ 9.9999999999999999e-232 test util-16.1.17.-230 {8.4 compatible formatting of doubles} \ - {expr 1e-230} \ + {expr {1e-230}} \ 1e-230 test util-16.1.17.-229 {8.4 compatible formatting of doubles} \ - {expr 1e-229} \ + {expr {1e-229}} \ 1.0000000000000001e-229 test util-16.1.17.-228 {8.4 compatible formatting of doubles} \ - {expr 1e-228} \ + {expr {1e-228}} \ 1e-228 test util-16.1.17.-227 {8.4 compatible formatting of doubles} \ - {expr 1e-227} \ + {expr {1e-227}} \ 9.9999999999999994e-228 test util-16.1.17.-226 {8.4 compatible formatting of doubles} \ - {expr 1e-226} \ + {expr {1e-226}} \ 9.9999999999999992e-227 test util-16.1.17.-225 {8.4 compatible formatting of doubles} \ - {expr 1e-225} \ + {expr {1e-225}} \ 9.9999999999999996e-226 test util-16.1.17.-224 {8.4 compatible formatting of doubles} \ - {expr 1e-224} \ + {expr {1e-224}} \ 1e-224 test util-16.1.17.-223 {8.4 compatible formatting of doubles} \ - {expr 1e-223} \ + {expr {1e-223}} \ 9.9999999999999997e-224 test util-16.1.17.-222 {8.4 compatible formatting of doubles} \ - {expr 1e-222} \ + {expr {1e-222}} \ 1e-222 test util-16.1.17.-221 {8.4 compatible formatting of doubles} \ - {expr 1e-221} \ + {expr {1e-221}} \ 1e-221 test util-16.1.17.-220 {8.4 compatible formatting of doubles} \ - {expr 1e-220} \ + {expr {1e-220}} \ 9.9999999999999999e-221 test util-16.1.17.-219 {8.4 compatible formatting of doubles} \ - {expr 1e-219} \ + {expr {1e-219}} \ 1e-219 test util-16.1.17.-218 {8.4 compatible formatting of doubles} \ - {expr 1e-218} \ + {expr {1e-218}} \ 1e-218 test util-16.1.17.-217 {8.4 compatible formatting of doubles} \ - {expr 1e-217} \ + {expr {1e-217}} \ 1.0000000000000001e-217 test util-16.1.17.-216 {8.4 compatible formatting of doubles} \ - {expr 1e-216} \ + {expr {1e-216}} \ 1e-216 test util-16.1.17.-215 {8.4 compatible formatting of doubles} \ - {expr 1e-215} \ + {expr {1e-215}} \ 1e-215 test util-16.1.17.-214 {8.4 compatible formatting of doubles} \ - {expr 1e-214} \ + {expr {1e-214}} \ 9.9999999999999991e-215 test util-16.1.17.-213 {8.4 compatible formatting of doubles} \ - {expr 1e-213} \ + {expr {1e-213}} \ 9.9999999999999995e-214 test util-16.1.17.-212 {8.4 compatible formatting of doubles} \ - {expr 1e-212} \ + {expr {1e-212}} \ 9.9999999999999995e-213 test util-16.1.17.-211 {8.4 compatible formatting of doubles} \ - {expr 1e-211} \ + {expr {1e-211}} \ 1.0000000000000001e-211 test util-16.1.17.-210 {8.4 compatible formatting of doubles} \ - {expr 1e-210} \ + {expr {1e-210}} \ 1e-210 test util-16.1.17.-209 {8.4 compatible formatting of doubles} \ - {expr 1e-209} \ + {expr {1e-209}} \ 1e-209 test util-16.1.17.-208 {8.4 compatible formatting of doubles} \ - {expr 1e-208} \ + {expr {1e-208}} \ 1.0000000000000001e-208 test util-16.1.17.-207 {8.4 compatible formatting of doubles} \ - {expr 1e-207} \ + {expr {1e-207}} \ 9.9999999999999993e-208 test util-16.1.17.-206 {8.4 compatible formatting of doubles} \ - {expr 1e-206} \ + {expr {1e-206}} \ 1e-206 test util-16.1.17.-205 {8.4 compatible formatting of doubles} \ - {expr 1e-205} \ + {expr {1e-205}} \ 1e-205 test util-16.1.17.-204 {8.4 compatible formatting of doubles} \ - {expr 1e-204} \ + {expr {1e-204}} \ 1e-204 test util-16.1.17.-203 {8.4 compatible formatting of doubles} \ - {expr 1e-203} \ + {expr {1e-203}} \ 1e-203 test util-16.1.17.-202 {8.4 compatible formatting of doubles} \ - {expr 1e-202} \ + {expr {1e-202}} \ 1e-202 test util-16.1.17.-201 {8.4 compatible formatting of doubles} \ - {expr 1e-201} \ + {expr {1e-201}} \ 9.9999999999999995e-202 test util-16.1.17.-200 {8.4 compatible formatting of doubles} \ - {expr 1e-200} \ + {expr {1e-200}} \ 9.9999999999999998e-201 test util-16.1.17.-199 {8.4 compatible formatting of doubles} \ - {expr 1e-199} \ + {expr {1e-199}} \ 9.9999999999999998e-200 test util-16.1.17.-198 {8.4 compatible formatting of doubles} \ - {expr 1e-198} \ + {expr {1e-198}} \ 9.9999999999999991e-199 test util-16.1.17.-197 {8.4 compatible formatting of doubles} \ - {expr 1e-197} \ + {expr {1e-197}} \ 9.9999999999999999e-198 test util-16.1.17.-196 {8.4 compatible formatting of doubles} \ - {expr 1e-196} \ + {expr {1e-196}} \ 1e-196 test util-16.1.17.-195 {8.4 compatible formatting of doubles} \ - {expr 1e-195} \ + {expr {1e-195}} \ 1.0000000000000001e-195 test util-16.1.17.-194 {8.4 compatible formatting of doubles} \ - {expr 1e-194} \ + {expr {1e-194}} \ 1e-194 test util-16.1.17.-193 {8.4 compatible formatting of doubles} \ - {expr 1e-193} \ + {expr {1e-193}} \ 1e-193 test util-16.1.17.-192 {8.4 compatible formatting of doubles} \ - {expr 1e-192} \ + {expr {1e-192}} \ 1.0000000000000001e-192 test util-16.1.17.-191 {8.4 compatible formatting of doubles} \ - {expr 1e-191} \ + {expr {1e-191}} \ 1e-191 test util-16.1.17.-190 {8.4 compatible formatting of doubles} \ - {expr 1e-190} \ + {expr {1e-190}} \ 1e-190 test util-16.1.17.-189 {8.4 compatible formatting of doubles} \ - {expr 1e-189} \ + {expr {1e-189}} \ 1.0000000000000001e-189 test util-16.1.17.-188 {8.4 compatible formatting of doubles} \ - {expr 1e-188} \ + {expr {1e-188}} \ 9.9999999999999995e-189 test util-16.1.17.-187 {8.4 compatible formatting of doubles} \ - {expr 1e-187} \ + {expr {1e-187}} \ 1e-187 test util-16.1.17.-186 {8.4 compatible formatting of doubles} \ - {expr 1e-186} \ + {expr {1e-186}} \ 9.9999999999999991e-187 test util-16.1.17.-185 {8.4 compatible formatting of doubles} \ - {expr 1e-185} \ + {expr {1e-185}} \ 9.9999999999999999e-186 test util-16.1.17.-184 {8.4 compatible formatting of doubles} \ - {expr 1e-184} \ + {expr {1e-184}} \ 1.0000000000000001e-184 test util-16.1.17.-183 {8.4 compatible formatting of doubles} \ - {expr 1e-183} \ + {expr {1e-183}} \ 1e-183 test util-16.1.17.-182 {8.4 compatible formatting of doubles} \ - {expr 1e-182} \ + {expr {1e-182}} \ 1e-182 test util-16.1.17.-181 {8.4 compatible formatting of doubles} \ - {expr 1e-181} \ + {expr {1e-181}} \ 1e-181 test util-16.1.17.-180 {8.4 compatible formatting of doubles} \ - {expr 1e-180} \ + {expr {1e-180}} \ 1e-180 test util-16.1.17.-179 {8.4 compatible formatting of doubles} \ - {expr 1e-179} \ + {expr {1e-179}} \ 1e-179 test util-16.1.17.-178 {8.4 compatible formatting of doubles} \ - {expr 1e-178} \ + {expr {1e-178}} \ 9.9999999999999995e-179 test util-16.1.17.-177 {8.4 compatible formatting of doubles} \ - {expr 1e-177} \ + {expr {1e-177}} \ 9.9999999999999995e-178 test util-16.1.17.-176 {8.4 compatible formatting of doubles} \ - {expr 1e-176} \ + {expr {1e-176}} \ 1e-176 test util-16.1.17.-175 {8.4 compatible formatting of doubles} \ - {expr 1e-175} \ + {expr {1e-175}} \ 1e-175 test util-16.1.17.-174 {8.4 compatible formatting of doubles} \ - {expr 1e-174} \ + {expr {1e-174}} \ 1e-174 test util-16.1.17.-173 {8.4 compatible formatting of doubles} \ - {expr 1e-173} \ + {expr {1e-173}} \ 1e-173 test util-16.1.17.-172 {8.4 compatible formatting of doubles} \ - {expr 1e-172} \ + {expr {1e-172}} \ 1e-172 test util-16.1.17.-171 {8.4 compatible formatting of doubles} \ - {expr 1e-171} \ + {expr {1e-171}} \ 9.9999999999999998e-172 test util-16.1.17.-170 {8.4 compatible formatting of doubles} \ - {expr 1e-170} \ + {expr {1e-170}} \ 9.9999999999999998e-171 test util-16.1.17.-169 {8.4 compatible formatting of doubles} \ - {expr 1e-169} \ + {expr {1e-169}} \ 1e-169 test util-16.1.17.-168 {8.4 compatible formatting of doubles} \ - {expr 1e-168} \ + {expr {1e-168}} \ 1e-168 test util-16.1.17.-167 {8.4 compatible formatting of doubles} \ - {expr 1e-167} \ + {expr {1e-167}} \ 1e-167 test util-16.1.17.-166 {8.4 compatible formatting of doubles} \ - {expr 1e-166} \ + {expr {1e-166}} \ 1e-166 test util-16.1.17.-165 {8.4 compatible formatting of doubles} \ - {expr 1e-165} \ + {expr {1e-165}} \ 1e-165 test util-16.1.17.-164 {8.4 compatible formatting of doubles} \ - {expr 1e-164} \ + {expr {1e-164}} \ 9.9999999999999996e-165 test util-16.1.17.-163 {8.4 compatible formatting of doubles} \ - {expr 1e-163} \ + {expr {1e-163}} \ 9.9999999999999992e-164 test util-16.1.17.-162 {8.4 compatible formatting of doubles} \ - {expr 1e-162} \ + {expr {1e-162}} \ 9.9999999999999995e-163 test util-16.1.17.-161 {8.4 compatible formatting of doubles} \ - {expr 1e-161} \ + {expr {1e-161}} \ 1e-161 test util-16.1.17.-160 {8.4 compatible formatting of doubles} \ - {expr 1e-160} \ + {expr {1e-160}} \ 9.9999999999999999e-161 test util-16.1.17.-159 {8.4 compatible formatting of doubles} \ - {expr 1e-159} \ + {expr {1e-159}} \ 9.9999999999999999e-160 test util-16.1.17.-158 {8.4 compatible formatting of doubles} \ - {expr 1e-158} \ + {expr {1e-158}} \ 1.0000000000000001e-158 test util-16.1.17.-157 {8.4 compatible formatting of doubles} \ - {expr 1e-157} \ + {expr {1e-157}} \ 9.9999999999999994e-158 test util-16.1.17.-156 {8.4 compatible formatting of doubles} \ - {expr 1e-156} \ + {expr {1e-156}} \ 1e-156 test util-16.1.17.-155 {8.4 compatible formatting of doubles} \ - {expr 1e-155} \ + {expr {1e-155}} \ 1e-155 test util-16.1.17.-154 {8.4 compatible formatting of doubles} \ - {expr 1e-154} \ + {expr {1e-154}} \ 9.9999999999999997e-155 test util-16.1.17.-153 {8.4 compatible formatting of doubles} \ - {expr 1e-153} \ + {expr {1e-153}} \ 1e-153 test util-16.1.17.-152 {8.4 compatible formatting of doubles} \ - {expr 1e-152} \ + {expr {1e-152}} \ 1.0000000000000001e-152 test util-16.1.17.-151 {8.4 compatible formatting of doubles} \ - {expr 1e-151} \ + {expr {1e-151}} \ 9.9999999999999994e-152 test util-16.1.17.-150 {8.4 compatible formatting of doubles} \ - {expr 1e-150} \ + {expr {1e-150}} \ 1e-150 test util-16.1.17.-149 {8.4 compatible formatting of doubles} \ - {expr 1e-149} \ + {expr {1e-149}} \ 9.9999999999999998e-150 test util-16.1.17.-148 {8.4 compatible formatting of doubles} \ - {expr 1e-148} \ + {expr {1e-148}} \ 9.9999999999999994e-149 test util-16.1.17.-147 {8.4 compatible formatting of doubles} \ - {expr 1e-147} \ + {expr {1e-147}} \ 9.9999999999999997e-148 test util-16.1.17.-146 {8.4 compatible formatting of doubles} \ - {expr 1e-146} \ + {expr {1e-146}} \ 1e-146 test util-16.1.17.-145 {8.4 compatible formatting of doubles} \ - {expr 1e-145} \ + {expr {1e-145}} \ 9.9999999999999991e-146 test util-16.1.17.-144 {8.4 compatible formatting of doubles} \ - {expr 1e-144} \ + {expr {1e-144}} \ 9.9999999999999995e-145 test util-16.1.17.-143 {8.4 compatible formatting of doubles} \ - {expr 1e-143} \ + {expr {1e-143}} \ 9.9999999999999995e-144 test util-16.1.17.-142 {8.4 compatible formatting of doubles} \ - {expr 1e-142} \ + {expr {1e-142}} \ 1e-142 test util-16.1.17.-141 {8.4 compatible formatting of doubles} \ - {expr 1e-141} \ + {expr {1e-141}} \ 1e-141 test util-16.1.17.-140 {8.4 compatible formatting of doubles} \ - {expr 1e-140} \ + {expr {1e-140}} \ 9.9999999999999998e-141 test util-16.1.17.-139 {8.4 compatible formatting of doubles} \ - {expr 1e-139} \ + {expr {1e-139}} \ 1e-139 test util-16.1.17.-138 {8.4 compatible formatting of doubles} \ - {expr 1e-138} \ + {expr {1e-138}} \ 1.0000000000000001e-138 test util-16.1.17.-137 {8.4 compatible formatting of doubles} \ - {expr 1e-137} \ + {expr {1e-137}} \ 9.9999999999999998e-138 test util-16.1.17.-136 {8.4 compatible formatting of doubles} \ - {expr 1e-136} \ + {expr {1e-136}} \ 1e-136 test util-16.1.17.-135 {8.4 compatible formatting of doubles} \ - {expr 1e-135} \ + {expr {1e-135}} \ 1e-135 test util-16.1.17.-134 {8.4 compatible formatting of doubles} \ - {expr 1e-134} \ + {expr {1e-134}} \ 1e-134 test util-16.1.17.-133 {8.4 compatible formatting of doubles} \ - {expr 1e-133} \ + {expr {1e-133}} \ 1.0000000000000001e-133 test util-16.1.17.-132 {8.4 compatible formatting of doubles} \ - {expr 1e-132} \ + {expr {1e-132}} \ 9.9999999999999999e-133 test util-16.1.17.-131 {8.4 compatible formatting of doubles} \ - {expr 1e-131} \ + {expr {1e-131}} \ 9.9999999999999999e-132 test util-16.1.17.-130 {8.4 compatible formatting of doubles} \ - {expr 1e-130} \ + {expr {1e-130}} \ 1.0000000000000001e-130 test util-16.1.17.-129 {8.4 compatible formatting of doubles} \ - {expr 1e-129} \ + {expr {1e-129}} \ 9.9999999999999993e-130 test util-16.1.17.-128 {8.4 compatible formatting of doubles} \ - {expr 1e-128} \ + {expr {1e-128}} \ 1.0000000000000001e-128 test util-16.1.17.-127 {8.4 compatible formatting of doubles} \ - {expr 1e-127} \ + {expr {1e-127}} \ 1e-127 test util-16.1.17.-126 {8.4 compatible formatting of doubles} \ - {expr 1e-126} \ + {expr {1e-126}} \ 9.9999999999999995e-127 test util-16.1.17.-125 {8.4 compatible formatting of doubles} \ - {expr 1e-125} \ + {expr {1e-125}} \ 1e-125 test util-16.1.17.-124 {8.4 compatible formatting of doubles} \ - {expr 1e-124} \ + {expr {1e-124}} \ 9.9999999999999993e-125 test util-16.1.17.-123 {8.4 compatible formatting of doubles} \ - {expr 1e-123} \ + {expr {1e-123}} \ 1.0000000000000001e-123 test util-16.1.17.-122 {8.4 compatible formatting of doubles} \ - {expr 1e-122} \ + {expr {1e-122}} \ 1.0000000000000001e-122 test util-16.1.17.-121 {8.4 compatible formatting of doubles} \ - {expr 1e-121} \ + {expr {1e-121}} \ 9.9999999999999998e-122 test util-16.1.17.-120 {8.4 compatible formatting of doubles} \ - {expr 1e-120} \ + {expr {1e-120}} \ 9.9999999999999998e-121 test util-16.1.17.-119 {8.4 compatible formatting of doubles} \ - {expr 1e-119} \ + {expr {1e-119}} \ 1e-119 test util-16.1.17.-118 {8.4 compatible formatting of doubles} \ - {expr 1e-118} \ + {expr {1e-118}} \ 9.9999999999999999e-119 test util-16.1.17.-117 {8.4 compatible formatting of doubles} \ - {expr 1e-117} \ + {expr {1e-117}} \ 1e-117 test util-16.1.17.-116 {8.4 compatible formatting of doubles} \ - {expr 1e-116} \ + {expr {1e-116}} \ 9.9999999999999999e-117 test util-16.1.17.-115 {8.4 compatible formatting of doubles} \ - {expr 1e-115} \ + {expr {1e-115}} \ 1.0000000000000001e-115 test util-16.1.17.-114 {8.4 compatible formatting of doubles} \ - {expr 1e-114} \ + {expr {1e-114}} \ 1.0000000000000001e-114 test util-16.1.17.-113 {8.4 compatible formatting of doubles} \ - {expr 1e-113} \ + {expr {1e-113}} \ 9.9999999999999998e-114 test util-16.1.17.-112 {8.4 compatible formatting of doubles} \ - {expr 1e-112} \ + {expr {1e-112}} \ 9.9999999999999995e-113 test util-16.1.17.-111 {8.4 compatible formatting of doubles} \ - {expr 1e-111} \ + {expr {1e-111}} \ 1.0000000000000001e-111 test util-16.1.17.-110 {8.4 compatible formatting of doubles} \ - {expr 1e-110} \ + {expr {1e-110}} \ 1.0000000000000001e-110 test util-16.1.17.-109 {8.4 compatible formatting of doubles} \ - {expr 1e-109} \ + {expr {1e-109}} \ 9.9999999999999999e-110 test util-16.1.17.-108 {8.4 compatible formatting of doubles} \ - {expr 1e-108} \ + {expr {1e-108}} \ 1e-108 test util-16.1.17.-107 {8.4 compatible formatting of doubles} \ - {expr 1e-107} \ + {expr {1e-107}} \ 1e-107 test util-16.1.17.-106 {8.4 compatible formatting of doubles} \ - {expr 1e-106} \ + {expr {1e-106}} \ 9.9999999999999994e-107 test util-16.1.17.-105 {8.4 compatible formatting of doubles} \ - {expr 1e-105} \ + {expr {1e-105}} \ 9.9999999999999997e-106 test util-16.1.17.-104 {8.4 compatible formatting of doubles} \ - {expr 1e-104} \ + {expr {1e-104}} \ 9.9999999999999993e-105 test util-16.1.17.-103 {8.4 compatible formatting of doubles} \ - {expr 1e-103} \ + {expr {1e-103}} \ 9.9999999999999996e-104 test util-16.1.17.-102 {8.4 compatible formatting of doubles} \ - {expr 1e-102} \ + {expr {1e-102}} \ 9.9999999999999993e-103 test util-16.1.17.-101 {8.4 compatible formatting of doubles} \ - {expr 1e-101} \ + {expr {1e-101}} \ 1.0000000000000001e-101 test util-16.1.17.-100 {8.4 compatible formatting of doubles} \ - {expr 1e-100} \ + {expr {1e-100}} \ 1e-100 test util-16.1.17.-99 {8.4 compatible formatting of doubles} \ - {expr 1e-99} \ + {expr {1e-99}} \ 1e-99 test util-16.1.17.-98 {8.4 compatible formatting of doubles} \ - {expr 1e-98} \ + {expr {1e-98}} \ 9.9999999999999994e-99 test util-16.1.17.-97 {8.4 compatible formatting of doubles} \ - {expr 1e-97} \ + {expr {1e-97}} \ 1e-97 test util-16.1.17.-96 {8.4 compatible formatting of doubles} \ - {expr 1e-96} \ + {expr {1e-96}} \ 9.9999999999999991e-97 test util-16.1.17.-95 {8.4 compatible formatting of doubles} \ - {expr 1e-95} \ + {expr {1e-95}} \ 9.9999999999999999e-96 test util-16.1.17.-94 {8.4 compatible formatting of doubles} \ - {expr 1e-94} \ + {expr {1e-94}} \ 9.9999999999999996e-95 test util-16.1.17.-93 {8.4 compatible formatting of doubles} \ - {expr 1e-93} \ + {expr {1e-93}} \ 9.999999999999999e-94 test util-16.1.17.-92 {8.4 compatible formatting of doubles} \ - {expr 1e-92} \ + {expr {1e-92}} \ 9.9999999999999999e-93 test util-16.1.17.-91 {8.4 compatible formatting of doubles} \ - {expr 1e-91} \ + {expr {1e-91}} \ 1e-91 test util-16.1.17.-90 {8.4 compatible formatting of doubles} \ - {expr 1e-90} \ + {expr {1e-90}} \ 9.9999999999999999e-91 test util-16.1.17.-89 {8.4 compatible formatting of doubles} \ - {expr 1e-89} \ + {expr {1e-89}} \ 1e-89 test util-16.1.17.-88 {8.4 compatible formatting of doubles} \ - {expr 1e-88} \ + {expr {1e-88}} \ 9.9999999999999993e-89 test util-16.1.17.-87 {8.4 compatible formatting of doubles} \ - {expr 1e-87} \ + {expr {1e-87}} \ 1e-87 test util-16.1.17.-86 {8.4 compatible formatting of doubles} \ - {expr 1e-86} \ + {expr {1e-86}} \ 1.0000000000000001e-86 test util-16.1.17.-85 {8.4 compatible formatting of doubles} \ - {expr 1e-85} \ + {expr {1e-85}} \ 9.9999999999999998e-86 test util-16.1.17.-84 {8.4 compatible formatting of doubles} \ - {expr 1e-84} \ + {expr {1e-84}} \ 1e-84 test util-16.1.17.-83 {8.4 compatible formatting of doubles} \ - {expr 1e-83} \ + {expr {1e-83}} \ 1e-83 test util-16.1.17.-82 {8.4 compatible formatting of doubles} \ - {expr 1e-82} \ + {expr {1e-82}} \ 9.9999999999999996e-83 test util-16.1.17.-81 {8.4 compatible formatting of doubles} \ - {expr 1e-81} \ + {expr {1e-81}} \ 9.9999999999999996e-82 test util-16.1.17.-80 {8.4 compatible formatting of doubles} \ - {expr 1e-80} \ + {expr {1e-80}} \ 9.9999999999999996e-81 test util-16.1.17.-79 {8.4 compatible formatting of doubles} \ - {expr 1e-79} \ + {expr {1e-79}} \ 1e-79 test util-16.1.17.-78 {8.4 compatible formatting of doubles} \ - {expr 1e-78} \ + {expr {1e-78}} \ 1e-78 test util-16.1.17.-77 {8.4 compatible formatting of doubles} \ - {expr 1e-77} \ + {expr {1e-77}} \ 9.9999999999999993e-78 test util-16.1.17.-76 {8.4 compatible formatting of doubles} \ - {expr 1e-76} \ + {expr {1e-76}} \ 9.9999999999999993e-77 test util-16.1.17.-75 {8.4 compatible formatting of doubles} \ - {expr 1e-75} \ + {expr {1e-75}} \ 9.9999999999999996e-76 test util-16.1.17.-74 {8.4 compatible formatting of doubles} \ - {expr 1e-74} \ + {expr {1e-74}} \ 9.9999999999999996e-75 test util-16.1.17.-73 {8.4 compatible formatting of doubles} \ - {expr 1e-73} \ + {expr {1e-73}} \ 1e-73 test util-16.1.17.-72 {8.4 compatible formatting of doubles} \ - {expr 1e-72} \ + {expr {1e-72}} \ 9.9999999999999997e-73 test util-16.1.17.-71 {8.4 compatible formatting of doubles} \ - {expr 1e-71} \ + {expr {1e-71}} \ 9.9999999999999992e-72 test util-16.1.17.-70 {8.4 compatible formatting of doubles} \ - {expr 1e-70} \ + {expr {1e-70}} \ 1e-70 test util-16.1.17.-69 {8.4 compatible formatting of doubles} \ - {expr 1e-69} \ + {expr {1e-69}} \ 9.9999999999999996e-70 test util-16.1.17.-68 {8.4 compatible formatting of doubles} \ - {expr 1e-68} \ + {expr {1e-68}} \ 1.0000000000000001e-68 test util-16.1.17.-67 {8.4 compatible formatting of doubles} \ - {expr 1e-67} \ + {expr {1e-67}} \ 9.9999999999999994e-68 test util-16.1.17.-66 {8.4 compatible formatting of doubles} \ - {expr 1e-66} \ + {expr {1e-66}} \ 9.9999999999999998e-67 test util-16.1.17.-65 {8.4 compatible formatting of doubles} \ - {expr 1e-65} \ + {expr {1e-65}} \ 9.9999999999999992e-66 test util-16.1.17.-64 {8.4 compatible formatting of doubles} \ - {expr 1e-64} \ + {expr {1e-64}} \ 9.9999999999999997e-65 test util-16.1.17.-63 {8.4 compatible formatting of doubles} \ - {expr 1e-63} \ + {expr {1e-63}} \ 1.0000000000000001e-63 test util-16.1.17.-62 {8.4 compatible formatting of doubles} \ - {expr 1e-62} \ + {expr {1e-62}} \ 1e-62 test util-16.1.17.-61 {8.4 compatible formatting of doubles} \ - {expr 1e-61} \ + {expr {1e-61}} \ 1e-61 test util-16.1.17.-60 {8.4 compatible formatting of doubles} \ - {expr 1e-60} \ + {expr {1e-60}} \ 9.9999999999999997e-61 test util-16.1.17.-59 {8.4 compatible formatting of doubles} \ - {expr 1e-59} \ + {expr {1e-59}} \ 1e-59 test util-16.1.17.-58 {8.4 compatible formatting of doubles} \ - {expr 1e-58} \ + {expr {1e-58}} \ 1e-58 test util-16.1.17.-57 {8.4 compatible formatting of doubles} \ - {expr 1e-57} \ + {expr {1e-57}} \ 9.9999999999999995e-58 test util-16.1.17.-56 {8.4 compatible formatting of doubles} \ - {expr 1e-56} \ + {expr {1e-56}} \ 1e-56 test util-16.1.17.-55 {8.4 compatible formatting of doubles} \ - {expr 1e-55} \ + {expr {1e-55}} \ 9.9999999999999999e-56 test util-16.1.17.-54 {8.4 compatible formatting of doubles} \ - {expr 1e-54} \ + {expr {1e-54}} \ 1e-54 test util-16.1.17.-53 {8.4 compatible formatting of doubles} \ - {expr 1e-53} \ + {expr {1e-53}} \ 1e-53 test util-16.1.17.-52 {8.4 compatible formatting of doubles} \ - {expr 1e-52} \ + {expr {1e-52}} \ 1e-52 test util-16.1.17.-51 {8.4 compatible formatting of doubles} \ - {expr 1e-51} \ + {expr {1e-51}} \ 1e-51 test util-16.1.17.-50 {8.4 compatible formatting of doubles} \ - {expr 1e-50} \ + {expr {1e-50}} \ 1e-50 test util-16.1.17.-49 {8.4 compatible formatting of doubles} \ - {expr 1e-49} \ + {expr {1e-49}} \ 9.9999999999999994e-50 test util-16.1.17.-48 {8.4 compatible formatting of doubles} \ - {expr 1e-48} \ + {expr {1e-48}} \ 9.9999999999999997e-49 test util-16.1.17.-47 {8.4 compatible formatting of doubles} \ - {expr 1e-47} \ + {expr {1e-47}} \ 9.9999999999999997e-48 test util-16.1.17.-46 {8.4 compatible formatting of doubles} \ - {expr 1e-46} \ + {expr {1e-46}} \ 1e-46 test util-16.1.17.-45 {8.4 compatible formatting of doubles} \ - {expr 1e-45} \ + {expr {1e-45}} \ 9.9999999999999998e-46 test util-16.1.17.-44 {8.4 compatible formatting of doubles} \ - {expr 1e-44} \ + {expr {1e-44}} \ 9.9999999999999995e-45 test util-16.1.17.-43 {8.4 compatible formatting of doubles} \ - {expr 1e-43} \ + {expr {1e-43}} \ 1.0000000000000001e-43 test util-16.1.17.-42 {8.4 compatible formatting of doubles} \ - {expr 1e-42} \ + {expr {1e-42}} \ 1e-42 test util-16.1.17.-41 {8.4 compatible formatting of doubles} \ - {expr 1e-41} \ + {expr {1e-41}} \ 1e-41 test util-16.1.17.-40 {8.4 compatible formatting of doubles} \ - {expr 1e-40} \ + {expr {1e-40}} \ 9.9999999999999993e-41 test util-16.1.17.-39 {8.4 compatible formatting of doubles} \ - {expr 1e-39} \ + {expr {1e-39}} \ 9.9999999999999993e-40 test util-16.1.17.-38 {8.4 compatible formatting of doubles} \ - {expr 1e-38} \ + {expr {1e-38}} \ 9.9999999999999996e-39 test util-16.1.17.-37 {8.4 compatible formatting of doubles} \ - {expr 1e-37} \ + {expr {1e-37}} \ 1.0000000000000001e-37 test util-16.1.17.-36 {8.4 compatible formatting of doubles} \ - {expr 1e-36} \ + {expr {1e-36}} \ 9.9999999999999994e-37 test util-16.1.17.-35 {8.4 compatible formatting of doubles} \ - {expr 1e-35} \ + {expr {1e-35}} \ 1e-35 test util-16.1.17.-34 {8.4 compatible formatting of doubles} \ - {expr 1e-34} \ + {expr {1e-34}} \ 9.9999999999999993e-35 test util-16.1.17.-33 {8.4 compatible formatting of doubles} \ - {expr 1e-33} \ + {expr {1e-33}} \ 1.0000000000000001e-33 test util-16.1.17.-32 {8.4 compatible formatting of doubles} \ - {expr 1e-32} \ + {expr {1e-32}} \ 1.0000000000000001e-32 test util-16.1.17.-31 {8.4 compatible formatting of doubles} \ - {expr 1e-31} \ + {expr {1e-31}} \ 1.0000000000000001e-31 test util-16.1.17.-30 {8.4 compatible formatting of doubles} \ - {expr 1e-30} \ + {expr {1e-30}} \ 1.0000000000000001e-30 test util-16.1.17.-29 {8.4 compatible formatting of doubles} \ - {expr 1e-29} \ + {expr {1e-29}} \ 9.9999999999999994e-30 test util-16.1.17.-28 {8.4 compatible formatting of doubles} \ - {expr 1e-28} \ + {expr {1e-28}} \ 9.9999999999999997e-29 test util-16.1.17.-27 {8.4 compatible formatting of doubles} \ - {expr 1e-27} \ + {expr {1e-27}} \ 1e-27 test util-16.1.17.-26 {8.4 compatible formatting of doubles} \ - {expr 1e-26} \ + {expr {1e-26}} \ 1e-26 test util-16.1.17.-25 {8.4 compatible formatting of doubles} \ - {expr 1e-25} \ + {expr {1e-25}} \ 1e-25 test util-16.1.17.-24 {8.4 compatible formatting of doubles} \ - {expr 1e-24} \ + {expr {1e-24}} \ 9.9999999999999992e-25 test util-16.1.17.-23 {8.4 compatible formatting of doubles} \ - {expr 1e-23} \ + {expr {1e-23}} \ 9.9999999999999996e-24 test util-16.1.17.-22 {8.4 compatible formatting of doubles} \ - {expr 1e-22} \ + {expr {1e-22}} \ 1e-22 test util-16.1.17.-21 {8.4 compatible formatting of doubles} \ - {expr 1e-21} \ + {expr {1e-21}} \ 9.9999999999999991e-22 test util-16.1.17.-20 {8.4 compatible formatting of doubles} \ - {expr 1e-20} \ + {expr {1e-20}} \ 9.9999999999999995e-21 test util-16.1.17.-19 {8.4 compatible formatting of doubles} \ - {expr 1e-19} \ + {expr {1e-19}} \ 9.9999999999999998e-20 test util-16.1.17.-18 {8.4 compatible formatting of doubles} \ - {expr 1e-18} \ + {expr {1e-18}} \ 1.0000000000000001e-18 test util-16.1.17.-17 {8.4 compatible formatting of doubles} \ - {expr 1e-17} \ + {expr {1e-17}} \ 1.0000000000000001e-17 test util-16.1.17.-16 {8.4 compatible formatting of doubles} \ - {expr 1e-16} \ + {expr {1e-16}} \ 9.9999999999999998e-17 test util-16.1.17.-15 {8.4 compatible formatting of doubles} \ - {expr 1e-15} \ + {expr {1e-15}} \ 1.0000000000000001e-15 test util-16.1.17.-14 {8.4 compatible formatting of doubles} \ - {expr 1e-14} \ + {expr {1e-14}} \ 1e-14 test util-16.1.17.-13 {8.4 compatible formatting of doubles} \ - {expr 1e-13} \ + {expr {1e-13}} \ 1e-13 test util-16.1.17.-12 {8.4 compatible formatting of doubles} \ - {expr 1e-12} \ + {expr {1e-12}} \ 9.9999999999999998e-13 test util-16.1.17.-11 {8.4 compatible formatting of doubles} \ - {expr 1e-11} \ + {expr {1e-11}} \ 9.9999999999999994e-12 test util-16.1.17.-10 {8.4 compatible formatting of doubles} \ - {expr 1e-10} \ + {expr {1e-10}} \ 1e-10 test util-16.1.17.-9 {8.4 compatible formatting of doubles} \ - {expr 1e-9} \ + {expr {1e-9}} \ 1.0000000000000001e-09 test util-16.1.17.-8 {8.4 compatible formatting of doubles} \ - {expr 1e-8} \ + {expr {1e-8}} \ 1e-08 test util-16.1.17.-7 {8.4 compatible formatting of doubles} \ - {expr 1e-7} \ + {expr {1e-7}} \ 9.9999999999999995e-08 test util-16.1.17.-6 {8.4 compatible formatting of doubles} \ - {expr 1e-6} \ + {expr {1e-6}} \ 9.9999999999999995e-07 test util-16.1.17.-5 {8.4 compatible formatting of doubles} \ - {expr 1e-5} \ + {expr {1e-5}} \ 1.0000000000000001e-05 test util-16.1.17.-4 {8.4 compatible formatting of doubles} \ - {expr 1e-4} \ + {expr {1e-4}} \ 0.0001 test util-16.1.17.-3 {8.4 compatible formatting of doubles} \ - {expr 1e-3} \ + {expr {1e-3}} \ 0.001 test util-16.1.17.-2 {8.4 compatible formatting of doubles} \ - {expr 1e-2} \ + {expr {1e-2}} \ 0.01 test util-16.1.17.-1 {8.4 compatible formatting of doubles} \ - {expr 1e-1} \ + {expr {1e-1}} \ 0.10000000000000001 test util-16.1.17.0 {8.4 compatible formatting of doubles} \ - {expr 1e0} \ + {expr {1e0}} \ 1.0 test util-16.1.17.1 {8.4 compatible formatting of doubles} \ - {expr 1e1} \ + {expr {1e1}} \ 10.0 test util-16.1.17.2 {8.4 compatible formatting of doubles} \ - {expr 1e2} \ + {expr {1e2}} \ 100.0 test util-16.1.17.3 {8.4 compatible formatting of doubles} \ - {expr 1e3} \ + {expr {1e3}} \ 1000.0 test util-16.1.17.4 {8.4 compatible formatting of doubles} \ - {expr 1e4} \ + {expr {1e4}} \ 10000.0 test util-16.1.17.5 {8.4 compatible formatting of doubles} \ - {expr 1e5} \ + {expr {1e5}} \ 100000.0 test util-16.1.17.6 {8.4 compatible formatting of doubles} \ - {expr 1e6} \ + {expr {1e6}} \ 1000000.0 test util-16.1.17.7 {8.4 compatible formatting of doubles} \ - {expr 1e7} \ + {expr {1e7}} \ 10000000.0 test util-16.1.17.8 {8.4 compatible formatting of doubles} \ - {expr 1e8} \ + {expr {1e8}} \ 100000000.0 test util-16.1.17.9 {8.4 compatible formatting of doubles} \ - {expr 1e9} \ + {expr {1e9}} \ 1000000000.0 test util-16.1.17.10 {8.4 compatible formatting of doubles} \ - {expr 1e10} \ + {expr {1e10}} \ 10000000000.0 test util-16.1.17.11 {8.4 compatible formatting of doubles} \ - {expr 1e11} \ + {expr {1e11}} \ 100000000000.0 test util-16.1.17.12 {8.4 compatible formatting of doubles} \ - {expr 1e12} \ + {expr {1e12}} \ 1000000000000.0 test util-16.1.17.13 {8.4 compatible formatting of doubles} \ - {expr 1e13} \ + {expr {1e13}} \ 10000000000000.0 test util-16.1.17.14 {8.4 compatible formatting of doubles} \ - {expr 1e14} \ + {expr {1e14}} \ 100000000000000.0 test util-16.1.17.15 {8.4 compatible formatting of doubles} \ - {expr 1e15} \ + {expr {1e15}} \ 1000000000000000.0 test util-16.1.17.16 {8.4 compatible formatting of doubles} \ - {expr 1e16} \ + {expr {1e16}} \ 10000000000000000.0 test util-16.1.17.17 {8.4 compatible formatting of doubles} \ - {expr 1e17} \ + {expr {1e17}} \ 1e+17 test util-16.1.17.18 {8.4 compatible formatting of doubles} \ - {expr 1e18} \ + {expr {1e18}} \ 1e+18 test util-16.1.17.19 {8.4 compatible formatting of doubles} \ - {expr 1e19} \ + {expr {1e19}} \ 1e+19 test util-16.1.17.20 {8.4 compatible formatting of doubles} \ - {expr 1e20} \ + {expr {1e20}} \ 1e+20 test util-16.1.17.21 {8.4 compatible formatting of doubles} \ - {expr 1e21} \ + {expr {1e21}} \ 1e+21 test util-16.1.17.22 {8.4 compatible formatting of doubles} \ - {expr 1e22} \ + {expr {1e22}} \ 1e+22 test util-16.1.17.23 {8.4 compatible formatting of doubles} \ - {expr 1e23} \ + {expr {1e23}} \ 9.9999999999999992e+22 test util-16.1.17.24 {8.4 compatible formatting of doubles} \ - {expr 1e24} \ + {expr {1e24}} \ 9.9999999999999998e+23 test util-16.1.17.25 {8.4 compatible formatting of doubles} \ - {expr 1e25} \ + {expr {1e25}} \ 1.0000000000000001e+25 test util-16.1.17.26 {8.4 compatible formatting of doubles} \ - {expr 1e26} \ + {expr {1e26}} \ 1e+26 test util-16.1.17.27 {8.4 compatible formatting of doubles} \ - {expr 1e27} \ + {expr {1e27}} \ 1e+27 test util-16.1.17.28 {8.4 compatible formatting of doubles} \ - {expr 1e28} \ + {expr {1e28}} \ 9.9999999999999996e+27 test util-16.1.17.29 {8.4 compatible formatting of doubles} \ - {expr 1e29} \ + {expr {1e29}} \ 9.9999999999999991e+28 test util-16.1.17.30 {8.4 compatible formatting of doubles} \ - {expr 1e30} \ + {expr {1e30}} \ 1e+30 test util-16.1.17.31 {8.4 compatible formatting of doubles} \ - {expr 1e31} \ + {expr {1e31}} \ 9.9999999999999996e+30 test util-16.1.17.32 {8.4 compatible formatting of doubles} \ - {expr 1e32} \ + {expr {1e32}} \ 1.0000000000000001e+32 test util-16.1.17.33 {8.4 compatible formatting of doubles} \ - {expr 1e33} \ + {expr {1e33}} \ 9.9999999999999995e+32 test util-16.1.17.34 {8.4 compatible formatting of doubles} \ - {expr 1e34} \ + {expr {1e34}} \ 9.9999999999999995e+33 test util-16.1.17.35 {8.4 compatible formatting of doubles} \ - {expr 1e35} \ + {expr {1e35}} \ 9.9999999999999997e+34 test util-16.1.17.36 {8.4 compatible formatting of doubles} \ - {expr 1e36} \ + {expr {1e36}} \ 1e+36 test util-16.1.17.37 {8.4 compatible formatting of doubles} \ - {expr 1e37} \ + {expr {1e37}} \ 9.9999999999999995e+36 test util-16.1.17.38 {8.4 compatible formatting of doubles} \ - {expr 1e38} \ + {expr {1e38}} \ 9.9999999999999998e+37 test util-16.1.17.39 {8.4 compatible formatting of doubles} \ - {expr 1e39} \ + {expr {1e39}} \ 9.9999999999999994e+38 test util-16.1.17.40 {8.4 compatible formatting of doubles} \ - {expr 1e40} \ + {expr {1e40}} \ 1e+40 test util-16.1.17.41 {8.4 compatible formatting of doubles} \ - {expr 1e41} \ + {expr {1e41}} \ 1e+41 test util-16.1.17.42 {8.4 compatible formatting of doubles} \ - {expr 1e42} \ + {expr {1e42}} \ 1e+42 test util-16.1.17.43 {8.4 compatible formatting of doubles} \ - {expr 1e43} \ + {expr {1e43}} \ 1e+43 test util-16.1.17.44 {8.4 compatible formatting of doubles} \ - {expr 1e44} \ + {expr {1e44}} \ 1.0000000000000001e+44 test util-16.1.17.45 {8.4 compatible formatting of doubles} \ - {expr 1e45} \ + {expr {1e45}} \ 9.9999999999999993e+44 test util-16.1.17.46 {8.4 compatible formatting of doubles} \ - {expr 1e46} \ + {expr {1e46}} \ 9.9999999999999999e+45 test util-16.1.17.47 {8.4 compatible formatting of doubles} \ - {expr 1e47} \ + {expr {1e47}} \ 1e+47 test util-16.1.17.48 {8.4 compatible formatting of doubles} \ - {expr 1e48} \ + {expr {1e48}} \ 1e+48 test util-16.1.17.49 {8.4 compatible formatting of doubles} \ - {expr 1e49} \ + {expr {1e49}} \ 9.9999999999999995e+48 test util-16.1.17.50 {8.4 compatible formatting of doubles} \ - {expr 1e50} \ + {expr {1e50}} \ 1.0000000000000001e+50 test util-16.1.17.51 {8.4 compatible formatting of doubles} \ - {expr 1e51} \ + {expr {1e51}} \ 9.9999999999999999e+50 test util-16.1.17.52 {8.4 compatible formatting of doubles} \ - {expr 1e52} \ + {expr {1e52}} \ 9.9999999999999999e+51 test util-16.1.17.53 {8.4 compatible formatting of doubles} \ - {expr 1e53} \ + {expr {1e53}} \ 9.9999999999999999e+52 test util-16.1.17.54 {8.4 compatible formatting of doubles} \ - {expr 1e54} \ + {expr {1e54}} \ 1.0000000000000001e+54 test util-16.1.17.55 {8.4 compatible formatting of doubles} \ - {expr 1e55} \ + {expr {1e55}} \ 1e+55 test util-16.1.17.56 {8.4 compatible formatting of doubles} \ - {expr 1e56} \ + {expr {1e56}} \ 1.0000000000000001e+56 test util-16.1.17.57 {8.4 compatible formatting of doubles} \ - {expr 1e57} \ + {expr {1e57}} \ 1e+57 test util-16.1.17.58 {8.4 compatible formatting of doubles} \ - {expr 1e58} \ + {expr {1e58}} \ 9.9999999999999994e+57 test util-16.1.17.59 {8.4 compatible formatting of doubles} \ - {expr 1e59} \ + {expr {1e59}} \ 9.9999999999999997e+58 test util-16.1.17.60 {8.4 compatible formatting of doubles} \ - {expr 1e60} \ + {expr {1e60}} \ 9.9999999999999995e+59 test util-16.1.17.61 {8.4 compatible formatting of doubles} \ - {expr 1e61} \ + {expr {1e61}} \ 9.9999999999999995e+60 test util-16.1.17.62 {8.4 compatible formatting of doubles} \ - {expr 1e62} \ + {expr {1e62}} \ 1e+62 test util-16.1.17.63 {8.4 compatible formatting of doubles} \ - {expr 1e63} \ + {expr {1e63}} \ 1.0000000000000001e+63 test util-16.1.17.64 {8.4 compatible formatting of doubles} \ - {expr 1e64} \ + {expr {1e64}} \ 1e+64 test util-16.1.17.65 {8.4 compatible formatting of doubles} \ - {expr 1e65} \ + {expr {1e65}} \ 9.9999999999999999e+64 test util-16.1.17.66 {8.4 compatible formatting of doubles} \ - {expr 1e66} \ + {expr {1e66}} \ 9.9999999999999995e+65 test util-16.1.17.67 {8.4 compatible formatting of doubles} \ - {expr 1e67} \ + {expr {1e67}} \ 9.9999999999999998e+66 test util-16.1.17.68 {8.4 compatible formatting of doubles} \ - {expr 1e68} \ + {expr {1e68}} \ 9.9999999999999995e+67 test util-16.1.17.69 {8.4 compatible formatting of doubles} \ - {expr 1e69} \ + {expr {1e69}} \ 1.0000000000000001e+69 test util-16.1.17.70 {8.4 compatible formatting of doubles} \ - {expr 1e70} \ + {expr {1e70}} \ 1.0000000000000001e+70 test util-16.1.17.71 {8.4 compatible formatting of doubles} \ - {expr 1e71} \ + {expr {1e71}} \ 1e+71 test util-16.1.17.72 {8.4 compatible formatting of doubles} \ - {expr 1e72} \ + {expr {1e72}} \ 9.9999999999999994e+71 test util-16.1.17.73 {8.4 compatible formatting of doubles} \ - {expr 1e73} \ + {expr {1e73}} \ 9.9999999999999998e+72 test util-16.1.17.74 {8.4 compatible formatting of doubles} \ - {expr 1e74} \ + {expr {1e74}} \ 9.9999999999999995e+73 test util-16.1.17.75 {8.4 compatible formatting of doubles} \ - {expr 1e75} \ + {expr {1e75}} \ 9.9999999999999993e+74 test util-16.1.17.76 {8.4 compatible formatting of doubles} \ - {expr 1e76} \ + {expr {1e76}} \ 1e+76 test util-16.1.17.77 {8.4 compatible formatting of doubles} \ - {expr 1e77} \ + {expr {1e77}} \ 9.9999999999999998e+76 test util-16.1.17.78 {8.4 compatible formatting of doubles} \ - {expr 1e78} \ + {expr {1e78}} \ 1e+78 test util-16.1.17.79 {8.4 compatible formatting of doubles} \ - {expr 1e79} \ + {expr {1e79}} \ 9.9999999999999997e+78 test util-16.1.17.80 {8.4 compatible formatting of doubles} \ - {expr 1e80} \ + {expr {1e80}} \ 1e+80 test util-16.1.17.81 {8.4 compatible formatting of doubles} \ - {expr 1e81} \ + {expr {1e81}} \ 9.9999999999999992e+80 test util-16.1.17.82 {8.4 compatible formatting of doubles} \ - {expr 1e82} \ + {expr {1e82}} \ 9.9999999999999996e+81 test util-16.1.17.83 {8.4 compatible formatting of doubles} \ - {expr 1e83} \ + {expr {1e83}} \ 1e+83 test util-16.1.17.84 {8.4 compatible formatting of doubles} \ - {expr 1e84} \ + {expr {1e84}} \ 1.0000000000000001e+84 test util-16.1.17.85 {8.4 compatible formatting of doubles} \ - {expr 1e85} \ + {expr {1e85}} \ 1e+85 test util-16.1.17.86 {8.4 compatible formatting of doubles} \ - {expr 1e86} \ + {expr {1e86}} \ 1e+86 test util-16.1.17.87 {8.4 compatible formatting of doubles} \ - {expr 1e87} \ + {expr {1e87}} \ 9.9999999999999996e+86 test util-16.1.17.88 {8.4 compatible formatting of doubles} \ - {expr 1e88} \ + {expr {1e88}} \ 9.9999999999999996e+87 test util-16.1.17.89 {8.4 compatible formatting of doubles} \ - {expr 1e89} \ + {expr {1e89}} \ 9.9999999999999999e+88 test util-16.1.17.90 {8.4 compatible formatting of doubles} \ - {expr 1e90} \ + {expr {1e90}} \ 9.9999999999999997e+89 test util-16.1.17.91 {8.4 compatible formatting of doubles} \ - {expr 1e91} \ + {expr {1e91}} \ 1.0000000000000001e+91 test util-16.1.17.92 {8.4 compatible formatting of doubles} \ - {expr 1e92} \ + {expr {1e92}} \ 1e+92 test util-16.1.17.93 {8.4 compatible formatting of doubles} \ - {expr 1e93} \ + {expr {1e93}} \ 1e+93 test util-16.1.17.94 {8.4 compatible formatting of doubles} \ - {expr 1e94} \ + {expr {1e94}} \ 1e+94 test util-16.1.17.95 {8.4 compatible formatting of doubles} \ - {expr 1e95} \ + {expr {1e95}} \ 1e+95 test util-16.1.17.96 {8.4 compatible formatting of doubles} \ - {expr 1e96} \ + {expr {1e96}} \ 1e+96 test util-16.1.17.97 {8.4 compatible formatting of doubles} \ - {expr 1e97} \ + {expr {1e97}} \ 1.0000000000000001e+97 test util-16.1.17.98 {8.4 compatible formatting of doubles} \ - {expr 1e98} \ + {expr {1e98}} \ 1e+98 test util-16.1.17.99 {8.4 compatible formatting of doubles} \ - {expr 1e99} \ + {expr {1e99}} \ 9.9999999999999997e+98 test util-16.1.17.100 {8.4 compatible formatting of doubles} \ - {expr 1e100} \ + {expr {1e100}} \ 1e+100 test util-16.1.17.101 {8.4 compatible formatting of doubles} \ - {expr 1e101} \ + {expr {1e101}} \ 9.9999999999999998e+100 test util-16.1.17.102 {8.4 compatible formatting of doubles} \ - {expr 1e102} \ + {expr {1e102}} \ 9.9999999999999998e+101 test util-16.1.17.103 {8.4 compatible formatting of doubles} \ - {expr 1e103} \ + {expr {1e103}} \ 1e+103 test util-16.1.17.104 {8.4 compatible formatting of doubles} \ - {expr 1e104} \ + {expr {1e104}} \ 1e+104 test util-16.1.17.105 {8.4 compatible formatting of doubles} \ - {expr 1e105} \ + {expr {1e105}} \ 9.9999999999999994e+104 test util-16.1.17.106 {8.4 compatible formatting of doubles} \ - {expr 1e106} \ + {expr {1e106}} \ 1.0000000000000001e+106 test util-16.1.17.107 {8.4 compatible formatting of doubles} \ - {expr 1e107} \ + {expr {1e107}} \ 9.9999999999999997e+106 test util-16.1.17.108 {8.4 compatible formatting of doubles} \ - {expr 1e108} \ + {expr {1e108}} \ 1e+108 test util-16.1.17.109 {8.4 compatible formatting of doubles} \ - {expr 1e109} \ + {expr {1e109}} \ 9.9999999999999998e+108 test util-16.1.17.110 {8.4 compatible formatting of doubles} \ - {expr 1e110} \ + {expr {1e110}} \ 1e+110 test util-16.1.17.111 {8.4 compatible formatting of doubles} \ - {expr 1e111} \ + {expr {1e111}} \ 9.9999999999999996e+110 test util-16.1.17.112 {8.4 compatible formatting of doubles} \ - {expr 1e112} \ + {expr {1e112}} \ 9.9999999999999993e+111 test util-16.1.17.113 {8.4 compatible formatting of doubles} \ - {expr 1e113} \ + {expr {1e113}} \ 1e+113 test util-16.1.17.114 {8.4 compatible formatting of doubles} \ - {expr 1e114} \ + {expr {1e114}} \ 1e+114 test util-16.1.17.115 {8.4 compatible formatting of doubles} \ - {expr 1e115} \ + {expr {1e115}} \ 1e+115 test util-16.1.17.116 {8.4 compatible formatting of doubles} \ - {expr 1e116} \ + {expr {1e116}} \ 1e+116 test util-16.1.17.117 {8.4 compatible formatting of doubles} \ - {expr 1e117} \ + {expr {1e117}} \ 1.0000000000000001e+117 test util-16.1.17.118 {8.4 compatible formatting of doubles} \ - {expr 1e118} \ + {expr {1e118}} \ 9.9999999999999997e+117 test util-16.1.17.119 {8.4 compatible formatting of doubles} \ - {expr 1e119} \ + {expr {1e119}} \ 9.9999999999999994e+118 test util-16.1.17.120 {8.4 compatible formatting of doubles} \ - {expr 1e120} \ + {expr {1e120}} \ 9.9999999999999998e+119 test util-16.1.17.121 {8.4 compatible formatting of doubles} \ - {expr 1e121} \ + {expr {1e121}} \ 1e+121 test util-16.1.17.122 {8.4 compatible formatting of doubles} \ - {expr 1e122} \ + {expr {1e122}} \ 1e+122 test util-16.1.17.123 {8.4 compatible formatting of doubles} \ - {expr 1e123} \ + {expr {1e123}} \ 9.9999999999999998e+122 test util-16.1.17.124 {8.4 compatible formatting of doubles} \ - {expr 1e124} \ + {expr {1e124}} \ 9.9999999999999995e+123 test util-16.1.17.125 {8.4 compatible formatting of doubles} \ - {expr 1e125} \ + {expr {1e125}} \ 9.9999999999999992e+124 test util-16.1.17.126 {8.4 compatible formatting of doubles} \ - {expr 1e126} \ + {expr {1e126}} \ 9.9999999999999992e+125 test util-16.1.17.127 {8.4 compatible formatting of doubles} \ - {expr 1e127} \ + {expr {1e127}} \ 9.9999999999999995e+126 test util-16.1.17.128 {8.4 compatible formatting of doubles} \ - {expr 1e128} \ + {expr {1e128}} \ 1.0000000000000001e+128 test util-16.1.17.129 {8.4 compatible formatting of doubles} \ - {expr 1e129} \ + {expr {1e129}} \ 1e+129 test util-16.1.17.130 {8.4 compatible formatting of doubles} \ - {expr 1e130} \ + {expr {1e130}} \ 1.0000000000000001e+130 test util-16.1.17.131 {8.4 compatible formatting of doubles} \ - {expr 1e131} \ + {expr {1e131}} \ 9.9999999999999991e+130 test util-16.1.17.132 {8.4 compatible formatting of doubles} \ - {expr 1e132} \ + {expr {1e132}} \ 9.9999999999999999e+131 test util-16.1.17.133 {8.4 compatible formatting of doubles} \ - {expr 1e133} \ + {expr {1e133}} \ 1e+133 test util-16.1.17.134 {8.4 compatible formatting of doubles} \ - {expr 1e134} \ + {expr {1e134}} \ 9.9999999999999992e+133 test util-16.1.17.135 {8.4 compatible formatting of doubles} \ - {expr 1e135} \ + {expr {1e135}} \ 9.9999999999999996e+134 test util-16.1.17.136 {8.4 compatible formatting of doubles} \ - {expr 1e136} \ + {expr {1e136}} \ 1.0000000000000001e+136 test util-16.1.17.137 {8.4 compatible formatting of doubles} \ - {expr 1e137} \ + {expr {1e137}} \ 1e+137 test util-16.1.17.138 {8.4 compatible formatting of doubles} \ - {expr 1e138} \ + {expr {1e138}} \ 1e+138 test util-16.1.17.139 {8.4 compatible formatting of doubles} \ - {expr 1e139} \ + {expr {1e139}} \ 1e+139 test util-16.1.17.140 {8.4 compatible formatting of doubles} \ - {expr 1e140} \ + {expr {1e140}} \ 1.0000000000000001e+140 test util-16.1.17.141 {8.4 compatible formatting of doubles} \ - {expr 1e141} \ + {expr {1e141}} \ 1e+141 test util-16.1.17.142 {8.4 compatible formatting of doubles} \ - {expr 1e142} \ + {expr {1e142}} \ 1.0000000000000001e+142 test util-16.1.17.143 {8.4 compatible formatting of doubles} \ - {expr 1e143} \ + {expr {1e143}} \ 1e+143 test util-16.1.17.144 {8.4 compatible formatting of doubles} \ - {expr 1e144} \ + {expr {1e144}} \ 1e+144 test util-16.1.17.145 {8.4 compatible formatting of doubles} \ - {expr 1e145} \ + {expr {1e145}} \ 9.9999999999999999e+144 test util-16.1.17.146 {8.4 compatible formatting of doubles} \ - {expr 1e146} \ + {expr {1e146}} \ 9.9999999999999993e+145 test util-16.1.17.147 {8.4 compatible formatting of doubles} \ - {expr 1e147} \ + {expr {1e147}} \ 9.9999999999999998e+146 test util-16.1.17.148 {8.4 compatible formatting of doubles} \ - {expr 1e148} \ + {expr {1e148}} \ 1e+148 test util-16.1.17.149 {8.4 compatible formatting of doubles} \ - {expr 1e149} \ + {expr {1e149}} \ 1e+149 test util-16.1.17.150 {8.4 compatible formatting of doubles} \ - {expr 1e150} \ + {expr {1e150}} \ 9.9999999999999998e+149 test util-16.1.17.151 {8.4 compatible formatting of doubles} \ - {expr 1e151} \ + {expr {1e151}} \ 1e+151 test util-16.1.17.152 {8.4 compatible formatting of doubles} \ - {expr 1e152} \ + {expr {1e152}} \ 1e+152 test util-16.1.17.153 {8.4 compatible formatting of doubles} \ - {expr 1e153} \ + {expr {1e153}} \ 1e+153 test util-16.1.17.154 {8.4 compatible formatting of doubles} \ - {expr 1e154} \ + {expr {1e154}} \ 1e+154 test util-16.1.17.155 {8.4 compatible formatting of doubles} \ - {expr 1e155} \ + {expr {1e155}} \ 1e+155 test util-16.1.17.156 {8.4 compatible formatting of doubles} \ - {expr 1e156} \ + {expr {1e156}} \ 9.9999999999999998e+155 test util-16.1.17.157 {8.4 compatible formatting of doubles} \ - {expr 1e157} \ + {expr {1e157}} \ 9.9999999999999998e+156 test util-16.1.17.158 {8.4 compatible formatting of doubles} \ - {expr 1e158} \ + {expr {1e158}} \ 9.9999999999999995e+157 test util-16.1.17.159 {8.4 compatible formatting of doubles} \ - {expr 1e159} \ + {expr {1e159}} \ 9.9999999999999993e+158 test util-16.1.17.160 {8.4 compatible formatting of doubles} \ - {expr 1e160} \ + {expr {1e160}} \ 1e+160 test util-16.1.17.161 {8.4 compatible formatting of doubles} \ - {expr 1e161} \ + {expr {1e161}} \ 1e+161 test util-16.1.17.162 {8.4 compatible formatting of doubles} \ - {expr 1e162} \ + {expr {1e162}} \ 9.9999999999999994e+161 test util-16.1.17.163 {8.4 compatible formatting of doubles} \ - {expr 1e163} \ + {expr {1e163}} \ 9.9999999999999994e+162 test util-16.1.17.164 {8.4 compatible formatting of doubles} \ - {expr 1e164} \ + {expr {1e164}} \ 1e+164 test util-16.1.17.165 {8.4 compatible formatting of doubles} \ - {expr 1e165} \ + {expr {1e165}} \ 9.999999999999999e+164 test util-16.1.17.166 {8.4 compatible formatting of doubles} \ - {expr 1e166} \ + {expr {1e166}} \ 9.9999999999999994e+165 test util-16.1.17.167 {8.4 compatible formatting of doubles} \ - {expr 1e167} \ + {expr {1e167}} \ 1e+167 test util-16.1.17.168 {8.4 compatible formatting of doubles} \ - {expr 1e168} \ + {expr {1e168}} \ 9.9999999999999993e+167 test util-16.1.17.169 {8.4 compatible formatting of doubles} \ - {expr 1e169} \ + {expr {1e169}} \ 9.9999999999999993e+168 test util-16.1.17.170 {8.4 compatible formatting of doubles} \ - {expr 1e170} \ + {expr {1e170}} \ 1e+170 test util-16.1.17.171 {8.4 compatible formatting of doubles} \ - {expr 1e171} \ + {expr {1e171}} \ 9.9999999999999995e+170 test util-16.1.17.172 {8.4 compatible formatting of doubles} \ - {expr 1e172} \ + {expr {1e172}} \ 1.0000000000000001e+172 test util-16.1.17.173 {8.4 compatible formatting of doubles} \ - {expr 1e173} \ + {expr {1e173}} \ 1e+173 test util-16.1.17.174 {8.4 compatible formatting of doubles} \ - {expr 1e174} \ + {expr {1e174}} \ 1.0000000000000001e+174 test util-16.1.17.175 {8.4 compatible formatting of doubles} \ - {expr 1e175} \ + {expr {1e175}} \ 9.9999999999999994e+174 test util-16.1.17.176 {8.4 compatible formatting of doubles} \ - {expr 1e176} \ + {expr {1e176}} \ 1e+176 test util-16.1.17.177 {8.4 compatible formatting of doubles} \ - {expr 1e177} \ + {expr {1e177}} \ 1e+177 test util-16.1.17.178 {8.4 compatible formatting of doubles} \ - {expr 1e178} \ + {expr {1e178}} \ 1.0000000000000001e+178 test util-16.1.17.179 {8.4 compatible formatting of doubles} \ - {expr 1e179} \ + {expr {1e179}} \ 9.9999999999999998e+178 test util-16.1.17.180 {8.4 compatible formatting of doubles} \ - {expr 1e180} \ + {expr {1e180}} \ 1e+180 test util-16.1.17.181 {8.4 compatible formatting of doubles} \ - {expr 1e181} \ + {expr {1e181}} \ 9.9999999999999992e+180 test util-16.1.17.182 {8.4 compatible formatting of doubles} \ - {expr 1e182} \ + {expr {1e182}} \ 1.0000000000000001e+182 test util-16.1.17.183 {8.4 compatible formatting of doubles} \ - {expr 1e183} \ + {expr {1e183}} \ 9.9999999999999995e+182 test util-16.1.17.184 {8.4 compatible formatting of doubles} \ - {expr 1e184} \ + {expr {1e184}} \ 1e+184 test util-16.1.17.185 {8.4 compatible formatting of doubles} \ - {expr 1e185} \ + {expr {1e185}} \ 9.9999999999999998e+184 test util-16.1.17.186 {8.4 compatible formatting of doubles} \ - {expr 1e186} \ + {expr {1e186}} \ 9.9999999999999998e+185 test util-16.1.17.187 {8.4 compatible formatting of doubles} \ - {expr 1e187} \ + {expr {1e187}} \ 9.9999999999999991e+186 test util-16.1.17.188 {8.4 compatible formatting of doubles} \ - {expr 1e188} \ + {expr {1e188}} \ 1e+188 test util-16.1.17.189 {8.4 compatible formatting of doubles} \ - {expr 1e189} \ + {expr {1e189}} \ 1e+189 test util-16.1.17.190 {8.4 compatible formatting of doubles} \ - {expr 1e190} \ + {expr {1e190}} \ 1.0000000000000001e+190 test util-16.1.17.191 {8.4 compatible formatting of doubles} \ - {expr 1e191} \ + {expr {1e191}} \ 1.0000000000000001e+191 test util-16.1.17.192 {8.4 compatible formatting of doubles} \ - {expr 1e192} \ + {expr {1e192}} \ 1e+192 test util-16.1.17.193 {8.4 compatible formatting of doubles} \ - {expr 1e193} \ + {expr {1e193}} \ 1.0000000000000001e+193 test util-16.1.17.194 {8.4 compatible formatting of doubles} \ - {expr 1e194} \ + {expr {1e194}} \ 9.9999999999999994e+193 test util-16.1.17.195 {8.4 compatible formatting of doubles} \ - {expr 1e195} \ + {expr {1e195}} \ 9.9999999999999998e+194 test util-16.1.17.196 {8.4 compatible formatting of doubles} \ - {expr 1e196} \ + {expr {1e196}} \ 9.9999999999999995e+195 test util-16.1.17.197 {8.4 compatible formatting of doubles} \ - {expr 1e197} \ + {expr {1e197}} \ 9.9999999999999995e+196 test util-16.1.17.198 {8.4 compatible formatting of doubles} \ - {expr 1e198} \ + {expr {1e198}} \ 1e+198 test util-16.1.17.199 {8.4 compatible formatting of doubles} \ - {expr 1e199} \ + {expr {1e199}} \ 1.0000000000000001e+199 test util-16.1.17.200 {8.4 compatible formatting of doubles} \ - {expr 1e200} \ + {expr {1e200}} \ 9.9999999999999997e+199 test util-16.1.17.201 {8.4 compatible formatting of doubles} \ - {expr 1e201} \ + {expr {1e201}} \ 1e+201 test util-16.1.17.202 {8.4 compatible formatting of doubles} \ - {expr 1e202} \ + {expr {1e202}} \ 9.999999999999999e+201 test util-16.1.17.203 {8.4 compatible formatting of doubles} \ - {expr 1e203} \ + {expr {1e203}} \ 9.9999999999999999e+202 test util-16.1.17.204 {8.4 compatible formatting of doubles} \ - {expr 1e204} \ + {expr {1e204}} \ 9.9999999999999999e+203 test util-16.1.17.205 {8.4 compatible formatting of doubles} \ - {expr 1e205} \ + {expr {1e205}} \ 1e+205 test util-16.1.17.206 {8.4 compatible formatting of doubles} \ - {expr 1e206} \ + {expr {1e206}} \ 1e+206 test util-16.1.17.207 {8.4 compatible formatting of doubles} \ - {expr 1e207} \ + {expr {1e207}} \ 1e+207 test util-16.1.17.208 {8.4 compatible formatting of doubles} \ - {expr 1e208} \ + {expr {1e208}} \ 9.9999999999999998e+207 test util-16.1.17.209 {8.4 compatible formatting of doubles} \ - {expr 1e209} \ + {expr {1e209}} \ 1.0000000000000001e+209 test util-16.1.17.210 {8.4 compatible formatting of doubles} \ - {expr 1e210} \ + {expr {1e210}} \ 9.9999999999999993e+209 test util-16.1.17.211 {8.4 compatible formatting of doubles} \ - {expr 1e211} \ + {expr {1e211}} \ 9.9999999999999996e+210 test util-16.1.17.212 {8.4 compatible formatting of doubles} \ - {expr 1e212} \ + {expr {1e212}} \ 9.9999999999999991e+211 test util-16.1.17.213 {8.4 compatible formatting of doubles} \ - {expr 1e213} \ + {expr {1e213}} \ 9.9999999999999998e+212 test util-16.1.17.214 {8.4 compatible formatting of doubles} \ - {expr 1e214} \ + {expr {1e214}} \ 9.9999999999999995e+213 test util-16.1.17.215 {8.4 compatible formatting of doubles} \ - {expr 1e215} \ + {expr {1e215}} \ 9.9999999999999991e+214 test util-16.1.17.216 {8.4 compatible formatting of doubles} \ - {expr 1e216} \ + {expr {1e216}} \ 1e+216 test util-16.1.17.217 {8.4 compatible formatting of doubles} \ - {expr 1e217} \ + {expr {1e217}} \ 9.9999999999999996e+216 test util-16.1.17.218 {8.4 compatible formatting of doubles} \ - {expr 1e218} \ + {expr {1e218}} \ 1.0000000000000001e+218 test util-16.1.17.219 {8.4 compatible formatting of doubles} \ - {expr 1e219} \ + {expr {1e219}} \ 9.9999999999999997e+218 test util-16.1.17.220 {8.4 compatible formatting of doubles} \ - {expr 1e220} \ + {expr {1e220}} \ 1e+220 test util-16.1.17.221 {8.4 compatible formatting of doubles} \ - {expr 1e221} \ + {expr {1e221}} \ 1e+221 test util-16.1.17.222 {8.4 compatible formatting of doubles} \ - {expr 1e222} \ + {expr {1e222}} \ 1e+222 test util-16.1.17.223 {8.4 compatible formatting of doubles} \ - {expr 1e223} \ + {expr {1e223}} \ 1e+223 test util-16.1.17.224 {8.4 compatible formatting of doubles} \ - {expr 1e224} \ + {expr {1e224}} \ 9.9999999999999997e+223 test util-16.1.17.225 {8.4 compatible formatting of doubles} \ - {expr 1e225} \ + {expr {1e225}} \ 9.9999999999999993e+224 test util-16.1.17.226 {8.4 compatible formatting of doubles} \ - {expr 1e226} \ + {expr {1e226}} \ 9.9999999999999996e+225 test util-16.1.17.227 {8.4 compatible formatting of doubles} \ - {expr 1e227} \ + {expr {1e227}} \ 1.0000000000000001e+227 test util-16.1.17.228 {8.4 compatible formatting of doubles} \ - {expr 1e228} \ + {expr {1e228}} \ 9.9999999999999992e+227 test util-16.1.17.229 {8.4 compatible formatting of doubles} \ - {expr 1e229} \ + {expr {1e229}} \ 9.9999999999999999e+228 test util-16.1.17.230 {8.4 compatible formatting of doubles} \ - {expr 1e230} \ + {expr {1e230}} \ 1.0000000000000001e+230 test util-16.1.17.231 {8.4 compatible formatting of doubles} \ - {expr 1e231} \ + {expr {1e231}} \ 1.0000000000000001e+231 test util-16.1.17.232 {8.4 compatible formatting of doubles} \ - {expr 1e232} \ + {expr {1e232}} \ 1.0000000000000001e+232 test util-16.1.17.233 {8.4 compatible formatting of doubles} \ - {expr 1e233} \ + {expr {1e233}} \ 9.9999999999999997e+232 test util-16.1.17.234 {8.4 compatible formatting of doubles} \ - {expr 1e234} \ + {expr {1e234}} \ 1e+234 test util-16.1.17.235 {8.4 compatible formatting of doubles} \ - {expr 1e235} \ + {expr {1e235}} \ 1.0000000000000001e+235 test util-16.1.17.236 {8.4 compatible formatting of doubles} \ - {expr 1e236} \ + {expr {1e236}} \ 1.0000000000000001e+236 test util-16.1.17.237 {8.4 compatible formatting of doubles} \ - {expr 1e237} \ + {expr {1e237}} \ 9.9999999999999994e+236 test util-16.1.17.238 {8.4 compatible formatting of doubles} \ - {expr 1e238} \ + {expr {1e238}} \ 1e+238 test util-16.1.17.239 {8.4 compatible formatting of doubles} \ - {expr 1e239} \ + {expr {1e239}} \ 9.9999999999999999e+238 test util-16.1.17.240 {8.4 compatible formatting of doubles} \ - {expr 1e240} \ + {expr {1e240}} \ 1e+240 test util-16.1.17.241 {8.4 compatible formatting of doubles} \ - {expr 1e241} \ + {expr {1e241}} \ 1.0000000000000001e+241 test util-16.1.17.242 {8.4 compatible formatting of doubles} \ - {expr 1e242} \ + {expr {1e242}} \ 1.0000000000000001e+242 test util-16.1.17.243 {8.4 compatible formatting of doubles} \ - {expr 1e243} \ + {expr {1e243}} \ 1.0000000000000001e+243 test util-16.1.17.244 {8.4 compatible formatting of doubles} \ - {expr 1e244} \ + {expr {1e244}} \ 1.0000000000000001e+244 test util-16.1.17.245 {8.4 compatible formatting of doubles} \ - {expr 1e245} \ + {expr {1e245}} \ 1e+245 test util-16.1.17.246 {8.4 compatible formatting of doubles} \ - {expr 1e246} \ + {expr {1e246}} \ 1.0000000000000001e+246 test util-16.1.17.247 {8.4 compatible formatting of doubles} \ - {expr 1e247} \ + {expr {1e247}} \ 9.9999999999999995e+246 test util-16.1.17.248 {8.4 compatible formatting of doubles} \ - {expr 1e248} \ + {expr {1e248}} \ 1e+248 test util-16.1.17.249 {8.4 compatible formatting of doubles} \ - {expr 1e249} \ + {expr {1e249}} \ 9.9999999999999992e+248 test util-16.1.17.250 {8.4 compatible formatting of doubles} \ - {expr 1e250} \ + {expr {1e250}} \ 9.9999999999999992e+249 test util-16.1.17.251 {8.4 compatible formatting of doubles} \ - {expr 1e251} \ + {expr {1e251}} \ 1e+251 test util-16.1.17.252 {8.4 compatible formatting of doubles} \ - {expr 1e252} \ + {expr {1e252}} \ 1.0000000000000001e+252 test util-16.1.17.253 {8.4 compatible formatting of doubles} \ - {expr 1e253} \ + {expr {1e253}} \ 9.9999999999999994e+252 test util-16.1.17.254 {8.4 compatible formatting of doubles} \ - {expr 1e254} \ + {expr {1e254}} \ 9.9999999999999994e+253 test util-16.1.17.255 {8.4 compatible formatting of doubles} \ - {expr 1e255} \ + {expr {1e255}} \ 9.9999999999999999e+254 test util-16.1.17.256 {8.4 compatible formatting of doubles} \ - {expr 1e256} \ + {expr {1e256}} \ 1e+256 test util-16.1.17.257 {8.4 compatible formatting of doubles} \ - {expr 1e257} \ + {expr {1e257}} \ 1e+257 test util-16.1.17.258 {8.4 compatible formatting of doubles} \ - {expr 1e258} \ + {expr {1e258}} \ 1.0000000000000001e+258 test util-16.1.17.259 {8.4 compatible formatting of doubles} \ - {expr 1e259} \ + {expr {1e259}} \ 9.9999999999999993e+258 test util-16.1.17.260 {8.4 compatible formatting of doubles} \ - {expr 1e260} \ + {expr {1e260}} \ 1.0000000000000001e+260 test util-16.1.17.261 {8.4 compatible formatting of doubles} \ - {expr 1e261} \ + {expr {1e261}} \ 9.9999999999999993e+260 test util-16.1.17.262 {8.4 compatible formatting of doubles} \ - {expr 1e262} \ + {expr {1e262}} \ 1e+262 test util-16.1.17.263 {8.4 compatible formatting of doubles} \ - {expr 1e263} \ + {expr {1e263}} \ 1e+263 test util-16.1.17.264 {8.4 compatible formatting of doubles} \ - {expr 1e264} \ + {expr {1e264}} \ 1e+264 test util-16.1.17.265 {8.4 compatible formatting of doubles} \ - {expr 1e265} \ + {expr {1e265}} \ 1.0000000000000001e+265 test util-16.1.17.266 {8.4 compatible formatting of doubles} \ - {expr 1e266} \ + {expr {1e266}} \ 1e+266 test util-16.1.17.267 {8.4 compatible formatting of doubles} \ - {expr 1e267} \ + {expr {1e267}} \ 9.9999999999999997e+266 test util-16.1.17.268 {8.4 compatible formatting of doubles} \ - {expr 1e268} \ + {expr {1e268}} \ 9.9999999999999997e+267 test util-16.1.17.269 {8.4 compatible formatting of doubles} \ - {expr 1e269} \ + {expr {1e269}} \ 1e+269 test util-16.1.17.270 {8.4 compatible formatting of doubles} \ - {expr 1e270} \ + {expr {1e270}} \ 1e+270 test util-16.1.17.271 {8.4 compatible formatting of doubles} \ - {expr 1e271} \ + {expr {1e271}} \ 9.9999999999999995e+270 test util-16.1.17.272 {8.4 compatible formatting of doubles} \ - {expr 1e272} \ + {expr {1e272}} \ 1.0000000000000001e+272 test util-16.1.17.273 {8.4 compatible formatting of doubles} \ - {expr 1e273} \ + {expr {1e273}} \ 9.9999999999999995e+272 test util-16.1.17.274 {8.4 compatible formatting of doubles} \ - {expr 1e274} \ + {expr {1e274}} \ 9.9999999999999992e+273 test util-16.1.17.275 {8.4 compatible formatting of doubles} \ - {expr 1e275} \ + {expr {1e275}} \ 9.9999999999999996e+274 test util-16.1.17.276 {8.4 compatible formatting of doubles} \ - {expr 1e276} \ + {expr {1e276}} \ 1.0000000000000001e+276 test util-16.1.17.277 {8.4 compatible formatting of doubles} \ - {expr 1e277} \ + {expr {1e277}} \ 1e+277 test util-16.1.17.278 {8.4 compatible formatting of doubles} \ - {expr 1e278} \ + {expr {1e278}} \ 9.9999999999999996e+277 test util-16.1.17.279 {8.4 compatible formatting of doubles} \ - {expr 1e279} \ + {expr {1e279}} \ 1.0000000000000001e+279 test util-16.1.17.280 {8.4 compatible formatting of doubles} \ - {expr 1e280} \ + {expr {1e280}} \ 1e+280 test util-16.1.17.281 {8.4 compatible formatting of doubles} \ - {expr 1e281} \ + {expr {1e281}} \ 1e+281 test util-16.1.17.282 {8.4 compatible formatting of doubles} \ - {expr 1e282} \ + {expr {1e282}} \ 1e+282 test util-16.1.17.283 {8.4 compatible formatting of doubles} \ - {expr 1e283} \ + {expr {1e283}} \ 9.9999999999999996e+282 test util-16.1.17.284 {8.4 compatible formatting of doubles} \ - {expr 1e284} \ + {expr {1e284}} \ 1.0000000000000001e+284 test util-16.1.17.285 {8.4 compatible formatting of doubles} \ - {expr 1e285} \ + {expr {1e285}} \ 9.9999999999999998e+284 test util-16.1.17.286 {8.4 compatible formatting of doubles} \ - {expr 1e286} \ + {expr {1e286}} \ 1e+286 test util-16.1.17.287 {8.4 compatible formatting of doubles} \ - {expr 1e287} \ + {expr {1e287}} \ 1.0000000000000001e+287 test util-16.1.17.288 {8.4 compatible formatting of doubles} \ - {expr 1e288} \ + {expr {1e288}} \ 1e+288 test util-16.1.17.289 {8.4 compatible formatting of doubles} \ - {expr 1e289} \ + {expr {1e289}} \ 1.0000000000000001e+289 test util-16.1.17.290 {8.4 compatible formatting of doubles} \ - {expr 1e290} \ + {expr {1e290}} \ 1.0000000000000001e+290 test util-16.1.17.291 {8.4 compatible formatting of doubles} \ - {expr 1e291} \ + {expr {1e291}} \ 9.9999999999999996e+290 test util-16.1.17.292 {8.4 compatible formatting of doubles} \ - {expr 1e292} \ + {expr {1e292}} \ 1e+292 test util-16.1.17.293 {8.4 compatible formatting of doubles} \ - {expr 1e293} \ + {expr {1e293}} \ 9.9999999999999992e+292 test util-16.1.17.294 {8.4 compatible formatting of doubles} \ - {expr 1e294} \ + {expr {1e294}} \ 1.0000000000000001e+294 test util-16.1.17.295 {8.4 compatible formatting of doubles} \ - {expr 1e295} \ + {expr {1e295}} \ 9.9999999999999998e+294 test util-16.1.17.296 {8.4 compatible formatting of doubles} \ - {expr 1e296} \ + {expr {1e296}} \ 9.9999999999999998e+295 test util-16.1.17.297 {8.4 compatible formatting of doubles} \ - {expr 1e297} \ + {expr {1e297}} \ 1e+297 test util-16.1.17.298 {8.4 compatible formatting of doubles} \ - {expr 1e298} \ + {expr {1e298}} \ 9.9999999999999996e+297 test util-16.1.17.299 {8.4 compatible formatting of doubles} \ - {expr 1e299} \ + {expr {1e299}} \ 1.0000000000000001e+299 test util-16.1.17.300 {8.4 compatible formatting of doubles} \ - {expr 1e300} \ + {expr {1e300}} \ 1.0000000000000001e+300 test util-16.1.17.301 {8.4 compatible formatting of doubles} \ - {expr 1e301} \ + {expr {1e301}} \ 1.0000000000000001e+301 test util-16.1.17.302 {8.4 compatible formatting of doubles} \ - {expr 1e302} \ + {expr {1e302}} \ 1.0000000000000001e+302 test util-16.1.17.303 {8.4 compatible formatting of doubles} \ - {expr 1e303} \ + {expr {1e303}} \ 1e+303 test util-16.1.17.304 {8.4 compatible formatting of doubles} \ - {expr 1e304} \ + {expr {1e304}} \ 9.9999999999999994e+303 test util-16.1.17.305 {8.4 compatible formatting of doubles} \ - {expr 1e305} \ + {expr {1e305}} \ 9.9999999999999994e+304 test util-16.1.17.306 {8.4 compatible formatting of doubles} \ - {expr 1e306} \ + {expr {1e306}} \ 1e+306 test util-16.1.17.307 {8.4 compatible formatting of doubles} \ - {expr 1e307} \ + {expr {1e307}} \ 9.9999999999999999e+306 test util-17.1 {bankers' rounding [Bug 3349507]} {ieeeFloatingPoint} { @@ -4043,9 +4043,9 @@ test util-17.1 {bankers' rounding [Bug 3349507]} {ieeeFloatingPoint} { 0x1fffffffffffff000 0x1fffffffffffff800 } { - binary scan [binary format q [expr double($input)]] wu x + binary scan [binary format q [expr {double($input)}]] wu x lappend r [format %#llx $x] - binary scan [binary format q [expr double(-$input)]] wu x + binary scan [binary format q [expr {double(-$input)}]] wu x lappend r [format %#llx $x] } set r -- cgit v0.12 From 2cb77a221b5b5d518e3c0dce95f36bc085866f73 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 28 Jan 2021 15:54:53 +0000 Subject: Lowercase package names are recommended now --- library/tm.tcl | 4 ++-- tests/tm.test | 2 +- unix/dltest/pkgb.c | 4 ++-- unix/dltest/pkgd.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/tm.tcl b/library/tm.tcl index 3c0ec22..c1a8f8a 100644 --- a/library/tm.tcl +++ b/library/tm.tcl @@ -316,7 +316,7 @@ proc ::tcl::tm::UnknownHandler {original name args} { proc ::tcl::tm::Defaults {} { global env tcl_platform - regexp {^(\d+)\.(\d+)} [package provide Tcl] - major minor + regexp {^(\d+)\.(\d+)} [package provide tcl] - major minor set exe [file normalize [info nameofexecutable]] # Note that we're using [::list], not [list] because [list] means @@ -359,7 +359,7 @@ proc ::tcl::tm::Defaults {} { # Calls 'path add' to paths to the list of module search paths. proc ::tcl::tm::roots {paths} { - regexp {^(\d+)\.(\d+)} [package provide Tcl] - major minor + regexp {^(\d+)\.(\d+)} [package provide tcl] - major minor foreach pa $paths { set p [file join $pa tcl$major] for {set n $minor} {$n >= 0} {incr n -1} { diff --git a/tests/tm.test b/tests/tm.test index 4dea27d..a1959e6 100644 --- a/tests/tm.test +++ b/tests/tm.test @@ -199,7 +199,7 @@ test tm-3.11 {tm: module path management, remove ignores unknown path} -setup { proc genpaths {base} { # Normalizing picks up drive letters on windows [Bug 1053568] set base [file normalize $base] - regexp {^(\d+)\.(\d+)} [package provide Tcl] - major minor + regexp {^(\d+)\.(\d+)} [package provide tcl] - major minor set results {} set base [file join $base tcl$major] lappend results [file join $base site-tcl] diff --git a/unix/dltest/pkgb.c b/unix/dltest/pkgb.c index 3210669..ebed46d 100644 --- a/unix/dltest/pkgb.c +++ b/unix/dltest/pkgb.c @@ -152,7 +152,7 @@ Pkgb_Init( if (Tcl_InitStubs(interp, "8.5-", 0) == NULL) { return TCL_ERROR; } - code = Tcl_PkgProvide(interp, "Pkgb", "2.3"); + code = Tcl_PkgProvide(interp, "pkgb", "2.3"); if (code != TCL_OK) { return code; } @@ -189,7 +189,7 @@ Pkgb_SafeInit( if (Tcl_InitStubs(interp, "8.5-", 0) == NULL) { return TCL_ERROR; } - code = Tcl_PkgProvide(interp, "Pkgb", "2.3"); + code = Tcl_PkgProvide(interp, "pkgb", "2.3"); if (code != TCL_OK) { return code; } diff --git a/unix/dltest/pkgd.c b/unix/dltest/pkgd.c index 5c799f5..ef0035f 100644 --- a/unix/dltest/pkgd.c +++ b/unix/dltest/pkgd.c @@ -121,7 +121,7 @@ Pkgd_Init( if (Tcl_InitStubs(interp, "8.5-", 0) == NULL) { return TCL_ERROR; } - code = Tcl_PkgProvide(interp, "PKGD", "7.3"); + code = Tcl_PkgProvide(interp, "pkgd", "7.3"); if (code != TCL_OK) { return code; } @@ -158,7 +158,7 @@ Pkgd_SafeInit( if (Tcl_InitStubs(interp, "8.5-", 0) == NULL) { return TCL_ERROR; } - code = Tcl_PkgProvide(interp, "PKGD", "7.3"); + code = Tcl_PkgProvide(interp, "pkgd", "7.3"); if (code != TCL_OK) { return code; } -- cgit v0.12 From 1fb596128b9e989bf27c554b12582de548b78638 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 29 Jan 2021 09:15:41 +0000 Subject: Fix [113be1991e]: zipfs on mac. From now on, --enable-framework automatically means --disable-zipfs, since those 2 options can never work together. --- macosx/GNUmakefile | 2 +- unix/configure | 342 ++++++++++++++++++++++++++--------------------------- unix/configure.ac | 92 +++++++------- 3 files changed, 218 insertions(+), 218 deletions(-) diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile index 93fd843..6451c66 100644 --- a/macosx/GNUmakefile +++ b/macosx/GNUmakefile @@ -88,7 +88,7 @@ space := ${empty} ${empty} objdir = $(subst ${space},\ ,${OBJ_DIR}) develop_make_args := BUILD_STYLE=Development CONFIGURE_ARGS=--enable-symbols -deploy_make_args := BUILD_STYLE=Deployment INSTALL_TARGET=install \ +deploy_make_args := BUILD_STYLE=Deployment INSTALL_TARGET=install-strip \ EXTRA_CFLAGS=-DNDEBUG embedded_make_args := EMBEDDED_BUILD=1 install_make_args := INSTALL_BUILD=1 diff --git a/unix/configure b/unix/configure index f48a252..8974bb1 100755 --- a/unix/configure +++ b/unix/configure @@ -810,8 +810,8 @@ enable_langinfo enable_dll_unloading with_tzdata enable_dtrace -enable_zipfs enable_framework +enable_zipfs ' ac_precious_vars='build_alias host_alias @@ -1459,9 +1459,9 @@ Optional Features: startup, otherwise use old heuristic (default: on) --enable-dll-unloading enable the 'unload' command (default: on) --enable-dtrace build with DTrace support (default: off) - --enable-zipfs build with Zipfs support (default: on) --enable-framework package shared libraries in MacOSX frameworks (default: off) + --enable-zipfs build with Zipfs support (default: on) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -10806,175 +10806,6 @@ fi printf "%s\n" "$tcl_ok" >&6; } #-------------------------------------------------------------------- -# Zipfs support - Tip 430 -#-------------------------------------------------------------------- -# Check whether --enable-zipfs was given. -if test ${enable_zipfs+y} -then : - enableval=$enable_zipfs; tcl_ok=$enableval -else $as_nop - tcl_ok=yes -fi - -if test "$tcl_ok" = "yes" ; then - # - # Find a native compiler - # - # Put a plausible default for CC_FOR_BUILD in Makefile. - if test -z "$CC_FOR_BUILD"; then - if test "x$cross_compiling" = "xno"; then - CC_FOR_BUILD='$(CC)' - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5 -printf %s "checking for gcc... " >&6; } - if test ${ac_cv_path_cc+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/gcc 2> /dev/null` \ - `ls -r $dir/gcc 2> /dev/null` ; do - if test x"$ac_cv_path_cc" = x ; then - if test -f "$j" ; then - ac_cv_path_cc=$j - break - fi - fi - done - done - -fi - - fi - fi - - # Also set EXEEXT_FOR_BUILD. - if test "x$cross_compiling" = "xno"; then - EXEEXT_FOR_BUILD='$(EXEEXT)' - OBJEXT_FOR_BUILD='$(OBJEXT)' - else - OBJEXT_FOR_BUILD='.no' - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5 -printf %s "checking for build system executable suffix... " >&6; } -if test ${bfd_cv_build_exeext+y} -then : - printf %s "(cached) " >&6 -else $as_nop - rm -f conftest* - echo 'int main () { return 0; }' > conftest.c - bfd_cv_build_exeext= - ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 - for file in conftest.*; do - case $file in - *.c | *.o | *.obj | *.ilk | *.pdb) ;; - *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; - esac - done - rm -f conftest* - test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5 -printf "%s\n" "$bfd_cv_build_exeext" >&6; } - EXEEXT_FOR_BUILD="" - test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} - fi - - # - # Find a native zip implementation - # - - ZIP_PROG="" - ZIP_PROG_OPTIONS="" - ZIP_PROG_VFSSEARCH="" - ZIP_INSTALL_OBJS="" - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 -printf %s "checking for zip... " >&6; } - if test ${ac_cv_path_zip+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi - fi - done - done - -fi - - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 -printf "%s\n" "$ZIP_PROG" >&6; } - ZIP_PROG_OPTIONS="-rq" - ZIP_PROG_VFSSEARCH="*" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 -printf "%s\n" "Found INFO Zip in environment" >&6; } - # Use standard arguments for zip - else - # It is not an error if an installed version of Zip can't be located. - # We can use the locally distributed minizip instead - ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o -r" - ZIP_PROG_VFSSEARCH="*" - ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH. Building minizip" >&5 -printf "%s\n" "No zip found on PATH. Building minizip" >&6; } - fi - - - - - - ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip -else - ZIPFS_BUILD=0 - TCL_ZIP_FILE= -fi -# Do checking message here to not mess up interleaved configure output -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5 -printf %s "checking for building with zipfs... " >&6; } -if test "${ZIPFS_BUILD}" = 1; then - if test "${SHARED_BUILD}" = 0; then - ZIPFS_BUILD=2; - -printf "%s\n" "#define ZIPFS_BUILD 2" >>confdefs.h - - INSTALL_LIBRARIES=install-libraries-zipfs-static - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - else - -printf "%s\n" "#define ZIPFS_BUILD 1" >>confdefs.h -\ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - fi -else -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -INSTALL_LIBRARIES=install-libraries -INSTALL_MSGS=install-msgs -fi - - - - - - -#-------------------------------------------------------------------- # The check below checks whether the cpuid instruction is usable. #-------------------------------------------------------------------- @@ -11154,6 +10985,175 @@ eval "CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}" VERSION=${TCL_VERSION} #-------------------------------------------------------------------- +# Zipfs support - Tip 430 +#-------------------------------------------------------------------- +# Check whether --enable-zipfs was given. +if test ${enable_zipfs+y} +then : + enableval=$enable_zipfs; tcl_ok=$enableval +else $as_nop + tcl_ok=yes +fi + +if test "$tcl_ok" = "yes" -a "$enable_framework" = "no"; then + # + # Find a native compiler + # + # Put a plausible default for CC_FOR_BUILD in Makefile. + if test -z "$CC_FOR_BUILD"; then + if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5 +printf %s "checking for gcc... " >&6; } + if test ${ac_cv_path_cc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/gcc 2> /dev/null` \ + `ls -r $dir/gcc 2> /dev/null` ; do + if test x"$ac_cv_path_cc" = x ; then + if test -f "$j" ; then + ac_cv_path_cc=$j + break + fi + fi + done + done + +fi + + fi + fi + + # Also set EXEEXT_FOR_BUILD. + if test "x$cross_compiling" = "xno"; then + EXEEXT_FOR_BUILD='$(EXEEXT)' + OBJEXT_FOR_BUILD='$(OBJEXT)' + else + OBJEXT_FOR_BUILD='.no' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5 +printf %s "checking for build system executable suffix... " >&6; } +if test ${bfd_cv_build_exeext+y} +then : + printf %s "(cached) " >&6 +else $as_nop + rm -f conftest* + echo 'int main () { return 0; }' > conftest.c + bfd_cv_build_exeext= + ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + rm -f conftest* + test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5 +printf "%s\n" "$bfd_cv_build_exeext" >&6; } + EXEEXT_FOR_BUILD="" + test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} + fi + + # + # Find a native zip implementation + # + + ZIP_PROG="" + ZIP_PROG_OPTIONS="" + ZIP_PROG_VFSSEARCH="" + ZIP_INSTALL_OBJS="" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 +printf %s "checking for zip... " >&6; } + if test ${ac_cv_path_zip+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + +fi + + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 +printf "%s\n" "$ZIP_PROG" >&6; } + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="*" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 +printf "%s\n" "Found INFO Zip in environment" >&6; } + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="*" + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH. Building minizip" >&5 +printf "%s\n" "No zip found on PATH. Building minizip" >&6; } + fi + + + + + + ZIPFS_BUILD=1 + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip +else + ZIPFS_BUILD=0 + TCL_ZIP_FILE= +fi +# Do checking message here to not mess up interleaved configure output +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5 +printf %s "checking for building with zipfs... " >&6; } +if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; + +printf "%s\n" "#define ZIPFS_BUILD 2" >>confdefs.h + + INSTALL_LIBRARIES=install-libraries-zipfs-static + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + +printf "%s\n" "#define ZIPFS_BUILD 1" >>confdefs.h +\ + INSTALL_LIBRARIES=install-libraries-zipfs-shared + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + fi +else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +INSTALL_LIBRARIES=install-libraries +INSTALL_MSGS=install-msgs +fi + + + + + + +#-------------------------------------------------------------------- # The statements below define the symbol TCL_PACKAGE_PATH, which # gives a list of directories that may contain packages. The list # consists of one directory for machine-dependent binaries and diff --git a/unix/configure.ac b/unix/configure.ac index d1a5da9..9967ef8 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -759,52 +759,6 @@ fi AC_MSG_RESULT([$tcl_ok]) #-------------------------------------------------------------------- -# Zipfs support - Tip 430 -#-------------------------------------------------------------------- -AC_ARG_ENABLE(zipfs, - AS_HELP_STRING([--enable-zipfs], - [build with Zipfs support (default: on)]), - [tcl_ok=$enableval], [tcl_ok=yes]) -if test "$tcl_ok" = "yes" ; then - # - # Find a native compiler - # - AX_CC_FOR_BUILD - # - # Find a native zip implementation - # - SC_ZIPFS_SUPPORT - ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip -else - ZIPFS_BUILD=0 - TCL_ZIP_FILE= -fi -# Do checking message here to not mess up interleaved configure output -AC_MSG_CHECKING([for building with zipfs]) -if test "${ZIPFS_BUILD}" = 1; then - if test "${SHARED_BUILD}" = 0; then - ZIPFS_BUILD=2; - AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) - INSTALL_LIBRARIES=install-libraries-zipfs-static - AC_MSG_RESULT([yes]) - else - AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - AC_MSG_RESULT([yes]) - fi -else -AC_MSG_RESULT([no]) -INSTALL_LIBRARIES=install-libraries -INSTALL_MSGS=install-msgs -fi -AC_SUBST(ZIPFS_BUILD) -AC_SUBST(TCL_ZIP_FILE) -AC_SUBST(INSTALL_LIBRARIES) -AC_SUBST(INSTALL_MSGS) - - -#-------------------------------------------------------------------- # The check below checks whether the cpuid instruction is usable. #-------------------------------------------------------------------- @@ -918,6 +872,52 @@ eval "CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}" VERSION=${TCL_VERSION} #-------------------------------------------------------------------- +# Zipfs support - Tip 430 +#-------------------------------------------------------------------- +AC_ARG_ENABLE(zipfs, + AS_HELP_STRING([--enable-zipfs], + [build with Zipfs support (default: on)]), + [tcl_ok=$enableval], [tcl_ok=yes]) +if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then + # + # Find a native compiler + # + AX_CC_FOR_BUILD + # + # Find a native zip implementation + # + SC_ZIPFS_SUPPORT + ZIPFS_BUILD=1 + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip +else + ZIPFS_BUILD=0 + TCL_ZIP_FILE= +fi +# Do checking message here to not mess up interleaved configure output +AC_MSG_CHECKING([for building with zipfs]) +if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; + AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) + INSTALL_LIBRARIES=install-libraries-zipfs-static + AC_MSG_RESULT([yes]) + else + AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ + INSTALL_LIBRARIES=install-libraries-zipfs-shared + AC_MSG_RESULT([yes]) + fi +else +AC_MSG_RESULT([no]) +INSTALL_LIBRARIES=install-libraries +INSTALL_MSGS=install-msgs +fi +AC_SUBST(ZIPFS_BUILD) +AC_SUBST(TCL_ZIP_FILE) +AC_SUBST(INSTALL_LIBRARIES) +AC_SUBST(INSTALL_MSGS) + + +#-------------------------------------------------------------------- # The statements below define the symbol TCL_PACKAGE_PATH, which # gives a list of directories that may contain packages. The list # consists of one directory for machine-dependent binaries and -- cgit v0.12 From f6c86d79724c41a91b32d8338fca720f56457b0f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 29 Jan 2021 09:18:36 +0000 Subject: re-generate unix/configure --- unix/configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/configure b/unix/configure index 8974bb1..2943334 100755 --- a/unix/configure +++ b/unix/configure @@ -10995,7 +10995,7 @@ else $as_nop tcl_ok=yes fi -if test "$tcl_ok" = "yes" -a "$enable_framework" = "no"; then +if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then # # Find a native compiler # -- cgit v0.12 From 57f9c7dae5abc33e7c2bfcf5f19bb487d8178719 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 29 Jan 2021 13:45:18 +0000 Subject: Fix 2 warnings when running "autoconf" (2.69 or 2.70) --- unix/configure.in | 2 +- unix/tcl.m4 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/unix/configure.in b/unix/configure.in index 21e47376..641f9bb 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -5,10 +5,10 @@ dnl to configure the system for the local environment. AC_INIT([tcl],[8.6]) AC_PREREQ([2.59]) +AC_CONFIG_HEADERS([tclConfig.h:../unix/tclConfig.h.in]) dnl This is only used when included from macosx/configure.ac m4_ifdef([SC_USE_CONFIG_HEADERS], [ - AC_CONFIG_HEADERS([tclConfig.h:../unix/tclConfig.h.in]) AC_CONFIG_COMMANDS_PRE([DEFS="-DHAVE_TCL_CONFIG_H -imacros tclConfig.h"]) AH_TOP([ #ifndef _TCLCONFIG diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 4665f44..8139569 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2477,8 +2477,8 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [ AC_DEFUN([SC_TCL_EARLY_FLAG],[ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]), AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])], - [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[[#define ]$1[ 1 -]$2]], [[$3]]), + [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ 1 +]$2]], [[$3]])], [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)])) if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then -- cgit v0.12 From 58625c6ba9cf9c05e354858011bc450c6a126f04 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 29 Jan 2021 15:45:01 +0000 Subject: Undo previous change to unix/configure.in --- unix/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/configure.in b/unix/configure.in index 641f9bb..21e47376 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -5,10 +5,10 @@ dnl to configure the system for the local environment. AC_INIT([tcl],[8.6]) AC_PREREQ([2.59]) -AC_CONFIG_HEADERS([tclConfig.h:../unix/tclConfig.h.in]) dnl This is only used when included from macosx/configure.ac m4_ifdef([SC_USE_CONFIG_HEADERS], [ + AC_CONFIG_HEADERS([tclConfig.h:../unix/tclConfig.h.in]) AC_CONFIG_COMMANDS_PRE([DEFS="-DHAVE_TCL_CONFIG_H -imacros tclConfig.h"]) AH_TOP([ #ifndef _TCLCONFIG -- cgit v0.12 From 00e0788723b72c953f9e8a31fdf16cad678b994b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 2 Feb 2021 08:41:35 +0000 Subject: On Big Sur, distingish 11.0, 11.1 and 11.2. platform 1.0.16 -> 1.0.17 --- library/platform/pkgIndex.tcl | 2 +- library/platform/platform.tcl | 10 +++++++--- unix/Makefile.in | 4 ++-- win/Makefile.in | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/library/platform/pkgIndex.tcl b/library/platform/pkgIndex.tcl index 401300a..7983831 100644 --- a/library/platform/pkgIndex.tcl +++ b/library/platform/pkgIndex.tcl @@ -1,3 +1,3 @@ -package ifneeded platform 1.0.16 [list source [file join $dir platform.tcl]] +package ifneeded platform 1.0.17 [list source [file join $dir platform.tcl]] package ifneeded platform::shell 1.1.4 [list source [file join $dir shell.tcl]] diff --git a/library/platform/platform.tcl b/library/platform/platform.tcl index 2c83102..e01334e 100644 --- a/library/platform/platform.tcl +++ b/library/platform/platform.tcl @@ -29,8 +29,10 @@ # are on "Windows NT" or "Windows XP" or whatever. # # Machine specific +# % amd64 -> x86_64 # % arm* -> arm # % sun4* -> sparc +# % ia32* -> ix86 # % intel -> ix86 # % i*86* -> ix86 # % Power* -> powerpc @@ -81,6 +83,7 @@ proc ::platform::generic {} { set cpu ix86 } } + ppc - "Power*" { set cpu powerpc } @@ -177,8 +180,9 @@ proc ::platform::identify {} { macosx { set major [lindex [split $tcl_platform(osVersion) .] 0] if {$major > 19} { - incr major -20 - append plat 11.$major + set minor [lindex [split $tcl_platform(osVersion) .] 1] + incr major -9 + append plat $major.[expr {$minor - 1}] } else { incr major -4 append plat 10.$major @@ -405,7 +409,7 @@ proc ::platform::patterns {id} { # ### ### ### ######### ######### ######### ## Ready -package provide platform 1.0.16 +package provide platform 1.0.17 # ### ### ### ######### ######### ######### ## Demo application diff --git a/unix/Makefile.in b/unix/Makefile.in index 4ad573c..161299e 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -791,8 +791,8 @@ install-libraries: libraries $(INSTALL_TZDATA) install-msgs @echo "Installing package tcltest 2.5.3 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.5.3.tm; - @echo "Installing package platform 1.0.16 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.16.tm; + @echo "Installing package platform 1.0.17 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.17.tm; @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform/shell-1.1.4.tm; diff --git a/win/Makefile.in b/win/Makefile.in index 890292e..9d82961 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -673,8 +673,8 @@ install-libraries: libraries install-tzdata install-msgs @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.5.2.tm; @echo "Installing package tcltest 2.5.3 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.5.3.tm; - @echo "Installing package platform 1.0.16 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.16.tm; + @echo "Installing package platform 1.0.17 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.17.tm; @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/platform/shell.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform/shell-1.1.4.tm; @echo "Installing encodings"; -- cgit v0.12 From 0d69fc832e95cff706d7bb039e2ff329b8c5d202 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 4 Feb 2021 11:11:34 +0000 Subject: Fix [03b70c8918]: core-8-branch : trying to build on macOS10.9 linked against XQuartz --- unix/configure | 65 +++++++++++++++++++++++++++++++++++++++-------------- unix/tcl.m4 | 70 ++++++++++++++++++++++++++++++++-------------------------- win/configure | 35 ++++++++++++++++++++++++++++- win/tcl.m4 | 10 ++++++++- 4 files changed, 131 insertions(+), 49 deletions(-) diff --git a/unix/configure b/unix/configure index 2943334..26de9a8 100755 --- a/unix/configure +++ b/unix/configure @@ -5581,7 +5581,7 @@ fi then : CFLAGS_OPTIMIZE=-O2 - CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8" + CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith" case "${CC}" in *++|*++-*) ;; @@ -7293,11 +7293,11 @@ then : fi - # See if the compiler supports casting to a union type. - # This is used to stop gcc from printing a compiler - # warning when initializing a union member. + # See if the compiler supports casting to a union type. + # This is used to stop gcc from printing a compiler + # warning when initializing a union member. - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5 printf %s "checking for cast to union support... " >&6; } if test ${tcl_cv_cast_to_union+y} then : @@ -7310,8 +7310,8 @@ int main (void) { - union foo { int i; double d; }; - union foo f = (union foo) (int) 0; + union foo { int i; double d; }; + union foo f = (union foo) (int) 0; ; return 0; @@ -7328,13 +7328,13 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5 printf "%s\n" "$tcl_cv_cast_to_union" >&6; } - if test "$tcl_cv_cast_to_union" = "yes"; then + if test "$tcl_cv_cast_to_union" = "yes"; then printf "%s\n" "#define HAVE_CAST_TO_UNION 1" >>confdefs.h - fi - hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working -fno-lto" >&5 + fi + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working -fno-lto" >&5 printf %s "checking for working -fno-lto... " >&6; } if test ${ac_cv_nolto+y} then : @@ -7362,12 +7362,45 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_nolto" >&5 printf "%s\n" "$ac_cv_nolto" >&6; } + CFLAGS=$hold_cflags + if test "$ac_cv_nolto" = "yes" ; then + CFLAGS_NOLTO="-fno-lto" + else + CFLAGS_NOLTO="" + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -finput-charset" >&5 +printf %s "checking if the compiler understands -finput-charset... " >&6; } +if test ${tcl_cv_cc_input_charset+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + tcl_cv_cc_input_charset=yes +else $as_nop + tcl_cv_cc_input_charset=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$hold_cflags - if test "$ac_cv_nolto" = "yes" ; then - CFLAGS_NOLTO="-fno-lto" - else - CFLAGS_NOLTO="" - fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_input_charset" >&5 +printf "%s\n" "$tcl_cv_cc_input_charset" >&6; } + if test $tcl_cv_cc_input_charset = yes; then + CFLAGS="$CFLAGS -finput-charset=UTF-8" + fi ac_fn_c_check_header_compile "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default" if test "x$ac_cv_header_stdbool_h" = xyes diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 08c1907..a8911f8 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -960,7 +960,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CFLAGS_DEBUG=-g AS_IF([test "$GCC" = yes], [ CFLAGS_OPTIMIZE=-O2 - CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8" + CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith" case "${CC}" in *++|*++-*) ;; @@ -1838,36 +1838,44 @@ dnl # preprocessing tests use only CPPFLAGS. TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}"]) AC_SUBST(TCL_LIBS) - # See if the compiler supports casting to a union type. - # This is used to stop gcc from printing a compiler - # warning when initializing a union member. - - AC_CACHE_CHECK(for cast to union support, - tcl_cv_cast_to_union, - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - union foo { int i; double d; }; - union foo f = (union foo) (int) 0; - ]])], - [tcl_cv_cast_to_union=yes], - [tcl_cv_cast_to_union=no]) - ) - if test "$tcl_cv_cast_to_union" = "yes"; then - AC_DEFINE(HAVE_CAST_TO_UNION, 1, - [Defined when compiler supports casting to union type.]) - fi - hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto" - AC_CACHE_CHECK(for working -fno-lto, - ac_cv_nolto, - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], - [ac_cv_nolto=yes], - [ac_cv_nolto=no]) - ) - CFLAGS=$hold_cflags - if test "$ac_cv_nolto" = "yes" ; then - CFLAGS_NOLTO="-fno-lto" - else - CFLAGS_NOLTO="" - fi + # See if the compiler supports casting to a union type. + # This is used to stop gcc from printing a compiler + # warning when initializing a union member. + + AC_CACHE_CHECK(for cast to union support, + tcl_cv_cast_to_union, + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ + union foo { int i; double d; }; + union foo f = (union foo) (int) 0; + ]])], + [tcl_cv_cast_to_union=yes], + [tcl_cv_cast_to_union=no]) + ) + if test "$tcl_cv_cast_to_union" = "yes"; then + AC_DEFINE(HAVE_CAST_TO_UNION, 1, + [Defined when compiler supports casting to union type.]) + fi + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto" + AC_CACHE_CHECK(for working -fno-lto, + ac_cv_nolto, + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], + [ac_cv_nolto=yes], + [ac_cv_nolto=no]) + ) + CFLAGS=$hold_cflags + if test "$ac_cv_nolto" = "yes" ; then + CFLAGS_NOLTO="-fno-lto" + else + CFLAGS_NOLTO="" + fi + AC_CACHE_CHECK([if the compiler understands -finput-charset], + tcl_cv_cc_input_charset, [ + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_input_charset=yes],[tcl_cv_cc_input_charset=no]) + CFLAGS=$hold_cflags]) + if test $tcl_cv_cc_input_charset = yes; then + CFLAGS="$CFLAGS -finput-charset=UTF-8" + fi AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have ?])],) diff --git a/win/configure b/win/configure index 97a680b..ae9e666 100755 --- a/win/configure +++ b/win/configure @@ -4323,6 +4323,39 @@ printf "%s\n" "$ac_cv_nolto" >&6; } else CFLAGS_NOLTO="" fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -finput-charset" >&5 +printf %s "checking if the compiler understands -finput-charset... " >&6; } +if test ${tcl_cv_cc_input_charset+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + tcl_cv_cc_input_charset=yes +else $as_nop + tcl_cv_cc_input_charset=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$hold_cflags +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_input_charset" >&5 +printf "%s\n" "$tcl_cv_cc_input_charset" >&6; } + if test $tcl_cv_cc_input_charset = yes; then + extra_cflags="$extra_cflags -finput-charset=UTF-8" + fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking compiler flags" >&5 @@ -4386,7 +4419,7 @@ printf "%s\n" "using shared flags" >&6; } CFLAGS_DEBUG=-g CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" - CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8" + CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith" LDFLAGS_DEBUG= LDFLAGS_OPTIMIZE= diff --git a/win/tcl.m4 b/win/tcl.m4 index 852aa33..b9a164c 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -617,6 +617,14 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ else CFLAGS_NOLTO="" fi + AC_CACHE_CHECK([if the compiler understands -finput-charset], + tcl_cv_cc_input_charset, [ + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_input_charset=yes],[tcl_cv_cc_input_charset=no]) + CFLAGS=$hold_cflags]) + if test $tcl_cv_cc_input_charset = yes; then + extra_cflags="$extra_cflags -finput-charset=UTF-8" + fi fi AC_MSG_CHECKING([compiler flags]) @@ -677,7 +685,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CFLAGS_DEBUG=-g CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" - CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -finput-charset=UTF-8" + CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith" LDFLAGS_DEBUG= LDFLAGS_OPTIMIZE= -- cgit v0.12 From c09ddd48e3db315912a6c3797f37c0a49a2dfb6d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 4 Feb 2021 13:11:37 +0000 Subject: In a --disable-shared build, attach the zip-file to the executable, so "onfiledist.yml" doesn't need to do that any more --- .github/workflows/onefiledist.yml | 20 ++++++++------------ unix/Makefile.in | 7 ++++++- win/Makefile.in | 7 ++++++- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/.github/workflows/onefiledist.yml b/.github/workflows/onefiledist.yml index 0fb6ba5..eaf9128 100644 --- a/.github/workflows/onefiledist.yml +++ b/.github/workflows/onefiledist.yml @@ -21,13 +21,13 @@ jobs: working-directory: unix - name: Build run: | - make tclsh tclzipfile + make tclsh make shell SCRIPT="$VER_PATH $GITHUB_ENV" echo "TCL_ZIP=`pwd`/`echo libtcl*.zip`" >> $GITHUB_ENV working-directory: unix - name: Package run: | - cat ../unix/tclsh $TCL_ZIP > tclsh${TCL_PATCHLEVEL}_unofficial + cp ../unix/tclsh tclsh${TCL_PATCHLEVEL}_unofficial chmod +x tclsh${TCL_PATCHLEVEL}_unofficial tar -cf tclsh${TCL_PATCHLEVEL}_unofficial.tar tclsh${TCL_PATCHLEVEL}_unofficial working-directory: 1dist @@ -62,7 +62,7 @@ jobs: working-directory: unix - name: Build run: | - make tclsh tclzipfile + make tclsh make shell SCRIPT="$VER_PATH $GITHUB_ENV" echo "TCL_BIN=`pwd`/tclsh" >> $GITHUB_ENV echo "TCL_ZIP=`pwd`/`echo libtcl*.zip`" >> $GITHUB_ENV @@ -70,7 +70,7 @@ jobs: - name: Package run: | mkdir contents - cat $TCL_BIN $TCL_ZIP > contents/tclsh${TCL_PATCHLEVEL}_unofficial + cp $TCL_BIN contents/tclsh${TCL_PATCHLEVEL}_unofficial chmod +x contents/tclsh${TCL_PATCHLEVEL}_unofficial cat > contents/README.txt <> $GITHUB_ENV working-directory: win - - name: Package - run: | - cat ../win/tclsh*.exe $TCL_ZIP > combined.exe - working-directory: 1dist - name: Get Exact Version run: | - ./combined.exe $VER_PATH $GITHUB_ENV - working-directory: 1dist + ./tclsh*.exe $VER_PATH $GITHUB_ENV + working-directory: win - name: Set Executable Name run: | - mv combined.exe tclsh${TCL_PATCHLEVEL}_unofficial.exe + cp ../win/tclsh*.exe tclsh${TCL_PATCHLEVEL}_unofficial.exe working-directory: 1dist - name: Upload uses: actions/upload-artifact@v2 diff --git a/unix/Makefile.in b/unix/Makefile.in index 114f0d1..5988ba6 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -814,10 +814,15 @@ tclLibObjs: # This targets actually build the objects needed for the lib in the above case objs: ${OBJS} -${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} +${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${TCL_ZIP_FILE} ${CC} ${CFLAGS} ${LDFLAGS} ${TCLSH_OBJS} \ @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCL_EXE} + @if test "${ZIPFS_BUILD}" = "2" ; then \ + cat ${TCL_ZIP_FILE} >> ${TCL_EXE}; \ + ${NATIVE_ZIP} -A ${TCL_EXE} \ + || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ + fi # Must be empty so it doesn't conflict with rule for ${TCL_EXE} above ${NATIVE_TCLSH}: diff --git a/win/Makefile.in b/win/Makefile.in index 1412016..5706b08 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -545,11 +545,16 @@ ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} ${DDE_DLL_FILE} ${REG_DLL_FILE} echo "${TCL_ZIP_FILE} successful created with $$zip" && \ cd ..) -$(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) +$(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) ${TCL_ZIP_FILE} $(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) $(COPY) tclsh.exe.manifest $(TCLSH).manifest @VC_MANIFEST_EMBED_EXE@ + @if test "${ZIPFS_BUILD}" = "2" ; then \ + cat ${TCL_ZIP_FILE} >> ${TCLSH}; \ + ${NATIVE_ZIP} -A ${TCLSH} \ + || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ + fi cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) -DUNICODE -D_UNICODE @DEPARG@ $(CC_OBJNAME) -- cgit v0.12 From 3a18a03f3d8489e156393863691903ce200ee574 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 5 Feb 2021 11:34:28 +0000 Subject: Fix filename-11.45 testcase when there are multiple volumes: This testcase only works for the native file system, which is the lastt one. --- tests/fileName.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fileName.test b/tests/fileName.test index 2648049..64aff40 100644 --- a/tests/fileName.test +++ b/tests/fileName.test @@ -1061,10 +1061,10 @@ test filename-11.45 {Tcl_GlobCmd on root volume} -setup { set tmpd [pwd] } -body { catch { - set res1 [glob -dir [lindex [file volumes] 0] -tails *] + set res1 [glob -dir [lindex [file volumes] end-1] -tails *] } catch { - cd [lindex [file volumes] 0] + cd [lindex [file volumes] end-1] set res2 [glob *] } list $res1 $res2 -- cgit v0.12 From d9e28af5f3009abed0834f48bc9b816719ce3e2b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 5 Feb 2021 13:37:26 +0000 Subject: Oops --- tests/fileName.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fileName.test b/tests/fileName.test index 64aff40..7a8ae61 100644 --- a/tests/fileName.test +++ b/tests/fileName.test @@ -1061,10 +1061,10 @@ test filename-11.45 {Tcl_GlobCmd on root volume} -setup { set tmpd [pwd] } -body { catch { - set res1 [glob -dir [lindex [file volumes] end-1] -tails *] + set res1 [glob -dir [lindex [file volumes] end] -tails *] } catch { - cd [lindex [file volumes] end-1] + cd [lindex [file volumes] end] set res2 [glob *] } list $res1 $res2 -- cgit v0.12 From fed1ff66dc94e36bd81d2375954f2f011f8c329a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 5 Feb 2021 13:42:40 +0000 Subject: More implicit type-casts, for better compatibility with C++ --- generic/tclAssembly.c | 85 +++++++++++++++++++++++++-------------------------- generic/tclAsync.c | 2 +- generic/tclBinary.c | 26 ++++++++-------- generic/tclClock.c | 28 ++++++++--------- generic/tclCmdIL.c | 42 ++++++++++++------------- generic/tclInt.h | 2 +- 6 files changed, 92 insertions(+), 93 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 94cb53c..7ecc1d5 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -497,7 +497,7 @@ static const TalInstDesc TalInstructionTable[] = { {"variable", ASSEM_LVT4, INST_VARIABLE, 1, 0}, {"verifyDict", ASSEM_1BYTE, INST_DICT_VERIFY, 1, 0}, {"yield", ASSEM_1BYTE, INST_YIELD, 1, 1}, - {NULL, 0, 0, 0, 0} + {NULL, ASSEM_1BYTE, 0, 0, 0} }; /* @@ -848,7 +848,6 @@ CompileAssembleObj( const char* source; /* String representation of the source code */ int sourceLen; /* Length of the source code in bytes */ - /* * Get the expression ByteCode from the object. If it exists, make sure it * is valid in the current context. @@ -856,7 +855,7 @@ CompileAssembleObj( if (objPtr->typePtr == &assembleCodeType) { namespacePtr = iPtr->varFramePtr->nsPtr; - codePtr = objPtr->internalRep.twoPtrValue.ptr1; + codePtr = (ByteCode *)objPtr->internalRep.twoPtrValue.ptr1; if (((Interp *) *codePtr->interpHandle == iPtr) && (codePtr->compileEpoch == iPtr->compileEpoch) && (codePtr->nsPtr == namespacePtr) @@ -903,7 +902,7 @@ CompileAssembleObj( * Record the local variable context to which the bytecode pertains */ - codePtr = objPtr->internalRep.twoPtrValue.ptr1; + codePtr = (ByteCode *)objPtr->internalRep.twoPtrValue.ptr1; if (iPtr->varFramePtr->localCachePtr) { codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr; codePtr->localCachePtr->refCount++; @@ -1144,9 +1143,9 @@ NewAssemblyEnv( { Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr; /* Tcl interpreter */ - AssemblyEnv* assemEnvPtr = TclStackAlloc(interp, sizeof(AssemblyEnv)); + AssemblyEnv* assemEnvPtr = (AssemblyEnv*)TclStackAlloc(interp, sizeof(AssemblyEnv)); /* Assembler environment under construction */ - Tcl_Parse* parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse)); + Tcl_Parse* parsePtr = (Tcl_Parse*)TclStackAlloc(interp, sizeof(Tcl_Parse)); /* Parse of one line of assembly code */ assemEnvPtr->envPtr = envPtr; @@ -1534,7 +1533,7 @@ AssembleOneLine( goto cleanup; } - jtPtr = ckalloc(sizeof(JumptableInfo)); + jtPtr = (JumptableInfo*)ckalloc(sizeof(JumptableInfo)); Tcl_InitHashTable(&jtPtr->hashTable, TCL_STRING_KEYS); assemEnvPtr->curr_bb->jumpLine = assemEnvPtr->cmdLine; @@ -1928,7 +1927,7 @@ MoveExceptionRangesToBasicBlock( curr_bb->foreignExceptionBase = savedExceptArrayNext; curr_bb->foreignExceptionCount = exceptionCount; curr_bb->foreignExceptions = - ckalloc(exceptionCount * sizeof(ExceptionRange)); + (ExceptionRange*)ckalloc(exceptionCount * sizeof(ExceptionRange)); memcpy(curr_bb->foreignExceptions, envPtr->exceptArrayPtr + savedExceptArrayNext, exceptionCount * sizeof(ExceptionRange)); @@ -1993,7 +1992,7 @@ CreateMirrorJumpTable( * Allocate the jumptable. */ - jtPtr = ckalloc(sizeof(JumptableInfo)); + jtPtr = (JumptableInfo*)ckalloc(sizeof(JumptableInfo)); jtHashPtr = &jtPtr->hashTable; Tcl_InitHashTable(jtHashPtr, TCL_STRING_KEYS); @@ -2053,7 +2052,7 @@ DeleteMirrorJumpTable( for (entry = Tcl_FirstHashEntry(jtHashPtr, &search); entry != NULL; entry = Tcl_NextHashEntry(&search)) { - label = Tcl_GetHashValue(entry); + label = (Tcl_Obj*)Tcl_GetHashValue(entry); Tcl_DecrRefCount(label); Tcl_SetHashValue(entry, NULL); } @@ -2642,7 +2641,7 @@ AllocBB( AssemblyEnv* assemEnvPtr) /* Assembly environment */ { CompileEnv* envPtr = assemEnvPtr->envPtr; - BasicBlock *bb = ckalloc(sizeof(BasicBlock)); + BasicBlock *bb = (BasicBlock*)ckalloc(sizeof(BasicBlock)); bb->originalStartOffset = bb->startOffset = envPtr->codeNext - envPtr->codeStart; @@ -2833,7 +2832,7 @@ CalculateJumpRelocations( * target is out of range. */ - jumpTarget = Tcl_GetHashValue(entry); + jumpTarget = (BasicBlock*)Tcl_GetHashValue(entry); if (bbPtr->flags & BB_JUMP1) { offset = jumpTarget->startOffset - (bbPtr->jumpOffset + motion); @@ -2900,7 +2899,7 @@ CheckJumpTableLabels( for (symEntryPtr = Tcl_FirstHashEntry(symHash, &search); symEntryPtr != NULL; symEntryPtr = Tcl_NextHashEntry(&search)) { - symbolObj = Tcl_GetHashValue(symEntryPtr); + symbolObj = (Tcl_Obj*)Tcl_GetHashValue(symEntryPtr); valEntryPtr = Tcl_FindHashEntry(&assemEnvPtr->labelHash, Tcl_GetString(symbolObj)); DEBUG_PRINT(" %s -> %s (%d)\n", @@ -3029,7 +3028,7 @@ FillInJumpOffsets( if (bbPtr->jumpTarget != NULL) { entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash, Tcl_GetString(bbPtr->jumpTarget)); - jumpTarget = Tcl_GetHashValue(entry); + jumpTarget = (BasicBlock*)Tcl_GetHashValue(entry); fromOffset = bbPtr->jumpOffset; targetOffset = jumpTarget->startOffset; if (bbPtr->flags & BB_JUMP1) { @@ -3088,7 +3087,7 @@ ResolveJumpTableTargets( auxDataIndex = TclGetInt4AtPtr(envPtr->codeStart + bbPtr->jumpOffset + 1); DEBUG_PRINT("bbPtr = %p jumpOffset = %d auxDataIndex = %d\n", bbPtr, bbPtr->jumpOffset, auxDataIndex); - realJumpTablePtr = TclFetchAuxData(envPtr, auxDataIndex); + realJumpTablePtr = (JumptableInfo*)TclFetchAuxData(envPtr, auxDataIndex); realJumpHashPtr = &realJumpTablePtr->hashTable; /* @@ -3099,12 +3098,12 @@ ResolveJumpTableTargets( for (symEntryPtr = Tcl_FirstHashEntry(symHash, &search); symEntryPtr != NULL; symEntryPtr = Tcl_NextHashEntry(&search)) { - symbolObj = Tcl_GetHashValue(symEntryPtr); + symbolObj = (Tcl_Obj*)Tcl_GetHashValue(symEntryPtr); DEBUG_PRINT(" symbol %s\n", Tcl_GetString(symbolObj)); valEntryPtr = Tcl_FindHashEntry(&assemEnvPtr->labelHash, Tcl_GetString(symbolObj)); - jumpTargetBBPtr = Tcl_GetHashValue(valEntryPtr); + jumpTargetBBPtr = (BasicBlock*)Tcl_GetHashValue(valEntryPtr); realJumpEntryPtr = Tcl_CreateHashEntry(realJumpHashPtr, Tcl_GetHashKey(symHash, symEntryPtr), &junk); @@ -3483,7 +3482,7 @@ StackCheckBasicBlock( if (result == TCL_OK && blockPtr->jumpTarget != NULL) { entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash, Tcl_GetString(blockPtr->jumpTarget)); - jumpTarget = Tcl_GetHashValue(entry); + jumpTarget = (BasicBlock*)Tcl_GetHashValue(entry); result = StackCheckBasicBlock(assemEnvPtr, jumpTarget, blockPtr, stackDepth); } @@ -3497,10 +3496,10 @@ StackCheckBasicBlock( &jtSearch); result == TCL_OK && jtEntry != NULL; jtEntry = Tcl_NextHashEntry(&jtSearch)) { - targetLabel = Tcl_GetHashValue(jtEntry); + targetLabel = (Tcl_Obj*)Tcl_GetHashValue(jtEntry); entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash, Tcl_GetString(targetLabel)); - jumpTarget = Tcl_GetHashValue(entry); + jumpTarget = (BasicBlock*)Tcl_GetHashValue(entry); result = StackCheckBasicBlock(assemEnvPtr, jumpTarget, blockPtr, stackDepth); } @@ -3805,7 +3804,7 @@ ProcessCatchesInBasicBlock( if (result == TCL_OK && bbPtr->jumpTarget != NULL) { entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash, Tcl_GetString(bbPtr->jumpTarget)); - jumpTarget = Tcl_GetHashValue(entry); + jumpTarget = (BasicBlock*)Tcl_GetHashValue(entry); result = ProcessCatchesInBasicBlock(assemEnvPtr, jumpTarget, jumpEnclosing, jumpState, catchDepth); } @@ -3818,10 +3817,10 @@ ProcessCatchesInBasicBlock( for (jtEntry = Tcl_FirstHashEntry(&bbPtr->jtPtr->hashTable,&jtSearch); result == TCL_OK && jtEntry != NULL; jtEntry = Tcl_NextHashEntry(&jtSearch)) { - targetLabel = Tcl_GetHashValue(jtEntry); + targetLabel = (Tcl_Obj*)Tcl_GetHashValue(jtEntry); entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash, Tcl_GetString(targetLabel)); - jumpTarget = Tcl_GetHashValue(entry); + jumpTarget = (BasicBlock*)Tcl_GetHashValue(entry); result = ProcessCatchesInBasicBlock(assemEnvPtr, jumpTarget, jumpEnclosing, jumpState, catchDepth); } @@ -3920,8 +3919,8 @@ BuildExceptionRanges( * Allocate memory for a stack of active catches. */ - catches = ckalloc(maxCatchDepth * sizeof(BasicBlock*)); - catchIndices = ckalloc(maxCatchDepth * sizeof(int)); + catches = (BasicBlock**)ckalloc(maxCatchDepth * sizeof(BasicBlock*)); + catchIndices = (int *)ckalloc(maxCatchDepth * sizeof(int)); for (i = 0; i < maxCatchDepth; ++i) { catches[i] = NULL; catchIndices[i] = -1; @@ -3989,7 +3988,7 @@ UnstackExpiredCatches( * corresponding to the catch contexts */ { ExceptionRange* range; /* Exception range for a specific catch */ - BasicBlock* catch; /* Catch block being examined */ + BasicBlock* block; /* Catch block being examined */ BasicBlockCatchState catchState; /* State of the code relative to the catch * block being examined ("in catch" or @@ -4017,18 +4016,18 @@ UnstackExpiredCatches( */ catchState = bbPtr->catchState; - catch = bbPtr->enclosingCatch; + block = bbPtr->enclosingCatch; while (catchDepth > 0) { --catchDepth; if (catches[catchDepth] != NULL) { - if (catches[catchDepth] != catch || catchState >= BBCS_CAUGHT) { + if (catches[catchDepth] != block || catchState >= BBCS_CAUGHT) { range = envPtr->exceptArrayPtr + catchIndices[catchDepth]; range->numCodeBytes = bbPtr->startOffset - range->codeOffset; catches[catchDepth] = NULL; catchIndices[catchDepth] = -1; } - catchState = catch->catchState; - catch = catch->enclosingCatch; + catchState = block->catchState; + block = block->enclosingCatch; } } } @@ -4057,19 +4056,19 @@ LookForFreshCatches( BasicBlockCatchState catchState; /* State ("in catch" or "caught") of the * current catch. */ - BasicBlock* catch; /* Current enclosing catch */ + BasicBlock* block; /* Current enclosing catch */ int catchDepth; /* Nesting depth of the current catch */ catchState = bbPtr->catchState; - catch = bbPtr->enclosingCatch; + block = bbPtr->enclosingCatch; catchDepth = bbPtr->catchDepth; while (catchDepth > 0) { --catchDepth; - if (catches[catchDepth] != catch && catchState < BBCS_CAUGHT) { - catches[catchDepth] = catch; + if (catches[catchDepth] != block && catchState < BBCS_CAUGHT) { + catches[catchDepth] = block; } - catchState = catch->catchState; - catch = catch->enclosingCatch; + catchState = block->catchState; + block = block->enclosingCatch; } } @@ -4097,7 +4096,7 @@ StackFreshCatches( CompileEnv* envPtr = assemEnvPtr->envPtr; /* Compilation environment */ ExceptionRange* range; /* Exception range for a specific catch */ - BasicBlock* catch; /* Catch block being examined */ + BasicBlock* block; /* Catch block being examined */ BasicBlock* errorExit; /* Error exit from the catch block */ Tcl_HashEntry* entryPtr; @@ -4114,7 +4113,7 @@ StackFreshCatches( * Create an exception range for a block that needs one. */ - catch = catches[catchDepth]; + block = catches[catchDepth]; catchIndices[catchDepth] = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr); range = envPtr->exceptArrayPtr + catchIndices[catchDepth]; @@ -4124,13 +4123,13 @@ StackFreshCatches( range->codeOffset = bbPtr->startOffset; entryPtr = Tcl_FindHashEntry(&assemEnvPtr->labelHash, - Tcl_GetString(catch->jumpTarget)); + Tcl_GetString(block->jumpTarget)); if (entryPtr == NULL) { Tcl_Panic("undefined label in tclAssembly.c:" "BuildExceptionRanges, can't happen"); } - errorExit = Tcl_GetHashValue(entryPtr); + errorExit = (BasicBlock*)Tcl_GetHashValue(entryPtr); range->catchOffset = errorExit->startOffset; } } @@ -4308,6 +4307,7 @@ DupAssembleCodeInternalRep( { (void)srcPtr; (void)copyPtr; + return; } @@ -4333,10 +4333,9 @@ static void FreeAssembleCodeInternalRep( Tcl_Obj *objPtr) { - ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; + ByteCode *codePtr = (ByteCode *)objPtr->internalRep.twoPtrValue.ptr1; - codePtr->refCount--; - if (codePtr->refCount <= 0) { + if (codePtr->refCount-- <= 1) { TclCleanupByteCode(codePtr); } objPtr->typePtr = NULL; diff --git a/generic/tclAsync.c b/generic/tclAsync.c index 14804e4..d1871f9 100644 --- a/generic/tclAsync.c +++ b/generic/tclAsync.c @@ -118,7 +118,7 @@ Tcl_AsyncCreate( AsyncHandler *asyncPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - asyncPtr = ckalloc(sizeof(AsyncHandler)); + asyncPtr = (AsyncHandler *)ckalloc(sizeof(AsyncHandler)); asyncPtr->ready = 0; asyncPtr->nextPtr = NULL; asyncPtr->proc = proc; diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 8520ec7..eb85103 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -420,7 +420,7 @@ Tcl_SetByteArrayLength( byteArrayPtr = GET_BYTEARRAY(objPtr); if (length > byteArrayPtr->allocated) { - byteArrayPtr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(length)); + byteArrayPtr = (ByteArray *)ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(length)); byteArrayPtr->allocated = length; SET_BYTEARRAY(objPtr, byteArrayPtr); } @@ -669,7 +669,7 @@ TclAppendBytesToByteArray( */ attempt = 2 * needed; - ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); + ptr = (ByteArray *)attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); } if (ptr == NULL) { /* @@ -681,7 +681,7 @@ TclAppendBytesToByteArray( int growth = (int) ((extra > limit) ? limit : extra); attempt = needed + growth; - ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); + ptr = (ByteArray *)attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); } if (ptr == NULL) { /* @@ -689,7 +689,7 @@ TclAppendBytesToByteArray( */ attempt = needed; - ptr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); + ptr = (ByteArray *)ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); } byteArrayPtr = ptr; byteArrayPtr->allocated = attempt; @@ -1806,8 +1806,8 @@ CopyNumber( memcpy(to, from, length); break; case 1: { - const unsigned char *fromPtr = from; - unsigned char *toPtr = to; + const unsigned char *fromPtr = (const unsigned char *)from; + unsigned char *toPtr = (unsigned char *)to; switch (length) { case 4: @@ -1830,8 +1830,8 @@ CopyNumber( break; } case 2: { - const unsigned char *fromPtr = from; - unsigned char *toPtr = to; + const unsigned char *fromPtr = (const unsigned char *)from; + unsigned char *toPtr = (unsigned char *)to; toPtr[0] = fromPtr[4]; toPtr[1] = fromPtr[5]; @@ -1844,8 +1844,8 @@ CopyNumber( break; } case 3: { - const unsigned char *fromPtr = from; - unsigned char *toPtr = to; + const unsigned char *fromPtr = (const unsigned char *)from; + unsigned char *toPtr = (unsigned char *)to; toPtr[0] = fromPtr[3]; toPtr[1] = fromPtr[2]; @@ -2152,7 +2152,7 @@ ScanNumber( hPtr = Tcl_CreateHashEntry(tablePtr, INT2PTR(value), &isNew); if (!isNew) { - return Tcl_GetHashValue(hPtr); + return (Tcl_Obj *)Tcl_GetHashValue(hPtr); } if (tablePtr->numEntries <= BINARY_SCAN_MAX_CACHE) { Tcl_Obj *objPtr = Tcl_NewLongObj(value); @@ -2274,7 +2274,7 @@ DeleteScanNumberCache( hEntry = Tcl_FirstHashEntry(numberCachePtr, &search); while (hEntry != NULL) { - Tcl_Obj *value = Tcl_GetHashValue(hEntry); + Tcl_Obj *value = (Tcl_Obj *)Tcl_GetHashValue(hEntry); if (value != NULL) { Tcl_DecrRefCount(value); @@ -2689,7 +2689,7 @@ BinaryEncodeUu( * enough". */ - resultObj = Tcl_NewObj(); + TclNewObj(resultObj); offset = 0; data = Tcl_GetByteArrayFromObj(objv[objc - 1], &count); rawLength = (lineLength - 1) * 3 / 4; diff --git a/generic/tclClock.c b/generic/tclClock.c index bab9fa5..37883bb 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -275,9 +275,9 @@ TclClockInit( * Create the client data, which is a refcounted literal pool. */ - data = ckalloc(sizeof(ClockClientData)); + data = (ClockClientData *)ckalloc(sizeof(ClockClientData)); data->refCount = 0; - data->literals = ckalloc(LIT__END * sizeof(Tcl_Obj*)); + data->literals = (Tcl_Obj **)ckalloc(LIT__END * sizeof(Tcl_Obj*)); for (i = 0; i < LIT__END; ++i) { data->literals[i] = Tcl_NewStringObj(literals[i], -1); Tcl_IncrRefCount(data->literals[i]); @@ -336,7 +336,7 @@ ClockConvertlocaltoutcObjCmd( int objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter vector */ { - ClockClientData *data = clientData; + ClockClientData *data = (ClockClientData *)clientData; Tcl_Obj *const *lit = data->literals; Tcl_Obj *secondsObj; Tcl_Obj *dict; @@ -430,7 +430,7 @@ ClockGetdatefieldsObjCmd( { TclDateFields fields; Tcl_Obj *dict; - ClockClientData *data = clientData; + ClockClientData *data = (ClockClientData *)clientData; Tcl_Obj *const *lit = data->literals; int changeover; @@ -584,7 +584,7 @@ ClockGetjuliandayfromerayearmonthdayObjCmd( { TclDateFields fields; Tcl_Obj *dict; - ClockClientData *data = clientData; + ClockClientData *data = (ClockClientData *)clientData; Tcl_Obj *const *lit = data->literals; int changeover; int copied = 0; @@ -668,7 +668,7 @@ ClockGetjuliandayfromerayearweekdayObjCmd( { TclDateFields fields; Tcl_Obj *dict; - ClockClientData *data = clientData; + ClockClientData *data = (ClockClientData *)clientData; Tcl_Obj *const *lit = data->literals; int changeover; int copied = 0; @@ -1693,7 +1693,7 @@ ThreadSafeLocalTime( * Get a thread-local buffer to hold the returned time. */ - struct tm *tmPtr = Tcl_GetThreadData(&tmKey, sizeof(struct tm)); + struct tm *tmPtr = (struct tm *)Tcl_GetThreadData(&tmKey, sizeof(struct tm)); #ifdef HAVE_LOCALTIME_R localtime_r(timePtr, tmPtr); #else @@ -1879,7 +1879,7 @@ ClockParseformatargsObjCmd( int objc, /* Parameter count */ Tcl_Obj *const objv[]) /* Parameter vector */ { - ClockClientData *dataPtr = clientData; + ClockClientData *dataPtr = (ClockClientData *)clientData; Tcl_Obj **litPtr = dataPtr->literals; Tcl_Obj *results[3]; /* Format, locale and timezone */ #define formatObj results[0] @@ -2029,23 +2029,23 @@ ClockSecondsObjCmd( static void TzsetIfNecessary(void) { - static char* tzWas = INT2PTR(-1); /* Previous value of TZ, protected by + static char* tzWas = (char*)INT2PTR(-1); /* Previous value of TZ, protected by * clockMutex. */ const char *tzIsNow; /* Current value of TZ */ Tcl_MutexLock(&clockMutex); tzIsNow = getenv("TZ"); - if (tzIsNow != NULL && (tzWas == NULL || tzWas == INT2PTR(-1) + if (tzIsNow != NULL && (tzWas == NULL || tzWas == (char*)INT2PTR(-1) || strcmp(tzIsNow, tzWas) != 0)) { tzset(); - if (tzWas != NULL && tzWas != INT2PTR(-1)) { + if (tzWas != NULL && tzWas != (char*)INT2PTR(-1)) { ckfree(tzWas); } - tzWas = ckalloc(strlen(tzIsNow) + 1); + tzWas = (char *)ckalloc(strlen(tzIsNow) + 1); strcpy(tzWas, tzIsNow); } else if (tzIsNow == NULL && tzWas != NULL) { tzset(); - if (tzWas != INT2PTR(-1)) ckfree(tzWas); + if (tzWas != (char*)INT2PTR(-1)) ckfree(tzWas); tzWas = NULL; } Tcl_MutexUnlock(&clockMutex); @@ -2069,7 +2069,7 @@ static void ClockDeleteCmdProc( ClientData clientData) /* Opaque pointer to the client data */ { - ClockClientData *data = clientData; + ClockClientData *data = (ClockClientData *)clientData; int i; if (data->refCount-- <= 1) { diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 85416a1..7583775 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -248,9 +248,9 @@ IfConditionCallback( { Interp *iPtr = (Interp *) interp; int objc = PTR2INT(data[0]); - Tcl_Obj *const *objv = data[1]; + Tcl_Obj *const *objv = (Tcl_Obj *const *)data[1]; int i = PTR2INT(data[2]); - Tcl_Obj *boolObj = data[3]; + Tcl_Obj *boolObj = (Tcl_Obj *)data[3]; int value, thenScriptIndex = 0; const char *clause; @@ -718,11 +718,11 @@ InfoCommandsCmd( entryPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern); if (entryPtr != NULL) { if (specificNsInPattern) { - cmd = Tcl_GetHashValue(entryPtr); + cmd = (Tcl_Command)Tcl_GetHashValue(entryPtr); TclNewObj(elemObjPtr); Tcl_GetCommandFullName(interp, cmd, elemObjPtr); } else { - cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); + cmdName = (const char *)Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); elemObjPtr = Tcl_NewStringObj(cmdName, -1); } Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr); @@ -749,7 +749,7 @@ InfoCommandsCmd( entryPtr = Tcl_FindHashEntry(tablePtr, simplePattern); } if (entryPtr != NULL) { - cmdName = Tcl_GetHashKey(tablePtr, entryPtr); + cmdName = (const char *)Tcl_GetHashKey(tablePtr, entryPtr); Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(cmdName, -1)); Tcl_SetObjResult(interp, listPtr); @@ -765,11 +765,11 @@ InfoCommandsCmd( entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); while (entryPtr != NULL) { - cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); + cmdName = (const char *)Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { if (specificNsInPattern) { - cmd = Tcl_GetHashValue(entryPtr); + cmd = (Tcl_Command)Tcl_GetHashValue(entryPtr); TclNewObj(elemObjPtr); Tcl_GetCommandFullName(interp, cmd, elemObjPtr); } else { @@ -791,7 +791,7 @@ InfoCommandsCmd( if ((nsPtr != globalNsPtr) && !specificNsInPattern) { entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search); while (entryPtr != NULL) { - cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr); + cmdName = (const char *)Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { if (Tcl_FindHashEntry(&nsPtr->cmdTable,cmdName) == NULL) { @@ -822,7 +822,7 @@ InfoCommandsCmd( entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); while (entryPtr != NULL) { - cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); + cmdName = (const char *)Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { elemObjPtr = Tcl_NewStringObj(cmdName, -1); @@ -848,7 +848,7 @@ InfoCommandsCmd( } entryPtr = Tcl_FirstHashEntry(&pathNsPtr->cmdTable, &search); while (entryPtr != NULL) { - cmdName = Tcl_GetHashKey(&pathNsPtr->cmdTable, entryPtr); + cmdName = (const char *)Tcl_GetHashKey(&pathNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { elemObjPtr = Tcl_NewStringObj(cmdName, -1); @@ -875,7 +875,7 @@ InfoCommandsCmd( if (!foundGlobal) { entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search); while (entryPtr != NULL) { - cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr); + cmdName = (const char *)Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { elemObjPtr = Tcl_NewStringObj(cmdName, -1); @@ -1321,7 +1321,7 @@ TclInfoFrame( * Execution of bytecode. Talk to the BC engine to fill out the frame. */ - CmdFrame *fPtr = TclStackAlloc(interp, sizeof(CmdFrame)); + CmdFrame *fPtr = (CmdFrame *)TclStackAlloc(interp, sizeof(CmdFrame)); *fPtr = *framePtr; @@ -1403,7 +1403,7 @@ TclInfoFrame( procNameObj); ADD_PAIR("proc", procNameObj); } else if (procPtr->cmdPtr->clientData) { - ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData; + ExtraFrameInfo *efiPtr = (ExtraFrameInfo *)procPtr->cmdPtr->clientData; int i; /* @@ -1417,7 +1417,7 @@ TclInfoFrame( lv[lc++] = efiPtr->fields[i].proc(efiPtr->fields[i].clientData); } else { - lv[lc++] = efiPtr->fields[i].clientData; + lv[lc++] = (Tcl_Obj *)efiPtr->fields[i].clientData; } } } @@ -1898,7 +1898,7 @@ InfoProcsCmd( if (simplePattern != NULL && TclMatchIsTrivial(simplePattern)) { entryPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern); if (entryPtr != NULL) { - cmdPtr = Tcl_GetHashValue(entryPtr); + cmdPtr = (Command *)Tcl_GetHashValue(entryPtr); if (!TclIsProc(cmdPtr)) { realCmdPtr = (Command *) @@ -1923,10 +1923,10 @@ InfoProcsCmd( { entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); while (entryPtr != NULL) { - cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); + cmdName = (const char *)Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr); if ((simplePattern == NULL) || Tcl_StringMatch(cmdName, simplePattern)) { - cmdPtr = Tcl_GetHashValue(entryPtr); + cmdPtr = (Command *)Tcl_GetHashValue(entryPtr); if (!TclIsProc(cmdPtr)) { realCmdPtr = (Command *) @@ -3085,7 +3085,7 @@ Tcl_LsearchObjCmd( sortInfo.indexv = &sortInfo.singleIndex; break; default: - sortInfo.indexv = + sortInfo.indexv = (int *) TclStackAlloc(interp, sizeof(int) * sortInfo.indexc); } @@ -3843,7 +3843,7 @@ Tcl_LsortObjCmd( sortInfo.indexv = &sortInfo.singleIndex; break; default: - sortInfo.indexv = + sortInfo.indexv = (int *) TclStackAlloc(interp, sizeof(int) * sortInfo.indexc); allocatedIndexVector = 1; /* Cannot use indexc field, as it * might be decreased by 1 later. */ @@ -3982,9 +3982,9 @@ Tcl_LsortObjCmd( elmArrSize = length * sizeof(SortElement); if (elmArrSize <= MAXCALLOC) { - elementArray = ckalloc(elmArrSize); + elementArray = (SortElement *)ckalloc(elmArrSize); } else { - elementArray = malloc(elmArrSize); + elementArray = (SortElement *)malloc(elmArrSize); } if (!elementArray) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( diff --git a/generic/tclInt.h b/generic/tclInt.h index f2f097c..df29da8 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4215,7 +4215,7 @@ MODULE_SCOPE void TclpFreeAllocCache(void *); (objPtr) = TclThreadAllocObj(); \ } else { \ (objPtr) = cachePtr->firstObjPtr; \ - cachePtr->firstObjPtr = (objPtr)->internalRep.twoPtrValue.ptr1; \ + cachePtr->firstObjPtr = (Tcl_Obj *)(objPtr)->internalRep.twoPtrValue.ptr1; \ --cachePtr->numObjects; \ } \ } while (0) -- cgit v0.12 From fa2bb177ebd40bbd17d74535df0e5ba6769e3175 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 Feb 2021 09:21:37 +0000 Subject: Makefile cleanup: Remove *.zip and *.vfs files/directories as part of "make clean", which might be a leftover of a previous Tcl 8.7 build in this directory --- unix/Makefile.in | 105 +++++++++++++++++++++++++------------------------------ win/Makefile.in | 5 +-- win/makefile.vc | 3 +- 3 files changed, 52 insertions(+), 61 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 161299e..4174069 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -28,6 +28,7 @@ bindir = @bindir@ libdir = @libdir@ includedir = @includedir@ datarootdir = @datarootdir@ +runstatedir = @runstatedir@ mandir = @mandir@ # The following definition can be set to non-null for special systems like AFS @@ -148,8 +149,8 @@ SHELL = @MAKEFILE_SHELL@ # around; better to use the install-sh script that comes with the # distribution, which is slower but guaranteed to work. -INSTALL_STRIP_PROGRAM = -s -INSTALL_STRIP_LIBRARY = -S -x +INSTALL_STRIP_PROGRAM = -s +INSTALL_STRIP_LIBRARY = -S -x INSTALL = $(SHELL) $(UNIX_DIR)/install-sh -c INSTALL_PROGRAM = ${INSTALL} @@ -176,7 +177,6 @@ SHLIB_LD_FLAGS = @SHLIB_LD_FLAGS@ TCL_SHLIB_LD_EXTRAS = @TCL_SHLIB_LD_EXTRAS@ SHLIB_SUFFIX = @SHLIB_SUFFIX@ -#SHLIB_SUFFIX = DLTEST_TARGETS = dltest.marker @@ -719,14 +719,12 @@ install-strip: install-binaries: binaries @for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" \ - "$(CONFIG_INSTALL_DIR)"; \ - do \ + "$(CONFIG_INSTALL_DIR)" ; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; + fi; \ + done @echo "Installing $(LIB_FILE) to $(DLL_INSTALL_DIR)/" @@INSTALL_LIB@ @chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)" @@ -796,83 +794,75 @@ install-libraries: libraries $(INSTALL_TZDATA) install-msgs @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform/shell-1.1.4.tm; - @echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/"; - @for i in $(TOP_DIR)/library/encoding/*.enc ; do \ - $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/encoding; \ - done; - @if [ -n "$(TCL_MODULE_PATH)" -a -f $(TOP_DIR)/library/tm.tcl ]; then \ + @echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/" + @for i in $(TOP_DIR)/library/encoding/*.enc; do \ + $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)/encoding"; \ + done + @if [ -n "$(TCL_MODULE_PATH)" -a -f $(TOP_DIR)/library/tm.tcl ] ; then \ echo "Customizing tcl module path"; \ echo "if {![interp issafe]} { ::tcl::tm::roots {$(TCL_MODULE_PATH)} }" >> \ - "$(SCRIPT_INSTALL_DIR)"/tm.tcl; \ + "$(SCRIPT_INSTALL_DIR)/tm.tcl"; \ fi install-tzdata: - @for i in tzdata; \ - do \ - if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ + @for i in tzdata; do \ + if [ ! -d "$(SCRIPT_INSTALL_DIR)/$$i" ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ - $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \ - else true; \ - fi; \ - done; + $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)/$$i"; \ + fi; \ + done @echo "Installing time zone files to $(SCRIPT_INSTALL_DIR)/tzdata/" - @for i in $(TOP_DIR)/library/tzdata/* ; do \ + @for i in $(TOP_DIR)/library/tzdata/*; do \ if [ -d $$i ] ; then \ ii=`basename $$i`; \ - if [ ! -d "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii ] ; then \ - $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii; \ + if [ ! -d "$(SCRIPT_INSTALL_DIR)/tzdata/$$ii" ] ; then \ + $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)/tzdata/$$ii"; \ fi; \ - for j in $$i/* ; do \ + for j in $$i/*; do \ if [ -d $$j ] ; then \ jj=`basename $$j`; \ - if [ ! -d "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj ] ; then \ - $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj; \ + if [ ! -d "$(SCRIPT_INSTALL_DIR)/tzdata/$$ii/$$jj" ] ; then \ + $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)/tzdata/$$ii/$$jj"; \ fi; \ - for k in $$j/* ; do \ - $(INSTALL_DATA) $$k "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj; \ + for k in $$j/*; do \ + $(INSTALL_DATA) $$k "$(SCRIPT_INSTALL_DIR)/tzdata/$$ii/$$jj"; \ done; \ else \ - $(INSTALL_DATA) $$j "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii; \ + $(INSTALL_DATA) $$j "$(SCRIPT_INSTALL_DIR)/tzdata/$$ii"; \ fi; \ done; \ else \ - $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/tzdata; \ + $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)/tzdata"; \ fi; \ - done; + done install-msgs: - @for i in msgs; \ - do \ - if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ + @for i in msgs; do \ + if [ ! -d "$(SCRIPT_INSTALL_DIR)/$$i" ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ - $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \ - else true; \ - fi; \ - done; + $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)/$$i"; \ + fi; \ + done @echo "Installing message catalog files to $(SCRIPT_INSTALL_DIR)/msgs/" - @for i in $(TOP_DIR)/library/msgs/*.msg ; do \ - $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/msgs; \ - done; + @for i in $(TOP_DIR)/library/msgs/*.msg; do \ + $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)/msgs"; \ + done install-doc: doc - @for i in "$(MAN_INSTALL_DIR)" "$(MAN1_INSTALL_DIR)" "$(MAN3_INSTALL_DIR)" "$(MANN_INSTALL_DIR)" ; \ - do \ + @for i in "$(MAN_INSTALL_DIR)" "$(MAN1_INSTALL_DIR)" "$(MAN3_INSTALL_DIR)" "$(MANN_INSTALL_DIR)"; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; - @echo "Installing and cross-linking top-level (.1) docs to $(MAN1_INSTALL_DIR)/"; + fi; \ + done + @echo "Installing and cross-linking top-level (.1) docs to $(MAN1_INSTALL_DIR)/" @for i in $(TOP_DIR)/doc/*.1; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN1_INSTALL_DIR)"; \ done - - @echo "Installing and cross-linking C API (.3) docs to $(MAN3_INSTALL_DIR)/"; + @echo "Installing and cross-linking C API (.3) docs to $(MAN3_INSTALL_DIR)/" @for i in $(TOP_DIR)/doc/*.3; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN3_INSTALL_DIR)"; \ done - @echo "Installing and cross-linking command (.n) docs to $(MANN_INSTALL_DIR)/"; @for i in $(TOP_DIR)/doc/*.n; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MANN_INSTALL_DIR)"; \ @@ -886,18 +876,18 @@ install-private-headers: libraries echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ else true; \ - fi; \ - done; + fi; \ + done @echo "Installing private header files to $(PRIVATE_INCLUDE_INSTALL_DIR)/"; @for i in $(GENERIC_DIR)/tclInt.h $(GENERIC_DIR)/tclIntDecls.h \ $(GENERIC_DIR)/tclIntPlatDecls.h $(GENERIC_DIR)/tclPort.h \ $(UNIX_DIR)/tclUnixPort.h; \ do \ $(INSTALL_DATA) $$i "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ - done; + done @if test -f tclConfig.h; then\ $(INSTALL_DATA) tclConfig.h "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ - fi; + fi Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in $(SHELL) config.status @@ -905,8 +895,9 @@ Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in # $(SHELL) config.status clean: - rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ - errors ${TCL_EXE} tcltest@EXEEXT@ lib.exp Tcl @DTRACE_HDR@ + rm -rf *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ + errors ${TCL_EXE} tcltest@EXEEXT@ lib.exp Tcl @DTRACE_HDR@ \ + *.zip *.vfs cd dltest ; $(MAKE) clean distclean: clean diff --git a/win/Makefile.in b/win/Makefile.in index 9d82961..f7fe219 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -171,7 +171,7 @@ TCL_EXE = tclsh # Setting the VPATH variable to a list of paths will cause the Makefile to # look into these paths when resolving .c to .obj dependencies. -VPATH = $(GENERIC_DIR):$(TOMMATH_DIR):$(WIN_DIR):$(COMPAT_DIR) +VPATH = $(GENERIC_DIR):$(WIN_DIR):$(COMPAT_DIR):$(TOMMATH_DIR) AR = @AR@ RANLIB = @RANLIB@ @@ -751,7 +751,8 @@ cleanhelp: clean: cleanhelp $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out $(RM) $(TCLSH) $(CAT32) $(TEST_EXE_FILE) tcltest.cmd tcltest.sh - $(RM) *.pch *.ilk *.pdb + $(RM) *.pch *.ilk *.pdb *.zip + $(RMDIR) *.vfs distclean: clean $(RM) Makefile config.status config.cache config.log tclConfig.sh \ diff --git a/win/makefile.vc b/win/makefile.vc index 692d209..4f657a5 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -1,7 +1,6 @@ #------------------------------------------------------------- -*- makefile -*- -# makefile.vc -- # -# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+) +# Microsoft Visual C++ makefile for building Tcl with nmake # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -- cgit v0.12 From 32dc9b67a9abfee0ac46d6fb2eeb10e229612723 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 Feb 2021 10:46:58 +0000 Subject: Merge 8.6 --- win/Makefile.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/win/Makefile.in b/win/Makefile.in index 5706b08..1da2455 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -991,9 +991,8 @@ cleanhelp: clean: cleanhelp clean-packages $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out $(RM) $(TCLSH) $(CAT32) $(TEST_EXE_FILE) $(TEST_DLL_FILE) tcltest.cmd tcltest.sh - $(RM) *.pch *.ilk *.pdb + $(RM) *.pch *.ilk *.pdb *.zip $(RM) minizip${HOST_EXEEXT} *.${HOST_OBJEXT} - $(RM) *.zip $(RMDIR) *.vfs distclean: distclean-packages clean -- cgit v0.12 From b142586b211b0e3b339168b0227baa42d975a7f2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 Feb 2021 15:25:55 +0000 Subject: Fix "auto.tcl" indenting --- library/auto.tcl | 196 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 99 insertions(+), 97 deletions(-) diff --git a/library/auto.tcl b/library/auto.tcl index 5f86c93..db7952a 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -70,60 +70,62 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # gives the end-user ultimate control to work-around any bugs, or # to customize. - if {[info exists env($enVarName)]} { - lappend dirs $env($enVarName) - } + if {[info exists env($enVarName)]} { + lappend dirs $env($enVarName) + } catch { - set found 0 + set found 0 set root [zipfs root] set mountpoint [file join $root lib [string tolower $basename]] - lappend dirs [file join $root app ${basename}_library] - lappend dirs [file join $root lib $mountpoint ${basename}_library] - lappend dirs [file join $root lib $mountpoint] + lappend dirs [file join $root app ${basename}_library] + lappend dirs [file join $root lib $mountpoint ${basename}_library] + lappend dirs [file join $root lib $mountpoint] if {![zipfs exists [file join $root app ${basename}_library]] \ - && ![zipfs exists $mountpoint]} { - set found 0 - foreach pkgdat [info loaded] { - lassign $pkgdat dllfile dllpkg - if {[string tolower $dllpkg] ne [string tolower $basename]} continue - if {$dllfile eq {}} { - # Loaded statically - break - } - set found 1 - zipfs mount $mountpoint $dllfile - break - } - if {!$found} { - set paths {} - lappend paths [file join $root app] - lappend paths [::${basename}::pkgconfig get libdir,runtime] - lappend paths [::${basename}::pkgconfig get bindir,runtime] - if {[catch {::${basename}::pkgconfig get zipfile,runtime} zipfile]} { - set zipfile [string tolower \ - "lib${basename}_[join [list {*}[split $version .] {*}$patch] _].zip"] - } - lappend paths [file dirname [file join [pwd] [info nameofexecutable]]] - foreach path $paths { - set archive [file join $path $zipfile] - if {![file exists $archive]} continue - zipfs mount $mountpoint $archive - if {[zipfs exists [file join $mountpoint ${basename}_library $initScript]]} { - lappend dirs [file join $mountpoint ${basename}_library] - set found 1 - break - } elseif {[zipfs exists [file join $mountpoint $initScript]]} { - lappend dirs [file join $mountpoint $initScript] - set found 1 - break - } else { - catch {zipfs unmount $archive} - } - } - } - } - } + && ![zipfs exists $mountpoint]} { + set found 0 + foreach pkgdat [info loaded] { + lassign $pkgdat dllfile dllpkg + if {[string tolower $dllpkg] ne [string tolower $basename]} continue + if {$dllfile eq {}} { + # Loaded statically + break + } + set found 1 + zipfs mount $mountpoint $dllfile + break + } + if {!$found} { + set paths {} + lappend paths [file join $root app] + lappend paths [::${basename}::pkgconfig get libdir,runtime] + lappend paths [::${basename}::pkgconfig get bindir,runtime] + if {[catch {::${basename}::pkgconfig get zipfile,runtime} zipfile]} { + set zipfile [string tolower \ + "lib${basename}_[join [list {*}[split $version .] {*}$patch] _].zip"] + } + lappend paths [file dirname [file join [pwd] [info nameofexecutable]]] + foreach path $paths { + set archive [file join $path $zipfile] + if {![file exists $archive]} { + continue + } + zipfs mount $mountpoint $archive + if {[zipfs exists [file join $mountpoint ${basename}_library $initScript]]} { + lappend dirs [file join $mountpoint ${basename}_library] + set found 1 + break + } elseif {[zipfs exists [file join $mountpoint $initScript]]} { + lappend dirs [file join $mountpoint $initScript] + set found 1 + break + } else { + catch {zipfs unmount $archive} + } + } + } + } + } # 2. In the package script directory registered within the # configuration of the package itself. @@ -158,11 +160,11 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # ../../../foo1.0.1/library # (From unix/arch directory in parallel build hierarchy) - set parentDir [file dirname [file dirname [info nameofexecutable]]] - set grandParentDir [file dirname $parentDir] - lappend dirs [file join $parentDir lib $basename$version] - lappend dirs [file join $grandParentDir lib $basename$version] - lappend dirs [file join $parentDir library] + set parentDir [file dirname [file dirname [info nameofexecutable]]] + set grandParentDir [file dirname $parentDir] + lappend dirs [file join $parentDir lib $basename$version] + lappend dirs [file join $grandParentDir lib $basename$version] + lappend dirs [file join $parentDir library] if {0} { lappend dirs [file join $grandParentDir library] lappend dirs [file join $grandParentDir $basename$patch library] @@ -185,19 +187,19 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { } set seen($norm) {} - set the_library $i - set file [file join $i $initScript] + set the_library $i + set file [file join $i $initScript] # source everything when in a safe interpreter because we have a # source command, but no file exists command - if {[interp issafe] || [file exists $file]} { - if {![catch {uplevel #0 [list source $file]} msg opts]} { - return - } + if {[interp issafe] || [file exists $file]} { + if {![catch {uplevel #0 [list source $file]} msg opts]} { + return + } append errors "$file: $msg\n" append errors [dict get $opts -errorinfo]\n - } + } } unset -nocomplain the_library set msg "Can't find a usable $initScript in the following directories: \n" @@ -236,7 +238,7 @@ if {[interp issafe]} { proc auto_mkindex {dir args} { if {[interp issafe]} { - error "can't generate index within safe interpreter" + error "can't generate index within safe interpreter" } set oldDir [pwd] @@ -424,7 +426,7 @@ proc auto_mkindex_parser::mkindex {file} { $parser eval $contents foreach name $imports { - catch {$parser eval [list _%@namespace forget $name]} + catch {$parser eval [list _%@namespace forget $name]} } return $index } @@ -494,9 +496,9 @@ proc auto_mkindex_parser::commandInit {name arglist body} { set ns [namespace qualifiers $name] set tail [namespace tail $name] if {$ns eq ""} { - set fakeName [namespace current]::_%@fake_$tail + set fakeName [namespace current]::_%@fake_$tail } else { - set fakeName [namespace current]::[string map {:: _} _%@fake_$name] + set fakeName [namespace current]::[string map {:: _} _%@fake_$name] } proc $fakeName $arglist $body @@ -505,8 +507,8 @@ proc auto_mkindex_parser::commandInit {name arglist body} { # the fully qualified names, and have the procs point to the aliases. if {[string match *::* $name]} { - set exportCmd [list _%@namespace export [namespace tail $name]] - $parser eval [list _%@namespace eval $ns $exportCmd] + set exportCmd [list _%@namespace export [namespace tail $name]] + $parser eval [list _%@namespace eval $ns $exportCmd] # The following proc definition does not work if you want to tolerate # space or something else diabolical in the procedure name, (i.e., @@ -518,11 +520,11 @@ proc auto_mkindex_parser::commandInit {name arglist body} { # A gold star to someone that can make test autoMkindex-3.3 work # properly - set alias [namespace tail $fakeName] - $parser invokehidden proc $name {args} "_%@eval {$alias} \$args" - $parser alias $alias $fakeName + set alias [namespace tail $fakeName] + $parser invokehidden proc $name {args} "_%@eval {$alias} \$args" + $parser alias $alias $fakeName } else { - $parser alias $name $fakeName + $parser alias $name $fakeName } return } @@ -544,18 +546,18 @@ proc auto_mkindex_parser::fullname {name} { variable contextStack if {![string match ::* $name]} { - foreach ns $contextStack { - set name "${ns}::$name" - if {[string match ::* $name]} { - break - } - } + foreach ns $contextStack { + set name "${ns}::$name" + if {[string match ::* $name]} { + break + } + } } if {[namespace qualifiers $name] eq ""} { - set name [namespace tail $name] + set name [namespace tail $name] } elseif {![string match ::* $name]} { - set name "::$name" + set name "::$name" } # Earlier, mkindex replaced all $'s with \0. Now, we have to reverse that @@ -645,27 +647,27 @@ auto_mkindex_parser::hook { auto_mkindex_parser::command namespace {op args} { switch -- $op { - eval { - variable parser - variable contextStack + eval { + variable parser + variable contextStack - set name [lindex $args 0] - set args [lrange $args 1 end] + set name [lindex $args 0] + set args [lrange $args 1 end] - set contextStack [linsert $contextStack 0 $name] + set contextStack [linsert $contextStack 0 $name] $parser eval [list _%@namespace eval $name] $args - set contextStack [lrange $contextStack 1 end] - } - import { - variable parser - variable imports - foreach pattern $args { - if {$pattern ne "-force"} { - lappend imports $pattern - } - } - catch {$parser eval "_%@namespace import $args"} - } + set contextStack [lrange $contextStack 1 end] + } + import { + variable parser + variable imports + foreach pattern $args { + if {$pattern ne "-force"} { + lappend imports $pattern + } + } + catch {$parser eval "_%@namespace import $args"} + } ensemble { variable parser variable contextStack -- cgit v0.12 From 6f3b0bd108aee3078fa25557f8831d12afd42ea1 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 Feb 2021 15:51:46 +0000 Subject: Bugfix in TIP #430 implementation: tcl_findLibrary should use the same zip-file naming as the configure scripts do --- library/auto.tcl | 7 +++---- unix/configure | 2 +- unix/configure.ac | 2 +- win/configure | 2 +- win/configure.ac | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/library/auto.tcl b/library/auto.tcl index db7952a..51d4ef1 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -77,7 +77,7 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { catch { set found 0 set root [zipfs root] - set mountpoint [file join $root lib [string tolower $basename]] + set mountpoint [file join $root lib $basename] lappend dirs [file join $root app ${basename}_library] lappend dirs [file join $root lib $mountpoint ${basename}_library] lappend dirs [file join $root lib $mountpoint] @@ -86,7 +86,7 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { set found 0 foreach pkgdat [info loaded] { lassign $pkgdat dllfile dllpkg - if {[string tolower $dllpkg] ne [string tolower $basename]} continue + if {$dllpkg ne $basename} continue if {$dllfile eq {}} { # Loaded statically break @@ -101,8 +101,7 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { lappend paths [::${basename}::pkgconfig get libdir,runtime] lappend paths [::${basename}::pkgconfig get bindir,runtime] if {[catch {::${basename}::pkgconfig get zipfile,runtime} zipfile]} { - set zipfile [string tolower \ - "lib${basename}_[join [list {*}[split $version .] {*}$patch] _].zip"] + set zipfile "lib${basename}[join [split $patch .] _].zip" } lappend paths [file dirname [file join [pwd] [info nameofexecutable]]] foreach path $paths { diff --git a/unix/configure b/unix/configure index 26de9a8..70e46d7 100755 --- a/unix/configure +++ b/unix/configure @@ -11149,7 +11149,7 @@ printf "%s\n" "No zip found on PATH. Building minizip" >&6; } ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else ZIPFS_BUILD=0 TCL_ZIP_FILE= diff --git a/unix/configure.ac b/unix/configure.ac index 9967ef8..55ce886 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -888,7 +888,7 @@ if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then # SC_ZIPFS_SUPPORT ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else ZIPFS_BUILD=0 TCL_ZIP_FILE= diff --git a/win/configure b/win/configure index ae9e666..33716bc 100755 --- a/win/configure +++ b/win/configure @@ -5135,7 +5135,7 @@ printf "%s\n" "No zip found on PATH building minizip" >&6; } ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else ZIPFS_BUILD=0 TCL_ZIP_FILE= diff --git a/win/configure.ac b/win/configure.ac index 02b6363..6184144 100644 --- a/win/configure.ac +++ b/win/configure.ac @@ -180,7 +180,7 @@ if test "$tcl_ok" = "yes" ; then SC_PROG_TCLSH SC_ZIPFS_SUPPORT ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else ZIPFS_BUILD=0 TCL_ZIP_FILE= -- cgit v0.12 From ebf4c78ed811b2c54015d5c0a0fb446da5ae5140 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 Feb 2021 18:23:40 +0000 Subject: Attempt to fix the last TIP #430 bits, needed to make it work for Tk (and other external packages) --- generic/tclPkgConfig.c | 1 - generic/tclZipfs.c | 18 ------------------ library/auto.tcl | 6 +++--- tests/config.test | 2 +- tests/zipfs.test | 7 +------ unix/Makefile.in | 19 +------------------ unix/configure | 9 +++------ unix/configure.ac | 6 ++---- win/Makefile.in | 9 +-------- win/configure | 9 +++------ win/configure.ac | 6 ++---- win/makefile.vc | 5 ++--- 12 files changed, 19 insertions(+), 78 deletions(-) diff --git a/generic/tclPkgConfig.c b/generic/tclPkgConfig.c index c8f0357..a802252 100644 --- a/generic/tclPkgConfig.c +++ b/generic/tclPkgConfig.c @@ -110,7 +110,6 @@ static Tcl_Config const cfg[] = { {"includedir,runtime", CFG_RUNTIME_INCDIR}, {"docdir,runtime", CFG_RUNTIME_DOCDIR}, {"dllfile,runtime", CFG_RUNTIME_DLLFILE}, - {"zipfile,runtime", CFG_RUNTIME_ZIPFILE}, /* Installation paths to various stuff */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index fc7be6f..7ee13a7 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3179,24 +3179,6 @@ TclZipfs_TclLibrary(void) #endif /* _WIN32 || CFG_RUNTIME_DLLFILE */ /* - * If we're configured to know about a ZIP archive we should use, do that. - */ - -#ifdef CFG_RUNTIME_ZIPFILE - if (ZipfsAppHookFindTclInit( - CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } - if (ZipfsAppHookFindTclInit( - CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } - if (ZipfsAppHookFindTclInit(CFG_RUNTIME_ZIPFILE) == TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } -#endif /* CFG_RUNTIME_ZIPFILE */ - - /* * If anything set the cache (but subsequently failed) go with that * anyway. */ diff --git a/library/auto.tcl b/library/auto.tcl index 51d4ef1..ea2fe5e 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -100,12 +100,12 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { lappend paths [file join $root app] lappend paths [::${basename}::pkgconfig get libdir,runtime] lappend paths [::${basename}::pkgconfig get bindir,runtime] - if {[catch {::${basename}::pkgconfig get zipfile,runtime} zipfile]} { - set zipfile "lib${basename}[join [split $patch .] _].zip" + if {[catch {::${basename}::pkgconfig get dllfile,runtime} dllfile]} { + set dllfile "lib${basename}${version}[info sharedlibextension]" } lappend paths [file dirname [file join [pwd] [info nameofexecutable]]] foreach path $paths { - set archive [file join $path $zipfile] + set archive [file join $path $dllfile] if {![file exists $archive]} { continue } diff --git a/tests/config.test b/tests/config.test index f87250a..d41021a 100644 --- a/tests/config.test +++ b/tests/config.test @@ -19,7 +19,7 @@ if {"::tcltest" ni [namespace children]} { test pkgconfig-1.1 {query keys} { lsort [::tcl::pkgconfig list] -} {64bit bindir,install bindir,runtime compile_debug compile_stats debug dllfile,runtime docdir,install docdir,runtime includedir,install includedir,runtime libdir,install libdir,runtime mem_debug optimized profiled scriptdir,install scriptdir,runtime threaded zipfile,runtime} +} {64bit bindir,install bindir,runtime compile_debug compile_stats debug dllfile,runtime docdir,install docdir,runtime includedir,install includedir,runtime libdir,install libdir,runtime mem_debug optimized profiled scriptdir,install scriptdir,runtime threaded} test pkgconfig-1.2 {query keys multiple times} { string compare [::tcl::pkgconfig list] [::tcl::pkgconfig list] } 0 diff --git a/tests/zipfs.test b/tests/zipfs.test index cdddc71..fd40f9e 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -20,11 +20,6 @@ testConstraint zipfs [expr { }] testConstraint zipfslib 1 -# Removed in tip430 - zipfs is no longer a static package -#test zipfs-0.0 {zipfs basics} -constraints zipfs -body { -# load {} zipfs -#} -result {} - set ziproot [zipfs root] set CWD [pwd] set tmpdir [file join $CWD tmp] @@ -44,7 +39,7 @@ if {![string match ${ziproot}* $tcl_library]} { # Hack the environment to pretend we did pull tcl_library from a zip # archive ### - set tclzip [file join $CWD [::tcl::pkgconfig get zipfile,runtime]] + set tclzip [file join $CWD [::tcl::pkgconfig get dllfile,runtime]] testConstraint zipfslib [file isfile $tclzip] if {[testConstraint zipfslib]} { zipfs mount /lib/tcl $tclzip diff --git a/unix/Makefile.in b/unix/Makefile.in index 5988ba6..00e29be 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -996,21 +996,6 @@ install-binaries: binaries @$(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/pkgconfig" @$(INSTALL_DATA) tcl.pc "$(LIB_INSTALL_DIR)/pkgconfig/tcl.pc" -install-libraries-zipfs-shared: libraries - @for i in "$(SCRIPT_INSTALL_DIR)"; do \ - if [ ! -d "$$i" ] ; then \ - echo "Making directory $$i"; \ - $(INSTALL_DATA_DIR) "$$i"; \ - fi; \ - done - @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/" - @for i in $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; do \ - $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \ - done - -install-libraries-zipfs-static: install-libraries-zipfs-shared - $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" - install-libraries: libraries @for i in "$(SCRIPT_INSTALL_DIR)" "$(MODULE_INSTALL_DIR)"; \ do \ @@ -1475,7 +1460,6 @@ tclPkgConfig.o: $(GENERIC_DIR)/tclPkgConfig.c -DCFG_RUNTIME_INCDIR="\"$(includedir)\"" \ -DCFG_RUNTIME_DOCDIR="\"$(mandir)\"" \ -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ - -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ $(GENERIC_DIR)/tclPkgConfig.c tclPosixStr.o: $(GENERIC_DIR)/tclPosixStr.c @@ -1529,7 +1513,6 @@ tclZlib.o: $(GENERIC_DIR)/tclZlib.c tclZipfs.o: $(GENERIC_DIR)/tclZipfs.c $(CC) -c $(CC_SWITCHES) \ -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ - -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ -DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \ -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY)\"" \ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip \ @@ -2412,7 +2395,7 @@ BUILD_HTML = \ .PHONY: install-tzdata install-msgs .PHONY: packages configure-packages test-packages clean-packages .PHONY: dist-packages distclean-packages install-packages -.PHONY: install-libraries-zipfs-shared install-libraries-zipfs-static tclzipfile +.PHONY: tclzipfile #-------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/unix/configure b/unix/configure index 70e46d7..34500ba 100755 --- a/unix/configure +++ b/unix/configure @@ -11163,17 +11163,14 @@ if test "${ZIPFS_BUILD}" = 1; then printf "%s\n" "#define ZIPFS_BUILD 2" >>confdefs.h - INSTALL_LIBRARIES=install-libraries-zipfs-static - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } else + ZIPFS_BUILD=1; printf "%s\n" "#define ZIPFS_BUILD 1" >>confdefs.h \ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } diff --git a/unix/configure.ac b/unix/configure.ac index 55ce886..ad837b9 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -899,13 +899,11 @@ if test "${ZIPFS_BUILD}" = 1; then if test "${SHARED_BUILD}" = 0; then ZIPFS_BUILD=2; AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) - INSTALL_LIBRARIES=install-libraries-zipfs-static - AC_MSG_RESULT([yes]) else + ZIPFS_BUILD=1; AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - AC_MSG_RESULT([yes]) fi + AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) INSTALL_LIBRARIES=install-libraries diff --git a/win/Makefile.in b/win/Makefile.in index 1da2455..b5b4f26 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -656,7 +656,6 @@ tclZipfs.${OBJEXT}: $(GENERIC_DIR)/tclZipfs.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl \ -DCFG_RUNTIME_PATH="\"$(bindir_native)\"" \ -DCFG_RUNTIME_DLLFILE="\"$(TCL_DLL_FILE)\"" \ - -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ -DCFG_RUNTIME_LIBDIR="\"$(bindir_native)\"" \ -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY_NATIVE)\"" \ $(ZLIB_INCLUDE) -I$(MINIZIP_DIR_NATIVE) @DEPARG@ $(CC_OBJNAME) @@ -684,7 +683,6 @@ tclPkgConfig.${OBJEXT}: tclPkgConfig.c -DCFG_RUNTIME_INCDIR="\"$(includedir_native)\"" \ -DCFG_RUNTIME_DOCDIR="\"$(mandir_native)\"" \ -DCFG_RUNTIME_DLLFILE="\"$(TCL_DLL_FILE)\"" \ - -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ -DBUILD_tcl \ @DEPARG@ $(CC_OBJNAME) @@ -839,11 +837,6 @@ install-binaries: binaries $(COPY) $(REG_LIB_FILE) "$(LIB_INSTALL_DIR)/registry${REGDOTVER}"; \ fi -install-libraries-zipfs-shared: libraries - -install-libraries-zipfs-static: install-libraries-zipfs-shared - $(COPY) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" - install-libraries: libraries install-tzdata install-msgs @for i in "$(prefix)/lib" "$(INCLUDE_INSTALL_DIR)" \ "$(SCRIPT_INSTALL_DIR)" "$(MODULE_INSTALL_DIR)"; \ @@ -1126,6 +1119,6 @@ html-tk: $(TCLSH) .PHONY: gdb depend cleanhelp clean distclean packages install-packages .PHONY: test-packages clean-packages distclean-packages genstubs html .PHONY: html-tcl html-tk -.PHONY: iinstall-libraries-zipfs-shared install-libraries-zipfs-static tclzipfile +.PHONY: tclzipfile # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/win/configure b/win/configure index 33716bc..090e040 100755 --- a/win/configure +++ b/win/configure @@ -5149,17 +5149,14 @@ if test "${ZIPFS_BUILD}" = 1; then printf "%s\n" "#define ZIPFS_BUILD 2" >>confdefs.h - INSTALL_LIBRARIES=install-libraries-zipfs-static - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } else + ZIPFS_BUILD=1; printf "%s\n" "#define ZIPFS_BUILD 1" >>confdefs.h \ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } diff --git a/win/configure.ac b/win/configure.ac index 6184144..7dc9c6d 100644 --- a/win/configure.ac +++ b/win/configure.ac @@ -191,13 +191,11 @@ if test "${ZIPFS_BUILD}" = 1; then if test "${SHARED_BUILD}" = 0; then ZIPFS_BUILD=2; AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) - INSTALL_LIBRARIES=install-libraries-zipfs-static - AC_MSG_RESULT([yes]) else + ZIPFS_BUILD=1; AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - AC_MSG_RESULT([yes]) fi + AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) INSTALL_LIBRARIES=install-libraries diff --git a/win/makefile.vc b/win/makefile.vc index 66879ab..cde68dc 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -824,7 +824,7 @@ $(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c $(cc32) $(pkgcflags) -I$(COMPATDIR)\zlib -Fo$@ $? # Following the lead of the autoconf based make, we define the -# CFG_RUNTIME_DLLFILE and CFG_RUNTIME_ZIPFILE flags specifically for tclPkgConfig +# CFG_RUNTIME_*DIR flags specifically for tclPkgConfig # and not as part of the global defines. These are all defined # as empty strings because they are intended to represent paths # at *runtime*, not build time. This may make sense on Unix systems @@ -848,8 +848,7 @@ $(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c /DCFG_RUNTIME_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ /DCFG_RUNTIME_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ /DCFG_RUNTIME_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ - /DCFG_RUNTIME_DLLFILE="\"\"" \ - /DCFG_RUNTIME_ZIPFILE="\"\"" \ + /DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ -Fo$@ $? $(TMP_DIR)\tclAppInit.obj: $(WIN_DIR)\tclAppInit.c -- cgit v0.12 From 5740a9e3d2db8f112a2af4353f86d9ca864b3a2f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Feb 2021 07:34:01 +0000 Subject: Add --disable-zipfs flag to GNUmakefile --- macosx/GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile index 6451c66..1ee3bf1 100644 --- a/macosx/GNUmakefile +++ b/macosx/GNUmakefile @@ -144,7 +144,7 @@ ${objdir}/Makefile: ${UNIX_DIR}/Makefile.in ${UNIX_DIR}/configure \ mkdir -p "${OBJ_DIR}" && cd "${OBJ_DIR}" && \ if [ ${UNIX_DIR}/configure -nt config.status ]; then ${UNIX_DIR}/configure -C \ --prefix="${PREFIX}" --bindir="${BINDIR}" --libdir="${LIBDIR}" \ - --mandir="${MANDIR}" --enable-framework --enable-dtrace \ + --mandir="${MANDIR}" --enable-framework --enable-dtrace --disable-zipfs \ ${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}; else ./config.status; fi build-${PROJECT}: ${objdir}/Makefile -- cgit v0.12 From af4a77f3e35d39964eeae9c3636a42d6d29f4d5d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Feb 2021 12:07:09 +0000 Subject: Change TCL_ZIP_FILE name, just using dots in stead of underscores --- tests/zipfs.test | 2 +- unix/configure | 2 +- unix/configure.ac | 2 +- unix/tcl.pc.in | 1 - win/configure | 2 +- win/configure.ac | 2 +- win/tcl.m4 | 2 -- 7 files changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/zipfs.test b/tests/zipfs.test index fd40f9e..8689268 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -39,7 +39,7 @@ if {![string match ${ziproot}* $tcl_library]} { # Hack the environment to pretend we did pull tcl_library from a zip # archive ### - set tclzip [file join $CWD [::tcl::pkgconfig get dllfile,runtime]] + set tclzip [file join $CWD libtcl[info patchlevel].zip] testConstraint zipfslib [file isfile $tclzip] if {[testConstraint zipfslib]} { zipfs mount /lib/tcl $tclzip diff --git a/unix/configure b/unix/configure index 34500ba..f54edf9 100755 --- a/unix/configure +++ b/unix/configure @@ -11149,7 +11149,7 @@ printf "%s\n" "No zip found on PATH. Building minizip" >&6; } ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip + TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else ZIPFS_BUILD=0 TCL_ZIP_FILE= diff --git a/unix/configure.ac b/unix/configure.ac index ad837b9..6b97f7e 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -888,7 +888,7 @@ if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then # SC_ZIPFS_SUPPORT ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip + TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else ZIPFS_BUILD=0 TCL_ZIP_FILE= diff --git a/unix/tcl.pc.in b/unix/tcl.pc.in index a343707..2693cd8 100644 --- a/unix/tcl.pc.in +++ b/unix/tcl.pc.in @@ -5,7 +5,6 @@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ libfile=@TCL_LIB_FILE@ -zipfile=@TCL_ZIP_FILE@ Name: Tool Command Language Description: Tcl is a powerful, easy-to-learn dynamic programming language, suitable for a wide range of uses. diff --git a/win/configure b/win/configure index 090e040..2fd5ecc 100755 --- a/win/configure +++ b/win/configure @@ -5135,7 +5135,7 @@ printf "%s\n" "No zip found on PATH building minizip" >&6; } ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip + TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else ZIPFS_BUILD=0 TCL_ZIP_FILE= diff --git a/win/configure.ac b/win/configure.ac index 7dc9c6d..a3c4c30 100644 --- a/win/configure.ac +++ b/win/configure.ac @@ -180,7 +180,7 @@ if test "$tcl_ok" = "yes" ; then SC_PROG_TCLSH SC_ZIPFS_SUPPORT ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip + TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else ZIPFS_BUILD=0 TCL_ZIP_FILE= diff --git a/win/tcl.m4 b/win/tcl.m4 index b9a164c..76711dd 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -251,7 +251,6 @@ AC_DEFUN([SC_PATH_TKCONFIG], [ # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE -# TCL_ZIP_FILE # #------------------------------------------------------------------------ @@ -288,7 +287,6 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [ AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) - AC_SUBST(TCL_ZIP_FILE) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) -- cgit v0.12 From 0043160893f36a39afbe5a4f9dff3fac577d0dec Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Feb 2021 13:34:26 +0000 Subject: Handle the situation that ::${basename}::pkgconfig does not have bindir/libdir,runtime keys: Either get those from Tcl, or from [info nameofexecutable] --- library/auto.tcl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/library/auto.tcl b/library/auto.tcl index ea2fe5e..dc37328 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -97,13 +97,22 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { } if {!$found} { set paths {} - lappend paths [file join $root app] - lappend paths [::${basename}::pkgconfig get libdir,runtime] - lappend paths [::${basename}::pkgconfig get bindir,runtime] + if {![catch {::${basename}::pkgconfig get libdir,runtime} dir]} { + lappend paths $dir + } else { + catch {lappend paths [::tcl::pkgconfig get libdir,runtime]} + } + if {![catch {::${basename}::pkgconfig get bindir,runtime} dir]} { + lappend paths $dir + } else { + catch {lappend paths [::tcl::pkgconfig get bindir,runtime]} + } if {[catch {::${basename}::pkgconfig get dllfile,runtime} dllfile]} { set dllfile "lib${basename}${version}[info sharedlibextension]" } - lappend paths [file dirname [file join [pwd] [info nameofexecutable]]] + set dir [file dirname [file join [pwd] [info nameofexecutable]]] + lappend paths $dir + lappend paths [file join [file dirname $dir] lib] foreach path $paths { set archive [file join $path $dllfile] if {![file exists $archive]} { -- cgit v0.12 From aeeb808b303e434a1ccff182ded81904c935d88d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Feb 2021 14:16:11 +0000 Subject: ZIPFS_BUILD=1 only needs to be set once --- unix/configure | 1 - unix/configure.ac | 1 - win/configure | 1 - win/configure.ac | 1 - 4 files changed, 4 deletions(-) diff --git a/unix/configure b/unix/configure index f54edf9..50a035b 100755 --- a/unix/configure +++ b/unix/configure @@ -11164,7 +11164,6 @@ if test "${ZIPFS_BUILD}" = 1; then printf "%s\n" "#define ZIPFS_BUILD 2" >>confdefs.h else - ZIPFS_BUILD=1; printf "%s\n" "#define ZIPFS_BUILD 1" >>confdefs.h \ diff --git a/unix/configure.ac b/unix/configure.ac index 6b97f7e..edf5f6d 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -900,7 +900,6 @@ if test "${ZIPFS_BUILD}" = 1; then ZIPFS_BUILD=2; AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) else - ZIPFS_BUILD=1; AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ fi AC_MSG_RESULT([yes]) diff --git a/win/configure b/win/configure index 2fd5ecc..4659c61 100755 --- a/win/configure +++ b/win/configure @@ -5150,7 +5150,6 @@ if test "${ZIPFS_BUILD}" = 1; then printf "%s\n" "#define ZIPFS_BUILD 2" >>confdefs.h else - ZIPFS_BUILD=1; printf "%s\n" "#define ZIPFS_BUILD 1" >>confdefs.h \ diff --git a/win/configure.ac b/win/configure.ac index a3c4c30..87ffd8d 100644 --- a/win/configure.ac +++ b/win/configure.ac @@ -192,7 +192,6 @@ if test "${ZIPFS_BUILD}" = 1; then ZIPFS_BUILD=2; AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) else - ZIPFS_BUILD=1; AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ fi AC_MSG_RESULT([yes]) -- cgit v0.12 From 6e603480b380cbf2699334cc475c3ffde87a5feb Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Feb 2021 16:43:57 +0000 Subject: Only set dllfile,runtime key info when doing a shared build --- generic/tclPkgConfig.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generic/tclPkgConfig.c b/generic/tclPkgConfig.c index a802252..672d3c9 100644 --- a/generic/tclPkgConfig.c +++ b/generic/tclPkgConfig.c @@ -109,7 +109,9 @@ static Tcl_Config const cfg[] = { {"scriptdir,runtime", CFG_RUNTIME_SCRDIR}, {"includedir,runtime", CFG_RUNTIME_INCDIR}, {"docdir,runtime", CFG_RUNTIME_DOCDIR}, +#if !defined(STATIC_BUILD) {"dllfile,runtime", CFG_RUNTIME_DLLFILE}, +#endif /* Installation paths to various stuff */ -- cgit v0.12 From 2ba1ef3db130005ec13803f56a5f8a64c1d2669c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 10 Feb 2021 08:11:29 +0000 Subject: In a static build, don't pack dde/registry in zip-file. In shared build, pack dde/registry dll's in zip-file. Rename zip-file --- win/makefile.vc | 7 +++++-- win/rules.vc | 12 ++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/win/makefile.vc b/win/makefile.vc index cde68dc..a124b34 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -576,18 +576,21 @@ $(OUT_DIR)\tommath.lib: $(TOMMATHDIR)\win32\tommath.lib $(COPY) $(TOMMATHDIR)\win32\tommath.lib $(OUT_DIR)\tommath.lib !endif -$(TCLSCRIPTZIP): .PHONY +$(TCLSCRIPTZIP): $(TCLDDELIB) $(TCLREGLIB) @echo Building Tcl library zip file @if exist "$(LIBTCLVFS)" $(RMDIR) "$(LIBTCLVFS)" @$(MKDIR) "$(LIBTCLVFS)" @$(CPYDIR) $(LIBDIR) "$(LIBTCLVFS)\tcl_library" @move /y "$(LIBTCLVFS)\tcl_library\manifest.txt" "$(LIBTCLVFS)\tcl_library\pkgIndex.tcl" > NUL -!if ! $(STATIC_BUILD) +!if $(STATIC_BUILD) # Remove the registry and dde directories as the DLLS are still external @del "$(LIBTCLVFS)\tcl_library\registry\pkgIndex.tcl" @rmdir "$(LIBTCLVFS)\tcl_library\registry" @del "$(LIBTCLVFS)\tcl_library\dde\pkgIndex.tcl" @rmdir "$(LIBTCLVFS)\tcl_library\dde" +!else + @$(COPY) $(TCLDDELIB) "$(LIBTCLVFS)\tcl_library\dde + @$(COPY) $(TCLREGLIB) "$(LIBTCLVFS)\tcl_library\registry !endif @echo file delete -force {$@} > "$(OUT_DIR)\zipper.tcl" @echo zipfs mkzip {$@} {$(LIBTCLVFS)} {$(LIBTCLVFS)} >> "$(OUT_DIR)\zipper.tcl" diff --git a/win/rules.vc b/win/rules.vc index e678c34..2ec5292 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -1122,16 +1122,8 @@ STUBPREFIX = $(PROJECT)stub # # TIP 430. Unused for 8.6 but no harm defining it to allow a common rules.vc -!if "$(TCL_PATCH_LETTER)" == "." -TCLSCRIPTZIPNAME = libtcl_$(TCL_MAJOR_VERSION)_$(TCL_MINOR_VERSION)_$(TCL_RELEASE_SERIAL).zip -!else -TCLSCRIPTZIPNAME = libtcl_$(TCL_MAJOR_VERSION)_$(TCL_MINOR_VERSION)_$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip -!endif -!if "$(TK_PATCH_LETTER)" == "." -TKSCRIPTZIPNAME = libtk_$(TK_MAJOR_VERSION)_$(TK_MINOR_VERSION)_$(TK_RELEASE_SERIAL).zip -!else -TKSCRIPTZIPNAME = libtk_$(TK_MAJOR_VERSION)_$(TK_MINOR_VERSION)_$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip -!endif +TCLSCRIPTZIPNAME = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip +TKSCRIPTZIPNAME = libtk$(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip !if $(DOING_TCL) TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe -- cgit v0.12 From ea4e2c54322fdec470e442447b66d815635851da Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 10 Feb 2021 08:52:08 +0000 Subject: Fix pkgconfig-1.1 testcase for static builds --- tests/config.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/config.test b/tests/config.test index d41021a..2d8b593 100644 --- a/tests/config.test +++ b/tests/config.test @@ -17,9 +17,9 @@ if {"::tcltest" ni [namespace children]} { namespace import -force ::tcltest::* } -test pkgconfig-1.1 {query keys} { +test pkgconfig-1.1 {query keys} -body { lsort [::tcl::pkgconfig list] -} {64bit bindir,install bindir,runtime compile_debug compile_stats debug dllfile,runtime docdir,install docdir,runtime includedir,install includedir,runtime libdir,install libdir,runtime mem_debug optimized profiled scriptdir,install scriptdir,runtime threaded} +} -match glob -result {64bit bindir,install bindir,runtime compile_debug compile_stats debug*docdir,install docdir,runtime includedir,install includedir,runtime libdir,install libdir,runtime mem_debug optimized profiled scriptdir,install scriptdir,runtime threaded} test pkgconfig-1.2 {query keys multiple times} { string compare [::tcl::pkgconfig list] [::tcl::pkgconfig list] } 0 -- cgit v0.12 From 24128f43dfd9e9865030174ad85ea232234b173a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 10 Feb 2021 10:44:52 +0000 Subject: Backport win/rules.vc from 8.7 --- win/rules.vc | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/win/rules.vc b/win/rules.vc index e678c34..2ec5292 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -1122,16 +1122,8 @@ STUBPREFIX = $(PROJECT)stub # # TIP 430. Unused for 8.6 but no harm defining it to allow a common rules.vc -!if "$(TCL_PATCH_LETTER)" == "." -TCLSCRIPTZIPNAME = libtcl_$(TCL_MAJOR_VERSION)_$(TCL_MINOR_VERSION)_$(TCL_RELEASE_SERIAL).zip -!else -TCLSCRIPTZIPNAME = libtcl_$(TCL_MAJOR_VERSION)_$(TCL_MINOR_VERSION)_$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip -!endif -!if "$(TK_PATCH_LETTER)" == "." -TKSCRIPTZIPNAME = libtk_$(TK_MAJOR_VERSION)_$(TK_MINOR_VERSION)_$(TK_RELEASE_SERIAL).zip -!else -TKSCRIPTZIPNAME = libtk_$(TK_MAJOR_VERSION)_$(TK_MINOR_VERSION)_$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip -!endif +TCLSCRIPTZIPNAME = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip +TKSCRIPTZIPNAME = libtk$(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip !if $(DOING_TCL) TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe -- cgit v0.12 From c0cb466a863a483140db1ffab76d806c696a4dff Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 10 Feb 2021 12:56:47 +0000 Subject: Make TIP #430 work on cygwin. Simplify some makefiles --- generic/tclZipfs.c | 31 +++++++++++-------------------- win/Makefile.in | 4 ---- win/makefile.vc | 11 ----------- 3 files changed, 11 insertions(+), 35 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 7ee13a7..ffc382a 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -38,8 +38,6 @@ #include "zutil.h" #include "crc32.h" -#ifdef CFG_RUNTIME_DLLFILE - /* ** We are compiling as part of the core. ** TIP430 style zipfs prefix @@ -50,22 +48,6 @@ #define ZIPFS_APP_MOUNT "//zipfs:/app" #define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" -#else /* !CFG_RUNTIME_DLLFILE */ - -/* -** We are compiling from the /compat folder of tclconfig -** Pre TIP430 style zipfs prefix -** //zipfs:/ doesn't work straight out of the box on either windows or Unix -** without other changes made to tip 430 -*/ - -#define ZIPFS_VOLUME "zipfs:/" -#define ZIPFS_VOLUME_LEN 7 -#define ZIPFS_APP_MOUNT "zipfs:/app" -#define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" - -#endif /* CFG_RUNTIME_DLLFILE */ - /* * Various constants and offsets found in ZIP archive files */ @@ -3163,6 +3145,7 @@ TclZipfs_TclLibrary(void) * that we must mount the zip file and dll before releasing to search. */ +#if !defined(STATIC_BUILD) #if defined(_WIN32) hModule = TclWinGetTclInstance(); GetModuleFileNameW(hModule, wName, MAX_PATH); @@ -3171,12 +3154,20 @@ TclZipfs_TclLibrary(void) if (ZipfsAppHookFindTclInit(dllName) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } -#elif /* !_WIN32 && */ defined(CFG_RUNTIME_DLLFILE) +#else +# if defined(CFG_RUNTIME_LIBDIR) if (ZipfsAppHookFindTclInit( CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } -#endif /* _WIN32 || CFG_RUNTIME_DLLFILE */ +# endif +# if defined(CFG_RUNTIME_BINDIR) + if (ZipfsAppHookFindTclInit( + CFG_RUNTIME_BINDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } +# endif +#endif /* _WIN32 */ /* * If anything set the cache (but subsequently failed) go with that diff --git a/win/Makefile.in b/win/Makefile.in index b5b4f26..cdaeec4 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -654,10 +654,6 @@ tclMainW.${OBJEXT}: tclMain.c # TIP #430, ZipFS Support tclZipfs.${OBJEXT}: $(GENERIC_DIR)/tclZipfs.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl \ - -DCFG_RUNTIME_PATH="\"$(bindir_native)\"" \ - -DCFG_RUNTIME_DLLFILE="\"$(TCL_DLL_FILE)\"" \ - -DCFG_RUNTIME_LIBDIR="\"$(bindir_native)\"" \ - -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY_NATIVE)\"" \ $(ZLIB_INCLUDE) -I$(MINIZIP_DIR_NATIVE) @DEPARG@ $(CC_OBJNAME) diff --git a/win/makefile.vc b/win/makefile.vc index a124b34..49a82d2 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -807,19 +807,8 @@ $(TMP_DIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c $(TMP_DIR)\tclWinTest.obj: $(WIN_DIR)\tclWinTest.c $(CCAPPCMD) $? -# Following the lead of the autoconf based make, we define the -# CFG_RUNTIME_DLLFILE flag specifically for tclZipfs and tclPkgConfig -# and not as part of the global defines. Moreover, for tclZipfs, -# we define only CFG_RUNTIME_DLLFILE to force use of //zipfs: -# as the zip fs root. However it is defined as empty. See tclPkgConfig.obj -# comments as to why. -# We do not define other CFG_RUNTIME_ZIPFILE at all because -# that causes the zipfs code to go looking at directories that existed -# on the *build* system as opposed to the target runtime system. This -# is the case even if the value is defined as an empty string. $(TMP_DIR)\tclZipfs.obj: $(GENERICDIR)\tclZipfs.c $(cc32) $(pkgcflags) \ - -DCFG_RUNTIME_DLLFILE="\"\"" \ -I$(COMPATDIR)\zlib -I$(COMPATDIR)\zlib\contrib\minizip \ -Fo$@ $? -- cgit v0.12 From dfd4a2e5c1a1e54b69e7317a2d71c09aa7cb42b9 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 10 Feb 2021 13:12:42 +0000 Subject: Missing #endif --- generic/tclZipfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index ffc382a..65c8cc7 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3168,6 +3168,7 @@ TclZipfs_TclLibrary(void) } # endif #endif /* _WIN32 */ +#endif /* !defined(STATIC_BUILD) */ /* * If anything set the cache (but subsequently failed) go with that -- cgit v0.12 From a4bf99fa2cdff061d141d8ae54adc69135adac34 Mon Sep 17 00:00:00 2001 From: culler Date: Thu, 11 Feb 2021 15:12:40 +0000 Subject: Add CFLAGS to the github actions to build fat binaries on macOS. --- .github/workflows/mac-build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/mac-build.yml b/.github/workflows/mac-build.yml index 7ca1817..cba8531 100644 --- a/.github/workflows/mac-build.yml +++ b/.github/workflows/mac-build.yml @@ -16,6 +16,8 @@ jobs: working-directory: generic - name: Build run: make all + env: + CFLAGS: -arch x86_64 -arch arm64e - name: Run Tests run: make test styles=develop env: @@ -46,10 +48,13 @@ jobs: # Note that macOS is always a 64 bit platform run: ./configure --enable-64bit --enable-dtrace --enable-framework ${CFGOPT} "--prefix=$HOME/install" || (cat config.log && exit 1) env: + CFLAGS: -arch x86_64 -arch arm64e CFGOPT: ${{ matrix.cfgopt }} - name: Build run: | make all tcltest + env: + CFLAGS: -arch x86_64 -arch arm64e - name: Run Tests run: | make test -- cgit v0.12 From c1a56eb2d1e2e43e4b1e17aef5fd7f1a627db4e4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 11 Feb 2021 16:30:11 +0000 Subject: Experiment: Integrate culler's "macher" tool. Only for thin binaries --- .github/workflows/mac-build.yml | 6 ++++++ unix/Makefile.in | 7 +++++++ unix/configure | 42 ++++++++++++++++++++++++++++++++++++----- unix/configure.ac | 10 +++++----- unix/tcl.m4 | 25 +++++++++++++++++++++++- 5 files changed, 79 insertions(+), 11 deletions(-) diff --git a/.github/workflows/mac-build.yml b/.github/workflows/mac-build.yml index 7ca1817..c0add28 100644 --- a/.github/workflows/mac-build.yml +++ b/.github/workflows/mac-build.yml @@ -13,6 +13,9 @@ jobs: - name: Prepare run: | touch tclStubInit.c tclOOStubInit.c tclOOScript.h + wget https://github.com/culler/macher/releases/download/v1.0/macher + sudo cp macher /usr/local/bin + sudo chmod a+x /usr/local/bin/macher working-directory: generic - name: Build run: make all @@ -40,6 +43,9 @@ jobs: - name: Prepare run: | touch tclStubInit.c tclOOStubInit.c tclOOScript.h + wget https://github.com/culler/macher/releases/download/v1.0/macher + sudo cp macher /usr/local/bin + sudo chmod a+x /usr/local/bin/macher mkdir "$HOME/install dir" working-directory: generic - name: Configure ${{ matrix.cfgopt }} diff --git a/unix/Makefile.in b/unix/Makefile.in index 00e29be..7c87f07 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -727,6 +727,7 @@ HOST_CC = @CC_FOR_BUILD@ HOST_EXEEXT = @EXEEXT_FOR_BUILD@ HOST_OBJEXT = @OBJEXT_FOR_BUILD@ ZIPFS_BUILD = @ZIPFS_BUILD@ +MACHER = @MACHER_PROG@ NATIVE_ZIP = @ZIP_PROG@ ZIP_PROG_OPTIONS = @ZIP_PROG_OPTIONS@ ZIP_PROG_VFSSEARCH = @ZIP_PROG_VFSSEARCH@ @@ -792,7 +793,10 @@ ${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS} ${TCL_ZIP_FILE} rm -f $@ @MAKE_LIB@ @if test "${ZIPFS_BUILD}" = "1" ; then \ + if test "x$(MACHER)" = "x" ; then \ cat ${TCL_ZIP_FILE} >> ${LIB_FILE}; \ + else $(MACHER) append ${TCL_ZIP_FILE} ${LIB_FILE}; \ + fi; \ ${NATIVE_ZIP} -A ${LIB_FILE} \ || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ fi @@ -819,7 +823,10 @@ ${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${TCL_ZIP_FILE} @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCL_EXE} @if test "${ZIPFS_BUILD}" = "2" ; then \ + if test "x$(MACHER)" = "x" ; then \ cat ${TCL_ZIP_FILE} >> ${TCL_EXE}; \ + else $(MACHER) append ${TCL_ZIP_FILE} ${TCL_EXE}; \ + fi; \ ${NATIVE_ZIP} -A ${TCL_EXE} \ || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ fi diff --git a/unix/configure b/unix/configure index 50a035b..b59a888 100755 --- a/unix/configure +++ b/unix/configure @@ -698,6 +698,7 @@ ZIP_INSTALL_OBJS ZIP_PROG_VFSSEARCH ZIP_PROG_OPTIONS ZIP_PROG +MACHER_PROG EXEEXT_FOR_BUILD CC_FOR_BUILD DTRACE @@ -11028,7 +11029,7 @@ else $as_nop tcl_ok=yes fi -if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then +if test "$tcl_ok" = "yes"; then # # Find a native compiler # @@ -11097,11 +11098,41 @@ printf "%s\n" "$bfd_cv_build_exeext" >&6; } # Find a native zip implementation # + MACHER_PROG="" ZIP_PROG="" ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for macher" >&5 +printf %s "checking for macher... " >&6; } + if test ${ac_cv_path_macher+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/macher 2> /dev/null` \ + `ls -r $dir/macher 2> /dev/null` ; do + if test x"$ac_cv_path_macher" = x ; then + if test -f "$j" ; then + ac_cv_path_macher=$j + break + fi + fi + done + done + +fi + + if test -f "$ac_cv_path_macher" ; then + MACHER_PROG="$ac_cv_path_macher" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MACHER_PROG" >&5 +printf "%s\n" "$MACHER_PROG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Found macher in environment" >&5 +printf "%s\n" "Found macher in environment" >&6; } + fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 printf %s "checking for zip... " >&6; } if test ${ac_cv_path_zip+y} @@ -11148,11 +11179,12 @@ printf "%s\n" "No zip found on PATH. Building minizip" >&6; } - ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip + + ZIPFS_BUILD=1 + TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else - ZIPFS_BUILD=0 - TCL_ZIP_FILE= + ZIPFS_BUILD=0 + TCL_ZIP_FILE= fi # Do checking message here to not mess up interleaved configure output { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5 diff --git a/unix/configure.ac b/unix/configure.ac index edf5f6d..7c30667 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -878,7 +878,7 @@ AC_ARG_ENABLE(zipfs, AS_HELP_STRING([--enable-zipfs], [build with Zipfs support (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) -if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then +if test "$tcl_ok" = "yes"; then # # Find a native compiler # @@ -887,11 +887,11 @@ if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then # Find a native zip implementation # SC_ZIPFS_SUPPORT - ZIPFS_BUILD=1 - TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip + ZIPFS_BUILD=1 + TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip else - ZIPFS_BUILD=0 - TCL_ZIP_FILE= + ZIPFS_BUILD=0 + TCL_ZIP_FILE= fi # Do checking message here to not mess up interleaved configure output AC_MSG_CHECKING([for building with zipfs]) diff --git a/unix/tcl.m4 b/unix/tcl.m4 index a8911f8..7fc696e 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -3011,18 +3011,40 @@ AC_DEFUN([AX_CC_FOR_BUILD],[# Put a plausible default for CC_FOR_BUILD in Makefi # # Results: # Substitutes the following vars: -# ZIP_PROG +# MACHER_PROG +# ZIP_PROG # ZIP_PROG_OPTIONS # ZIP_PROG_VFSSEARCH # ZIP_INSTALL_OBJS #------------------------------------------------------------------------ AC_DEFUN([SC_ZIPFS_SUPPORT], [ + MACHER_PROG="" ZIP_PROG="" ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" + AC_MSG_CHECKING([for macher]) + AC_CACHE_VAL(ac_cv_path_macher, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/macher 2> /dev/null` \ + `ls -r $dir/macher 2> /dev/null` ; do + if test x"$ac_cv_path_macher" = x ; then + if test -f "$j" ; then + ac_cv_path_macher=$j + break + fi + fi + done + done + ]) + if test -f "$ac_cv_path_macher" ; then + MACHER_PROG="$ac_cv_path_macher" + AC_MSG_RESULT([$MACHER_PROG]) + AC_MSG_RESULT([Found macher in environment]) + fi AC_MSG_CHECKING([for zip]) AC_CACHE_VAL(ac_cv_path_zip, [ search_path=`echo ${PATH} | sed -e 's/:/ /g'` @@ -3054,6 +3076,7 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" AC_MSG_RESULT([No zip found on PATH. Building minizip]) fi + AC_SUBST(MACHER_PROG) AC_SUBST(ZIP_PROG) AC_SUBST(ZIP_PROG_OPTIONS) AC_SUBST(ZIP_PROG_VFSSEARCH) -- cgit v0.12 From 89fa1f862f5eda2693f5783393adf5352a96a1da Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 11 Feb 2021 17:19:38 +0000 Subject: macher 1.0 -> 1.1 --- .github/workflows/mac-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mac-build.yml b/.github/workflows/mac-build.yml index c0add28..fa946d2 100644 --- a/.github/workflows/mac-build.yml +++ b/.github/workflows/mac-build.yml @@ -13,7 +13,7 @@ jobs: - name: Prepare run: | touch tclStubInit.c tclOOStubInit.c tclOOScript.h - wget https://github.com/culler/macher/releases/download/v1.0/macher + wget https://github.com/culler/macher/releases/download/v1.1/macher sudo cp macher /usr/local/bin sudo chmod a+x /usr/local/bin/macher working-directory: generic @@ -43,7 +43,7 @@ jobs: - name: Prepare run: | touch tclStubInit.c tclOOStubInit.c tclOOScript.h - wget https://github.com/culler/macher/releases/download/v1.0/macher + wget https://github.com/culler/macher/releases/download/v1.1/macher sudo cp macher /usr/local/bin sudo chmod a+x /usr/local/bin/macher mkdir "$HOME/install dir" -- cgit v0.12 From 840ba03059b7fa3e6995fdf5b6ba2f4f6c9b1023 Mon Sep 17 00:00:00 2001 From: culler Date: Fri, 12 Feb 2021 01:46:21 +0000 Subject: macher 1.1 -> 1.2 (bug fixes) and account for new append syntax. --- .github/workflows/mac-build.yml | 4 ++-- unix/Makefile.in | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/mac-build.yml b/.github/workflows/mac-build.yml index fa946d2..ea640d0 100644 --- a/.github/workflows/mac-build.yml +++ b/.github/workflows/mac-build.yml @@ -13,7 +13,7 @@ jobs: - name: Prepare run: | touch tclStubInit.c tclOOStubInit.c tclOOScript.h - wget https://github.com/culler/macher/releases/download/v1.1/macher + wget https://github.com/culler/macher/releases/download/v1.2/macher sudo cp macher /usr/local/bin sudo chmod a+x /usr/local/bin/macher working-directory: generic @@ -43,7 +43,7 @@ jobs: - name: Prepare run: | touch tclStubInit.c tclOOStubInit.c tclOOScript.h - wget https://github.com/culler/macher/releases/download/v1.1/macher + wget https://github.com/culler/macher/releases/download/v1.2/macher sudo cp macher /usr/local/bin sudo chmod a+x /usr/local/bin/macher mkdir "$HOME/install dir" diff --git a/unix/Makefile.in b/unix/Makefile.in index 7c87f07..df55f5d 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -795,7 +795,8 @@ ${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS} ${TCL_ZIP_FILE} @if test "${ZIPFS_BUILD}" = "1" ; then \ if test "x$(MACHER)" = "x" ; then \ cat ${TCL_ZIP_FILE} >> ${LIB_FILE}; \ - else $(MACHER) append ${TCL_ZIP_FILE} ${LIB_FILE}; \ + else $(MACHER) append ${LIB_FILE} ${TCL_ZIP_FILE} /tmp/macher_output; \ + mv /tmp/macher_output ${LIB_FILE}; \ fi; \ ${NATIVE_ZIP} -A ${LIB_FILE} \ || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ @@ -825,7 +826,8 @@ ${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${TCL_ZIP_FILE} @if test "${ZIPFS_BUILD}" = "2" ; then \ if test "x$(MACHER)" = "x" ; then \ cat ${TCL_ZIP_FILE} >> ${TCL_EXE}; \ - else $(MACHER) append ${TCL_ZIP_FILE} ${TCL_EXE}; \ + else $(MACHER) append ${TCL_EXE} ${TCL_ZIP_FILE} /tmp/macher_output; \ + mv /tmp/macher_output ${TCL_EXE}; \ fi; \ ${NATIVE_ZIP} -A ${TCL_EXE} \ || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ -- cgit v0.12 From 42e3415106fd0092b5a661973d6c5406d8d46db6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 12 Feb 2021 08:21:46 +0000 Subject: Fix warning about unused symbol on --disable-shared build --- generic/tclZipfs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 65c8cc7..50653ff 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -285,7 +285,9 @@ static const char *zipfs_literal_tcl_library = NULL; static inline int DescribeMounted(Tcl_Interp *interp, const char *mountPoint); static inline int ListMountPoints(Tcl_Interp *interp); +#if !defined(STATIC_BUILD) static int ZipfsAppHookFindTclInit(const char *archive); +#endif static int ZipFSPathInFilesystemProc(Tcl_Obj *pathPtr, void **clientDataPtr); static Tcl_Obj * ZipFSFilesystemPathTypeProc(Tcl_Obj *pathPtr); @@ -4755,6 +4757,7 @@ TclZipfs_Init( #endif /* HAVE_ZLIB */ } +#if !defined(STATIC_BUILD) static int ZipfsAppHookFindTclInit( const char *archive) @@ -4791,6 +4794,7 @@ ZipfsAppHookFindTclInit( return TCL_ERROR; } +#endif static void ZipfsExitHandler( -- cgit v0.12 From 7b662b613dffa1e3ec17a36f921d80e0fd5a9e02 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 12 Feb 2021 11:12:09 +0000 Subject: Syntax error in yaml-file --- .github/workflows/mac-build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mac-build.yml b/.github/workflows/mac-build.yml index cba8531..81f8882 100644 --- a/.github/workflows/mac-build.yml +++ b/.github/workflows/mac-build.yml @@ -17,7 +17,7 @@ jobs: - name: Build run: make all env: - CFLAGS: -arch x86_64 -arch arm64e + CFLAGS: "-arch x86_64 -arch arm64e" - name: Run Tests run: make test styles=develop env: @@ -48,13 +48,13 @@ jobs: # Note that macOS is always a 64 bit platform run: ./configure --enable-64bit --enable-dtrace --enable-framework ${CFGOPT} "--prefix=$HOME/install" || (cat config.log && exit 1) env: - CFLAGS: -arch x86_64 -arch arm64e + CFLAGS: "-arch x86_64 -arch arm64e" CFGOPT: ${{ matrix.cfgopt }} - name: Build run: | make all tcltest env: - CFLAGS: -arch x86_64 -arch arm64e + CFLAGS: "-arch x86_64 -arch arm64e" - name: Run Tests run: | make test -- cgit v0.12 From 21d34a19569a60fcfb184212d11b6c0174799ca5 Mon Sep 17 00:00:00 2001 From: culler Date: Fri, 12 Feb 2021 14:57:10 +0000 Subject: The syntax error was caused by Aquamacs inserting tabs into the YAML file. --- .github/workflows/mac-build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/mac-build.yml b/.github/workflows/mac-build.yml index 81f8882..bf3c420 100644 --- a/.github/workflows/mac-build.yml +++ b/.github/workflows/mac-build.yml @@ -16,8 +16,8 @@ jobs: working-directory: generic - name: Build run: make all - env: - CFLAGS: "-arch x86_64 -arch arm64e" + env: + CFLAGS: -arch x86_64 -arch arm64e - name: Run Tests run: make test styles=develop env: @@ -48,13 +48,13 @@ jobs: # Note that macOS is always a 64 bit platform run: ./configure --enable-64bit --enable-dtrace --enable-framework ${CFGOPT} "--prefix=$HOME/install" || (cat config.log && exit 1) env: - CFLAGS: "-arch x86_64 -arch arm64e" + CFLAGS: -arch x86_64 -arch arm64e CFGOPT: ${{ matrix.cfgopt }} - name: Build run: | make all tcltest - env: - CFLAGS: "-arch x86_64 -arch arm64e" + env: + CFLAGS: -arch x86_64 -arch arm64e - name: Run Tests run: | make test -- cgit v0.12 From 6fcd32ac08f4b7f5d4dd5a52c5d18ddc70dea857 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 Feb 2021 07:31:08 +0000 Subject: "macher" output should be executable --- unix/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index df55f5d..aa54fbe 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -796,7 +796,7 @@ ${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS} ${TCL_ZIP_FILE} if test "x$(MACHER)" = "x" ; then \ cat ${TCL_ZIP_FILE} >> ${LIB_FILE}; \ else $(MACHER) append ${LIB_FILE} ${TCL_ZIP_FILE} /tmp/macher_output; \ - mv /tmp/macher_output ${LIB_FILE}; \ + mv /tmp/macher_output ${LIB_FILE}; chmod u+x ${LIB_FILE} \ fi; \ ${NATIVE_ZIP} -A ${LIB_FILE} \ || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ @@ -827,7 +827,7 @@ ${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${TCL_ZIP_FILE} if test "x$(MACHER)" = "x" ; then \ cat ${TCL_ZIP_FILE} >> ${TCL_EXE}; \ else $(MACHER) append ${TCL_EXE} ${TCL_ZIP_FILE} /tmp/macher_output; \ - mv /tmp/macher_output ${TCL_EXE}; \ + mv /tmp/macher_output ${TCL_EXE}; chmod u+x ${TCL_EXE} \ fi; \ ${NATIVE_ZIP} -A ${TCL_EXE} \ || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ -- cgit v0.12 From 0d7614dd81f9fba7b15f5d1e3fc174b6d1e8038d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 Feb 2021 07:47:33 +0000 Subject: Missing semicolon in UNIX Makefile --- unix/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index aa54fbe..32b99a2 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -796,7 +796,7 @@ ${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS} ${TCL_ZIP_FILE} if test "x$(MACHER)" = "x" ; then \ cat ${TCL_ZIP_FILE} >> ${LIB_FILE}; \ else $(MACHER) append ${LIB_FILE} ${TCL_ZIP_FILE} /tmp/macher_output; \ - mv /tmp/macher_output ${LIB_FILE}; chmod u+x ${LIB_FILE} \ + mv /tmp/macher_output ${LIB_FILE}; chmod u+x ${LIB_FILE}; \ fi; \ ${NATIVE_ZIP} -A ${LIB_FILE} \ || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ @@ -827,7 +827,7 @@ ${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${TCL_ZIP_FILE} if test "x$(MACHER)" = "x" ; then \ cat ${TCL_ZIP_FILE} >> ${TCL_EXE}; \ else $(MACHER) append ${TCL_EXE} ${TCL_ZIP_FILE} /tmp/macher_output; \ - mv /tmp/macher_output ${TCL_EXE}; chmod u+x ${TCL_EXE} \ + mv /tmp/macher_output ${TCL_EXE}; chmod u+x ${TCL_EXE}; \ fi; \ ${NATIVE_ZIP} -A ${TCL_EXE} \ || echo 'ignore zip-error by adjust sfx process (not executable?)'; \ -- cgit v0.12 From 5eba4fa4d73e7249d46af537a2d631f6799f8f11 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 Feb 2021 07:48:54 +0000 Subject: Add testcases, contributed by Christian Werner. Two of them fail, so still some work to do. [d43f96c1a8] --- tests/string.test | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/string.test b/tests/string.test index 3775c0d..62bc062 100644 --- a/tests/string.test +++ b/tests/string.test @@ -1897,6 +1897,33 @@ test string-21.15.$noComp {string wordend, unicode} -body { test string-21.16.$noComp {string wordend, unicode} -constraints utf16 -body { run {string wordend "\U1D7CA\U1D7CA abc" 10} } -result 8 +test string-21.17 {string trim, unicode} knownBug { + string trim "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD83D\uDE02 +} "Hello world!" +test string-21.18 {string trimleft, unicode} { + string trimleft "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD83D\uDE02 +} "Hello world!\uD83D\uDE02" +test string-21.19 {string trimright, unicode} knownBug { + string trimright "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD83D\uDE02 +} "\uD83D\uDE02Hello world!" +test string-21.20 {string trim, unicode} { + string trim "\uF602Hello world!\uF602" \uD83D\uDE02 +} "\uF602Hello world!\uF602" +test string-21.21 {string trimleft, unicode} { + string trimleft "\uF602Hello world!\uF602" \uD83D\uDE02 +} "\uF602Hello world!\uF602" +test string-21.22 {string trimright, unicode} { + string trimright "\uF602Hello world!\uF602" \uD83D\uDE02 +} "\uF602Hello world!\uF602" +test string-21.23 {string trim, unicode} { + string trim "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD93D\uDE02 +} "\uD83D\uDE02Hello world!\uD83D\uDE02" +test string-21.24 {string trimleft, unicode} { + string trimleft "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD93D\uDE02 +} "\uD83D\uDE02Hello world!\uD83D\uDE02" +test string-21.25 {string trimright, unicode} { + string trimright "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD93D\uDE02 +} "\uD83D\uDE02Hello world!\uD83D\uDE02" test string-22.1.$noComp {string wordstart} -body { list [catch {run {string word a}} msg] $msg -- cgit v0.12 From ab91723185690febc744d2e0f85bcbeac259874a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 Feb 2021 08:07:42 +0000 Subject: Add testcases from Christian Werner, regarding "string trim" with Emoji --- tests/string.test | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/string.test b/tests/string.test index b1f9dc3..c7cf8d5 100644 --- a/tests/string.test +++ b/tests/string.test @@ -1645,6 +1645,33 @@ test string-21.13 {string wordend, unicode} { test string-21.14 {string wordend, unicode} { string wordend "\uC700\uC700 abc" 8 } 6 +test string-21.17 {string trim, unicode} knownBug { + string trim "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD83D\uDE02 +} "Hello world!" +test string-21.18 {string trimleft, unicode} { + string trimleft "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD83D\uDE02 +} "Hello world!\uD83D\uDE02" +test string-21.19 {string trimright, unicode} knownBug { + string trimright "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD83D\uDE02 +} "\uD83D\uDE02Hello world!" +test string-21.20 {string trim, unicode} { + string trim "\uF602Hello world!\uF602" \uD83D\uDE02 +} "\uF602Hello world!\uF602" +test string-21.21 {string trimleft, unicode} { + string trimleft "\uF602Hello world!\uF602" \uD83D\uDE02 +} "\uF602Hello world!\uF602" +test string-21.22 {string trimright, unicode} { + string trimright "\uF602Hello world!\uF602" \uD83D\uDE02 +} "\uF602Hello world!\uF602" +test string-21.23 {string trim, unicode} knownBug { + string trim "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD93D\uDE02 +} "\uD83D\uDE02Hello world!\uD83D\uDE02" +test string-21.24 {string trimleft, unicode} { + string trimleft "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD93D\uDE02 +} "\uD83D\uDE02Hello world!\uD83D\uDE02" +test string-21.25 {string trimright, unicode} knownBug { + string trimright "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD93D\uDE02 +} "\uD83D\uDE02Hello world!\uD83D\uDE02" test string-22.1 {string wordstart} { list [catch {string word a} msg] $msg -- cgit v0.12 From 13b1a0635f7e5f4c9fce04fe3474d16418d57522 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 Feb 2021 12:35:33 +0000 Subject: More testcases from Christian Werner, regarding "string reverse" with Emoji. Those testcases fail in all Tcl 8.6.x releases. --- tests/string.test | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/string.test b/tests/string.test index c7cf8d5..3f0a04b 100644 --- a/tests/string.test +++ b/tests/string.test @@ -1828,6 +1828,24 @@ test string-24.15 {string reverse command - pure bytearray} { binary scan [tcl::string::reverse [binary format H* 010203]] H* x set x } 030201 +test string-24.16 {string reverse command - surrogates} knownBug { + string reverse \u0444bulb\uD83D\uDE02 +} \uD83D\uDE02blub\u0444 +test string-24.17 {string reverse command - surrogates} knownBug { + string reverse \uD83D\uDE02hello\uD83D\uDE02 +} \uD83D\uDE02olleh\uD83D\uDE02 +test string-24.18 {string reverse command - surrogates} knownBug { + set s \u0444bulb\uD83D\uDE02 + # shim shimmery ... + string index $s 0 + string reverse $s +} \uD83D\uDE02blub\u0444 +test string-24.19 {string reverse command - surrogates} knownBug { + set s \uD83D\uDE02hello\uD83D\uDE02 + # shim shimmery ... + string index $s 0 + string reverse $s +} \uD83D\uDE02olleh\uD83D\uDE02 test string-25.1 {string is list} { string is list {a b c} -- cgit v0.12 From b4660a7ff9a3dac758b033af3fd7618db6a68b9d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 Feb 2021 15:41:55 +0000 Subject: Remove unused variable in win32 static build --- generic/tclZipfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 50653ff..0d646aa 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3113,7 +3113,7 @@ TclZipfs_TclLibrary(void) { Tcl_Obj *vfsInitScript; int found; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(STATIC_BUILD) HMODULE hModule; WCHAR wName[MAX_PATH + LIBRARY_SIZE]; char dllName[(MAX_PATH + LIBRARY_SIZE) * 3]; -- cgit v0.12 From c6e348a28b0d74bc880f56b2f2db6f8c97f1b6ca Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 Feb 2021 16:13:15 +0000 Subject: Fix [d43f96c1a8]: string trimright is broken for Emoji --- generic/tclUtil.c | 17 +++++++++-------- tests/string.test | 8 ++++---- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index d7baedd..0e3449d 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1686,7 +1686,7 @@ TclTrimRight( * rely on (trim[numTrim] == '\0'). */ { const char *pp, *p = bytes + numBytes; - Tcl_UniChar ch1 = 0; + int ch1, ch2; /* Empty strings -> nothing to do */ if ((numBytes == 0) || (numTrim == 0)) { @@ -1700,12 +1700,14 @@ TclTrimRight( do { const char *q = trim; int pInc = 0, bytesLeft = numTrim; - Tcl_UniChar ch2 = 0; pp = TclUtfPrev(p, bytes); +#if TCL_UTF_MAX <= 4 + pp = TclUtfPrev(pp, bytes); +#endif do { pp += pInc; - pInc = TclUtfToUniChar(pp, &ch1); + pInc = TclUtfToUCS4(pp, &ch1); } while (pp + pInc < p); /* @@ -1713,7 +1715,7 @@ TclTrimRight( */ do { - int qInc = TclUtfToUniChar(q, &ch2); + int qInc = TclUtfToUCS4(q, &ch2); if (ch1 == ch2) { break; @@ -1766,7 +1768,7 @@ TclTrimLeft( * rely on (trim[numTrim] == '\0'). */ { const char *p = bytes; - Tcl_UniChar ch1 = 0; + int ch1, ch2; /* Empty strings -> nothing to do */ if ((numBytes == 0) || (numTrim == 0)) { @@ -1778,8 +1780,7 @@ TclTrimLeft( */ do { - Tcl_UniChar ch2 = 0; - int pInc = TclUtfToUniChar(p, &ch1); + int pInc = TclUtfToUCS4(p, &ch1); const char *q = trim; int bytesLeft = numTrim; @@ -1788,7 +1789,7 @@ TclTrimLeft( */ do { - int qInc = TclUtfToUniChar(q, &ch2); + int qInc = TclUtfToUCS4(q, &ch2); if (ch1 == ch2) { break; diff --git a/tests/string.test b/tests/string.test index 3f0a04b..3ac3060 100644 --- a/tests/string.test +++ b/tests/string.test @@ -1645,13 +1645,13 @@ test string-21.13 {string wordend, unicode} { test string-21.14 {string wordend, unicode} { string wordend "\uC700\uC700 abc" 8 } 6 -test string-21.17 {string trim, unicode} knownBug { +test string-21.17 {string trim, unicode} { string trim "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD83D\uDE02 } "Hello world!" test string-21.18 {string trimleft, unicode} { string trimleft "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD83D\uDE02 } "Hello world!\uD83D\uDE02" -test string-21.19 {string trimright, unicode} knownBug { +test string-21.19 {string trimright, unicode} { string trimright "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD83D\uDE02 } "\uD83D\uDE02Hello world!" test string-21.20 {string trim, unicode} { @@ -1663,13 +1663,13 @@ test string-21.21 {string trimleft, unicode} { test string-21.22 {string trimright, unicode} { string trimright "\uF602Hello world!\uF602" \uD83D\uDE02 } "\uF602Hello world!\uF602" -test string-21.23 {string trim, unicode} knownBug { +test string-21.23 {string trim, unicode} { string trim "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD93D\uDE02 } "\uD83D\uDE02Hello world!\uD83D\uDE02" test string-21.24 {string trimleft, unicode} { string trimleft "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD93D\uDE02 } "\uD83D\uDE02Hello world!\uD83D\uDE02" -test string-21.25 {string trimright, unicode} knownBug { +test string-21.25 {string trimright, unicode} { string trimright "\uD83D\uDE02Hello world!\uD83D\uDE02" \uD93D\uDE02 } "\uD83D\uDE02Hello world!\uD83D\uDE02" -- cgit v0.12 From 3eb07e538c3bf623b1b048ccf5c866ea118b4e4f Mon Sep 17 00:00:00 2001 From: culler Date: Mon, 15 Feb 2021 17:06:47 +0000 Subject: Switch to version 1.3 of macher for the onefiledist --- .github/workflows/onefiledist.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/onefiledist.yml b/.github/workflows/onefiledist.yml index 158542a..df98bec 100644 --- a/.github/workflows/onefiledist.yml +++ b/.github/workflows/onefiledist.yml @@ -55,7 +55,7 @@ jobs: run: | mkdir 1dist touch generic/tclStubInit.c generic/tclOOStubInit.c || true - wget https://github.com/culler/macher/releases/download/v1.2/macher + wget https://github.com/culler/macher/releases/download/v1.3/macher sudo cp macher /usr/local/bin sudo chmod a+x /usr/local/bin/macher echo "VER_PATH=$(cd tools; pwd)/addVerToFile.tcl" >> $GITHUB_ENV -- cgit v0.12 From d97e25b2ad96e4be2e23c349c2d0e6d44cab07e4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 16 Feb 2021 08:10:34 +0000 Subject: Fix Tcl_UtfPrev for TCL_UTF_MAX>3, so it can jump back over Emoji. Backported from 8.7, no change for TCL_UTF_MAX=3. This way, the previous fix can be slightly more simplified, and working for TCL_UTF_MAX>3 too. --- generic/tclUtf.c | 2 +- generic/tclUtil.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 5ae977a..f99c497 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -888,7 +888,7 @@ Tcl_UtfPrev( /* Continue the search backwards... */ look--; - } while (trailBytesSeen < 3); + } while (trailBytesSeen < (TCL_UTF_MAX < 4 ? 3 : 4)); /* * We've seen 3 trail bytes, so we know there will not be a diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 0e3449d..450f3bf 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1702,7 +1702,7 @@ TclTrimRight( int pInc = 0, bytesLeft = numTrim; pp = TclUtfPrev(p, bytes); -#if TCL_UTF_MAX <= 4 +#if TCL_UTF_MAX < 4 pp = TclUtfPrev(pp, bytes); #endif do { @@ -1715,14 +1715,14 @@ TclTrimRight( */ do { - int qInc = TclUtfToUCS4(q, &ch2); + pInc = TclUtfToUCS4(q, &ch2); if (ch1 == ch2) { break; } - q += qInc; - bytesLeft -= qInc; + q += pInc; + bytesLeft -= pInc; } while (bytesLeft); if (bytesLeft == 0) { -- cgit v0.12 From 4b639c1ec59a558f0feda5d8f16f0c8482f22f85 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 16 Feb 2021 09:00:14 +0000 Subject: Fix Tcl_UtfPrev expected testcases for TCL_UTF_MAX>3 --- tests/utf.test | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/tests/utf.test b/tests/utf.test index 99d4c36..8e886ae 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -781,9 +781,12 @@ test utf-7.18.2 {Tcl_UtfPrev} {testutfprev testbytestring} { test utf-7.19 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A[testbytestring \xF8\xA0\xA0\xA0] } 4 -test utf-7.20 {Tcl_UtfPrev} {testutfprev testbytestring} { +test utf-7.20.0 {Tcl_UtfPrev} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF2\xA0\xA0\xA0] } 4 +test utf-7.20.1 {Tcl_UtfPrev} {testutfprev testbytestring fullutf} { + testutfprev A[testbytestring \xF2\xA0\xA0\xA0] +} 1 test utf-7.21 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A\u8820[testbytestring \xA0] } 4 @@ -844,9 +847,12 @@ test utf-7.37 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring} { test utf-7.38 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring} { testutfprev A[testbytestring \xE0\xA0\x80] 2 } 1 -test utf-7.39 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring} { +test utf-7.39.0 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF0\x90\x80\x80] } 4 +test utf-7.39.1 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring fullutf} { + testutfprev A[testbytestring \xF0\x90\x80\x80] +} 1 test utf-7.40.0 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF0\x90\x80\x80] 4 } 3 @@ -883,22 +889,25 @@ test utf-7.47.1 {Tcl_UtfPrev, pointing to 3th byte of 3-byte valid sequence} tes test utf-7.47.2 {Tcl_UtfPrev, pointing to 3th byte of 3-byte invalid sequence} {testutfprev testbytestring} { testutfprev [testbytestring \xE8\xA0\x00] 2 } 0 -test utf-7.48.0 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring} { +test utf-7.48.0 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] } 4 -test utf-7.48.1 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { +test utf-7.48.1 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { + testutfprev A[testbytestring \xF4\x8F\xBF\xBF] +} 1 +test utf-7.48.2 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 4 } 3 -test utf-7.48.2 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { +test utf-7.48.3 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 4 } 1 -test utf-7.48.3 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { +test utf-7.48.4 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 3 } 2 -test utf-7.48.4 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { +test utf-7.48.5 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 3 } 1 -test utf-7.48.5 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring} { +test utf-7.48.6 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 2 } 1 test utf-7.49.0 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring} { -- cgit v0.12 From 3001f870632e5d152e76bbc599fea7b27d79b2af Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 16 Feb 2021 11:05:18 +0000 Subject: Remove unnecessary end-of-line spacing in test-cases --- tests/apply.test | 2 +- tests/assemble.test | 76 ++++++++++++++++++++++++------------------------ tests/assemble1.bench | 19 ++++++------ tests/chan.test | 4 +-- tests/cmdMZ.test | 2 +- tests/env.test | 4 +-- tests/history.test | 2 +- tests/httpd | 2 +- tests/init.test | 10 +++---- tests/internals.tcl | 4 +-- tests/iogt.test | 2 +- tests/lindex.test | 4 +-- tests/lrange.test | 2 +- tests/lrepeat.test | 4 +-- tests/misc.test | 4 +-- tests/nre.test | 6 ++-- tests/obj.test | 6 ++-- tests/package.test | 4 +-- tests/parseExpr.test | 4 +-- tests/platform.test | 4 +-- tests/regexp.test | 10 +++---- tests/regexpComp.test | 12 ++++---- tests/split.test | 2 +- tests/stack.test | 2 +- tests/tailcall.test | 12 ++++---- tests/unixForkEvent.test | 2 +- tests/unixNotfy.test | 4 +-- tests/upvar.test | 2 +- tests/winPipe.test | 2 +- 29 files changed, 106 insertions(+), 107 deletions(-) diff --git a/tests/apply.test b/tests/apply.test index 0a64aa0..8696245 100644 --- a/tests/apply.test +++ b/tests/apply.test @@ -228,7 +228,7 @@ test apply-8.3 {args treatment} { apply [list {x args} $applyBody] 1 2 3 } {{x 1} {args {2 3}}} test apply-8.4 {default values} { - apply [list {{x 1} {y 2}} $applyBody] + apply [list {{x 1} {y 2}} $applyBody] } {{x 1} {y 2}} test apply-8.5 {default values} { apply [list {{x 1} {y 2}} $applyBody] 3 4 diff --git a/tests/assemble.test b/tests/assemble.test index d2e626b..42c268a 100644 --- a/tests/assemble.test +++ b/tests/assemble.test @@ -301,12 +301,12 @@ test assemble-7.1 {add, wrong # args} { -result {wrong # args*} } test assemble-7.2 {add} { - -body { + -body { assemble { push 2 push 2 add - } + } } -result {4} } @@ -349,7 +349,7 @@ test assemble-7.5 {bitwise ops} { } test assemble-7.6 {div} { -body { - assemble {push 999999; push 7; div} + assemble {push 999999; push 7; div} } -result 142857 } @@ -360,7 +360,7 @@ test assemble-7.7 {dup} { } } -result 9 -} +} test assemble-7.8 {eq} { -body { list \ @@ -638,7 +638,7 @@ test assemble-7.24 {lsetList} { test assemble-7.25 {lshift} { -body { assemble {push 16; push 4; lshift} - } + } -result 256 } test assemble-7.26 {mod} { @@ -678,7 +678,7 @@ test assemble-7.30 {pop} { test assemble-7.31 {rshift} { -body { assemble {push 257; push 4; rshift} - } + } -result 16 } test assemble-7.32 {storeArrayStk} { @@ -1201,7 +1201,7 @@ test assemble-10.7 {expr - noncompilable} { # assemble-11 - ASSEM_LVT4 (exist, existArray, dictAppend, dictLappend, # nsupvar, variable, upvar) - + test assemble-11.1 {exist - wrong # args} { -body { assemble {exist} @@ -1310,7 +1310,7 @@ test assemble-11.10 {variable} { } # assemble-12 - ASSEM_LVT1 (incr and incrArray) - + test assemble-12.1 {incr - wrong # args} { -body { assemble {incr} @@ -1723,16 +1723,16 @@ test assemble-17.9 {jump - resolve a label multiple times} { set result {} assemble { jump common - + label zero - pop + pop incrImm case 1 pop push a append result pop jump common - + label one pop incrImm case 1 @@ -1741,7 +1741,7 @@ test assemble-17.9 {jump - resolve a label multiple times} { append result pop jump common - + label common load case dup @@ -1760,7 +1760,7 @@ test assemble-17.9 {jump - resolve a label multiple times} { push 3 eq jumpTrue three - + label two pop incrImm case 1 @@ -1769,7 +1769,7 @@ test assemble-17.9 {jump - resolve a label multiple times} { append result pop jump common - + label three pop incrImm case 1 @@ -1867,7 +1867,7 @@ test assemble-17.15 {multiple passes of code resizing} { append body {label b15; push b; concat 2; nop; nop; jump c} \n append body {label d} proc x {} [list assemble $body] - } + } -body { x } @@ -2060,7 +2060,7 @@ test assemble-20.5 {lsetFlat - negative operand count} { test assemble-20.6 {lsetFlat} { -body { assemble {push b; push a; lsetFlat 2} - } + } -result b } test assemble-20.7 {lsetFlat} { @@ -3046,12 +3046,12 @@ test assemble-40.1 {unbalanced stack} { [catch { assemble { push 3 - dup - mult + dup + mult push 4 - dup - mult - pop + dup + mult + pop expon } } result] $result $::errorInfo @@ -3150,7 +3150,7 @@ test assemble-50.1 {Ulam's 3n+1 problem, TAL implementation} { load n; # max dup; # max n jump start; # max n - + label loop; # max n over 1; # max n max over 1; # max in max n @@ -3160,29 +3160,29 @@ test assemble-50.1 {Ulam's 3n+1 problem, TAL implementation} { reverse 2; # n max pop; # n dup; # n n - + label skip; # max n dup; # max n n push 2; # max n n 2 mod; # max n n%2 jumpTrue odd; # max n - + push 2; # max n 2 div; # max n/2 -> max n jump start; # max n - + label odd; # max n push 3; # max n 3 mult; # max 3*n push 1; # max 3*n 1 add; # max 3*n+1 - + label start; # max n dup; # max n n push 1; # max n n 1 neq; # max n n>1 jumpTrue loop; # max n - + pop; # max } } @@ -3212,7 +3212,7 @@ test assemble-51.3 {memory leak testing} memory { load n; # max dup; # max n jump start; # max n - + label loop; # max n over 1; # max n max over 1; # max in max n @@ -3222,29 +3222,29 @@ test assemble-51.3 {memory leak testing} memory { reverse 2; # n max pop; # n dup; # n n - + label skip; # max n dup; # max n n push 2; # max n n 2 mod; # max n n%2 jumpTrue odd; # max n - + push 2; # max n 2 div; # max n/2 -> max n jump start; # max n - + label odd; # max n push 3; # max n 3 mult; # max 3*n push 1; # max 3*n 1 add; # max 3*n+1 - + label start; # max n dup; # max n n push 1; # max n n 1 neq; # max n n>1 jumpTrue loop; # max n - + pop; # max } }} 1 @@ -3277,7 +3277,7 @@ test assemble-52.1 {Bug 3154ea2759} { label @okLabel endCatch pop - + beginCatch @badLabel2 push error push testing @@ -3290,7 +3290,7 @@ test assemble-52.1 {Bug 3154ea2759} { label @okLabel2 endCatch pop - + beginCatch @badLabel3 push error push testing @@ -3303,7 +3303,7 @@ test assemble-52.1 {Bug 3154ea2759} { label @okLabel3 endCatch pop - + beginCatch @badLabel4 push error push testing @@ -3316,7 +3316,7 @@ test assemble-52.1 {Bug 3154ea2759} { label @okLabel4 endCatch pop - + beginCatch @badLabel5 push error push testing @@ -3329,7 +3329,7 @@ test assemble-52.1 {Bug 3154ea2759} { label @okLabel5 endCatch pop - + beginCatch @badLabel6 push error push testing diff --git a/tests/assemble1.bench b/tests/assemble1.bench index 18fd3a9..e294108 100644 --- a/tests/assemble1.bench +++ b/tests/assemble1.bench @@ -20,7 +20,7 @@ proc ulam2 {n} { load n; # max dup; # max n jump start; # max n - + label loop; # max n over 1; # max n max over 1; # max in max n @@ -30,29 +30,29 @@ proc ulam2 {n} { reverse 2; # n max pop; # n dup; # n n - + label skip; # max n dup; # max n n push 2; # max n n 2 mod; # max n n%2 jumpTrue odd; # max n - + push 2; # max n 2 div; # max n/2 -> max n jump start; # max n - + label odd; # max n push 3; # max n 3 mult; # max 3*n push 1; # max 3*n 1 add; # max 3*n+1 - + label start; # max n dup; # max n n push 1; # max n n 1 neq; # max n n>1 jumpTrue loop; # max n - + pop; # max } } @@ -60,12 +60,12 @@ set tcl_traceCompile 2; ulam2 1; set tcl_traceCompile 0 proc test1 {n} { for {set i 1} {$i <= $n} {incr i} { - ulam1 $i + ulam1 $i } } proc test2 {n} { for {set i 1} {$i <= $n} {incr i} { - ulam2 $i + ulam2 $i } } @@ -75,11 +75,10 @@ for {set j 0} {$j < 10} {incr j} { test1 30000 set after [clock microseconds] puts "compiled: [expr {1e-6 * ($after - $before)}]" - + test2 1 set before [clock microseconds] test2 30000 set after [clock microseconds] puts "assembled: [expr {1e-6 * ($after - $before)}]" } - \ No newline at end of file diff --git a/tests/chan.test b/tests/chan.test index 49afdc6..5d05935 100644 --- a/tests/chan.test +++ b/tests/chan.test @@ -135,7 +135,7 @@ test chan-16.4 {chan command: pending subcommand} -body { chan pending {input output} stdout } -returnCodes error -result "bad mode \"input output\": must be input or output" test chan-16.5 {chan command: pending input subcommand} -body { - chan pending input stdout + chan pending input stdout } -result -1 test chan-16.6 {chan command: pending input subcommand} -body { chan pending input stdin @@ -194,7 +194,7 @@ test chan-16.9 {chan command: pending input subcommand} -setup { set ::chan-16.9-data [list] set ::chan-16.9-done 0 } -body { - after idle chan-16.9-client + after idle chan-16.9-client vwait ::chan-16.9-done set ::chan-16.9-data } -result {-1 0 0 1 36 -1 0 0 1 72 -1 0 0 1 108 -1 0 0 1 144 ABC 890} -cleanup { diff --git a/tests/cmdMZ.test b/tests/cmdMZ.test index fb2ca4a..61203c1 100644 --- a/tests/cmdMZ.test +++ b/tests/cmdMZ.test @@ -321,7 +321,7 @@ test cmdMZ-4.13 {Tcl_SplitObjCmd: basic split commands} { # The tests for Tcl_SubstObjCmd are in subst.test # The tests for Tcl_SwitchObjCmd are in switch.test -# todo: rewrite this if monotonic clock is provided resp. command "after" +# todo: rewrite this if monotonic clock is provided resp. command "after" # gets microsecond accuracy (RFE [fdfbd5e10] gets merged): proc _nrt_sleep {msec} { set usec [expr {$msec * 1000}] diff --git a/tests/env.test b/tests/env.test index 036c7a2..e4e209f 100644 --- a/tests/env.test +++ b/tests/env.test @@ -419,8 +419,8 @@ test env-8.0 { # cleanup -rename getenv {} -rename envrestore {} +rename getenv {} +rename envrestore {} rename envprep {} rename encodingrestore {} rename encodingswitch {} diff --git a/tests/history.test b/tests/history.test index b6a2755..813f84f 100644 --- a/tests/history.test +++ b/tests/history.test @@ -10,7 +10,7 @@ # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. - + if {"::tcltest" ni [namespace children]} { package require tcltest 2.5 namespace import -force ::tcltest::* diff --git a/tests/httpd b/tests/httpd index 4f5f600..3cf2170 100644 --- a/tests/httpd +++ b/tests/httpd @@ -214,7 +214,7 @@ proc httpdRespond { sock } { } # Catch errors from premature client closes - + catch { if {$data(proto) == "HEAD"} { puts $sock "HTTP/1.0 200 OK" diff --git a/tests/init.test b/tests/init.test index e8d484b..91df4a1 100644 --- a/tests/init.test +++ b/tests/init.test @@ -41,7 +41,7 @@ test init-1.2 {auto_qualify - absolute cmd - global} { } global test init-1.3 {auto_qualify - no colons cmd - global} { auto_qualify nocolons :: -} nocolons +} nocolons test init-1.4 {auto_qualify - no colons cmd - namespace} { auto_qualify nocolons ::sub } {::sub::nocolons nocolons} @@ -106,11 +106,11 @@ test init-2.5 {load safe:::setLogCmd - stage 2} { auto_reset catch {rename ::safe::setLogCmd {}} test init-2.6 {load setLogCmd from safe:: - stage 1} { - namespace eval safe setLogCmd + namespace eval safe setLogCmd rename ::safe::setLogCmd {} ;# should not fail } {} test init-2.7 {oad setLogCmd from safe:: - stage 2} { - namespace eval safe setLogCmd + namespace eval safe setLogCmd rename ::safe::setLogCmd {} ;# should not fail } {} test init-2.8 {load tcl::HistAdd} -setup { @@ -145,12 +145,12 @@ foreach arg [subst -nocommands -novariables { and is long enough to be truncated and " <- includes a false lead in the prune point search and must be longer still to force truncation} - {contrived example: rare circumstance + {contrived example: rare circumstance where the point at which to prune the error stack cannot be uniquely determined. foo bar foo "} - {contrived example: rare circumstance + {contrived example: rare circumstance where the point at which to prune the error stack cannot be uniquely determined. foo bar diff --git a/tests/internals.tcl b/tests/internals.tcl index 6b5bb87..e859afe 100644 --- a/tests/internals.tcl +++ b/tests/internals.tcl @@ -21,7 +21,7 @@ namespace path ::tcltest # Options: # -addmem - set additional memory limit (in bytes) as difference (extra memory needed to run a test) # -maxmem - set absolute maximum address space limit (in bytes) -# +# proc testWithLimit args { set body [lindex $args end] array set in [lrange $args 0 end-1] @@ -45,7 +45,7 @@ proc testWithLimit args { incr in(-addmem) 20000000 # + size of locale-archive (may be up to 100MB): incr in(-addmem) [expr { - [file exists /usr/lib/locale/locale-archive] ? + [file exists /usr/lib/locale/locale-archive] ? [file size /usr/lib/locale/locale-archive] : 0 }] } diff --git a/tests/iogt.test b/tests/iogt.test index 269a0ba..3cac2cf 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -5,7 +5,7 @@ # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. -# +# # Copyright (c) 2000 Ajuba Solutions. # Copyright (c) 2000 Andreas Kupries. # All rights reserved. diff --git a/tests/lindex.test b/tests/lindex.test index dadf275..0b8c327 100644 --- a/tests/lindex.test +++ b/tests/lindex.test @@ -441,7 +441,7 @@ test lindex-16.7 {data reuse} { test lindex-17.0 {Bug 1718580} {*}{ -body { lindex {} end foo - } + } -match glob -result {bad index "foo"*} -returnCodes 1 @@ -450,7 +450,7 @@ test lindex-17.0 {Bug 1718580} {*}{ test lindex-17.1 {Bug 1718580} {*}{ -body { lindex a end foo - } + } -match glob -result {bad index "foo"*} -returnCodes 1 diff --git a/tests/lrange.test b/tests/lrange.test index 4bce1b3..6765038 100644 --- a/tests/lrange.test +++ b/tests/lrange.test @@ -69,7 +69,7 @@ test lrange-1.15 {range of list elements} { } {"a b \{\ "} # emacs highlighting bug workaround --> " test lrange-1.16 {list element quoting} { - lrange {[append a .b]} 0 end + lrange {[append a .b]} 0 end } {{[append} a .b\]} test lrange-2.1 {error conditions} { diff --git a/tests/lrepeat.test b/tests/lrepeat.test index 61f2b62..f62f35f 100644 --- a/tests/lrepeat.test +++ b/tests/lrepeat.test @@ -40,7 +40,7 @@ test lrepeat-1.4 {error cases} { lrepeat -3 1 } -returnCodes 1 - -result {bad count "-3": must be integer >= 0} + -result {bad count "-3": must be integer >= 0} } test lrepeat-1.5 {Accept zero repetitions (TIP 323)} { -body { @@ -53,7 +53,7 @@ test lrepeat-1.6 {error cases} { lrepeat 3.5 1 } -returnCodes 1 - -result {expected integer but got "3.5"} + -result {expected integer but got "3.5"} } test lrepeat-1.7 {Accept zero repetitions (TIP 323)} { -body { diff --git a/tests/misc.test b/tests/misc.test index 8b6e1b7..8f8516e 100644 --- a/tests/misc.test +++ b/tests/misc.test @@ -25,7 +25,7 @@ testConstraint testhashsystemhash [llength [info commands testhashsystemhash]] test misc-1.1 {error in variable ref. in command in array reference} { proc tstProc {} { global a - + set tst $a([winfo name $zz]) # this is a bogus comment # this is a bogus comment @@ -42,7 +42,7 @@ test misc-1.1 {error in variable ref. in command in array reference} { test misc-1.2 {error in variable ref. in command in array reference} { proc tstProc {} " global a - + set tst \$a(\[winfo name \$\{zz) # this is a bogus comment # this is a bogus comment diff --git a/tests/nre.test b/tests/nre.test index e420b06..7cf06d1 100644 --- a/tests/nre.test +++ b/tests/nre.test @@ -29,9 +29,9 @@ if {[testConstraint testnrelevels]} { namespace path ::tcl::mathop # # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels, - # cmdFrame level, callFrame level, tosPtr and callback depth + # cmdFrame level, callFrame level, tosPtr and callback depth # - variable last [testnrelevels] + variable last [testnrelevels] proc depthDiff {} { variable last set depth [testnrelevels] @@ -329,7 +329,7 @@ test nre-8.1 {nre and {*}} -body { } -cleanup { rename inner {} rename outer {} -} -result {1 1 1} +} -result {1 1 1} test nre-8.2 {nre and {*}, [Bug 2415422]} -body { # force an expansion that grows the evaluation stack, check that nre # adapts the bcFramePtr. This causes an NRE assertion to fail if it is not diff --git a/tests/obj.test b/tests/obj.test index e5fec9a..e49a908 100644 --- a/tests/obj.test +++ b/tests/obj.test @@ -26,7 +26,7 @@ testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj { set r 1 foreach {t} { - {array search} + {array search} bytearray bytecode cmdName @@ -82,7 +82,7 @@ test obj-6.1 {Tcl_DuplicateObj, object has internal rep} testobj { set result "" lappend result [testobj freeallvars] lappend result [testintobj set 1 47] - lappend result [testobj duplicate 1 2] + lappend result [testobj duplicate 1 2] lappend result [testintobj get 2] lappend result [testobj refcount 1] lappend result [testobj refcount 2] @@ -91,7 +91,7 @@ test obj-6.2 {Tcl_DuplicateObj, "empty string" object} testobj { set result "" lappend result [testobj freeallvars] lappend result [testobj newobj 1] - lappend result [testobj duplicate 1 2] + lappend result [testobj duplicate 1 2] lappend result [testintobj get 2] lappend result [testobj refcount 1] lappend result [testobj refcount 2] diff --git a/tests/package.test b/tests/package.test index a147457..641ce49 100644 --- a/tests/package.test +++ b/tests/package.test @@ -613,13 +613,13 @@ test package-3.54 {Tcl_PkgRequire procedure, coroutine support} -setup { } -body { coroutine coro1 apply {{} { package ifneeded t 2.1 { - yield + yield package provide t 2.1 } package require t 2.1 }} list [catch {coro1} msg] $msg -} -match glob -result {0 2.1} +} -match glob -result {0 2.1} test package-4.1 {Tcl_PackageCmd procedure} -returnCodes error -body { diff --git a/tests/parseExpr.test b/tests/parseExpr.test index bb0920e..aded88a 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -770,11 +770,11 @@ test parseExpr-21.8 {error messages} -body { expr {0o8x} } -returnCodes error -match glob -result {*invalid octal number*} test parseExpr-21.9 {error messages} -body { - expr {"} + expr {"} } -returnCodes error -result {missing " in expression """} test parseExpr-21.10 {error messages} -body { - expr \{ + expr \{ } -returnCodes error -result "missing close-brace in expression \"\{\"" test parseExpr-21.11 {error messages} -body { diff --git a/tests/platform.test b/tests/platform.test index e40ff39..042469b 100644 --- a/tests/platform.test +++ b/tests/platform.test @@ -54,12 +54,12 @@ test platform-2.1 {tcl_platform(wordSize) indicates size of native word} { test platform-3.1 {CPU ID on Windows/UNIX} \ -constraints testCPUID \ - -body { + -body { set cpudata [testcpuid 0] binary format iii \ [lindex $cpudata 1] \ [lindex $cpudata 3] \ - [lindex $cpudata 2] + [lindex $cpudata 2] } \ -match regexp \ -result {^(?:AuthenticAMD|CentaurHauls|CyrixInstead|GenuineIntel)$} diff --git a/tests/regexp.test b/tests/regexp.test index 563a5ee..e29cecf 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -491,7 +491,7 @@ test regexp-11.12 {regsub without final variable name returns value} { } {a,bcd,c,ea,bcfd,cf,e} # This test crashes on the Mac unless you increase the Stack Space to about 1 -# Meg. This is probably bigger than most users want... +# Meg. This is probably bigger than most users want... # 8.2.3 regexp reduced stack space requirements, but this should be # tested again test regexp-12.1 {Tcl_RegExpExec: large number of subexpressions} {macCrash} { @@ -753,10 +753,10 @@ test regexp-19.2 {regsub null replacement} { test regexp-20.1 {regsub shared object shimmering} { # Bug #461322 - set a abcdefghijklmnopqurstuvwxyz - set b $a - set c abcdefghijklmnopqurstuvwxyz0123456789 - regsub $a $c $b d + set a abcdefghijklmnopqurstuvwxyz + set b $a + set c abcdefghijklmnopqurstuvwxyz0123456789 + regsub $a $c $b d list $d [string length $d] [string bytelength $d] } [list abcdefghijklmnopqurstuvwxyz0123456789 37 37] test regexp-20.2 {regsub shared object shimmering with -about} { diff --git a/tests/regexpComp.test b/tests/regexpComp.test index 2fd7f88..926d9ef 100644 --- a/tests/regexpComp.test +++ b/tests/regexpComp.test @@ -22,7 +22,7 @@ if {"::tcltest" ni [namespace children]} { proc evalInProc { script } { proc testProc {} $script set status [catch { - testProc + testProc } result] rename testProc {} return $result @@ -607,7 +607,7 @@ test regexpComp-11.8 {regsub errors, -start bad int check} { } {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}} # This test crashes on the Mac unless you increase the Stack Space to about 1 -# Meg. This is probably bigger than most users want... +# Meg. This is probably bigger than most users want... # 8.2.3 regexp reduced stack space requirements, but this should be # tested again test regexpComp-12.1 {Tcl_RegExpExec: large number of subexpressions} {macCrash} { @@ -794,10 +794,10 @@ test regexpComp-19.1 {regsub null replacement} { test regexpComp-20.1 {regsub shared object shimmering} { evalInProc { # Bug #461322 - set a abcdefghijklmnopqurstuvwxyz - set b $a - set c abcdefghijklmnopqurstuvwxyz0123456789 - regsub $a $c $b d + set a abcdefghijklmnopqurstuvwxyz + set b $a + set c abcdefghijklmnopqurstuvwxyz0123456789 + regsub $a $c $b d list $d [string length $d] [string bytelength $d] } } [list abcdefghijklmnopqurstuvwxyz0123456789 37 37] diff --git a/tests/split.test b/tests/split.test index 8e82367..efd4323 100644 --- a/tests/split.test +++ b/tests/split.test @@ -43,7 +43,7 @@ test split-1.8 {basic split commands} { foreach f [split {]\n} {}] { append x $f } - return $x + return $x } foo } {]\n} diff --git a/tests/stack.test b/tests/stack.test index 44417df..77cb69f 100644 --- a/tests/stack.test +++ b/tests/stack.test @@ -33,7 +33,7 @@ test stack-2.1 {maxNestingDepth reached on infinite recursion} -body { puts $msg } } -result {too many nested evaluations (infinite loop?)} - + # Make sure that there is enough stack to run regexp even if we're # close to the recursion limit. [Bug 947070] [Patch 746378] test stack-3.1 {enough room for regexp near recursion limit} -body { diff --git a/tests/tailcall.test b/tests/tailcall.test index c664455..3704333 100644 --- a/tests/tailcall.test +++ b/tests/tailcall.test @@ -28,9 +28,9 @@ if {[testConstraint testnrelevels]} { namespace eval testnre { # # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels, - # cmdFrame level, callFrame level, tosPtr and callback depth + # cmdFrame level, callFrame level, tosPtr and callback depth # - variable last [testnrelevels] + variable last [testnrelevels] proc depthDiff {} { variable last set depth [testnrelevels] @@ -148,7 +148,7 @@ test tailcall-0.5 {tailcall is constant space} -constraints testnrelevels -setup } -result {0 0 0 0 0 0} test tailcall-0.5.1 {tailcall is constant space} -constraints testnrelevels -setup { - # + # # This test is related to [bug d87cb182053fd79b3]: the fix to that bug was # to remove a call to TclSkipTailcall, which caused a violation of the # constant-space property of tailcall in that particular @@ -245,7 +245,7 @@ test tailcall-1 {tailcall} -body { } variable x *:: proc xset args {error ::xset} - list [::b::moo] | $x $a::x $b::x | $::b::y + list [::b::moo] | $x $a::x $b::x | $::b::y } -cleanup { unset x rename xset {} @@ -619,7 +619,7 @@ test tailcall-12.3a3 {[Bug 2695587]} -body { set x } -cleanup { unset x -} -result {0 1} +} -result {0 1} test tailcall-12.3b0 {[Bug 2695587]} -body { apply {{} { @@ -654,7 +654,7 @@ test tailcall-12.3b3 {[Bug 2695587]} -body { set x } -cleanup { unset x -} -result {0 1} +} -result {0 1} # MORE VARIANTS MISSING: bc'ed caught script vs (bc'ed, not-bc'ed) # catch. Actually superfluous now, as tailcall just returns TCL_RETURN so that diff --git a/tests/unixForkEvent.test b/tests/unixForkEvent.test index 4a0ac15..5299db3 100644 --- a/tests/unixForkEvent.test +++ b/tests/unixForkEvent.test @@ -37,7 +37,7 @@ test unixforkevent-1.1 {fork and test writeable event} \ viewFile result.txt $myFolder } \ -result {writable} \ - -cleanup { + -cleanup { catch { removeFolder $myFolder } } diff --git a/tests/unixNotfy.test b/tests/unixNotfy.test index df95c46..7d32555 100644 --- a/tests/unixNotfy.test +++ b/tests/unixNotfy.test @@ -34,7 +34,7 @@ test unixNotfy-1.1 {Tcl_DeleteFileHandler} -constraints {noTk unix unthreaded} - vwait x close $f list [catch {vwait x} msg] $msg -} -result {1 {can't wait for variable "x": would wait forever}} -cleanup { +} -result {1 {can't wait for variable "x": would wait forever}} -cleanup { catch { close $f } catch { removeFile foo } } @@ -90,7 +90,7 @@ test unixNotfy-2.2 {Tcl_DeleteFileHandler} \ set x } \ -result {ok} \ - -cleanup { + -cleanup { catch { close $f1 } catch { close $f2 } catch { removeFile foo } diff --git a/tests/upvar.test b/tests/upvar.test index 10e0e9f..9e44a79 100644 --- a/tests/upvar.test +++ b/tests/upvar.test @@ -492,7 +492,7 @@ test upvar-NS-1.4 {nsupvar links to correct variable} -body { } -returnCodes error -cleanup { namespace delete test_ns_1 } -result {namespace "test_ns_0" not found in "::test_ns_1"} - + test upvar-NS-1.5 {nsupvar links to correct variable} -body { namespace eval test_ns_1 { namespace eval test_ns_0 {} diff --git a/tests/winPipe.test b/tests/winPipe.test index d3a580c..ce786db 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -39,7 +39,7 @@ testConstraint slowTest 0 set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n append big $big -append big $big +append big $big append big $big append big $big append big $big -- cgit v0.12 From 999decddb383b6dbe467570cb9e3997a48286fa2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 16 Feb 2021 11:11:23 +0000 Subject: Fix [22324bcbd]: string reverse is broken for Emoji. Thanks to Chrisian Werner for bug report and POC patch. --- generic/tclStringObj.c | 44 +++++++++++++++++++++++++++++++++++++++++--- tests/string.test | 8 ++++---- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 33b2139..bdc9c99 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2899,6 +2899,9 @@ TclStringReverse( { String *stringPtr; Tcl_UniChar ch = 0; +#if TCL_UTF_MAX <= 4 + int needFlip = 0; +#endif if (TclIsPureByteArray(objPtr)) { int numBytes; @@ -2917,10 +2920,9 @@ TclStringReverse( if (stringPtr->hasUnicode) { Tcl_UniChar *from = Tcl_GetUnicode(objPtr); Tcl_UniChar *src = from + stringPtr->numChars; + Tcl_UniChar *to; if (Tcl_IsShared(objPtr)) { - Tcl_UniChar *to; - /* * Create a non-empty, pure unicode value, so we can coax * Tcl_SetObjLength into growing the unicode rep buffer. @@ -2930,19 +2932,54 @@ TclStringReverse( Tcl_SetObjLength(objPtr, stringPtr->numChars); to = Tcl_GetUnicode(objPtr); while (--src >= from) { +#if TCL_UTF_MAX <= 4 + ch = *src; + if ((ch & 0xF800) == 0xD800) { + needFlip = 1; + } + *to++ = ch; +#else *to++ = *src; +#endif } } else { /* * Reversing in place. */ +#if TCL_UTF_MAX <= 4 + to = src; +#endif while (--src > from) { ch = *src; +#if TCL_UTF_MAX <= 4 + if ((ch & 0xF800) == 0xD800) { + needFlip = 1; + } +#endif *src = *from; *from++ = ch; } } +#if TCL_UTF_MAX <= 4 + if (needFlip) { + /* + * Flip back surrogate pairs. + */ + + from = to - stringPtr->numChars; + while (--to >= from) { + ch = *to; + if ((ch & 0xFC00) == 0xD800) { + if ((to-1 >= from) && ((to[-1] & 0xFC00) == 0xDC00)) { + to[0] = to[-1]; + to[-1] = ch; + --to; + } + } + } + } +#endif } if (objPtr->bytes) { @@ -2968,6 +3005,7 @@ TclStringReverse( int charCount = 0; int bytesLeft = numBytes; + int chw; while (bytesLeft) { /* @@ -2976,7 +3014,7 @@ TclStringReverse( * skip calling Tcl_UtfCharComplete() here. */ - int bytesInChar = TclUtfToUniChar(from, &ch); + int bytesInChar = TclUtfToUCS4(from, &chw); ReverseBytes((unsigned char *)to, (unsigned char *)from, bytesInChar); diff --git a/tests/string.test b/tests/string.test index 3ac3060..66eb6ad 100644 --- a/tests/string.test +++ b/tests/string.test @@ -1828,19 +1828,19 @@ test string-24.15 {string reverse command - pure bytearray} { binary scan [tcl::string::reverse [binary format H* 010203]] H* x set x } 030201 -test string-24.16 {string reverse command - surrogates} knownBug { +test string-24.16 {string reverse command - surrogates} { string reverse \u0444bulb\uD83D\uDE02 } \uD83D\uDE02blub\u0444 -test string-24.17 {string reverse command - surrogates} knownBug { +test string-24.17 {string reverse command - surrogates} { string reverse \uD83D\uDE02hello\uD83D\uDE02 } \uD83D\uDE02olleh\uD83D\uDE02 -test string-24.18 {string reverse command - surrogates} knownBug { +test string-24.18 {string reverse command - surrogates} { set s \u0444bulb\uD83D\uDE02 # shim shimmery ... string index $s 0 string reverse $s } \uD83D\uDE02blub\u0444 -test string-24.19 {string reverse command - surrogates} knownBug { +test string-24.19 {string reverse command - surrogates} { set s \uD83D\uDE02hello\uD83D\uDE02 # shim shimmery ... string index $s 0 -- cgit v0.12 From 5fd34b88068d8c84b8d32ebd8cde63e0bfcdde70 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 16 Feb 2021 12:07:42 +0000 Subject: Fix bug in previous commit: Don't update stringPtr->numChars when doing a "string reverse", because TclUtfToUCS4() doesn't count surrogate pairs as 2 --- generic/tclStringObj.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index bdc9c99..0e1acf0 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -3003,7 +3003,6 @@ TclStringReverse( * Pass 1. Reverse the bytes of each multi-byte character. */ - int charCount = 0; int bytesLeft = numBytes; int chw; @@ -3021,11 +3020,9 @@ TclStringReverse( to += bytesInChar; from += bytesInChar; bytesLeft -= bytesInChar; - charCount++; } from = to = objPtr->bytes; - stringPtr->numChars = charCount; } /* Pass 2. Reverse all the bytes. */ ReverseBytes((unsigned char *)to, (unsigned char *)from, numBytes); -- cgit v0.12 From 0b9b440ce054242497aea45b976231329374c770 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 16 Feb 2021 13:59:08 +0000 Subject: Attempt to produce double-arch (x86_64 and arm) binary for MacOS --- .github/workflows/onefiledist.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/onefiledist.yml b/.github/workflows/onefiledist.yml index df98bec..3715555 100644 --- a/.github/workflows/onefiledist.yml +++ b/.github/workflows/onefiledist.yml @@ -60,6 +60,7 @@ jobs: sudo chmod a+x /usr/local/bin/macher echo "VER_PATH=$(cd tools; pwd)/addVerToFile.tcl" >> $GITHUB_ENV echo "CREATE_DMG=$(cd create-dmg;pwd)/create-dmg" >> $GITHUB_ENV + echo "CFLAGS=-arch x86_64 -arch arm64e" >> $GITHUB_ENV - name: Configure run: ./configure --disable-symbols --disable-shared --enable-zipfs working-directory: unix -- cgit v0.12 From 499e962572ad76700414e1c910b330ac52578cf8 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Feb 2021 08:32:53 +0000 Subject: Don't try to use ln when creating libtcl.vfs on windows: It doesn't work for encodings or msg-files (anything on a deeper level) when zipping (at least not on cygwin) --- win/Makefile.in | 9 --------- 1 file changed, 9 deletions(-) diff --git a/win/Makefile.in b/win/Makefile.in index cdaeec4..3a8e0a9 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -524,15 +524,6 @@ ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} ${DDE_DLL_FILE} ${REG_DLL_FILE} @mkdir -p ${TCL_VFS_PATH} @echo "creating ${TCL_VFS_PATH} (prepare compression)" @( \ - $(LN) $$(find $(TOP_DIR)/library/* -maxdepth 0 -type f) ${TCL_VFS_PATH}/ && \ - (for D in $$(find $(TOP_DIR)/library/* -maxdepth 0 -type d); do \ - mkdir -p "${TCL_VFS_PATH}/$$(basename $$D)"; \ - $(LN) -s $$D/* ${TCL_VFS_PATH}/$$(basename $$D)/; \ - done) && \ - $(LN) ${TCL_VFS_PATH}/manifest.txt ${TCL_VFS_PATH}/pkgIndex.tcl && \ - $(LN) ${DDE_DLL_FILE} ${TCL_VFS_PATH}/dde/ && \ - $(LN) ${REG_DLL_FILE} ${TCL_VFS_PATH}/registry/ \ - ) || ( \ $(COPY) -a $(TOP_DIR)/library/* ${TCL_VFS_PATH}; \ $(COPY) -a ${TCL_VFS_PATH}/manifest.txt ${TCL_VFS_PATH}/pkgIndex.tcl; \ $(COPY) ${DDE_DLL_FILE} ${TCL_VFS_PATH}/dde; \ -- cgit v0.12 From b3d34ad31717286dabbaa72b93d7ff5f3e0626a6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Feb 2021 08:35:44 +0000 Subject: Another TIP #430 fix for cygwin: libtcl8.7.dll is installed in /usr/bin, not in /usr/lib as on other platforms --- generic/tclZipfs.c | 15 ++++++--------- unix/Makefile.in | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 0d646aa..f052c2e 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3157,18 +3157,15 @@ TclZipfs_TclLibrary(void) return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } #else -# if defined(CFG_RUNTIME_LIBDIR) if (ZipfsAppHookFindTclInit( - CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } -# endif -# if defined(CFG_RUNTIME_BINDIR) - if (ZipfsAppHookFindTclInit( - CFG_RUNTIME_BINDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { +#ifdef __CYGWIN__ + CFG_RUNTIME_BINDIR +#else + CFG_RUNTIME_LIBDIR +#endif + "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } -# endif #endif /* _WIN32 */ #endif /* !defined(STATIC_BUILD) */ diff --git a/unix/Makefile.in b/unix/Makefile.in index 32b99a2..9c64d05 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1523,7 +1523,7 @@ tclZipfs.o: $(GENERIC_DIR)/tclZipfs.c $(CC) -c $(CC_SWITCHES) \ -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ -DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \ - -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY)\"" \ + -DCFG_RUNTIME_BINDIR="\"$(bindir)\"" \ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip \ $(GENERIC_DIR)/tclZipfs.c -- cgit v0.12 From 6ee6cd1ae4ffb8a3fe3e602632cd3f0683c392d1 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Feb 2021 08:50:17 +0000 Subject: Fix "make dist" on UNIX, broken due to TIP #590 --- unix/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 9c64d05..e8b5110 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -2218,7 +2218,7 @@ DISTROOT = /tmp/dist DISTNAME = tcl${VERSION}${PATCH_LEVEL} ZIPNAME = tcl${MAJOR_VERSION}${MINOR_VERSION}${PATCH_LEVEL}-src.zip DISTDIR = $(DISTROOT)/$(DISTNAME) -BUILTIN_PACKAGE_LIST = cookiejar http opt msgcat reg dde tcltest platform +BUILTIN_PACKAGE_LIST = cookiejar http opt msgcat registry dde tcltest platform $(UNIX_DIR)/configure: $(UNIX_DIR)/configure.ac $(UNIX_DIR)/tcl.m4 \ $(UNIX_DIR)/aclocal.m4 -- cgit v0.12 From 467337387f361bbb38bc6e50b6d3a5432399ef68 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Feb 2021 09:41:46 +0000 Subject: Don't pack tcl_library/registry/pkgIndex in zip-file on UNIX --- unix/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index e8b5110..15d80cb 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -778,7 +778,7 @@ ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} cp -a $(TOP_DIR)/library/* ${TCL_VFS_PATH}; \ fi mv ${TCL_VFS_PATH}/manifest.txt ${TCL_VFS_PATH}/pkgIndex.tcl - rm -rf ${TCL_VFS_PATH}/dde ${TCL_VFS_PATH}/reg + rm -rf ${TCL_VFS_PATH}/dde ${TCL_VFS_PATH}/registry @find ${TCL_VFS_ROOT} -type d -empty -delete @echo "creating ${TCL_ZIP_FILE} from ${TCL_VFS_PATH}" @(zip=`(realpath '${NATIVE_ZIP}' || readlink -m '${NATIVE_ZIP}' || \ -- cgit v0.12 From 39a8b9813a755db4534124f7cd28212544ed4203 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Feb 2021 13:07:18 +0000 Subject: Multi-arch only works on MacOS-11 --- .github/workflows/onefiledist.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/onefiledist.yml b/.github/workflows/onefiledist.yml index 3715555..a60428d 100644 --- a/.github/workflows/onefiledist.yml +++ b/.github/workflows/onefiledist.yml @@ -38,7 +38,7 @@ jobs: path: 1dist/*.tar macos: name: macOS - runs-on: macos-latest + runs-on: macos-11.0 defaults: run: shell: bash -- cgit v0.12 From 6067ce5573215928878a619b512a6cf06ab4690e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Feb 2021 15:44:24 +0000 Subject: Fix compiler warning on non-intel CPU's --- unix/tclUnixCompat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/unix/tclUnixCompat.c b/unix/tclUnixCompat.c index 74b4bf3..9e43c01 100644 --- a/unix/tclUnixCompat.c +++ b/unix/tclUnixCompat.c @@ -1009,6 +1009,9 @@ TclWinCPUID( : "a"(index)); #endif status = TCL_OK; +#else + (void)index; + (void)regsPtr; #endif return status; } -- cgit v0.12 From 28d58d74b0e3837b5ca9c2020bd14cf21ee98a41 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Feb 2021 16:16:19 +0000 Subject: Fix abs(-9223372036854775808) special-case on platforms where sizeof(Tcl_WideInt) > sizeof(int64_t). Theoretical, yes, but at least add a testcase for this (expr-38.14) --- generic/tclBasic.c | 11 ++++++++++- tests/expr.test | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 2ed4270..b2d3f28 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -7906,7 +7906,16 @@ ExprAbsFunc( } goto unChanged; } else if (l == WIDE_MIN) { - if (mp_init_i64(&big, l) != MP_OKAY) { + if (sizeof(Tcl_WideInt) > sizeof(int64_t)) { + Tcl_WideUInt ul = -(Tcl_WideUInt)WIDE_MIN; + if (mp_init(&big) != MP_OKAY || mp_unpack(&big, 1, 1, + sizeof(Tcl_WideInt), 0, 0, &ul) != MP_OKAY) { + return TCL_ERROR; + } + if (mp_neg(&big, &big) != MP_OKAY) { + return TCL_ERROR; + } + } else if (mp_init_i64(&big, l) != MP_OKAY) { return TCL_ERROR; } goto tooLarge; diff --git a/tests/expr.test b/tests/expr.test index 9add1f1..5435a18 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -6699,6 +6699,9 @@ test expr-38.12 {abs and -0x0 [Bug 2954959]} { test expr-38.13 {abs and 0.0 [Bug 2954959]} { ::tcl::mathfunc::abs 1e-324 } 1e-324 +test expr-38.14 {abs and WIDE_MIN special-case} { + ::tcl::mathfunc::abs -9223372036854775808 +} 9223372036854775808 testConstraint testexprlongobj [llength [info commands testexprlongobj]] testConstraint testexprdoubleobj [llength [info commands testexprdoubleobj]] -- cgit v0.12 From 042e9a4f8ae09cf75efccd7697c9b1a53f83e70a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Feb 2021 18:48:47 +0000 Subject: Backport 3 additional test-cases from 8.6 for TCL_UTF_MAX>3 --- tests/utf.test | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/utf.test b/tests/utf.test index c61082f..e65f352 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -783,9 +783,12 @@ test utf-7.18.2 {Tcl_UtfPrev} {testutfprev testbytestring} { test utf-7.19 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A[testbytestring \xF8\xA0\xA0\xA0] } 4 -test utf-7.20 {Tcl_UtfPrev} {testutfprev testbytestring ucs2} { +test utf-7.20.0 {Tcl_UtfPrev} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF2\xA0\xA0\xA0] } 4 +test utf-7.20.1 {Tcl_UtfPrev} {testutfprev testbytestring fullutf} { + testutfprev A[testbytestring \xF2\xA0\xA0\xA0] +} 1 test utf-7.21 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A\u8820[testbytestring \xA0] } 4 @@ -846,9 +849,12 @@ test utf-7.37 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring} { test utf-7.38 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring} { testutfprev A[testbytestring \xE0\xA0\x80] 2 } 1 -test utf-7.39 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring ucs2} { +test utf-7.39.0 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF0\x90\x80\x80] } 4 +test utf-7.39.1 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring fullutf} { + testutfprev A[testbytestring \xF0\x90\x80\x80] +} 1 test utf-7.40.0 {Tcl_UtfPrev -- overlong sequence} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF0\x90\x80\x80] 4 } 3 @@ -888,19 +894,22 @@ test utf-7.47.2 {Tcl_UtfPrev, pointing to 3th byte of 3-byte invalid sequence} { test utf-7.48.0 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] } 4 -test utf-7.48.1 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { +test utf-7.48.1 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { + testutfprev A[testbytestring \xF4\x8F\xBF\xBF] +} 1 +test utf-7.48.2 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 4 } 3 -test utf-7.48.2 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { +test utf-7.48.3 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 4 } 1 -test utf-7.48.3 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { +test utf-7.48.4 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring ucs2} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 3 } 2 -test utf-7.48.4 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { +test utf-7.48.5 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring fullutf} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 3 } 1 -test utf-7.48.5 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring} { +test utf-7.48.6 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring} { testutfprev A[testbytestring \xF4\x8F\xBF\xBF] 2 } 1 test utf-7.49.0 {Tcl_UtfPrev, validity check [493dccc2de]} {testutfprev testbytestring} { -- cgit v0.12 From f2c4a32d7fbff5e3b59d4d1594a55ea3dbf52837 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Feb 2021 07:55:08 +0000 Subject: Performance optimization in TzsetIfNecessary() function. Cherry-picked from sebres-8-6-clock-speedup-cr2 branch --- generic/tclClock.c | 19 ++++++++++++++++++- generic/tclEnv.c | 9 +++++++++ generic/tclInt.h | 7 +++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 37883bb..2c5173a 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -2029,10 +2029,27 @@ ClockSecondsObjCmd( static void TzsetIfNecessary(void) { - static char* tzWas = (char*)INT2PTR(-1); /* Previous value of TZ, protected by + static char *tzWas = (char *)INT2PTR(-1); /* Previous value of TZ, protected by * clockMutex. */ + static long tzLastRefresh = 0; /* Used for latency before next refresh */ + static size_t tzEnvEpoch = 0; /* Last env epoch, for faster signaling, + that TZ changed via TCL */ const char *tzIsNow; /* Current value of TZ */ + /* + * Prevent performance regression on some platforms by resolving of system time zone: + * small latency for check whether environment was changed (once per second) + * no latency if environment was changed with tcl-env (compare both epoch values) + */ + Tcl_Time now; + Tcl_GetTime(&now); + if (now.sec == tzLastRefresh && tzEnvEpoch == TclEnvEpoch) { + return; + } + + tzEnvEpoch = TclEnvEpoch; + tzLastRefresh = now.sec; + Tcl_MutexLock(&clockMutex); tzIsNow = getenv("TZ"); if (tzIsNow != NULL && (tzWas == NULL || tzWas == (char*)INT2PTR(-1) diff --git a/generic/tclEnv.c b/generic/tclEnv.c index 15dd8b5..e4246a1 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -36,6 +36,11 @@ TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */ # define techar char #endif + +/* MODULE_SCOPE */ +size_t TclEnvEpoch = 0; /* Epoch of the tcl environment + * (if changed with tcl-env). */ + static struct { int cacheSize; /* Number of env strings in cache. */ char **cache; /* Array containing all of the environment @@ -417,6 +422,7 @@ Tcl_PutEnv( value[0] = '\0'; TclSetEnv(name, value+1); } + TclEnvEpoch++; Tcl_DStringFree(&nameString); return 0; @@ -625,6 +631,7 @@ EnvTraceProc( if (flags & TCL_TRACE_ARRAY) { TclSetupEnv(interp); + TclEnvEpoch++; return NULL; } @@ -645,6 +652,7 @@ EnvTraceProc( value = Tcl_GetVar2(interp, "env", name2, TCL_GLOBAL_ONLY); TclSetEnv(name2, value); + TclEnvEpoch++; } /* @@ -668,6 +676,7 @@ EnvTraceProc( if (flags & TCL_TRACE_UNSETS) { TclUnsetEnv(name2); + TclEnvEpoch++; } return NULL; } diff --git a/generic/tclInt.h b/generic/tclInt.h index df29da8..5da21b0 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4977,6 +4977,13 @@ typedef struct NRE_callback { #define Tcl_Free(ptr) TclpFree(ptr) #endif +/* + * Other externals. + */ + +MODULE_SCOPE size_t TclEnvEpoch; /* Epoch of the tcl environment + * (if changed with tcl-env). */ + #endif /* _TCLINT */ /* -- cgit v0.12 From 957890bf54197a9221fb3c3e65ef4cbc07490352 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Feb 2021 08:32:28 +0000 Subject: Two new testcases for abs() --- tests/expr.test | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/expr.test b/tests/expr.test index b81c4a7..4fa6821 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -138,7 +138,7 @@ proc do_twelve_days {} { unset xxx return $result } - + # start of tests catch {unset a b i x} @@ -6722,6 +6722,12 @@ test expr-38.12 {abs and -0x0 [Bug 2954959]} { test expr-38.13 {abs and 0.0 [Bug 2954959]} { ::tcl::mathfunc::abs 1e-324 } 1e-324 +test expr-38.14 {abs and INT64_MIN special-case} { + ::tcl::mathfunc::abs -9223372036854775808 +} 9223372036854775808 +test expr-38.15 {abs and INT128_MIN special-case} { + ::tcl::mathfunc::abs -170141183460469231731687303715884105728 +} 170141183460469231731687303715884105728 testConstraint testexprlongobj [llength [info commands testexprlongobj]] testConstraint testexprdoubleobj [llength [info commands testexprdoubleobj]] -- cgit v0.12 From 0d15664cbdafeb59a53986a6e646b79f7e5124da Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Feb 2021 11:31:11 +0000 Subject: Change (internal) signatures for TclpGetClicks/TclpGetSeconds to use "unsigned long long" in stead of Tcl_WideUInt as return value. --- generic/tclClock.c | 4 ++-- generic/tclInt.decls | 4 ++-- generic/tclIntDecls.h | 8 ++++---- unix/tclUnixTime.c | 16 ++++++++-------- win/tclWinTime.c | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index f05a7a1..8cb1b40 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -1762,13 +1762,13 @@ ClockClicksObjCmd( switch (index) { case CLICKS_MILLIS: Tcl_GetTime(&now); - clicks = (Tcl_WideInt) now.sec * 1000 + now.usec / 1000; + clicks = (Tcl_WideInt)(unsigned long)now.sec * 1000 + now.usec / 1000; break; case CLICKS_NATIVE: #ifdef TCL_WIDE_CLICKS clicks = TclpGetWideClicks(); #else - clicks = (Tcl_WideInt) TclpGetClicks(); + clicks = (Tcl_WideInt)TclpGetClicks(); #endif break; case CLICKS_MICROS: diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 42e6899..3fbc571 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -151,10 +151,10 @@ declare 74 { void TclpFree(void *ptr) } declare 75 { - Tcl_WideUInt TclpGetClicks(void) + unsigned long long TclpGetClicks(void) } declare 76 { - Tcl_WideUInt TclpGetSeconds(void) + unsigned long long TclpGetSeconds(void) } declare 81 { void *TclpRealloc(void *ptr, size_t size) diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index 2969f27..23cf3e6 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -186,9 +186,9 @@ EXTERN void * TclpAlloc(size_t size); /* 74 */ EXTERN void TclpFree(void *ptr); /* 75 */ -EXTERN Tcl_WideUInt TclpGetClicks(void); +EXTERN unsigned long long TclpGetClicks(void); /* 76 */ -EXTERN Tcl_WideUInt TclpGetSeconds(void); +EXTERN unsigned long long TclpGetSeconds(void); /* Slot 77 is reserved */ /* Slot 78 is reserved */ /* Slot 79 is reserved */ @@ -663,8 +663,8 @@ typedef struct TclIntStubs { void (*reserved72)(void); void (*reserved73)(void); void (*tclpFree) (void *ptr); /* 74 */ - Tcl_WideUInt (*tclpGetClicks) (void); /* 75 */ - Tcl_WideUInt (*tclpGetSeconds) (void); /* 76 */ + unsigned long long (*tclpGetClicks) (void); /* 75 */ + unsigned long long (*tclpGetSeconds) (void); /* 76 */ void (*reserved77)(void); void (*reserved78)(void); void (*reserved79)(void); diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index dc48a32..990503d 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -49,10 +49,10 @@ void *tclTimeClientData = NULL; *---------------------------------------------------------------------- */ -Tcl_WideUInt +unsigned long long TclpGetSeconds(void) { - return time(NULL); + return (unsigned long long)time(NULL); } /* @@ -78,7 +78,7 @@ TclpGetMicroseconds(void) Tcl_Time time; tclGetTimeProcPtr(&time, tclTimeClientData); - return ((long long)time.sec)*1000000 + time.usec; + return ((long long)(unsigned long)time.sec)*1000000 + time.usec; } /* @@ -100,30 +100,30 @@ TclpGetMicroseconds(void) *---------------------------------------------------------------------- */ -Tcl_WideUInt +unsigned long long TclpGetClicks(void) { - Tcl_WideUInt now; + unsigned long long now; #ifdef NO_GETTOD if (tclGetTimeProcPtr != NativeGetTime) { Tcl_Time time; tclGetTimeProcPtr(&time, tclTimeClientData); - now = (Tcl_WideUInt)time.sec*1000000 + time.usec; + now = (unsigned long long)(unsigned long)time.sec*1000000 + time.usec; } else { /* * A semi-NativeGetTime, specialized to clicks. */ struct tms dummy; - now = (Tcl_WideUInt) times(&dummy); + now = (unsigned long long)times(&dummy); } #else Tcl_Time time; tclGetTimeProcPtr(&time, tclTimeClientData); - now = (Tcl_WideUInt)time.sec*1000000 + time.usec; + now = (unsigned long long)time.sec*1000000 + time.usec; #endif return now; diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 3c52451..0bd5b7e 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -144,7 +144,7 @@ ClientData tclTimeClientData = NULL; *---------------------------------------------------------------------- */ -Tcl_WideUInt +unsigned long long TclpGetSeconds(void) { long long usecSincePosixEpoch; @@ -158,7 +158,7 @@ TclpGetSeconds(void) Tcl_Time t; tclGetTimeProcPtr(&t, tclTimeClientData); /* Tcl_GetTime inlined. */ - return t.sec; + return (unsigned long long)(unsigned long)t.sec; } } @@ -181,7 +181,7 @@ TclpGetSeconds(void) *---------------------------------------------------------------------- */ -Tcl_WideUInt +unsigned long long TclpGetClicks(void) { long long usecSincePosixEpoch; @@ -200,7 +200,7 @@ TclpGetClicks(void) Tcl_Time now; /* Current Tcl time */ tclGetTimeProcPtr(&now, tclTimeClientData); /* Tcl_GetTime inlined */ - return (Tcl_WideUInt)(now.sec * 1000000) + now.usec; + return ((unsigned long long)(unsigned long)now.sec * 1000000ULL) + now.usec; } } -- cgit v0.12 From 345894cae91f9e72bbbfd6264ab98a2263d9dd1b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Feb 2021 12:01:44 +0000 Subject: Protect "interp limit" command better for allowed range in -millis and -seconds values --- generic/tclInterp.c | 22 +++++++++++----------- tests/interp.test | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/generic/tclInterp.c b/generic/tclInterp.c index a263a66..d63add2 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -4785,7 +4785,7 @@ ChildTimeLimitCmd( Tcl_Obj *milliObj = NULL, *secObj = NULL; int gran = 0; Tcl_Time limitMoment; - int tmp; + Tcl_WideInt tmp; Tcl_LimitGetTime(childInterp, &limitMoment); for (i=consumedObjc ; i LONG_MAX) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "milliseconds must be between 0 and %ld", LONG_MAX)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADVALUE", NULL); return TCL_ERROR; } - limitMoment.usec = ((long) tmp)*1000; + limitMoment.usec = ((long)tmp)*1000; break; case OPT_SEC: secObj = objv[i+1]; @@ -4835,17 +4835,17 @@ ChildTimeLimitCmd( if (secLen == 0) { break; } - if (TclGetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) { + if (TclGetWideIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) { return TCL_ERROR; } - if (tmp < 0) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "seconds must be at least 0", -1)); + if (tmp < 0 || tmp > LONG_MAX) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "seconds must be between 0 and %ld", LONG_MAX)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADVALUE", NULL); return TCL_ERROR; } - limitMoment.sec = tmp; + limitMoment.sec = (long)tmp; break; } } diff --git a/tests/interp.test b/tests/interp.test index c19755f..385d3e2 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -3524,7 +3524,7 @@ test interp-35.19 {interp limit syntax} -body { interp limit $i time -seconds -1 } -cleanup { interp delete $i -} -returnCodes error -result {seconds must be at least 0} +} -match glob -returnCodes error -result {seconds must be between 0 and *} test interp-35.20 {interp limit syntax} -body { set i [interp create] interp limit $i time -millis foobar @@ -3536,7 +3536,7 @@ test interp-35.21 {interp limit syntax} -body { interp limit $i time -millis -1 } -cleanup { interp delete $i -} -returnCodes error -result {milliseconds must be at least 0} +} -match glob -returnCodes error -result {milliseconds must be between 0 and *} test interp-35.22 {interp time limits normalize milliseconds} -body { set i [interp create] interp limit $i time -seconds 1 -millis 1500 -- cgit v0.12 From bdd6e3f4dfea4d7d47d323b51a660c7c7517a531 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 19 Feb 2021 07:18:13 +0000 Subject: Fix [7c64aa5e1a]: Another uninitialized-variable bug in BRE-mode parsing. Thanks to Tom Lane for the bug-report and the fix. --- generic/regc_lex.c | 2 +- tests/reg.test | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/generic/regc_lex.c b/generic/regc_lex.c index 1c60427..0cc62a2 100644 --- a/generic/regc_lex.c +++ b/generic/regc_lex.c @@ -427,7 +427,7 @@ next( if (INCON(L_BBND) && NEXT1('}')) { v->now++; INTOCON(L_BRE); - RET('}'); + RETV('}', 1); } else { FAILW(REG_BADBR); } diff --git a/tests/reg.test b/tests/reg.test index 6cd2eb3..56444ba 100644 --- a/tests/reg.test +++ b/tests/reg.test @@ -1120,6 +1120,10 @@ test reg-33.29 {} { test reg-33.30 {Bug 1080042} { regexp {(\Y)+} foo } 1 +test reg-33.31 {Bug 7c64aa5e1a} { + regexp -inline {(?b).\{1,10\}} {abcdef} +} abcdef + # cleanup -- cgit v0.12 From 8242d1a544d685846fe49557be8c9fd628d42329 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 23 Feb 2021 07:23:29 +0000 Subject: Use _wgetenv() in stead of getenv() on Windows: The wide environment is not always well-synchonized with the locale environment. Problem detected on the sebres-8-6-clock-speedup-cr2, but this branch only exposed the bug, it did not cause it. --- generic/tclBasic.c | 4 ++++ generic/tclClock.c | 44 +++++++++++++++++++++++++++++++++++--------- generic/tclIOUtil.c | 11 +++++++++-- library/clock.tcl | 3 +-- 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 895d160..2f1819f 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -583,6 +583,10 @@ Tcl_CreateInterp(void) Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS); iPtr->packageUnknown = NULL; +#ifdef _WIN32 +# define getenv(x) _wgetenv(L##x) /* On Windows, use _wgetenv below */ +#endif + /* TIP #268 */ if (getenv("TCL_PKG_PREFER_LATEST") == NULL) { iPtr->packagePrefer = PKG_PREFER_STABLE; diff --git a/generic/tclClock.c b/generic/tclClock.c index 2c5173a..ca1df44 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -1650,20 +1650,37 @@ ClockGetenvObjCmd( int objc, Tcl_Obj *const objv[]) { +#ifdef _WIN32 + const WCHAR *varName; + const WCHAR *varValue; + Tcl_DString ds; +#else const char *varName; const char *varValue; +#endif (void)clientData; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "name"); return TCL_ERROR; } +#ifdef _WIN32 + varName = (const WCHAR *)Tcl_WinUtfToTChar(TclGetString(objv[1]), -1, &ds); + varValue = _wgetenv(varName); + Tcl_DStringFree(&ds); + if (varValue == NULL) { + varValue = L""; + } + Tcl_WinTCharToUtf((TCHAR *)varValue, -1, &ds); + Tcl_DStringResult(interp, &ds); +#else varName = TclGetString(objv[1]); varValue = getenv(varName); if (varValue == NULL) { varValue = ""; } Tcl_SetObjResult(interp, Tcl_NewStringObj(varValue, -1)); +#endif return TCL_OK; } @@ -2026,15 +2043,24 @@ ClockSecondsObjCmd( *---------------------------------------------------------------------- */ +#ifdef _WIN32 +#define getenv(x) _wgetenv(L##x) +#else +#define WCHAR char +#define wcslen strlen +#define wcscmp strcmp +#define wcscpy strcpy +#endif + static void TzsetIfNecessary(void) { - static char *tzWas = (char *)INT2PTR(-1); /* Previous value of TZ, protected by - * clockMutex. */ + static WCHAR* tzWas = (WCHAR *)INT2PTR(-1); /* Previous value of TZ, protected by + * clockMutex. */ static long tzLastRefresh = 0; /* Used for latency before next refresh */ static size_t tzEnvEpoch = 0; /* Last env epoch, for faster signaling, that TZ changed via TCL */ - const char *tzIsNow; /* Current value of TZ */ + const WCHAR *tzIsNow; /* Current value of TZ */ /* * Prevent performance regression on some platforms by resolving of system time zone: @@ -2052,17 +2078,17 @@ TzsetIfNecessary(void) Tcl_MutexLock(&clockMutex); tzIsNow = getenv("TZ"); - if (tzIsNow != NULL && (tzWas == NULL || tzWas == (char*)INT2PTR(-1) - || strcmp(tzIsNow, tzWas) != 0)) { + if (tzIsNow != NULL && (tzWas == NULL || tzWas == (WCHAR *)INT2PTR(-1) + || wcscmp(tzIsNow, tzWas) != 0)) { tzset(); - if (tzWas != NULL && tzWas != (char*)INT2PTR(-1)) { + if (tzWas != NULL && tzWas != (WCHAR *)INT2PTR(-1)) { ckfree(tzWas); } - tzWas = (char *)ckalloc(strlen(tzIsNow) + 1); - strcpy(tzWas, tzIsNow); + tzWas = (WCHAR *)ckalloc(sizeof(WCHAR) * (wcslen(tzIsNow) + 1)); + wcscpy(tzWas, tzIsNow); } else if (tzIsNow == NULL && tzWas != NULL) { tzset(); - if (tzWas != (char*)INT2PTR(-1)) ckfree(tzWas); + if (tzWas != (WCHAR *)INT2PTR(-1)) ckfree(tzWas); tzWas = NULL; } Tcl_MutexUnlock(&clockMutex); diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 5566f3e..312fd08 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -3158,6 +3158,13 @@ Tcl_FSLoadFile( * present and set to true (any integer > 0) then the unlink is skipped. */ +#ifdef _WIN32 +#define getenv(x) _wgetenv(L##x) +#define atoi(x) _wtoi(x) +#else +#define WCHAR char +#endif + static int skipUnlink (Tcl_Obj* shlibFile) { @@ -3178,9 +3185,9 @@ skipUnlink (Tcl_Obj* shlibFile) #ifdef hpux return 1; #else - char* skipstr; + WCHAR *skipstr; - skipstr = getenv ("TCL_TEMPLOAD_NO_UNLINK"); + skipstr = getenv("TCL_TEMPLOAD_NO_UNLINK"); if (skipstr && (skipstr[0] != '\0')) { return atoi(skipstr); } diff --git a/library/clock.tcl b/library/clock.tcl index 273b534..aa5d228 100644 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -2988,8 +2988,7 @@ proc ::tcl::clock::GetSystemTimeZone {} { set timezone $result } elseif {[set result [getenv TZ]] ne {}} { set timezone $result - } - if {![info exists timezone]} { + } else { # Cache the time zone only if it was detected by one of the # expensive methods. if { [info exists CachedSystemTimeZone] } { -- cgit v0.12 From 06ea55d820a91810fe57afda632449d0bca2fe52 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 23 Feb 2021 10:08:46 +0000 Subject: Simplify implementation on Cygwin: No need to use CFG_RUNTIME_BINDIR any more --- generic/tclZipfs.c | 16 +++++++--------- unix/Makefile.in | 1 - unix/tclUnixFile.c | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index f052c2e..4c668b0 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3113,7 +3113,7 @@ TclZipfs_TclLibrary(void) { Tcl_Obj *vfsInitScript; int found; -#if defined(_WIN32) && !defined(STATIC_BUILD) +#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(STATIC_BUILD) HMODULE hModule; WCHAR wName[MAX_PATH + LIBRARY_SIZE]; char dllName[(MAX_PATH + LIBRARY_SIZE) * 3]; @@ -3148,22 +3148,20 @@ TclZipfs_TclLibrary(void) */ #if !defined(STATIC_BUILD) -#if defined(_WIN32) +#if defined(_WIN32) || defined(__CYGWIN__) hModule = TclWinGetTclInstance(); GetModuleFileNameW(hModule, wName, MAX_PATH); +#ifdef __CYGWIN__ + cygwin_conv_path(3, wName, dllName, sizeof(dllName)); +#else WideCharToMultiByte(CP_UTF8, 0, wName, -1, dllName, sizeof(dllName), NULL, NULL); +#endif if (ZipfsAppHookFindTclInit(dllName) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } #else - if (ZipfsAppHookFindTclInit( -#ifdef __CYGWIN__ - CFG_RUNTIME_BINDIR -#else - CFG_RUNTIME_LIBDIR -#endif - "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { + if (ZipfsAppHookFindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } #endif /* _WIN32 */ diff --git a/unix/Makefile.in b/unix/Makefile.in index 15d80cb..f885f5a 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1523,7 +1523,6 @@ tclZipfs.o: $(GENERIC_DIR)/tclZipfs.c $(CC) -c $(CC_SWITCHES) \ -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ -DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \ - -DCFG_RUNTIME_BINDIR="\"$(bindir)\"" \ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip \ $(GENERIC_DIR)/tclZipfs.c diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index 203a118..d72913b 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -45,7 +45,7 @@ TclpFindExecutable( char name[PATH_MAX * 3 + 1]; GetModuleFileNameW(NULL, buf, PATH_MAX); - cygwin_conv_path(3, buf, name, PATH_MAX); + cygwin_conv_path(3, buf, name, sizeof(name)); length = strlen(name); if ((length > 4) && !strcasecmp(name + length - 4, ".exe")) { /* Strip '.exe' part. */ -- cgit v0.12 From c0f6db4b8165a139a30bd801ca3d8ffb56210940 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 23 Feb 2021 12:34:58 +0000 Subject: Revise buffer-sizes used in GetModuleFileNameW() calls. Available buffer-size reported to GetModuleFileNameW() was not always accurate --- unix/tclUnixFile.c | 6 +++--- win/tclWinFile.c | 2 +- win/tclWinInit.c | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index 3b09799..f2a6b23 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -43,9 +43,9 @@ TclpFindExecutable( #ifdef __CYGWIN__ int length; char buf[PATH_MAX * 2]; - char name[PATH_MAX * TCL_UTF_MAX + 1]; - GetModuleFileNameW(NULL, buf, PATH_MAX); - cygwin_conv_path(3, buf, name, PATH_MAX); + char name[PATH_MAX * 3 + 1]; + GetModuleFileNameW(NULL, buf, sizeof(buf)/2); + cygwin_conv_path(3, buf, name, sizeof(name)); length = strlen(name); if ((length > 4) && !strcasecmp(name + length - 4, ".exe")) { /* Strip '.exe' part. */ diff --git a/win/tclWinFile.c b/win/tclWinFile.c index d582664..8df346f 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -852,7 +852,7 @@ TclpFindExecutable( * create this process. */ - if (GetModuleFileNameW(NULL, wName, MAX_PATH) == 0) { + if (GetModuleFileNameW(NULL, wName, sizeof(wName)/sizeof(WCHAR)) == 0) { GetModuleFileNameA(NULL, name, sizeof(name)); /* diff --git a/win/tclWinInit.c b/win/tclWinInit.c index 6c34573..2abcd3e 100644 --- a/win/tclWinInit.c +++ b/win/tclWinInit.c @@ -342,11 +342,11 @@ InitializeDefaultLibraryDir( { HMODULE hModule = TclWinGetTclInstance(); WCHAR wName[MAX_PATH + LIBRARY_SIZE]; - char name[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; + char name[(MAX_PATH + LIBRARY_SIZE) * 3]; char *end, *p; - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { - GetModuleFileNameA(hModule, name, MAX_PATH); + if (GetModuleFileNameW(hModule, wName, sizeof(wName)/sizeof(WCHAR)) == 0) { + GetModuleFileNameA(hModule, name, sizeof(name)); } else { ToUtf(wName, name); } @@ -393,11 +393,11 @@ InitializeSourceLibraryDir( { HMODULE hModule = TclWinGetTclInstance(); WCHAR wName[MAX_PATH + LIBRARY_SIZE]; - char name[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; + char name[(MAX_PATH + LIBRARY_SIZE) * 3]; char *end, *p; - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { - GetModuleFileNameA(hModule, name, MAX_PATH); + if (GetModuleFileNameW(hModule, wName, sizeof(wName)/sizeof(WCHAR)) == 0) { + GetModuleFileNameA(hModule, name, sizeof(name)); } else { ToUtf(wName, name); } -- cgit v0.12 From e5153a8d0c265d7dfb9ea1939563faf94f544a1b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 24 Feb 2021 08:58:15 +0000 Subject: Fix typo, eliminate type-cast --- generic/tclZipfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b45bdfe..ed3b42d 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -2,7 +2,7 @@ * tclZipfs.c -- * * Implementation of the ZIP filesystem used in TIP 430 - * Adapted from the implentation for AndroWish. + * Adapted from the implementation for AndroWish. * * Copyright © 2016-2017 Sean Woods * Copyright © 2013-2015 Christian Werner @@ -4822,14 +4822,14 @@ TclZipfs_AppHook( char ***argvPtr) /* Pointer to argv */ #endif /* _WIN32 */ { - char *archive; + const char *archive; #ifdef _WIN32 Tcl_FindExecutable(NULL); #else Tcl_FindExecutable((*argvPtr)[0]); #endif - archive = (char *) Tcl_GetNameOfExecutable(); + archive = Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); /* -- cgit v0.12 From d134d35fef774db63654e487bb6303b79597b820 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 24 Feb 2021 11:56:53 +0000 Subject: Fix "make checkstubs": A few more MODULE_SCOPE libtommath functions --- generic/tcl.decls | 3 +++ generic/tclStubInit.c | 2 +- generic/tclTomMathDecls.h | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 5895946..b659684 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2497,6 +2497,9 @@ export { export { void Tcl_InitSubsystems(void) } +export { + int TclZipfs_AppHook(int *argc, char ***argv) +} # Local Variables: # mode: tcl diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index dd7dc26..50c99ad 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -142,7 +142,7 @@ static void uniCodePanic(void) { #define TclBN_mp_xor mp_xor #define TclBN_mp_zero mp_zero #define TclBN_s_mp_add s_mp_add -#define TclBN_s_mp_balance_mul mp_balance_mul +#define TclBN_s_mp_balance_mul s_mp_balance_mul #define TclBN_mp_karatsuba_mul s_mp_karatsuba_mul #define TclBN_mp_karatsuba_sqr s_mp_karatsuba_sqr #define TclBN_s_mp_mul_digs s_mp_mul_digs diff --git a/generic/tclTomMathDecls.h b/generic/tclTomMathDecls.h index 62605fc..1b2c05f 100644 --- a/generic/tclTomMathDecls.h +++ b/generic/tclTomMathDecls.h @@ -73,6 +73,11 @@ MODULE_SCOPE mp_err TclBN_s_mp_mul_d(const mp_int *a, mp_digit b, mp_int *c); MODULE_SCOPE void TclBN_s_mp_reverse(unsigned char *s, size_t len); MODULE_SCOPE void TclBN_s_mp_set(mp_int *a, mp_digit b); MODULE_SCOPE mp_err TclBN_s_mp_sub_d(const mp_int *a, mp_digit b, mp_int *c); +MODULE_SCOPE mp_err TclBN_s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c); +MODULE_SCOPE const char *const TclBN_mp_s_rmap; +MODULE_SCOPE const uint8_t TclBN_mp_s_rmap_reverse[]; +MODULE_SCOPE const size_t TclBN_mp_s_rmap_reverse_sz; +MODULE_SCOPE mp_err TclBN_mp_set_int(mp_int *a, unsigned long b); #ifdef __cplusplus } #endif @@ -149,7 +154,7 @@ MODULE_SCOPE mp_err TclBN_s_mp_sub_d(const mp_int *a, mp_digit b, mp_int *c); #define mp_xor TclBN_mp_xor #define mp_zero TclBN_mp_zero #define s_mp_add TclBN_s_mp_add -#define s_mp_balance_mul TclBN_mp_balance_mul +#define s_mp_balance_mul TclBN_s_mp_balance_mul #define s_mp_karatsuba_mul TclBN_mp_karatsuba_mul #define s_mp_karatsuba_sqr TclBN_mp_karatsuba_sqr #define s_mp_mul_digs TclBN_s_mp_mul_digs -- cgit v0.12 From a97e3eef6d56096f000475cef61a482b7cf21b73 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 26 Feb 2021 13:18:50 +0000 Subject: Increase some (internal) variables from int/long to long/size_t. On the way to allow bigger blocks in the threaded allocator --- generic/tclInt.h | 2 +- generic/tclThreadAlloc.c | 56 +++++++++++++++++++++++------------------------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 27e818c..cc4f6a9 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1804,7 +1804,7 @@ typedef struct AllocCache { struct Cache *nextPtr; /* Linked list of cache entries. */ Tcl_ThreadId owner; /* Which thread's cache is this? */ Tcl_Obj *firstObjPtr; /* List of free objects for thread. */ - int numObjects; /* Number of objects for thread. */ + size_t numObjects; /* Number of objects for thread. */ } AllocCache; /* diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index ad508b9..cd55ab9 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -89,11 +89,10 @@ typedef struct Bucket { /* All fields below for accounting only */ - long numRemoves; /* Number of removes from bucket */ - long numInserts; /* Number of inserts into bucket */ - long numWaits; /* Number of waits to acquire a lock */ - long numLocks; /* Number of locks acquired */ - long totalAssigned; /* Total space assigned to bucket */ + size_t numRemoves; /* Number of removes from bucket */ + size_t numInserts; /* Number of inserts into bucket */ + size_t numLocks; /* Number of locks acquired */ + size_t totalAssigned; /* Total space assigned to bucket */ } Bucket; /* @@ -107,9 +106,9 @@ typedef struct Cache { struct Cache *nextPtr; /* Linked list of cache entries */ Tcl_ThreadId owner; /* Which thread's cache is this? */ Tcl_Obj *firstObjPtr; /* List of free objects for thread */ - int numObjects; /* Number of objects for thread */ + size_t numObjects; /* Number of objects for thread */ Tcl_Obj *lastPtr; /* Last object in this cache */ - int totalAssigned; /* Total space assigned to thread */ + size_t totalAssigned; /* Total space assigned to thread */ Bucket buckets[NBUCKETS]; /* The buckets for this thread */ } Cache; @@ -132,12 +131,12 @@ static struct { static Cache * GetCache(void); static void LockBucket(Cache *cachePtr, int bucket); static void UnlockBucket(Cache *cachePtr, int bucket); -static void PutBlocks(Cache *cachePtr, int bucket, int numMove); +static void PutBlocks(Cache *cachePtr, int bucket, long numMove); static int GetBlocks(Cache *cachePtr, int bucket); static Block * Ptr2Block(void *ptr); static void * Block2Ptr(Block *blockPtr, int bucket, unsigned int reqSize); -static void MoveObjs(Cache *fromPtr, Cache *toPtr, int numMove); -static void PutObjs(Cache *fromPtr, int numMove); +static void MoveObjs(Cache *fromPtr, Cache *toPtr, long numMove); +static void PutObjs(Cache *fromPtr, long numMove); /* * Local variables defined in this file and initialized at startup. @@ -548,7 +547,7 @@ TclThreadAllocObj(void) */ if (cachePtr->numObjects == 0) { - int numMove; + long numMove; Tcl_MutexLock(objLockPtr); numMove = sharedPtr->numObjects; @@ -565,11 +564,11 @@ TclThreadAllocObj(void) cachePtr->numObjects = numMove = NOBJALLOC; newObjsPtr = (Tcl_Obj *)TclpSysAlloc(sizeof(Tcl_Obj) * numMove, 0); if (newObjsPtr == NULL) { - Tcl_Panic("alloc: could not allocate %d new objects", numMove); + Tcl_Panic("alloc: could not allocate %ld new objects", numMove); } cachePtr->lastPtr = newObjsPtr + numMove - 1; objPtr = cachePtr->firstObjPtr; /* NULL */ - while (--numMove >= 0) { + while (numMove-- > 0) { newObjsPtr[numMove].internalRep.twoPtrValue.ptr1 = objPtr; objPtr = newObjsPtr + numMove; } @@ -671,14 +670,13 @@ Tcl_GetMemoryInfo( Tcl_DStringAppendElement(dsPtr, buf); } for (n = 0; n < NBUCKETS; ++n) { - sprintf(buf, "%lu %ld %ld %ld %ld %ld %ld", - (unsigned long) bucketInfo[n].blockSize, + sprintf(buf, "%" TCL_Z_MODIFIER "u %ld %" TCL_Z_MODIFIER "d %" TCL_Z_MODIFIER "d %" TCL_Z_MODIFIER "d %" TCL_Z_MODIFIER "d", + bucketInfo[n].blockSize, cachePtr->buckets[n].numFree, cachePtr->buckets[n].numRemoves, cachePtr->buckets[n].numInserts, cachePtr->buckets[n].totalAssigned, - cachePtr->buckets[n].numLocks, - cachePtr->buckets[n].numWaits); + cachePtr->buckets[n].numLocks); Tcl_DStringAppendElement(dsPtr, buf); } Tcl_DStringEndSublist(dsPtr); @@ -707,7 +705,7 @@ static void MoveObjs( Cache *fromPtr, Cache *toPtr, - int numMove) + long numMove) { Tcl_Obj *objPtr = fromPtr->firstObjPtr; Tcl_Obj *fromFirstObjPtr = objPtr; @@ -720,7 +718,7 @@ MoveObjs( * to be moved) as the first object in the 'from' cache. */ - while (--numMove) { + while (numMove-- > 1) { objPtr = (Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1; } fromPtr->firstObjPtr = (Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1; @@ -754,9 +752,9 @@ MoveObjs( static void PutObjs( Cache *fromPtr, - int numMove) + long numMove) { - int keep = fromPtr->numObjects - numMove; + size_t keep = fromPtr->numObjects - numMove; Tcl_Obj *firstPtr, *lastPtr = NULL; fromPtr->numObjects = keep; @@ -767,7 +765,7 @@ PutObjs( do { lastPtr = firstPtr; firstPtr = (Tcl_Obj *)firstPtr->internalRep.twoPtrValue.ptr1; - } while (--keep > 0); + } while (keep-- > 1); lastPtr->internalRep.twoPtrValue.ptr1 = NULL; } @@ -898,14 +896,14 @@ static void PutBlocks( Cache *cachePtr, int bucket, - int numMove) + long numMove) { /* * We have numFree. Want to shed numMove. So compute how many * Blocks to keep. */ - int keep = cachePtr->buckets[bucket].numFree - numMove; + long keep = cachePtr->buckets[bucket].numFree - numMove; Block *lastPtr = NULL, *firstPtr; cachePtr->buckets[bucket].numFree = keep; @@ -916,7 +914,7 @@ PutBlocks( do { lastPtr = firstPtr; firstPtr = firstPtr->nextBlock; - } while (--keep > 0); + } while (keep-- > 1); lastPtr->nextBlock = NULL; } @@ -961,7 +959,7 @@ GetBlocks( int bucket) { Block *blockPtr; - int n; + long n; /* * First, atttempt to move blocks from the shared cache. Note the @@ -994,7 +992,7 @@ GetBlocks( cachePtr->buckets[bucket].firstPtr = blockPtr; sharedPtr->buckets[bucket].numFree -= n; cachePtr->buckets[bucket].numFree = n; - while (--n > 0) { + while (n-- > 1) { blockPtr = blockPtr->nextBlock; } sharedPtr->buckets[bucket].firstPtr = blockPtr->nextBlock; @@ -1016,7 +1014,7 @@ GetBlocks( blockPtr = NULL; n = NBUCKETS; size = 0; - while (--n > bucket) { + while (n-- > bucket + 1) { if (cachePtr->buckets[n].numFree > 0) { size = bucketInfo[n].blockSize; blockPtr = cachePtr->buckets[n].firstPtr; @@ -1045,7 +1043,7 @@ GetBlocks( n = size / bucketInfo[bucket].blockSize; cachePtr->buckets[bucket].numFree = n; cachePtr->buckets[bucket].firstPtr = blockPtr; - while (--n > 0) { + while (n-- > 1) { blockPtr->nextBlock = (Block *) ((char *) blockPtr + bucketInfo[bucket].blockSize); blockPtr = blockPtr->nextBlock; -- cgit v0.12 From 62939392967f50a987a386e6075c7913db471c5a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 26 Feb 2021 14:52:14 +0000 Subject: Further internal variable upgrade from long -> size_t --- generic/tclAlloc.c | 10 +++++----- generic/tclThreadAlloc.c | 39 ++++++++++++++++++++------------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c index 70cb1b6..2043248 100644 --- a/generic/tclAlloc.c +++ b/generic/tclAlloc.c @@ -94,7 +94,7 @@ union overhead { #define MINBLOCK ((sizeof(union overhead) + (TCL_ALLOCALIGN-1)) & ~(TCL_ALLOCALIGN-1)) #define NBUCKETS (13 - (MINBLOCK >> 4)) -#define MAXMALLOC (1<<(NBUCKETS+2)) +#define MAXMALLOC ((size_t)1 << (NBUCKETS+2)) static union overhead *nextf[NBUCKETS]; /* @@ -583,7 +583,7 @@ TclpRealloc( Tcl_MutexUnlock(allocMutexPtr); return (void *)(overPtr+1); } - maxSize = 1 << (i+3); + maxSize = (size_t)1 << (i+3); expensive = 0; if (numBytes+OVERHEAD > maxSize) { expensive = 1; @@ -656,18 +656,18 @@ mstats( for (j=0, overPtr=nextf[i]; overPtr; overPtr=overPtr->next, j++) { fprintf(stderr, " %u", j); } - totalFree += ((size_t)j) * (1 << (i + 3)); + totalFree += ((size_t)j) * ((size_t)1 << (i + 3)); } fprintf(stderr, "\nused:\t"); for (i = 0; i < NBUCKETS; i++) { fprintf(stderr, " %" TCL_Z_MODIFIER "u", numMallocs[i]); - totalUsed += numMallocs[i] * (1 << (i + 3)); + totalUsed += numMallocs[i] * ((size_t)1 << (i + 3)); } fprintf(stderr, "\n\tTotal small in use: %" TCL_Z_MODIFIER "u, total free: %" TCL_Z_MODIFIER "u\n", totalUsed, totalFree); - fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %" TCL_Z_MODIFIER "u\n", + fprintf(stderr, "\n\tNumber of big (>%" TCL_Z_MODIFIER "u) blocks in use: %" TCL_Z_MODIFIER "u\n", MAXMALLOC, numMallocs[NBUCKETS]); Tcl_MutexUnlock(allocMutexPtr); diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index cd55ab9..28475f9 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -82,10 +82,10 @@ typedef union Block { * and statistics information. */ -typedef struct Bucket { +typedef struct { Block *firstPtr; /* First block available */ Block *lastPtr; /* End of block list */ - long numFree; /* Number of blocks available */ + size_t numFree; /* Number of blocks available */ /* All fields below for accounting only */ @@ -119,8 +119,8 @@ typedef struct Cache { static struct { size_t blockSize; /* Bucket blocksize. */ - int maxBlocks; /* Max blocks before move to share. */ - int numMove; /* Num blocks to move to share. */ + size_t maxBlocks; /* Max blocks before move to share. */ + size_t numMove; /* Num blocks to move to share. */ Tcl_Mutex *lockPtr; /* Share bucket lock. */ } bucketInfo[NBUCKETS]; @@ -131,12 +131,12 @@ static struct { static Cache * GetCache(void); static void LockBucket(Cache *cachePtr, int bucket); static void UnlockBucket(Cache *cachePtr, int bucket); -static void PutBlocks(Cache *cachePtr, int bucket, long numMove); +static void PutBlocks(Cache *cachePtr, int bucket, size_t numMove); static int GetBlocks(Cache *cachePtr, int bucket); static Block * Ptr2Block(void *ptr); -static void * Block2Ptr(Block *blockPtr, int bucket, unsigned int reqSize); -static void MoveObjs(Cache *fromPtr, Cache *toPtr, long numMove); -static void PutObjs(Cache *fromPtr, long numMove); +static void * Block2Ptr(Block *blockPtr, int bucket, size_t reqSize); +static void MoveObjs(Cache *fromPtr, Cache *toPtr, size_t numMove); +static void PutObjs(Cache *fromPtr, size_t numMove); /* * Local variables defined in this file and initialized at startup. @@ -547,7 +547,7 @@ TclThreadAllocObj(void) */ if (cachePtr->numObjects == 0) { - long numMove; + size_t numMove; Tcl_MutexLock(objLockPtr); numMove = sharedPtr->numObjects; @@ -670,7 +670,8 @@ Tcl_GetMemoryInfo( Tcl_DStringAppendElement(dsPtr, buf); } for (n = 0; n < NBUCKETS; ++n) { - sprintf(buf, "%" TCL_Z_MODIFIER "u %ld %" TCL_Z_MODIFIER "d %" TCL_Z_MODIFIER "d %" TCL_Z_MODIFIER "d %" TCL_Z_MODIFIER "d", + sprintf(buf, "%" TCL_Z_MODIFIER "u %" TCL_Z_MODIFIER "u %" TCL_Z_MODIFIER "u %" + TCL_Z_MODIFIER "u %" TCL_Z_MODIFIER "u %" TCL_Z_MODIFIER "u", bucketInfo[n].blockSize, cachePtr->buckets[n].numFree, cachePtr->buckets[n].numRemoves, @@ -705,7 +706,7 @@ static void MoveObjs( Cache *fromPtr, Cache *toPtr, - long numMove) + size_t numMove) { Tcl_Obj *objPtr = fromPtr->firstObjPtr; Tcl_Obj *fromFirstObjPtr = objPtr; @@ -752,7 +753,7 @@ MoveObjs( static void PutObjs( Cache *fromPtr, - long numMove) + size_t numMove) { size_t keep = fromPtr->numObjects - numMove; Tcl_Obj *firstPtr, *lastPtr = NULL; @@ -806,7 +807,7 @@ static void * Block2Ptr( Block *blockPtr, int bucket, - unsigned int reqSize) + size_t reqSize) { void *ptr; @@ -896,14 +897,14 @@ static void PutBlocks( Cache *cachePtr, int bucket, - long numMove) + size_t numMove) { /* * We have numFree. Want to shed numMove. So compute how many * Blocks to keep. */ - long keep = cachePtr->buckets[bucket].numFree - numMove; + size_t keep = cachePtr->buckets[bucket].numFree - numMove; Block *lastPtr = NULL, *firstPtr; cachePtr->buckets[bucket].numFree = keep; @@ -959,7 +960,7 @@ GetBlocks( int bucket) { Block *blockPtr; - long n; + size_t n; /* * First, atttempt to move blocks from the shared cache. Note the @@ -1014,7 +1015,7 @@ GetBlocks( blockPtr = NULL; n = NBUCKETS; size = 0; - while (n-- > bucket + 1) { + while (n-- > (size_t)bucket + 1) { if (cachePtr->buckets[n].numFree > 0) { size = bucketInfo[n].blockSize; blockPtr = cachePtr->buckets[n].firstPtr; @@ -1080,9 +1081,9 @@ TclInitThreadAlloc(void) objLockPtr = TclpNewAllocMutex(); for (i = 0; i < NBUCKETS; ++i) { bucketInfo[i].blockSize = MINALLOC << i; - bucketInfo[i].maxBlocks = 1 << (NBUCKETS - 1 - i); + bucketInfo[i].maxBlocks = ((size_t)1) << (NBUCKETS - 1 - i); bucketInfo[i].numMove = i < NBUCKETS - 1 ? - 1 << (NBUCKETS - 2 - i) : 1; + (size_t)1 << (NBUCKETS - 2 - i) : 1; bucketInfo[i].lockPtr = TclpNewAllocMutex(); } TclpInitAllocCache(); -- cgit v0.12 From 1ac55b7d3fca0fa53e5ebbd6f7107d4dc3b79c9b Mon Sep 17 00:00:00 2001 From: oehhar Date: Sat, 27 Feb 2021 11:19:28 +0000 Subject: Ticket [87082587c4]: typo in msgcat man page --- doc/msgcat.n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/msgcat.n b/doc/msgcat.n index 2fc1eee..0811bae 100644 --- a/doc/msgcat.n +++ b/doc/msgcat.n @@ -143,7 +143,7 @@ cannot be set independently. For example, if the current locale is en_US_funky, then \fB::msgcat::mcpreferences\fR returns \fB{en_us_funky en_us en {}}\fR. .TP -\fB::msgcat:mcloadedlocales subcommand\fR ?\fIlocale\fR? +\fB::msgcat::mcloadedlocales subcommand\fR ?\fIlocale\fR? . This group of commands manage the list of loaded locales for packages not setting a package locale. .PP -- cgit v0.12 From b697c844add273719e0d724f0e7680d215a0b163 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 2 Mar 2021 10:10:54 +0000 Subject: Backport some UTF-8-related changed from 8.7 to 8.6, only for TCL_UTF_MAX > 3. No change for TCL_UTF_MAX=3. Also adapt test-cases accordingly, and add comments why the changes were done. --- generic/tclUtf.c | 20 ++++++++++++++--- tests/utf.test | 65 ++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index f99c497..65a3f41 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -90,6 +90,8 @@ static const unsigned char complete[256] = { #if TCL_UTF_MAX > 3 4,4,4,4,4, #else + /* Tcl_UtfToUniChar() accesses src[1] and src[2] to check whether + * the UTF-8 sequence is valid, so we cannot use 1 here. */ 3,3,3,3,3, #endif 1,1,1,1,1,1,1,1,1,1,1 @@ -536,7 +538,7 @@ Tcl_UtfToUniCharDString( w = wString; p = src; endPtr = src + length; - optPtr = endPtr - TCL_UTF_MAX; + optPtr = endPtr - ((TCL_UTF_MAX > 3) ? 4 : 3) ; while (p <= optPtr) { p += TclUtfToUniChar(p, &ch); *w++ = ch; @@ -623,7 +625,7 @@ Tcl_NumUtfChars( /* Pointer to the end of string. Never read endPtr[0] */ const char *endPtr = src + length; /* Pointer to last byte where optimization still can be used */ - const char *optPtr = endPtr - TCL_UTF_MAX; + const char *optPtr = endPtr - ((TCL_UTF_MAX > 3) ? 4 : 3); /* * Optimize away the call in this loop. Justified because... @@ -759,6 +761,19 @@ Tcl_UtfNext( int left; const char *next; +#if TCL_UTF_MAX > 3 + if (((*src) & 0xC0) == 0x80) { + /* Continuation byte, so we start 'inside' a (possible valid) UTF-8 + * sequence. Since we are not allowed to access src[-1], we cannot + * check if the sequence is actually valid, the best we can do is + * just assume it is valid and locate the end. */ + if ((((*++src) & 0xC0) == 0x80) && (((*++src) & 0xC0) == 0x80)) { + ++src; + } + return src; + } +#endif + left = totalBytes[UCHAR(*src)]; next = src + 1; while (--left) { @@ -895,7 +910,6 @@ Tcl_UtfPrev( * properly formed byte sequence to find, and we can stop looking, * accepting the fallback. */ - return fallback; } diff --git a/tests/utf.test b/tests/utf.test index 8e886ae..cd8feb6 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -3,7 +3,7 @@ # errors. No output means no errors were found. # # Copyright (c) 1997 Sun Microsystems, Inc. -# Copyright (c) 1998-1999 by Scriptics Corporation. +# Copyright (c) 1998-1999 Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -21,6 +21,7 @@ testConstraint fullutf [expr {[format %c 0x010000] ne "\uFFFD"}] testConstraint utf16 [expr {[string length [format %c 0x10000]] == 2}] testConstraint ucs4 [expr {[testConstraint fullutf] && [string length [format %c 0x10000]] == 1}] +testConstraint ucs2_utf16 [expr {![testConstraint ucs4]}] testConstraint Uesc [expr {"\U0041" eq "A"}] testConstraint pre388 [expr {"\x741" eq "A"}] @@ -78,9 +79,12 @@ test utf-1.11 {Tcl_UniCharToUtf: 3 byte sequence, low surrogate} testbytestring test utf-1.12 {Tcl_UniCharToUtf: 4 byte sequence, high/low surrogate} {pairsTo4bytes testbytestring} { expr {"\uD842\uDC42" eq [testbytestring \xF0\xA0\xA1\x82]} } 1 -test utf-1.13 {Tcl_UniCharToUtf: Invalid surrogate} {Uesc ucs2} { +test utf-1.13.0 {Tcl_UniCharToUtf: Invalid surrogate} {Uesc ucs2} { expr {"\UD842" eq "\uD842"} } 1 +test utf-1.13.1 {Tcl_UniCharToUtf: Invalid surrogate} {Uesc testbytestring fullutf} { + expr {"\UD842" eq [testbytestring \xEF\xBF\xBD]} +} 1 test utf-2.1 {Tcl_UtfToUniChar: low ascii} { string length "abc" @@ -103,7 +107,7 @@ test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} testbytestrin test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} testbytestring { string length [testbytestring \xE4\xB9\x8E] } 1 -test utf-2.8.0 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {testbytestring ucs2} { +test utf-2.8.0 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {testbytestring ucs2_utf16} { string length [testbytestring \xF0\x90\x80\x80] } 2 test utf-2.8.1 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {testbytestring ucs4} { @@ -215,9 +219,12 @@ test utf-6.9 {Tcl_UtfNext} {testutfnext testbytestring} { test utf-6.10 {Tcl_UtfNext} {testutfnext testbytestring} { testutfnext [testbytestring \xA0]G } 1 -test utf-6.11 {Tcl_UtfNext} {testutfnext testbytestring} { +test utf-6.11.0 {Tcl_UtfNext} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\x00] } 1 +test utf-6.11.1 {Tcl_UtfNext} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\x00] +} 2 test utf-6.12 {Tcl_UtfNext} {testutfnext testbytestring} { testutfnext [testbytestring \xA0\xD0] } 1 @@ -476,12 +483,18 @@ test utf-6.87.0 {Tcl_UtfNext - overlong sequences} {testutfnext testbytestring u test utf-6.87.1 {Tcl_UtfNext - overlong sequences} {testutfnext testbytestring fullutf} { testutfnext [testbytestring \xF0\x90\x80\x80] } 4 -test utf-6.88 {Tcl_UtfNext, pointing to 2th byte of 3-byte valid sequence} {testutfnext testbytestring} { +test utf-6.88.0 {Tcl_UtfNext, pointing to 2th byte of 3-byte valid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\x00] } 1 -test utf-6.89 {Tcl_UtfNext, pointing to 2th byte of 3-byte invalid sequence} {testutfnext testbytestring} { +test utf-6.88.1 {Tcl_UtfNext, pointing to 2th byte of 3-byte valid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\x00] +} 2 +test utf-6.89.0 {Tcl_UtfNext, pointing to 2th byte of 3-byte invalid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \x80\x80\x00] } 1 +test utf-6.89.1 {Tcl_UtfNext, pointing to 2th byte of 3-byte invalid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \x80\x80\x00] +} 2 test utf-6.90.0 {Tcl_UtfNext, validity check [493dccc2de]} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xF4\x8F\xBF\xBF] } 1 @@ -491,18 +504,30 @@ test utf-6.90.1 {Tcl_UtfNext, validity check [493dccc2de]} {testutfnext testbyte test utf-6.91 {Tcl_UtfNext, validity check [493dccc2de]} {testutfnext testbytestring} { testutfnext [testbytestring \xF4\x90\x80\x80] } 1 -test utf-6.92 {Tcl_UtfNext, pointing to 2th byte of 4-byte valid sequence} {testutfnext testbytestring} { +test utf-6.92.0 {Tcl_UtfNext, pointing to 2th byte of 4-byte valid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0] } 1 -test utf-6.93 {Tcl_UtfNext, pointing to 2th byte of 4-byte invalid sequence} {testutfnext testbytestring} { +test utf-6.92.1 {Tcl_UtfNext, pointing to 2th byte of 4-byte valid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0] +} 3 +test utf-6.93.0 {Tcl_UtfNext, pointing to 2th byte of 4-byte invalid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \x80\x80\x80] } 1 -test utf-6.94 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring} { +test utf-6.93.1 {Tcl_UtfNext, pointing to 2th byte of 4-byte invalid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \x80\x80\x80] +} 3 +test utf-6.94.0 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0\xA0] } 1 -test utf-6.95 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring} { +test utf-6.94.1 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0\xA0] +} 3 +test utf-6.95.0 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \x80\x80\x80\x80] } 1 +test utf-6.95.1 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \x80\x80\x80\x80] +} 3 test utf-6.96 {Tcl_UtfNext, read limits} testutfnext { testutfnext G 0 } 0 @@ -600,18 +625,30 @@ test utf-6.121 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { test utf-6.122 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { testutfnext [testbytestring \xA0\xA0\xA0] 2 } 0 -test utf-6.123 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.123.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0]G 3 } 1 -test utf-6.124 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.123.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0]G 3 +} 3 +test utf-6.124.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0\xA0] 3 } 1 -test utf-6.125 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.124.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0\xA0] 3 +} 3 +test utf-6.125.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0\xA0]G 4 } 1 -test utf-6.126 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.125.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0\xA0]G 4 +} 3 +test utf-6.126.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0\xA0\xA0] 4 } 1 +test utf-6.126.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0\xA0\xA0] 4 +} 3 test utf-7.1 {Tcl_UtfPrev} testutfprev { testutfprev {} -- cgit v0.12 From 773a30a541bb7f3681c3e0dc08b5c9d7e23fbaed Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 2 Mar 2021 10:53:30 +0000 Subject: Using 0xFC00 is more readable here than ~0x3FF. It's sufficient becauwe ch1 and ch2 are only 16-bit. Backported from 8.7 --- generic/tclUtf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 65a3f41..57e58c1 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -1296,11 +1296,11 @@ Tcl_UtfNcmp( if (ch1 != ch2) { #if TCL_UTF_MAX == 4 /* Surrogates always report higher than non-surrogates */ - if (((ch1 & ~0x3FF) == 0xD800)) { - if ((ch2 & ~0x3FF) != 0xD800) { + if (((ch1 & 0xFC00) == 0xD800)) { + if ((ch2 & 0xFC00) != 0xD800) { return ch1; } - } else if ((ch2 & ~0x3FF) == 0xD800) { + } else if ((ch2 & 0xFC00) == 0xD800) { return -ch2; } #endif -- cgit v0.12 From 6433d6a30be72d681a6f24797f77f14f65d7b031 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 3 Mar 2021 14:31:37 +0000 Subject: Backport improvements in UTF-8 handling for Tcl_UtfPrev/Tcl_UtfNext from 8.7 (through 8.6). No change for TCL_UTF_MAX=3. Adapt test-cases accordingly --- generic/tclInt.h | 8 ++--- generic/tclUtf.c | 50 ++++++++++++++++++------------ tests/utf.test | 92 +++++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 99 insertions(+), 51 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index b6d6a88..1a286a0 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3685,17 +3685,17 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, CONST char *file, */ #define TclUtfToUniChar(str, chPtr) \ - ((((unsigned char) *(str)) < 0xC0) ? \ - ((*(chPtr) = (unsigned char) *(str)), 1) \ + (((UCHAR(*(str))) < 0x80) ? \ + ((*(chPtr) = UCHAR(*(str))), 1) \ : Tcl_UtfToUniChar(str, chPtr)) #define TclUtfPrev(src, start) \ (((src) < (start)+2) ? (start) : \ - ((unsigned char) *(src - 1)) < 0x80 ? (src)-1 : \ + (UCHAR(*((src) - 1))) < 0x80 ? (src)-1 : \ Tcl_UtfPrev(src, start)) #define TclUtfNext(src) \ - ((((unsigned char) *(src)) < 0xC0) ? src + 1 : Tcl_UtfNext(src)) + (((UCHAR(*(src))) < 0x80) ? src + 1 : Tcl_UtfNext(src)) /* *---------------------------------------------------------------- diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 7309208..03d0f3a 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -167,14 +167,13 @@ Invalid( unsigned char byte = UCHAR(*src); int index; - if ((byte & 0xC3) != 0xC0) { + if ((byte & 0xC3) == 0xC0) { /* Only lead bytes 0xC0, 0xE0, 0xF0, 0xF4 need examination */ - return 0; - } - index = (byte - 0xC0) >> 1; - if (UCHAR(src[1]) < bounds[index] || UCHAR(src[1]) > bounds[index+1]) { - /* Out of bounds - report invalid. */ - return 1; + index = (byte - 0xC0) >> 1; + if (UCHAR(src[1]) < bounds[index] || UCHAR(src[1]) > bounds[index+1]) { + /* Out of bounds - report invalid. */ + return 1; + } } return 0; } @@ -425,10 +424,10 @@ Tcl_UtfToUniCharDString( Tcl_UniChar *w, *wString; const char *p; int oldLength; - /* Pointer to the end of string. Never read endPtr[0] */ - const char *endPtr = src + length; - /* Pointer to breakpoint in scan where optimization is lost */ - const char *optPtr = endPtr - TCL_UTF_MAX; + /* Pointer to the end of string. Never read endPtr[0] */ + const char *endPtr; + /* Pointer to last byte where optimization still can be used */ + const char *optPtr; if (length < 0) { length = strlen(src); @@ -448,14 +447,15 @@ Tcl_UtfToUniCharDString( w = wString; p = src; endPtr = src + length; - optPtr = endPtr - TCL_UTF_MAX; + optPtr = endPtr - ((TCL_UTF_MAX > 3) ? 4 : 3) ; while (p <= optPtr) { p += TclUtfToUniChar(p, w); w++; } while (p < endPtr) { if (Tcl_UtfCharComplete(p, endPtr-p)) { - p += TclUtfToUniChar(p, w++); + p += TclUtfToUniChar(p, w); + w++; } else { *w++ = UCHAR(*p++); } @@ -534,7 +534,7 @@ Tcl_NumUtfChars( /* Pointer to the end of string. Never read endPtr[0] */ const char *endPtr = src + length; /* Pointer to last byte where optimization still can be used */ - const char *optPtr = endPtr - TCL_UTF_MAX; + const char *optPtr = endPtr - ((TCL_UTF_MAX > 3) ? 4 : 3); /* * Optimize away the call in this loop. Justified because... @@ -554,7 +554,7 @@ Tcl_NumUtfChars( src += TclUtfToUniChar(src, &ch); } else { /* - * src points to incomplete UTF-8 sequence + * src points to incomplete UTF-8 sequence * Treat first byte as character and count it */ src++; @@ -570,7 +570,7 @@ Tcl_NumUtfChars( * * Tcl_UtfFindFirst -- * - * Returns a pointer to the first occurance of the given Unicode character + * Returns a pointer to the first occurrence of the given Unicode character * in the NULL-terminated UTF-8 string. The NULL terminator is considered * part of the UTF-8 string. Equivalent to Plan 9 utfrune(). * @@ -671,6 +671,19 @@ Tcl_UtfNext( int left; const char *next; +#if TCL_UTF_MAX > 3 + if (((*src) & 0xC0) == 0x80) { + /* Continuation byte, so we start 'inside' a (possible valid) UTF-8 + * sequence. Since we are not allowed to access src[-1], we cannot + * check if the sequence is actually valid, the best we can do is + * just assume it is valid and locate the end. */ + if ((((*++src) & 0xC0) == 0x80) && (((*++src) & 0xC0) == 0x80)) { + ++src; + } + return src; + } +#endif + left = totalBytes[UCHAR(*src)]; next = src + 1; while (--left) { @@ -800,14 +813,13 @@ Tcl_UtfPrev( /* Continue the search backwards... */ look--; - } while (trailBytesSeen < TCL_UTF_MAX); + } while (trailBytesSeen < (TCL_UTF_MAX < 4 ? 3 : 4)); /* - * We've seen TCL_UTF_MAX trail bytes, so we know there will not be a + * We've seen 3 trail bytes, so we know there will not be a * properly formed byte sequence to find, and we can stop looking, * accepting the fallback. */ - return fallback; } diff --git a/tests/utf.test b/tests/utf.test index e65f352..06ac329 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -3,7 +3,7 @@ # errors. No output means no errors were found. # # Copyright (c) 1997 Sun Microsystems, Inc. -# Copyright (c) 1998-1999 by Scriptics Corporation. +# Copyright (c) 1998-1999 Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -78,7 +78,10 @@ test utf-1.11 {Tcl_UniCharToUtf: 3 byte sequence, low surrogate} testbytestring test utf-1.12 {Tcl_UniCharToUtf: 4 byte sequence, high/low surrogate} {pairsTo4bytes testbytestring} { expr {"\uD842\uDC42" eq [testbytestring \xF0\xA0\xA1\x82]} } 1 -test utf-1.13 {Tcl_UniCharToUtf: Invalid surrogate} {Uesc testbytestring} { +test utf-1.13.0 {Tcl_UniCharToUtf: Invalid surrogate} {Uesc ucs2} { + expr {"\UD842" eq "\uD842"} +} 1 +test utf-1.13.1 {Tcl_UniCharToUtf: Invalid surrogate} {Uesc testbytestring fullutf} { expr {"\UD842" eq [testbytestring \xEF\xBF\xBD]} } 1 @@ -106,13 +109,19 @@ test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} testbytestrin test utf-2.8.0 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {testbytestring ucs2} { string length [testbytestring \xF0\x90\x80\x80] } 4 -test utf-2.8.1 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {testbytestring ucs4} { - string length [testbytestring \xF0\x90\x80\x80] +test utf-2.8.1 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {Uesc utf16} { + string length \U010000 +} 2 +test utf-2.8.2 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {Uesc ucs4} { + string length \U010000 } 1 test utf-2.9.0 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {testbytestring ucs2} { string length [testbytestring \xF4\x8F\xBF\xBF] } 4 -test utf-2.9.1 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {Uesc ucs4} { +test utf-2.9.1 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {Uesc utf16} { + string length \U10FFFF +} 2 +test utf-2.9.2 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {Uesc ucs4} { string length \U10FFFF } 1 test utf-2.10 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail, underflow} testbytestring { @@ -209,15 +218,18 @@ test utf-6.7 {Tcl_UtfNext} {testutfnext testbytestring} { test utf-6.8 {Tcl_UtfNext} {testutfnext testbytestring} { testutfnext A[testbytestring \xF8] } 1 -test utf-6.9 {Tcl_UtfNext} {testutfnext testbytestring} { +test utf-6.9 {Tcl_UtfNext} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0] } 1 test utf-6.10 {Tcl_UtfNext} {testutfnext testbytestring} { testutfnext [testbytestring \xA0]G } 1 -test utf-6.11 {Tcl_UtfNext} {testutfnext testbytestring} { +test utf-6.11.0 {Tcl_UtfNext} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\x00] } 1 +test utf-6.11.1 {Tcl_UtfNext} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\x00] +} 2 test utf-6.12 {Tcl_UtfNext} {testutfnext testbytestring} { testutfnext [testbytestring \xA0\xD0] } 1 @@ -476,12 +488,18 @@ test utf-6.87.0 {Tcl_UtfNext - overlong sequences} {testutfnext testbytestring u test utf-6.87.1 {Tcl_UtfNext - overlong sequences} {testutfnext testbytestring fullutf} { testutfnext [testbytestring \xF0\x90\x80\x80] } 4 -test utf-6.88 {Tcl_UtfNext, pointing to 2th byte of 3-byte valid sequence} {testutfnext testbytestring} { +test utf-6.88.0 {Tcl_UtfNext, pointing to 2th byte of 3-byte valid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\x00] } 1 -test utf-6.89 {Tcl_UtfNext, pointing to 2th byte of 3-byte invalid sequence} {testutfnext testbytestring} { +test utf-6.88.1 {Tcl_UtfNext, pointing to 2th byte of 3-byte valid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\x00] +} 2 +test utf-6.89.0 {Tcl_UtfNext, pointing to 2th byte of 3-byte invalid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \x80\x80\x00] } 1 +test utf-6.89.1 {Tcl_UtfNext, pointing to 2th byte of 3-byte invalid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \x80\x80\x00] +} 2 test utf-6.90.0 {Tcl_UtfNext, validity check [493dccc2de]} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xF4\x8F\xBF\xBF] } 1 @@ -491,18 +509,30 @@ test utf-6.90.1 {Tcl_UtfNext, validity check [493dccc2de]} {testutfnext testbyte test utf-6.91 {Tcl_UtfNext, validity check [493dccc2de]} {testutfnext testbytestring} { testutfnext [testbytestring \xF4\x90\x80\x80] } 1 -test utf-6.92 {Tcl_UtfNext, pointing to 2th byte of 4-byte valid sequence} {testutfnext testbytestring} { +test utf-6.92.0 {Tcl_UtfNext, pointing to 2th byte of 4-byte valid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0] } 1 -test utf-6.93 {Tcl_UtfNext, pointing to 2th byte of 4-byte invalid sequence} {testutfnext testbytestring} { +test utf-6.92.1 {Tcl_UtfNext, pointing to 2th byte of 4-byte valid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0] +} 3 +test utf-6.93.0 {Tcl_UtfNext, pointing to 2th byte of 4-byte invalid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \x80\x80\x80] } 1 -test utf-6.94 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring} { +test utf-6.93.1 {Tcl_UtfNext, pointing to 2th byte of 4-byte invalid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \x80\x80\x80] +} 3 +test utf-6.94.0 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0\xA0] } 1 -test utf-6.95 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring} { +test utf-6.94.1 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0\xA0] +} 3 +test utf-6.95.0 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \x80\x80\x80\x80] } 1 +test utf-6.95.1 {Tcl_UtfNext, pointing to 2th byte of 5-byte invalid sequence} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \x80\x80\x80\x80] +} 3 test utf-6.96 {Tcl_UtfNext, read limits} testutfnext { testutfnext G 0 } 0 @@ -554,10 +584,7 @@ test utf-6.111 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { test utf-6.112.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xF2\xA0\xA0\xA0]G 3 } 1 -test utf-6.112.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring utf16} { - testutfnext [testbytestring \xF2\xA0\xA0\xA0]G 3 -} 4 -test utf-6.112.3 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs4} { +test utf-6.112.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { testutfnext [testbytestring \xF2\xA0\xA0\xA0]G 3 } 0 test utf-6.113.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { @@ -575,10 +602,7 @@ test utf-6.115 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { test utf-6.116.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xF2\xA0\xA0\xA0\xA0] 3 } 1 -test utf-6.116.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring utf16} { - testutfnext [testbytestring \xF2\xA0\xA0\xA0\xA0] 3 -} 4 -test utf-6.116.2 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs4} { +test utf-6.116.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { testutfnext [testbytestring \xF2\xA0\xA0\xA0\xA0] 3 } 0 test utf-6.117.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { @@ -593,27 +617,39 @@ test utf-6.118 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { test utf-6.119 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { testutfnext [testbytestring \xA0]G 1 } 1 -test utf-6.120 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.120 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0] 1 } 1 -test utf-6.121 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.121 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0]G 2 } 1 -test utf-6.122 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.122 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0] 2 } 1 -test utf-6.123 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.123.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0]G 3 } 1 -test utf-6.124 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.123.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0]G 3 +} 3 +test utf-6.124.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0\xA0] 3 } 1 -test utf-6.125 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.124.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0\xA0] 3 +} 3 +test utf-6.125.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0\xA0]G 4 } 1 -test utf-6.126 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.125.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0\xA0]G 4 +} 3 +test utf-6.126.0 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0\xA0\xA0\xA0\xA0] 4 } 1 +test utf-6.126.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} { + testutfnext [testbytestring \xA0\xA0\xA0\xA0\xA0] 4 +} 3 test utf-7.1 {Tcl_UtfPrev} testutfprev { testutfprev {} -- cgit v0.12 From bebf0454f609132c9de5705f9a7b7f720438dd5e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 4 Mar 2021 09:42:47 +0000 Subject: cleanup genStubs.tcl, e.g. "==" -> "eq" and "!=" -> "ne". No change in output --- tools/genStubs.tcl | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tools/genStubs.tcl b/tools/genStubs.tcl index 67b5112..814d154 100644 --- a/tools/genStubs.tcl +++ b/tools/genStubs.tcl @@ -4,7 +4,7 @@ # interface. # # -# Copyright (c) 1998-1999 by Scriptics Corporation. +# Copyright (c) 1998-1999 Scriptics Corporation. # Copyright (c) 2007 Daniel A. Steffen # # See the file "license.terms" for information on usage and redistribution @@ -194,7 +194,7 @@ proc genStubs::declare {args} { set decl [parseDecl $decl] foreach platform $platformList { - if {$decl != ""} { + if {$decl ne ""} { set stubs($curName,$platform,$index) $decl if {![info exists stubs($curName,$platform,lastNum)] \ || ($index > $stubs($curName,$platform,lastNum))} { @@ -243,8 +243,9 @@ proc genStubs::rewriteFile {file text} { return } set in [open ${file} r] + fconfigure $in -eofchar "\032 {}" -encoding utf-8 set out [open ${file}.new w] - fconfigure $out -translation lf + fconfigure $out -translation lf -encoding utf-8 while {![eof $in]} { set line [gets $in] @@ -465,7 +466,9 @@ proc genStubs::makeDecl {name decl index} { } set line "$scspec $rtype" set count [expr {2 - ([string length $line] / 8)}] - append line [string range "\t\t\t" 0 $count] + if {$count >= 0} { + append line [string range "\t\t\t" 0 $count] + } set pad [expr {24 - [string length $line]}] if {$pad <= 0} { append line " " @@ -552,7 +555,7 @@ proc genStubs::makeMacro {name decl index} { append lfname [string range $fname 1 end] set text "#ifndef $fname\n#define $fname \\\n\t(" - if {$args == ""} { + if {$args eq ""} { append text "*" } append text "${name}StubsPtr->$lfname)" @@ -579,14 +582,14 @@ proc genStubs::makeSlot {name decl index} { append lfname [string range $fname 1 end] set text " " - if {$args == ""} { + if {$args eq ""} { append text $rtype " *" $lfname "; /* $index */\n" return $text } if {$rtype ne "void"} { regsub -all void $rtype VOID rtype } - if {[string range $rtype end-8 end] == "__stdcall"} { + if {[string range $rtype end-8 end] eq "__stdcall"} { append text [string trim [string range $rtype 0 end-9]] " (__stdcall *" $lfname ") " } else { append text $rtype " (*" $lfname ") " @@ -1004,7 +1007,7 @@ proc genStubs::emitHeader {name} { } append text "\ntypedef struct ${capName}Stubs {\n" append text " int magic;\n" - if {$epoch != ""} { + if {$epoch ne ""} { append text " int epoch;\n" append text " int revision;\n" } @@ -1053,7 +1056,7 @@ proc genStubs::emitInit {name textVar} { } append text "\n${capName}Stubs ${name}Stubs = \{\n" append text " TCL_STUB_MAGIC,\n" - if {$epoch != ""} { + if {$epoch ne ""} { set CAPName [string toupper $name] append text " ${CAPName}_STUBS_EPOCH,\n" append text " ${CAPName}_STUBS_REVISION,\n" @@ -1132,7 +1135,7 @@ proc genStubs::init {} { set outDir [lindex $argv 0] foreach file [lrange $argv 1 end] { - source $file + source -encoding utf-8 $file } foreach name [lsort [array names interfaces]] { @@ -1154,7 +1157,7 @@ proc genStubs::init {} { # Results: # Returns any values that were not assigned to variables. -if {[string length [namespace which lassign]] == 0} { +if {[namespace which lassign] ne ""} { proc lassign {valueList args} { if {[llength $args] == 0} { error "wrong # args: should be \"lassign list varName ?varName ...?\"" -- cgit v0.12 From 3f89004e3770f9777b2c028f268d0e8cda84172c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 4 Mar 2021 09:53:10 +0000 Subject: Add some more unused entries to the stub table, keeping up with the table size increase of higher Tcl versions --- generic/tcl.decls | 7 ++++++- generic/tclDecls.h | 27 ++++++++++++++++++++++++--- generic/tclInt.decls | 1 + generic/tclPlatDecls.h | 10 ++++++++++ generic/tclStubInit.c | 10 +++++++++- generic/tclTomMath.decls | 1 - 6 files changed, 50 insertions(+), 6 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 6510249..50e9465 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -21,6 +21,7 @@ library tcl interface tcl hooks {tclPlat tclInt tclIntPlat} +scspec EXTERN # Declare each of the functions in the public Tcl interface. Note that # the an index should never be reused for a different function in order @@ -2110,7 +2111,7 @@ declare 579 { # ----- BASELINE -- FOR -- 8.5.0 ----- # -declare 649 { +declare 656 { void TclUnusedStubEntry(void) } @@ -2150,6 +2151,9 @@ declare 1 macosx { const char *bundleName, const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath) } +declare 2 macosx { + void TclUnusedStubEntry(void) +} ############################################################################## @@ -2191,6 +2195,7 @@ export { export { TclTomMathStubs *tclTomMathStubsPtr (fool checkstubs) } + # Local Variables: # mode: tcl # End: diff --git a/generic/tclDecls.h b/generic/tclDecls.h index a5b7ec1..3651a3b 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -3481,9 +3481,16 @@ EXTERN void Tcl_AppendPrintfToObj(Tcl_Obj *objPtr, /* Slot 646 is reserved */ /* Slot 647 is reserved */ /* Slot 648 is reserved */ +/* Slot 649 is reserved */ +/* Slot 650 is reserved */ +/* Slot 651 is reserved */ +/* Slot 652 is reserved */ +/* Slot 653 is reserved */ +/* Slot 654 is reserved */ +/* Slot 655 is reserved */ #ifndef TclUnusedStubEntry_TCL_DECLARED #define TclUnusedStubEntry_TCL_DECLARED -/* 649 */ +/* 656 */ EXTERN void TclUnusedStubEntry(void); #endif @@ -4170,7 +4177,14 @@ typedef struct TclStubs { VOID *reserved646; VOID *reserved647; VOID *reserved648; - void (*tclUnusedStubEntry) (void); /* 649 */ + VOID *reserved649; + VOID *reserved650; + VOID *reserved651; + VOID *reserved652; + VOID *reserved653; + VOID *reserved654; + VOID *reserved655; + void (*tclUnusedStubEntry) (void); /* 656 */ } TclStubs; extern TclStubs *tclStubsPtr; @@ -6592,9 +6606,16 @@ extern TclStubs *tclStubsPtr; /* Slot 646 is reserved */ /* Slot 647 is reserved */ /* Slot 648 is reserved */ +/* Slot 649 is reserved */ +/* Slot 650 is reserved */ +/* Slot 651 is reserved */ +/* Slot 652 is reserved */ +/* Slot 653 is reserved */ +/* Slot 654 is reserved */ +/* Slot 655 is reserved */ #ifndef TclUnusedStubEntry #define TclUnusedStubEntry \ - (tclStubsPtr->tclUnusedStubEntry) /* 649 */ + (tclStubsPtr->tclUnusedStubEntry) /* 656 */ #endif #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 892f977..df39bef 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -17,6 +17,7 @@ library tcl # Define the unsupported generic interfaces. interface tclInt +scspec EXTERN # Declare each of the functions in the unsupported internal Tcl # interface. These interfaces are allowed to changed between versions. diff --git a/generic/tclPlatDecls.h b/generic/tclPlatDecls.h index ef23c84..16e8af0 100644 --- a/generic/tclPlatDecls.h +++ b/generic/tclPlatDecls.h @@ -75,6 +75,11 @@ EXTERN int Tcl_MacOSXOpenVersionedBundleResources( int hasResourceFile, int maxPathLen, char *libraryPath); #endif +#ifndef TclUnusedStubEntry_TCL_DECLARED +#define TclUnusedStubEntry_TCL_DECLARED +/* 2 */ +EXTERN void TclUnusedStubEntry(void); +#endif #endif /* MACOSX */ typedef struct TclPlatStubs { @@ -88,6 +93,7 @@ typedef struct TclPlatStubs { #ifdef MAC_OSX_TCL /* MACOSX */ int (*tcl_MacOSXOpenBundleResources) (Tcl_Interp *interp, CONST char *bundleName, int hasResourceFile, int maxPathLen, char *libraryPath); /* 0 */ int (*tcl_MacOSXOpenVersionedBundleResources) (Tcl_Interp *interp, CONST char *bundleName, CONST char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); /* 1 */ + void (*tclUnusedStubEntry) (void); /* 2 */ #endif /* MACOSX */ } TclPlatStubs; @@ -122,6 +128,10 @@ extern TclPlatStubs *tclPlatStubsPtr; #define Tcl_MacOSXOpenVersionedBundleResources \ (tclPlatStubsPtr->tcl_MacOSXOpenVersionedBundleResources) /* 1 */ #endif +#ifndef TclUnusedStubEntry +#define TclUnusedStubEntry \ + (tclPlatStubsPtr->tclUnusedStubEntry) /* 2 */ +#endif #endif /* MACOSX */ #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 1a83752..6968d89 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -675,6 +675,7 @@ TclPlatStubs tclPlatStubs = { #ifdef MAC_OSX_TCL /* MACOSX */ Tcl_MacOSXOpenBundleResources, /* 0 */ Tcl_MacOSXOpenVersionedBundleResources, /* 1 */ + TclUnusedStubEntry, /* 2 */ #endif /* MACOSX */ }; @@ -1446,7 +1447,14 @@ TclStubs tclStubs = { NULL, /* 646 */ NULL, /* 647 */ NULL, /* 648 */ - TclUnusedStubEntry, /* 649 */ + NULL, /* 649 */ + NULL, /* 650 */ + NULL, /* 651 */ + NULL, /* 652 */ + NULL, /* 653 */ + NULL, /* 654 */ + NULL, /* 655 */ + TclUnusedStubEntry, /* 656 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclTomMath.decls b/generic/tclTomMath.decls index dfb6956..56993f2 100644 --- a/generic/tclTomMath.decls +++ b/generic/tclTomMath.decls @@ -17,7 +17,6 @@ library tcl # Define the unsupported generic interfaces. interface tclTomMath -# hooks {tclTomMathInt} scspec EXTERN # Declare each of the functions in the Tcl tommath interface -- cgit v0.12 From a085ffdd4371ddbd3b82e0c569031cb340dac662 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 4 Mar 2021 15:53:15 +0000 Subject: In man2html, use consistant color-names (6-char, uppercase), encoding (utf-8) and translation (lf) independant from platform --- tools/tcltk-man2html-utils.tcl | 10 ++++++---- tools/tcltk-man2html.tcl | 30 +++++++++++++++++++----------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/tools/tcltk-man2html-utils.tcl b/tools/tcltk-man2html-utils.tcl index 34222e3..db94a72 100644 --- a/tools/tcltk-man2html-utils.tcl +++ b/tools/tcltk-man2html-utils.tcl @@ -130,8 +130,8 @@ proc htmlize-text {text {charmap {}}} { \" {"} \ {<} {<} \ {>} {>} \ - \u201c "“" \ - \u201d "”" + \u201C "“" \ + \u201D "”" return [string map $charmap $text] } @@ -1303,8 +1303,8 @@ proc make-manpage-section {outputDir sectionDescriptor} { global manual overall_title tcltkdesc verbose global excluded_pages forced_index_pages process_first_patterns - set LQ \u201c - set RQ \u201d + set LQ \u201C + set RQ \u201D lassign $sectionDescriptor \ manual(wing-glob) \ @@ -1314,6 +1314,7 @@ proc make-manpage-section {outputDir sectionDescriptor} { set manual(wing-copyrights) {} makedirhier $outputDir/$manual(wing-file) set manual(wing-toc-fp) [open $outputDir/$manual(wing-file)/[indexfile] w] + fconfigure $manual(wing-toc-fp) -translation lf -encoding utf-8 # whistle puts stderr "scanning section $manual(wing-name)" # put the entry for this section into the short table of contents @@ -1364,6 +1365,7 @@ proc make-manpage-section {outputDir sectionDescriptor} { continue } set manual(infp) [open $manual(page)] + fconfigure $manual(infp) -encoding utf-8 set manual(text) {} set manual(partial-text) {} foreach p {.RS .DS .CS .SO} { diff --git a/tools/tcltk-man2html.tcl b/tools/tcltk-man2html.tcl index a9327b8..5b0e4a8 100755 --- a/tools/tcltk-man2html.tcl +++ b/tools/tcltk-man2html.tcl @@ -116,7 +116,7 @@ proc parse_command_line {} { } if {$build_tcl} { - # Find Tcl. + # Find Tcl set tcldir [lindex [lsort [glob -nocomplain -tails -type d \ -directory $tcltkdir tcl$useversion]] end] if {$tcldir eq ""} { @@ -127,7 +127,7 @@ proc parse_command_line {} { } if {$build_tk} { - # Find Tk. + # Find Tk set tkdir [lindex [lsort [glob -nocomplain -tails -type d \ -directory $tcltkdir tk$useversion]] end] if {$tkdir eq ""} { @@ -168,7 +168,7 @@ proc css-style args { append style $tokens " \{" $body "\}\n" } proc css-stylesheet {} { - set hBd "1px dotted #11577b" + set hBd "1px dotted #11577B" css-style body div p th td li dd ul ol dl dt blockquote { font-family: Verdana, sans-serif; @@ -177,7 +177,7 @@ proc css-stylesheet {} { font-family: 'Courier New', Courier, monospace; } css-style pre { - background-color: #f6fcec; + background-color: #F6FCEC; border-top: 1px solid #6A6A6A; border-bottom: 1px solid #6A6A6A; padding: 1em; @@ -197,20 +197,20 @@ proc css-stylesheet {} { } css-style h1 { font-size: 18px; - color: #11577b; + color: #11577B; border-bottom: $hBd; margin-top: 0px; } css-style h2 { font-size: 14px; - color: #11577b; - background-color: #c5dce8; + color: #11577B; + background-color: #C5DCE8; padding-left: 1em; border: 1px solid #6A6A6A; } css-style h3 h4 { color: #1674A4; - background-color: #e8f2f6; + background-color: #E8F2F6; border-bottom: $hBd; border-top: $hBd; } @@ -224,16 +224,16 @@ proc css-stylesheet {} { width: 20em; float: left; padding: 2px; - border-top: 1px solid #999; + border-top: 1px solid #999999; } css-style ".keylist dt" { font-weight: bold; } css-style ".keylist dd" ".arguments dd" { margin-left: 20em; padding: 2px; - border-top: 1px solid #999; + border-top: 1px solid #999999; } css-style .copy { - background-color: #f6fcfc; + background-color: #F6FCFC; white-space: pre; font-size: 80%; border-top: 1px solid #6A6A6A; @@ -257,10 +257,12 @@ proc make-man-pages {html args} { makedirhier $html set cssfd [open $html/$::CSSFILE w] + fconfigure $cssfd -translation lf -encoding utf-8 puts $cssfd [css-stylesheet] close $cssfd set manual(short-toc-n) 1 set manual(short-toc-fp) [open $html/[indexfile] w] + fconfigure $manual(short-toc-fp) -translation lf -encoding utf-8 puts $manual(short-toc-fp) [htmlhead $overall_title $overall_title] puts $manual(short-toc-fp) "
" set manual(merge-copyrights) {} @@ -298,6 +300,7 @@ proc make-man-pages {html args} { file delete -force -- $html/Keywords makedirhier $html/Keywords set keyfp [open $html/Keywords/[indexfile] w] + fconfigure $keyfp -translation lf -encoding utf-8 puts $keyfp [htmlhead "$tcltkdesc Keywords" "$tcltkdesc Keywords" \ $overall_title "../[indexfile]"] set letters {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} @@ -321,6 +324,7 @@ proc make-man-pages {html args} { } # Per-keyword page set afp [open $html/Keywords/$a.htm w] + fconfigure $afp -translation lf -encoding utf-8 puts $afp [htmlhead "$tcltkdesc Keywords - $a" \ "$tcltkdesc Keywords - $a" \ $overall_title "../[indexfile]"] @@ -397,6 +401,7 @@ proc make-man-pages {html args} { puts -nonewline stderr . } set outfd [open $html/$manual(wing-file)/$manual(name).htm w] + fconfigure $outfd -translation lf -encoding utf-8 puts $outfd [htmlhead "$manual($manual(wing-file)-$manual(name)-title)" \ $manual(name) $wing_name "[indexfile]" \ $overall_title "../[indexfile]"] @@ -439,6 +444,7 @@ proc plus-base {var root glob name dir desc} { if {$var} { if {[file exists $tcltkdir/$root/README]} { set f [open $tcltkdir/$root/README] + fconfigure $f -encoding utf-8 set d [read $f] close $f if {[regexp {This is the \w+ (\S+) source distribution} $d -> version]} { @@ -674,6 +680,7 @@ try { } trap {POSIX ENOENT} {} { set f [open [file join $pkgsDir $dir configure.ac]] } + fconfigure $f -encoding utf-8 foreach line [split [read $f] \n] { if {2 == [scan $line \ { AC_INIT ( [%[^]]] , [%[^]]] ) } n v]} { @@ -698,6 +705,7 @@ try { set packageDirNameMap {} if {$build_tcl} { set f [open $tcltkdir/$tcldir/pkgs/package.list.txt] + fconfigure $f -encoding utf-8 try { foreach line [split [read $f] \n] { if {[string trim $line] eq ""} continue -- cgit v0.12 From a1d8e47ea7ef4acf4228052d71aa77bf788a9d15 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 6 Mar 2021 16:28:43 +0000 Subject: Document that [zipfs mkimg] strips an existing ZIP. We ought to merge instead, but we don't yet. --- doc/zipfs.n | 2 + generic/tclZipfs.c | 130 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 87 insertions(+), 45 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index da2e026..ada0d28 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -146,6 +146,8 @@ the ZIP archive, otherwise the file returned by \fBinfo nameofexecutable\fR (see \fBzipfs mkkey\fR) is placed between the image and ZIP chunks of the output file and the contents of the ZIP chunk are protected with that password. +If the starting image has a ZIP archive already attached to it, it is removed +from the copy in \fIoutfile\fR before the new ZIP archive is added. .PP If there is a file, \fBmain.tcl\fR, in the root directory of the resulting archive and the image file that the archive is attached to is a \fBtclsh\fR diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index ed3b42d..bf74823 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -360,7 +360,7 @@ static const Tcl_Filesystem zipfsFilesystem = { NULL, /* renameFileProc */ NULL, /* copyDirectoryProc */ NULL, /* lstatProc */ - (Tcl_FSLoadFileProc *)(void *)ZipFSLoadFile, + (Tcl_FSLoadFileProc *) (void *) ZipFSLoadFile, NULL, /* getCwdProc */ NULL, /* chdirProc */ }; @@ -779,7 +779,7 @@ ZipFSLookup( hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, filename); if (hPtr) { - z = (ZipEntry *)Tcl_GetHashValue(hPtr); + z = (ZipEntry *) Tcl_GetHashValue(hPtr); } return z; } @@ -867,7 +867,7 @@ ZipFSCloseArchive( #else /* !_WIN32 */ if ((zf->data != MAP_FAILED) && !zf->ptrToFree) { munmap(zf->data, zf->length); - zf->data = (unsigned char *)MAP_FAILED; + zf->data = (unsigned char *) MAP_FAILED; } #endif /* _WIN32 */ @@ -1037,7 +1037,7 @@ ZipFSOpenArchive( zf->data = NULL; zf->mountHandle = INVALID_HANDLE_VALUE; #else /* !_WIN32 */ - zf->data = (unsigned char *)MAP_FAILED; + zf->data = (unsigned char *) MAP_FAILED; #endif /* _WIN32 */ zf->length = 0; zf->numFiles = 0; @@ -1066,7 +1066,7 @@ ZipFSOpenArchive( ZIPFS_POSIX_ERROR(interp, "seek error"); goto error; } - zf->ptrToFree = zf->data = (unsigned char *)attemptckalloc(zf->length); + zf->ptrToFree = zf->data = (unsigned char *) attemptckalloc(zf->length); if (!zf->ptrToFree) { ZIPFS_ERROR(interp, "out of memory"); if (interp) { @@ -1101,8 +1101,9 @@ ZipFSOpenArchive( ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } - zf->data = (unsigned char *)MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0, - zf->length); + zf->data = (unsigned char *) + MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0, + zf->length); if (!zf->data) { ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; @@ -1197,7 +1198,7 @@ ZipFSCatalogFilesystem( hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mountPoint, &isNew); if (!isNew) { if (interp) { - zf = (ZipFile *)Tcl_GetHashValue(hPtr); + zf = (ZipFile *) Tcl_GetHashValue(hPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s is already mounted on %s", zf->name, mountPoint)); Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "MOUNTED", NULL); @@ -1206,7 +1207,7 @@ ZipFSCatalogFilesystem( ZipFSCloseArchive(interp, zf0); return TCL_ERROR; } - zf = (ZipFile *)attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); + zf = (ZipFile *) attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); if (!zf) { if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1219,11 +1220,11 @@ ZipFSCatalogFilesystem( Unlock(); *zf = *zf0; - zf->mountPoint = (char *)Tcl_GetHashKey(&ZipFS.zipHash, hPtr); + zf->mountPoint = (char *) Tcl_GetHashKey(&ZipFS.zipHash, hPtr); Tcl_CreateExitHandler(ZipfsExitHandler, zf); zf->mountPointLen = strlen(zf->mountPoint); zf->nameLength = strlen(zipname); - zf->name = (char *)ckalloc(zf->nameLength + 1); + zf->name = (char *) ckalloc(zf->nameLength + 1); memcpy(zf->name, zipname, zf->nameLength + 1); zf->entries = NULL; zf->topEnts = NULL; @@ -1242,7 +1243,7 @@ ZipFSCatalogFilesystem( if (mountPoint[0] != '\0') { hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mountPoint, &isNew); if (isNew) { - z = (ZipEntry *)ckalloc(sizeof(ZipEntry)); + z = (ZipEntry *) ckalloc(sizeof(ZipEntry)); Tcl_SetHashValue(hPtr, z); z->tnext = NULL; @@ -1256,7 +1257,7 @@ ZipFSCatalogFilesystem( z->numBytes = z->numCompressedBytes = 0; z->compressMethod = ZIP_COMPMETH_STORED; z->data = NULL; - z->name = (char *)Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; zf->entries = z; } @@ -1337,7 +1338,7 @@ ZipFSCatalogFilesystem( } Tcl_DStringSetLength(&fpBuf, 0); fullpath = CanonicalPath(mountPoint, path, &fpBuf, 1); - z = (ZipEntry *)ckalloc(sizeof(ZipEntry)); + z = (ZipEntry *) ckalloc(sizeof(ZipEntry)); z->name = NULL; z->tnext = NULL; z->depth = CountSlashes(fullpath); @@ -1369,7 +1370,7 @@ ZipFSCatalogFilesystem( ckfree(z); } else { Tcl_SetHashValue(hPtr, z); - z->name = (char *)Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; zf->entries = z; if (isdir && (mountPoint[0] == '\0') && (z->depth == 1)) { @@ -1391,7 +1392,7 @@ ZipFSCatalogFilesystem( if (!isNew) { break; } - zd = (ZipEntry *)ckalloc(sizeof(ZipEntry)); + zd = (ZipEntry *) ckalloc(sizeof(ZipEntry)); zd->name = NULL; zd->tnext = NULL; zd->depth = CountSlashes(dir); @@ -1405,7 +1406,7 @@ ZipFSCatalogFilesystem( zd->compressMethod = ZIP_COMPMETH_STORED; zd->data = NULL; Tcl_SetHashValue(hPtr, zd); - zd->name = (char *)Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + zd->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr); zd->next = zf->entries; zf->entries = zd; if ((mountPoint[0] == '\0') && (zd->depth == 1)) { @@ -1491,7 +1492,7 @@ ListMountPoints( if (!interp) { return TCL_OK; } - zf = (ZipFile *)Tcl_GetHashValue(hPtr); + zf = (ZipFile *) Tcl_GetHashValue(hPtr); Tcl_AppendElement(interp, zf->mountPoint); Tcl_AppendElement(interp, zf->name); } @@ -1528,7 +1529,7 @@ DescribeMounted( if (interp) { hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); if (hPtr) { - zf = (ZipFile *)Tcl_GetHashValue(hPtr); + zf = (ZipFile *) Tcl_GetHashValue(hPtr); Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); return TCL_OK; } @@ -1605,7 +1606,7 @@ TclZipfs_Mount( return TCL_ERROR; } } - zf = (ZipFile *)attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); + zf = (ZipFile *) attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); if (!zf) { if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1686,7 +1687,7 @@ TclZipfs_MountBuffer( * Have both a mount point and data to mount there. */ - zf = (ZipFile *)attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); + zf = (ZipFile *) attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); if (!zf) { if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1697,7 +1698,7 @@ TclZipfs_MountBuffer( zf->isMemBuffer = 1; zf->length = datalen; if (copy) { - zf->data = (unsigned char *)attemptckalloc(datalen); + zf->data = (unsigned char *) attemptckalloc(datalen); if (!zf->data) { if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1767,7 +1768,7 @@ TclZipfs_Unmount( goto done; } - zf = (ZipFile *)Tcl_GetHashValue(hPtr); + zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (zf->numOpen > 0) { ZIPFS_ERROR(interp, "filesystem is busy"); ret = TCL_ERROR; @@ -2309,7 +2310,7 @@ ZipAddFile( return TCL_ERROR; } - z = (ZipEntry *)ckalloc(sizeof(ZipEntry)); + z = (ZipEntry *) ckalloc(sizeof(ZipEntry)); Tcl_SetHashValue(hPtr, z); z->name = NULL; z->tnext = NULL; @@ -2324,7 +2325,7 @@ ZipAddFile( z->numCompressedBytes = nbytecompr; z->compressMethod = compMeth; z->data = NULL; - z->name = (char *)Tcl_GetHashKey(fileHash, hPtr); + z->name = (char *) Tcl_GetHashKey(fileHash, hPtr); z->next = NULL; /* @@ -2425,6 +2426,10 @@ ZipFSMkZipOrImgObjCmd( } else { Tcl_Obj *cmd[3]; + /* + * Discover the list of files to add. + */ + cmd[1] = Tcl_NewStringObj("::tcl::zipfs::find", -1); cmd[2] = objv[2]; cmd[0] = Tcl_NewListObj(2, cmd + 1); @@ -2463,6 +2468,13 @@ ZipFSMkZipOrImgObjCmd( pw = NULL; pwlen = 0; } + + /* + * Copy the existing contents from the image if it is an executable image. + * Care must be taken because this might include an existing ZIP, which + * needs to be stripped. + */ + if (isImg) { ZipFile *zf, zf0; int isMounted = 0; @@ -2499,7 +2511,7 @@ ZipFSMkZipOrImgObjCmd( WriteLock(); for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { - zf = (ZipFile *)Tcl_GetHashValue(hPtr); + zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (strcmp(zf->name, imgName) == 0) { isMounted = 1; zf->numOpen++; @@ -2507,10 +2519,15 @@ ZipFSMkZipOrImgObjCmd( } } Unlock(); + if (!isMounted) { zf = &zf0; } if (isMounted || ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK) { + /* + * Copy everything up to the ZIP-related suffix. + */ + if ((size_t) Tcl_Write(out, (char *) zf->data, zf->passOffset) != zf->passOffset) { memset(passBuf, 0, sizeof(passBuf)); @@ -2585,6 +2602,11 @@ ZipFSMkZipOrImgObjCmd( } Tcl_Close(interp, in); } + + /* + * Store the password so that the automounter can find it. + */ + len = strlen(passBuf); if (len > 0) { i = Tcl_Write(out, passBuf, len); @@ -2599,6 +2621,11 @@ ZipFSMkZipOrImgObjCmd( memset(passBuf, 0, sizeof(passBuf)); Tcl_Flush(out); } + + /* + * Prepare the contents of the ZIP archive. + */ + Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); pos[0] = Tcl_Tell(out); if (!isList && (objc > 3)) { @@ -2632,6 +2659,11 @@ ZipFSMkZipOrImgObjCmd( goto done; } } + + /* + * Construct the contents of the ZIP central directory. + */ + pos[1] = Tcl_Tell(out); count = 0; for (i = 0; i < (size_t) lobjc; i += (isList ? 2 : 1)) { @@ -2660,7 +2692,7 @@ ZipFSMkZipOrImgObjCmd( if (!hPtr) { continue; } - z = (ZipEntry *)Tcl_GetHashValue(hPtr); + z = (ZipEntry *) Tcl_GetHashValue(hPtr); len = strlen(z->name); ZipWriteInt(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); ZipWriteShort(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); @@ -2688,6 +2720,11 @@ ZipFSMkZipOrImgObjCmd( } count++; } + + /* + * Finalize the central directory. + */ + Tcl_Flush(out); pos[2] = Tcl_Tell(out); ZipWriteInt(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); @@ -2715,7 +2752,7 @@ ZipFSMkZipOrImgObjCmd( Tcl_DecrRefCount(list); for (hPtr = Tcl_FirstHashEntry(&fileHash, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { - z = (ZipEntry *)Tcl_GetHashValue(hPtr); + z = (ZipEntry *) Tcl_GetHashValue(hPtr); ckfree(z); Tcl_DeleteHashEntry(hPtr); } @@ -3055,7 +3092,7 @@ ZipFSListObjCmd( if (pattern) { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr); + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); if (Tcl_StringMatch(z->name, pattern)) { Tcl_ListObjAppendElement(interp, result, @@ -3065,7 +3102,7 @@ ZipFSListObjCmd( } else if (regexp) { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr); + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { Tcl_ListObjAppendElement(interp, result, @@ -3075,7 +3112,7 @@ ZipFSListObjCmd( } else { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr); + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(z->name, -1)); @@ -3235,7 +3272,7 @@ ZipChannelClose( TCL_UNUSED(Tcl_Interp *), int flags) { - ZipChannel *info = (ZipChannel *)instanceData; + ZipChannel *info = (ZipChannel *) instanceData; if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) { return EINVAL; @@ -3251,7 +3288,8 @@ ZipChannelClose( } if (info->isWriting) { ZipEntry *z = info->zipEntryPtr; - unsigned char *newdata = (unsigned char *)attemptckrealloc(info->ubuf, info->numRead); + unsigned char *newdata = (unsigned char *) + attemptckrealloc(info->ubuf, info->numRead); if (newdata) { if (z->data) { @@ -3614,7 +3652,7 @@ ZipChannelOpen( } else { flags = TCL_WRITABLE; } - info = (ZipChannel *)attemptckalloc(sizeof(ZipChannel)); + info = (ZipChannel *) attemptckalloc(sizeof(ZipChannel)); if (!info) { ZIPFS_ERROR(interp, "out of memory"); if (interp) { @@ -3632,7 +3670,7 @@ ZipChannelOpen( info->maxWrite = ZipFS.wrmax; info->iscompr = 0; info->isEncrypted = 0; - info->ubuf = (unsigned char *)attemptckalloc(info->maxWrite); + info->ubuf = (unsigned char *) attemptckalloc(info->maxWrite); if (!info->ubuf) { merror0: if (info->ubuf) { @@ -3690,7 +3728,7 @@ ZipChannelOpen( unsigned int j; stream.avail_in -= 12; - cbuf = (unsigned char *)attemptckalloc(stream.avail_in); + cbuf = (unsigned char *) attemptckalloc(stream.avail_in); if (!cbuf) { goto merror0; } @@ -3790,7 +3828,7 @@ ZipChannelOpen( stream.avail_in = z->numCompressedBytes; if (info->isEncrypted) { stream.avail_in -= 12; - ubuf = (unsigned char *)attemptckalloc(stream.avail_in); + ubuf = (unsigned char *) attemptckalloc(stream.avail_in); if (!ubuf) { info->ubuf = NULL; goto merror; @@ -3803,7 +3841,8 @@ ZipChannelOpen( } else { stream.next_in = info->ubuf; } - stream.next_out = info->ubuf = (unsigned char *)attemptckalloc(info->numBytes); + stream.next_out = info->ubuf = (unsigned char *) + attemptckalloc(info->numBytes); if (!info->ubuf) { merror: if (ubuf) { @@ -4164,7 +4203,7 @@ ZipFSMatchInDirectoryProc( } for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { - ZipFile *zf = (ZipFile *)Tcl_GetHashValue(hPtr); + ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (zf->mountPointLen == 0) { ZipEntry *z; @@ -4215,7 +4254,7 @@ ZipFSMatchInDirectoryProc( if (!pattern || (pattern[0] == '\0')) { hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); if (hPtr) { - ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr); + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); if ((dirOnly < 0) || (!dirOnly && !z->isDirectory) || (dirOnly && z->isDirectory)) { @@ -4235,7 +4274,7 @@ ZipFSMatchInDirectoryProc( } l = strlen(pattern); - pat = (char *)ckalloc(len + l + 2); + pat = (char *) ckalloc(len + l + 2); memcpy(pat, path, len); while ((len > 1) && (pat[len - 1] == '/')) { --len; @@ -4248,7 +4287,7 @@ ZipFSMatchInDirectoryProc( scnt = CountSlashes(pat); for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr); + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); if ((dirOnly >= 0) && ((dirOnly && !z->isDirectory) || (!dirOnly && z->isDirectory))) { @@ -4324,7 +4363,7 @@ ZipFSPathInFilesystemProc( for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { - ZipFile *zf = (ZipFile *)Tcl_GetHashValue(hPtr); + ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (zf->mountPointLen == 0) { ZipEntry *z; @@ -4636,7 +4675,8 @@ ZipFSLoadFile( Tcl_DecrRefCount(objs[1]); } - loadFileProc = (Tcl_FSLoadFileProc2 *)(void *)tclNativeFilesystem.loadFileProc; + loadFileProc = (Tcl_FSLoadFileProc2 *) (void *) + tclNativeFilesystem.loadFileProc; if (loadFileProc) { ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } else { @@ -4792,7 +4832,7 @@ static void ZipfsExitHandler( ClientData clientData) { - ZipFile *zf = (ZipFile *)clientData; + ZipFile *zf = (ZipFile *) clientData; if (TCL_OK != TclZipfs_Unmount(NULL, zf->mountPoint)) { Tcl_Panic("tried to unmount busy filesystem"); -- cgit v0.12 From b9bc37e2b8d6b0ee9fa2839ad1a37f42266d417d Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 7 Mar 2021 18:42:27 +0000 Subject: Added some tests for [zipfs lmkimg] --- doc/zipfs.n | 2 +- generic/tclZipfs.c | 14 +++---- tests/zipfs.test | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 8 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index ada0d28..a75a70b 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -84,7 +84,7 @@ Return a list of all files in the mounted zipfs, or just those matching \fIpattern\fR (optionally controlled by the option parameters). The order of the names in the list is arbitrary. .TP -\fBzipfs mount ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR? +\fBzipfs mount\fR ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR? . The \fBzipfs mount\fR command mounts a ZIP archive file as a Tcl virtual filesystem at \fImountpoint\fR. After this command executes, files contained diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index bf74823..d1d5deb 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -2424,21 +2424,21 @@ ZipFSMkZipOrImgObjCmd( list = objv[2]; Tcl_IncrRefCount(list); } else { - Tcl_Obj *cmd[3]; + Tcl_Obj *cmd[2]; + int result; /* * Discover the list of files to add. */ - cmd[1] = Tcl_NewStringObj("::tcl::zipfs::find", -1); - cmd[2] = objv[2]; - cmd[0] = Tcl_NewListObj(2, cmd + 1); + cmd[0] = Tcl_NewStringObj("::tcl::zipfs::find", -1); + cmd[1] = objv[2]; Tcl_IncrRefCount(cmd[0]); - if (Tcl_EvalObjEx(interp, cmd[0], TCL_EVAL_DIRECT) != TCL_OK) { - Tcl_DecrRefCount(cmd[0]); + result = Tcl_EvalObjv(interp, 2, cmd, 0); + Tcl_DecrRefCount(cmd[0]); + if (result != TCL_OK) { return TCL_ERROR; } - Tcl_DecrRefCount(cmd[0]); list = Tcl_GetObjResult(interp); Tcl_IncrRefCount(list); } diff --git a/tests/zipfs.test b/tests/zipfs.test index 8689268..3c11895 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -270,6 +270,116 @@ test zipfs-3.4 {zipfs in child interpreters} -constraints zipfs -setup { } -returnCodes error -cleanup { interp delete $safe } -result {not allowed to invoke subcommand mkzip of zipfs} + +test zipfs-4.1 {zipfs lmkimg} -constraints zipfs -setup { + set baseImage [makeFile "return sourceWorking\n\x1a" base] + set targetImage [makeFile "" target] + set addFile [makeFile "return mountWorking" add.data] + file delete $targetImage +} -body { + zipfs lmkimg $targetImage [list $addFile test/add.tcl] {} $baseImage + zipfs mount ziptest $targetImage + try { + list [source $targetImage] [source //zipfs:/ziptest/test/add.tcl] + } finally { + zipfs unmount ziptest + } +} -cleanup { + removeFile $baseImage + removeFile $targetImage + removeFile $addFile +} -result {sourceWorking mountWorking} +test zipfs-4.2 {zipfs lmkimg: making an image from an image} -constraints zipfs -setup { + set baseImage [makeFile "return sourceWorking\n\x1a" base_image.tcl] + set midImage [makeFile "" mid_image.tcl] + set targetImage [makeFile "" target_image.tcl] + set addFile [makeFile "return mountWorking" add.data] + file delete $midImage $targetImage +} -body { + zipfs lmkimg $midImage [list $addFile test/ko.tcl] {} $baseImage + zipfs lmkimg $targetImage [list $addFile test/ok.tcl] {} $midImage + zipfs mount ziptest $targetImage + try { + list [glob -tails -directory //zipfs://ziptest/test *.tcl] \ + [if {[file size $midImage] == [file size $targetImage]} { + string cat equal + } else { + list mid=[file size $midImage] target=[file size $targetImage] + }] + } finally { + zipfs unmount ziptest + } +} -cleanup { + removeFile $baseImage + removeFile $midImage + removeFile $targetImage + removeFile $addFile +} -result {ok.tcl equal} +test zipfs-4.3 {zipfs lmkimg: stripping password} -constraints zipfs -setup { + set baseImage [makeFile "return sourceWorking\n\x1a" base_image.tcl] + set midImage [makeFile "" mid_image.tcl] + set targetImage [makeFile "" target_image.tcl] + set addFile [makeFile "return mountWorking" add.data] + file delete $midImage $targetImage +} -body { + set pass gorp + zipfs lmkimg $midImage [list $addFile test/add.tcl] $pass $baseImage + zipfs lmkimg $targetImage [list $addFile test/ok.tcl] {} $midImage + zipfs mount ziptest $targetImage + try { + glob -tails -directory //zipfs://ziptest/test *.tcl + } finally { + zipfs unmount ziptest + } +} -cleanup { + removeFile $baseImage + removeFile $midImage + removeFile $targetImage + removeFile $addFile +} -result {ok.tcl} +test zipfs-4.4 {zipfs lmkimg: final password} -constraints zipfs -setup { + set baseImage [makeFile "return sourceWorking\n\x1a" base_image.tcl] + set midImage [makeFile "" mid_image.tcl] + set targetImage [makeFile "" target_image.tcl] + set addFile [makeFile "return mountWorking" add.data] + file delete $midImage $targetImage +} -body { + set pass gorp + zipfs lmkimg $midImage [list $addFile test/add.tcl] {} $baseImage + zipfs lmkimg $targetImage [list $addFile test/ok.tcl] $pass $midImage + zipfs mount ziptest $targetImage + try { + glob -tails -directory //zipfs://ziptest/test *.tcl + } finally { + zipfs unmount ziptest + } +} -cleanup { + removeFile $baseImage + removeFile $midImage + removeFile $targetImage + removeFile $addFile +} -result {ok.tcl} +test zipfs-4.5 {zipfs lmkimg: making image from mounted} -constraints zipfs -setup { + set baseImage [makeFile "return sourceWorking\n\x1a" base_image.tcl] + set midImage [makeFile "" mid_image.tcl] + set targetImage [makeFile "" target_image.tcl] + set addFile [makeFile "return mountWorking" add.data] + file delete $midImage $targetImage +} -body { + zipfs lmkimg $midImage [list $addFile test/add.tcl] {} $baseImage + zipfs mount ziptest $midImage + set f [glob -directory //zipfs://ziptest/test *.tcl] + zipfs lmkimg $targetImage [list $f test/ok.tcl] {} $midImage + zipfs unmount ziptest + zipfs mount ziptest $targetImage + list $f [glob -directory //zipfs://ziptest/test *.tcl] +} -cleanup { + zipfs unmount ziptest + removeFile $baseImage + removeFile $midImage + removeFile $targetImage + removeFile $addFile +} -result {//zipfs://ziptest/test/add.tcl //zipfs://ziptest/test/ok.tcl} ::tcltest::cleanupTests return -- cgit v0.12 From 25bbbbf3ee5102d8fd13884456e828e6dacd4b5b Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 8 Mar 2021 16:53:51 +0000 Subject: Fix SEGV in zipfs mounting, and try to make that code more comprehensible --- generic/tclZipfs.c | 699 ++++++++++++++++++++++++++++++++++++++--------------- tests/zipfs.test | 4 + unix/Makefile.in | 3 + 3 files changed, 511 insertions(+), 195 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index d1d5deb..b7571b7 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -138,7 +138,8 @@ } while (0) /* - * Macros to read and write 16 and 32 bit integers from/to ZIP archives. + * Macros to read and write little-endial 16 and 32 bit integers from/to ZIP + * archives. */ #define ZipReadInt(p) \ @@ -282,9 +283,19 @@ static const char *zipfs_literal_tcl_library = NULL; /* Function prototypes */ +static int CopyImageFile(Tcl_Interp *interp, const char *imgName, + Tcl_Channel out); static inline int DescribeMounted(Tcl_Interp *interp, const char *mountPoint); static inline int ListMountPoints(Tcl_Interp *interp); +static void SerializeCentralDirectoryEntry(char *buf, ZipEntry *z, + size_t nameLength, long long dataStartOffset); +static void SerializeCentralDirectorySuffix(char *buf, + int entryCount, long long dataStartOffset, + long long directoryStartOffset, + long long suffixStartOffset); +static void SerializeLocalEntryHeader(char *buf, ZipEntry *z, + int nameLength, int align); #if !defined(STATIC_BUILD) static int ZipfsAppHookFindTclInit(const char *archive); #endif @@ -309,6 +320,8 @@ static int ZipFSFileAttrsSetProc(Tcl_Interp *interp, int index, static int ZipFSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); +static int ZipMapArchive(Tcl_Interp *interp, ZipFile *zf, + void *handle); static void ZipfsExitHandler(ClientData clientData); static void ZipfsSetup(void); static int ZipChannelClose(void *instanceData, @@ -320,8 +333,8 @@ static int ZipChannelRead(void *instanceData, char *buf, static int ZipChannelSeek(void *instanceData, long offset, int mode, int *errloc); #endif -static long long ZipChannelWideSeek(void *instanceData, long long offset, - int mode, int *errloc); +static long long ZipChannelWideSeek(void *instanceData, + long long offset, int mode, int *errloc); static void ZipChannelWatchChannel(void *instanceData, int mask); static int ZipChannelWrite(void *instanceData, @@ -824,6 +837,43 @@ ZipFSLookupMount( /* *------------------------------------------------------------------------- * + * AllocateZipFile -- + * + * Allocates the memory for a ZipFile structure. Always ensures that it + * is zeroed out for safety. + * + * Returns: + * The allocated structure, or NULL if allocate fails. + * + * Side effects: + * The interpreter result may be written to on error. Which might fail in + * a low-memory situation. + * + *------------------------------------------------------------------------- + */ + +static ZipFile * +AllocateZipFile( + Tcl_Interp *interp, + size_t mountPointNameLength) +{ + size_t size = sizeof(ZipFile) + mountPointNameLength + 1; + ZipFile *zf = (ZipFile *) attemptckalloc(size); + + if (!zf) { + if (interp) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); + } + } else { + memset(zf, 0, size); + } + return zf; +} + +/* + *------------------------------------------------------------------------- + * * ZipFSCloseArchive -- * * This function closes a mounted ZIP archive file. @@ -856,6 +906,10 @@ ZipFSCloseArchive( return; } + /* + * Remove the memory mapping, if we have one. + */ + #ifdef _WIN32 if (zf->data && !zf->ptrToFree) { UnmapViewOfFile(zf->data); @@ -888,7 +942,7 @@ ZipFSCloseArchive( * * This function takes a memory mapped zip file and indexes the contents. * When "needZip" is zero an embedded ZIP archive in an executable file - * is accepted. + * is accepted. Note that we do not support ZIP64. * * Results: * TCL_OK on success, TCL_ERROR otherwise with an error message placed @@ -910,6 +964,12 @@ ZipFSFindTOC( size_t i; unsigned char *p, *q; + /* + * Scan backwards from the end of the file for the signature. This is + * necessary because ZIP archives aren't the only things that get tagged + * on the end of executables; digital signatures can also go there. + */ + p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; while (p >= zf->data) { if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { @@ -922,6 +982,11 @@ ZipFSFindTOC( } } if (p < zf->data) { + /* + * Didn't find it (or not enough space for a central directory!); not + * a ZIP archive. This might be OK or a problem. + */ + if (!needZip) { zf->baseOffset = zf->passOffset = zf->length; return TCL_OK; @@ -932,6 +997,11 @@ ZipFSFindTOC( } goto error; } + + /* + * How many files in the archive? If that's bogus, we're done here. + */ + zf->numFiles = ZipReadShort(p + ZIP_CENTRAL_ENTS_OFFS); if (zf->numFiles == 0) { if (!needZip) { @@ -944,6 +1014,11 @@ ZipFSFindTOC( } goto error; } + + /* + * Where does the central directory start? + */ + q = zf->data + ZipReadInt(p + ZIP_CENTRAL_DIRSTART_OFFS); p -= ZipReadInt(p + ZIP_CENTRAL_DIRSIZE_OFFS); if ((p < zf->data) || (p > zf->data + zf->length) @@ -958,6 +1033,11 @@ ZipFSFindTOC( } goto error; } + + /* + * Read the central directory. + */ + zf->baseOffset = zf->passOffset = p - q; zf->directoryOffset = p - zf->data; q = p; @@ -983,6 +1063,12 @@ ZipFSFindTOC( extra = ZipReadShort(q + ZIP_CENTRAL_EXTRALEN_OFFS); q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } + + /* + * If there's also an encoded password, extract that too (but don't decode + * yet). + */ + q = zf->data + zf->baseOffset; if ((zf->baseOffset >= 6) && (ZipReadInt(q - 4) == ZIP_PASSWORD_END_SIG)) { i = q[-5]; @@ -1044,11 +1130,35 @@ ZipFSOpenArchive( zf->baseOffset = zf->passOffset = 0; zf->ptrToFree = NULL; zf->passBuf[0] = 0; + + /* + * Actually open the file. + */ + zf->chan = Tcl_OpenFileChannel(interp, zipname, "rb", 0); if (!zf->chan) { return TCL_ERROR; } - if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { + + /* + * See if we can get the OS handle. If we can, we can use that to memory + * map the file, which is nice and efficient. However, it totally depends + * on the filename pointing to a real regular OS file. + * + * Opening real filesystem entities that are not files will lead to an + * error. + */ + + if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) == TCL_OK) { + if (ZipMapArchive(interp, zf, handle) != TCL_OK) { + goto error; + } + } else { + /* + * Not an OS file, but rather something in a Tcl VFS. Must copy into + * memory. + */ + zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); if (zf->length == ERROR_LENGTH) { ZIPFS_POSIX_ERROR(interp, "seek error"); @@ -1081,53 +1191,93 @@ ZipFSOpenArchive( } Tcl_Close(interp, zf->chan); zf->chan = NULL; - } else { + } + return ZipFSFindTOC(interp, needZip, zf); + + /* + * Handle errors by closing the archive. This includes closing the channel + * handle for the archive file. + */ + + error: + ZipFSCloseArchive(interp, zf); + return TCL_ERROR; +} + +/* + *------------------------------------------------------------------------- + * + * ZipMapArchive -- + * + * Wrapper around the platform-specific parts of mmap() (and Windows's + * equivalent) because it's not part of the standard channel API. + * + *------------------------------------------------------------------------- + */ + +static int +ZipMapArchive( + Tcl_Interp *interp, /* Interpreter for error reporting. */ + ZipFile *zf, /* The archive descriptor structure. */ + void *handle) /* The OS handle to the open archive. */ +{ #ifdef _WIN32 - int readSuccessful; + HANDLE hFile = (HANDLE) handle; + int readSuccessful; + + /* + * Determine the file size. + */ + # ifdef _WIN64 - i = GetFileSizeEx((HANDLE) handle, (PLARGE_INTEGER) &zf->length); - readSuccessful = (i != 0); + readSuccessful = GetFileSizeEx(hFile, (PLARGE_INTEGER) &zf->length) != 0; # else /* !_WIN64 */ - zf->length = GetFileSize((HANDLE) handle, 0); - readSuccessful = (zf->length != (size_t) INVALID_FILE_SIZE); + zf->length = GetFileSize(hFile, 0); + readSuccessful = (zf->length != (size_t) INVALID_FILE_SIZE); # endif /* _WIN64 */ - if (!readSuccessful || (zf->length < ZIP_CENTRAL_END_LEN)) { - ZIPFS_POSIX_ERROR(interp, "invalid file size"); - goto error; - } - zf->mountHandle = CreateFileMappingW((HANDLE) handle, 0, PAGE_READONLY, - 0, zf->length, 0); - if (zf->mountHandle == INVALID_HANDLE_VALUE) { - ZIPFS_POSIX_ERROR(interp, "file mapping failed"); - goto error; - } - zf->data = (unsigned char *) - MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0, - zf->length); - if (!zf->data) { - ZIPFS_POSIX_ERROR(interp, "file mapping failed"); - goto error; - } + if (!readSuccessful || (zf->length < ZIP_CENTRAL_END_LEN)) { + ZIPFS_POSIX_ERROR(interp, "invalid file size"); + return TCL_ERROR; + } + + /* + * Map the file. + */ + + zf->mountHandle = CreateFileMappingW(hFile, 0, PAGE_READONLY, 0, + zf->length, 0); + if (zf->mountHandle == INVALID_HANDLE_VALUE) { + ZIPFS_POSIX_ERROR(interp, "file mapping failed"); + return TCL_ERROR; + } + zf->data = (unsigned char *) + MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0, zf->length); + if (!zf->data) { + ZIPFS_POSIX_ERROR(interp, "file mapping failed"); + return TCL_ERROR; + } #else /* !_WIN32 */ - zf->length = lseek(PTR2INT(handle), 0, SEEK_END); - if (zf->length == ERROR_LENGTH || zf->length < ZIP_CENTRAL_END_LEN) { - ZIPFS_POSIX_ERROR(interp, "invalid file size"); - goto error; - } - lseek(PTR2INT(handle), 0, SEEK_SET); - zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, - MAP_FILE | MAP_PRIVATE, PTR2INT(handle), 0); - if (zf->data == MAP_FAILED) { - ZIPFS_POSIX_ERROR(interp, "file mapping failed"); - goto error; - } -#endif /* _WIN32 */ + int fd = PTR2INT(handle); + + /* + * Determine the file size. + */ + + zf->length = lseek(fd, 0, SEEK_END); + if (zf->length == ERROR_LENGTH || zf->length < ZIP_CENTRAL_END_LEN) { + ZIPFS_POSIX_ERROR(interp, "invalid file size"); + return TCL_ERROR; } - return ZipFSFindTOC(interp, needZip, zf); + lseek(fd, 0, SEEK_SET); - error: - ZipFSCloseArchive(interp, zf); - return TCL_ERROR; + zf->data = (unsigned char *) + mmap(0, zf->length, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); + if (zf->data == MAP_FAILED) { + ZIPFS_POSIX_ERROR(interp, "file mapping failed"); + return TCL_ERROR; + } +#endif /* _WIN32 */ + return TCL_OK; } /* @@ -1150,7 +1300,7 @@ ZipFSOpenArchive( static int ZipFSCatalogFilesystem( Tcl_Interp *interp, /* Current interpreter. NULLable. */ - ZipFile *zf0, + ZipFile *zf0, /* Temporary buffer hold archive descriptors */ const char *mountPoint, /* Mount point path. */ const char *passwd, /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ @@ -1181,6 +1331,20 @@ ZipFSCatalogFilesystem( } } + /* + * Validate the TOC data. If that's bad, things fall apart. + */ + + if (zf0->baseOffset < 0 || zf0->baseOffset >= zf0->length || + zf0->passOffset < 0 || zf0->passOffset >= zf0->length || + zf0->directoryOffset < 0 || zf0->directoryOffset >= zf0->length) { + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("bad zip data", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_ZIP", NULL); + } + return TCL_ERROR; + } + WriteLock(); /* @@ -1207,18 +1371,18 @@ ZipFSCatalogFilesystem( ZipFSCloseArchive(interp, zf0); return TCL_ERROR; } - zf = (ZipFile *) attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); + zf = AllocateZipFile(interp, strlen(mountPoint)); if (!zf) { - if (interp) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); - } Unlock(); ZipFSCloseArchive(interp, zf0); return TCL_ERROR; } Unlock(); + /* + * Convert to a real archive descriptor. + */ + *zf = *zf0; zf->mountPoint = (char *) Tcl_GetHashKey(&ZipFS.zipHash, hPtr); Tcl_CreateExitHandler(ZipfsExitHandler, zf); @@ -1559,7 +1723,8 @@ int TclZipfs_Mount( Tcl_Interp *interp, /* Current interpreter. NULLable. */ const char *mountPoint, /* Mount point path. */ - const char *zipname, /* Path to ZIP file to mount. */ + const char *zipname, /* Path to ZIP file to mount; should be + * normalized. */ const char *passwd) /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ { @@ -1606,12 +1771,8 @@ TclZipfs_Mount( return TCL_ERROR; } } - zf = (ZipFile *) attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); + zf = AllocateZipFile(interp, strlen(mountPoint)); if (!zf) { - if (interp) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); - } return TCL_ERROR; } if (ZipFSOpenArchive(interp, zipname, 1, zf) != TCL_OK) { @@ -1687,12 +1848,8 @@ TclZipfs_MountBuffer( * Have both a mount point and data to mount there. */ - zf = (ZipFile *) attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); + zf = AllocateZipFile(interp, strlen(mountPoint)); if (!zf) { - if (interp) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); - } return TCL_ERROR; } zf->isMemBuffer = 1; @@ -1821,16 +1978,38 @@ ZipFSMountObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { + const char *mountPoint = NULL, *zipFile = NULL, *password = NULL; + Tcl_Obj *zipFileObj = NULL; + int result; if (objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "?mountpoint? ?zipfile? ?password?"); return TCL_ERROR; } + if (objc > 1) { + mountPoint = Tcl_GetString(objv[1]); + } + if (objc > 2) { + zipFileObj = Tcl_FSGetNormalizedPath(interp, objv[2]); + if (!zipFileObj) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "could not normalize zip filename", -1)); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NORMALIZE", NULL); + return TCL_ERROR; + } + Tcl_IncrRefCount(zipFileObj); + zipFile = Tcl_GetString(zipFileObj); + } + if (objc > 3) { + password = Tcl_GetString(objv[3]); + } - return TclZipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, - (objc > 2) ? Tcl_GetString(objv[2]) : NULL, - (objc > 3) ? Tcl_GetString(objv[3]) : NULL); + result = TclZipfs_Mount(interp, mountPoint, zipFile, password); + if (zipFileObj != NULL) { + Tcl_DecrRefCount(zipFileObj); + } + return result; } /* @@ -2043,7 +2222,7 @@ ZipAddFile( const char *zpath; int crc, flush, zpathlen; size_t nbyte, nbytecompr, len, olen, align = 0; - long long pos[3]; + long long headerStartOffset, dataStartOffset, dataEndOffset; int mtime = 0, isNew, compMeth; unsigned long keys[3], keys0[3]; char obuf[4096]; @@ -2116,7 +2295,7 @@ ZipAddFile( Tcl_Close(interp, in); return TCL_ERROR; } - pos[0] = Tcl_Tell(out); + headerStartOffset = Tcl_Tell(out); memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); len = zpathlen + ZIP_LOCAL_HEADER_LEN; @@ -2127,7 +2306,7 @@ ZipAddFile( Tcl_Close(interp, in); return TCL_ERROR; } - if ((len + pos[0]) & 3) { + if ((len + headerStartOffset) & 3) { unsigned char abuf[8]; /* @@ -2135,7 +2314,7 @@ ZipAddFile( * similar to the zipalign tool from Android's SDK. */ - align = 4 + ((len + pos[0]) & 3); + align = 4 + ((len + headerStartOffset) & 3); ZipWriteShort(abuf, 0xffff); ZipWriteShort(abuf + 2, align - 4); ZipWriteInt(abuf + 4, 0x03020100); @@ -2193,7 +2372,7 @@ ZipAddFile( nbytecompr += 12; } Tcl_Flush(out); - pos[2] = Tcl_Tell(out); + dataStartOffset = Tcl_Tell(out); compMeth = ZIP_COMPMETH_DEFLATED; memset(&stream, 0, sizeof(z_stream)); stream.zalloc = Z_NULL; @@ -2252,15 +2431,16 @@ ZipAddFile( } while (flush != Z_FINISH); deflateEnd(&stream); Tcl_Flush(out); - pos[1] = Tcl_Tell(out); + dataEndOffset = Tcl_Tell(out); if (nbyte - nbytecompr <= 0) { /* * Compressed file larger than input, write it again uncompressed. */ + if (Tcl_Seek(in, 0, SEEK_SET) != 0) { goto seekErr; } - if (Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { + if (Tcl_Seek(out, dataStartOffset, SEEK_SET) != dataStartOffset) { seekErr: Tcl_Close(interp, in); Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2297,8 +2477,8 @@ ZipAddFile( } compMeth = ZIP_COMPMETH_STORED; Tcl_Flush(out); - pos[1] = Tcl_Tell(out); - Tcl_TruncateChannel(out, pos[1]); + dataEndOffset = Tcl_Tell(out); + Tcl_TruncateChannel(out, dataEndOffset); } Tcl_Close(interp, in); @@ -2318,7 +2498,7 @@ ZipAddFile( z->zipFilePtr = NULL; z->isDirectory = 0; z->isEncrypted = (passwd ? 1 : 0); - z->offset = pos[0]; + z->offset = headerStartOffset; z->crc32 = crc; z->timestamp = mtime; z->numBytes = nbyte; @@ -2331,18 +2511,9 @@ ZipAddFile( /* * Write final local header information. */ - ZipWriteInt(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); - ZipWriteShort(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_LOCAL_FLAGS_OFFS, z->isEncrypted); - ZipWriteShort(buf + ZIP_LOCAL_COMPMETH_OFFS, z->compressMethod); - ZipWriteShort(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); - ZipWriteShort(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); - ZipWriteInt(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); - ZipWriteInt(buf + ZIP_LOCAL_COMPLEN_OFFS, z->numCompressedBytes); - ZipWriteInt(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->numBytes); - ZipWriteShort(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); - ZipWriteShort(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); - if (Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { + + SerializeLocalEntryHeader(buf, z, zpathlen, align); + if (Tcl_Seek(out, headerStartOffset, SEEK_SET) != headerStartOffset) { Tcl_DeleteHashEntry(hPtr); ckfree(z); Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2357,7 +2528,7 @@ ZipAddFile( return TCL_ERROR; } Tcl_Flush(out); - if (Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { + if (Tcl_Seek(out, dataEndOffset, SEEK_SET) != dataEndOffset) { Tcl_DeleteHashEntry(hPtr); ckfree(z); Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2390,15 +2561,25 @@ static int ZipFSMkZipOrImgObjCmd( Tcl_Interp *interp, /* Current interpreter. */ int isImg, - int isList, - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ + Tcl_Obj *targetFile, + Tcl_Obj *dirRoot, + Tcl_Obj *mappingList, + Tcl_Obj *originFile, + Tcl_Obj *stripPrefix, + Tcl_Obj *passwordObj) { Tcl_Channel out; - int pwlen = 0, count, ret = TCL_ERROR, lobjc; - size_t len, slen = 0, i = 0; - long long pos[3]; - Tcl_Obj **lobjv, *list = NULL; + int pwlen = 0, slen = 0, count, ret = TCL_ERROR, lobjc; + size_t len, i = 0; + long long dataStartOffset; /* The overall file offset of the start of the + * data section of the file. */ + long long directoryStartOffset; + /* The overall file offset of the start of the + * central directory. */ + long long suffixStartOffset;/* The overall file offset of the start of the + * suffix of the central directory (i.e., + * where this data will be written). */ + Tcl_Obj **lobjv, *list = mappingList; ZipEntry *z; Tcl_HashEntry *hPtr; Tcl_HashSearch search; @@ -2410,9 +2591,8 @@ ZipFSMkZipOrImgObjCmd( */ passBuf[0] = 0; - if (objc > (isList ? 3 : 4)) { - pw = Tcl_GetString(objv[isList ? 3 : 4]); - pwlen = strlen(pw); + if (passwordObj != NULL) { + pw = Tcl_GetStringFromObj(passwordObj, &pwlen); if ((pwlen > 255) || strchr(pw, 0xff)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); @@ -2420,10 +2600,7 @@ ZipFSMkZipOrImgObjCmd( return TCL_ERROR; } } - if (isList) { - list = objv[2]; - Tcl_IncrRefCount(list); - } else { + if (dirRoot != NULL) { Tcl_Obj *cmd[2]; int result; @@ -2432,7 +2609,7 @@ ZipFSMkZipOrImgObjCmd( */ cmd[0] = Tcl_NewStringObj("::tcl::zipfs::find", -1); - cmd[1] = objv[2]; + cmd[1] = dirRoot; Tcl_IncrRefCount(cmd[0]); result = Tcl_EvalObjv(interp, 2, cmd, 0); Tcl_DecrRefCount(cmd[0]); @@ -2440,13 +2617,13 @@ ZipFSMkZipOrImgObjCmd( return TCL_ERROR; } list = Tcl_GetObjResult(interp); - Tcl_IncrRefCount(list); } + Tcl_IncrRefCount(list); if (Tcl_ListObjGetElements(interp, list, &lobjc, &lobjv) != TCL_OK) { Tcl_DecrRefCount(list); return TCL_ERROR; } - if (isList && (lobjc % 2)) { + if (mappingList && (lobjc % 2)) { Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_NewStringObj("need even number of elements", -1)); @@ -2459,7 +2636,7 @@ ZipFSMkZipOrImgObjCmd( Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "EMPTY", NULL); return TCL_ERROR; } - out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "wb", 0755); + out = Tcl_OpenFileChannel(interp, Tcl_GetString(targetFile), "wb", 0755); if (out == NULL) { Tcl_DecrRefCount(list); return TCL_ERROR; @@ -2480,13 +2657,9 @@ ZipFSMkZipOrImgObjCmd( int isMounted = 0; const char *imgName; - if (isList) { - imgName = (objc > 4) ? Tcl_GetString(objv[4]) : - Tcl_GetNameOfExecutable(); - } else { - imgName = (objc > 5) ? Tcl_GetString(objv[5]) : - Tcl_GetNameOfExecutable(); - } + // TODO: normalize the origin file name + imgName = (originFile != NULL) ? Tcl_GetString(originFile) : + Tcl_GetNameOfExecutable(); if (pwlen) { i = 0; for (len = pwlen; len-- > 0;) { @@ -2552,55 +2725,17 @@ ZipFSMkZipOrImgObjCmd( Unlock(); } } else { - size_t k; - int m, n; - Tcl_Channel in; - const char *errMsg = "seek error"; - /* * Fall back to read it as plain file which hopefully is a static * tclsh or wish binary with proper zipfs infrastructure built in. */ - Tcl_ResetResult(interp); - in = Tcl_OpenFileChannel(interp, imgName, "rb", 0644); - if (!in) { + if (CopyImageFile(interp, imgName, out) != TCL_OK) { memset(passBuf, 0, sizeof(passBuf)); Tcl_DecrRefCount(list); Tcl_Close(interp, out); return TCL_ERROR; } - i = Tcl_Seek(in, 0, SEEK_END); - if (i == ERROR_LENGTH) { - cperr: - memset(passBuf, 0, sizeof(passBuf)); - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "%s: %s", errMsg, Tcl_PosixError(interp))); - Tcl_Close(interp, out); - Tcl_Close(interp, in); - return TCL_ERROR; - } - Tcl_Seek(in, 0, SEEK_SET); - for (k = 0; k < i; k += m) { - m = i - k; - if (m > (int) sizeof(buf)) { - m = (int) sizeof(buf); - } - n = Tcl_Read(in, buf, m); - if (n == -1) { - errMsg = "read error"; - goto cperr; - } else if (n == 0) { - break; - } - m = Tcl_Write(out, buf, n); - if (m != n) { - errMsg = "write error"; - goto cperr; - } - } - Tcl_Close(interp, in); } /* @@ -2627,22 +2762,22 @@ ZipFSMkZipOrImgObjCmd( */ Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); - pos[0] = Tcl_Tell(out); - if (!isList && (objc > 3)) { - strip = Tcl_GetString(objv[3]); - slen = strlen(strip); + dataStartOffset = Tcl_Tell(out); + if (mappingList == NULL && stripPrefix != NULL) { + strip = Tcl_GetStringFromObj(stripPrefix, &slen); } - for (i = 0; i < (size_t) lobjc; i += (isList ? 2 : 1)) { + for (i = 0; i < (size_t) lobjc; i += (mappingList ? 2 : 1)) { const char *path, *name; path = Tcl_GetString(lobjv[i]); - if (isList) { + if (mappingList) { name = Tcl_GetString(lobjv[i + 1]); } else { name = path; if (slen > 0) { len = strlen(name); - if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + if ((len <= (size_t) slen) || + (strncmp(strip, name, slen) != 0)) { continue; } name += slen; @@ -2664,19 +2799,20 @@ ZipFSMkZipOrImgObjCmd( * Construct the contents of the ZIP central directory. */ - pos[1] = Tcl_Tell(out); + directoryStartOffset = Tcl_Tell(out); count = 0; - for (i = 0; i < (size_t) lobjc; i += (isList ? 2 : 1)) { + for (i = 0; i < (size_t) lobjc; i += (mappingList ? 2 : 1)) { const char *path, *name; path = Tcl_GetString(lobjv[i]); - if (isList) { + if (mappingList) { name = Tcl_GetString(lobjv[i + 1]); } else { name = path; if (slen > 0) { len = strlen(name); - if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + if ((len <= (size_t) slen) || + (strncmp(strip, name, slen) != 0)) { continue; } name += slen; @@ -2694,25 +2830,9 @@ ZipFSMkZipOrImgObjCmd( } z = (ZipEntry *) Tcl_GetHashValue(hPtr); len = strlen(z->name); - ZipWriteInt(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); - ZipWriteShort(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isEncrypted); - ZipWriteShort(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->compressMethod); - ZipWriteShort(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); - ZipWriteShort(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); - ZipWriteInt(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); - ZipWriteInt(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->numCompressedBytes); - ZipWriteInt(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->numBytes); - ZipWriteShort(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); - ZipWriteShort(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_IATTR_OFFS, 0); - ZipWriteInt(buf + ZIP_CENTRAL_EATTR_OFFS, 0); - ZipWriteInt(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); - if ((Tcl_Write(out, buf, - ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) + SerializeCentralDirectoryEntry(buf, z, len, dataStartOffset); + if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) + != ZIP_CENTRAL_HEADER_LEN) || ((size_t) Tcl_Write(out, z->name, len) != len)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); @@ -2726,15 +2846,9 @@ ZipFSMkZipOrImgObjCmd( */ Tcl_Flush(out); - pos[2] = Tcl_Tell(out); - ZipWriteInt(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); - ZipWriteShort(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_ENTS_OFFS, count); - ZipWriteShort(buf + ZIP_CENTRAL_TOTALENTS_OFFS, count); - ZipWriteInt(buf + ZIP_CENTRAL_DIRSIZE_OFFS, pos[2] - pos[1]); - ZipWriteInt(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); - ZipWriteShort(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); + suffixStartOffset = Tcl_Tell(out); + SerializeCentralDirectorySuffix(buf, count, dataStartOffset, + directoryStartOffset, suffixStartOffset); if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); @@ -2761,6 +2875,177 @@ ZipFSMkZipOrImgObjCmd( } /* + * --------------------------------------------------------------------- + * + * CopyImageFile -- + * + * A simple file copy function that is used (by ZipFSMkZipOrImgObjCmd) + * for anything that is not an image with a ZIP appended. + * + * Returns: + * A Tcl result code. + * + * Side effects: + * Writes to an output channel. + * + * --------------------------------------------------------------------- + */ + +static int +CopyImageFile( + Tcl_Interp *interp, /* For error reporting. */ + const char *imgName, /* Where to copy from. */ + Tcl_Channel out) /* Where to copy to; already open for writing + * binary data. */ +{ + size_t i, k; + int m, n; + Tcl_Channel in; + char buf[4096]; + const char *errMsg; + + Tcl_ResetResult(interp); + in = Tcl_OpenFileChannel(interp, imgName, "rb", 0644); + if (!in) { + return TCL_ERROR; + } + + /* + * Get the length of the file (and exclude non-files). + */ + + i = Tcl_Seek(in, 0, SEEK_END); + if (i == ERROR_LENGTH) { + errMsg = "seek error"; + goto copyError; + } + Tcl_Seek(in, 0, SEEK_SET); + + /* + * Copy the whole file, 8 blocks at a time (reasonably efficient). Note + * that this totally ignores things like Windows's Alternate File Streams. + */ + + for (k = 0; k < i; k += m) { + m = i - k; + if (m > (int) sizeof(buf)) { + m = (int) sizeof(buf); + } + n = Tcl_Read(in, buf, m); + if (n == -1) { + errMsg = "read error"; + goto copyError; + } else if (n == 0) { + break; + } + m = Tcl_Write(out, buf, n); + if (m != n) { + errMsg = "write error"; + goto copyError; + } + } + Tcl_Close(interp, in); + return TCL_OK; + + copyError: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s: %s", errMsg, Tcl_PosixError(interp))); + Tcl_Close(interp, in); + return TCL_ERROR; +} + +/* + * --------------------------------------------------------------------- + * + * SerializeLocalEntryHeader, SerializeCentralDirectoryEntry, + * SerializeCentralDirectorySuffix -- + * + * Create serialized forms of the structures that make up the ZIP + * metadata. Note that the both the local entry and the central directory + * entry need to have the name of the entry written directly afterwards. + * + * We could write these as structs except we need to guarantee that we + * are writing these out as little-endian values. + * + * Side effects: + * Both update their buffer arguments, but otherwise change nothing. + * + * --------------------------------------------------------------------- + */ + +static void +SerializeLocalEntryHeader( + char *buf, /* Where to serialize to */ + ZipEntry *z, /* The description of what to serialize. */ + int nameLength, /* The length of the name. */ + int align) /* The number of alignment bytes. */ +{ + ZipWriteInt(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); + ZipWriteShort(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(buf + ZIP_LOCAL_FLAGS_OFFS, z->isEncrypted); + ZipWriteShort(buf + ZIP_LOCAL_COMPMETH_OFFS, z->compressMethod); + ZipWriteShort(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); + ZipWriteShort(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); + ZipWriteInt(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); + ZipWriteInt(buf + ZIP_LOCAL_COMPLEN_OFFS, z->numCompressedBytes); + ZipWriteInt(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->numBytes); + ZipWriteShort(buf + ZIP_LOCAL_PATHLEN_OFFS, nameLength); + ZipWriteShort(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); +} + +static void +SerializeCentralDirectoryEntry( + char *buf, /* Where to serialize to */ + ZipEntry *z, /* The description of what to serialize. */ + size_t nameLength, /* The length of the name. */ + long long dataStartOffset) /* The overall file offset of the start of the + * data section of the file. */ +{ + ZipWriteInt(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); + ZipWriteShort(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isEncrypted); + ZipWriteShort(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->compressMethod); + ZipWriteShort(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); + ZipWriteShort(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); + ZipWriteInt(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); + ZipWriteInt(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->numCompressedBytes); + ZipWriteInt(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->numBytes); + ZipWriteShort(buf + ZIP_CENTRAL_PATHLEN_OFFS, nameLength); + ZipWriteShort(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_IATTR_OFFS, 0); + ZipWriteInt(buf + ZIP_CENTRAL_EATTR_OFFS, 0); + ZipWriteInt(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - dataStartOffset); +} + +static void +SerializeCentralDirectorySuffix( + char *buf, /* Where to serialize to */ + int entryCount, /* The number of entries in the directory */ + long long dataStartOffset, /* The overall file offset of the start of the + * data section of the file. */ + long long directoryStartOffset, + /* The overall file offset of the start of the + * central directory. */ + long long suffixStartOffset)/* The overall file offset of the start of the + * suffix of the central directory (i.e., + * where this data will be written). */ +{ + ZipWriteInt(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); + ZipWriteShort(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_ENTS_OFFS, entryCount); + ZipWriteShort(buf + ZIP_CENTRAL_TOTALENTS_OFFS, entryCount); + ZipWriteInt(buf + ZIP_CENTRAL_DIRSIZE_OFFS, + suffixStartOffset - directoryStartOffset); + ZipWriteInt(buf + ZIP_CENTRAL_DIRSTART_OFFS, + directoryStartOffset - dataStartOffset); + ZipWriteShort(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); +} + +/* *------------------------------------------------------------------------- * * ZipFSMkZipObjCmd, ZipFSLMkZipObjCmd -- @@ -2784,6 +3069,8 @@ ZipFSMkZipObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { + Tcl_Obj *stripPrefix, *password; + if (objc < 3 || objc > 5) { Tcl_WrongNumArgs(interp, 1, objv, "outfile indir ?strip? ?password?"); return TCL_ERROR; @@ -2794,7 +3081,11 @@ ZipFSMkZipObjCmd( Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); return TCL_ERROR; } - return ZipFSMkZipOrImgObjCmd(interp, 0, 0, objc, objv); + + stripPrefix = (objc > 3 ? objv[3] : NULL); + password = (objc > 4 ? objv[4] : NULL); + return ZipFSMkZipOrImgObjCmd(interp, 0, objv[1], objv[2], NULL, NULL, + stripPrefix, password); } static int @@ -2804,6 +3095,8 @@ ZipFSLMkZipObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { + Tcl_Obj *password; + if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password?"); return TCL_ERROR; @@ -2814,7 +3107,10 @@ ZipFSLMkZipObjCmd( Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); return TCL_ERROR; } - return ZipFSMkZipOrImgObjCmd(interp, 0, 1, objc, objv); + + password = (objc > 3 ? objv[3] : NULL); + return ZipFSMkZipOrImgObjCmd(interp, 0, objv[1], NULL, objv[2], NULL, + NULL, password); } /* @@ -2841,6 +3137,8 @@ ZipFSMkImgObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { + Tcl_Obj *originFile, *stripPrefix, *password; + if (objc < 3 || objc > 6) { Tcl_WrongNumArgs(interp, 1, objv, "outfile indir ?strip? ?password? ?infile?"); @@ -2852,7 +3150,12 @@ ZipFSMkImgObjCmd( Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); return TCL_ERROR; } - return ZipFSMkZipOrImgObjCmd(interp, 1, 0, objc, objv); + + originFile = (objc > 5 ? objv[5] : NULL); + stripPrefix = (objc > 3 ? objv[3] : NULL); + password = (objc > 4 ? objv[4] : NULL); + return ZipFSMkZipOrImgObjCmd(interp, 1, objv[1], objv[2], NULL, + originFile, stripPrefix, password); } static int @@ -2862,6 +3165,8 @@ ZipFSLMkImgObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { + Tcl_Obj *originFile, *password; + if (objc < 3 || objc > 5) { Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password infile?"); return TCL_ERROR; @@ -2872,7 +3177,11 @@ ZipFSLMkImgObjCmd( Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); return TCL_ERROR; } - return ZipFSMkZipOrImgObjCmd(interp, 1, 1, objc, objv); + + originFile = (objc > 4 ? objv[4] : NULL); + password = (objc > 3 ? objv[3] : NULL); + return ZipFSMkZipOrImgObjCmd(interp, 1, objv[1], NULL, objv[2], + originFile, NULL, password); } /* diff --git a/tests/zipfs.test b/tests/zipfs.test index 3c11895..36fc6d6 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -380,6 +380,10 @@ test zipfs-4.5 {zipfs lmkimg: making image from mounted} -constraints zipfs -set removeFile $targetImage removeFile $addFile } -result {//zipfs://ziptest/test/add.tcl //zipfs://ziptest/test/ok.tcl} + +test zipfs-5.1 {zipfs mount_data: short data} -body { + zipfs mount_data gorp {} +} -constraints zipfs -returnCodes error -result {bad zip data} ::tcltest::cleanupTests return diff --git a/unix/Makefile.in b/unix/Makefile.in index f885f5a..30e2104 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -945,6 +945,9 @@ shell: ${TCL_EXE} gdb: ${TCL_EXE} $(SHELL_ENV) $(GDB) ./${TCL_EXE} +lldb: ${TCL_EXE} + $(SHELL_ENV) $(LLDB) ./${TCL_EXE} + valgrind: ${TCL_EXE} ${TCLTEST_EXE} $(SHELL_ENV) $(VALGRIND) $(VALGRINDARGS) ./${TCLTEST_EXE} \ $(TOP_DIR)/tests/all.tcl -singleproc 1 -constraints valgrind \ -- cgit v0.12 From 3b584dd13f75df5189437493efabbd778b627520 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Mar 2021 08:36:11 +0000 Subject: Remove end-of-line spacing --- tools/tcltk-man2html-utils.tcl | 2 +- tools/tcltk-man2html.tcl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/tcltk-man2html-utils.tcl b/tools/tcltk-man2html-utils.tcl index db94a72..bdd6065 100644 --- a/tools/tcltk-man2html-utils.tcl +++ b/tools/tcltk-man2html-utils.tcl @@ -1365,7 +1365,7 @@ proc make-manpage-section {outputDir sectionDescriptor} { continue } set manual(infp) [open $manual(page)] - fconfigure $manual(infp) -encoding utf-8 + fconfigure $manual(infp) -encoding utf-8 set manual(text) {} set manual(partial-text) {} foreach p {.RS .DS .CS .SO} { diff --git a/tools/tcltk-man2html.tcl b/tools/tcltk-man2html.tcl index 5b0e4a8..236a49f 100755 --- a/tools/tcltk-man2html.tcl +++ b/tools/tcltk-man2html.tcl @@ -680,7 +680,7 @@ try { } trap {POSIX ENOENT} {} { set f [open [file join $pkgsDir $dir configure.ac]] } - fconfigure $f -encoding utf-8 + fconfigure $f -encoding utf-8 foreach line [split [read $f] \n] { if {2 == [scan $line \ { AC_INIT ( [%[^]]] , [%[^]]] ) } n v]} { @@ -705,7 +705,7 @@ try { set packageDirNameMap {} if {$build_tcl} { set f [open $tcltkdir/$tcldir/pkgs/package.list.txt] - fconfigure $f -encoding utf-8 + fconfigure $f -encoding utf-8 try { foreach line [split [read $f] \n] { if {[string trim $line] eq ""} continue -- cgit v0.12 From 8aca3246abd4f40476a6f99fce4ee021703a71e7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Mar 2021 09:14:04 +0000 Subject: Fix [8419c55e2c]: Tclsh read loop does not handle EINTR --- unix/tclUnixChan.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index fc01616..b49dde7 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -253,12 +253,15 @@ FileInputProc( * nonblocking, the read will never block. */ - bytesRead = read(fsPtr->fd, buf, (size_t) toRead); - if (bytesRead > -1) { - return bytesRead; + do { + bytesRead = read(fsPtr->fd, buf, (size_t) toRead); + } while ((bytesRead < 0) && (errno == EINTR)); + + if (bytesRead < 0) { + *errorCodePtr = errno; + return -1; } - *errorCodePtr = errno; - return -1; + return bytesRead; } /* -- cgit v0.12 From a2b56f4c74eeed4f6c3e8f3a25317fa4cf2b5ed6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Mar 2021 15:28:40 +0000 Subject: TclWinConvertError -> Tcl_WinConvertError --- generic/tclIntPlatDecls.h | 2 +- unix/tclUnixFCmd.c | 2 +- win/tclWinChan.c | 24 ++++++++++++------------ win/tclWinConsole.c | 16 ++++++++-------- win/tclWinFCmd.c | 30 +++++++++++++++--------------- win/tclWinFile.c | 46 +++++++++++++++++++++++----------------------- win/tclWinLoad.c | 4 ++-- win/tclWinPipe.c | 32 ++++++++++++++++---------------- win/tclWinSerial.c | 22 +++++++++++----------- win/tclWinSock.c | 36 ++++++++++++++++++------------------ 10 files changed, 107 insertions(+), 107 deletions(-) diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index 60907ca..25edfd8 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -571,7 +571,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; #undef TclWinConvertWSAError #undef TclWinConvertError #if !defined(TCL_USE_STUBS) && !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 -# define TclWinConvertWSAError TclWinConvertError +# define TclWinConvertWSAError Tcl_WinConvertError # define TclWinConvertError Tcl_WinConvertError #endif diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c index 4d08c1d..9e9a493 100644 --- a/unix/tclUnixFCmd.c +++ b/unix/tclUnixFCmd.c @@ -2350,7 +2350,7 @@ StatError( Tcl_Obj *fileName) /* The name of the file which caused the * error. */ { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } diff --git a/win/tclWinChan.c b/win/tclWinChan.c index a4ec1ae..62991fc 100644 --- a/win/tclWinChan.c +++ b/win/tclWinChan.c @@ -421,7 +421,7 @@ FileCloseProc( && (GetStdHandle(STD_OUTPUT_HANDLE) != fileInfoPtr->handle) && (GetStdHandle(STD_ERROR_HANDLE) != fileInfoPtr->handle))) { if (CloseHandle(fileInfoPtr->handle) == FALSE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); errorCode = errno; } } @@ -497,7 +497,7 @@ FileSeekProc( DWORD winError = GetLastError(); if (winError != NO_ERROR) { - TclWinConvertError(winError); + Tcl_WinConvertError(winError); *errorCodePtr = errno; return -1; } @@ -509,7 +509,7 @@ FileSeekProc( DWORD winError = GetLastError(); if (winError != NO_ERROR) { - TclWinConvertError(winError); + Tcl_WinConvertError(winError); *errorCodePtr = errno; return -1; } @@ -573,7 +573,7 @@ FileWideSeekProc( DWORD winError = GetLastError(); if (winError != NO_ERROR) { - TclWinConvertError(winError); + Tcl_WinConvertError(winError); *errorCodePtr = errno; return -1; } @@ -616,7 +616,7 @@ FileTruncateProc( DWORD winError = GetLastError(); if (winError != NO_ERROR) { - TclWinConvertError(winError); + Tcl_WinConvertError(winError); return errno; } } @@ -632,7 +632,7 @@ FileTruncateProc( DWORD winError = GetLastError(); if (winError != NO_ERROR) { - TclWinConvertError(winError); + Tcl_WinConvertError(winError); return errno; } } @@ -643,7 +643,7 @@ FileTruncateProc( */ if (!SetEndOfFile(infoPtr->handle)) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return errno; } @@ -703,7 +703,7 @@ FileInputProc( return bytesRead; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); *errorCode = errno; if (errno == EPIPE) { return 0; @@ -752,7 +752,7 @@ FileOutputProc( if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite, &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); *errorCode = errno; return -1; } @@ -927,7 +927,7 @@ TclpOpenFileChannel( if (NativeIsComPort(nativeName)) { handle = TclWinSerialOpen(INVALID_HANDLE_VALUE, nativeName, accessMode); if (handle == INVALID_HANDLE_VALUE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open serial \"%s\": %s", @@ -984,7 +984,7 @@ TclpOpenFileChannel( err = TEST_FLAG(mode, O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND; } - TclWinConvertError(err); + Tcl_WinConvertError(err); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open \"%s\": %s", @@ -1008,7 +1008,7 @@ TclpOpenFileChannel( handle = TclWinSerialOpen(handle, nativeName, accessMode); if (handle == INVALID_HANDLE_VALUE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't reopen serial \"%s\": %s", diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 0556646..c3ba814 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -602,7 +602,7 @@ ConsoleCloseProc( && (GetStdHandle(STD_OUTPUT_HANDLE) != consolePtr->handle) && (GetStdHandle(STD_ERROR_HANDLE) != consolePtr->handle))) { if (CloseHandle(consolePtr->handle) == FALSE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); errorCode = errno; } } @@ -772,7 +772,7 @@ ConsoleOutputProc( */ if (infoPtr->writeError) { - TclWinConvertError(infoPtr->writeError); + Tcl_WinConvertError(infoPtr->writeError); infoPtr->writeError = 0; goto error; } @@ -807,7 +807,7 @@ ConsoleOutputProc( if (WriteConsoleBytes(infoPtr->handle, buf, (DWORD) toWrite, &bytesWritten) == FALSE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); goto error; } } @@ -1065,7 +1065,7 @@ WaitForRead( * Check to see if the peek failed because of EOF. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (errno == EOF) { infoPtr->readFlags |= CONSOLE_EOF; @@ -1477,7 +1477,7 @@ ConsoleSetOptionProc( DWORD mode; if (GetConsoleMode(infoPtr->handle, &mode) == 0) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read console mode: %s", @@ -1509,7 +1509,7 @@ ConsoleSetOptionProc( return TCL_ERROR; } if (SetConsoleMode(infoPtr->handle, mode) == 0) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't set console mode: %s", @@ -1589,7 +1589,7 @@ ConsoleGetOptionProc( valid = 1; if (GetConsoleMode(infoPtr->handle, &mode) == 0) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read console mode: %s", @@ -1620,7 +1620,7 @@ ConsoleGetOptionProc( valid = 1; if (!GetConsoleScreenBufferInfo(infoPtr->handle, &consoleInfo)) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read console size: %s", diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c index c88621c..3f6d7f4 100644 --- a/win/tclWinFCmd.c +++ b/win/tclWinFCmd.c @@ -279,7 +279,7 @@ DoRenameFile( return retval; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); srcAttr = GetFileAttributesW(nativeSrc); dstAttr = GetFileAttributesW(nativeDst); @@ -420,7 +420,7 @@ DoRenameFile( * be, but report this one. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); CreateDirectoryW(nativeDst, NULL); SetFileAttributesW(nativeDst, dstAttr); if (Tcl_GetErrno() == EACCES) { @@ -488,7 +488,7 @@ DoRenameFile( * error. Could happen if an open file refers to dst. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (Tcl_GetErrno() == EACCES) { /* * Decode the EACCES to a more meaningful error. @@ -669,7 +669,7 @@ DoCopyFile( return retval; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (Tcl_GetErrno() == EBADF) { Tcl_SetErrno(EACCES); return TCL_ERROR; @@ -706,7 +706,7 @@ DoCopyFile( * attributes of dst. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); SetFileAttributesW(nativeDst, dstAttr); } } @@ -766,7 +766,7 @@ TclpDeleteFile( if (DeleteFileW(path) != FALSE) { return TCL_OK; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (Tcl_GetErrno() == EACCES) { attr = GetFileAttributesW(path); @@ -797,7 +797,7 @@ TclpDeleteFile( (DeleteFileW(path) != FALSE)) { return TCL_OK; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (res != 0) { SetFileAttributesW(path, attr); } @@ -866,7 +866,7 @@ DoCreateDirectory( if (CreateDirectoryW(nativePath, NULL) == 0) { DWORD error = GetLastError(); - TclWinConvertError(error); + Tcl_WinConvertError(error); return TCL_ERROR; } return TCL_OK; @@ -1054,7 +1054,7 @@ DoRemoveJustDirectory( } } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (Tcl_GetErrno() == EACCES) { attr = GetFileAttributesW(nativePath); @@ -1088,7 +1088,7 @@ DoRemoveJustDirectory( if (RemoveDirectoryW(nativePath) != FALSE) { return TCL_OK; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); SetFileAttributesW(nativePath, attr | FILE_ATTRIBUTE_READONLY); } @@ -1235,7 +1235,7 @@ TraverseWinTree( * Can't read directory. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); nativeErrfile = nativeSource; goto end; } @@ -1329,7 +1329,7 @@ TraverseWinTree( end: if (nativeErrfile != NULL) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (errorPtr != NULL) { Tcl_DStringInit(errorPtr); Tcl_WCharToUtfDString(nativeErrfile, -1, errorPtr); @@ -1384,7 +1384,7 @@ TraversalCopy( attr) != FALSE) { return TCL_OK; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); } break; case DOTREE_POSTD: @@ -1482,7 +1482,7 @@ StatError( Tcl_Obj *fileName) /* The name of the file which caused the * error. */ { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } @@ -2067,7 +2067,7 @@ TclpCreateTemporaryDirectory( */ if (error != ERROR_SUCCESS) { - TclWinConvertError(error); + Tcl_WinConvertError(error); Tcl_DStringFree(&base); return NULL; } diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 1e0aca7..b02dc84 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -209,7 +209,7 @@ WinLink( * Invalid file. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return -1; } @@ -233,7 +233,7 @@ WinLink( * Invalid file. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return -1; } @@ -247,7 +247,7 @@ WinLink( * The target doesn't exist. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { /* * It is a file. @@ -262,7 +262,7 @@ WinLink( return 0; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); } else if (linkAction & TCL_CREATE_SYMBOLIC_LINK) { if (CreateSymbolicLinkW(linkSourcePath, linkTargetPath, 0x2 /* SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE */)) { @@ -272,7 +272,7 @@ WinLink( return 0; } else { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); } } else { Tcl_SetErrno(ENODEV); @@ -327,7 +327,7 @@ WinReadLink( * Invalid file. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return NULL; } @@ -341,7 +341,7 @@ WinReadLink( * The source doesn't exist. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return NULL; } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { @@ -502,7 +502,7 @@ TclWinSymLinkDelete( * Error setting junction. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); CloseHandle(hFile); } else { CloseHandle(hFile); @@ -695,7 +695,7 @@ NativeReadReparse( * Error creating directory. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return -1; } @@ -709,7 +709,7 @@ NativeReadReparse( * Error setting junction. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); CloseHandle(hFile); return -1; } @@ -751,7 +751,7 @@ NativeWriteReparse( * Error creating directory. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return -1; } hFile = CreateFileW(linkDirPath, GENERIC_WRITE, 0, NULL, @@ -762,7 +762,7 @@ NativeWriteReparse( * Error creating directory. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return -1; } @@ -777,7 +777,7 @@ NativeWriteReparse( * Error setting junction. */ - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); CloseHandle(hFile); RemoveDirectoryW(linkDirPath); return -1; @@ -1057,7 +1057,7 @@ TclpMatchInDirectory( return TCL_OK; } - TclWinConvertError(err); + Tcl_WinConvertError(err); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read directory \"%s\": %s", @@ -1606,7 +1606,7 @@ NativeAccess( DWORD lasterror = GetLastError(); if (lasterror != ERROR_SHARING_VIOLATION) { - TclWinConvertError(lasterror); + Tcl_WinConvertError(lasterror); return -1; } } @@ -1732,7 +1732,7 @@ NativeAccess( * to EACCES - just what we want! */ - TclWinConvertError((DWORD) error); + Tcl_WinConvertError((DWORD) error); return -1; } @@ -1837,7 +1837,7 @@ NativeAccess( */ accessError: - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (sdPtr != NULL) { HeapFree(GetProcessHeap(), 0, sdPtr); } @@ -1932,7 +1932,7 @@ TclpObjChdir( result = SetCurrentDirectoryW(nativePath); if (result == 0) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return -1; } return 0; @@ -1971,7 +1971,7 @@ TclpGetCwd( WCHAR *native; if (GetCurrentDirectoryW(MAX_PATH, buffer) == 0) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error getting working directory name: %s", @@ -2136,12 +2136,12 @@ NativeStat( DWORD lasterror = GetLastError(); if (lasterror != ERROR_SHARING_VIOLATION) { - TclWinConvertError(lasterror); + Tcl_WinConvertError(lasterror); return -1; } hFind = FindFirstFileW(nativePath, &ffd); if (hFind == INVALID_HANDLE_VALUE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return -1; } memcpy(&data, &ffd, sizeof(data)); @@ -2370,7 +2370,7 @@ TclpGetNativeCwd( WCHAR buffer[MAX_PATH]; if (GetCurrentDirectoryW(MAX_PATH, buffer) == 0) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return NULL; } @@ -3271,7 +3271,7 @@ TclpUtime( if (fileHandle == INVALID_HANDLE_VALUE || !SetFileTime(fileHandle, NULL, &lastAccessTime, &lastModTime)) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); res = -1; } if (fileHandle != INVALID_HANDLE_VALUE) { diff --git a/win/tclWinLoad.c b/win/tclWinLoad.c index 656148a..0f664f0 100644 --- a/win/tclWinLoad.c +++ b/win/tclWinLoad.c @@ -159,7 +159,7 @@ TclpDlopen( Tcl_AppendToObj(errMsg, "Bad exe format. Possibly a 32/64-bit mismatch.", -1); break; default: - TclWinConvertError(lastError); + Tcl_WinConvertError(lastError); Tcl_AppendToObj(errMsg, Tcl_PosixError(interp), -1); } Tcl_SetObjResult(interp, errMsg); @@ -379,7 +379,7 @@ InitDLLDirectoryName(void) id *= 16777619; } - TclWinConvertError(lastError); + Tcl_WinConvertError(lastError); return TCL_ERROR; /* diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 90ac9ef..29b1c03 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -549,7 +549,7 @@ TclpOpenFile( accessMode = (GENERIC_READ | GENERIC_WRITE); break; default: - TclWinConvertError(ERROR_INVALID_FUNCTION); + Tcl_WinConvertError(ERROR_INVALID_FUNCTION); return NULL; } @@ -613,7 +613,7 @@ TclpOpenFile( if ((err & 0xFFFFL) == ERROR_OPEN_FAILED) { err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND; } - TclWinConvertError(err); + Tcl_WinConvertError(err); return NULL; } @@ -719,7 +719,7 @@ TclpCreateTempFile( Tcl_DStringFree(&dstring); } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); CloseHandle(handle); DeleteFileW(name); return NULL; @@ -784,7 +784,7 @@ TclpCreatePipe( return 1; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return 0; } @@ -825,7 +825,7 @@ TclpCloseFile( && (GetStdHandle(STD_ERROR_HANDLE) != filePtr->handle))) { if (filePtr->handle != NULL && CloseHandle(filePtr->handle) == FALSE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); ckfree(filePtr); return -1; } @@ -1026,7 +1026,7 @@ TclpCreateProcess( 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdInput == INVALID_HANDLE_VALUE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't duplicate input handle: %s", Tcl_PosixError(interp))); @@ -1055,7 +1055,7 @@ TclpCreateProcess( &startInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't duplicate output handle: %s", Tcl_PosixError(interp))); @@ -1075,7 +1075,7 @@ TclpCreateProcess( 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdError == INVALID_HANDLE_VALUE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't duplicate error handle: %s", Tcl_PosixError(interp))); @@ -1137,7 +1137,7 @@ TclpCreateProcess( if (CreateProcessW(NULL, (WCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE, (DWORD) createFlags, NULL, NULL, &startInfo, &procInfo) == 0) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s", argv[0], Tcl_PosixError(interp))); goto end; @@ -1387,7 +1387,7 @@ ApplicationType( Tcl_DStringFree(&nameBuf); if (applType == APPL_NONE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s", originalName, Tcl_PosixError(interp))); return APPL_NONE; @@ -1866,7 +1866,7 @@ Tcl_CreatePipe( sec.bInheritHandle = FALSE; if (!CreatePipe(&readHandle, &writeHandle, &sec, 0)) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "pipe creation failed: %s", Tcl_PosixError(interp))); return TCL_ERROR; @@ -2224,7 +2224,7 @@ PipeInputProc( return bytesRead; } - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); if (errno == EPIPE) { infoPtr->readFlags |= PIPE_EOF; return 0; @@ -2283,7 +2283,7 @@ PipeOutputProc( */ if (infoPtr->writeError) { - TclWinConvertError(infoPtr->writeError); + Tcl_WinConvertError(infoPtr->writeError); infoPtr->writeError = 0; goto error; } @@ -2318,7 +2318,7 @@ PipeOutputProc( if (WriteFile(filePtr->handle, (LPVOID) buf, (DWORD) toWrite, &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); goto error; } } @@ -2850,7 +2850,7 @@ WaitForRead( if (PeekNamedPipe(handle, (LPVOID) NULL, (DWORD) 0, (LPDWORD) NULL, &count, (LPDWORD) NULL) != TRUE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); /* * Check to see if the peek failed because of EOF. @@ -3260,7 +3260,7 @@ TclpOpenTemporaryFile( TCL_READABLE|TCL_WRITABLE); gotError: - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); return NULL; } diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c index 32f4c31..403c9d5 100644 --- a/win/tclWinSerial.c +++ b/win/tclWinSerial.c @@ -645,7 +645,7 @@ SerialCloseProc( && (GetStdHandle(STD_OUTPUT_HANDLE) != serialPtr->handle) && (GetStdHandle(STD_ERROR_HANDLE) != serialPtr->handle))) { if (CloseHandle(serialPtr->handle) == FALSE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); errorCode = errno; } } @@ -928,7 +928,7 @@ SerialInputProc( if (SerialBlockingRead(infoPtr, (LPVOID) buf, (DWORD) bufSize, &bytesRead, &infoPtr->osRead) == FALSE) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); *errorCode = errno; return -1; } @@ -1010,7 +1010,7 @@ SerialOutputProc( */ if (infoPtr->writeError) { - TclWinConvertError(infoPtr->writeError); + Tcl_WinConvertError(infoPtr->writeError); infoPtr->writeError = 0; goto error1; } @@ -1069,7 +1069,7 @@ SerialOutputProc( return (int) bytesWritten; writeError: - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); error: /* @@ -1936,7 +1936,7 @@ SerialSetOptionProc( if (!SetupComm(infoPtr->handle, inSize, outSize)) { if (interp != NULL) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't setup comm buffers: %s", Tcl_PosixError(interp))); @@ -1987,7 +1987,7 @@ SerialSetOptionProc( tout.ReadTotalTimeoutConstant = msec; if (!SetCommTimeouts(infoPtr->handle, &tout)) { if (interp != NULL) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't set comm timeouts: %s", Tcl_PosixError(interp))); @@ -2004,7 +2004,7 @@ SerialSetOptionProc( getStateFailed: if (interp != NULL) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get comm state: %s", Tcl_PosixError(interp))); } @@ -2012,7 +2012,7 @@ SerialSetOptionProc( setStateFailed: if (interp != NULL) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't set comm state: %s", Tcl_PosixError(interp))); } @@ -2095,7 +2095,7 @@ SerialGetOptionProc( if (!GetCommState(infoPtr->handle, &dcb)) { if (interp != NULL) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get comm state: %s", Tcl_PosixError(interp))); } @@ -2165,7 +2165,7 @@ SerialGetOptionProc( if (!GetCommState(infoPtr->handle, &dcb)) { if (interp != NULL) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get comm state: %s", Tcl_PosixError(interp))); } @@ -2243,7 +2243,7 @@ SerialGetOptionProc( if (!GetCommModemStatus(infoPtr->handle, &status)) { if (interp != NULL) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get tty status: %s", Tcl_PosixError(interp))); } diff --git a/win/tclWinSock.c b/win/tclWinSock.c index a31e1a2..60575df 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -882,7 +882,7 @@ TcpInputProc( if (GOT_BITS(statePtr->flags, TCP_NONBLOCKING) || (error != WSAEWOULDBLOCK)) { - TclWinConvertError(error); + Tcl_WinConvertError(error); *errorCodePtr = Tcl_GetErrno(); bytesRead = -1; break; @@ -996,7 +996,7 @@ TcpOutputProc( break; } } else { - TclWinConvertError(error); + Tcl_WinConvertError(error); *errorCodePtr = Tcl_GetErrno(); written = -1; break; @@ -1064,7 +1064,7 @@ TcpCloseProc( statePtr->sockets = thisfd->next; if (closesocket(thisfd->fd) == SOCKET_ERROR) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); } ckfree(thisfd); @@ -1154,11 +1154,11 @@ TcpClose2Proc( */ if ((flags & TCL_CLOSE_READ) && (shutdown(statePtr->sockets->fd, SD_RECEIVE) == SOCKET_ERROR)) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); readError = Tcl_GetErrno(); } if ((flags & TCL_CLOSE_WRITE) && (shutdown(statePtr->sockets->fd, SD_SEND) == SOCKET_ERROR)) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); writeError = Tcl_GetErrno(); } return (readError != 0) ? readError : writeError; @@ -1225,7 +1225,7 @@ TcpSetOptionProc( rtn = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const char *) &val, sizeof(BOOL)); if (rtn != 0) { - TclWinConvertError(WSAGetLastError()); + Tcl_WinConvertError(WSAGetLastError()); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't set socket option: %s", @@ -1247,7 +1247,7 @@ TcpSetOptionProc( rtn = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *) &val, sizeof(BOOL)); if (rtn != 0) { - TclWinConvertError(WSAGetLastError()); + Tcl_WinConvertError(WSAGetLastError()); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't set socket option: %s", @@ -1382,7 +1382,7 @@ TcpGetOptionProc( */ if (err) { - TclWinConvertError(err); + Tcl_WinConvertError(err); Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1); } @@ -1452,7 +1452,7 @@ TcpGetOptionProc( */ if (len) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get peername: %s", @@ -1528,7 +1528,7 @@ TcpGetOptionProc( Tcl_DStringEndSublist(dsPtr); } else { if (interp) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't get sockname: %s", Tcl_PosixError(interp))); } @@ -1780,7 +1780,7 @@ TcpConnect( */ if (statePtr->sockets->fd == INVALID_SOCKET) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); continue; } @@ -1805,7 +1805,7 @@ TcpConnect( if (bind(statePtr->sockets->fd, statePtr->myaddr->ai_addr, statePtr->myaddr->ai_addrlen) == SOCKET_ERROR) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); continue; } @@ -1876,7 +1876,7 @@ TcpConnect( statePtr->addr->ai_addrlen); error = WSAGetLastError(); - TclWinConvertError(error); + Tcl_WinConvertError(error); if (async_connect && error == WSAEWOULDBLOCK) { /* @@ -1908,7 +1908,7 @@ TcpConnect( * Get signaled connect error. */ - TclWinConvertError((DWORD) statePtr->notifierConnectError); + Tcl_WinConvertError((DWORD) statePtr->notifierConnectError); /* * Clear eventual connect flag. @@ -2237,7 +2237,7 @@ Tcl_OpenTcpServerEx( sock = socket(addrPtr->ai_family, addrPtr->ai_socktype, addrPtr->ai_protocol); if (sock == INVALID_SOCKET) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); continue; } @@ -2288,7 +2288,7 @@ Tcl_OpenTcpServerEx( if (bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen) == SOCKET_ERROR) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); closesocket(sock); continue; } @@ -2313,7 +2313,7 @@ Tcl_OpenTcpServerEx( */ if (listen(sock, SOMAXCONN) == SOCKET_ERROR) { - TclWinConvertError((DWORD) WSAGetLastError()); + Tcl_WinConvertError((DWORD) WSAGetLastError()); closesocket(sock); continue; } @@ -2498,7 +2498,7 @@ InitSockets(void) windowClass.hCursor = NULL; if (!RegisterClassW(&windowClass)) { - TclWinConvertError(GetLastError()); + Tcl_WinConvertError(GetLastError()); goto initFailure; } } -- cgit v0.12 From 50b24193def55fb992f0acfb7ef1cdb326bb5323 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Mar 2021 15:38:06 +0000 Subject: Compatibility tweak wrt 8.6 --- generic/tclIntPlatDecls.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index 25edfd8..bd8d8e5 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -569,9 +569,9 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; #undef TclpLocaltime_unix #undef TclpGmtime_unix #undef TclWinConvertWSAError -#undef TclWinConvertError +#define TclWinConvertWSAError TclWinConvertError #if !defined(TCL_USE_STUBS) && !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 -# define TclWinConvertWSAError Tcl_WinConvertError +# undef TclWinConvertError # define TclWinConvertError Tcl_WinConvertError #endif -- cgit v0.12 From 3cbac4bb5be49ca8f19243442343db01c08bb733 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 10 Mar 2021 07:51:34 +0000 Subject: Move internal stub entry 260 to 259, the same place it is in 8.7. --- generic/tclInt.decls | 16 +++++++++------- generic/tclIntDecls.h | 19 ++++++++----------- generic/tclStubInit.c | 5 ++--- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/generic/tclInt.decls b/generic/tclInt.decls index d7ea540..eb18fd8 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -468,6 +468,7 @@ declare 232 { declare 233 { void TclGetSrcInfoForPc(CmdFrame *contextPtr) } + # Exports for VarReform compat: Itcl, XOTcl like to peek into our varTables :( declare 234 { Var *TclVarHashCreateVar(TclVarHashTable *tablePtr, const char *key, @@ -476,10 +477,17 @@ declare 234 { declare 235 { void TclInitVarHashTable(TclVarHashTable *tablePtr, Namespace *nsPtr) } +# TIP 542 +declare 236 { + void TclAppendUnicodeToObj(Tcl_Obj *objPtr, + const Tcl_UniChar *unicode, size_t length) +} + # TIP #285: Script cancellation support. declare 237 { int TclResetCancellation(Tcl_Interp *interp, int force) } + # NRE functions for "rogue" extensions to exploit NRE; they will need to # include NRE.h too. declare 238 { @@ -568,7 +576,6 @@ declare 256 { int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags) } - declare 257 { void TclStaticPackage(Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) @@ -579,13 +586,8 @@ declare 258 { Tcl_Obj *TclpCreateTemporaryDirectory(Tcl_Obj *dirObj, Tcl_Obj *basenameObj) } -# TIP 542 -declare 259 { - void TclAppendUnicodeToObj(Tcl_Obj *objPtr, - const Tcl_UniChar *unicode, size_t length) -} -declare 260 { +declare 259 { unsigned char *TclGetBytesFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, size_t *lengthPtr) } diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index 23cf3e6..fc0a9a3 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -501,7 +501,9 @@ EXTERN Var * TclVarHashCreateVar(TclVarHashTable *tablePtr, /* 235 */ EXTERN void TclInitVarHashTable(TclVarHashTable *tablePtr, Namespace *nsPtr); -/* Slot 236 is reserved */ +/* 236 */ +EXTERN void TclAppendUnicodeToObj(Tcl_Obj *objPtr, + const Tcl_UniChar *unicode, size_t length); /* 237 */ EXTERN int TclResetCancellation(Tcl_Interp *interp, int force); /* 238 */ @@ -578,9 +580,6 @@ EXTERN void TclStaticPackage(Tcl_Interp *interp, EXTERN Tcl_Obj * TclpCreateTemporaryDirectory(Tcl_Obj *dirObj, Tcl_Obj *basenameObj); /* 259 */ -EXTERN void TclAppendUnicodeToObj(Tcl_Obj *objPtr, - const Tcl_UniChar *unicode, size_t length); -/* 260 */ EXTERN unsigned char * TclGetBytesFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, size_t *lengthPtr); @@ -824,7 +823,7 @@ typedef struct TclIntStubs { void (*tclGetSrcInfoForPc) (CmdFrame *contextPtr); /* 233 */ Var * (*tclVarHashCreateVar) (TclVarHashTable *tablePtr, const char *key, int *newPtr); /* 234 */ void (*tclInitVarHashTable) (TclVarHashTable *tablePtr, Namespace *nsPtr); /* 235 */ - void (*reserved236)(void); + void (*tclAppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t length); /* 236 */ int (*tclResetCancellation) (Tcl_Interp *interp, int force); /* 237 */ int (*tclNRInterpProc) (void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 238 */ int (*tclNRInterpProcCore) (Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip, ProcErrorProc *errorProc); /* 239 */ @@ -847,8 +846,7 @@ typedef struct TclIntStubs { int (*tclPtrUnsetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 256 */ void (*tclStaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ Tcl_Obj * (*tclpCreateTemporaryDirectory) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj); /* 258 */ - void (*tclAppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, size_t length); /* 259 */ - unsigned char * (*tclGetBytesFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, size_t *lengthPtr); /* 260 */ + unsigned char * (*tclGetBytesFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, size_t *lengthPtr); /* 259 */ } TclIntStubs; extern const TclIntStubs *tclIntStubsPtr; @@ -1219,7 +1217,8 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclVarHashCreateVar) /* 234 */ #define TclInitVarHashTable \ (tclIntStubsPtr->tclInitVarHashTable) /* 235 */ -/* Slot 236 is reserved */ +#define TclAppendUnicodeToObj \ + (tclIntStubsPtr->tclAppendUnicodeToObj) /* 236 */ #define TclResetCancellation \ (tclIntStubsPtr->tclResetCancellation) /* 237 */ #define TclNRInterpProc \ @@ -1264,10 +1263,8 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclStaticPackage) /* 257 */ #define TclpCreateTemporaryDirectory \ (tclIntStubsPtr->tclpCreateTemporaryDirectory) /* 258 */ -#define TclAppendUnicodeToObj \ - (tclIntStubsPtr->tclAppendUnicodeToObj) /* 259 */ #define TclGetBytesFromObj \ - (tclIntStubsPtr->tclGetBytesFromObj) /* 260 */ + (tclIntStubsPtr->tclGetBytesFromObj) /* 259 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index f6b8b0d..e1ba73e 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -527,7 +527,7 @@ static const TclIntStubs tclIntStubs = { TclGetSrcInfoForPc, /* 233 */ TclVarHashCreateVar, /* 234 */ TclInitVarHashTable, /* 235 */ - 0, /* 236 */ + TclAppendUnicodeToObj, /* 236 */ TclResetCancellation, /* 237 */ TclNRInterpProc, /* 238 */ TclNRInterpProcCore, /* 239 */ @@ -550,8 +550,7 @@ static const TclIntStubs tclIntStubs = { TclPtrUnsetVar, /* 256 */ TclStaticPackage, /* 257 */ TclpCreateTemporaryDirectory, /* 258 */ - TclAppendUnicodeToObj, /* 259 */ - TclGetBytesFromObj, /* 260 */ + TclGetBytesFromObj, /* 259 */ }; static const TclIntPlatStubs tclIntPlatStubs = { -- cgit v0.12 From 0834bb45471baf76fe11345ac6893304cd971420 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 10 Mar 2021 15:39:15 +0000 Subject: Fix [4c591fa487]: [string compare] EIAS violation --- generic/tclCmdMZ.c | 2 +- generic/tclInt.h | 2 +- generic/tclUtf.c | 17 ++++++++--------- tests/utf.test | 20 +------------------- 4 files changed, 11 insertions(+), 30 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index ee30a7a..c895039 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2755,7 +2755,7 @@ TclStringCmp( s1 = (char *) Tcl_GetUnicode(value1Ptr); s2 = (char *) Tcl_GetUnicode(value2Ptr); if ( -#ifdef WORDS_BIGENDIAN +#if defined(WORDS_BIGENDIAN) && (TCL_UTF_MAX != 4) 1 #else checkEq diff --git a/generic/tclInt.h b/generic/tclInt.h index 5da21b0..9fec41e 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4534,7 +4534,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, *---------------------------------------------------------------- */ -#ifdef WORDS_BIGENDIAN +#if defined(WORDS_BIGENDIAN) && (TCL_UTF_MAX != 4) # define TclUniCharNcmp(cs,ct,n) memcmp((cs),(ct),(n)*sizeof(Tcl_UniChar)) #else /* !WORDS_BIGENDIAN */ # define TclUniCharNcmp Tcl_UniCharNcmp diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 57e58c1..6e6d386 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -1592,25 +1592,24 @@ Tcl_UniCharNcmp( const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */ unsigned long numChars) /* Number of unichars to compare. */ { -#ifdef WORDS_BIGENDIAN - /* - * We are definitely on a big-endian machine; memcmp() is safe - */ - - return memcmp(ucs, uct, numChars*sizeof(Tcl_UniChar)); - -#else /* !WORDS_BIGENDIAN */ /* * We can't simply call memcmp() because that is not lexically correct. */ for ( ; numChars != 0; ucs++, uct++, numChars--) { if (*ucs != *uct) { +#if TCL_UTF_MAX == 4 + /* special case for handling upper surrogates */ + if (((*ucs & 0xFC00) == 0xD800) && ((*uct & 0xFC00) != 0xD800)) { + return 1; + } else if (((*uct & 0xFC00) == 0xD800)) { + return -1; + } +#endif return (*ucs - *uct); } } return 0; -#endif /* WORDS_BIGENDIAN */ } /* diff --git a/tests/utf.test b/tests/utf.test index 8985313..f4d9134 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -1332,25 +1332,7 @@ test utf-19.1 {TclUniCharLen} -body { test utf-20.1 {TclUniCharNcmp} ucs4 { string compare [string range [format %c 0xFFFF] 0 0] [string range [format %c 0x10000] 0 0] } -1 -test utf-20.2 {[4c591fa487] TclUniCharNcmp/TclUtfNcmp} ucs2 { - set one [format %c 0xFFFF] - set two [format %c 0x10000] - set first [string compare $one $two] - string range $one 0 0 - string range $two 0 0 - set second [string compare $one $two] - expr {($first == $second) ? "agree" : "disagree"} -} agree -test utf-20.2.1 {[4c591fa487] TclUniCharNcmp/TclUtfNcmp} {utf16 knownBug} { - set one [format %c 0xFFFF] - set two [format %c 0x10000] - set first [string compare $one $two] - string range $one 0 0 - string range $two 0 0 - set second [string compare $one $two] - expr {($first == $second) ? "agree" : "disagree"} -} agree -test utf-20.2.2 {[4c591fa487] TclUniCharNcmp/TclUtfNcmp} ucs4 { +test utf-20.2 {[4c591fa487] TclUniCharNcmp/TclUtfNcmp} { set one [format %c 0xFFFF] set two [format %c 0x10000] set first [string compare $one $two] -- cgit v0.12 From f223db50fda34233096578863259fadfb133e804 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 10 Mar 2021 16:12:01 +0000 Subject: Repair Tcl_UniCharNcasecmp() in the same way as Tcl_UniCharNcmp() for fix [4c591fa487]. Also put back minor optimization for big-endian machines removed in the previous commit --- generic/tclUtf.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 6e6d386..bcae055 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -1592,6 +1592,14 @@ Tcl_UniCharNcmp( const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */ unsigned long numChars) /* Number of unichars to compare. */ { +#if defined(WORDS_BIGENDIAN) && (TCL_UTF_MAX != 4) + /* + * We are definitely on a big-endian machine; memcmp() is safe + */ + + return memcmp(ucs, uct, numChars*sizeof(Tcl_UniChar)); + +#else /* !WORDS_BIGENDIAN */ /* * We can't simply call memcmp() because that is not lexically correct. */ @@ -1610,6 +1618,7 @@ Tcl_UniCharNcmp( } } return 0; +#endif /* WORDS_BIGENDIAN */ } /* @@ -1642,6 +1651,14 @@ Tcl_UniCharNcasecmp( Tcl_UniChar lct = Tcl_UniCharToLower(*uct); if (lcs != lct) { +#if TCL_UTF_MAX == 4 + /* special case for handling upper surrogates */ + if (((lcs & 0xFC00) == 0xD800) && ((lct & 0xFC00) != 0xD800)) { + return 1; + } else if (((lct & 0xFC00) == 0xD800)) { + return -1; + } +#endif return (lcs - lct); } } -- cgit v0.12 From 2ea2ef0609d7e306bf981672cda2e66782ed4db3 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 11 Mar 2021 12:19:14 +0000 Subject: Backport Tcl_UtfCharComplete() functionality from 8.6 for TCL_UTF_MAX>3. This makes Tcl_UtfCharComplete() usable to protect Tcl_UtfNext() calls for overflow. No change for TCL_UTF_MAX=3 (default build) --- generic/tclUtf.c | 19 ++++++++++++++++++- tests/utf.test | 6 +++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 03d0f3a..efbd383 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -76,6 +76,23 @@ static const unsigned char totalBytes[256] = { 1,1,1,1,1,1,1,1,1,1,1 }; +#if TCL_UTF_MAX > 3 +static const unsigned char complete[256] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +/* Tcl_UtfCharComplete() might point to 2nd byte of valid 4-byte sequence */ + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +/* End of "continuation byte section" */ + 2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1 +}; +#else +# define complete totalBytes +#endif + /* * Functions used only in this module. */ @@ -492,7 +509,7 @@ Tcl_UtfCharComplete( * a complete UTF-8 character. */ int length) /* Length of above string in bytes. */ { - return length >= totalBytes[UCHAR(*src)]; + return length >= complete[UCHAR(*src)]; } /* diff --git a/tests/utf.test b/tests/utf.test index 06ac329..76b6847 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -8,8 +8,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest 2 +if {"::tcltest" ni [namespace children]} { + package require tcltest 2.5 namespace import -force ::tcltest::* } @@ -614,7 +614,7 @@ test utf-6.117.1 {Tcl_UtfNext, read limits} {testutfnext testbytestring fullutf} test utf-6.118 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { testutfnext [testbytestring \xA0]G 0 } 0 -test utf-6.119 {Tcl_UtfNext, read limits} {testutfnext testbytestring} { +test utf-6.119 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { testutfnext [testbytestring \xA0]G 1 } 1 test utf-6.120 {Tcl_UtfNext, read limits} {testutfnext testbytestring ucs2} { -- cgit v0.12 From 58fb98d8a916de0e1d9dc34c76262d80ab853927 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 14 Mar 2021 15:26:44 +0000 Subject: More on making tclZipfs.c comprehensible. Refactoring to the rescue! --- generic/tclZipfs.c | 1768 +++++++++++++++++++++++++++++++--------------------- tests/zipfs.test | 16 +- 2 files changed, 1087 insertions(+), 697 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b8a772b..ffad98f 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -129,6 +129,14 @@ Tcl_SetObjResult(interp, Tcl_NewStringObj(errstr, -1)); \ } \ } while (0) +#define ZIPFS_MEM_ERROR(interp) \ + do { \ + if (interp) { \ + Tcl_SetObjResult(interp, Tcl_NewStringObj( \ + "out of memory", -1)); \ + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); \ + } \ + } while (0) #define ZIPFS_POSIX_ERROR(interp,errstr) \ do { \ if (interp) { \ @@ -136,28 +144,11 @@ "%s: %s", errstr, Tcl_PosixError(interp))); \ } \ } while (0) - -/* - * Macros to read and write little-endial 16 and 32 bit integers from/to ZIP - * archives. - */ - -#define ZipReadInt(p) \ - ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) -#define ZipReadShort(p) \ - ((p)[0] | ((p)[1] << 8)) - -#define ZipWriteInt(p, v) \ - do { \ - (p)[0] = (v) & 0xff; \ - (p)[1] = ((v) >> 8) & 0xff; \ - (p)[2] = ((v) >> 16) & 0xff; \ - (p)[3] = ((v) >> 24) & 0xff; \ - } while (0) -#define ZipWriteShort(p, v) \ - do { \ - (p)[0] = (v) & 0xff; \ - (p)[1] = ((v) >> 8) & 0xff; \ +#define ZIPFS_ERROR_CODE(interp,errcode) \ + do { \ + if (interp) { \ + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", errcode, NULL); \ + } \ } while (0) /* @@ -287,15 +278,26 @@ static int CopyImageFile(Tcl_Interp *interp, const char *imgName, Tcl_Channel out); static inline int DescribeMounted(Tcl_Interp *interp, const char *mountPoint); +static int InitReadableChannel(Tcl_Interp *interp, + ZipChannel *info, ZipEntry *z); +static int InitWritableChannel(Tcl_Interp *interp, + ZipChannel *info, ZipEntry *z, int trunc); static inline int ListMountPoints(Tcl_Interp *interp); -static void SerializeCentralDirectoryEntry(char *buf, ZipEntry *z, - size_t nameLength, long long dataStartOffset); -static void SerializeCentralDirectorySuffix(char *buf, +static void SerializeCentralDirectoryEntry( + const unsigned char *start, + const unsigned char *end, unsigned char *buf, + ZipEntry *z, size_t nameLength, + long long dataStartOffset); +static void SerializeCentralDirectorySuffix( + const unsigned char *start, + const unsigned char *end, unsigned char *buf, int entryCount, long long dataStartOffset, long long directoryStartOffset, long long suffixStartOffset); -static void SerializeLocalEntryHeader(char *buf, ZipEntry *z, - int nameLength, int align); +static void SerializeLocalEntryHeader( + const unsigned char *start, + const unsigned char *end, unsigned char *buf, + ZipEntry *z, int nameLength, int align); #if !defined(STATIC_BUILD) static int ZipfsAppHookFindTclInit(const char *archive); #endif @@ -310,6 +312,9 @@ static Tcl_Channel ZipFSOpenFileChannelProc(Tcl_Interp *interp, static int ZipFSMatchInDirectoryProc(Tcl_Interp *interp, Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); +static void ZipFSMatchMountPoints(Tcl_Obj *result, + Tcl_Obj *normPathPtr, const char *pattern, + Tcl_DString *prefix); static Tcl_Obj * ZipFSListVolumesProc(void); static const char *const *ZipFSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); @@ -415,6 +420,79 @@ static Tcl_ChannelType ZipChannelType = { /* *------------------------------------------------------------------------- * + * ZipReadInt, ZipReadShort, ZipWriteInt, ZipWriteShort -- + * + * Inline functions to read and write little-endian 16 and 32 bit + * integers from/to buffers representing parts of ZIP archives. + * + * These take bufferStart and bufferEnd pointers, which are used to + * maintain a guarantee that out-of-bounds accesses don't happen when + * reading or writing critical directory structures. + * + *------------------------------------------------------------------------- + */ + +static inline unsigned int +ZipReadInt( + const unsigned char *bufferStart, + const unsigned char *bufferEnd, + const unsigned char *ptr) +{ + if (ptr < bufferStart || ptr + 4 > bufferEnd) { + Tcl_Panic("out of bounds read(4): start=%p, end=%p, ptr=%p", + bufferStart, bufferEnd, ptr); + } + return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); +} + +static inline unsigned short +ZipReadShort( + const unsigned char *bufferStart, + const unsigned char *bufferEnd, + const unsigned char *ptr) +{ + if (ptr < bufferStart || ptr + 2 > bufferEnd) { + Tcl_Panic("out of bounds read(2): start=%p, end=%p, ptr=%p", + bufferStart, bufferEnd, ptr); + } + return ptr[0] | (ptr[1] << 8); +} + +static inline void +ZipWriteInt( + const unsigned char *bufferStart, + const unsigned char *bufferEnd, + unsigned char *ptr, + unsigned int value) +{ + if (ptr < bufferStart || ptr + 4 > bufferEnd) { + Tcl_Panic("out of bounds write(4): start=%p, end=%p, ptr=%p", + bufferStart, bufferEnd, ptr); + } + ptr[0] = value & 0xff; + ptr[1] = (value >> 8) & 0xff; + ptr[2] = (value >> 16) & 0xff; + ptr[3] = (value >> 24) & 0xff; +} + +static inline void +ZipWriteShort( + const unsigned char *bufferStart, + const unsigned char *bufferEnd, + unsigned char *ptr, + unsigned short value) +{ + if (ptr < bufferStart || ptr + 2 > bufferEnd) { + Tcl_Panic("out of bounds write(2): start=%p, end=%p, ptr=%p", + bufferStart, bufferEnd, ptr); + } + ptr[0] = value & 0xff; + ptr[1] = (value >> 8) & 0xff; +} + +/* + *------------------------------------------------------------------------- + * * ReadLock, WriteLock, Unlock -- * * POSIX like rwlock functions to support multiple readers and single @@ -800,13 +878,13 @@ ZipFSLookup( /* *------------------------------------------------------------------------- * - * ZipFSLookupMount -- + * ZipFSLookupZip -- * - * This function returns an indication if the given file name corresponds - * to a mounted ZIP archive file. + * This function gets the structure for a mounted ZIP archive. * * Results: - * Returns true, if the given file name is a mounted ZIP archive file. + * Returns a pointer to the structure, or NULL if the file is ZIP file is + * unknown/not mounted. * * Side effects: * None. @@ -814,40 +892,35 @@ ZipFSLookup( *------------------------------------------------------------------------- */ -#ifdef NEVER_USED -static int -ZipFSLookupMount( - char *filename) +static ZipFile * +ZipFSLookupZip( + const char *mountPoint) { Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - - for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; - hPtr = Tcl_NextHashEntry(&search)) { - ZipFile *zf = Tcl_GetHashValue(hPtr); + ZipFile *zf = NULL; - if (strcmp(zf->mountPoint, filename) == 0) { - return 1; - } + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); + if (hPtr) { + zf = (ZipFile *) Tcl_GetHashValue(hPtr); } - return 0; + return zf; } -#endif /* NEVER_USED */ /* *------------------------------------------------------------------------- * - * AllocateZipFile -- + * AllocateZipFile, AllocateZipEntry, AllocateZipChannel -- * - * Allocates the memory for a ZipFile structure. Always ensures that it - * is zeroed out for safety. + * Allocates the memory for a datastructure. Always ensures that it is + * zeroed out for safety. * * Returns: * The allocated structure, or NULL if allocate fails. * * Side effects: - * The interpreter result may be written to on error. Which might fail in - * a low-memory situation. + * The interpreter result may be written to on error. Which might fail + * (for ZipFile) in a low-memory situation. Always panics if ZipEntry + * allocation fails. * *------------------------------------------------------------------------- */ @@ -861,15 +934,34 @@ AllocateZipFile( ZipFile *zf = (ZipFile *) attemptckalloc(size); if (!zf) { - if (interp) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); - } + ZIPFS_MEM_ERROR(interp); } else { memset(zf, 0, size); } return zf; } + +static ZipEntry * +AllocateZipEntry(void) +{ + ZipEntry *z = (ZipEntry *) ckalloc(sizeof(ZipEntry)); + memset(z, 0, sizeof(ZipEntry)); + return z; +} + +static ZipChannel * +AllocateZipChannel( + Tcl_Interp *interp) +{ + ZipChannel *zc = (ZipChannel *) attemptckalloc(sizeof(ZipChannel)); + + if (!zc) { + ZIPFS_MEM_ERROR(interp); + } else { + memset(zc, 0, sizeof(ZipChannel)); + } + return zc; +} /* *------------------------------------------------------------------------- @@ -963,6 +1055,8 @@ ZipFSFindTOC( { size_t i; unsigned char *p, *q; + const unsigned char *start = zf->data; + const unsigned char *end = zf->data + zf->length; /* * Scan backwards from the end of the file for the signature. This is @@ -971,9 +1065,9 @@ ZipFSFindTOC( */ p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; - while (p >= zf->data) { + while (p >= start) { if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { - if (ZipReadInt(p) == ZIP_CENTRAL_END_SIG) { + if (ZipReadInt(start, end, p) == ZIP_CENTRAL_END_SIG) { break; } p -= ZIP_SIG_LEN; @@ -992,9 +1086,7 @@ ZipFSFindTOC( return TCL_OK; } ZIPFS_ERROR(interp, "wrong end signature"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "END_SIG", NULL); - } + ZIPFS_ERROR_CODE(interp, "END_SIG"); goto error; } @@ -1002,16 +1094,14 @@ ZipFSFindTOC( * How many files in the archive? If that's bogus, we're done here. */ - zf->numFiles = ZipReadShort(p + ZIP_CENTRAL_ENTS_OFFS); + zf->numFiles = ZipReadShort(start, end, p + ZIP_CENTRAL_ENTS_OFFS); if (zf->numFiles == 0) { if (!needZip) { zf->baseOffset = zf->passOffset = zf->length; return TCL_OK; } ZIPFS_ERROR(interp, "empty archive"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "EMPTY", NULL); - } + ZIPFS_ERROR_CODE(interp, "EMPTY"); goto error; } @@ -1019,8 +1109,8 @@ ZipFSFindTOC( * Where does the central directory start? */ - q = zf->data + ZipReadInt(p + ZIP_CENTRAL_DIRSTART_OFFS); - p -= ZipReadInt(p + ZIP_CENTRAL_DIRSIZE_OFFS); + q = zf->data + ZipReadInt(start, end, p + ZIP_CENTRAL_DIRSTART_OFFS); + p -= ZipReadInt(start, end, p + ZIP_CENTRAL_DIRSIZE_OFFS); if ((p < zf->data) || (p > zf->data + zf->length) || (q < zf->data) || (q > zf->data + zf->length)) { if (!needZip) { @@ -1028,9 +1118,7 @@ ZipFSFindTOC( return TCL_OK; } ZIPFS_ERROR(interp, "archive directory not found"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_DIR", NULL); - } + ZIPFS_ERROR_CODE(interp, "NO_DIR"); goto error; } @@ -1044,23 +1132,19 @@ ZipFSFindTOC( for (i = 0; i < zf->numFiles; i++) { int pathlen, comlen, extra; - if (q + ZIP_CENTRAL_HEADER_LEN > zf->data + zf->length) { + if (q + ZIP_CENTRAL_HEADER_LEN > end) { ZIPFS_ERROR(interp, "wrong header length"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "HDR_LEN", NULL); - } + ZIPFS_ERROR_CODE(interp, "HDR_LEN"); goto error; } - if (ZipReadInt(q) != ZIP_CENTRAL_HEADER_SIG) { + if (ZipReadInt(start, end, q) != ZIP_CENTRAL_HEADER_SIG) { ZIPFS_ERROR(interp, "wrong header signature"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "HDR_SIG", NULL); - } + ZIPFS_ERROR_CODE(interp, "HDR_SIG"); goto error; } - pathlen = ZipReadShort(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = ZipReadShort(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = ZipReadShort(q + ZIP_CENTRAL_EXTRALEN_OFFS); + pathlen = ZipReadShort(start, end, q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = ZipReadShort(start, end, q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = ZipReadShort(start, end, q + ZIP_CENTRAL_EXTRALEN_OFFS); q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } @@ -1070,7 +1154,8 @@ ZipFSFindTOC( */ q = zf->data + zf->baseOffset; - if ((zf->baseOffset >= 6) && (ZipReadInt(q - 4) == ZIP_PASSWORD_END_SIG)) { + if ((zf->baseOffset >= 6) && + (ZipReadInt(start, end, q - 4) == ZIP_PASSWORD_END_SIG)) { i = q[-5]; if (q - 5 - i > zf->data) { zf->passBuf[0] = i; @@ -1167,9 +1252,7 @@ ZipFSOpenArchive( if ((zf->length - ZIP_CENTRAL_END_LEN) > (64 * 1024 * 1024 - ZIP_CENTRAL_END_LEN)) { ZIPFS_ERROR(interp, "illegal file size"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "FILE_SIZE", NULL); - } + ZIPFS_ERROR_CODE(interp, "FILE_SIZE"); goto error; } if (Tcl_Seek(zf->chan, 0, SEEK_SET) == -1) { @@ -1178,10 +1261,7 @@ ZipFSOpenArchive( } zf->ptrToFree = zf->data = (unsigned char *) attemptckalloc(zf->length); if (!zf->ptrToFree) { - ZIPFS_ERROR(interp, "out of memory"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); - } + ZIPFS_MEM_ERROR(interp); goto error; } i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); @@ -1283,6 +1363,34 @@ ZipMapArchive( /* *------------------------------------------------------------------------- * + * IsPasswordValid -- + * + * Basic test for whether a passowrd is valid. If the test fails, sets an + * error message in the interpreter. + * + * Returns: + * TCL_OK if the test passes, TCL_ERROR if it fails. + * + *------------------------------------------------------------------------- + */ + +static inline int +IsPasswordValid( + Tcl_Interp *interp, + const char *passwd, + int pwlen) +{ + if ((pwlen > 255) || strchr(passwd, 0xff)) { + ZIPFS_ERROR(interp, "illegal password"); + ZIPFS_ERROR_CODE(interp, "BAD_PASS"); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * * ZipFSRootNode -- * * This function generates the root node for a ZIPFS filesystem. @@ -1321,12 +1429,7 @@ ZipFSCatalogFilesystem( pwlen = 0; if (passwd) { pwlen = strlen(passwd); - if ((pwlen > 255) || strchr(passwd, 0xff)) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_PASS", NULL); - } + if (IsPasswordValid(interp, passwd, pwlen) != TCL_OK) { return TCL_ERROR; } } @@ -1338,10 +1441,8 @@ ZipFSCatalogFilesystem( if (zf0->baseOffset < 0 || zf0->baseOffset >= zf0->length || zf0->passOffset < 0 || zf0->passOffset >= zf0->length || zf0->directoryOffset < 0 || zf0->directoryOffset >= zf0->length) { - if (interp) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("bad zip data", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_ZIP", NULL); - } + ZIPFS_ERROR(interp, "bad zip data"); + ZIPFS_ERROR_CODE(interp, "BAD_ZIP"); return TCL_ERROR; } @@ -1365,7 +1466,7 @@ ZipFSCatalogFilesystem( zf = (ZipFile *) Tcl_GetHashValue(hPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s is already mounted on %s", zf->name, mountPoint)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "MOUNTED", NULL); + ZIPFS_ERROR_CODE(interp, "MOUNTED"); } Unlock(); ZipFSCloseArchive(interp, zf0); @@ -1390,9 +1491,6 @@ ZipFSCatalogFilesystem( zf->nameLength = strlen(zipname); zf->name = (char *) ckalloc(zf->nameLength + 1); memcpy(zf->name, zipname, zf->nameLength + 1); - zf->entries = NULL; - zf->topEnts = NULL; - zf->numOpen = 0; Tcl_SetHashValue(hPtr, zf); if ((zf->passBuf[0] == 0) && pwlen) { int k = 0; @@ -1407,20 +1505,14 @@ ZipFSCatalogFilesystem( if (mountPoint[0] != '\0') { hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mountPoint, &isNew); if (isNew) { - z = (ZipEntry *) ckalloc(sizeof(ZipEntry)); + z = AllocateZipEntry(); Tcl_SetHashValue(hPtr, z); - z->tnext = NULL; z->depth = CountSlashes(mountPoint); z->zipFilePtr = zf; z->isDirectory = (zf->baseOffset == 0) ? 1 : -1; /* root marker */ - z->isEncrypted = 0; z->offset = zf->baseOffset; - z->crc32 = 0; - z->timestamp = 0; - z->numBytes = z->numCompressedBytes = 0; z->compressMethod = ZIP_COMPMETH_STORED; - z->data = NULL; z->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; zf->entries = z; @@ -1429,14 +1521,16 @@ ZipFSCatalogFilesystem( q = zf->data + zf->directoryOffset; Tcl_DStringInit(&fpBuf); for (i = 0; i < zf->numFiles; i++) { + const unsigned char *start = zf->data; + const unsigned char *end = zf->data + zf->length; int extra, isdir = 0, dosTime, dosDate, nbcompr; size_t offs, pathlen, comlen; unsigned char *lq, *gq = NULL; char *fullpath, *path; - pathlen = ZipReadShort(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = ZipReadShort(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = ZipReadShort(q + ZIP_CENTRAL_EXTRALEN_OFFS); + pathlen = ZipReadShort(start, end, q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = ZipReadShort(start, end, q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = ZipReadShort(start, end, q + ZIP_CENTRAL_EXTRALEN_OFFS); Tcl_DStringSetLength(&ds, 0); Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); path = Tcl_DStringValue(&ds); @@ -1449,24 +1543,25 @@ ZipFSCatalogFilesystem( goto nextent; } lq = zf->data + zf->baseOffset - + ZipReadInt(q + ZIP_CENTRAL_LOCALHDR_OFFS); - if ((lq < zf->data) || (lq > zf->data + zf->length)) { + + ZipReadInt(start, end, q + ZIP_CENTRAL_LOCALHDR_OFFS); + if ((lq < start) || (lq + ZIP_LOCAL_HEADER_LEN > end)) { goto nextent; } - nbcompr = ZipReadInt(lq + ZIP_LOCAL_COMPLEN_OFFS); + nbcompr = ZipReadInt(start, end, lq + ZIP_LOCAL_COMPLEN_OFFS); if (!isdir && (nbcompr == 0) - && (ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) - && (ZipReadInt(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { + && (ZipReadInt(start, end, lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) + && (ZipReadInt(start, end, lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { gq = q; - nbcompr = ZipReadInt(gq + ZIP_CENTRAL_COMPLEN_OFFS); + nbcompr = ZipReadInt(start, end, gq + ZIP_CENTRAL_COMPLEN_OFFS); } offs = (lq - zf->data) + ZIP_LOCAL_HEADER_LEN - + ZipReadShort(lq + ZIP_LOCAL_PATHLEN_OFFS) - + ZipReadShort(lq + ZIP_LOCAL_EXTRALEN_OFFS); + + ZipReadShort(start, end, lq + ZIP_LOCAL_PATHLEN_OFFS) + + ZipReadShort(start, end, lq + ZIP_LOCAL_EXTRALEN_OFFS); if (offs + nbcompr > zf->length) { goto nextent; } + if (!isdir && (mountPoint[0] == '\0') && !CountSlashes(path)) { #ifdef ANDROID /* @@ -1482,8 +1577,7 @@ ZipFSCatalogFilesystem( Tcl_DStringInit(&ds2); Tcl_DStringAppend(&ds2, "assets/.root/", -1); Tcl_DStringAppend(&ds2, path, -1); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); - if (hPtr) { + if (ZipFSLookup(Tcl_DStringValue(&ds2))) { /* should not happen but skip it anyway */ Tcl_DStringFree(&ds2); goto nextent; @@ -1500,83 +1594,91 @@ ZipFSCatalogFilesystem( goto nextent; #endif /* ANDROID */ } + Tcl_DStringSetLength(&fpBuf, 0); fullpath = CanonicalPath(mountPoint, path, &fpBuf, 1); - z = (ZipEntry *) ckalloc(sizeof(ZipEntry)); - z->name = NULL; - z->tnext = NULL; + z = AllocateZipEntry(); z->depth = CountSlashes(fullpath); z->zipFilePtr = zf; z->isDirectory = isdir; - z->isEncrypted = (ZipReadShort(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) + z->isEncrypted = + (ZipReadShort(start, end, lq + ZIP_LOCAL_FLAGS_OFFS) & 1) && (nbcompr > 12); z->offset = offs; if (gq) { - z->crc32 = ZipReadInt(gq + ZIP_CENTRAL_CRC32_OFFS); - dosDate = ZipReadShort(gq + ZIP_CENTRAL_MDATE_OFFS); - dosTime = ZipReadShort(gq + ZIP_CENTRAL_MTIME_OFFS); + z->crc32 = ZipReadInt(start, end, gq + ZIP_CENTRAL_CRC32_OFFS); + dosDate = ZipReadShort(start, end, gq + ZIP_CENTRAL_MDATE_OFFS); + dosTime = ZipReadShort(start, end, gq + ZIP_CENTRAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->numBytes = ZipReadInt(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); - z->compressMethod = ZipReadShort(gq + ZIP_CENTRAL_COMPMETH_OFFS); + z->numBytes = ZipReadInt(start, end, + gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); + z->compressMethod = ZipReadShort(start, end, + gq + ZIP_CENTRAL_COMPMETH_OFFS); } else { - z->crc32 = ZipReadInt(lq + ZIP_LOCAL_CRC32_OFFS); - dosDate = ZipReadShort(lq + ZIP_LOCAL_MDATE_OFFS); - dosTime = ZipReadShort(lq + ZIP_LOCAL_MTIME_OFFS); + z->crc32 = ZipReadInt(start, end, lq + ZIP_LOCAL_CRC32_OFFS); + dosDate = ZipReadShort(start, end, lq + ZIP_LOCAL_MDATE_OFFS); + dosTime = ZipReadShort(start, end, lq + ZIP_LOCAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->numBytes = ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); - z->compressMethod = ZipReadShort(lq + ZIP_LOCAL_COMPMETH_OFFS); + z->numBytes = ZipReadInt(start, end, + lq + ZIP_LOCAL_UNCOMPLEN_OFFS); + z->compressMethod = ZipReadShort(start, end, + lq + ZIP_LOCAL_COMPMETH_OFFS); } z->numCompressedBytes = nbcompr; - z->data = NULL; hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); if (!isNew) { /* should not happen but skip it anyway */ ckfree(z); - } else { - Tcl_SetHashValue(hPtr, z); - z->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - z->next = zf->entries; - zf->entries = z; - if (isdir && (mountPoint[0] == '\0') && (z->depth == 1)) { - z->tnext = zf->topEnts; - zf->topEnts = z; - } - if (!z->isDirectory && (z->depth > 1)) { - char *dir, *end; - ZipEntry *zd; - - Tcl_DStringSetLength(&ds, strlen(z->name) + 8); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, z->name, -1); - dir = Tcl_DStringValue(&ds); - for (end = strrchr(dir, '/'); end && (end != dir); - end = strrchr(dir, '/')) { - Tcl_DStringSetLength(&ds, end - dir); - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); - if (!isNew) { - break; - } - zd = (ZipEntry *) ckalloc(sizeof(ZipEntry)); - zd->name = NULL; - zd->tnext = NULL; - zd->depth = CountSlashes(dir); - zd->zipFilePtr = zf; - zd->isDirectory = 1; - zd->isEncrypted = 0; - zd->offset = z->offset; - zd->crc32 = 0; - zd->timestamp = z->timestamp; - zd->numBytes = zd->numCompressedBytes = 0; - zd->compressMethod = ZIP_COMPMETH_STORED; - zd->data = NULL; - Tcl_SetHashValue(hPtr, zd); - zd->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - zd->next = zf->entries; - zf->entries = zd; - if ((mountPoint[0] == '\0') && (zd->depth == 1)) { - zd->tnext = zf->topEnts; - zf->topEnts = zd; - } + goto nextent; + } + + Tcl_SetHashValue(hPtr, z); + z->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->next = zf->entries; + zf->entries = z; + if (isdir && (mountPoint[0] == '\0') && (z->depth == 1)) { + z->tnext = zf->topEnts; + zf->topEnts = z; + } + + /* + * Make any directory nodes we need. ZIPs are not consistent about + * containing directory nodes. + */ + + if (!z->isDirectory && (z->depth > 1)) { + char *dir, *endPtr; + ZipEntry *zd; + + Tcl_DStringSetLength(&ds, strlen(z->name) + 8); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, z->name, -1); + dir = Tcl_DStringValue(&ds); + for (endPtr = strrchr(dir, '/'); endPtr && (endPtr != dir); + endPtr = strrchr(dir, '/')) { + Tcl_DStringSetLength(&ds, endPtr - dir); + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); + if (!isNew) { + /* + * Already made. That's fine. + */ + break; + } + + zd = AllocateZipEntry(); + zd->depth = CountSlashes(dir); + zd->zipFilePtr = zf; + zd->isDirectory = 1; + zd->offset = z->offset; + zd->timestamp = z->timestamp; + zd->compressMethod = ZIP_COMPMETH_STORED; + Tcl_SetHashValue(hPtr, zd); + zd->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + zd->next = zf->entries; + zf->entries = zd; + if ((mountPoint[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topEnts; + zf->topEnts = zd; } } } @@ -1687,13 +1789,10 @@ DescribeMounted( Tcl_Interp *interp, const char *mountPoint) { - Tcl_HashEntry *hPtr; - ZipFile *zf; - if (interp) { - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); - if (hPtr) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); + ZipFile *zf = ZipFSLookupZip(mountPoint); + + if (zf) { Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); return TCL_OK; } @@ -1761,15 +1860,8 @@ TclZipfs_Mount( * Have both a mount point and a file (name) to mount there. */ - if (passwd) { - if ((strlen(passwd) > 255) || strchr(passwd, 0xff)) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_PASS", NULL); - } - return TCL_ERROR; - } + if (passwd && IsPasswordValid(interp, passwd, strlen(passwd)) != TCL_OK) { + return TCL_ERROR; } zf = AllocateZipFile(interp, strlen(mountPoint)); if (!zf) { @@ -1857,10 +1949,7 @@ TclZipfs_MountBuffer( if (copy) { zf->data = (unsigned char *) attemptckalloc(datalen); if (!zf->data) { - if (interp) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); - } + ZIPFS_MEM_ERROR(interp); return TCL_ERROR; } memcpy(zf->data, data, datalen); @@ -1928,6 +2017,7 @@ TclZipfs_Unmount( zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (zf->numOpen > 0) { ZIPFS_ERROR(interp, "filesystem is busy"); + ZIPFS_ERROR_CODE(interp, "BUSY"); ret = TCL_ERROR; goto done; } @@ -2161,8 +2251,7 @@ ZipFSMkKeyObjCmd( if (len == 0) { return TCL_OK; } - if ((len > 255) || strchr(pw, 0xff)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); + if (IsPasswordValid(interp, pw, len) != TCL_OK) { return TCL_ERROR; } while (len > 0) { @@ -2186,9 +2275,53 @@ ZipFSMkKeyObjCmd( /* *------------------------------------------------------------------------- * + * RandomChar -- + * + * Worker for ZipAddFile(). Picks a random character (range: 0..255) + * using Tcl's standard PRNG. + * + * Returns: + * Tcl result code. Updates chPtr with random character on success. + * + * Side effects: + * Advances the PRNG state. May reenter the Tcl interpreter if the user + * has replaced the PRNG. + * + *------------------------------------------------------------------------- + */ + +static int +RandomChar( + Tcl_Interp *interp, + int step, + int *chPtr) +{ + double r; + Tcl_Obj *ret; + + if (Tcl_EvalEx(interp, "::tcl::mathfunc::rand", -1, 0) != TCL_OK) { + goto failed; + } + ret = Tcl_GetObjResult(interp); + if (Tcl_GetDoubleFromObj(interp, ret, &r) != TCL_OK) { + goto failed; + } + *chPtr = (int) (r * 256); + return TCL_OK; + + failed: + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (evaluating PRNG step %d for password encoding)", + step)); + return TCL_ERROR; +} + +/* + *------------------------------------------------------------------------- + * * ZipAddFile -- * - * This procedure is used by ZipFSMkZipOrImgCmd() to add a single file to + * This procedure is used by ZipFSMkZipOrImg() to add a single file to * the output ZIP archive file being written. A ZipEntry struct about the * input file is added to the given fileHash table for later creation of * the central ZIP directory. @@ -2215,6 +2348,8 @@ ZipAddFile( int bufsize, Tcl_HashTable *fileHash) { + const unsigned char *start = (unsigned char *) buf; + const unsigned char *end = (unsigned char *) buf + bufsize; Tcl_Channel in; Tcl_HashEntry *hPtr; ZipEntry *z; @@ -2244,7 +2379,7 @@ ZipAddFile( if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "path too long for \"%s\"", path)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "PATH_LEN", NULL); + ZIPFS_ERROR_CODE(interp, "PATH_LEN"); return TCL_ERROR; } in = Tcl_OpenFileChannel(interp, path, "rb", 0); @@ -2269,6 +2404,11 @@ ZipAddFile( Tcl_DecrRefCount(pathObj); } Tcl_ResetResult(interp); + + /* + * Compute the CRC. + */ + crc = 0; nbyte = nbytecompr = 0; while (1) { @@ -2295,7 +2435,19 @@ ZipAddFile( Tcl_Close(interp, in); return TCL_ERROR; } + + /* + * Remember where we've got to so far so we can write the header (after + * writing the file). + */ + headerStartOffset = Tcl_Tell(out); + + /* + * Reserve space for the per-file header. Includes writing the file name + * as we already know that. + */ + memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); len = zpathlen + ZIP_LOCAL_HEADER_LEN; @@ -2306,51 +2458,40 @@ ZipAddFile( Tcl_Close(interp, in); return TCL_ERROR; } + + /* + * Align payload to next 4-byte boundary (if necessary) using a dummy + * extra entry similar to the zipalign tool from Android's SDK. + */ + if ((len + headerStartOffset) & 3) { unsigned char abuf[8]; - - /* - * Align payload to next 4-byte boundary using a dummy extra entry - * similar to the zipalign tool from Android's SDK. - */ + const unsigned char *astart = abuf; + const unsigned char *aend = abuf + 8; align = 4 + ((len + headerStartOffset) & 3); - ZipWriteShort(abuf, 0xffff); - ZipWriteShort(abuf + 2, align - 4); - ZipWriteInt(abuf + 4, 0x03020100); + ZipWriteShort(astart, aend, abuf, 0xffff); + ZipWriteShort(astart, aend, abuf + 2, align - 4); + ZipWriteInt(astart, aend, abuf + 4, 0x03020100); if ((size_t) Tcl_Write(out, (const char *) abuf, align) != align) { goto wrerr; } } + + /* + * Set up encryption if we were asked to. + */ + if (passwd) { int i, ch, tmp; unsigned char kvbuf[24]; - Tcl_Obj *ret; init_keys(passwd, keys, crc32tab); for (i = 0; i < 12 - 2; i++) { - double r; - - if (Tcl_EvalEx(interp, "::tcl::mathfunc::rand", -1, 0) != TCL_OK) { - Tcl_Obj *eiPtr = Tcl_ObjPrintf( - "\n (evaluating PRNG step %d for password encoding)", - i); - - Tcl_AppendObjToErrorInfo(interp, eiPtr); - Tcl_Close(interp, in); - return TCL_ERROR; - } - ret = Tcl_GetObjResult(interp); - if (Tcl_GetDoubleFromObj(interp, ret, &r) != TCL_OK) { - Tcl_Obj *eiPtr = Tcl_ObjPrintf( - "\n (evaluating PRNG step %d for password encoding)", - i); - - Tcl_AppendObjToErrorInfo(interp, eiPtr); + if (RandomChar(interp, i, &ch) != TCL_OK) { Tcl_Close(interp, in); return TCL_ERROR; } - ch = (int) (r * 256); kvbuf[i + 12] = UCHAR(zencode(keys, crc32tab, ch, tmp)); } Tcl_ResetResult(interp); @@ -2371,8 +2512,18 @@ ZipAddFile( memcpy(keys0, keys, sizeof(keys0)); nbytecompr += 12; } + + /* + * Save where we've got to in case we need to just store this file. + */ + Tcl_Flush(out); dataStartOffset = Tcl_Tell(out); + + /* + * Compress the stream. + */ + compMeth = ZIP_COMPMETH_DEFLATED; memset(&stream, 0, sizeof(z_stream)); stream.zalloc = Z_NULL; @@ -2382,7 +2533,7 @@ ZipAddFile( Z_DEFAULT_STRATEGY) != Z_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "compression init error on \"%s\"", path)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "DEFLATE_INIT", NULL); + ZIPFS_ERROR_CODE(interp, "DEFLATE_INIT"); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2405,7 +2556,7 @@ ZipAddFile( if (len == (size_t) Z_STREAM_ERROR) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "deflate error on %s", path)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "DEFLATE", NULL); + ZIPFS_ERROR_CODE(interp, "DEFLATE"); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; @@ -2430,8 +2581,14 @@ ZipAddFile( } while (stream.avail_out == 0); } while (flush != Z_FINISH); deflateEnd(&stream); + + /* + * Work out where we've got to. + */ + Tcl_Flush(out); dataEndOffset = Tcl_Tell(out); + if (nbyte - nbytecompr <= 0) { /* * Compressed file larger than input, write it again uncompressed. @@ -2476,6 +2633,12 @@ ZipAddFile( nbytecompr += len; } compMeth = ZIP_COMPMETH_STORED; + + /* + * Chop off everything after this; it's the over-large compressed data + * and we don't know if it is going to get overwritten otherwise. + */ + Tcl_Flush(out); dataEndOffset = Tcl_Tell(out); Tcl_TruncateChannel(out, dataEndOffset); @@ -2486,17 +2649,18 @@ ZipAddFile( if (!isNew) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "non-unique path name \"%s\"", path)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "DUPLICATE_PATH", NULL); + ZIPFS_ERROR_CODE(interp, "DUPLICATE_PATH"); return TCL_ERROR; } - z = (ZipEntry *) ckalloc(sizeof(ZipEntry)); + /* + * Remember that we've written the file (for central directory generation) + * and generate the local (per-file) header in the space that we reserved + * earlier. + */ + + z = AllocateZipEntry(); Tcl_SetHashValue(hPtr, z); - z->name = NULL; - z->tnext = NULL; - z->depth = 0; - z->zipFilePtr = NULL; - z->isDirectory = 0; z->isEncrypted = (passwd ? 1 : 0); z->offset = headerStartOffset; z->crc32 = crc; @@ -2504,15 +2668,14 @@ ZipAddFile( z->numBytes = nbyte; z->numCompressedBytes = nbytecompr; z->compressMethod = compMeth; - z->data = NULL; z->name = (char *) Tcl_GetHashKey(fileHash, hPtr); - z->next = NULL; /* * Write final local header information. */ - SerializeLocalEntryHeader(buf, z, zpathlen, align); + SerializeLocalEntryHeader(start, end, (unsigned char *) buf, z, + zpathlen, align); if (Tcl_Seek(out, headerStartOffset, SEEK_SET) != headerStartOffset) { Tcl_DeleteHashEntry(hPtr); ckfree(z); @@ -2541,12 +2704,43 @@ ZipAddFile( /* *------------------------------------------------------------------------- * - * ZipFSMkZipOrImgObjCmd -- + * ZipFSFind -- + * + * Worker for ZipFSMkZipOrImg() that discovers the list of files to add. + * Simple wrapper around [zipfs find]. + * + *------------------------------------------------------------------------- + */ + +static Tcl_Obj * +ZipFSFind( + Tcl_Interp *interp, + Tcl_Obj *dirRoot) +{ + Tcl_Obj *cmd[2]; + int result; + + cmd[0] = Tcl_NewStringObj("::tcl::zipfs::find", -1); + cmd[1] = dirRoot; + Tcl_IncrRefCount(cmd[0]); + result = Tcl_EvalObjv(interp, 2, cmd, 0); + Tcl_DecrRefCount(cmd[0]); + if (result != TCL_OK) { + return NULL; + } + return Tcl_GetObjResult(interp); +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSMkZipOrImg -- * * This procedure is creates a new ZIP archive file or image file given * output filename, input directory of files to be archived, optional * password, and optional image to be prepended to the output ZIP archive - * file. + * file. It's the core of the implementation of [zipfs mkzip], [zipfs + * mkimg], [zipfs lmkzip] and [zipfs lmkimg]. * * Results: * A standard Tcl result. @@ -2558,15 +2752,24 @@ ZipAddFile( */ static int -ZipFSMkZipOrImgObjCmd( +ZipFSMkZipOrImg( Tcl_Interp *interp, /* Current interpreter. */ - int isImg, - Tcl_Obj *targetFile, - Tcl_Obj *dirRoot, - Tcl_Obj *mappingList, - Tcl_Obj *originFile, - Tcl_Obj *stripPrefix, - Tcl_Obj *passwordObj) + int isImg, /* Are we making an image? */ + Tcl_Obj *targetFile, /* What file are we making? */ + Tcl_Obj *dirRoot, /* What directory do we take files from? Do + * not specify at the same time as + * mappingList (one must be NULL). */ + Tcl_Obj *mappingList, /* What files are we putting in, and with what + * names? Do not specify at the same time as + * dirRoot (one must be NULL). */ + Tcl_Obj *originFile, /* If we're making an image, what file does + * the non-ZIP part of the image come from? */ + Tcl_Obj *stripPrefix, /* Are we going to strip a prefix from + * filenames found beneath dirRoot? If NULL, + * do not strip anything (except for dirRoot + * itself). */ + Tcl_Obj *passwordObj) /* The password for encoding things. NULL if + * there's no password protection. */ { Tcl_Channel out; int pwlen = 0, slen = 0, count, ret = TCL_ERROR, lobjc; @@ -2585,6 +2788,8 @@ ZipFSMkZipOrImgObjCmd( Tcl_HashSearch search; Tcl_HashTable fileHash; char *strip = NULL, *pw = NULL, passBuf[264], buf[4096]; + unsigned char *start = (unsigned char *) buf; + unsigned char *end = start + sizeof(buf); /* * Caller has verified that the number of arguments is correct. @@ -2593,30 +2798,19 @@ ZipFSMkZipOrImgObjCmd( passBuf[0] = 0; if (passwordObj != NULL) { pw = Tcl_GetStringFromObj(passwordObj, &pwlen); - if ((pwlen > 255) || strchr(pw, 0xff)) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_PASS", NULL); + if (IsPasswordValid(interp, pw, pwlen) != TCL_OK) { return TCL_ERROR; } + if (pwlen <= 0) { + pw = NULL; + pwlen = 0; + } } if (dirRoot != NULL) { - Tcl_Obj *cmd[2]; - int result; - - /* - * Discover the list of files to add. - */ - - cmd[0] = Tcl_NewStringObj("::tcl::zipfs::find", -1); - cmd[1] = dirRoot; - Tcl_IncrRefCount(cmd[0]); - result = Tcl_EvalObjv(interp, 2, cmd, 0); - Tcl_DecrRefCount(cmd[0]); - if (result != TCL_OK) { + list = ZipFSFind(interp, dirRoot); + if (!list) { return TCL_ERROR; } - list = Tcl_GetObjResult(interp); } Tcl_IncrRefCount(list); if (Tcl_ListObjGetElements(interp, list, &lobjc, &lobjv) != TCL_OK) { @@ -2625,15 +2819,14 @@ ZipFSMkZipOrImgObjCmd( } if (mappingList && (lobjc % 2)) { Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, - Tcl_NewStringObj("need even number of elements", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "LIST_LENGTH", NULL); + ZIPFS_ERROR(interp, "need even number of elements"); + ZIPFS_ERROR_CODE(interp, "LIST_LENGTH"); return TCL_ERROR; } if (lobjc == 0) { Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "EMPTY", NULL); + ZIPFS_ERROR(interp, "empty archive"); + ZIPFS_ERROR_CODE(interp, "EMPTY"); return TCL_ERROR; } out = Tcl_OpenFileChannel(interp, Tcl_GetString(targetFile), "wb", 0755); @@ -2641,10 +2834,6 @@ ZipFSMkZipOrImgObjCmd( Tcl_DecrRefCount(list); return TCL_ERROR; } - if (pwlen <= 0) { - pw = NULL; - pwlen = 0; - } /* * Copy the existing contents from the image if it is an executable image. @@ -2830,7 +3019,8 @@ ZipFSMkZipOrImgObjCmd( } z = (ZipEntry *) Tcl_GetHashValue(hPtr); len = strlen(z->name); - SerializeCentralDirectoryEntry(buf, z, len, dataStartOffset); + SerializeCentralDirectoryEntry(start, end, (unsigned char *) buf, + z, len, dataStartOffset); if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) || ((size_t) Tcl_Write(out, z->name, len) != len)) { @@ -2847,8 +3037,8 @@ ZipFSMkZipOrImgObjCmd( Tcl_Flush(out); suffixStartOffset = Tcl_Tell(out); - SerializeCentralDirectorySuffix(buf, count, dataStartOffset, - directoryStartOffset, suffixStartOffset); + SerializeCentralDirectorySuffix(start, end, (unsigned char *) buf, + count, dataStartOffset, directoryStartOffset, suffixStartOffset); if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); @@ -2879,8 +3069,8 @@ ZipFSMkZipOrImgObjCmd( * * CopyImageFile -- * - * A simple file copy function that is used (by ZipFSMkZipOrImgObjCmd) - * for anything that is not an image with a ZIP appended. + * A simple file copy function that is used (by ZipFSMkZipOrImg) for + * anything that is not an image with a ZIP appended. * * Returns: * A Tcl result code. @@ -2975,54 +3165,71 @@ CopyImageFile( static void SerializeLocalEntryHeader( - char *buf, /* Where to serialize to */ + const unsigned char *start, /* The start of writable memory. */ + const unsigned char *end, /* The end of writable memory. */ + unsigned char *buf, /* Where to serialize to */ ZipEntry *z, /* The description of what to serialize. */ int nameLength, /* The length of the name. */ int align) /* The number of alignment bytes. */ { - ZipWriteInt(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); - ZipWriteShort(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_LOCAL_FLAGS_OFFS, z->isEncrypted); - ZipWriteShort(buf + ZIP_LOCAL_COMPMETH_OFFS, z->compressMethod); - ZipWriteShort(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); - ZipWriteShort(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); - ZipWriteInt(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); - ZipWriteInt(buf + ZIP_LOCAL_COMPLEN_OFFS, z->numCompressedBytes); - ZipWriteInt(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->numBytes); - ZipWriteShort(buf + ZIP_LOCAL_PATHLEN_OFFS, nameLength); - ZipWriteShort(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); + ZipWriteInt(start, end, buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); + ZipWriteShort(start, end, buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(start, end, buf + ZIP_LOCAL_FLAGS_OFFS, z->isEncrypted); + ZipWriteShort(start, end, buf + ZIP_LOCAL_COMPMETH_OFFS, + z->compressMethod); + ZipWriteShort(start, end, buf + ZIP_LOCAL_MTIME_OFFS, + ToDosTime(z->timestamp)); + ZipWriteShort(start, end, buf + ZIP_LOCAL_MDATE_OFFS, + ToDosDate(z->timestamp)); + ZipWriteInt(start, end, buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); + ZipWriteInt(start, end, buf + ZIP_LOCAL_COMPLEN_OFFS, + z->numCompressedBytes); + ZipWriteInt(start, end, buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->numBytes); + ZipWriteShort(start, end, buf + ZIP_LOCAL_PATHLEN_OFFS, nameLength); + ZipWriteShort(start, end, buf + ZIP_LOCAL_EXTRALEN_OFFS, align); } static void SerializeCentralDirectoryEntry( - char *buf, /* Where to serialize to */ + const unsigned char *start, /* The start of writable memory. */ + const unsigned char *end, /* The end of writable memory. */ + unsigned char *buf, /* Where to serialize to */ ZipEntry *z, /* The description of what to serialize. */ size_t nameLength, /* The length of the name. */ long long dataStartOffset) /* The overall file offset of the start of the * data section of the file. */ { - ZipWriteInt(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); - ZipWriteShort(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isEncrypted); - ZipWriteShort(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->compressMethod); - ZipWriteShort(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); - ZipWriteShort(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); - ZipWriteInt(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); - ZipWriteInt(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->numCompressedBytes); - ZipWriteInt(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->numBytes); - ZipWriteShort(buf + ZIP_CENTRAL_PATHLEN_OFFS, nameLength); - ZipWriteShort(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_IATTR_OFFS, 0); - ZipWriteInt(buf + ZIP_CENTRAL_EATTR_OFFS, 0); - ZipWriteInt(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - dataStartOffset); + ZipWriteInt(start, end, buf + ZIP_CENTRAL_SIG_OFFS, + ZIP_CENTRAL_HEADER_SIG); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_VERSIONMADE_OFFS, + ZIP_MIN_VERSION); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_FLAGS_OFFS, z->isEncrypted); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_COMPMETH_OFFS, + z->compressMethod); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_MTIME_OFFS, + ToDosTime(z->timestamp)); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_MDATE_OFFS, + ToDosDate(z->timestamp)); + ZipWriteInt(start, end, buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); + ZipWriteInt(start, end, buf + ZIP_CENTRAL_COMPLEN_OFFS, + z->numCompressedBytes); + ZipWriteInt(start, end, buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->numBytes); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_PATHLEN_OFFS, nameLength); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_IATTR_OFFS, 0); + ZipWriteInt(start, end, buf + ZIP_CENTRAL_EATTR_OFFS, 0); + ZipWriteInt(start, end, buf + ZIP_CENTRAL_LOCALHDR_OFFS, + z->offset - dataStartOffset); } static void SerializeCentralDirectorySuffix( - char *buf, /* Where to serialize to */ + const unsigned char *start, /* The start of writable memory. */ + const unsigned char *end, /* The end of writable memory. */ + unsigned char *buf, /* Where to serialize to */ int entryCount, /* The number of entries in the directory */ long long dataStartOffset, /* The overall file offset of the start of the * data section of the file. */ @@ -3033,16 +3240,17 @@ SerializeCentralDirectorySuffix( * suffix of the central directory (i.e., * where this data will be written). */ { - ZipWriteInt(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); - ZipWriteShort(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); - ZipWriteShort(buf + ZIP_CENTRAL_ENTS_OFFS, entryCount); - ZipWriteShort(buf + ZIP_CENTRAL_TOTALENTS_OFFS, entryCount); - ZipWriteInt(buf + ZIP_CENTRAL_DIRSIZE_OFFS, + ZipWriteInt(start, end, buf + ZIP_CENTRAL_END_SIG_OFFS, + ZIP_CENTRAL_END_SIG); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_DISKNO_OFFS, 0); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_ENTS_OFFS, entryCount); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_TOTALENTS_OFFS, entryCount); + ZipWriteInt(start, end, buf + ZIP_CENTRAL_DIRSIZE_OFFS, suffixStartOffset - directoryStartOffset); - ZipWriteInt(buf + ZIP_CENTRAL_DIRSTART_OFFS, + ZipWriteInt(start, end, buf + ZIP_CENTRAL_DIRSTART_OFFS, directoryStartOffset - dataStartOffset); - ZipWriteShort(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); + ZipWriteShort(start, end, buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); } /* @@ -3051,13 +3259,13 @@ SerializeCentralDirectorySuffix( * ZipFSMkZipObjCmd, ZipFSLMkZipObjCmd -- * * These procedures are invoked to process the [zipfs mkzip] and [zipfs - * lmkzip] commands. See description of ZipFSMkZipOrImgCmd(). + * lmkzip] commands. See description of ZipFSMkZipOrImg(). * * Results: * A standard Tcl result. * * Side effects: - * See description of ZipFSMkZipOrImgCmd(). + * See description of ZipFSMkZipOrImg(). * *------------------------------------------------------------------------- */ @@ -3076,15 +3284,14 @@ ZipFSMkZipObjCmd( return TCL_ERROR; } if (Tcl_IsSafe(interp)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "operation not permitted in a safe interpreter", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); + ZIPFS_ERROR(interp, "operation not permitted in a safe interpreter"); + ZIPFS_ERROR_CODE(interp, "SAFE_INTERP"); return TCL_ERROR; } stripPrefix = (objc > 3 ? objv[3] : NULL); password = (objc > 4 ? objv[4] : NULL); - return ZipFSMkZipOrImgObjCmd(interp, 0, objv[1], objv[2], NULL, NULL, + return ZipFSMkZipOrImg(interp, 0, objv[1], objv[2], NULL, NULL, stripPrefix, password); } @@ -3102,14 +3309,13 @@ ZipFSLMkZipObjCmd( return TCL_ERROR; } if (Tcl_IsSafe(interp)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "operation not permitted in a safe interpreter", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); + ZIPFS_ERROR(interp, "operation not permitted in a safe interpreter"); + ZIPFS_ERROR_CODE(interp, "SAFE_INTERP"); return TCL_ERROR; } password = (objc > 3 ? objv[3] : NULL); - return ZipFSMkZipOrImgObjCmd(interp, 0, objv[1], NULL, objv[2], NULL, + return ZipFSMkZipOrImg(interp, 0, objv[1], NULL, objv[2], NULL, NULL, password); } @@ -3119,13 +3325,13 @@ ZipFSLMkZipObjCmd( * ZipFSMkImgObjCmd, ZipFSLMkImgObjCmd -- * * These procedures are invoked to process the [zipfs mkimg] and [zipfs - * lmkimg] commands. See description of ZipFSMkZipOrImgCmd(). + * lmkimg] commands. See description of ZipFSMkZipOrImg(). * * Results: * A standard Tcl result. * * Side effects: - * See description of ZipFSMkZipOrImgCmd(). + * See description of ZipFSMkZipOrImg(). * *------------------------------------------------------------------------- */ @@ -3145,16 +3351,15 @@ ZipFSMkImgObjCmd( return TCL_ERROR; } if (Tcl_IsSafe(interp)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "operation not permitted in a safe interpreter", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); + ZIPFS_ERROR(interp, "operation not permitted in a safe interpreter"); + ZIPFS_ERROR_CODE(interp, "SAFE_INTERP"); return TCL_ERROR; } originFile = (objc > 5 ? objv[5] : NULL); stripPrefix = (objc > 3 ? objv[3] : NULL); password = (objc > 4 ? objv[4] : NULL); - return ZipFSMkZipOrImgObjCmd(interp, 1, objv[1], objv[2], NULL, + return ZipFSMkZipOrImg(interp, 1, objv[1], objv[2], NULL, originFile, stripPrefix, password); } @@ -3172,15 +3377,14 @@ ZipFSLMkImgObjCmd( return TCL_ERROR; } if (Tcl_IsSafe(interp)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "operation not permitted in a safe interpreter", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); + ZIPFS_ERROR(interp, "operation not permitted in a safe interpreter"); + ZIPFS_ERROR_CODE(interp, "SAFE_INTERP"); return TCL_ERROR; } originFile = (objc > 4 ? objv[4] : NULL); password = (objc > 3 ? objv[3] : NULL); - return ZipFSMkZipOrImgObjCmd(interp, 1, objv[1], NULL, objv[2], + return ZipFSMkZipOrImg(interp, 1, objv[1], NULL, objv[2], originFile, NULL, password); } @@ -3372,31 +3576,43 @@ ZipFSListObjCmd( Tcl_HashEntry *hPtr; Tcl_HashSearch search; Tcl_Obj *result = Tcl_GetObjResult(interp); + const char *options[] = {"-glob", "-regexp", NULL}; + enum list_options { OPT_GLOB, OPT_REGEXP }; + + /* + * Parse arguments. + */ if (objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); return TCL_ERROR; } if (objc == 3) { - int n; - char *what = Tcl_GetStringFromObj(objv[1], &n); + int idx; - if ((n >= 2) && (strncmp(what, "-glob", n) == 0)) { + if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", + 0, &idx) != TCL_OK) { + return TCL_ERROR; + } + switch (idx) { + case OPT_GLOB: pattern = Tcl_GetString(objv[2]); - } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { + break; + case OPT_REGEXP: regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); if (!regexp) { return TCL_ERROR; } - } else { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "unknown option \"%s\"", what)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_OPT", NULL); - return TCL_ERROR; + break; } } else if (objc == 2) { pattern = Tcl_GetString(objv[1]); } + + /* + * Scan for matching entries. + */ + ReadLock(); if (pattern) { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); @@ -3903,18 +4119,29 @@ ZipChannelOpen( { ZipEntry *z; ZipChannel *info; - int i, ch, trunc, wr, flags = 0; + int trunc = (mode & O_TRUNC) != 0; + int wr = (mode & (O_WRONLY | O_RDWR)) != 0; + int flags = 0; char cname[128]; - if ((mode & O_APPEND) - || ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR)))) { + /* + * Check for unsupported modes. + */ + + if ((mode & O_APPEND) || ((ZipFS.wrmax <= 0) && wr)) { + Tcl_SetErrno(EACCES); if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("unsupported open mode", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_MODE", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write access not supported: %s", + Tcl_PosixError(interp))); } return NULL; } + + /* + * Is the file there? + */ + WriteLock(); z = ZipFSLookup(filename); if (!z) { @@ -3926,188 +4153,161 @@ ZipChannelOpen( } goto error; } - trunc = (mode & O_TRUNC) != 0; - wr = (mode & (O_WRONLY | O_RDWR)) != 0; - if ((z->compressMethod != ZIP_COMPMETH_STORED) - && (z->compressMethod != ZIP_COMPMETH_DEFLATED)) { - ZIPFS_ERROR(interp, "unsupported compression method"); + + /* + * Do we support opening the file that way? + */ + + if (wr && z->isDirectory) { + Tcl_SetErrno(EISDIR); if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "COMP_METHOD", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unsupported file type: %s", + Tcl_PosixError(interp))); } goto error; } - if (wr && z->isDirectory) { - ZIPFS_ERROR(interp, "unsupported file type"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "FILE_TYPE", NULL); - } + if ((z->compressMethod != ZIP_COMPMETH_STORED) + && (z->compressMethod != ZIP_COMPMETH_DEFLATED)) { + ZIPFS_ERROR(interp, "unsupported compression method"); + ZIPFS_ERROR_CODE(interp, "COMP_METHOD"); goto error; } if (!trunc) { flags |= TCL_READABLE; if (z->isEncrypted && (z->zipFilePtr->passBuf[0] == 0)) { ZIPFS_ERROR(interp, "decryption failed"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "DECRYPT", NULL); - } + ZIPFS_ERROR_CODE(interp, "DECRYPT"); goto error; } else if (wr && !z->data && (z->numBytes > ZipFS.wrmax)) { ZIPFS_ERROR(interp, "file too large"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "FILE_SIZE", NULL); - } + ZIPFS_ERROR_CODE(interp, "FILE_SIZE"); goto error; } } else { flags = TCL_WRITABLE; } - info = (ZipChannel *) attemptckalloc(sizeof(ZipChannel)); + + info = AllocateZipChannel(interp); if (!info) { - ZIPFS_ERROR(interp, "out of memory"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); - } goto error; } info->zipFilePtr = z->zipFilePtr; info->zipEntryPtr = z; - info->numRead = 0; if (wr) { + /* + * Set up a writable channel. + */ + flags |= TCL_WRITABLE; - info->isWriting = 1; - info->isDirectory = 0; - info->maxWrite = ZipFS.wrmax; - info->iscompr = 0; - info->isEncrypted = 0; - info->ubuf = (unsigned char *) attemptckalloc(info->maxWrite); - if (!info->ubuf) { - merror0: - if (info->ubuf) { - ckfree(info->ubuf); - } + if (InitWritableChannel(interp, info, z, trunc) == TCL_ERROR) { ckfree(info); - ZIPFS_ERROR(interp, "out of memory"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); - } goto error; } - memset(info->ubuf, 0, info->maxWrite); - if (trunc) { - info->numBytes = 0; - } else if (z->data) { - unsigned int j = z->numBytes; - - if (j > info->maxWrite) { - j = info->maxWrite; - } - memcpy(info->ubuf, z->data, j); - info->numBytes = j; - } else { - unsigned char *zbuf = z->zipFilePtr->data + z->offset; - - if (z->isEncrypted) { - int len = z->zipFilePtr->passBuf[0] & 0xFF; - char passBuf[260]; - - for (i = 0; i < len; i++) { - ch = z->zipFilePtr->passBuf[len - i]; - passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - } - passBuf[i] = '\0'; - init_keys(passBuf, info->keys, crc32tab); - memset(passBuf, 0, sizeof(passBuf)); - for (i = 0; i < 12; i++) { - ch = info->ubuf[i]; - zdecode(info->keys, crc32tab, ch); - } - zbuf += i; - } - if (z->compressMethod == ZIP_COMPMETH_DEFLATED) { - z_stream stream; - int err; - unsigned char *cbuf = NULL; - - memset(&stream, 0, sizeof(z_stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = z->numCompressedBytes; - if (z->isEncrypted) { - unsigned int j; - - stream.avail_in -= 12; - cbuf = (unsigned char *) attemptckalloc(stream.avail_in); - if (!cbuf) { - goto merror0; - } - for (j = 0; j < stream.avail_in; j++) { - ch = info->ubuf[j]; - cbuf[j] = zdecode(info->keys, crc32tab, ch); - } - stream.next_in = cbuf; - } else { - stream.next_in = zbuf; - } - stream.next_out = info->ubuf; - stream.avail_out = info->maxWrite; - if (inflateInit2(&stream, -15) != Z_OK) { - goto cerror0; - } - err = inflate(&stream, Z_SYNC_FLUSH); - inflateEnd(&stream); - if ((err == Z_STREAM_END) - || ((err == Z_OK) && (stream.avail_in == 0))) { - if (cbuf) { - memset(info->keys, 0, sizeof(info->keys)); - ckfree(cbuf); - } - goto wrapchan; - } - cerror0: - if (cbuf) { - memset(info->keys, 0, sizeof(info->keys)); - ckfree(cbuf); - } - if (info->ubuf) { - ckfree(info->ubuf); - } - ckfree(info); - ZIPFS_ERROR(interp, "decompression error"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "CORRUPT", NULL); - } - goto error; - } else if (z->isEncrypted) { - for (i = 0; i < z->numBytes - 12; i++) { - ch = zbuf[i]; - info->ubuf[i] = zdecode(info->keys, crc32tab, ch); - } - } else { - memcpy(info->ubuf, zbuf, z->numBytes); - } - memset(info->keys, 0, sizeof(info->keys)); - goto wrapchan; - } } else if (z->data) { + /* + * Set up a readable channel for direct data. + */ + flags |= TCL_READABLE; - info->isWriting = 0; - info->iscompr = 0; - info->isDirectory = 0; - info->isEncrypted = 0; info->numBytes = z->numBytes; - info->maxWrite = 0; info->ubuf = z->data; } else { + /* + * Set up a readable channel. + */ + flags |= TCL_READABLE; - info->isWriting = 0; - info->iscompr = (z->compressMethod == ZIP_COMPMETH_DEFLATED); - info->ubuf = z->zipFilePtr->data + z->offset; - info->isDirectory = z->isDirectory; - info->isEncrypted = z->isEncrypted; - info->numBytes = z->numBytes; - info->maxWrite = 0; - if (info->isEncrypted) { + if (InitReadableChannel(interp, info, z) == TCL_ERROR) { + ckfree(info); + goto error; + } + } + + /* + * Wrap the ZipChannel into a Tcl_Channel. + */ + + sprintf(cname, "zipfs_%" TCL_Z_MODIFIER "x_%d", z->offset, + ZipFS.idCount++); + z->zipFilePtr->numOpen++; + Unlock(); + return Tcl_CreateChannel(&ZipChannelType, cname, info, flags); + + error: + Unlock(); + return NULL; +} + +/* + *------------------------------------------------------------------------- + * + * InitWritableChannel -- + * + * Assistant for ZipChannelOpen() that sets up a writable channel. It's + * up to the caller to actually register the channel. + * + * Returns: + * Tcl result code. + * + * Side effects: + * Allocates memory for the implementation of the channel. Writes to the + * interpreter's result on error. + * + *------------------------------------------------------------------------- + */ + +static int +InitWritableChannel( + Tcl_Interp *interp, /* Current interpreter, or NULL (when errors + * will be silent). */ + ZipChannel *info, /* The channel to set up. */ + ZipEntry *z, /* The zipped file that the channel will write + * to. */ + int trunc) /* Whether to truncate the data. */ +{ + int i, ch; + unsigned char *cbuf = NULL; + + /* + * Set up a writable channel. + */ + + info->isWriting = 1; + info->maxWrite = ZipFS.wrmax; + + info->ubuf = (unsigned char *) attemptckalloc(info->maxWrite); + if (!info->ubuf) { + goto memoryError; + } + memset(info->ubuf, 0, info->maxWrite); + + if (trunc) { + /* + * Truncate; nothing there. + */ + + info->numBytes = 0; + } else if (z->data) { + /* + * Already got uncompressed data. + */ + + unsigned int j = z->numBytes; + + if (j > info->maxWrite) { + j = info->maxWrite; + } + memcpy(info->ubuf, z->data, j); + info->numBytes = j; + } else { + /* + * Need to uncompress the existing data. + */ + + unsigned char *zbuf = z->zipFilePtr->data + z->offset; + + if (z->isEncrypted) { int len = z->zipFilePtr->passBuf[0] & 0xFF; char passBuf[260]; @@ -4122,119 +4322,244 @@ ZipChannelOpen( ch = info->ubuf[i]; zdecode(info->keys, crc32tab, ch); } - info->ubuf += i; + zbuf += i; } - if (info->iscompr) { + + if (z->compressMethod == ZIP_COMPMETH_DEFLATED) { z_stream stream; int err; - unsigned char *ubuf = NULL; - unsigned int j; memset(&stream, 0, sizeof(z_stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; stream.avail_in = z->numCompressedBytes; - if (info->isEncrypted) { + if (z->isEncrypted) { + unsigned int j; + stream.avail_in -= 12; - ubuf = (unsigned char *) attemptckalloc(stream.avail_in); - if (!ubuf) { - info->ubuf = NULL; - goto merror; + cbuf = (unsigned char *) attemptckalloc(stream.avail_in); + if (!cbuf) { + goto memoryError; } for (j = 0; j < stream.avail_in; j++) { ch = info->ubuf[j]; - ubuf[j] = zdecode(info->keys, crc32tab, ch); + cbuf[j] = zdecode(info->keys, crc32tab, ch); } - stream.next_in = ubuf; + stream.next_in = cbuf; } else { - stream.next_in = info->ubuf; - } - stream.next_out = info->ubuf = (unsigned char *) - attemptckalloc(info->numBytes); - if (!info->ubuf) { - merror: - if (ubuf) { - info->isEncrypted = 0; - memset(info->keys, 0, sizeof(info->keys)); - ckfree(ubuf); - } - ckfree(info); - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); - Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); - } - goto error; + stream.next_in = zbuf; } - stream.avail_out = info->numBytes; + stream.next_out = info->ubuf; + stream.avail_out = info->maxWrite; if (inflateInit2(&stream, -15) != Z_OK) { - goto cerror; + goto corruptionError; } err = inflate(&stream, Z_SYNC_FLUSH); inflateEnd(&stream); if ((err == Z_STREAM_END) || ((err == Z_OK) && (stream.avail_in == 0))) { - if (ubuf) { - info->isEncrypted = 0; + if (cbuf) { memset(info->keys, 0, sizeof(info->keys)); - ckfree(ubuf); + ckfree(cbuf); } - goto wrapchan; - } - cerror: - if (ubuf) { - info->isEncrypted = 0; - memset(info->keys, 0, sizeof(info->keys)); - ckfree(ubuf); - } - if (info->ubuf) { - ckfree(info->ubuf); - } - ckfree(info); - ZIPFS_ERROR(interp, "decompression error"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "CORRUPT", NULL); + return TCL_OK; } - goto error; - } else if (info->isEncrypted) { - unsigned char *ubuf = NULL; - unsigned int j, len; + goto corruptionError; + } else if (z->isEncrypted) { + /* + * Need to decrypt some otherwise-simple stored data. + */ + for (i = 0; i < z->numBytes - 12; i++) { + ch = zbuf[i]; + info->ubuf[i] = zdecode(info->keys, crc32tab, ch); + } + } else { /* - * Decode encrypted but uncompressed file, since we support - * Tcl_Seek() on it, and it can be randomly accessed later. + * Simple stored data. Copy into our working buffer. */ - len = z->numCompressedBytes - 12; - ubuf = (unsigned char *) attemptckalloc(len); - if (ubuf == NULL) { - ckfree((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); - } - goto error; + memcpy(info->ubuf, zbuf, z->numBytes); + } + memset(info->keys, 0, sizeof(info->keys)); + } + return TCL_OK; + + memoryError: + if (info->ubuf) { + ckfree(info->ubuf); + } + ZIPFS_MEM_ERROR(interp); + return TCL_ERROR; + + corruptionError: + if (cbuf) { + memset(info->keys, 0, sizeof(info->keys)); + ckfree(cbuf); + } + if (info->ubuf) { + ckfree(info->ubuf); + } + ZIPFS_ERROR(interp, "decompression error"); + ZIPFS_ERROR_CODE(interp, "CORRUPT"); + return TCL_ERROR; +} + +/* + *------------------------------------------------------------------------- + * + * InitReadableChannel -- + * + * Assistant for ZipChannelOpen() that sets up a readable channel. It's + * up to the caller to actually register the channel. + * + * Returns: + * Tcl result code. + * + * Side effects: + * Allocates memory for the implementation of the channel. Writes to the + * interpreter's result on error. + * + *------------------------------------------------------------------------- + */ + +static int +InitReadableChannel( + Tcl_Interp *interp, /* Current interpreter, or NULL (when errors + * will be silent). */ + ZipChannel *info, /* The channel to set up. */ + ZipEntry *z) /* The zipped file that the channel will read + * from. */ +{ + unsigned char *ubuf = NULL; + int i, ch; + + info->iscompr = (z->compressMethod == ZIP_COMPMETH_DEFLATED); + info->ubuf = z->zipFilePtr->data + z->offset; + info->isDirectory = z->isDirectory; + info->isEncrypted = z->isEncrypted; + info->numBytes = z->numBytes; + + if (info->isEncrypted) { + int len = z->zipFilePtr->passBuf[0] & 0xFF; + char passBuf[260]; + + for (i = 0; i < len; i++) { + ch = z->zipFilePtr->passBuf[len - i]; + passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + passBuf[i] = '\0'; + init_keys(passBuf, info->keys, crc32tab); + memset(passBuf, 0, sizeof(passBuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + info->ubuf += i; + } + + if (info->iscompr) { + z_stream stream; + int err; + unsigned int j; + + /* + * Data to decode is compressed, and possibly encrpyted too. + */ + + memset(&stream, 0, sizeof(z_stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->numCompressedBytes; + if (info->isEncrypted) { + stream.avail_in -= 12; + ubuf = (unsigned char *) attemptckalloc(stream.avail_in); + if (!ubuf) { + info->ubuf = NULL; + goto memoryError; } - for (j = 0; j < len; j++) { + + for (j = 0; j < stream.avail_in; j++) { ch = info->ubuf[j]; ubuf[j] = zdecode(info->keys, crc32tab, ch); } - info->ubuf = ubuf; + stream.next_in = ubuf; + } else { + stream.next_in = info->ubuf; + } + stream.next_out = info->ubuf = (unsigned char *) + attemptckalloc(info->numBytes); + if (!info->ubuf) { + goto memoryError; + } + stream.avail_out = info->numBytes; + if (inflateInit2(&stream, -15) != Z_OK) { + goto corruptionError; + } + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + + /* + * Decompression was successful if we're either in the END state, or + * in the OK state with no buffered bytes. + */ + + if ((err != Z_STREAM_END) + && ((err != Z_OK) || (stream.avail_in != 0))) { + goto corruptionError; + } + + if (ubuf) { info->isEncrypted = 0; + memset(info->keys, 0, sizeof(info->keys)); + ckfree(ubuf); + } + return TCL_OK; + } else if (info->isEncrypted) { + unsigned int j, len; + + /* + * Decode encrypted but uncompressed file, since we support Tcl_Seek() + * on it, and it can be randomly accessed later. + */ + + len = z->numCompressedBytes - 12; + ubuf = (unsigned char *) attemptckalloc(len); + if (ubuf == NULL) { + goto memoryError; + } + for (j = 0; j < len; j++) { + ch = info->ubuf[j]; + ubuf[j] = zdecode(info->keys, crc32tab, ch); } + info->ubuf = ubuf; + info->isEncrypted = 0; } + return TCL_OK; - wrapchan: - sprintf(cname, "zipfs_%" TCL_Z_MODIFIER "x_%d", z->offset, - ZipFS.idCount++); - z->zipFilePtr->numOpen++; - Unlock(); - return Tcl_CreateChannel(&ZipChannelType, cname, info, flags); + corruptionError: + if (ubuf) { + info->isEncrypted = 0; + memset(info->keys, 0, sizeof(info->keys)); + ckfree(ubuf); + } + if (info->ubuf) { + ckfree(info->ubuf); + } + ZIPFS_ERROR(interp, "decompression error"); + ZIPFS_ERROR_CODE(interp, "CORRUPT"); + return TCL_ERROR; - error: - Unlock(); - return NULL; + memoryError: + if (ubuf) { + info->isEncrypted = 0; + memset(info->keys, 0, sizeof(info->keys)); + ckfree(ubuf); + } + ZIPFS_MEM_ERROR(interp); + return TCL_ERROR; } /* @@ -4434,6 +4759,38 @@ ZipFSFilesystemSeparatorProc( /* *------------------------------------------------------------------------- * + * AppendWithPrefix -- + * + * Worker for ZipFSMatchInDirectoryProc() that is a wrapper around + * Tcl_ListObjAppendElement() which knows about handling prefixes. + * + *------------------------------------------------------------------------- + */ + +static inline void +AppendWithPrefix( + Tcl_Obj *result, /* Where to append a list element to. */ + Tcl_DString *prefix, /* The prefix to add to the element, or NULL + * for don't do that. */ + const char *name, /* The name to append. */ + int nameLen) /* The length of the name. May be -1 for + * append-up-to-NUL-byte. */ +{ + if (prefix) { + int prefixLength = Tcl_DStringLength(prefix); + + Tcl_DStringAppend(prefix, name, nameLen); + Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj( + Tcl_DStringValue(prefix), Tcl_DStringLength(prefix))); + Tcl_DStringSetLength(prefix, prefixLength); + } else { + Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(name, nameLen)); + } +} + +/* + *------------------------------------------------------------------------- + * * ZipFSMatchInDirectoryProc -- * * This routine is used by the globbing code to search a directory for @@ -4453,24 +4810,25 @@ ZipFSFilesystemSeparatorProc( static int ZipFSMatchInDirectoryProc( TCL_UNUSED(Tcl_Interp *), - Tcl_Obj *result, - Tcl_Obj *pathPtr, - const char *pattern, - Tcl_GlobTypeData *types) + Tcl_Obj *result, /* Where to append matched items to. */ + Tcl_Obj *pathPtr, /* Where we are looking. */ + const char *pattern, /* What names we are looking for. */ + Tcl_GlobTypeData *types) /* What types we are looking for. */ { Tcl_HashEntry *hPtr; Tcl_HashSearch search; Tcl_Obj *normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); - int scnt, l, dirOnly = -1, prefixLen, strip = 0; + int scnt, l, dirOnly = -1, prefixLen, strip = 0, mounts = 0; size_t len; char *pat, *prefix, *path; - Tcl_DString dsPref; + Tcl_DString dsPref, *prefixBuf = NULL; if (!normPathPtr) { return -1; } if (types) { dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; + mounts = (types->type == TCL_GLOB_TYPE_MOUNT); } /* @@ -4487,101 +4845,53 @@ ZipFSMatchInDirectoryProc( len = normPathPtr->length; Tcl_DStringInit(&dsPref); - Tcl_DStringAppend(&dsPref, prefix, prefixLen); - if (strcmp(prefix, path) == 0) { - prefix = NULL; + prefixBuf = NULL; } else { + /* + * We need to strip the normalized prefix of the filenames and replace + * it with the official prefix that we were expecting to get. + */ + strip = len + 1; - } - if (prefix) { + Tcl_DStringAppend(&dsPref, prefix, prefixLen); Tcl_DStringAppend(&dsPref, "/", 1); - prefixLen++; prefix = Tcl_DStringValue(&dsPref); + prefixBuf = &dsPref; } + ReadLock(); - if (types && (types->type == TCL_GLOB_TYPE_MOUNT)) { - l = CountSlashes(path); - if (path[len - 1] == '/') { - len--; - } else { - l++; - } - if (!pattern || (pattern[0] == '\0')) { - pattern = "*"; - } - for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; - hPtr = Tcl_NextHashEntry(&search)) { - ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); - - if (zf->mountPointLen == 0) { - ZipEntry *z; - - for (z = zf->topEnts; z; z = z->tnext) { - size_t lenz = strlen(z->name); - - if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0) - && (z->name[len] == '/') - && (CountSlashes(z->name) == l) - && Tcl_StringCaseMatch(z->name + len + 1, pattern, - 0)) { - if (prefix) { - Tcl_DStringAppend(&dsPref, z->name, lenz); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name, lenz)); - } - } - } - } else if ((zf->mountPointLen > len + 1) - && (strncmp(zf->mountPoint, path, len) == 0) - && (zf->mountPoint[len] == '/') - && (CountSlashes(zf->mountPoint) == l) - && Tcl_StringCaseMatch(zf->mountPoint + len + 1, - pattern, 0)) { - if (prefix) { - Tcl_DStringAppend(&dsPref, zf->mountPoint, - zf->mountPointLen); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(zf->mountPoint, - zf->mountPointLen)); - } - } - } + + /* + * Are we globbing the mount points? + */ + + if (mounts) { + ZipFSMatchMountPoints(result, normPathPtr, pattern, prefixBuf); goto end; } + /* + * Can we skip the complexity of actual globbing? Without a pattern, yes; + * it's a directory existence test. + */ + if (!pattern || (pattern[0] == '\0')) { - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + ZipEntry *z = ZipFSLookup(path); - if ((dirOnly < 0) || (!dirOnly && !z->isDirectory) - || (dirOnly && z->isDirectory)) { - if (prefix) { - Tcl_DStringAppend(&dsPref, z->name, -1); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name, -1)); - } - } + if (z && ((dirOnly < 0) || (!dirOnly && !z->isDirectory) + || (dirOnly && z->isDirectory))) { + AppendWithPrefix(result, prefixBuf, z->name, -1); } goto end; } + /* + * We've got to work for our supper and do the actual globbing. And all + * we've got really is an undifferentiated pile of all the filenames we've + * got from all our ZIP mounts. + */ + l = strlen(pattern); pat = (char *) ckalloc(len + l + 2); memcpy(pat, path, len); @@ -4594,6 +4904,7 @@ ZipFSMatchInDirectoryProc( } memcpy(pat + len, pattern, l + 1); scnt = CountSlashes(pat); + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); @@ -4603,16 +4914,7 @@ ZipFSMatchInDirectoryProc( continue; } if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { - if (prefix) { - Tcl_DStringAppend(&dsPref, z->name + strip, -1); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name + strip, -1)); - } + AppendWithPrefix(result, prefixBuf, z->name + strip, -1); } } ckfree(pat); @@ -4626,6 +4928,87 @@ ZipFSMatchInDirectoryProc( /* *------------------------------------------------------------------------- * + * ZipFSMatchMountPoints -- + * + * This routine is a worker for ZipFSMatchInDirectoryProc, used by the + * globbing code to search for all mount points files which match a given + * pattern. + * + * Results: + * None. + * + * Side effects: + * Adds the matching mounts to the list in result, uses prefix as working + * space if it is non-NULL. + * + *------------------------------------------------------------------------- + */ + +static void +ZipFSMatchMountPoints( + Tcl_Obj *result, /* The list of matches being built. */ + Tcl_Obj *normPathPtr, /* Where we're looking from. */ + const char *pattern, /* What we're looking for. NULL for a full + * list. */ + Tcl_DString *prefix) /* Workspace filled with a prefix for all the + * filenames, or NULL if no prefix is to be + * used. */ +{ + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + int l, normLength; + const char *path = Tcl_GetStringFromObj(normPathPtr, &normLength); + size_t len = (size_t) normLength; + + l = CountSlashes(path); + if (path[len - 1] == '/') { + len--; + } else { + l++; + } + if (!pattern || (pattern[0] == '\0')) { + pattern = "*"; + } + + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { + ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); + + if (zf->mountPointLen == 0) { + ZipEntry *z; + + /* + * Enumerate the contents of the ZIP; it's mounted on the root. + */ + + for (z = zf->topEnts; z; z = z->tnext) { + size_t lenz = strlen(z->name); + + if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0) + && (z->name[len] == '/') + && (CountSlashes(z->name) == l) + && Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) { + AppendWithPrefix(result, prefix, z->name, lenz); + } + } + } else if ((zf->mountPointLen > len + 1) + && (strncmp(zf->mountPoint, path, len) == 0) + && (zf->mountPoint[len] == '/') + && (CountSlashes(zf->mountPoint) == l) + && Tcl_StringCaseMatch(zf->mountPoint + len + 1, + pattern, 0)) { + /* + * Standard mount; append if it matches. + */ + + AppendWithPrefix(result, prefix, zf->mountPoint, zf->mountPointLen); + } + } +} + +/* + *------------------------------------------------------------------------- + * * ZipFSPathInFilesystemProc -- * * This function determines if the given path object is in the ZIP @@ -4821,6 +5204,7 @@ ZipFSFileAttrsGetProc( break; default: ZIPFS_ERROR(interp, "unknown attribute"); + ZIPFS_ERROR_CODE(interp, "FILE_ATTR"); ret = TCL_ERROR; } @@ -4853,10 +5237,8 @@ ZipFSFileAttrsSetProc( TCL_UNUSED(Tcl_Obj *) /*pathPtr*/, TCL_UNUSED(Tcl_Obj *) /*objPtr*/) { - if (interp) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "UNSUPPORTED_OP", NULL); - } + ZIPFS_ERROR(interp, "unsupported operation"); + ZIPFS_ERROR_CODE(interp, "UNSUPPORTED_OP"); return TCL_ERROR; } @@ -4958,7 +5340,7 @@ ZipFSLoadFile( if (execName) { const char *p = strrchr(execName, '/'); - if (p > execName + 1) { + if (p && p > execName + 1) { --p; objs[0] = Tcl_NewStringObj(execName, p - execName); } @@ -5074,8 +5456,10 @@ TclZipfs_Init( Tcl_Obj *mapObj; Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); - Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, - TCL_LINK_INT); + if (Tcl_IsSafe(interp)) { + Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, + TCL_LINK_INT); + } ensemble = TclMakeEnsemble(interp, "zipfs", Tcl_IsSafe(interp) ? (initMap + 4) : initMap); @@ -5093,7 +5477,7 @@ TclZipfs_Init( return TCL_OK; #else /* !HAVE_ZLIB */ ZIPFS_ERROR(interp, "no zlib available"); - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_ZLIB", NULL); + ZIPFS_ERROR_CODE(interp, "NO_ZLIB"); return TCL_ERROR; #endif /* HAVE_ZLIB */ } @@ -5303,9 +5687,7 @@ TclZipfs_Mount( * the ZIP is unprotected. */ { ZIPFS_ERROR(interp, "no zlib available"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_ZLIB", NULL); - } + ZIPFS_ERROR_CODE(interp, "NO_ZLIB"); return TCL_ERROR; } @@ -5318,9 +5700,7 @@ TclZipfs_MountBuffer( int copy) { ZIPFS_ERROR(interp, "no zlib available"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_ZLIB", NULL); - } + ZIPFS_ERROR_CODE(interp, "NO_ZLIB"); return TCL_ERROR; } @@ -5330,9 +5710,7 @@ TclZipfs_Unmount( const char *mountPoint) /* Mount point path. */ { ZIPFS_ERROR(interp, "no zlib available"); - if (interp) { - Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_ZLIB", NULL); - } + ZIPFS_ERROR_CODE(interp, "NO_ZLIB"); return TCL_ERROR; } #endif /* !HAVE_ZLIB */ diff --git a/tests/zipfs.test b/tests/zipfs.test index 36fc6d6..eba2a1e 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -381,9 +381,21 @@ test zipfs-4.5 {zipfs lmkimg: making image from mounted} -constraints zipfs -set removeFile $addFile } -result {//zipfs://ziptest/test/add.tcl //zipfs://ziptest/test/ok.tcl} -test zipfs-5.1 {zipfs mount_data: short data} -body { +test zipfs-5.1 {zipfs mount_data: short data} -constraints zipfs -body { zipfs mount_data gorp {} -} -constraints zipfs -returnCodes error -result {bad zip data} +} -returnCodes error -result {bad zip data} +test zipfs-5.2 {zipfs mount_data: short data} -constraints zipfs -body { + zipfs mount_data gorp gorpGORPgorp +} -returnCodes error -result {bad zip data} +test zipfs-5.3 {zipfs mount_data: short data} -constraints zipfs -body { + set data PK\x03\x04..................................... + append data PK\x01\x02..................................... + append data PK\x05\x06..................................... + zipfs mount_data gorp $data +} -returnCodes error -result {bad zip data} +test zipfs-5.4 {zipfs mount_data: bad arg count} -constraints zipfs -body { + zipfs mount_data gorp {} foobar +} -returnCodes error -result {wrong # args: should be "zipfs mount_data ?mountpoint? ?data?"} ::tcltest::cleanupTests return -- cgit v0.12 From b0e0d4b618d58c962735cb62982229a8f67fb632 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 14 Mar 2021 16:12:25 +0000 Subject: Document that Tcl_UtfCharComplete() can (now) be used to protect Tcl_UtfNext() calls against overflow, if the string being handled is not NULL-terminated. --- doc/Utf.3 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/Utf.3 b/doc/Utf.3 index cca6498..9687eb6 100644 --- a/doc/Utf.3 +++ b/doc/Utf.3 @@ -141,8 +141,8 @@ source buffer is long enough such that this routine does not run off the end and dereference non-existent or random memory; if the source buffer is known to be null-terminated, this will not happen. If the input is not in proper UTF-8 format, \fBTcl_UtfToUniChar\fR will store the first -byte of \fIsrc\fR in \fI*chPtr\fR as a Tcl_UniChar between 0x0080 and -0x00FF and return 1. +byte of \fIsrc\fR in \fI*chPtr\fR as a Tcl_UniChar between 0x80 and +0xFF and return 1. .PP \fBTcl_UniCharToUtfDString\fR converts the given Unicode string to UTF-8, storing the result in a previously initialized \fBTcl_DString\fR. @@ -197,10 +197,10 @@ characters. .PP \fBTcl_UtfCharComplete\fR returns 1 if the source UTF-8 string \fIsrc\fR of \fIlength\fR bytes is long enough to be decoded by -\fBTcl_UtfToUniChar\fR, or 0 otherwise. This function does not guarantee -that the UTF-8 string is properly formed. This routine is used by -procedures that are operating on a byte at a time and need to know if a -full Tcl_UniChar has been seen. +\fBTcl_UtfToUniChar\fR/\fBTcl_UtfNext\fR, or 0 otherwise. This function +does not guarantee that the UTF-8 string is properly formed. This routine +is used by procedures that are operating on a byte at a time and need to +know if a full Tcl_UniChar has been seen. .PP \fBTcl_NumUtfChars\fR corresponds to \fBstrlen\fR for UTF-8 strings. It returns the number of Tcl_UniChars that are represented by the UTF-8 string @@ -221,7 +221,8 @@ Given \fIsrc\fR, a pointer to some location in a UTF-8 string, \fBTcl_UtfNext\fR returns a pointer to the next UTF-8 character in the string. The caller must not ask for the next character after the last character in the string if the string is not terminated by a null -character. +character. \fBTcl_UtfCharComplete\fR can be used in that case to +make sure enough bytes are available before calling \fBTcl_UtfNext\fR. .PP \fBTcl_UtfPrev\fR is used to step backward through but not beyond the UTF-8 string that begins at \fIstart\fR. If the UTF-8 string is made -- cgit v0.12 From 1f2858fefd73a6dfd349b59ff63427810467b2ac Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 14 Mar 2021 20:53:39 +0000 Subject: Flipped a test --- generic/tclZipfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index ffad98f..adb3bf7 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -5456,7 +5456,7 @@ TclZipfs_Init( Tcl_Obj *mapObj; Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); - if (Tcl_IsSafe(interp)) { + if (!Tcl_IsSafe(interp)) { Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, TCL_LINK_INT); } -- cgit v0.12 From 57bf9fe12f8859459556da1de27dbdef24048a68 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 15 Mar 2021 09:52:02 +0000 Subject: More refactoring to reduce the choked-up complexity of tclZipfs.c --- generic/tclIO.c | 3 +- generic/tclZipfs.c | 327 ++++++++++++++++++++++++++++++----------------------- 2 files changed, 190 insertions(+), 140 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 9cace8c..3954af2 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3387,7 +3387,8 @@ int Tcl_Close( Tcl_Interp *interp, /* Interpreter for errors. */ Tcl_Channel chan) /* The channel being closed. Must not be - * referenced in any interpreter. */ + * referenced in any interpreter. May be NULL, + * in which case this is a no-op. */ { CloseCallback *cbPtr; /* Iterate over close callbacks for this * channel. */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index adb3bf7..05affa8 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -169,6 +169,12 @@ TCL_DECLARE_MUTEX(localtimeMutex) #endif /* !_WIN32 && !HAVE_LOCALTIME_R && TCL_THREADS */ /* + * Forward declaration. + */ + +struct ZipEntry; + +/* * In-core description of mounted ZIP archive file. */ @@ -197,6 +203,7 @@ typedef struct ZipFile { /* * In-core description of file contained in mounted ZIP archive. + * ZIP_ATTR_ */ typedef struct ZipEntry { @@ -252,7 +259,9 @@ static struct { int initialized; /* True when initialized */ int lock; /* RW lock, see below */ int waiters; /* RW lock, see below */ - int wrmax; /* Maximum write size of a file */ + int wrmax; /* Maximum write size of a file; only written + * to from Tcl code in a trusted interpreter, + * so NOT protected by mutex. */ int idCount; /* Counter for channel names */ Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ @@ -388,27 +397,28 @@ static const Tcl_Filesystem zipfsFilesystem = { */ static Tcl_ChannelType ZipChannelType = { - "zip", /* Type name. */ + "zip", /* Type name. */ TCL_CHANNEL_VERSION_5, - TCL_CLOSE2PROC, /* Close channel, clean instance data */ - ZipChannelRead, /* Handle read request */ - ZipChannelWrite, /* Handle write request */ + TCL_CLOSE2PROC, /* Close channel, clean instance data */ + ZipChannelRead, /* Handle read request */ + ZipChannelWrite, /* Handle write request */ #ifndef TCL_NO_DEPRECATED - ZipChannelSeek, /* Move location of access point, NULL'able */ + ZipChannelSeek, /* Move location of access point, NULL'able */ #else - NULL, /* Move location of access point, NULL'able */ + NULL, /* Move location of access point, NULL'able */ #endif - NULL, /* Set options, NULL'able */ - NULL, /* Get options, NULL'able */ - ZipChannelWatchChannel, /* Initialize notifier */ - ZipChannelGetFile, /* Get OS handle from the channel */ - ZipChannelClose, /* 2nd version of close channel, NULL'able */ - NULL, /* Set blocking mode for raw channel, NULL'able */ - NULL, /* Function to flush channel, NULL'able */ - NULL, /* Function to handle event, NULL'able */ - ZipChannelWideSeek, /* Wide seek function, NULL'able */ - NULL, /* Thread action function, NULL'able */ - NULL, /* Truncate function, NULL'able */ + NULL, /* Set options, NULL'able */ + NULL, /* Get options, NULL'able */ + ZipChannelWatchChannel, /* Initialize notifier */ + ZipChannelGetFile, /* Get OS handle from the channel */ + ZipChannelClose, /* 2nd version of close channel, NULL'able */ + NULL, /* Set blocking mode for raw channel, + * NULL'able */ + NULL, /* Function to flush channel, NULL'able */ + NULL, /* Function to handle event, NULL'able */ + ZipChannelWideSeek, /* Wide seek function, NULL'able */ + NULL, /* Thread action function, NULL'able */ + NULL, /* Truncate function, NULL'able */ }; /* @@ -511,7 +521,7 @@ TCL_DECLARE_MUTEX(ZipFSMutex) static Tcl_Condition ZipFSCond; -static void +static inline void ReadLock(void) { Tcl_MutexLock(&ZipFSMutex); @@ -524,7 +534,7 @@ ReadLock(void) Tcl_MutexUnlock(&ZipFSMutex); } -static void +static inline void WriteLock(void) { Tcl_MutexLock(&ZipFSMutex); @@ -537,7 +547,7 @@ WriteLock(void) Tcl_MutexUnlock(&ZipFSMutex); } -static void +static inline void Unlock(void) { Tcl_MutexLock(&ZipFSMutex); @@ -657,7 +667,7 @@ ToDosDate( *------------------------------------------------------------------------- */ -static int +static inline int CountSlashes( const char *string) { @@ -861,7 +871,7 @@ CanonicalPath( *------------------------------------------------------------------------- */ -static ZipEntry * +static inline ZipEntry * ZipFSLookup( char *filename) { @@ -892,7 +902,7 @@ ZipFSLookup( *------------------------------------------------------------------------- */ -static ZipFile * +static inline ZipFile * ZipFSLookupZip( const char *mountPoint) { @@ -925,7 +935,7 @@ ZipFSLookupZip( *------------------------------------------------------------------------- */ -static ZipFile * +static inline ZipFile * AllocateZipFile( Tcl_Interp *interp, size_t mountPointNameLength) @@ -941,7 +951,7 @@ AllocateZipFile( return zf; } -static ZipEntry * +static inline ZipEntry * AllocateZipEntry(void) { ZipEntry *z = (ZipEntry *) ckalloc(sizeof(ZipEntry)); @@ -949,7 +959,7 @@ AllocateZipEntry(void) return z; } -static ZipChannel * +static inline ZipChannel * AllocateZipChannel( Tcl_Interp *interp) { @@ -1391,16 +1401,17 @@ IsPasswordValid( /* *------------------------------------------------------------------------- * - * ZipFSRootNode -- + * ZipFSCatalogFilesystem -- * - * This function generates the root node for a ZIPFS filesystem. + * This function generates the root node for a ZIPFS filesystem by + * reading the ZIP's central directory. * * Results: * TCL_OK on success, TCL_ERROR otherwise with an error message placed * into the given "interp" if it is not NULL. * * Side effects: - * ... + * Will acquire and release the write lock. * *------------------------------------------------------------------------- */ @@ -2022,6 +2033,12 @@ TclZipfs_Unmount( goto done; } Tcl_DeleteHashEntry(hPtr); + + /* + * Now no longer mounted - the rest of the code won't find it - but we're + * still cleaning things up. + */ + for (z = zf->entries; z; z = znext) { znext = z->next; hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); @@ -2037,6 +2054,7 @@ TclZipfs_Unmount( Tcl_DeleteExitHandler(ZipfsExitHandler, zf); ckfree(zf); unmounted = 1; + done: Unlock(); if (unmounted) { @@ -2339,14 +2357,15 @@ RandomChar( static int ZipAddFile( Tcl_Interp *interp, /* Current interpreter. */ - const char *path, - const char *name, - Tcl_Channel out, + Tcl_Obj *pathObj, /* Actual name of the file to add. */ + const char *name, /* Name to use in the ZIP archive. */ + Tcl_Channel out, /* The open ZIP archive being built. */ const char *passwd, /* Password for encoding the file, or NULL if * the file is to be unprotected. */ - char *buf, - int bufsize, - Tcl_HashTable *fileHash) + char *buf, /* Working buffer. */ + int bufsize, /* Size of buf */ + Tcl_HashTable *fileHash) /* Where to record ZIP entry metdata so we can + * built the central directory. */ { const unsigned char *start = (unsigned char *) buf; const unsigned char *end = (unsigned char *) buf + bufsize; @@ -2378,11 +2397,11 @@ ZipAddFile( zpathlen = strlen(zpath); if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "path too long for \"%s\"", path)); + "path too long for \"%s\"", Tcl_GetString(pathObj))); ZIPFS_ERROR_CODE(interp, "PATH_LEN"); return TCL_ERROR; } - in = Tcl_OpenFileChannel(interp, path, "rb", 0); + in = Tcl_FSOpenFileChannel(interp, pathObj, "rb", 0); if (!in) { #ifdef _WIN32 /* hopefully a directory */ @@ -2394,14 +2413,11 @@ ZipAddFile( Tcl_Close(interp, in); return TCL_ERROR; } else { - Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1); Tcl_StatBuf statBuf; - Tcl_IncrRefCount(pathObj); if (Tcl_FSStat(pathObj, &statBuf) != -1) { mtime = statBuf.st_mtime; } - Tcl_DecrRefCount(pathObj); } Tcl_ResetResult(interp); @@ -2418,8 +2434,9 @@ ZipAddFile( Tcl_Close(interp, in); return TCL_OK; } + readErrorWithChannelOpen: Tcl_SetObjResult(interp, Tcl_ObjPrintf("read error on \"%s\": %s", - path, Tcl_PosixError(interp))); + Tcl_GetString(pathObj), Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2431,7 +2448,7 @@ ZipAddFile( } if (Tcl_Seek(in, 0, SEEK_SET) == -1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("seek error on \"%s\": %s", - path, Tcl_PosixError(interp))); + Tcl_GetString(pathObj), Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2452,9 +2469,10 @@ ZipAddFile( memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); len = zpathlen + ZIP_LOCAL_HEADER_LEN; if ((size_t) Tcl_Write(out, buf, len) != len) { - wrerr: + writeErrorWithChannelOpen: Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "write error on %s: %s", path, Tcl_PosixError(interp))); + "write error on \"%s\": %s", + Tcl_GetString(pathObj), Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2474,7 +2492,7 @@ ZipAddFile( ZipWriteShort(astart, aend, abuf + 2, align - 4); ZipWriteInt(astart, aend, abuf + 4, 0x03020100); if ((size_t) Tcl_Write(out, (const char *) abuf, align) != align) { - goto wrerr; + goto writeErrorWithChannelOpen; } } @@ -2504,10 +2522,7 @@ ZipAddFile( len = Tcl_Write(out, (char *) kvbuf, 12); memset(kvbuf, 0, 24); if (len != 12) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "write error on %s: %s", path, Tcl_PosixError(interp))); - Tcl_Close(interp, in); - return TCL_ERROR; + goto writeErrorWithChannelOpen; } memcpy(keys0, keys, sizeof(keys0)); nbytecompr += 12; @@ -2532,19 +2547,17 @@ ZipAddFile( if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "compression init error on \"%s\"", path)); + "compression init error on \"%s\"", Tcl_GetString(pathObj))); ZIPFS_ERROR_CODE(interp, "DEFLATE_INIT"); Tcl_Close(interp, in); return TCL_ERROR; } + do { len = Tcl_Read(in, buf, bufsize); if (len == ERROR_LENGTH) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "read error on %s: %s", path, Tcl_PosixError(interp))); deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; + goto readErrorWithChannelOpen; } stream.avail_in = len; stream.next_in = (unsigned char *) buf; @@ -2555,7 +2568,7 @@ ZipAddFile( len = deflate(&stream, flush); if (len == (size_t) Z_STREAM_ERROR) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "deflate error on %s", path)); + "deflate error on \"%s\"", Tcl_GetString(pathObj))); ZIPFS_ERROR_CODE(interp, "DEFLATE"); deflateEnd(&stream); Tcl_Close(interp, in); @@ -2571,11 +2584,8 @@ ZipAddFile( } } if (olen && ((size_t) Tcl_Write(out, obuf, olen) != olen)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "write error: %s", Tcl_PosixError(interp))); deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; + goto writeErrorWithChannelOpen; } nbytecompr += olen; } while (stream.avail_out == 0); @@ -2599,20 +2609,16 @@ ZipAddFile( } if (Tcl_Seek(out, dataStartOffset, SEEK_SET) != dataStartOffset) { seekErr: - Tcl_Close(interp, in); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "seek error: %s", Tcl_PosixError(interp))); + Tcl_Close(interp, in); return TCL_ERROR; } nbytecompr = (passwd ? 12 : 0); while (1) { len = Tcl_Read(in, buf, bufsize); if (len == ERROR_LENGTH) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "read error on \"%s\": %s", - path, Tcl_PosixError(interp))); - Tcl_Close(interp, in); - return TCL_ERROR; + goto readErrorWithChannelOpen; } else if (len == 0) { break; } @@ -2625,10 +2631,7 @@ ZipAddFile( } } if ((size_t) Tcl_Write(out, buf, len) != len) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "write error: %s", Tcl_PosixError(interp))); - Tcl_Close(interp, in); - return TCL_ERROR; + goto writeErrorWithChannelOpen; } nbytecompr += len; } @@ -2648,7 +2651,7 @@ ZipAddFile( hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "non-unique path name \"%s\"", path)); + "non-unique path name \"%s\"", Tcl_GetString(pathObj))); ZIPFS_ERROR_CODE(interp, "DUPLICATE_PATH"); return TCL_ERROR; } @@ -2734,6 +2737,59 @@ ZipFSFind( /* *------------------------------------------------------------------------- * + * ComputeNameInArchive -- + * + * Helper for ZipFSMkZipOrImg() that computes what the actual name of a + * file in the ZIP archive should be, stripping a prefix (if appropriate) + * and any leading slashes. If the result is an empty string, the entry + * should be skipped. + * + * Returns: + * Pointer to the name, which will be in memory owned by one of the + * argument objects. + * + * Side effects: + * None (if Tcl_Objs have string representations) + * + *------------------------------------------------------------------------- + */ + +static inline const char * +ComputeNameInArchive( + Tcl_Obj *pathObj, /* The path to the origin file */ + Tcl_Obj *directNameObj, /* User-specified name for use in the ZIP + * archive */ + const char *strip, /* A prefix to strip */ + int slen) /* The length of the prefix */ +{ + const char *name; + int len; + + if (directNameObj) { + name = Tcl_GetString(directNameObj); + } else { + name = Tcl_GetStringFromObj(pathObj, &len); + if (slen > 0) { + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + /* + * Guaranteed to be a NUL at the end, which will make this + * entry be skipped. + */ + + return name + len; + } + name += slen; + } + } + while (name[0] == '/') { + ++name; + } + return name; +} + +/* + *------------------------------------------------------------------------- + * * ZipFSMkZipOrImg -- * * This procedure is creates a new ZIP archive file or image file given @@ -2829,7 +2885,7 @@ ZipFSMkZipOrImg( ZIPFS_ERROR_CODE(interp, "EMPTY"); return TCL_ERROR; } - out = Tcl_OpenFileChannel(interp, Tcl_GetString(targetFile), "wb", 0755); + out = Tcl_FSOpenFileChannel(interp, targetFile, "wb", 0755); if (out == NULL) { Tcl_DecrRefCount(list); return TCL_ERROR; @@ -2956,29 +3012,14 @@ ZipFSMkZipOrImg( strip = Tcl_GetStringFromObj(stripPrefix, &slen); } for (i = 0; i < (size_t) lobjc; i += (mappingList ? 2 : 1)) { - const char *path, *name; + Tcl_Obj *pathObj = lobjv[i]; + const char *name = ComputeNameInArchive(pathObj, + (mappingList ? lobjv[i + 1] : NULL), strip, slen); - path = Tcl_GetString(lobjv[i]); - if (mappingList) { - name = Tcl_GetString(lobjv[i + 1]); - } else { - name = path; - if (slen > 0) { - len = strlen(name); - if ((len <= (size_t) slen) || - (strncmp(strip, name, slen) != 0)) { - continue; - } - name += slen; - } - } - while (name[0] == '/') { - ++name; - } if (name[0] == '\0') { continue; } - if (ZipAddFile(interp, path, name, out, pw, buf, sizeof(buf), + if (ZipAddFile(interp, pathObj, name, out, pw, buf, sizeof(buf), &fileHash) != TCL_OK) { goto done; } @@ -2991,25 +3032,9 @@ ZipFSMkZipOrImg( directoryStartOffset = Tcl_Tell(out); count = 0; for (i = 0; i < (size_t) lobjc; i += (mappingList ? 2 : 1)) { - const char *path, *name; + const char *name = ComputeNameInArchive(lobjv[i], + (mappingList ? lobjv[i + 1] : NULL), strip, slen); - path = Tcl_GetString(lobjv[i]); - if (mappingList) { - name = Tcl_GetString(lobjv[i + 1]); - } else { - name = path; - if (slen > 0) { - len = strlen(name); - if ((len <= (size_t) slen) || - (strncmp(strip, name, slen) != 0)) { - continue; - } - name += slen; - } - } - while (name[0] == '/') { - ++name; - } if (name[0] == '\0') { continue; } @@ -3500,7 +3525,7 @@ ZipFSExistsObjCmd( * * ZipFSInfoObjCmd -- * - * This procedure is invoked to process the [zipfs info] command. On + * This procedure is invoked to process the [zipfs info] command. On * success, it returns a Tcl list made up of name of ZIP archive file, * size uncompressed, size compressed, and archive offset of a file in * the ZIP filesystem. @@ -4099,7 +4124,7 @@ ZipChannelGetFile( * ZipChannelOpen -- * * This function opens a Tcl_Channel on a file from a mounted ZIP archive - * according to given open mode. + * according to given open mode (already parsed by caller). * * Results: * Tcl_Channel on success, or NULL on error. @@ -4113,32 +4138,16 @@ ZipChannelGetFile( static Tcl_Channel ZipChannelOpen( Tcl_Interp *interp, /* Current interpreter. */ - char *filename, - int mode, - TCL_UNUSED(int) /*permissions*/) + char *filename, /* What are we opening. */ + int wr, /* True if we're opening in write mode. */ + int trunc) /* True if we're opening in truncate mode. */ { ZipEntry *z; ZipChannel *info; - int trunc = (mode & O_TRUNC) != 0; - int wr = (mode & (O_WRONLY | O_RDWR)) != 0; int flags = 0; char cname[128]; /* - * Check for unsupported modes. - */ - - if ((mode & O_APPEND) || ((ZipFS.wrmax <= 0) && wr)) { - Tcl_SetErrno(EACCES); - if (interp) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "write access not supported: %s", - Tcl_PosixError(interp))); - } - return NULL; - } - - /* * Is the file there? */ @@ -4644,9 +4653,14 @@ ZipEntryAccess( * * ZipFSOpenFileChannelProc -- * + * Open a channel to a file in a mounted ZIP archive. Delegates to + * ZipChannelOpen(). + * * Results: + * Tcl_Channel on success, or NULL on error. * * Side effects: + * Allocates memory. * *------------------------------------------------------------------------- */ @@ -4656,16 +4670,33 @@ ZipFSOpenFileChannelProc( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *pathPtr, int mode, - int permissions) + TCL_UNUSED(int) /* permissions */) { + int trunc = (mode & O_TRUNC) != 0; + int wr = (mode & (O_WRONLY | O_RDWR)) != 0; int len; pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (!pathPtr) { return NULL; } - return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), mode, - permissions); + + /* + * Check for unsupported modes. + */ + + if ((mode & O_APPEND) || ((ZipFS.wrmax <= 0) && wr)) { + Tcl_SetErrno(EACCES); + if (interp) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write access not supported: %s", + Tcl_PosixError(interp))); + } + return NULL; + } + + return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), wr, + trunc); } /* @@ -5120,11 +5151,25 @@ ZipFSListVolumesProc(void) *------------------------------------------------------------------------- */ +enum ZipFileAttrs { + ZIP_ATTR_UNCOMPSIZE, + ZIP_ATTR_COMPSIZE, + ZIP_ATTR_OFFSET, + ZIP_ATTR_MOUNT, + ZIP_ATTR_ARCHIVE, + ZIP_ATTR_PERMISSIONS, + ZIP_ATTR_CRC +}; + static const char *const * ZipFSFileAttrStringsProc( TCL_UNUSED(Tcl_Obj *) /*pathPtr*/, TCL_UNUSED(Tcl_Obj **) /*objPtrRef*/) { + /* + * Must match up with ZipFileAttrs enum above. + */ + static const char *const attrs[] = { "-uncompsize", "-compsize", @@ -5132,6 +5177,7 @@ ZipFSFileAttrStringsProc( "-mount", "-archive", "-permissions", + "-crc", NULL, }; @@ -5183,25 +5229,28 @@ ZipFSFileAttrsGetProc( goto done; } switch (index) { - case 0: + case ZIP_ATTR_UNCOMPSIZE: TclNewIntObj(*objPtrRef, z->numBytes); break; - case 1: + case ZIP_ATTR_COMPSIZE: TclNewIntObj(*objPtrRef, z->numCompressedBytes); break; - case 2: + case ZIP_ATTR_OFFSET: TclNewIntObj(*objPtrRef, z->offset); break; - case 3: + case ZIP_ATTR_MOUNT: *objPtrRef = Tcl_NewStringObj(z->zipFilePtr->mountPoint, z->zipFilePtr->mountPointLen); break; - case 4: + case ZIP_ATTR_ARCHIVE: *objPtrRef = Tcl_NewStringObj(z->zipFilePtr->name, -1); break; - case 5: + case ZIP_ATTR_PERMISSIONS: *objPtrRef = Tcl_NewStringObj("0o555", -1); break; + case ZIP_ATTR_CRC: + TclNewIntObj(*objPtrRef, z->crc32); + break; default: ZIPFS_ERROR(interp, "unknown attribute"); ZIPFS_ERROR_CODE(interp, "FILE_ATTR"); -- cgit v0.12 From c54d29df06056eda6a5dd8c5845283204d56418f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 Mar 2021 13:17:54 +0000 Subject: Tweak usage of TCL_NO_DEPRECATED --- generic/tclZipfs.c | 6 +++--- generic/tclZlib.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 05affa8..ee166f8 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -343,7 +343,7 @@ static int ZipChannelClose(void *instanceData, static Tcl_DriverGetHandleProc ZipChannelGetFile; static int ZipChannelRead(void *instanceData, char *buf, int toRead, int *errloc); -#ifndef TCL_NO_DEPRECATED +#if !defined(TCL_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9) static int ZipChannelSeek(void *instanceData, long offset, int mode, int *errloc); #endif @@ -402,7 +402,7 @@ static Tcl_ChannelType ZipChannelType = { TCL_CLOSE2PROC, /* Close channel, clean instance data */ ZipChannelRead, /* Handle read request */ ZipChannelWrite, /* Handle write request */ -#ifndef TCL_NO_DEPRECATED +#if !defined(TCL_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9) ZipChannelSeek, /* Move location of access point, NULL'able */ #else NULL, /* Move location of access point, NULL'able */ @@ -4055,7 +4055,7 @@ ZipChannelWideSeek( return info->numRead; } -#ifndef TCL_NO_DEPRECATED +#if !defined(TCL_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9) static int ZipChannelSeek( void *instanceData, diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 9fc84da..440bb9a 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -3957,7 +3957,7 @@ TclZlibInit( * Formally provide the package as a Tcl built-in. */ -#ifndef TCL_NO_DEPRECATED +#if !defined(TCL_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9) Tcl_PkgProvide(interp, "zlib", TCL_ZLIB_VERSION); #endif return Tcl_PkgProvide(interp, "tcl::zlib", TCL_ZLIB_VERSION); -- cgit v0.12 From 0013597b33c5df5a4239d2fc042d9eeb597e94e0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 16 Mar 2021 09:16:39 +0000 Subject: Fix gcc warnings --- generic/tclThreadAlloc.c | 2 +- generic/tclZipfs.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index 28475f9..727f061 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -564,7 +564,7 @@ TclThreadAllocObj(void) cachePtr->numObjects = numMove = NOBJALLOC; newObjsPtr = (Tcl_Obj *)TclpSysAlloc(sizeof(Tcl_Obj) * numMove, 0); if (newObjsPtr == NULL) { - Tcl_Panic("alloc: could not allocate %ld new objects", numMove); + Tcl_Panic("alloc: could not allocate %" TCL_Z_MODIFIER "u new objects", numMove); } cachePtr->lastPtr = newObjsPtr + numMove - 1; objPtr = cachePtr->firstObjPtr; /* NULL */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index ee166f8..a3e1304 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -1449,9 +1449,8 @@ ZipFSCatalogFilesystem( * Validate the TOC data. If that's bad, things fall apart. */ - if (zf0->baseOffset < 0 || zf0->baseOffset >= zf0->length || - zf0->passOffset < 0 || zf0->passOffset >= zf0->length || - zf0->directoryOffset < 0 || zf0->directoryOffset >= zf0->length) { + if (zf0->baseOffset >= zf0->length || zf0->passOffset >= zf0->length || + zf0->directoryOffset >= zf0->length) { ZIPFS_ERROR(interp, "bad zip data"); ZIPFS_ERROR_CODE(interp, "BAD_ZIP"); return TCL_ERROR; -- cgit v0.12 From 90040e057364edd61cc2c470ec1df31f1f4d8e6a Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 16 Mar 2021 20:45:39 +0000 Subject: More cleaning up of zipfs Don't put straight binary data in a Tcl string, and other better API uses. --- generic/tclZipfs.c | 102 +++++++++++++++++++++++++++++------------------------ tests/zipfs.test | 5 +++ 2 files changed, 61 insertions(+), 46 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index a3e1304..cab666c 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -873,7 +873,7 @@ CanonicalPath( static inline ZipEntry * ZipFSLookup( - char *filename) + const char *filename) { Tcl_HashEntry *hPtr; ZipEntry *z = NULL; @@ -1064,7 +1064,7 @@ ZipFSFindTOC( ZipFile *zf) { size_t i; - unsigned char *p, *q; + const unsigned char *p, *q; const unsigned char *start = zf->data; const unsigned char *end = zf->data + zf->length; @@ -1121,7 +1121,7 @@ ZipFSFindTOC( q = zf->data + ZipReadInt(start, end, p + ZIP_CENTRAL_DIRSTART_OFFS); p -= ZipReadInt(start, end, p + ZIP_CENTRAL_DIRSIZE_OFFS); - if ((p < zf->data) || (p > zf->data + zf->length) + if ((p < q) || (p < zf->data) || (p > zf->data + zf->length) || (q < zf->data) || (q > zf->data + zf->length)) { if (!needZip) { zf->baseOffset = zf->passOffset = zf->length; @@ -1166,10 +1166,13 @@ ZipFSFindTOC( q = zf->data + zf->baseOffset; if ((zf->baseOffset >= 6) && (ZipReadInt(start, end, q - 4) == ZIP_PASSWORD_END_SIG)) { + const unsigned char *passPtr; + i = q[-5]; - if (q - 5 - i > zf->data) { + passPtr = q - 5 - i; + if (passPtr >= start && passPtr + i < end) { zf->passBuf[0] = i; - memcpy(zf->passBuf + 1, q - 5 - i, i); + memcpy(zf->passBuf + 1, passPtr, i); zf->passOffset -= i ? (5 + i) : 0; } } @@ -1498,9 +1501,11 @@ ZipFSCatalogFilesystem( zf->mountPoint = (char *) Tcl_GetHashKey(&ZipFS.zipHash, hPtr); Tcl_CreateExitHandler(ZipfsExitHandler, zf); zf->mountPointLen = strlen(zf->mountPoint); + zf->nameLength = strlen(zipname); zf->name = (char *) ckalloc(zf->nameLength + 1); memcpy(zf->name, zipname, zf->nameLength + 1); + Tcl_SetHashValue(hPtr, zf); if ((zf->passBuf[0] == 0) && pwlen) { int k = 0; @@ -1762,17 +1767,28 @@ ListMountPoints( Tcl_HashEntry *hPtr; Tcl_HashSearch search; ZipFile *zf; + Tcl_Obj *resultList; + + if (!interp) { + /* + * Are there any entries in the zipHash? Don't need to enumerate them + * all to know. + */ + + return (ZipFS.zipHash.numEntries ? TCL_OK : TCL_BREAK); + } + resultList = Tcl_NewObj(); for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; hPtr = Tcl_NextHashEntry(&search)) { - if (!interp) { - return TCL_OK; - } zf = (ZipFile *) Tcl_GetHashValue(hPtr); - Tcl_AppendElement(interp, zf->mountPoint); - Tcl_AppendElement(interp, zf->name); + Tcl_ListObjAppendElement(NULL, resultList, Tcl_NewStringObj( + zf->mountPoint, -1)); + Tcl_ListObjAppendElement(NULL, resultList, Tcl_NewStringObj( + zf->name, -1)); } - return (interp ? TCL_OK : TCL_BREAK); + Tcl_SetObjResult(interp, resultList); + return TCL_OK; } /* @@ -1968,7 +1984,6 @@ TclZipfs_MountBuffer( zf->data = data; zf->ptrToFree = NULL; } - zf->passBuf[0] = 0; /* stop valgrind cries */ if (ZipFSFindTOC(interp, 0, zf) != TCL_OK) { return TCL_ERROR; } @@ -2224,7 +2239,6 @@ ZipFSUnmountObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); return TCL_ERROR; @@ -2257,35 +2271,35 @@ ZipFSMkKeyObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int len, i = 0; - char *pw, passBuf[264]; + const char *pw; + Tcl_Obj *passObj; + unsigned char *passBuf; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "password"); return TCL_ERROR; } - pw = Tcl_GetString(objv[1]); - len = strlen(pw); + pw = Tcl_GetStringFromObj(objv[1], &len); if (len == 0) { return TCL_OK; } if (IsPasswordValid(interp, pw, len) != TCL_OK) { return TCL_ERROR; } + + passObj = Tcl_NewByteArrayObj(NULL, 264); + passBuf = Tcl_GetByteArrayFromObj(passObj, NULL); while (len > 0) { int ch = pw[len - 1]; - passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - i++; + passBuf[i++] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; len--; } passBuf[i] = i; - ++i; - passBuf[i++] = (char) ZIP_PASSWORD_END_SIG; - passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); - passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); - passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); - passBuf[i] = '\0'; - Tcl_AppendResult(interp, passBuf, (char *) NULL); + i++; + ZipWriteInt(passBuf, passBuf + 264, passBuf + i, ZIP_PASSWORD_END_SIG); + Tcl_SetByteArrayLength(passObj, i + 4); + Tcl_SetObjResult(interp, passObj); return TCL_OK; } @@ -4673,7 +4687,6 @@ ZipFSOpenFileChannelProc( { int trunc = (mode & O_TRUNC) != 0; int wr = (mode & (O_WRONLY | O_RDWR)) != 0; - int len; pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (!pathPtr) { @@ -4694,8 +4707,7 @@ ZipFSOpenFileChannelProc( return NULL; } - return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), wr, - trunc); + return ZipChannelOpen(interp, Tcl_GetString(pathPtr), wr, trunc); } /* @@ -4720,13 +4732,11 @@ ZipFSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *buf) { - int len; - pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (!pathPtr) { return -1; } - return ZipEntryStat(Tcl_GetStringFromObj(pathPtr, &len), buf); + return ZipEntryStat(Tcl_GetString(pathPtr), buf); } /* @@ -4751,13 +4761,11 @@ ZipFSAccessProc( Tcl_Obj *pathPtr, int mode) { - int len; - pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (!pathPtr) { return -1; } - return ZipEntryAccess(Tcl_GetStringFromObj(pathPtr, &len), mode); + return ZipEntryAccess(Tcl_GetString(pathPtr), mode); } /* @@ -4848,8 +4856,7 @@ ZipFSMatchInDirectoryProc( Tcl_HashEntry *hPtr; Tcl_HashSearch search; Tcl_Obj *normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); - int scnt, l, dirOnly = -1, prefixLen, strip = 0, mounts = 0; - size_t len; + int scnt, l, dirOnly = -1, prefixLen, strip = 0, mounts = 0, len; char *pat, *prefix, *path; Tcl_DString dsPref, *prefixBuf = NULL; @@ -4871,8 +4878,7 @@ ZipFSMatchInDirectoryProc( * The (normalized) path we're searching. */ - path = Tcl_GetString(normPathPtr); - len = normPathPtr->length; + path = Tcl_GetStringFromObj(normPathPtr, &len); Tcl_DStringInit(&dsPref); if (strcmp(prefix, path) == 0) { @@ -4990,6 +4996,13 @@ ZipFSMatchMountPoints( const char *path = Tcl_GetStringFromObj(normPathPtr, &normLength); size_t len = (size_t) normLength; + if (len < 1) { + /* + * Shouldn't happen. But "shouldn't"... + */ + + return; + } l = CountSlashes(path); if (path[len - 1] == '/') { len--; @@ -5060,22 +5073,18 @@ ZipFSPathInFilesystemProc( { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - int ret = -1; - size_t len; + int ret = -1, len; char *path; pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); if (!pathPtr) { return -1; } - - path = Tcl_GetString(pathPtr); + path = Tcl_GetStringFromObj(pathPtr, &len); if (strncmp(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) != 0) { return -1; } - len = pathPtr->length; - ReadLock(); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); if (hPtr) { @@ -5093,12 +5102,13 @@ ZipFSPathInFilesystemProc( for (z = zf->topEnts; z != NULL; z = z->tnext) { size_t lenz = strlen(z->name); - if ((len >= lenz) && (strncmp(path, z->name, lenz) == 0)) { + if (((size_t) len >= lenz) && + (strncmp(path, z->name, lenz) == 0)) { ret = TCL_OK; goto endloop; } } - } else if ((len >= zf->mountPointLen) && + } else if (((size_t) len >= zf->mountPointLen) && (strncmp(path, zf->mountPoint, zf->mountPointLen) == 0)) { ret = TCL_OK; break; diff --git a/tests/zipfs.test b/tests/zipfs.test index eba2a1e..40655b4 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -396,6 +396,11 @@ test zipfs-5.3 {zipfs mount_data: short data} -constraints zipfs -body { test zipfs-5.4 {zipfs mount_data: bad arg count} -constraints zipfs -body { zipfs mount_data gorp {} foobar } -returnCodes error -result {wrong # args: should be "zipfs mount_data ?mountpoint? ?data?"} + +test zipfs-6.1 {zipfs mkkey} -constraints zipfs -body { + binary scan [zipfs mkkey gorp] cu* x + return $x +} -result {224 226 111 103 4 80 75 90 90} ::tcltest::cleanupTests return -- cgit v0.12 From 15849c859a2ac4cde3f65a071a4b8c47f3f2add0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Mar 2021 08:50:28 +0000 Subject: Fix MSVC build --- generic/tclZipfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index cab666c..ce06a8e 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -2288,7 +2288,7 @@ ZipFSMkKeyObjCmd( } passObj = Tcl_NewByteArrayObj(NULL, 264); - passBuf = Tcl_GetByteArrayFromObj(passObj, NULL); + passBuf = Tcl_GetByteArrayFromObj(passObj, (int *)NULL); while (len > 0) { int ch = pw[len - 1]; -- cgit v0.12 From 4b3814f7527e7b7cb252b96ebfdc47badfbe4e2e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Mar 2021 15:01:54 +0000 Subject: Simplify UtfToUtfProc() and UtfToUtf16Proc(): Using TclUtfToUCS4() internally means that we don't have to keep track of internal state any more (Tcl_EncodingState) Also, add (HMODULE) cast (back) in tclZipfs.c --- generic/tclEncoding.c | 89 ++++++++++++++++++--------------------------------- generic/tclZipfs.c | 2 +- 2 files changed, 32 insertions(+), 59 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index ea2d6fa..7569ce4 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2275,11 +2275,7 @@ UtfToUtfProc( const char *src, /* Source string in UTF-8. */ int srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ - Tcl_EncodingState *statePtr,/* Place for conversion routine to store state - * information used during a piecewise - * conversion. Contents of statePtr are - * initialized and/or reset by conversion - * routine under control of flags argument. */ + TCL_UNUSED(Tcl_EncodingState *), char *dst, /* Output buffer in which converted string is * stored. */ int dstLen, /* The maximum length of output buffer in @@ -2302,11 +2298,8 @@ UtfToUtfProc( const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd; int result, numChars, charLimit = INT_MAX; - int *chPtr = (int *) statePtr; + int ch; - if (flags & TCL_ENCODING_START) { - *statePtr = 0; - } result = TCL_OK; srcStart = src; @@ -2343,7 +2336,6 @@ UtfToUtfProc( */ *dst++ = *src++; - *chPtr = 0; /* reset surrogate handling */ } else if (pureNullMode == 1 && UCHAR(*src) == 0xC0 && (src + 1 < srcEnd) && UCHAR(*(src+1)) == 0x80) { /* @@ -2351,7 +2343,6 @@ UtfToUtfProc( */ *dst++ = 0; - *chPtr = 0; /* reset surrogate handling */ src += 2; } else if (!Tcl_UtfCharComplete(src, srcEnd - src)) { /* @@ -2360,26 +2351,26 @@ UtfToUtfProc( * incomplete char its bytes are made to represent themselves. */ - *chPtr = UCHAR(*src); + ch = UCHAR(*src); src += 1; - dst += Tcl_UniCharToUtf(*chPtr, dst); + dst += Tcl_UniCharToUtf(ch, dst); } else { - src += TclUtfToUCS4(src, chPtr); - if ((*chPtr | 0x7FF) == 0xDFFF) { + src += TclUtfToUCS4(src, &ch); + if ((ch | 0x7FF) == 0xDFFF) { /* A surrogate character is detected, handle especially */ - int low = *chPtr; + int low = ch; size_t len = (src <= srcEnd-3) ? TclUtfToUCS4(src, &low) : 0; - if (((low & ~0x3FF) != 0xDC00) || (*chPtr & 0x400)) { - *dst++ = (char) (((*chPtr >> 12) | 0xE0) & 0xEF); - *dst++ = (char) (((*chPtr >> 6) | 0x80) & 0xBF); - *dst++ = (char) ((*chPtr | 0x80) & 0xBF); + if (((low & ~0x3FF) != 0xDC00) || (ch & 0x400)) { + *dst++ = (char) (((ch >> 12) | 0xE0) & 0xEF); + *dst++ = (char) (((ch >> 6) | 0x80) & 0xBF); + *dst++ = (char) ((ch | 0x80) & 0xBF); continue; } src += len; - dst += Tcl_UniCharToUtf(*chPtr, dst); - *chPtr = low; + dst += Tcl_UniCharToUtf(ch, dst); + ch = low; } - dst += Tcl_UniCharToUtf(*chPtr, dst); + dst += Tcl_UniCharToUtf(ch, dst); } } @@ -2506,11 +2497,7 @@ UtfToUtf16Proc( const char *src, /* Source string in UTF-8. */ int srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ - Tcl_EncodingState *statePtr,/* Place for conversion routine to store state - * information used during a piecewise - * conversion. Contents of statePtr are - * initialized and/or reset by conversion - * routine under control of flags argument. */ + TCL_UNUSED(Tcl_EncodingState *), char *dst, /* Output buffer in which converted string is * stored. */ int dstLen, /* The maximum length of output buffer in @@ -2529,11 +2516,8 @@ UtfToUtf16Proc( { const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd; int result, numChars; - Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr; + int ch; - if (flags & TCL_ENCODING_START) { - *statePtr = 0; - } srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; @@ -2559,38 +2543,27 @@ UtfToUtf16Proc( result = TCL_CONVERT_NOSPACE; break; } - src += TclUtfToUniChar(src, chPtr); - + src += TclUtfToUCS4(src, &ch); if (clientData) { -#if TCL_UTF_MAX > 3 - if (*chPtr <= 0xFFFF) { - *dst++ = (*chPtr & 0xFF); - *dst++ = (*chPtr >> 8); + if (ch <= 0xFFFF) { + *dst++ = (ch & 0xFF); + *dst++ = (ch >> 8); } else { - *dst++ = (((*chPtr - 0x10000) >> 10) & 0xFF); - *dst++ = (((*chPtr - 0x10000) >> 18) & 0x3) | 0xD8; - *dst++ = (*chPtr & 0xFF); - *dst++ = ((*chPtr >> 8) & 0x3) | 0xDC; + *dst++ = (((ch - 0x10000) >> 10) & 0xFF); + *dst++ = (((ch - 0x10000) >> 18) & 0x3) | 0xD8; + *dst++ = (ch & 0xFF); + *dst++ = ((ch >> 8) & 0x3) | 0xDC; } -#else - *dst++ = (*chPtr & 0xFF); - *dst++ = (*chPtr >> 8); -#endif } else { -#if TCL_UTF_MAX > 3 - if (*chPtr <= 0xFFFF) { - *dst++ = (*chPtr >> 8); - *dst++ = (*chPtr & 0xFF); + if (ch <= 0xFFFF) { + *dst++ = (ch >> 8); + *dst++ = (ch & 0xFF); } else { - *dst++ = (((*chPtr - 0x10000) >> 18) & 0x3) | 0xD8; - *dst++ = (((*chPtr - 0x10000) >> 10) & 0xFF); - *dst++ = ((*chPtr >> 8) & 0x3) | 0xDC; - *dst++ = (*chPtr & 0xFF); + *dst++ = (((ch - 0x10000) >> 18) & 0x3) | 0xD8; + *dst++ = (((ch - 0x10000) >> 10) & 0xFF); + *dst++ = ((ch >> 8) & 0x3) | 0xDC; + *dst++ = (ch & 0xFF); } -#else - *dst++ = (*chPtr >> 8); - *dst++ = (*chPtr & 0xFF); -#endif } } *srcReadPtr = src - srcStart; diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index ce06a8e..feb5324 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3746,7 +3746,7 @@ TclZipfs_TclLibrary(void) #if !defined(STATIC_BUILD) #if defined(_WIN32) || defined(__CYGWIN__) - hModule = TclWinGetTclInstance(); + hModule = (HMODULE)TclWinGetTclInstance(); GetModuleFileNameW(hModule, wName, MAX_PATH); #ifdef __CYGWIN__ cygwin_conv_path(3, wName, dllName, sizeof(dllName)); -- cgit v0.12 From c84e03a7a89d44077d777f0cc9dced8c20045f65 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Mar 2021 09:12:18 +0000 Subject: More simplification of UtfToUtfProc(). Get rid of wrapper functions UtfIntToUtfExtProc/UtfExtToUtfIntProc. This can be handled by additional flags. --- generic/tclEncoding.c | 150 ++++++++------------------------------------------ 1 file changed, 24 insertions(+), 126 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 7569ce4..c682128 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -220,14 +220,7 @@ static size_t unilen(const char *src); static Tcl_EncodingConvertProc Utf16ToUtfProc; static Tcl_EncodingConvertProc UtfToUtf16Proc; static Tcl_EncodingConvertProc UtfToUcs2Proc; -static int UtfToUtfProc(ClientData clientData, - const char *src, int srcLen, int flags, - Tcl_EncodingState *statePtr, char *dst, - int dstLen, int *srcReadPtr, - int *dstWrotePtr, int *dstCharsPtr, - int pureNullMode); -static Tcl_EncodingConvertProc UtfIntToUtfExtProc; -static Tcl_EncodingConvertProc UtfExtToUtfIntProc; +static Tcl_EncodingConvertProc UtfToUtfProc; static Tcl_EncodingConvertProc Iso88591FromUtfProc; static Tcl_EncodingConvertProc Iso88591ToUtfProc; @@ -517,6 +510,10 @@ FillEncodingFileMap(void) *--------------------------------------------------------------------------- */ +/* Those flags must not conflict with other TCL_ENCODING_* flags in tcl.h */ +#define TCL_ENCODING_LE 0x40 /* Little-endian encoding */ +#define TCL_ENCODING_EXTERNAL 0x80 /* Converting from internal to external variant */ + void TclInitEncodingSubsystem(void) { @@ -525,7 +522,7 @@ TclInitEncodingSubsystem(void) unsigned size; unsigned short i; union { - char c; + unsigned char c; short s; } isLe; @@ -533,7 +530,7 @@ TclInitEncodingSubsystem(void) return; } - isLe.s = 1; + isLe.s = TCL_ENCODING_LE; Tcl_MutexLock(&encodingMutex); Tcl_InitHashTable(&encodingTable, TCL_STRING_KEYS); Tcl_MutexUnlock(&encodingMutex); @@ -553,8 +550,8 @@ TclInitEncodingSubsystem(void) tclIdentityEncoding = Tcl_CreateEncoding(&type); type.encodingName = "utf-8"; - type.toUtfProc = UtfExtToUtfIntProc; - type.fromUtfProc = UtfIntToUtfExtProc; + type.toUtfProc = UtfToUtfProc; + type.fromUtfProc = UtfToUtfProc; type.freeProc = NULL; type.nullSize = 1; type.clientData = NULL; @@ -565,7 +562,7 @@ TclInitEncodingSubsystem(void) type.freeProc = NULL; type.nullSize = 2; type.encodingName = "ucs-2le"; - type.clientData = INT2PTR(1); + type.clientData = INT2PTR(TCL_ENCODING_LE); Tcl_CreateEncoding(&type); type.encodingName = "ucs-2be"; type.clientData = INT2PTR(0); @@ -579,7 +576,7 @@ TclInitEncodingSubsystem(void) type.freeProc = NULL; type.nullSize = 2; type.encodingName = "utf-16le"; - type.clientData = INT2PTR(1); + type.clientData = INT2PTR(TCL_ENCODING_LE); Tcl_CreateEncoding(&type); type.encodingName = "utf-16be"; type.clientData = INT2PTR(0); @@ -1331,7 +1328,7 @@ Tcl_UtfToExternalDString( flags = TCL_ENCODING_START | TCL_ENCODING_END; while (1) { result = encodingPtr->fromUtfProc(encodingPtr->clientData, src, - srcLen, flags, &state, dst, dstLen, &srcRead, &dstWrote, + srcLen, flags | TCL_ENCODING_EXTERNAL, &state, dst, dstLen, &srcRead, &dstWrote, &dstChars); soFar = dst + dstWrote - Tcl_DStringValue(dstPtr); @@ -1433,7 +1430,7 @@ Tcl_UtfToExternal( dstLen -= encodingPtr->nullSize; result = encodingPtr->fromUtfProc(encodingPtr->clientData, src, srcLen, - flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, + flags | TCL_ENCODING_EXTERNAL, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr); if (encodingPtr->nullSize == 2) { dst[*dstWrotePtr + 1] = '\0'; @@ -2156,104 +2153,6 @@ BinaryProc( /* *------------------------------------------------------------------------- * - * UtfIntToUtfExtProc -- - * - * Convert from UTF-8 to UTF-8. While converting null-bytes from the - * Tcl's internal representation (0xC0, 0x80) to the official - * representation (0x00). See UtfToUtfProc for details. - * - * Results: - * Returns TCL_OK if conversion was successful. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -UtfIntToUtfExtProc( - ClientData clientData, - const char *src, /* Source string in UTF-8. */ - int srcLen, /* Source string length in bytes. */ - int flags, /* Conversion control flags. */ - Tcl_EncodingState *statePtr,/* Place for conversion routine to store state - * information used during a piecewise - * conversion. Contents of statePtr are - * initialized and/or reset by conversion - * routine under control of flags argument. */ - char *dst, /* Output buffer in which converted string - * is stored. */ - int dstLen, /* The maximum length of output buffer in - * bytes. */ - int *srcReadPtr, /* Filled with the number of bytes from the - * source string that were converted. This may - * be less than the original source length if - * there was a problem converting some source - * characters. */ - int *dstWrotePtr, /* Filled with the number of bytes that were - * stored in the output buffer as a result of - * the conversion. */ - int *dstCharsPtr) /* Filled with the number of characters that - * correspond to the bytes stored in the - * output buffer. */ -{ - return UtfToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen, - srcReadPtr, dstWrotePtr, dstCharsPtr, 1); -} - -/* - *------------------------------------------------------------------------- - * - * UtfExtToUtfIntProc -- - * - * Convert from UTF-8 to UTF-8 while converting null-bytes from the - * official representation (0x00) to Tcl's internal representation (0xC0, - * 0x80). See UtfToUtfProc for details. - * - * Results: - * Returns TCL_OK if conversion was successful. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -UtfExtToUtfIntProc( - ClientData clientData, - const char *src, /* Source string in UTF-8. */ - int srcLen, /* Source string length in bytes. */ - int flags, /* Conversion control flags. */ - Tcl_EncodingState *statePtr,/* Place for conversion routine to store state - * information used during a piecewise - * conversion. Contents of statePtr are - * initialized and/or reset by conversion - * routine under control of flags argument. */ - char *dst, /* Output buffer in which converted string is - * stored. */ - int dstLen, /* The maximum length of output buffer in - * bytes. */ - int *srcReadPtr, /* Filled with the number of bytes from the - * source string that were converted. This may - * be less than the original source length if - * there was a problem converting some source - * characters. */ - int *dstWrotePtr, /* Filled with the number of bytes that were - * stored in the output buffer as a result of - * the conversion. */ - int *dstCharsPtr) /* Filled with the number of characters that - * correspond to the bytes stored in the - * output buffer. */ -{ - return UtfToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen, - srcReadPtr, dstWrotePtr, dstCharsPtr, 0); -} - -/* - *------------------------------------------------------------------------- - * * UtfToUtfProc -- * * Convert from UTF-8 to UTF-8. Note that the UTF-8 to UTF-8 translation @@ -2288,12 +2187,9 @@ UtfToUtfProc( int *dstWrotePtr, /* Filled with the number of bytes that were * stored in the output buffer as a result of * the conversion. */ - int *dstCharsPtr, /* Filled with the number of characters that + int *dstCharsPtr) /* Filled with the number of characters that * correspond to the bytes stored in the * output buffer. */ - int pureNullMode) /* Convert embedded nulls from internal - * representation to real null-bytes or vice - * versa. Also combine or separate surrogate pairs */ { const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd; @@ -2329,15 +2225,15 @@ UtfToUtfProc( result = TCL_CONVERT_NOSPACE; break; } - if (UCHAR(*src) < 0x80 && !(UCHAR(*src) == 0 && pureNullMode == 0)) { + if ((UCHAR(*src - 1) < 0x7F) && !(flags & TCL_ENCODING_EXTERNAL)) { /* * Copy 7bit characters, but skip null-bytes when we are in input * mode, so that they get converted to 0xC080. */ *dst++ = *src++; - } else if (pureNullMode == 1 && UCHAR(*src) == 0xC0 && - (src + 1 < srcEnd) && UCHAR(*(src+1)) == 0x80) { + } else if (UCHAR(*src) == 0xC0 && (src + 1 < srcEnd) + && UCHAR(src[1]) == 0x80 && (flags & TCL_ENCODING_EXTERNAL)) { /* * Convert 0xC080 to real nulls when we are in output mode. */ @@ -2398,7 +2294,7 @@ UtfToUtfProc( static int Utf16ToUtfProc( - ClientData clientData, /* != NULL means LE, == NUL means BE */ + ClientData clientData, /* additional flags, e.g. TCL_ENCODING_LE */ const char *src, /* Source string in Unicode. */ int srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ @@ -2424,6 +2320,7 @@ Utf16ToUtfProc( int result, numChars, charLimit = INT_MAX; unsigned short ch; + flags |= PTR2INT(clientData); if (flags & TCL_ENCODING_CHAR_LIMIT) { charLimit = *dstCharsPtr; } @@ -2435,7 +2332,7 @@ Utf16ToUtfProc( srcLen--; } /* If last code point is a high surrogate, we cannot handle that yet */ - if ((srcLen >= 2) && ((src[srcLen - (clientData?1:2)] & 0xFC) == 0xD8)) { + if ((srcLen >= 2) && ((src[srcLen - ((flags & TCL_ENCODING_LE)?1:2)] & 0xFC) == 0xD8)) { result = TCL_CONVERT_MULTIBYTE; srcLen-= 2; } @@ -2452,7 +2349,7 @@ Utf16ToUtfProc( break; } - if (clientData) { + if (flags & TCL_ENCODING_LE) { ch = (src[1] & 0xFF) << 8 | (src[0] & 0xFF); } else { ch = (src[0] & 0xFF) << 8 | (src[1] & 0xFF); @@ -2590,7 +2487,7 @@ UtfToUtf16Proc( static int UtfToUcs2Proc( - ClientData clientData, /* != NULL means LE, == NUL means BE */ + ClientData clientData, /* additional flags, e.g. TCL_ENCODING_LE */ const char *src, /* Source string in UTF-8. */ int srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ @@ -2618,6 +2515,7 @@ UtfToUcs2Proc( #endif Tcl_UniChar ch = 0; + flags |= PTR2INT(clientData); srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; @@ -2661,7 +2559,7 @@ UtfToUcs2Proc( * casting dst to a Tcl_UniChar. [Bug 1122671] */ - if (clientData) { + if (flags & TCL_ENCODING_LE) { *dst++ = (ch & 0xFF); *dst++ = (ch >> 8); } else { -- cgit v0.12 From 6da553ec22b666e880e62654a28d44ecf9fd02e4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Mar 2021 09:26:03 +0000 Subject: Proposed implementation of RFE [4b4830eb54] --- doc/refchan.n | 13 +++++++ generic/tclIORChan.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 111 insertions(+), 5 deletions(-) diff --git a/doc/refchan.n b/doc/refchan.n index 8737556..c17117d 100644 --- a/doc/refchan.n +++ b/doc/refchan.n @@ -322,6 +322,19 @@ invocation (usually \fBfconfigure\fR or \fBchan configure\fR) will appear to have thrown this error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\fR, etc.) is treated as and converted to an error. .RE +.TP +\fIcmdPrefix \fBtruncate\fR \fIchannelId length\fR +. +This \fIoptional\fR subcommand handles changing the length of the +underlying data stream for the channel \fIchannelId\fR. Its length +gets set to \fIlength\fR. +.RS +.PP +If the subcommand throws an error the command which caused its +invocation (usually \fBchan truncate\fR) will appear to have thrown +this error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\fR, +etc.) is treated as and converted to an error. +.RE .SH NOTES Some of the functions supported in channels defined in Tcl's C interface are not available to channels reflected to the Tcl level. diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index e6e8e58..88f6de8 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -56,12 +56,13 @@ static int ReflectGetOption(ClientData clientData, static int ReflectSetOption(ClientData clientData, Tcl_Interp *interp, const char *optionName, const char *newValue); +static int ReflectTruncate(ClientData clientData, + long long length); static void TimerRunRead(ClientData clientData); static void TimerRunWrite(ClientData clientData); /* - * The C layer channel type/driver definition used by the reflection. This is - * a version 3 structure. + * The C layer channel type/driver definition used by the reflection. */ static const Tcl_ChannelType tclRChannelType = { @@ -89,7 +90,7 @@ static const Tcl_ChannelType tclRChannelType = { #else NULL, /* thread action */ #endif - NULL /* truncate */ + ReflectTruncate /* Truncate. NULL'able */ }; /* @@ -187,6 +188,7 @@ static const char *const methodNames[] = { "initialize", /* */ "read", /* OPT */ "seek", /* OPT */ + "truncate", /* OPT */ "watch", /* */ "write", /* OPT */ NULL @@ -200,6 +202,7 @@ typedef enum { METH_INIT, METH_READ, METH_SEEK, + METH_TRUNCATE, METH_WATCH, METH_WRITE } MethodName; @@ -209,7 +212,8 @@ typedef enum { (FLAG(METH_INIT) | FLAG(METH_FINAL) | FLAG(METH_WATCH)) #define NULLABLE_METHODS \ (FLAG(METH_BLOCKING) | FLAG(METH_SEEK) | \ - FLAG(METH_CONFIGURE) | FLAG(METH_CGET) | FLAG(METH_CGETALL)) + FLAG(METH_CONFIGURE) | FLAG(METH_CGET) | \ + FLAG(METH_CGETALL) | FLAG(METH_TRUNCATE)) #define RANDW \ (TCL_READABLE | TCL_WRITABLE) @@ -239,7 +243,8 @@ typedef enum { ForwardedBlock, ForwardedSetOpt, ForwardedGetOpt, - ForwardedGetOptAll + ForwardedGetOptAll, + ForwardedTruncate } ForwardedOperation; /* @@ -302,6 +307,10 @@ struct ForwardParamGetOpt { const char *name; /* Name of option to get, maybe NULL */ Tcl_DString *value; /* Result */ }; +struct ForwardParamTruncate { + ForwardParamBase base; /* "Supertype". MUST COME FIRST. */ + Tcl_WideInt length; /* I: Length of file. */ +}; /* * Now join all these together in a single union for convenience. @@ -316,6 +325,7 @@ typedef union ForwardParam { struct ForwardParamBlock block; struct ForwardParamSetOpt setOpt; struct ForwardParamGetOpt getOpt; + struct ForwardParamTruncate truncate; } ForwardParam; /* @@ -706,6 +716,9 @@ TclChanCreateObjCmd( #endif clonePtr->wideSeekProc = NULL; } + if (!(methods & FLAG(METH_TRUNCATE))) { + clonePtr->truncateProc = NULL; + } chanPtr->typePtr = clonePtr; } @@ -2048,6 +2061,73 @@ ReflectGetOption( } /* + *---------------------------------------------------------------------- + * + * ReflectTruncate -- + * + * This function is invoked to truncate a channel's file size. + * + * Results: + * A standard Tcl result code. + * + * Side effects: + * Arbitrary, as it calls upon a Tcl script. + * + *---------------------------------------------------------------------- + */ + +static int +ReflectTruncate( + ClientData clientData, /* Channel to query */ + long long length) /* Length to truncate to. */ +{ + ReflectedChannel *rcPtr = (ReflectedChannel *)clientData; + Tcl_Obj *lenObj; + int errorNum; /* EINVAL or EOK (success). */ + Tcl_Obj *resObj; /* Result for 'truncate' */ + + /* + * Are we in the correct thread? + */ + +#ifdef TCL_THREADS + if (rcPtr->thread != Tcl_GetCurrentThread()) { + ForwardParam p; + + p.truncate.length = length; + + ForwardOpToHandlerThread(rcPtr, ForwardedTruncate, &p); + + if (p.base.code != TCL_OK) { + PassReceivedError(rcPtr->chan, &p); + return EINVAL; + } + + return EOK; + } +#endif + + /* ASSERT: rcPtr->method & FLAG(METH_TRUNCATE) */ + + Tcl_Preserve(rcPtr); + + lenObj = Tcl_NewIntObj(length); + Tcl_IncrRefCount(lenObj); + + if (InvokeTclMethod(rcPtr,METH_TRUNCATE,lenObj,NULL,&resObj)!=TCL_OK) { + Tcl_SetChannelError(rcPtr->chan, resObj); + errorNum = EINVAL; + } else { + errorNum = EOK; + } + + Tcl_DecrRefCount(lenObj); + Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ + Tcl_Release(rcPtr); + return errorNum; +} + +/* * Helpers. ========================================================= */ @@ -3278,6 +3358,19 @@ ForwardProc( Tcl_Release(rcPtr); break; + case ForwardedTruncate: { + Tcl_Obj *lenObj = Tcl_NewIntObj(paramPtr->truncate.length); + + Tcl_IncrRefCount(lenObj); + Tcl_Preserve(rcPtr); + if (InvokeTclMethod(rcPtr,METH_TRUNCATE,lenObj,NULL,&resObj)!=TCL_OK) { + ForwardSetObjError(paramPtr, resObj); + } + Tcl_Release(rcPtr); + Tcl_DecrRefCount(lenObj); + break; + } + default: /* * Bad operation code. -- cgit v0.12 From 3aa4b20ea8f659c593c8ab827efc535856cd540a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Mar 2021 09:36:27 +0000 Subject: Remove incorrect/useless comment --- generic/tclIORChan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index dd24b0f..c48c904 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -58,8 +58,7 @@ static int ReflectSetOption(ClientData clientData, const char *newValue); /* - * The C layer channel type/driver definition used by the reflection. This is - * a version 3 structure. + * The C layer channel type/driver definition used by the reflection. */ static const Tcl_ChannelType tclRChannelType = { -- cgit v0.12 From a3ae9d7e5701156f675454df19664b0c220271b0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Mar 2021 12:05:56 +0000 Subject: Fix [2860859e84]: Misleading description in README file --- tools/README | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/tools/README b/tools/README index f4bf627..a37c2f4 100644 --- a/tools/README +++ b/tools/README @@ -9,17 +9,12 @@ uniClass.tcl -- Script for generating regexp class tables from the Tcl "string is" classes Generating HTML files. -The tcl-tk-man-html.tcl script from Robert Critchlow -generates a nice set of HTML with good cross references. -Use it like - tclsh tcl-tk-man-html.tcl --htmldir=/tmp/tcl8.2 +The tcltk-man2html.tcl script generates a nice set of HTML with +good cross references. Use it like + cd unix + ./configure + make html This script is very picky about the organization of man pages, effectively acting as a style enforcer. - -Generating Windows Help Files: -1) Build tcl in the ../unix directory -2) On UNIX, (after autoconf and configure), do - make - this converts the Nroff to RTF files. -2) On Windows, convert the RTF to a Help doc, do - nmake helpfile +The resulting documentation can be found at + /tmp/dist/tcl/html -- cgit v0.12 From 2b7eb65f53e75a84e02c3b5da96c45bbefc6ff8a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Mar 2021 13:20:47 +0000 Subject: Suggested fix for [0221b993a1]: Tcl command [update idletasks] doesn't skip main loop in Tcl_DoOneEvent --- generic/tclEvent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclEvent.c b/generic/tclEvent.c index bf3be38..52cd351 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -1513,7 +1513,7 @@ Tcl_UpdateObjCmd( } switch ((enum updateOptionsEnum) optionIndex) { case OPT_IDLETASKS: - flags = TCL_WINDOW_EVENTS|TCL_IDLE_EVENTS|TCL_DONT_WAIT; + flags = TCL_IDLE_EVENTS|TCL_DONT_WAIT; break; default: Tcl_Panic("Tcl_UpdateObjCmd: bad option index to UpdateOptions"); -- cgit v0.12 From 8390478dbf758e04f04223c4db37e62c1ca1d519 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Mar 2021 14:46:57 +0000 Subject: Fix [8663689908]. Final documentation fix, implementation was already fixed earlier. --- doc/re_syntax.n | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/re_syntax.n b/doc/re_syntax.n index 9a9e2b0..ef8c570 100644 --- a/doc/re_syntax.n +++ b/doc/re_syntax.n @@ -446,7 +446,7 @@ commonly-used character classes: .TP \fB\ew\fR . -\fB[[:alnum:]_]\fR (note underscore) +\fB[[:alnum:]_\eu203F\eu2040\eu2054\euFE33\euFE34\euFE4D\euFE4E\euFE4F\euFF3F]\fR (including punctuation connector characters) .TP \fB\eD\fR . @@ -458,7 +458,7 @@ commonly-used character classes: .TP \fB\eW\fR . -\fB[^[:alnum:]_]\fR (note underscore) +\fB[^[:alnum:]_\eu203F\eu2040\eu2054\euFE33\euFE34\euFE4D\euFE4E\euFE4F\euFF3F]\fR (including punctuation connector characters) .RE .PP Within bracket expressions, -- cgit v0.12 From e6d6e2962de378b019acce96758ea25fb4566243 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 18 Mar 2021 21:17:46 +0000 Subject: Delete some useless code. Was only place where we fed an uncontrolled value to %f, and it was actually a conversion we didn't need to do at all. --- generic/tclIndexObj.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c index 7e23931..d7dfb71 100644 --- a/generic/tclIndexObj.c +++ b/generic/tclIndexObj.c @@ -1328,7 +1328,6 @@ PrintUsage( int width, numSpaces; #define NUM_SPACES 20 static const char spaces[] = " "; - char tmp[TCL_DOUBLE_SPACE]; Tcl_Obj *msg; /* @@ -1378,7 +1377,6 @@ PrintUsage( case TCL_ARGV_FLOAT: Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: %g", *((double *) infoPtr->dstPtr)); - sprintf(tmp, "%g", *((double *) infoPtr->dstPtr)); break; case TCL_ARGV_STRING: { char *string = *((char **) infoPtr->dstPtr); -- cgit v0.12 From f2cb38dda94341ddbb64b3b72efdeeb62ec610be Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 18 Mar 2021 21:35:09 +0000 Subject: Handle the encoding of filenames in ZIPs correctly. (This is awful. The awful isn't Tcl's fault. Terrible spec...) --- generic/tclEncoding.c | 55 +++++++++----- generic/tclZipfs.c | 199 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 215 insertions(+), 39 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index c682128..4f08a17 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -512,7 +512,7 @@ FillEncodingFileMap(void) /* Those flags must not conflict with other TCL_ENCODING_* flags in tcl.h */ #define TCL_ENCODING_LE 0x40 /* Little-endian encoding */ -#define TCL_ENCODING_EXTERNAL 0x80 /* Converting from internal to external variant */ +#define TCL_ENCODING_EXTERNAL 0x80 /* Converting from internal to external variant */ void TclInitEncodingSubsystem(void) @@ -1328,8 +1328,8 @@ Tcl_UtfToExternalDString( flags = TCL_ENCODING_START | TCL_ENCODING_END; while (1) { result = encodingPtr->fromUtfProc(encodingPtr->clientData, src, - srcLen, flags | TCL_ENCODING_EXTERNAL, &state, dst, dstLen, &srcRead, &dstWrote, - &dstChars); + srcLen, flags | TCL_ENCODING_EXTERNAL, &state, dst, dstLen, + &srcRead, &dstWrote, &dstChars); soFar = dst + dstWrote - Tcl_DStringValue(dstPtr); if (result != TCL_CONVERT_NOSPACE) { @@ -1430,8 +1430,8 @@ Tcl_UtfToExternal( dstLen -= encodingPtr->nullSize; result = encodingPtr->fromUtfProc(encodingPtr->clientData, src, srcLen, - flags | TCL_ENCODING_EXTERNAL, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, - dstCharsPtr); + flags | TCL_ENCODING_EXTERNAL, statePtr, dst, dstLen, srcReadPtr, + dstWrotePtr, dstCharsPtr); if (encodingPtr->nullSize == 2) { dst[*dstWrotePtr + 1] = '\0'; } @@ -2244,23 +2244,32 @@ UtfToUtfProc( /* * Always check before using TclUtfToUCS4. Not doing can so * cause it run beyond the end of the buffer! If we happen such an - * incomplete char its bytes are made to represent themselves. + * incomplete char its bytes are made to represent themselves + * unless the user has explicitly asked to be told. */ + if (flags & TCL_ENCODING_STOPONERROR) { + result = TCL_CONVERT_MULTIBYTE; + break; + } ch = UCHAR(*src); src += 1; dst += Tcl_UniCharToUtf(ch, dst); } else { src += TclUtfToUCS4(src, &ch); if ((ch | 0x7FF) == 0xDFFF) { - /* A surrogate character is detected, handle especially */ + /* + * A surrogate character is detected, handle especially. + */ + int low = ch; size_t len = (src <= srcEnd-3) ? TclUtfToUCS4(src, &low) : 0; + if (((low & ~0x3FF) != 0xDC00) || (ch & 0x400)) { - *dst++ = (char) (((ch >> 12) | 0xE0) & 0xEF); - *dst++ = (char) (((ch >> 6) | 0x80) & 0xBF); - *dst++ = (char) ((ch | 0x80) & 0xBF); - continue; + *dst++ = (char) (((ch >> 12) | 0xE0) & 0xEF); + *dst++ = (char) (((ch >> 6) | 0x80) & 0xBF); + *dst++ = (char) ((ch | 0x80) & 0xBF); + continue; } src += len; dst += Tcl_UniCharToUtf(ch, dst); @@ -2326,13 +2335,21 @@ Utf16ToUtfProc( } result = TCL_OK; - /* check alignment with utf-16 (2 == sizeof(UTF-16)) */ + /* + * Check alignment with utf-16 (2 == sizeof(UTF-16)) + */ + if ((srcLen % 2) != 0) { result = TCL_CONVERT_MULTIBYTE; srcLen--; } - /* If last code point is a high surrogate, we cannot handle that yet */ - if ((srcLen >= 2) && ((src[srcLen - ((flags & TCL_ENCODING_LE)?1:2)] & 0xFC) == 0xD8)) { + + /* + * If last code point is a high surrogate, we cannot handle that yet. + */ + + if ((srcLen >= 2) && + ((src[srcLen - ((flags & TCL_ENCODING_LE)?1:2)] & 0xFC) == 0xD8)) { result = TCL_CONVERT_MULTIBYTE; srcLen-= 2; } @@ -2354,10 +2371,12 @@ Utf16ToUtfProc( } else { ch = (src[0] & 0xFF) << 8 | (src[1] & 0xFF); } + /* * Special case for 1-byte utf chars for speed. Make sure we work with * unsigned short-size data. */ + if (ch && ch < 0x80) { *dst++ = (ch & 0xFF); } else { @@ -2967,7 +2986,9 @@ Iso88591FromUtfProc( break; } #if TCL_UTF_MAX <= 3 - if ((ch >= 0xD800) && (len < 3)) len = 4; + if ((ch >= 0xD800) && (len < 3)) { + len = 4; + } #endif /* * Plunge on, using '?' as a fallback character. @@ -3012,7 +3033,7 @@ TableFreeProc( ClientData clientData) /* TableEncodingData that specifies * encoding. */ { - TableEncodingData *dataPtr = (TableEncodingData *)clientData; + TableEncodingData *dataPtr = (TableEncodingData *) clientData; /* * Make sure we aren't freeing twice on shutdown. [Bug 219314] @@ -3070,7 +3091,7 @@ EscapeToUtfProc( * correspond to the bytes stored in the * output buffer. */ { - EscapeEncodingData *dataPtr = (EscapeEncodingData *)clientData; + EscapeEncodingData *dataPtr = (EscapeEncodingData *) clientData; const char *prefixBytes, *tablePrefixBytes, *srcStart, *srcEnd; const unsigned short *const *tableToUnicode; const Encoding *encodingPtr; diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index feb5324..0b1963b 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -47,6 +47,7 @@ #define ZIPFS_VOLUME_LEN 9 #define ZIPFS_APP_MOUNT "//zipfs:/app" #define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" +#define ZIPFS_FALLBACK_ENCODING "cp437" /* * Various constants and offsets found in ZIP archive files @@ -262,11 +263,19 @@ static struct { int wrmax; /* Maximum write size of a file; only written * to from Tcl code in a trusted interpreter, * so NOT protected by mutex. */ + char *fallbackEntryEncoding;/* The fallback encoding for ZIP entries when + * they are believed to not be UTF-8; only + * written to from Tcl code in a trusted + * interpreter, so not protected by mutex. */ + Tcl_Encoding utf8; /* The UTF-8 encoding that we prefer to use + * for the strings (especially filenames) + * embedded in a ZIP. Other encodings are used + * dynamically. */ int idCount; /* Counter for channel names */ Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ } ZipFS = { - 0, 0, 0, DEFAULT_WRITE_MAX_SIZE, 0, + 0, 0, 0, DEFAULT_WRITE_MAX_SIZE, NULL, NULL, 0, {0,{0,0,0,0},0,0,0,0,0,0,0,0,0}, {0,{0,0,0,0},0,0,0,0,0,0,0,0,0} }; @@ -686,6 +695,115 @@ CountSlashes( /* *------------------------------------------------------------------------- * + * DecodeZipEntryText -- + * + * Given a sequence of bytes from an entry in a ZIP central directory, + * convert that into a Tcl string. This is complicated because we don't + * actually know what encoding is in use! So we try to use UTF-8, and if + * that goes wrong, we fall back to a user-specified encoding, or to an + * encoding we specify (Windows code page 437), or to ISO 8859-1 if + * absolutely nothing else works. + * + * During Tcl startup, we skip the user-specified encoding and cp437, as + * we may well not have any loadable encodings yet. Tcl's own library + * files ought to be using ASCII filenames. + * + * Results: + * The decoded filename; the filename is owned by the argument DString. + * + * Side effects: + * Updates dstPtr. + * + *------------------------------------------------------------------------- + */ + +static char * +DecodeZipEntryText( + const unsigned char *inputBytes, + unsigned int inputLength, + Tcl_DString *dstPtr) +{ + Tcl_Encoding encoding; + const char *src; + char *dst; + int dstLen, srcLen = inputLength, flags; + Tcl_EncodingState state; + + Tcl_DStringInit(dstPtr); + if (inputLength < 1) { + return Tcl_DStringValue(dstPtr); + } + + /* + * We can't use Tcl_ExternalToUtfDString at this point; it has no way to + * fail. So we use this modified version of it that can report encoding + * errors to us (so we can fall back to something else). + * + * The utf-8 encoding is implemented internally, and so is guaranteed to + * be present. + */ + + src = (const char *) inputBytes; + dst = Tcl_DStringValue(dstPtr); + dstLen = dstPtr->spaceAvl - 1; + flags = TCL_ENCODING_START | TCL_ENCODING_END | + TCL_ENCODING_STOPONERROR; /* Special flag! */ + + while (1) { + int srcRead, dstWrote; + int result = Tcl_ExternalToUtf(NULL, ZipFS.utf8, src, srcLen, flags, + &state, dst, dstLen, &srcRead, &dstWrote, NULL); + int soFar = dst + dstWrote - Tcl_DStringValue(dstPtr); + + if (result == TCL_OK) { + Tcl_DStringSetLength(dstPtr, soFar); + return Tcl_DStringValue(dstPtr); + } else if (result != TCL_CONVERT_NOSPACE) { + break; + } + + flags &= ~TCL_ENCODING_START; + src += srcRead; + srcLen -= srcRead; + if (Tcl_DStringLength(dstPtr) == 0) { + Tcl_DStringSetLength(dstPtr, dstLen); + } + Tcl_DStringSetLength(dstPtr, 2 * Tcl_DStringLength(dstPtr) + 1); + dst = Tcl_DStringValue(dstPtr) + soFar; + dstLen = Tcl_DStringLength(dstPtr) - soFar - 1; + } + + /* + * Something went wrong. Fall back to another encoding. Those *can* use + * Tcl_ExternalToUtfDString(). + */ + + encoding = NULL; + if (ZipFS.fallbackEntryEncoding) { + encoding = Tcl_GetEncoding(NULL, ZipFS.fallbackEntryEncoding); + } + if (!encoding) { + encoding = Tcl_GetEncoding(NULL, ZIPFS_FALLBACK_ENCODING); + } + if (!encoding) { + /* + * Fallback to internal encoding that always converts all bytes. + * Should only happen when a filename isn't UTF-8 and we've not got + * our encodings initialised for some reason. + */ + + encoding = Tcl_GetEncoding(NULL, "iso8859-1"); + } + + char *converted = Tcl_ExternalToUtfDString(encoding, + (const char *) inputBytes, inputLength, dstPtr); + Tcl_FreeEncoding(encoding); + return converted; +} + +/* + *------------------------------------------------------------------------- + * * CanonicalPath -- * * This function computes the canonical path from a directory and file @@ -1546,9 +1664,7 @@ ZipFSCatalogFilesystem( pathlen = ZipReadShort(start, end, q + ZIP_CENTRAL_PATHLEN_OFFS); comlen = ZipReadShort(start, end, q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); extra = ZipReadShort(start, end, q + ZIP_CENTRAL_EXTRALEN_OFFS); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); - path = Tcl_DStringValue(&ds); + path = DecodeZipEntryText(q + ZIP_CENTRAL_HEADER_LEN, pathlen, &ds); if ((pathlen > 0) && (path[pathlen - 1] == '/')) { Tcl_DStringSetLength(&ds, pathlen - 1); path = Tcl_DStringValue(&ds); @@ -1738,6 +1854,10 @@ ZipfsSetup(void) Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); ZipFS.idCount = 1; ZipFS.wrmax = DEFAULT_WRITE_MAX_SIZE; + ZipFS.fallbackEntryEncoding = + Tcl_Alloc(strlen(ZIPFS_FALLBACK_ENCODING) + 1); + strcpy(ZipFS.fallbackEntryEncoding, ZIPFS_FALLBACK_ENCODING); + ZipFS.utf8 = Tcl_GetEncoding(NULL, "utf-8"); ZipFS.initialized = 1; } @@ -2357,6 +2477,9 @@ RandomChar( * input file is added to the given fileHash table for later creation of * the central ZIP directory. * + * Tcl *always* encodes filenames in the ZIP as UTF-8. Similarly, it + * would always encode comments as UTF-8, if it supported comments. + * * Results: * A standard Tcl result. * @@ -2371,7 +2494,8 @@ static int ZipAddFile( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *pathObj, /* Actual name of the file to add. */ - const char *name, /* Name to use in the ZIP archive. */ + const char *name, /* Name to use in the ZIP archive, in Tcl's + * internal encoding. */ Tcl_Channel out, /* The open ZIP archive being built. */ const char *passwd, /* Password for encoding the file, or NULL if * the file is to be unprotected. */ @@ -2386,7 +2510,10 @@ ZipAddFile( Tcl_HashEntry *hPtr; ZipEntry *z; z_stream stream; - const char *zpath; + Tcl_DString zpathDs; /* Buffer for the encoded filename. */ + const char *zpathExt; /* Filename in external encoding (true + * UTF-8). */ + const char *zpathTcl; /* Filename in Tcl's internal encoding. */ int crc, flush, zpathlen; size_t nbyte, nbytecompr, len, olen, align = 0; long long headerStartOffset, dataStartOffset, dataEndOffset; @@ -2399,23 +2526,31 @@ ZipAddFile( * nothing to do. */ - zpath = name; - while (zpath && zpath[0] == '/') { - zpath++; + zpathTcl = name; + while (zpathTcl && zpathTcl[0] == '/') { + zpathTcl++; } - if (!zpath || (zpath[0] == '\0')) { + if (!zpathTcl || (zpathTcl[0] == '\0')) { return TCL_OK; } - zpathlen = strlen(zpath); + /* + * Convert to encoded form. Note that we use strlen() here; if someone's + * crazy enough to embed NULs in filenames, they deserve what they get! + */ + + zpathExt = Tcl_UtfToExternalDString(ZipFS.utf8, zpathTcl, -1, &zpathDs); + zpathlen = strlen(zpathExt); if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "path too long for \"%s\"", Tcl_GetString(pathObj))); ZIPFS_ERROR_CODE(interp, "PATH_LEN"); + Tcl_DStringFree(&zpathDs); return TCL_ERROR; } in = Tcl_FSOpenFileChannel(interp, pathObj, "rb", 0); if (!in) { + Tcl_DStringFree(&zpathDs); #ifdef _WIN32 /* hopefully a directory */ if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { @@ -2443,6 +2578,7 @@ ZipAddFile( while (1) { len = Tcl_Read(in, buf, bufsize); if (len == ERROR_LENGTH) { + Tcl_DStringFree(&zpathDs); if (nbyte == 0 && errno == EISDIR) { Tcl_Close(interp, in); return TCL_OK; @@ -2463,6 +2599,7 @@ ZipAddFile( Tcl_SetObjResult(interp, Tcl_ObjPrintf("seek error on \"%s\": %s", Tcl_GetString(pathObj), Tcl_PosixError(interp))); Tcl_Close(interp, in); + Tcl_DStringFree(&zpathDs); return TCL_ERROR; } @@ -2479,7 +2616,7 @@ ZipAddFile( */ memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); - memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); + memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpathExt, zpathlen); len = zpathlen + ZIP_LOCAL_HEADER_LEN; if ((size_t) Tcl_Write(out, buf, len) != len) { writeErrorWithChannelOpen: @@ -2487,6 +2624,7 @@ ZipAddFile( "write error on \"%s\": %s", Tcl_GetString(pathObj), Tcl_PosixError(interp))); Tcl_Close(interp, in); + Tcl_DStringFree(&zpathDs); return TCL_ERROR; } @@ -2563,6 +2701,7 @@ ZipAddFile( "compression init error on \"%s\"", Tcl_GetString(pathObj))); ZIPFS_ERROR_CODE(interp, "DEFLATE_INIT"); Tcl_Close(interp, in); + Tcl_DStringFree(&zpathDs); return TCL_ERROR; } @@ -2585,6 +2724,7 @@ ZipAddFile( ZIPFS_ERROR_CODE(interp, "DEFLATE"); deflateEnd(&stream); Tcl_Close(interp, in); + Tcl_DStringFree(&zpathDs); return TCL_ERROR; } olen = sizeof(obuf) - stream.avail_out; @@ -2625,6 +2765,7 @@ ZipAddFile( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "seek error: %s", Tcl_PosixError(interp))); Tcl_Close(interp, in); + Tcl_DStringFree(&zpathDs); return TCL_ERROR; } nbytecompr = (passwd ? 12 : 0); @@ -2660,8 +2801,10 @@ ZipAddFile( Tcl_TruncateChannel(out, dataEndOffset); } Tcl_Close(interp, in); + Tcl_DStringFree(&zpathDs); + zpathExt = NULL; - hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); + hPtr = Tcl_CreateHashEntry(fileHash, zpathTcl, &isNew); if (!isNew) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "non-unique path name \"%s\"", Tcl_GetString(pathObj))); @@ -2758,8 +2901,8 @@ ZipFSFind( * should be skipped. * * Returns: - * Pointer to the name, which will be in memory owned by one of the - * argument objects. + * Pointer to the name (in Tcl's internal encoding), which will be in + * memory owned by one of the argument objects. * * Side effects: * None (if Tcl_Objs have string representations) @@ -2772,8 +2915,10 @@ ComputeNameInArchive( Tcl_Obj *pathObj, /* The path to the origin file */ Tcl_Obj *directNameObj, /* User-specified name for use in the ZIP * archive */ - const char *strip, /* A prefix to strip */ - int slen) /* The length of the prefix */ + const char *strip, /* A prefix to strip; may be NULL if no + * stripping need be done. */ + int slen) /* The length of the prefix; must be 0 if no + * stripping need be done. */ { const char *name; int len; @@ -2811,6 +2956,9 @@ ComputeNameInArchive( * file. It's the core of the implementation of [zipfs mkzip], [zipfs * mkimg], [zipfs lmkzip] and [zipfs lmkimg]. * + * Tcl *always* encodes filenames in the ZIP as UTF-8. Similarly, it + * would always encode comments as UTF-8, if it supported comments. + * * Results: * A standard Tcl result. * @@ -3023,6 +3171,9 @@ ZipFSMkZipOrImg( dataStartOffset = Tcl_Tell(out); if (mappingList == NULL && stripPrefix != NULL) { strip = Tcl_GetStringFromObj(stripPrefix, &slen); + if (!slen) { + strip = NULL; + } } for (i = 0; i < (size_t) lobjc; i += (mappingList ? 2 : 1)) { Tcl_Obj *pathObj = lobjv[i]; @@ -3047,25 +3198,27 @@ ZipFSMkZipOrImg( for (i = 0; i < (size_t) lobjc; i += (mappingList ? 2 : 1)) { const char *name = ComputeNameInArchive(lobjv[i], (mappingList ? lobjv[i + 1] : NULL), strip, slen); + Tcl_DString ds; - if (name[0] == '\0') { - continue; - } hPtr = Tcl_FindHashEntry(&fileHash, name); if (!hPtr) { continue; } z = (ZipEntry *) Tcl_GetHashValue(hPtr); - len = strlen(z->name); + + name = Tcl_UtfToExternalDString(ZipFS.utf8, z->name, -1, &ds); + len = Tcl_DStringLength(&ds); SerializeCentralDirectoryEntry(start, end, (unsigned char *) buf, z, len, dataStartOffset); if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) - || ((size_t) Tcl_Write(out, z->name, len) != len)) { + || ((size_t) Tcl_Write(out, name, len) != len)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); + Tcl_DStringFree(&ds); goto done; } + Tcl_DStringFree(&ds); count++; } @@ -5517,6 +5670,8 @@ TclZipfs_Init( if (!Tcl_IsSafe(interp)) { Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, TCL_LINK_INT); + Tcl_LinkVar(interp, "::tcl::zipfs::fallbackEntryEncoding", + (char *) &ZipFS.fallbackEntryEncoding, TCL_LINK_STRING); } ensemble = TclMakeEnsemble(interp, "zipfs", Tcl_IsSafe(interp) ? (initMap + 4) : initMap); -- cgit v0.12 From fff5060d945d7ee8f74e84dea9b0f703e2bae424 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 19 Mar 2021 09:20:26 +0000 Subject: Change Tcl_StaticPackage's "pkgName" argument to "prefix" and improve documentation, describing better what this argument does. --- doc/StaticPkg.3 | 8 +++--- doc/load.n | 71 +++++++++++++++++++++++++-------------------------- doc/unload.n | 36 +++++++++++++------------- generic/tcl.decls | 2 +- generic/tclDecls.h | 4 +-- generic/tclInt.decls | 2 +- generic/tclIntDecls.h | 4 +-- generic/tclLoad.c | 62 ++++++++++++++++++++++---------------------- generic/tclTest.c | 2 +- tests/load.test | 2 +- 10 files changed, 96 insertions(+), 97 deletions(-) diff --git a/doc/StaticPkg.3 b/doc/StaticPkg.3 index 41e2d65..bd00ab7 100644 --- a/doc/StaticPkg.3 +++ b/doc/StaticPkg.3 @@ -13,7 +13,7 @@ Tcl_StaticPackage \- make a statically linked package available via the 'load' c .nf \fB#include \fR .sp -\fBTcl_StaticPackage\fR(\fIinterp, pkgName, initProc, safeInitProc\fR) +\fBTcl_StaticPackage\fR(\fIinterp, prefix, initProc, safeInitProc\fR) .SH ARGUMENTS .AS Tcl_PackageInitProc *safeInitProc .AP Tcl_Interp *interp in @@ -21,9 +21,9 @@ If not NULL, points to an interpreter into which the package has already been loaded (i.e., the caller has already invoked the appropriate initialization procedure). NULL means the package has not yet been incorporated into any interpreter. -.AP "const char" *pkgName in -Name of the package; should be properly capitalized (first letter -upper-case, all others lower-case). +.AP "const char" *prefix in +Prefix for library initialization function; should be properly +capitalized (first letter upper-case, all others lower-case). .AP Tcl_PackageInitProc *initProc in Procedure to invoke to incorporate this package into a trusted interpreter. diff --git a/doc/load.n b/doc/load.n index b592bb3..54d90a3 100644 --- a/doc/load.n +++ b/doc/load.n @@ -13,22 +13,21 @@ load \- Load machine code and initialize new commands .SH SYNOPSIS \fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName\fR .br -\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName\fR +\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName prefix\fR .br -\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName interp\fR +\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName prefix interp\fR .BE .SH DESCRIPTION .PP This command loads binary code from a file into the application's address space and calls an initialization procedure -in the package to incorporate it into an interpreter. \fIfileName\fR +in the library to incorporate it into an interpreter. \fIfileName\fR is the name of the file containing the code; its exact form varies from system to system but on most systems it is a shared library, such as a \fB.so\fR file under Solaris or a DLL under Windows. -\fIpackageName\fR is the name of the package, and is used to -compute the name of an initialization procedure. +\fIprefix\fR is used to compute the name of an initialization procedure. \fIinterp\fR is the path name of the interpreter into which to load -the package (see the \fBinterp\fR manual entry for details); +the library (see the \fBinterp\fR manual entry for details); if \fIinterp\fR is omitted, it defaults to the interpreter in which the \fBload\fR command was invoked. .PP @@ -37,21 +36,21 @@ one of two initialization procedures will be invoked in the new code. Typically the initialization procedure will add new commands to a Tcl interpreter. The name of the initialization procedure is determined by -\fIpackageName\fR and whether or not the target interpreter +\fIprefix\fR and whether or not the target interpreter is a safe one. For normal interpreters the name of the initialization -procedure will have the form \fIpkg\fB_Init\fR, where \fIpkg\fR -is the same as \fIpackageName\fR except that the first letter is +procedure will have the form \fIpfx\fB_Init\fR, where \fIpfx\fR +is the same as \fIprefix\fR except that the first letter is converted to upper case and all other letters -are converted to lower case. For example, if \fIpackageName\fR is +are converted to lower case. For example, if \fIprefix\fR is \fBfoo\fR or \fBFOo\fR, the initialization procedure's name will be \fBFoo_Init\fR. .PP If the target interpreter is a safe interpreter, then the name -of the initialization procedure will be \fIpkg\fB_SafeInit\fR -instead of \fIpkg\fB_Init\fR. -The \fIpkg\fB_SafeInit\fR function should be written carefully, so that it +of the initialization procedure will be \fIpfx\fB_SafeInit\fR +instead of \fIpfx\fB_Init\fR. +The \fIpfx\fB_SafeInit\fR function should be written carefully, so that it initializes the safe interpreter only with partial functionality provided -by the package that is safe for use by untrusted code. For more information +by the library that is safe for use by untrusted code. For more information on Safe\-Tcl, see the \fBsafe\fR manual entry. .PP The initialization procedure must match the following prototype: @@ -62,7 +61,7 @@ typedef int \fBTcl_PackageInitProc\fR( .CE .PP The \fIinterp\fR argument identifies the interpreter in which the -package is to be loaded. The initialization procedure must return +library is to be loaded. The initialization procedure must return \fBTCL_OK\fR or \fBTCL_ERROR\fR to indicate whether or not it completed successfully; in the event of an error it should set the interpreter's result to point to an error message. The result of the \fBload\fR command @@ -74,36 +73,36 @@ interpreters, then the first \fBload\fR will load the code and call the initialization procedure; subsequent \fBload\fRs will call the initialization procedure without loading the code again. For Tcl versions lower than 8.5, it is not possible to unload or reload a -package. From version 8.5 however, the \fBunload\fR command allows the unloading +library. From version 8.5 however, the \fBunload\fR command allows the unloading of libraries loaded with \fBload\fR, for libraries that are aware of the Tcl's unloading mechanism. .PP -The \fBload\fR command also supports packages that are statically -linked with the application, if those packages have been registered +The \fBload\fR command also supports libraries that are statically +linked with the application, if those libraries have been registered by calling the \fBTcl_StaticPackage\fR procedure. -If \fIfileName\fR is an empty string, then \fIpackageName\fR must +If \fIfileName\fR is an empty string, then \fIprefix\fR must be specified. .PP -If \fIpackageName\fR is omitted or specified as an empty string, -Tcl tries to guess the name of the package. -This may be done differently on different platforms. -The default guess, which is used on most UNIX platforms, is to -take the last element of \fIfileName\fR, strip off the first -three characters if they are \fBlib\fR, and use any following -alphabetic and underline characters as the module name. -For example, the command \fBload libxyz4.2.so\fR uses the module -name \fBxyz\fR and the command \fBload bin/last.so {}\fR uses the -module name \fBlast\fR. -.PP -If \fIfileName\fR is an empty string, then \fIpackageName\fR must +If \fIprefix\fR is omitted or specified as an empty string, +Tcl tries to guess the prefix. This may be done differently on +different platforms. The default guess, which is used on most +UNIX platforms, is to take the last element of +\fIfileName\fR, strip off the first three characters if they +are \fBlib\fR, and use any following alphabetic and +underline characters, converted to titlecase as the prefix. +For example, the command \fBload libxyz4.2.so\fR uses the prefix +\fBXyz\fR and the command \fBload bin/last.so {}\fR uses the +prefix \fBLast\fR. +.PP +If \fIfileName\fR is an empty string, then \fIprefix\fR must be specified. -The \fBload\fR command first searches for a statically loaded package +The \fBload\fR command first searches for a statically loaded library (one that has been registered by calling the \fBTcl_StaticPackage\fR procedure) by that name; if one is found, it is used. Otherwise, the \fBload\fR command searches for a dynamically loaded -package by that name, and uses it if it is found. If several +library by that name, and uses it if it is found. If several different files have been \fBload\fRed with different versions of -the package, Tcl picks the file that was loaded first. +the library, Tcl picks the file that was loaded first. .PP If \fB\-global\fR is specified preceding the filename, all symbols found in the shared library are exported for global use by other @@ -111,7 +110,7 @@ libraries. The option \fB\-lazy\fR delays the actual loading of symbols until their first actual use. The options may be abbreviated. The option \fB\-\-\fR indicates the end of the options, and should be used if you wish to use a filename which starts with \fB\-\fR -and you provide a packageName to the \fBload\fR command. +and you provide a prefix to the \fBload\fR command. .PP On platforms which do not support the \fB\-global\fR or \fB\-lazy\fR options, the options still exist but have no effect. Note that use @@ -154,7 +153,7 @@ The following is a minimal extension: .CS #include #include -static int fooCmd(ClientData clientData, +static int fooCmd(void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { printf("called with %d arguments\en", objc); return TCL_OK; diff --git a/doc/unload.n b/doc/unload.n index 0a8e99b..61caca1 100644 --- a/doc/unload.n +++ b/doc/unload.n @@ -13,9 +13,9 @@ unload \- Unload machine code .SH SYNOPSIS \fBunload \fR?\fIswitches\fR? \fIfileName\fR .br -\fBunload \fR?\fIswitches\fR? \fIfileName packageName\fR +\fBunload \fR?\fIswitches\fR? \fIfileName prefix\fR .br -\fBunload \fR?\fIswitches\fR? \fIfileName packageName interp\fR +\fBunload \fR?\fIswitches\fR? \fIfileName prefix interp\fR .BE .SH DESCRIPTION .PP @@ -24,7 +24,7 @@ with \fBload\fR from the application's address space. \fIfileName\fR is the name of the file containing the library file to be unload; it must be the same as the filename provided to \fBload\fR for loading the library. -The \fIpackageName\fR argument is the name of the package (as +The \fIprefix\fR argument is the prefix (as determined by or passed to \fBload\fR), and is used to compute the name of the unload procedure; if not supplied, it is computed from \fIfileName\fR in the same manner as \fBload\fR. @@ -66,12 +66,12 @@ proper reference count. \fBunload\fR works in the opposite direction. As a first step, \fBunload\fR will check whether the library is unloadable: an unloadable library exports a special unload procedure. The name of the unload procedure is determined by -\fIpackageName\fR and whether or not the target interpreter +\fIprefix\fR and whether or not the target interpreter is a safe one. For normal interpreters the name of the initialization -procedure will have the form \fIpkg\fB_Unload\fR, where \fIpkg\fR -is the same as \fIpackageName\fR except that the first letter is +procedure will have the form \fIpfx\fB_Unload\fR, where \fIpfx\fR +is the same as \fIprefix\fR except that the first letter is converted to upper case and all other letters -are converted to lower case. For example, if \fIpackageName\fR is +are converted to lower case. For example, if \fIprefix\fR is \fBfoo\fR or \fBFOo\fR, the initialization procedure's name will be \fBFoo_Unload\fR. If the target interpreter is a safe interpreter, then the name @@ -114,19 +114,19 @@ the \fIflags\fR argument will be set to \fBTCL_UNLOAD_DETACH_FROM_PROCESS\fR. .PP The \fBunload\fR command cannot unload libraries that are statically linked with the application. -If \fIfileName\fR is an empty string, then the \fIpackageName\fR argument must +If \fIfileName\fR is an empty string, then the \fIprefix\fR argument must be specified. .PP -If \fIpackageName\fR is omitted or specified as an empty string, -Tcl tries to guess the name of the package. -This may be done differently on different platforms. -The default guess, which is used on most UNIX platforms, is to -take the last element of \fIfileName\fR, strip off the first -three characters if they are \fBlib\fR, and use any following -alphabetic and underline characters as the module name. -For example, the command \fBunload libxyz4.2.so\fR uses the module -name \fBxyz\fR and the command \fBunload bin/last.so {}\fR uses the -module name \fBlast\fR. +If \fIprefix\fR is omitted or specified as an empty string, +Tcl tries to guess the prefix. This may be done differently on +different platforms. The default guess, which is used on most +UNIX platforms, is to take the last element of +\fIfileName\fR, strip off the first three characters if they +are \fBlib\fR, and use any following alphabetic and +underline characters, converted to titlecase as the prefix. +For example, the command \fBunload libxyz4.2.so\fR uses the prefix +\fBXyz\fR and the command \fBunload bin/last.so {}\fR uses the +prefix \fBLast\fR. .SH "PORTABILITY ISSUES" .TP \fBUnix\fR\0\0\0\0\0 diff --git a/generic/tcl.decls b/generic/tcl.decls index 6583aff..05cecdd 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -861,7 +861,7 @@ declare 243 { void Tcl_SplitPath(const char *path, int *argcPtr, CONST84 char ***argvPtr) } declare 244 { - void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName, + void Tcl_StaticPackage(Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } declare 245 { diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 89c2808..37764da 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -725,7 +725,7 @@ EXTERN void Tcl_SplitPath(const char *path, int *argcPtr, CONST84 char ***argvPtr); /* 244 */ EXTERN void Tcl_StaticPackage(Tcl_Interp *interp, - const char *pkgName, + const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 245 */ @@ -2121,7 +2121,7 @@ typedef struct TclStubs { void (*tcl_SourceRCFile) (Tcl_Interp *interp); /* 241 */ int (*tcl_SplitList) (Tcl_Interp *interp, const char *listStr, int *argcPtr, CONST84 char ***argvPtr); /* 242 */ void (*tcl_SplitPath) (const char *path, int *argcPtr, CONST84 char ***argvPtr); /* 243 */ - void (*tcl_StaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */ + void (*tcl_StaticPackage) (Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */ int (*tcl_StringMatch) (const char *str, const char *pattern); /* 245 */ int (*tcl_TellOld) (Tcl_Channel chan); /* 246 */ int (*tcl_TraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 247 */ diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 3c3b50a..6e36971 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -1040,7 +1040,7 @@ declare 256 { } declare 257 { - void TclStaticPackage(Tcl_Interp *interp, const char *pkgName, + void TclStaticPackage(Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index b7ac0e7..27fbb86 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -640,7 +640,7 @@ EXTERN int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Obj *part2Ptr, const int flags); /* 257 */ EXTERN void TclStaticPackage(Tcl_Interp *interp, - const char *pkgName, + const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* Slot 258 is reserved */ @@ -909,7 +909,7 @@ typedef struct TclIntStubs { Tcl_Obj * (*tclPtrIncrObjVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, const int flags); /* 254 */ int (*tclPtrObjMakeUpvar) (Tcl_Interp *interp, Tcl_Var otherPtr, Tcl_Obj *myNamePtr, int myFlags); /* 255 */ int (*tclPtrUnsetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 256 */ - void (*tclStaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ + void (*tclStaticPackage) (Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ void (*reserved258)(void); void (*reserved259)(void); void (*tclUnusedStubEntry) (void); /* 260 */ diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 9ca2e7a..a6fd7ec 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -122,7 +122,7 @@ Tcl_LoadObjCmd( { Tcl_Interp *target; LoadedPackage *pkgPtr, *defaultPtr; - Tcl_DString pkgName, tmp, initName, safeInitName; + Tcl_DString prefix, tmp, initName, safeInitName; Tcl_DString unloadName, safeUnloadName; InterpPackage *ipFirstPtr, *ipPtr; int code, namesMatch, filesMatch, offset; @@ -167,7 +167,7 @@ Tcl_LoadObjCmd( } fullFileName = Tcl_GetString(objv[1]); - Tcl_DStringInit(&pkgName); + Tcl_DStringInit(&prefix); Tcl_DStringInit(&initName); Tcl_DStringInit(&safeInitName); Tcl_DStringInit(&unloadName); @@ -222,20 +222,20 @@ Tcl_LoadObjCmd( if (packageName == NULL) { namesMatch = 0; } else { - TclDStringClear(&pkgName); - Tcl_DStringAppend(&pkgName, packageName, -1); + TclDStringClear(&prefix); + Tcl_DStringAppend(&prefix, packageName, -1); TclDStringClear(&tmp); Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1); - Tcl_UtfToLower(Tcl_DStringValue(&pkgName)); + Tcl_UtfToLower(Tcl_DStringValue(&prefix)); Tcl_UtfToLower(Tcl_DStringValue(&tmp)); if (strcmp(Tcl_DStringValue(&tmp), - Tcl_DStringValue(&pkgName)) == 0) { + Tcl_DStringValue(&prefix)) == 0) { namesMatch = 1; } else { namesMatch = 0; } } - TclDStringClear(&pkgName); + TclDStringClear(&prefix); filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0); if (filesMatch && (namesMatch || (packageName == NULL))) { @@ -300,7 +300,7 @@ Tcl_LoadObjCmd( */ if (packageName != NULL) { - Tcl_DStringAppend(&pkgName, packageName, -1); + Tcl_DStringAppend(&prefix, packageName, -1); } else { int retc; @@ -308,7 +308,7 @@ Tcl_LoadObjCmd( * Threading note - this call used to be protected by a mutex. */ - retc = TclGuessPackageName(fullFileName, &pkgName); + retc = TclGuessPackageName(fullFileName, &prefix); if (!retc) { Tcl_Obj *splitPtr, *pkgGuessPtr; int pElements; @@ -353,7 +353,7 @@ Tcl_LoadObjCmd( code = TCL_ERROR; goto done; } - Tcl_DStringAppend(&pkgName, pkgGuess, p - pkgGuess); + Tcl_DStringAppend(&prefix, pkgGuess, p - pkgGuess); Tcl_DecrRefCount(splitPtr); } } @@ -364,21 +364,21 @@ Tcl_LoadObjCmd( * lower-case. */ - Tcl_DStringSetLength(&pkgName, - Tcl_UtfToTitle(Tcl_DStringValue(&pkgName))); + Tcl_DStringSetLength(&prefix, + Tcl_UtfToTitle(Tcl_DStringValue(&prefix))); /* * Compute the names of the two initialization functions, based on the * package name. */ - TclDStringAppendDString(&initName, &pkgName); + TclDStringAppendDString(&initName, &prefix); TclDStringAppendLiteral(&initName, "_Init"); - TclDStringAppendDString(&safeInitName, &pkgName); + TclDStringAppendDString(&safeInitName, &prefix); TclDStringAppendLiteral(&safeInitName, "_SafeInit"); - TclDStringAppendDString(&unloadName, &pkgName); + TclDStringAppendDString(&unloadName, &prefix); TclDStringAppendLiteral(&unloadName, "_Unload"); - TclDStringAppendDString(&safeUnloadName, &pkgName); + TclDStringAppendDString(&safeUnloadName, &prefix); TclDStringAppendLiteral(&safeUnloadName, "_SafeUnload"); /* @@ -405,9 +405,9 @@ Tcl_LoadObjCmd( len = strlen(fullFileName) + 1; pkgPtr->fileName = ckalloc(len); memcpy(pkgPtr->fileName, fullFileName, len); - len = (unsigned) Tcl_DStringLength(&pkgName) + 1; + len = (unsigned) Tcl_DStringLength(&prefix) + 1; pkgPtr->packageName = ckalloc(len); - memcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName), len); + memcpy(pkgPtr->packageName, Tcl_DStringValue(&prefix), len); pkgPtr->loadHandle = loadHandle; pkgPtr->initProc = initProc; pkgPtr->safeInitProc = (Tcl_PackageInitProc *) @@ -501,7 +501,7 @@ Tcl_LoadObjCmd( Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipPtr); done: - Tcl_DStringFree(&pkgName); + Tcl_DStringFree(&prefix); Tcl_DStringFree(&initName); Tcl_DStringFree(&safeInitName); Tcl_DStringFree(&unloadName); @@ -536,7 +536,7 @@ Tcl_UnloadObjCmd( { Tcl_Interp *target; /* Which interpreter to unload from. */ LoadedPackage *pkgPtr, *defaultPtr; - Tcl_DString pkgName, tmp; + Tcl_DString prefix, tmp; Tcl_PackageUnloadProc *unloadProc; InterpPackage *ipFirstPtr, *ipPtr; int i, index, code, complain = 1, keepLibrary = 0; @@ -594,7 +594,7 @@ Tcl_UnloadObjCmd( } fullFileName = Tcl_GetString(objv[i]); - Tcl_DStringInit(&pkgName); + Tcl_DStringInit(&prefix); Tcl_DStringInit(&tmp); packageName = NULL; @@ -646,20 +646,20 @@ Tcl_UnloadObjCmd( if (packageName == NULL) { namesMatch = 0; } else { - TclDStringClear(&pkgName); - Tcl_DStringAppend(&pkgName, packageName, -1); + TclDStringClear(&prefix); + Tcl_DStringAppend(&prefix, packageName, -1); TclDStringClear(&tmp); Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1); - Tcl_UtfToLower(Tcl_DStringValue(&pkgName)); + Tcl_UtfToLower(Tcl_DStringValue(&prefix)); Tcl_UtfToLower(Tcl_DStringValue(&tmp)); if (strcmp(Tcl_DStringValue(&tmp), - Tcl_DStringValue(&pkgName)) == 0) { + Tcl_DStringValue(&prefix)) == 0) { namesMatch = 1; } else { namesMatch = 0; } } - TclDStringClear(&pkgName); + TclDStringClear(&prefix); filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0); if (filesMatch && (namesMatch || (packageName == NULL))) { @@ -899,7 +899,7 @@ Tcl_UnloadObjCmd( } done: - Tcl_DStringFree(&pkgName); + Tcl_DStringFree(&prefix); Tcl_DStringFree(&tmp); if (!complain && (code != TCL_OK)) { code = TCL_OK; @@ -932,7 +932,7 @@ Tcl_StaticPackage( * already been loaded into the given * interpreter by calling the appropriate init * proc. */ - const char *pkgName, /* Name of package (must be properly + const char *prefix, /* Prefix (must be properly * capitalized: first letter upper case, * others lower case). */ Tcl_PackageInitProc *initProc, @@ -957,7 +957,7 @@ Tcl_StaticPackage( for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { if ((pkgPtr->initProc == initProc) && (pkgPtr->safeInitProc == safeInitProc) - && (strcmp(pkgPtr->packageName, pkgName) == 0)) { + && (strcmp(pkgPtr->packageName, prefix) == 0)) { break; } } @@ -972,8 +972,8 @@ Tcl_StaticPackage( pkgPtr = ckalloc(sizeof(LoadedPackage)); pkgPtr->fileName = ckalloc(1); pkgPtr->fileName[0] = 0; - pkgPtr->packageName = ckalloc(strlen(pkgName) + 1); - strcpy(pkgPtr->packageName, pkgName); + pkgPtr->packageName = ckalloc(strlen(prefix) + 1); + strcpy(pkgPtr->packageName, prefix); pkgPtr->loadHandle = NULL; pkgPtr->initProc = initProc; pkgPtr->safeInitProc = safeInitProc; diff --git a/generic/tclTest.c b/generic/tclTest.c index 2c29cda..a759e74 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -4185,7 +4185,7 @@ TeststaticpkgCmd( if (argc != 4) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", - argv[0], " pkgName safe loaded\"", NULL); + argv[0], " prefix safe loaded\"", NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &safe) != TCL_OK) { diff --git a/tests/load.test b/tests/load.test index c79ddf4..b13f1f4 100644 --- a/tests/load.test +++ b/tests/load.test @@ -234,7 +234,7 @@ test load-10.1 {load from vfs} -setup { cd $testDir testsimplefilesystem 1 } -constraints [list $dll $loaded testsimplefilesystem] -body { - list [catch {load simplefs:/pkgd$ext pkgd} msg] $msg + list [catch {load simplefs:/pkgd$ext Pkgd} msg] $msg } -result {0 {}} -cleanup { testsimplefilesystem 0 cd $dir -- cgit v0.12 From d5479489aab71c267a1371d2ac1d0674a15a0c61 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 19 Mar 2021 12:58:41 +0000 Subject: Fully implement TCL_ENCODING_STOPONERROR flag for Utf2Utf encoder/decoder. --- generic/tclEncoding.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 688d46e..4eabbda 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2225,7 +2225,7 @@ UtfToUtfProc( result = TCL_CONVERT_NOSPACE; break; } - if ((UCHAR(*src - 1) < 0x7F) && !(flags & TCL_ENCODING_EXTERNAL)) { + if (UCHAR(*src) < 0x80 && !(UCHAR(*src) == 0 && !(flags & TCL_ENCODING_EXTERNAL))) { /* * Copy 7bit characters, but skip null-bytes when we are in input * mode, so that they get converted to 0xC080. @@ -2256,14 +2256,19 @@ UtfToUtfProc( src += 1; dst += Tcl_UniCharToUtf(ch, dst); } else { - src += TclUtfToUCS4(src, &ch); + size_t len = TclUtfToUCS4(src, &ch); + if ((len < 2) && (ch != 0) && (flags & TCL_ENCODING_STOPONERROR)) { + result = TCL_CONVERT_SYNTAX; + break; + } + src += len; if ((ch | 0x7FF) == 0xDFFF) { /* * A surrogate character is detected, handle especially. */ int low = ch; - size_t len = (src <= srcEnd-3) ? TclUtfToUCS4(src, &low) : 0; + len = (src <= srcEnd-3) ? TclUtfToUCS4(src, &low) : 0; if (((low & ~0x3FF) != 0xDC00) || (ch & 0x400)) { *dst++ = (char) (((ch >> 12) | 0xE0) & 0xEF); -- cgit v0.12 From dd9f3c1246178a54af32d25015227a5a1a7dced8 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 21 Mar 2021 09:27:07 +0000 Subject: Implement TCL_ENCODING_STOPONERROR flag for UtfToUtf encoder/decoder. Backported from 8.7 --- generic/tclEncoding.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index f1529e1..012c954 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2345,15 +2345,24 @@ UtfToUtfProc( /* * Always check before using TclUtfToUniChar. Not doing can so * cause it run beyond the end of the buffer! If we happen such an - * incomplete char its bytes are made to represent themselves. + * incomplete char its bytes are made to represent themselves + * unless the user has explicitly asked to be told. */ + if (flags & TCL_ENCODING_STOPONERROR) { + result = TCL_CONVERT_MULTIBYTE; + break; + } *chPtr = UCHAR(*src); src += 1; dst += Tcl_UniCharToUtf(*chPtr, dst); } else { size_t len = TclUtfToUniChar(src, chPtr); - + if ((len < 2) && (flags & TCL_ENCODING_STOPONERROR) && (*chPtr != 0) + && ((*chPtr & ~0x7FF) != 0xD800)) { + result = TCL_CONVERT_SYNTAX; + break; + } src += len; if ((*chPtr & ~0x7FF) == 0xD800) { Tcl_UniChar low; @@ -2453,8 +2462,13 @@ UnicodeToUtfProc( result = TCL_CONVERT_MULTIBYTE; srcLen--; } - /* If last code point is a high surrogate, we cannot handle that yet */ - if ((srcLen >= 2) && ((src[srcLen - (clientData?1:2)] & 0xFC) == 0xD8)) { + + /* + * If last code point is a high surrogate, we cannot handle that yet. + */ + + if ((srcLen >= 2) && + ((src[srcLen - (clientData?1:2)] & 0xFC) == 0xD8)) { result = TCL_CONVERT_MULTIBYTE; srcLen-= 2; } @@ -2476,10 +2490,12 @@ UnicodeToUtfProc( } else { ch = (src[0] & 0xFF) << 8 | (src[1] & 0xFF); } + /* * Special case for 1-byte utf chars for speed. Make sure we work with * unsigned short-size data. */ + if (ch && ch < 0x80) { *dst++ = (ch & 0xFF); } else { @@ -3015,7 +3031,9 @@ Iso88591FromUtfProc( break; } #if TCL_UTF_MAX == 4 - if ((ch >= 0xD800) && (len < 3)) len = 4; + if ((ch >= 0xD800) && (len < 3)) { + len = 4; + } #endif /* * Plunge on, using '?' as a fallback character. @@ -3060,7 +3078,7 @@ TableFreeProc( ClientData clientData) /* TableEncodingData that specifies * encoding. */ { - TableEncodingData *dataPtr = (TableEncodingData *)clientData; + TableEncodingData *dataPtr = (TableEncodingData *) clientData; /* * Make sure we aren't freeing twice on shutdown. [Bug 219314] @@ -3118,7 +3136,7 @@ EscapeToUtfProc( * correspond to the bytes stored in the * output buffer. */ { - EscapeEncodingData *dataPtr = (EscapeEncodingData *)clientData; + EscapeEncodingData *dataPtr = (EscapeEncodingData *) clientData; const char *prefixBytes, *tablePrefixBytes, *srcStart, *srcEnd; const unsigned short *const *tableToUnicode; const Encoding *encodingPtr; -- cgit v0.12 From c49b98fa6b7afdb6f63c4abca16d73c56990b715 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 21 Mar 2021 13:07:15 +0000 Subject: Start of doing a clean up of the notifier code. This originated as trying to stop macOS builds from doing silly warnings during a static build, but I noticed that there were common patterns that belong in generic code instead of being repeated in each of the platform-specific pieces. --- generic/tclAlloc.c | 2 + generic/tclInt.h | 26 ++- generic/tclThreadJoin.c | 2 + unix/tclEpollNotfy.c | 428 ++++++++++++++++++++++++++---------------------- unix/tclKqueueNotfy.c | 20 ++- unix/tclSelectNotfy.c | 16 +- unix/tclUnixEvent.c | 2 + 7 files changed, 278 insertions(+), 218 deletions(-) diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c index 2043248..03655b9 100644 --- a/generic/tclAlloc.c +++ b/generic/tclAlloc.c @@ -748,6 +748,8 @@ TclpRealloc( } #endif /* !USE_TCLALLOC */ +#else +TCL_MAC_EMPTY_FILE(generic_tclAlloc_c) #endif /* !TCL_THREADS */ /* diff --git a/generic/tclInt.h b/generic/tclInt.h index 1d192ff..4c3977a 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -5145,11 +5145,33 @@ typedef struct NRE_callback { #endif /* + * Special hack for macOS, where the static linker (technically the 'ar' + * command) hates empty object files, and accepts no flags to make it shut up. + * + * These symbols are otherwise completely useless. + * + * They can't be written to or written through. They can't be seen by any + * other code. They use a separate attribute (supported by all macOS + * compilers, which are derivatives of clang or gcc) to stop the compilation + * from moaning. They will be excluded during the final linking stage. + * + * Other platforms get nothing at all. That's good. + */ + +#ifdef MAC_OSX_TCL +#define TCL_MAC_EMPTY_FILE(name) \ + static __attribute__((used)) const void *const TclUnusedFile_ ## name; \ + static const void *const TclUnusedFile_ ## name = NULL; +#else +#define TCL_MAC_EMPTY_FILE(name) +#endif /* MAC_OSX_TCL */ + +/* * Other externals. */ -MODULE_SCOPE size_t TclEnvEpoch; /* Epoch of the tcl environment - * (if changed with tcl-env). */ +MODULE_SCOPE size_t TclEnvEpoch; /* Epoch of the tcl environment + * (if changed with tcl-env). */ #endif /* _TCLINT */ diff --git a/generic/tclThreadJoin.c b/generic/tclThreadJoin.c index ba789d3..4d2aca5 100644 --- a/generic/tclThreadJoin.c +++ b/generic/tclThreadJoin.c @@ -305,6 +305,8 @@ TclSignalExitThread( Tcl_MutexUnlock(&threadPtr->threadMutex); } +#else +TCL_MAC_EMPTY_FILE(generic_tclThreadJoin_c) #endif /* _WIN32 */ /* diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c index 3a99e6d..5de6c90 100644 --- a/unix/tclEpollNotfy.c +++ b/unix/tclEpollNotfy.c @@ -119,6 +119,9 @@ static Tcl_ThreadDataKey dataKey; * Forward declarations. */ +static void PlatformCreateFileHandler(int fd, int mask, + Tcl_FileProc *proc, ClientData clientData); +static void PlatformDeleteFileHandler(int fd) static void PlatformEventsControl(FileHandler *filePtr, ThreadSpecificData *tsdPtr, int op, int isNew); static void PlatformEventsFinalize(void); @@ -126,6 +129,7 @@ static void PlatformEventsInit(void); static int PlatformEventsTranslate(struct epoll_event *event); static int PlatformEventsWait(struct epoll_event *events, size_t numEvents, struct timeval *timePtr); +static int PlatformWaitForEvent(const Tcl_Time *timePtr); /* * Incorporate the base notifier API. @@ -144,8 +148,8 @@ static int PlatformEventsWait(struct epoll_event *events, * Returns a handle to the notifier state for this thread. * * Side effects: - * If no initNotifierProc notifier hook exists, PlatformEventsInit - * is called. + * If no initNotifierProc notifier hook exists, PlatformEventsInit is + * called. * *---------------------------------------------------------------------- */ @@ -221,7 +225,7 @@ Tcl_FinalizeNotifier( *---------------------------------------------------------------------- */ -void +static void PlatformEventsControl( FileHandler *filePtr, ThreadSpecificData *tsdPtr, @@ -240,7 +244,8 @@ PlatformEventsControl( newEvent.events |= EPOLLOUT; } if (isNew) { - newPedPtr = (struct PlatformEventData *)ckalloc(sizeof(struct PlatformEventData)); + newPedPtr = (struct PlatformEventData *) + ckalloc(sizeof(struct PlatformEventData)); newPedPtr->filePtr = filePtr; newPedPtr->tsdPtr = tsdPtr; filePtr->pedPtr = newPedPtr; @@ -249,7 +254,7 @@ PlatformEventsControl( /* * N.B. As discussed in Tcl_WaitForEvent(), epoll(7) does not support - * regular files (S_IFREG.) Therefore, filePtr is in these cases simply + * regular files (S_IFREG). Therefore, filePtr is in these cases simply * added or deleted from the list of FileHandlers associated with regular * files belonging to tsdPtr. */ @@ -298,9 +303,8 @@ PlatformEventsControl( *---------------------------------------------------------------------- */ -void -PlatformEventsFinalize( - void) +static void +PlatformEventsFinalize(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -362,7 +366,7 @@ PlatformEventsFinalize( *---------------------------------------------------------------------- */ -void +static void PlatformEventsInit(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -393,7 +397,7 @@ PlatformEventsInit(void) PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_ADD, 1); if (!tsdPtr->readyEvents) { tsdPtr->maxReadyEvents = 512; - tsdPtr->readyEvents = (struct epoll_event *)ckalloc( + tsdPtr->readyEvents = (struct epoll_event *) ckalloc( tsdPtr->maxReadyEvents * sizeof(tsdPtr->readyEvents[0])); } LIST_INIT(&tsdPtr->firstReadyFileHandlerPtr); @@ -416,7 +420,7 @@ PlatformEventsInit(void) *---------------------------------------------------------------------- */ -int +static int PlatformEventsTranslate( struct epoll_event *eventPtr) { @@ -457,7 +461,7 @@ PlatformEventsTranslate( *---------------------------------------------------------------------- */ -int +static int PlatformEventsWait( struct epoll_event *events, size_t numEvents, @@ -510,7 +514,7 @@ PlatformEventsWait( /* *---------------------------------------------------------------------- * - * Tcl_CreateFileHandler -- + * Tcl_CreateFileHandler, CreateFileHandler -- * * This function registers a file handler with the epoll notifier of the * thread of the caller. @@ -540,40 +544,53 @@ Tcl_CreateFileHandler( if (tclNotifierHooks.createFileHandlerProc) { tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData); - return; } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - FileHandler *filePtr; + PlatformCreateFileHandler(fd, mask, proc, clientData); + } +} - for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; - filePtr = filePtr->nextPtr) { - if (filePtr->fd == fd) { - break; - } - } - if (filePtr == NULL) { - filePtr = (FileHandler *)ckalloc(sizeof(FileHandler)); - filePtr->fd = fd; - filePtr->readyMask = 0; - filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; - tsdPtr->firstFileHandlerPtr = filePtr; - isNew = 1; - } else { - isNew = 0; - } - filePtr->proc = proc; - filePtr->clientData = clientData; - filePtr->mask = mask; +static void +PlatformCreateFileHandler( + int fd, /* Handle of stream to watch. */ + int mask, /* OR'ed combination of TCL_READABLE, + * TCL_WRITABLE, and TCL_EXCEPTION: indicates + * conditions under which proc should be + * called. */ + Tcl_FileProc *proc, /* Function to call for each selected + * event. */ + ClientData clientData) /* Arbitrary data to pass to proc. */ +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + FileHandler *filePtr; - PlatformEventsControl(filePtr, tsdPtr, - isNew ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, isNew); + for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; + filePtr = filePtr->nextPtr) { + if (filePtr->fd == fd) { + break; + } } + if (filePtr == NULL) { + filePtr = (FileHandler *) ckalloc(sizeof(FileHandler)); + filePtr->fd = fd; + filePtr->readyMask = 0; + filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; + tsdPtr->firstFileHandlerPtr = filePtr; + isNew = 1; + } else { + isNew = 0; + } + filePtr->proc = proc; + filePtr->clientData = clientData; + filePtr->mask = mask; + + PlatformEventsControl(filePtr, tsdPtr, + isNew ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, isNew); } /* *---------------------------------------------------------------------- * - * Tcl_DeleteFileHandler -- + * Tcl_DeleteFileHandler, PlatformDeleteFileHandler -- * * Cancel a previously-arranged callback arrangement for a file on the * epoll file descriptor of the thread of the caller. @@ -597,51 +614,58 @@ Tcl_DeleteFileHandler( { if (tclNotifierHooks.deleteFileHandlerProc) { tclNotifierHooks.deleteFileHandlerProc(fd); - return; } else { - FileHandler *filePtr, *prevPtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + PlatformDeleteFileHandler(fd); + } +} - /* - * Find the entry for the given file (and return if there isn't one). - */ +static void +PlatformDeleteFileHandler( + int fd) /* Stream id for which to remove callback + * function. */ +{ + FileHandler *filePtr, *prevPtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; - prevPtr = filePtr, filePtr = filePtr->nextPtr) { - if (filePtr == NULL) { - return; - } - if (filePtr->fd == fd) { - break; - } + /* + * Find the entry for the given file (and return if there isn't one). + */ + + for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; + prevPtr = filePtr, filePtr = filePtr->nextPtr) { + if (filePtr == NULL) { + return; } + if (filePtr->fd == fd) { + break; + } + } - /* - * Update the check masks for this file. - */ + /* + * Update the check masks for this file. + */ - PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_DEL, 0); - if (filePtr->pedPtr) { - ckfree(filePtr->pedPtr); - } + PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_DEL, 0); + if (filePtr->pedPtr) { + ckfree(filePtr->pedPtr); + } - /* - * Clean up information in the callback record. - */ + /* + * Clean up information in the callback record. + */ - if (prevPtr == NULL) { - tsdPtr->firstFileHandlerPtr = filePtr->nextPtr; - } else { - prevPtr->nextPtr = filePtr->nextPtr; - } - ckfree(filePtr); + if (prevPtr == NULL) { + tsdPtr->firstFileHandlerPtr = filePtr->nextPtr; + } else { + prevPtr->nextPtr = filePtr->nextPtr; } + ckfree(filePtr); } /* *---------------------------------------------------------------------- * - * Tcl_WaitForEvent -- + * Tcl_WaitForEvent, PlatformWaitForEvent -- * * This function is called by Tcl_DoOneEvent to wait for new events on * the message queue. If the block time is 0, then Tcl_WaitForEvent just @@ -666,166 +690,170 @@ Tcl_WaitForEvent( if (tclNotifierHooks.waitForEventProc) { return tclNotifierHooks.waitForEventProc(timePtr); } else { - FileHandler *filePtr; - int mask; - Tcl_Time vTime; - /* - * Impl. notes: timeout & timeoutPtr are used if, and only if threads - * are not enabled. They are the arguments for the regular epoll_wait() - * used when the core is not thread-enabled. - */ - - struct timeval timeout, *timeoutPtr; - int numFound, numEvent; - struct PlatformEventData *pedPtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - int numQueued; - ssize_t i; + return PlatformWaitForEvent(timePtr); + } +} - /* - * Set up the timeout structure. Note that if there are no events to - * check for, we return with a negative result rather than blocking - * forever. - */ +static int +PlatformWaitForEvent( + const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ +{ + FileHandler *filePtr; + Tcl_Time vTime; + struct timeval timeout, *timeoutPtr; + /* Impl. notes: timeout & timeoutPtr are used + * if, and only if threads are not enabled. + * They are the arguments for the regular + * epoll_wait() used when the core is not + * thread-enabled. */ + int mask, numFound, numEvent; + struct PlatformEventData *pedPtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + int numQueued; + ssize_t i; - if (timePtr != NULL) { - /* - * TIP #233 (Virtualized Time). Is virtual time in effect? And do - * we actually have something to scale? If yes to both then we - * call the handler to do this scaling. - */ - - if (timePtr->sec != 0 || timePtr->usec != 0) { - vTime = *timePtr; - tclScaleTimeProcPtr(&vTime, tclTimeClientData); - timePtr = &vTime; - } - timeout.tv_sec = timePtr->sec; - timeout.tv_usec = timePtr->usec; - timeoutPtr = &timeout; - } else { - timeoutPtr = NULL; - } + /* + * Set up the timeout structure. Note that if there are no events to check + * for, we return with a negative result rather than blocking forever. + */ + if (timePtr != NULL) { /* - * Walk the list of FileHandlers associated with regular files - * (S_IFREG) belonging to tsdPtr, queue Tcl events for them, and - * update their mask of events of interest. - * - * As epoll(7) does not support regular files, the behaviour of - * {select,poll}(2) is simply simulated here: fds associated with - * regular files are added to this list by PlatformEventsControl() and - * processed here before calling (and possibly blocking) on - * PlatformEventsWait(). + * TIP #233 (Virtualized Time). Is virtual time in effect? And do we + * actually have something to scale? If yes to both then we call the + * handler to do this scaling. */ - numQueued = 0; - LIST_FOREACH(filePtr, &tsdPtr->firstReadyFileHandlerPtr, readyNode) { - mask = 0; - if (filePtr->mask & TCL_READABLE) { - mask |= TCL_READABLE; - } - if (filePtr->mask & TCL_WRITABLE) { - mask |= TCL_WRITABLE; - } - - /* - * Don't bother to queue an event if the mask was previously - * non-zero since an event must still be on the queue. - */ + if (timePtr->sec != 0 || timePtr->usec != 0) { + vTime = *timePtr; + tclScaleTimeProcPtr(&vTime, tclTimeClientData); + timePtr = &vTime; + } + timeout.tv_sec = timePtr->sec; + timeout.tv_usec = timePtr->usec; + timeoutPtr = &timeout; + } else { + timeoutPtr = NULL; + } - if (filePtr->readyMask == 0) { - FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) - ckalloc(sizeof(FileHandlerEvent)); + /* + * Walk the list of FileHandlers associated with regular files (S_IFREG) + * belonging to tsdPtr, queue Tcl events for them, and update their mask + * of events of interest. + * + * As epoll(7) does not support regular files, the behaviour of + * {select,poll}(2) is simply simulated here: fds associated with regular + * files are added to this list by PlatformEventsControl() and processed + * here before calling (and possibly blocking) on PlatformEventsWait(). + */ - fileEvPtr->header.proc = FileHandlerEventProc; - fileEvPtr->fd = filePtr->fd; - Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); - numQueued++; - } - filePtr->readyMask = mask; + numQueued = 0; + LIST_FOREACH(filePtr, &tsdPtr->firstReadyFileHandlerPtr, readyNode) { + mask = 0; + if (filePtr->mask & TCL_READABLE) { + mask |= TCL_READABLE; + } + if (filePtr->mask & TCL_WRITABLE) { + mask |= TCL_WRITABLE; } /* - * If any events were queued in the above loop, force - * PlatformEventsWait() to poll as there already are events that need - * to be processed at this point. + * Don't bother to queue an event if the mask was previously non-zero + * since an event must still be on the queue. */ - if (numQueued) { - timeout.tv_sec = 0; - timeout.tv_usec = 0; - timeoutPtr = &timeout; + if (filePtr->readyMask == 0) { + FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) + ckalloc(sizeof(FileHandlerEvent)); + + fileEvPtr->header.proc = FileHandlerEventProc; + fileEvPtr->fd = filePtr->fd; + Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); + numQueued++; } + filePtr->readyMask = mask; + } - /* - * Wait or poll for new events, queue Tcl events for the FileHandlers - * corresponding to them, and update the FileHandlers' mask of events - * of interest registered by the last call to Tcl_CreateFileHandler(). - * - * Events for the eventfd(2)/trigger pipe are processed here in order - * to facilitate inter-thread IPC. If another thread intends to wake - * up this thread whilst it's blocking on PlatformEventsWait(), it - * write(2)s to the eventfd(2)/trigger pipe (see Tcl_AlertNotifier(),) - * which in turn will cause PlatformEventsWait() to return - * immediately. - */ + /* + * If any events were queued in the above loop, force PlatformEventsWait() + * to poll as there already are events that need to be processed at this + * point. + */ - numFound = PlatformEventsWait(tsdPtr->readyEvents, - tsdPtr->maxReadyEvents, timeoutPtr); - for (numEvent = 0; numEvent < numFound; numEvent++) { - pedPtr = (struct PlatformEventData*)tsdPtr->readyEvents[numEvent].data.ptr; - filePtr = pedPtr->filePtr; - mask = PlatformEventsTranslate(&tsdPtr->readyEvents[numEvent]); + if (numQueued) { + timeout.tv_sec = 0; + timeout.tv_usec = 0; + timeoutPtr = &timeout; + } + + /* + * Wait or poll for new events, queue Tcl events for the FileHandlers + * corresponding to them, and update the FileHandlers' mask of events of + * interest registered by the last call to Tcl_CreateFileHandler(). + * + * Events for the eventfd(2)/trigger pipe are processed here in order to + * facilitate inter-thread IPC. If another thread intends to wake up this + * thread whilst it's blocking on PlatformEventsWait(), it write(2)s to + * the eventfd(2)/trigger pipe (see Tcl_AlertNotifier(),) which in turn + * will cause PlatformEventsWait() to return immediately. + */ + + numFound = PlatformEventsWait(tsdPtr->readyEvents, + tsdPtr->maxReadyEvents, timeoutPtr); + for (numEvent = 0; numEvent < numFound; numEvent++) { + pedPtr = (struct PlatformEventData *) + tsdPtr->readyEvents[numEvent].data.ptr; + filePtr = pedPtr->filePtr; + mask = PlatformEventsTranslate(&tsdPtr->readyEvents[numEvent]); #ifdef HAVE_EVENTFD - if (filePtr->fd == tsdPtr->triggerEventFd) { - uint64_t eventFdVal; - i = read(tsdPtr->triggerEventFd, &eventFdVal, - sizeof(eventFdVal)); - if ((i != sizeof(eventFdVal)) && (errno != EAGAIN)) { - Tcl_Panic( - "Tcl_WaitForEvent: read from %p->triggerEventFd: %s", - (void *) tsdPtr, strerror(errno)); - } - continue; + if (filePtr->fd == tsdPtr->triggerEventFd) { + uint64_t eventFdVal; + + i = read(tsdPtr->triggerEventFd, &eventFdVal, sizeof(eventFdVal)); + if ((i != sizeof(eventFdVal)) && (errno != EAGAIN)) { + Tcl_Panic("%s: read from %p->triggerEventFd: %s", + "Tcl_WaitForEvent", (void *) tsdPtr, strerror(errno)); } + continue; + } #else /* !HAVE_EVENTFD */ - if (filePtr->fd == tsdPtr->triggerPipe[0]) { - char triggerPipeVal; - i = read(tsdPtr->triggerPipe[0], &triggerPipeVal, - sizeof(triggerPipeVal)); - if ((i != sizeof(triggerPipeVal)) && (errno != EAGAIN)) { - Tcl_Panic( - "Tcl_WaitForEvent: read from %p->triggerPipe[0]: %s", - (void *) tsdPtr, strerror(errno)); - } - continue; + if (filePtr->fd == tsdPtr->triggerPipe[0]) { + char triggerPipeVal; + + i = read(tsdPtr->triggerPipe[0], &triggerPipeVal, + sizeof(triggerPipeVal)); + if ((i != sizeof(triggerPipeVal)) && (errno != EAGAIN)) { + Tcl_Panic("%s: read from %p->triggerPipe[0]: %s", + "Tcl_WaitForEvent", (void *) tsdPtr, strerror(errno)); } + continue; + } #endif /* HAVE_EVENTFD */ - if (!mask) { - continue; - } + if (!mask) { + continue; + } - /* - * Don't bother to queue an event if the mask was previously - * non-zero since an event must still be on the queue. - */ + /* + * Don't bother to queue an event if the mask was previously non-zero + * since an event must still be on the queue. + */ - if (filePtr->readyMask == 0) { - FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) - ckalloc(sizeof(FileHandlerEvent)); + if (filePtr->readyMask == 0) { + FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) + ckalloc(sizeof(FileHandlerEvent)); - fileEvPtr->header.proc = FileHandlerEventProc; - fileEvPtr->fd = filePtr->fd; - Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); - } - filePtr->readyMask = mask; + fileEvPtr->header.proc = FileHandlerEventProc; + fileEvPtr->fd = filePtr->fd; + Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); } - return 0; + filePtr->readyMask = mask; } + return 0; } #endif /* NOTIFIER_EPOLL && TCL_THREADS */ +#else +TCL_MAC_EMPTY_FILE(unix_tclEpollNotfy_c) #endif /* !HAVE_COREFOUNDATION */ /* diff --git a/unix/tclKqueueNotfy.c b/unix/tclKqueueNotfy.c index 2f1d8e6..fbd38dc 100644 --- a/unix/tclKqueueNotfy.c +++ b/unix/tclKqueueNotfy.c @@ -209,7 +209,7 @@ Tcl_FinalizeNotifier( *---------------------------------------------------------------------- */ -void +static void PlatformEventsControl( FileHandler *filePtr, ThreadSpecificData *tsdPtr, @@ -222,7 +222,8 @@ PlatformEventsControl( struct stat fdStat; if (isNew) { - newPedPtr = (struct PlatformEventData *)ckalloc(sizeof(struct PlatformEventData)); + newPedPtr = (struct PlatformEventData *) + ckalloc(sizeof(struct PlatformEventData)); newPedPtr->filePtr = filePtr; newPedPtr->tsdPtr = tsdPtr; filePtr->pedPtr = newPedPtr; @@ -324,9 +325,8 @@ PlatformEventsControl( *---------------------------------------------------------------------- */ -void -PlatformEventsFinalize( - void) +static void +PlatformEventsFinalize(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -380,7 +380,7 @@ PlatformEventsFinalize( *---------------------------------------------------------------------- */ -void +static void PlatformEventsInit(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -438,7 +438,7 @@ PlatformEventsInit(void) *---------------------------------------------------------------------- */ -int +static int PlatformEventsTranslate( struct kevent *eventPtr) { @@ -459,7 +459,7 @@ PlatformEventsTranslate( } return mask; } - + /* *---------------------------------------------------------------------- * @@ -483,7 +483,7 @@ PlatformEventsTranslate( *---------------------------------------------------------------------- */ -int +static int PlatformEventsWait( struct kevent *events, size_t numEvents, @@ -842,6 +842,8 @@ Tcl_WaitForEvent( } #endif /* NOTIFIER_KQUEUE && TCL_THREADS */ +#else +TCL_MAC_EMPTY_FILE(unix_tclKqueueNotfy_c) #endif /* !HAVE_COREFOUNDATION */ /* diff --git a/unix/tclSelectNotfy.c b/unix/tclSelectNotfy.c index 1d16114..e40997f 100644 --- a/unix/tclSelectNotfy.c +++ b/unix/tclSelectNotfy.c @@ -216,8 +216,8 @@ extern "C" { typedef struct { void *hwnd; /* Messaging window. */ unsigned int *message; /* Message payload. */ - size_t wParam; /* Event-specific "word" parameter. */ - size_t lParam; /* Event-specific "long" parameter. */ + size_t wParam; /* Event-specific "word" parameter. */ + size_t lParam; /* Event-specific "long" parameter. */ int time; /* Event timestamp. */ int x; /* Event location (where meaningful). */ int y; @@ -244,8 +244,8 @@ extern void __stdcall CloseHandle(void *); extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char, void *); extern void *__stdcall CreateWindowExW(void *, const void *, const void *, - unsigned int, int, int, int, int, void *, void *, void *, - void *); + unsigned int, int, int, int, int, void *, void *, + void *, void *); extern unsigned int __stdcall DefWindowProcW(void *, int, void *, void *); extern unsigned char __stdcall DestroyWindow(void *); extern int __stdcall DispatchMessageW(const MSG *); @@ -504,7 +504,7 @@ Tcl_CreateFileHandler( FD_CLR(fd, &tsdPtr->checkMasks.exception); } if (tsdPtr->numFdBits <= fd) { - tsdPtr->numFdBits = fd+1; + tsdPtr->numFdBits = fd + 1; } } } @@ -573,11 +573,11 @@ Tcl_DeleteFileHandler( if (fd+1 == tsdPtr->numFdBits) { int numFdBits = 0; - for (i = fd-1; i >= 0; i--) { + for (i = fd - 1; i >= 0; i--) { if (FD_ISSET(i, &tsdPtr->checkMasks.readable) || FD_ISSET(i, &tsdPtr->checkMasks.writable) || FD_ISSET(i, &tsdPtr->checkMasks.exception)) { - numFdBits = i+1; + numFdBits = i + 1; break; } } @@ -1113,6 +1113,8 @@ NotifierThreadProc( #endif /* TCL_THREADS */ #endif /* (!NOTIFIER_EPOLL && !NOTIFIER_KQUEUE) || !TCL_THREADS */ +#else +TCL_MAC_EMPTY_FILE(unix_tclSelectNotfy_c) #endif /* !HAVE_COREFOUNDATION */ /* diff --git a/unix/tclUnixEvent.c b/unix/tclUnixEvent.c index aff7797..f7545db 100644 --- a/unix/tclUnixEvent.c +++ b/unix/tclUnixEvent.c @@ -85,6 +85,8 @@ Tcl_Sleep( } } +#else +TCL_MAC_EMPTY_FILE(unix_tclUnixEvent_c) #endif /* HAVE_COREFOUNDATION */ /* * Local Variables: -- cgit v0.12 From 9e6945739aa490d624e42622e9e0f5f2d695c80b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 22 Mar 2021 10:00:06 +0000 Subject: Rename internal variables, making it more clear that tclLoad.c is not part of Tcl's "package" mechanism. --- generic/tclLoad.c | 324 +++++++++++++++++++++++++++--------------------------- 1 file changed, 162 insertions(+), 162 deletions(-) diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 8b92ac3..0fd21c0 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -21,13 +21,13 @@ * freed. */ -typedef struct LoadedPackage { +typedef struct LoadedLibrary { char *fileName; /* Name of the file from which the library was * loaded. An empty string means the library * is loaded statically. Malloc-ed. */ char *prefix; /* Prefix for the library, * properly capitalized (first letter UC, - * others LC), no "_", as in "Net". + * others LC), as in "Net". * Malloc-ed. */ Tcl_LoadHandle loadHandle; /* Token for the loaded file which should be * passed to (*unLoadProcPtr)() when the file @@ -55,23 +55,23 @@ typedef struct LoadedPackage { * in trusted interpreters. */ int safeInterpRefCount; /* How many times the library has been loaded * in safe interpreters. */ - struct LoadedPackage *nextPtr; + struct LoadedLibrary *nextPtr; /* Next in list of all libraries loaded into * this application process. NULL means end of * list. */ -} LoadedPackage; +} LoadedLibrary; /* * TCL_THREADS - * There is a global list of libraries that is anchored at firstPackagePtr. + * There is a global list of libraries that is anchored at firstLibraryPtr. * Access to this list is governed by a mutex. */ -static LoadedPackage *firstPackagePtr = NULL; +static LoadedLibrary *firstLibraryPtr = NULL; /* First in list of all libraries loaded into * this process. */ -TCL_DECLARE_MUTEX(packageMutex) +TCL_DECLARE_MUTEX(libraryMutex) /* * The following structure represents a particular library that has been @@ -81,13 +81,13 @@ TCL_DECLARE_MUTEX(packageMutex) * first library (if any). */ -typedef struct InterpPackage { - LoadedPackage *pkgPtr; /* Points to detailed information about +typedef struct InterpLibrary { + LoadedLibrary *libraryPtr; /* Points to detailed information about * library. */ - struct InterpPackage *nextPtr; + struct InterpLibrary *nextPtr; /* Next library in this interpreter, or NULL * for end of list. */ -} InterpPackage; +} InterpLibrary; /* * Prototypes for functions that are private to this file: @@ -121,10 +121,10 @@ Tcl_LoadObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *target; - LoadedPackage *pkgPtr, *defaultPtr; + LoadedLibrary *libraryPtr, *defaultPtr; Tcl_DString pfx, tmp, initName, safeInitName; Tcl_DString unloadName, safeUnloadName; - InterpPackage *ipFirstPtr, *ipPtr; + InterpLibrary *ipFirstPtr, *ipPtr; int code, namesMatch, filesMatch, offset; const char *symbols[2]; Tcl_PackageInitProc *initProc; @@ -215,17 +215,17 @@ Tcl_LoadObjCmd( * only no statically loaded library with the same prefix. */ - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); defaultPtr = NULL; - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; libraryPtr = libraryPtr->nextPtr) { if (prefix == NULL) { namesMatch = 0; } else { TclDStringClear(&pfx); Tcl_DStringAppend(&pfx, prefix, -1); TclDStringClear(&tmp); - Tcl_DStringAppend(&tmp, pkgPtr->prefix, -1); + Tcl_DStringAppend(&tmp, libraryPtr->prefix, -1); Tcl_UtfToLower(Tcl_DStringValue(&pfx)); Tcl_UtfToLower(Tcl_DStringValue(&tmp)); if (strcmp(Tcl_DStringValue(&tmp), @@ -237,12 +237,12 @@ Tcl_LoadObjCmd( } TclDStringClear(&pfx); - filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0); + filesMatch = (strcmp(libraryPtr->fileName, fullFileName) == 0); if (filesMatch && (namesMatch || (prefix == NULL))) { break; } if (namesMatch && (fullFileName[0] == 0)) { - defaultPtr = pkgPtr; + defaultPtr = libraryPtr; } if (filesMatch && !namesMatch && (fullFileName[0] != 0)) { /* @@ -251,17 +251,17 @@ Tcl_LoadObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" is already loaded for prefix \"%s\"", - fullFileName, pkgPtr->prefix)); + fullFileName, libraryPtr->prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "SPLITPERSONALITY", NULL); code = TCL_ERROR; - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); goto done; } } - Tcl_MutexUnlock(&packageMutex); - if (pkgPtr == NULL) { - pkgPtr = defaultPtr; + Tcl_MutexUnlock(&libraryMutex); + if (libraryPtr == NULL) { + libraryPtr = defaultPtr; } /* @@ -270,17 +270,17 @@ Tcl_LoadObjCmd( * there's nothing for us to do. */ - if (pkgPtr != NULL) { - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); + if (libraryPtr != NULL) { + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - if (ipPtr->pkgPtr == pkgPtr) { + if (ipPtr->libraryPtr == libraryPtr) { code = TCL_OK; goto done; } } } - if (pkgPtr == NULL) { + if (libraryPtr == NULL) { /* * The desired file isn't currently loaded, so load it. It's an error * if the desired library is a static one. @@ -388,10 +388,10 @@ Tcl_LoadObjCmd( symbols[0] = Tcl_DStringValue(&initName); symbols[1] = NULL; - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); code = Tcl_LoadFile(interp, objv[1], symbols, flags, &initProc, &loadHandle); - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); if (code != TCL_OK) { goto done; } @@ -400,31 +400,31 @@ Tcl_LoadObjCmd( * Create a new record to describe this library. */ - pkgPtr = (LoadedPackage *)ckalloc(sizeof(LoadedPackage)); + libraryPtr = (LoadedLibrary *)ckalloc(sizeof(LoadedLibrary)); len = strlen(fullFileName) + 1; - pkgPtr->fileName = (char *)ckalloc(len); - memcpy(pkgPtr->fileName, fullFileName, len); + libraryPtr->fileName = (char *)ckalloc(len); + memcpy(libraryPtr->fileName, fullFileName, len); len = Tcl_DStringLength(&pfx) + 1; - pkgPtr->prefix = (char *)ckalloc(len); - memcpy(pkgPtr->prefix, Tcl_DStringValue(&pfx), len); - pkgPtr->loadHandle = loadHandle; - pkgPtr->initProc = initProc; - pkgPtr->safeInitProc = (Tcl_PackageInitProc *) + libraryPtr->prefix = (char *)ckalloc(len); + memcpy(libraryPtr->prefix, Tcl_DStringValue(&pfx), len); + libraryPtr->loadHandle = loadHandle; + libraryPtr->initProc = initProc; + libraryPtr->safeInitProc = (Tcl_PackageInitProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&safeInitName)); - pkgPtr->unloadProc = (Tcl_PackageUnloadProc *) + libraryPtr->unloadProc = (Tcl_PackageUnloadProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&unloadName)); - pkgPtr->safeUnloadProc = (Tcl_PackageUnloadProc *) + libraryPtr->safeUnloadProc = (Tcl_PackageUnloadProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&safeUnloadName)); - pkgPtr->interpRefCount = 0; - pkgPtr->safeInterpRefCount = 0; + libraryPtr->interpRefCount = 0; + libraryPtr->safeInterpRefCount = 0; - Tcl_MutexLock(&packageMutex); - pkgPtr->nextPtr = firstPackagePtr; - firstPackagePtr = pkgPtr; - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexLock(&libraryMutex); + libraryPtr->nextPtr = firstLibraryPtr; + firstLibraryPtr = libraryPtr; + Tcl_MutexUnlock(&libraryMutex); /* * The Tcl_FindSymbol calls may have left a spurious error message in @@ -440,27 +440,27 @@ Tcl_LoadObjCmd( */ if (Tcl_IsSafe(target)) { - if (pkgPtr->safeInitProc == NULL) { + if (libraryPtr->safeInitProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't use library in a safe interpreter: no" - " %s_SafeInit procedure", pkgPtr->prefix)); + " %s_SafeInit procedure", libraryPtr->prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "UNSAFE", NULL); code = TCL_ERROR; goto done; } - code = pkgPtr->safeInitProc(target); + code = libraryPtr->safeInitProc(target); } else { - if (pkgPtr->initProc == NULL) { + if (libraryPtr->initProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't attach library to interpreter: no %s_Init procedure", - pkgPtr->prefix)); + libraryPtr->prefix)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "ENTRYPOINT", NULL); code = TCL_ERROR; goto done; } - code = pkgPtr->initProc(target); + code = libraryPtr->initProc(target); } /* @@ -493,22 +493,22 @@ Tcl_LoadObjCmd( * Update the proper reference count. */ - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); if (Tcl_IsSafe(target)) { - pkgPtr->safeInterpRefCount++; + libraryPtr->safeInterpRefCount++; } else { - pkgPtr->interpRefCount++; + libraryPtr->interpRefCount++; } - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); /* * Refetch ipFirstPtr: loading the library may have introduced additional * static libraries at the head of the linked list! */ - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); - ipPtr = (InterpPackage *)ckalloc(sizeof(InterpPackage)); - ipPtr->pkgPtr = pkgPtr; + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); + ipPtr = (InterpLibrary *)ckalloc(sizeof(InterpLibrary)); + ipPtr->libraryPtr = libraryPtr; ipPtr->nextPtr = ipFirstPtr; Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipPtr); @@ -547,10 +547,10 @@ Tcl_UnloadObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Interp *target; /* Which interpreter to unload from. */ - LoadedPackage *pkgPtr, *defaultPtr; + LoadedLibrary *libraryPtr, *defaultPtr; Tcl_DString pfx, tmp; Tcl_PackageUnloadProc *unloadProc; - InterpPackage *ipFirstPtr, *ipPtr; + InterpLibrary *ipFirstPtr, *ipPtr; int i, index, code, complain = 1, keepLibrary = 0; int trustedRefCount = -1, safeRefCount = -1; const char *fullFileName = ""; @@ -649,10 +649,10 @@ Tcl_UnloadObjCmd( * only no statically loaded library with the same prefix. */ - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); defaultPtr = NULL; - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; libraryPtr = libraryPtr->nextPtr) { int namesMatch, filesMatch; if (prefix == NULL) { @@ -661,7 +661,7 @@ Tcl_UnloadObjCmd( TclDStringClear(&pfx); Tcl_DStringAppend(&pfx, prefix, -1); TclDStringClear(&tmp); - Tcl_DStringAppend(&tmp, pkgPtr->prefix, -1); + Tcl_DStringAppend(&tmp, libraryPtr->prefix, -1); Tcl_UtfToLower(Tcl_DStringValue(&pfx)); Tcl_UtfToLower(Tcl_DStringValue(&tmp)); if (strcmp(Tcl_DStringValue(&tmp), @@ -673,18 +673,18 @@ Tcl_UnloadObjCmd( } TclDStringClear(&pfx); - filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0); + filesMatch = (strcmp(libraryPtr->fileName, fullFileName) == 0); if (filesMatch && (namesMatch || (prefix == NULL))) { break; } if (namesMatch && (fullFileName[0] == 0)) { - defaultPtr = pkgPtr; + defaultPtr = libraryPtr; } if (filesMatch && !namesMatch && (fullFileName[0] != 0)) { break; } } - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); if (fullFileName[0] == 0) { /* * It's an error to try unload a static library. @@ -698,7 +698,7 @@ Tcl_UnloadObjCmd( code = TCL_ERROR; goto done; } - if (pkgPtr == NULL) { + if (libraryPtr == NULL) { /* * The DLL pointed by the provided filename has never been loaded. */ @@ -718,10 +718,10 @@ Tcl_UnloadObjCmd( */ code = TCL_ERROR; - if (pkgPtr != NULL) { - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); + if (libraryPtr != NULL) { + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - if (ipPtr->pkgPtr == pkgPtr) { + if (ipPtr->libraryPtr == libraryPtr) { code = TCL_OK; break; } @@ -743,12 +743,12 @@ Tcl_UnloadObjCmd( /* * Ensure that the DLL can be unloaded. If it is a trusted interpreter, - * pkgPtr->unloadProc must not be NULL for the DLL to be unloadable. If - * the interpreter is a safe one, pkgPtr->safeUnloadProc must be non-NULL. + * libraryPtr->unloadProc must not be NULL for the DLL to be unloadable. If + * the interpreter is a safe one, libraryPtr->safeUnloadProc must be non-NULL. */ if (Tcl_IsSafe(target)) { - if (pkgPtr->safeUnloadProc == NULL) { + if (libraryPtr->safeUnloadProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" cannot be unloaded under a safe interpreter", fullFileName)); @@ -757,9 +757,9 @@ Tcl_UnloadObjCmd( code = TCL_ERROR; goto done; } - unloadProc = pkgPtr->safeUnloadProc; + unloadProc = libraryPtr->safeUnloadProc; } else { - if (pkgPtr->unloadProc == NULL) { + if (libraryPtr->unloadProc == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file \"%s\" cannot be unloaded under a trusted interpreter", fullFileName)); @@ -768,7 +768,7 @@ Tcl_UnloadObjCmd( code = TCL_ERROR; goto done; } - unloadProc = pkgPtr->unloadProc; + unloadProc = libraryPtr->unloadProc; } /* @@ -783,10 +783,10 @@ Tcl_UnloadObjCmd( code = TCL_UNLOAD_DETACH_FROM_INTERPRETER; if (!keepLibrary) { - Tcl_MutexLock(&packageMutex); - trustedRefCount = pkgPtr->interpRefCount; - safeRefCount = pkgPtr->safeInterpRefCount; - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexLock(&libraryMutex); + trustedRefCount = libraryPtr->interpRefCount; + safeRefCount = libraryPtr->safeInterpRefCount; + Tcl_MutexUnlock(&libraryMutex); if (Tcl_IsSafe(target)) { safeRefCount--; @@ -809,34 +809,34 @@ Tcl_UnloadObjCmd( * if we unload the DLL. */ - Tcl_MutexLock(&packageMutex); + Tcl_MutexLock(&libraryMutex); if (Tcl_IsSafe(target)) { - pkgPtr->safeInterpRefCount--; + libraryPtr->safeInterpRefCount--; /* * Do not let counter get negative. */ - if (pkgPtr->safeInterpRefCount < 0) { - pkgPtr->safeInterpRefCount = 0; + if (libraryPtr->safeInterpRefCount < 0) { + libraryPtr->safeInterpRefCount = 0; } } else { - pkgPtr->interpRefCount--; + libraryPtr->interpRefCount--; /* * Do not let counter get negative. */ - if (pkgPtr->interpRefCount < 0) { - pkgPtr->interpRefCount = 0; + if (libraryPtr->interpRefCount < 0) { + libraryPtr->interpRefCount = 0; } } - trustedRefCount = pkgPtr->interpRefCount; - safeRefCount = pkgPtr->safeInterpRefCount; - Tcl_MutexUnlock(&packageMutex); + trustedRefCount = libraryPtr->interpRefCount; + safeRefCount = libraryPtr->safeInterpRefCount; + Tcl_MutexUnlock(&libraryMutex); code = TCL_OK; - if (pkgPtr->safeInterpRefCount <= 0 && pkgPtr->interpRefCount <= 0 + if (libraryPtr->safeInterpRefCount <= 0 && libraryPtr->interpRefCount <= 0 && !keepLibrary) { /* * Unload the shared library from the application memory... @@ -850,21 +850,21 @@ Tcl_UnloadObjCmd( * it's been unloaded. */ - if (pkgPtr->fileName[0] != '\0') { - Tcl_MutexLock(&packageMutex); - if (Tcl_FSUnloadFile(interp, pkgPtr->loadHandle) == TCL_OK) { + if (libraryPtr->fileName[0] != '\0') { + Tcl_MutexLock(&libraryMutex); + if (Tcl_FSUnloadFile(interp, libraryPtr->loadHandle) == TCL_OK) { /* * Remove this library from the loaded library cache. */ - defaultPtr = pkgPtr; - if (defaultPtr == firstPackagePtr) { - firstPackagePtr = pkgPtr->nextPtr; + defaultPtr = libraryPtr; + if (defaultPtr == firstLibraryPtr) { + firstLibraryPtr = libraryPtr->nextPtr; } else { - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; - pkgPtr = pkgPtr->nextPtr) { - if (pkgPtr->nextPtr == defaultPtr) { - pkgPtr->nextPtr = defaultPtr->nextPtr; + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; + libraryPtr = libraryPtr->nextPtr) { + if (libraryPtr->nextPtr == defaultPtr) { + libraryPtr->nextPtr = defaultPtr->nextPtr; break; } } @@ -874,16 +874,16 @@ Tcl_UnloadObjCmd( * Remove this library from the interpreter's library cache. */ - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); ipPtr = ipFirstPtr; - if (ipPtr->pkgPtr == defaultPtr) { + if (ipPtr->libraryPtr == defaultPtr) { ipFirstPtr = ipFirstPtr->nextPtr; } else { - InterpPackage *ipPrevPtr; + InterpLibrary *ipPrevPtr; for (ipPrevPtr = ipPtr; ipPtr != NULL; ipPrevPtr = ipPtr, ipPtr = ipPtr->nextPtr) { - if (ipPtr->pkgPtr == defaultPtr) { + if (ipPtr->libraryPtr == defaultPtr) { ipPrevPtr->nextPtr = ipPtr->nextPtr; break; } @@ -895,7 +895,7 @@ Tcl_UnloadObjCmd( ckfree(defaultPtr->prefix); ckfree(defaultPtr); ckfree(ipPtr); - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); } else { code = TCL_ERROR; } @@ -957,42 +957,42 @@ Tcl_StaticPackage( * the library can't be used in safe * interpreters. */ { - LoadedPackage *pkgPtr; - InterpPackage *ipPtr, *ipFirstPtr; + LoadedLibrary *libraryPtr; + InterpLibrary *ipPtr, *ipFirstPtr; /* * Check to see if someone else has already reported this library as * statically loaded in the process. */ - Tcl_MutexLock(&packageMutex); - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) { - if ((pkgPtr->initProc == initProc) - && (pkgPtr->safeInitProc == safeInitProc) - && (strcmp(pkgPtr->prefix, prefix) == 0)) { + Tcl_MutexLock(&libraryMutex); + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; libraryPtr = libraryPtr->nextPtr) { + if ((libraryPtr->initProc == initProc) + && (libraryPtr->safeInitProc == safeInitProc) + && (strcmp(libraryPtr->prefix, prefix) == 0)) { break; } } - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); /* * If the library is not yet recorded as being loaded statically, add it * to the list now. */ - if (pkgPtr == NULL) { - pkgPtr = (LoadedPackage *)ckalloc(sizeof(LoadedPackage)); - pkgPtr->fileName = (char *)ckalloc(1); - pkgPtr->fileName[0] = 0; - pkgPtr->prefix = (char *)ckalloc(strlen(prefix) + 1); - strcpy(pkgPtr->prefix, prefix); - pkgPtr->loadHandle = NULL; - pkgPtr->initProc = initProc; - pkgPtr->safeInitProc = safeInitProc; - Tcl_MutexLock(&packageMutex); - pkgPtr->nextPtr = firstPackagePtr; - firstPackagePtr = pkgPtr; - Tcl_MutexUnlock(&packageMutex); + if (libraryPtr == NULL) { + libraryPtr = (LoadedLibrary *)ckalloc(sizeof(LoadedLibrary)); + libraryPtr->fileName = (char *)ckalloc(1); + libraryPtr->fileName[0] = 0; + libraryPtr->prefix = (char *)ckalloc(strlen(prefix) + 1); + strcpy(libraryPtr->prefix, prefix); + libraryPtr->loadHandle = NULL; + libraryPtr->initProc = initProc; + libraryPtr->safeInitProc = safeInitProc; + Tcl_MutexLock(&libraryMutex); + libraryPtr->nextPtr = firstLibraryPtr; + firstLibraryPtr = libraryPtr; + Tcl_MutexUnlock(&libraryMutex); } if (interp != NULL) { @@ -1002,9 +1002,9 @@ Tcl_StaticPackage( * it's already loaded. */ - ipFirstPtr = (InterpPackage *)Tcl_GetAssocData(interp, "tclLoad", NULL); + ipFirstPtr = (InterpLibrary *)Tcl_GetAssocData(interp, "tclLoad", NULL); for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - if (ipPtr->pkgPtr == pkgPtr) { + if (ipPtr->libraryPtr == libraryPtr) { return; } } @@ -1014,8 +1014,8 @@ Tcl_StaticPackage( * loaded. */ - ipPtr = (InterpPackage *)ckalloc(sizeof(InterpPackage)); - ipPtr->pkgPtr = pkgPtr; + ipPtr = (InterpLibrary *)ckalloc(sizeof(InterpLibrary)); + ipPtr->libraryPtr = libraryPtr; ipPtr->nextPtr = ipFirstPtr; Tcl_SetAssocData(interp, "tclLoad", LoadCleanupProc, ipPtr); } @@ -1055,21 +1055,21 @@ TclGetLoadedPackagesEx( */ { Tcl_Interp *target; - LoadedPackage *pkgPtr; - InterpPackage *ipPtr; + LoadedLibrary *libraryPtr; + InterpLibrary *ipPtr; Tcl_Obj *resultObj, *pkgDesc[2]; if (targetName == NULL) { TclNewObj(resultObj); - Tcl_MutexLock(&packageMutex); - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; - pkgPtr = pkgPtr->nextPtr) { - pkgDesc[0] = Tcl_NewStringObj(pkgPtr->fileName, -1); - pkgDesc[1] = Tcl_NewStringObj(pkgPtr->prefix, -1); + Tcl_MutexLock(&libraryMutex); + for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; + libraryPtr = libraryPtr->nextPtr) { + pkgDesc[0] = Tcl_NewStringObj(libraryPtr->fileName, -1); + pkgDesc[1] = Tcl_NewStringObj(libraryPtr->prefix, -1); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewListObj(2, pkgDesc)); } - Tcl_MutexUnlock(&packageMutex); + Tcl_MutexUnlock(&libraryMutex); Tcl_SetObjResult(interp, resultObj); return TCL_OK; } @@ -1078,7 +1078,7 @@ TclGetLoadedPackagesEx( if (target == NULL) { return TCL_ERROR; } - ipPtr = (InterpPackage *)Tcl_GetAssocData(target, "tclLoad", NULL); + ipPtr = (InterpLibrary *)Tcl_GetAssocData(target, "tclLoad", NULL); /* * Return information about all of the available libraries. @@ -1087,10 +1087,10 @@ TclGetLoadedPackagesEx( resultObj = NULL; for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - pkgPtr = ipPtr->pkgPtr; + libraryPtr = ipPtr->libraryPtr; - if (!strcmp(prefix, pkgPtr->prefix)) { - resultObj = Tcl_NewStringObj(pkgPtr->fileName, -1); + if (!strcmp(prefix, libraryPtr->prefix)) { + resultObj = Tcl_NewStringObj(libraryPtr->fileName, -1); break; } } @@ -1108,9 +1108,9 @@ TclGetLoadedPackagesEx( TclNewObj(resultObj); for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { - pkgPtr = ipPtr->pkgPtr; - pkgDesc[0] = Tcl_NewStringObj(pkgPtr->fileName, -1); - pkgDesc[1] = Tcl_NewStringObj(pkgPtr->prefix, -1); + libraryPtr = ipPtr->libraryPtr; + pkgDesc[0] = Tcl_NewStringObj(libraryPtr->fileName, -1); + pkgDesc[1] = Tcl_NewStringObj(libraryPtr->prefix, -1); Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewListObj(2, pkgDesc)); } Tcl_SetObjResult(interp, resultObj); @@ -1122,7 +1122,7 @@ TclGetLoadedPackagesEx( * * LoadCleanupProc -- * - * This function is called to delete all of the InterpPackage structures + * This function is called to delete all of the InterpLibrary structures * for an interpreter when the interpreter is deleted. It gets invoked * via the Tcl AssocData mechanism. * @@ -1130,20 +1130,20 @@ TclGetLoadedPackagesEx( * None. * * Side effects: - * Storage for all of the InterpPackage functions for interp get deleted. + * Storage for all of the InterpLibrary functions for interp get deleted. * *---------------------------------------------------------------------- */ static void LoadCleanupProc( - ClientData clientData, /* Pointer to first InterpPackage structure + ClientData clientData, /* Pointer to first InterpLibrary structure * for interp. */ TCL_UNUSED(Tcl_Interp *)) { - InterpPackage *ipPtr, *nextPtr; + InterpLibrary *ipPtr, *nextPtr; - ipPtr = (InterpPackage *)clientData; + ipPtr = (InterpLibrary *)clientData; while (ipPtr != NULL) { nextPtr = ipPtr->nextPtr; ckfree(ipPtr); @@ -1157,7 +1157,7 @@ LoadCleanupProc( * TclFinalizeLoad -- * * This function is invoked just before the application exits. It frees - * all of the LoadedPackage structures. + * all of the LoadedLibrary structures. * * Results: * None. @@ -1171,18 +1171,18 @@ LoadCleanupProc( void TclFinalizeLoad(void) { - LoadedPackage *pkgPtr; + LoadedLibrary *libraryPtr; /* * No synchronization here because there should just be one thread alive - * at this point. Logically, packageMutex should be grabbed at this point, + * at this point. Logically, libraryMutex should be grabbed at this point, * but the Mutexes get finalized before the call to this routine. The only * subsystem left alive at this point is the memory allocator. */ - while (firstPackagePtr != NULL) { - pkgPtr = firstPackagePtr; - firstPackagePtr = pkgPtr->nextPtr; + while (firstLibraryPtr != NULL) { + libraryPtr = firstLibraryPtr; + firstLibraryPtr = libraryPtr->nextPtr; #if defined(TCL_UNLOAD_DLLS) || defined(_WIN32) /* @@ -1192,14 +1192,14 @@ TclFinalizeLoad(void) * it has been unloaded. */ - if (pkgPtr->fileName[0] != '\0') { - Tcl_FSUnloadFile(NULL, pkgPtr->loadHandle); + if (libraryPtr->fileName[0] != '\0') { + Tcl_FSUnloadFile(NULL, libraryPtr->loadHandle); } #endif - ckfree(pkgPtr->fileName); - ckfree(pkgPtr->prefix); - ckfree(pkgPtr); + ckfree(libraryPtr->fileName); + ckfree(libraryPtr->prefix); + ckfree(libraryPtr); } } -- cgit v0.12 From d63f456a83dd1cbb7dedd7fd1148a89f0905bcd0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 22 Mar 2021 10:04:12 +0000 Subject: Fix incorrect comment: underscore ('_') is allowed in a packageName --- generic/tclLoad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 2891884..e1c21b0 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -27,7 +27,7 @@ typedef struct LoadedPackage { * is loaded statically. Malloc-ed. */ char *packageName; /* Name of package prefix for the package, * properly capitalized (first letter UC, - * others LC), no "_", as in "Net". + * others LC), as in "Net". * Malloc-ed. */ Tcl_LoadHandle loadHandle; /* Token for the loaded file which should be * passed to (*unLoadProcPtr)() when the file -- cgit v0.12 From 7429625aafffe2055c21ac133cb885cccb0b8ad2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 22 Mar 2021 12:36:02 +0000 Subject: test tweaks --- tests/load.test | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/load.test b/tests/load.test index 857d1b3..c419bfb 100644 --- a/tests/load.test +++ b/tests/load.test @@ -174,7 +174,7 @@ test load-7.3 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { catch {load [file join $testDir pkga$ext] Pkga} catch {load [file join $testDir pkgb$ext] Pkgb} catch {load [file join $testDir pkge$ext] Pkge} -set currentRealPackages [list [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] +set currentRealLibraries [list [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] test load-7.4 {Tcl_StaticLibrary procedure, redundant calls} -setup { teststaticlibrary Test 1 0 teststaticlibrary Another 0 0 @@ -183,7 +183,7 @@ test load-7.4 {Tcl_StaticLibrary procedure, redundant calls} -setup { teststaticlibrary Double 0 1 teststaticlibrary Double 0 1 info loaded -} -result [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded] +} -result [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealLibraries {*}$alreadyTotalLoaded] testConstraint teststaticlibrary_8.x 0 if {[testConstraint teststaticlibrary]} { @@ -196,19 +196,19 @@ if {[testConstraint teststaticlibrary]} { } } -test load-8.1 {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { +test load-8.1 {TclGetLoadedLibraries procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded] -} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded]] -test load-8.2 {TclGetLoadedPackages procedure} -constraints {teststaticlibrary_8.x} -body { +} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealLibraries {*}$alreadyTotalLoaded]] +test load-8.2 {TclGetLoadedLibraries procedure} -constraints {teststaticlibrary_8.x} -body { info loaded gorp } -returnCodes error -result {could not find interpreter "gorp"} -test load-8.3a {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { +test load-8.3a {TclGetLoadedLibraries procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded {}] } [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga] [list [file join $testDir pkgb$ext] Pkgb] {*}$alreadyLoaded]] -test load-8.3b {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { +test load-8.3b {TclGetLoadedLibraries procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded child] } [lsort -index 1 [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]] -test load-8.4 {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { +test load-8.4 {TclGetLoadedLibraries procedure} [list teststaticlibrary_8.x $dll $loaded] { load [file join $testDir pkgb$ext] Pkgb list [lsort -index 1 [info loaded {}]] [lsort [info commands pkgb_*]] } [list [lsort -index 1 [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded]] {pkgb_demo pkgb_sub pkgb_unsafe}] -- cgit v0.12 From 6c6a470c2bc258d42f224373a084ee2a4d61e9a6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 22 Mar 2021 17:07:01 +0000 Subject: Rename MODULESCOPE TclGetLoadedPackagesEx() to TclGetLoadedLibraries() --- generic/tclCmdIL.c | 2 +- generic/tclInt.h | 2 +- generic/tclLoad.c | 4 ++-- generic/tclStubInit.c | 2 +- library/safe.tcl | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index beb55c0..d3588aa 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -1700,7 +1700,7 @@ InfoLoadedCmd( } else { /* Get pkgs just in specified interp. */ packageName = TclGetString(objv[2]); } - return TclGetLoadedPackagesEx(interp, interpName, packageName); + return TclGetLoadedLibraries(interp, interpName, packageName); } /* diff --git a/generic/tclInt.h b/generic/tclInt.h index 1d192ff..75167df 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3044,7 +3044,7 @@ MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE char * TclGetStringStorage(Tcl_Obj *objPtr, unsigned int *sizePtr); -MODULE_SCOPE int TclGetLoadedPackagesEx(Tcl_Interp *interp, +MODULE_SCOPE int TclGetLoadedLibraries(Tcl_Interp *interp, const char *targetName, const char *packageName); MODULE_SCOPE int TclGetWideBitsFromObj(Tcl_Interp *, Tcl_Obj *, diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 0fd21c0..afad897 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -1024,7 +1024,7 @@ Tcl_StaticPackage( /* *---------------------------------------------------------------------- * - * TclGetLoadedPackagesEx -- + * TclGetLoadedLibraries -- * * This function returns information about all of the files that are * loaded (either in a particular interpreter, or for all interpreters). @@ -1043,7 +1043,7 @@ Tcl_StaticPackage( */ int -TclGetLoadedPackagesEx( +TclGetLoadedLibraries( Tcl_Interp *interp, /* Interpreter in which to return information * or error message. */ const char *targetName, /* Name of target interpreter or NULL. If diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index f0056eb..b66af58 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -309,7 +309,7 @@ static int TclGetLoadedPackages( * otherwise, just return info about this * interpreter. */ { - return TclGetLoadedPackagesEx(interp, targetName, NULL); + return TclGetLoadedLibraries(interp, targetName, NULL); } mp_err TclBN_mp_div_3(const mp_int *a, mp_int *c, unsigned int *d) { diff --git a/library/safe.tcl b/library/safe.tcl index 27033b2..3c01f75 100644 --- a/library/safe.tcl +++ b/library/safe.tcl @@ -1029,14 +1029,14 @@ proc ::safe::AliasLoad {child file args} { # Determine what kind of load is requested if {$file eq ""} { - # static library loading + # static loading if {$prefix eq ""} { set msg "load error: empty filename and no prefix" Log $child $msg return -code error $msg } if {!$state(staticsok)} { - Log $child "static library loading disabled\ + Log $child "static loading disabled\ (trying to load $prefix to $target)" return -code error "permission denied (static library)" } -- cgit v0.12 From 73019a8bbd67347ff72a37a7a57b7eb001689c8a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 22 Mar 2021 17:20:23 +0000 Subject: indenting --- generic/tclLoad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 4ab26bd..b565eba 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -332,7 +332,7 @@ Tcl_LoadObjCmd( for (p = pkgGuess; *p != 0; p += offset) { offset = TclUtfToUniChar(p, &ch); if (!Tcl_UniCharIsWordChar(UCHAR(ch)) - || Tcl_UniCharIsDigit(UCHAR(ch))) { + || Tcl_UniCharIsDigit(UCHAR(ch))) { break; } } -- cgit v0.12 From 79b9ab1039274a64062f7a8b3a0931b72e79682d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 28 Mar 2021 20:09:51 +0000 Subject: Change TCL_ENCODING_EXTERNAL flag into TCL_ENCODING_MODIFIED, but with opposite meaning. Simplify code. --- generic/tclEncoding.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 4eabbda..3f03bf4 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -511,8 +511,8 @@ FillEncodingFileMap(void) */ /* Those flags must not conflict with other TCL_ENCODING_* flags in tcl.h */ -#define TCL_ENCODING_LE 0x40 /* Little-endian encoding */ -#define TCL_ENCODING_EXTERNAL 0x80 /* Converting from internal to external variant */ +#define TCL_ENCODING_MODIFIED 0x20 /* Converting NULL bytes to 0xC0 0x80 */ +#define TCL_ENCODING_LE 0x80 /* Little-endian encoding, for ucs-2/utf-16 only */ void TclInitEncodingSubsystem(void) @@ -1137,7 +1137,7 @@ Tcl_ExternalToUtfDString( srcLen = encodingPtr->lengthProc(src); } - flags = TCL_ENCODING_START | TCL_ENCODING_END; + flags = TCL_ENCODING_START | TCL_ENCODING_END | TCL_ENCODING_MODIFIED; while (1) { result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen, @@ -1253,18 +1253,17 @@ Tcl_ExternalToUtf( dstLen--; } + flags |= TCL_ENCODING_MODIFIED; do { - int savedFlags = flags; Tcl_EncodingState savedState = *statePtr; result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen, - flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, + flags , statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr); if (*dstCharsPtr <= maxChars) { break; } dstLen = Tcl_UtfAtIndex(dst, maxChars) - dst + (TCL_UTF_MAX - 1); - flags = savedFlags; *statePtr = savedState; } while (1); if (!noTerminate) { @@ -1328,7 +1327,7 @@ Tcl_UtfToExternalDString( flags = TCL_ENCODING_START | TCL_ENCODING_END; while (1) { result = encodingPtr->fromUtfProc(encodingPtr->clientData, src, - srcLen, flags | TCL_ENCODING_EXTERNAL, &state, dst, dstLen, + srcLen, flags, &state, dst, dstLen, &srcRead, &dstWrote, &dstChars); soFar = dst + dstWrote - Tcl_DStringValue(dstPtr); @@ -1430,7 +1429,7 @@ Tcl_UtfToExternal( dstLen -= encodingPtr->nullSize; result = encodingPtr->fromUtfProc(encodingPtr->clientData, src, srcLen, - flags | TCL_ENCODING_EXTERNAL, statePtr, dst, dstLen, srcReadPtr, + flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr); if (encodingPtr->nullSize == 2) { dst[*dstWrotePtr + 1] = '\0'; @@ -2225,7 +2224,7 @@ UtfToUtfProc( result = TCL_CONVERT_NOSPACE; break; } - if (UCHAR(*src) < 0x80 && !(UCHAR(*src) == 0 && !(flags & TCL_ENCODING_EXTERNAL))) { + if (UCHAR(*src) < 0x80 && !(UCHAR(*src) == 0 && (flags & TCL_ENCODING_MODIFIED))) { /* * Copy 7bit characters, but skip null-bytes when we are in input * mode, so that they get converted to 0xC080. @@ -2233,7 +2232,7 @@ UtfToUtfProc( *dst++ = *src++; } else if (UCHAR(*src) == 0xC0 && (src + 1 < srcEnd) - && UCHAR(src[1]) == 0x80 && (flags & TCL_ENCODING_EXTERNAL)) { + && UCHAR(src[1]) == 0x80 && !(flags & TCL_ENCODING_MODIFIED)) { /* * Convert 0xC080 to real nulls when we are in output mode. */ -- cgit v0.12 From 9eb5b14a3c8a078ee645a69b398cc03579126c05 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 30 Mar 2021 06:10:23 +0000 Subject: remove useless save/restore --- generic/tclEncoding.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 012c954..1536f98 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -1241,7 +1241,6 @@ Tcl_ExternalToUtf( dstLen--; } do { - int savedFlags = flags; Tcl_EncodingState savedState = *statePtr; result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen, @@ -1251,7 +1250,6 @@ Tcl_ExternalToUtf( break; } dstLen = Tcl_UtfAtIndex(dst, maxChars) - dst + (TCL_UTF_MAX - 1); - flags = savedFlags; *statePtr = savedState; } while (1); if (!noTerminate) { -- cgit v0.12 From 1f1f43fcd2bfa68c8bff1a9d6dbb8ecab4be43e7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 30 Mar 2021 07:11:18 +0000 Subject: Thanks to TIP #587, convert many escapes in the testcases into the actual (UTF-8) character. --- generic/tclEncoding.c | 2 +- tests/binary.test | 480 +++++++++++++++++++++--------------------- tests/chan.test | 4 +- tests/chanio.test | 221 ++++++++++--------- tests/clock.test | 22 +- tests/cmdAH.test | 16 +- tests/cmdIL.test | 30 +-- tests/cmdMZ.test | 10 +- tests/compExpr-old.test | 20 +- tests/compile.test | 4 +- tests/encoding.test | 78 +++---- tests/exec.test | 10 +- tests/execute.test | 2 +- tests/expr-old.test | 20 +- tests/expr.test | 26 +-- tests/fCmd.test | 4 +- tests/fileSystemEncoding.test | 2 +- tests/format.test | 20 +- tests/http.test | 50 ++--- tests/init.test | 2 +- tests/io.test | 127 ++++++----- tests/ioCmd.test | 4 +- tests/list.test | 14 +- tests/lsearch.test | 4 +- tests/main.test | 36 ++-- tests/obj.test | 4 +- tests/parse.test | 14 +- tests/parseExpr.test | 44 ++-- tests/parseOld.test | 12 +- tests/reg.test | 8 +- tests/regexp.test | 14 +- tests/regexpComp.test | 8 +- tests/scan.test | 30 +-- tests/source.test | 24 +-- tests/split.test | 14 +- tests/string.test | 112 +++++----- tests/stringObj.test | 87 ++++---- tests/subst.test | 2 +- tests/timer.test | 18 +- tests/unixInit.test | 6 +- tests/utf.test | 308 +++++++++++++-------------- tests/util.test | 80 +++---- tests/var.test | 16 +- tests/winPipe.test | 2 +- tests/zipfs.test | 10 +- 45 files changed, 1004 insertions(+), 1017 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 3f03bf4..6fd4503 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -1246,7 +1246,7 @@ Tcl_ExternalToUtf( if (!noTerminate) { /* * If there are any null characters in the middle of the buffer, - * they will converted to the UTF-8 null character (\xC080). To get + * they will converted to the UTF-8 null character (\xC0\x80). To get * the actual \0 at the end of the destination buffer, we need to * append it manually. First make room for it... */ diff --git a/tests/binary.test b/tests/binary.test index 8b326d4..36e31ce 100644 --- a/tests/binary.test +++ b/tests/binary.test @@ -25,9 +25,9 @@ proc testIEEE {} { switch -exact -- $c { {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} { # little endian - binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xFF d \ ieeeValues(-Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xBF d \ ieeeValues(-Normal) binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \ ieeeValues(-Subnormal) @@ -37,19 +37,19 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \ ieeeValues(+Subnormal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x3F d \ ieeeValues(+Normal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x7F d \ ieeeValues(+Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF8\x7F d \ ieeeValues(NaN) set ieeeValues(littleEndian) 1 return 1 } {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} { - binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xFF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Infinity) - binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xBF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Normal) binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Subnormal) @@ -59,11 +59,11 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Subnormal) - binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x3F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Normal) - binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Infinity) - binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF8\x00\x00\x00\x00\x00\x00 d \ ieeeValues(NaN) set ieeeValues(littleEndian) 0 return 1 @@ -160,16 +160,16 @@ test binary-4.3 {Tcl_BinaryObjCmd: format} { } \x80 test binary-4.4 {Tcl_BinaryObjCmd: format} { binary format B* 010011 -} \x4c +} \x4C test binary-4.5 {Tcl_BinaryObjCmd: format} { binary format B8 01001101 -} \x4d +} \x4D test binary-4.6 {Tcl_BinaryObjCmd: format} { binary format A2X2B9 oo 01001101 -} \x4d\x00 +} \x4D\x00 test binary-4.7 {Tcl_BinaryObjCmd: format} { binary format B9 010011011010 -} \x4d\x80 +} \x4D\x80 test binary-4.8 {Tcl_BinaryObjCmd: format} { binary format B2B3 10 010 } \x80\x40 @@ -191,16 +191,16 @@ test binary-5.4 {Tcl_BinaryObjCmd: format} { } 2 test binary-5.5 {Tcl_BinaryObjCmd: format} { binary format b8 01001101 -} \xb2 +} \xB2 test binary-5.6 {Tcl_BinaryObjCmd: format} { binary format A2X2b9 oo 01001101 -} \xb2\x00 +} \xB2\x00 test binary-5.7 {Tcl_BinaryObjCmd: format} { binary format b9 010011011010 -} \xb2\x01 +} \xB2\x01 test binary-5.8 {Tcl_BinaryObjCmd: format} { binary format b17 1 -} \x01\00\00 +} \x01\x00\x00 test binary-5.9 {Tcl_BinaryObjCmd: format} { binary format b2b3 10 010 } \x01\x02 @@ -219,19 +219,19 @@ test binary-6.3 {Tcl_BinaryObjCmd: format} { } \x01 test binary-6.4 {Tcl_BinaryObjCmd: format} { binary format h c -} \x0c +} \x0C test binary-6.5 {Tcl_BinaryObjCmd: format} { binary format h* baadf00d -} \xab\xda\x0f\xd0 +} \xAB\xDA\x0F\xD0 test binary-6.6 {Tcl_BinaryObjCmd: format} { binary format h4 c410 -} \x4c\x01 +} \x4C\x01 test binary-6.7 {Tcl_BinaryObjCmd: format} { binary format h6 c4102 -} \x4c\x01\x02 +} \x4C\x01\x02 test binary-6.8 {Tcl_BinaryObjCmd: format} { binary format h5 c41020304 -} \x4c\x01\x02 +} \x4C\x01\x02 test binary-6.9 {Tcl_BinaryObjCmd: format} { binary format a3X3h5 foo 2 } \x02\x00\x00 @@ -253,19 +253,19 @@ test binary-7.3 {Tcl_BinaryObjCmd: format} { } \x10 test binary-7.4 {Tcl_BinaryObjCmd: format} { binary format H c -} \xc0 +} \xC0 test binary-7.5 {Tcl_BinaryObjCmd: format} { binary format H* baadf00d -} \xba\xad\xf0\x0d +} \xBA\xAD\xF0\x0D test binary-7.6 {Tcl_BinaryObjCmd: format} { binary format H4 c410 -} \xc4\x10 +} \xC4\x10 test binary-7.7 {Tcl_BinaryObjCmd: format} { binary format H6 c4102 -} \xc4\x10\x20 +} \xC4\x10\x20 test binary-7.8 {Tcl_BinaryObjCmd: format} { binary format H5 c41023304 -} \xc4\x10\x20 +} \xC4\x10\x20 test binary-7.9 {Tcl_BinaryObjCmd: format} { binary format a3X3H5 foo 2 } \x20\x00\x00 @@ -485,34 +485,34 @@ test binary-13.3 {Tcl_BinaryObjCmd: format} { } {} test binary-13.4 {Tcl_BinaryObjCmd: format} bigEndian { binary format f 1.6 -} \x3f\xcc\xcc\xcd +} \x3F\xCC\xCC\xCD test binary-13.5 {Tcl_BinaryObjCmd: format} littleEndian { binary format f 1.6 -} \xcd\xcc\xcc\x3f +} \xCD\xCC\xCC\x3F test binary-13.6 {Tcl_BinaryObjCmd: format} bigEndian { binary format f* {1.6 3.4} -} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a +} \x3F\xCC\xCC\xCD\x40\x59\x99\x9A test binary-13.7 {Tcl_BinaryObjCmd: format} littleEndian { binary format f* {1.6 3.4} -} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 +} \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 test binary-13.8 {Tcl_BinaryObjCmd: format} bigEndian { binary format f2 {1.6 3.4} -} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a +} \x3F\xCC\xCC\xCD\x40\x59\x99\x9A test binary-13.9 {Tcl_BinaryObjCmd: format} littleEndian { binary format f2 {1.6 3.4} -} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 +} \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 test binary-13.10 {Tcl_BinaryObjCmd: format} bigEndian { binary format f2 {1.6 3.4 5.6} -} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a +} \x3F\xCC\xCC\xCD\x40\x59\x99\x9A test binary-13.11 {Tcl_BinaryObjCmd: format} littleEndian { binary format f2 {1.6 3.4 5.6} -} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 +} \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 test binary-13.12 {Tcl_BinaryObjCmd: float overflow} bigEndian { binary format f -3.402825e+38 -} \xff\x7f\xff\xff +} \xFF\x7F\xFF\xFF test binary-13.13 {Tcl_BinaryObjCmd: float overflow} littleEndian { binary format f -3.402825e+38 -} \xff\xff\x7f\xff +} \xFF\xFF\x7F\xFF test binary-13.14 {Tcl_BinaryObjCmd: float underflow} bigEndian { binary format f -3.402825e-100 } \x80\x00\x00\x00 @@ -529,11 +529,11 @@ test binary-13.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body { test binary-13.18 {Tcl_BinaryObjCmd: format} bigEndian { set a {1.6 3.4} binary format f1 $a -} \x3f\xcc\xcc\xcd +} \x3F\xCC\xCC\xCD test binary-13.19 {Tcl_BinaryObjCmd: format} littleEndian { set a {1.6 3.4} binary format f1 $a -} \xcd\xcc\xcc\x3f +} \xCD\xCC\xCC\x3F test binary-14.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body { binary format d @@ -546,28 +546,28 @@ test binary-14.3 {Tcl_BinaryObjCmd: format} { } {} test binary-14.4 {Tcl_BinaryObjCmd: format} bigEndian { binary format d 1.6 -} \x3f\xf9\x99\x99\x99\x99\x99\x9a +} \x3F\xF9\x99\x99\x99\x99\x99\x9A test binary-14.5 {Tcl_BinaryObjCmd: format} littleEndian { binary format d 1.6 -} \x9a\x99\x99\x99\x99\x99\xf9\x3f +} \x9A\x99\x99\x99\x99\x99\xF9\x3F test binary-14.6 {Tcl_BinaryObjCmd: format} bigEndian { binary format d* {1.6 3.4} -} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 +} \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 test binary-14.7 {Tcl_BinaryObjCmd: format} littleEndian { binary format d* {1.6 3.4} -} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 +} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 test binary-14.8 {Tcl_BinaryObjCmd: format} bigEndian { binary format d2 {1.6 3.4} -} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 +} \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 test binary-14.9 {Tcl_BinaryObjCmd: format} littleEndian { binary format d2 {1.6 3.4} -} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 +} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 test binary-14.10 {Tcl_BinaryObjCmd: format} bigEndian { binary format d2 {1.6 3.4 5.6} -} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 +} \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 test binary-14.11 {Tcl_BinaryObjCmd: format} littleEndian { binary format d2 {1.6 3.4 5.6} -} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 +} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 test binary-14.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body { binary format d2 {1.6} } -result {number of elements in list does not match count} @@ -578,11 +578,11 @@ test binary-14.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body { test binary-14.16 {Tcl_BinaryObjCmd: format} bigEndian { set a {1.6 3.4} binary format d1 $a -} \x3f\xf9\x99\x99\x99\x99\x99\x9a +} \x3F\xF9\x99\x99\x99\x99\x99\x9A test binary-14.17 {Tcl_BinaryObjCmd: format} littleEndian { set a {1.6 3.4} binary format d1 $a -} \x9a\x99\x99\x99\x99\x99\xf9\x3f +} \x9A\x99\x99\x99\x99\x99\xF9\x3F test binary-14.18 {FormatNumber: Bug 1116542} { binary scan [binary format d 1.25] d w set w @@ -874,11 +874,11 @@ test binary-24.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-24.2 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 h* arg1] $arg1 + list [binary scan \x52\xA3 h* arg1] $arg1 } {1 253a} test binary-24.3 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \xc2\xa3 h arg1] $arg1 + list [binary scan \xC2\xA3 h arg1] $arg1 } {1 2} test binary-24.4 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -890,7 +890,7 @@ test binary-24.5 {Tcl_BinaryObjCmd: scan} { } {1 {}} test binary-24.6 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \xf2\x53 h2 arg1] $arg1 + list [binary scan \xF2\x53 h2 arg1] $arg1 } {1 2f} test binary-24.7 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -920,11 +920,11 @@ test binary-25.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-25.2 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 H* arg1] $arg1 + list [binary scan \x52\xA3 H* arg1] $arg1 } {1 52a3} test binary-25.3 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \xc2\xa3 H arg1] $arg1 + list [binary scan \xC2\xA3 H arg1] $arg1 } {1 c} test binary-25.4 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -936,7 +936,7 @@ test binary-25.5 {Tcl_BinaryObjCmd: scan} { } {1 {}} test binary-25.6 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \xf2\x53 H2 arg1] $arg1 + list [binary scan \xF2\x53 H2 arg1] $arg1 } {1 f2} test binary-25.7 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -965,27 +965,27 @@ test binary-26.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-26.2 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 c* arg1] $arg1 + list [binary scan \x52\xA3 c* arg1] $arg1 } {1 {82 -93}} test binary-26.3 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 c arg1] $arg1 + list [binary scan \x52\xA3 c arg1] $arg1 } {1 82} test binary-26.4 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 c1 arg1] $arg1 + list [binary scan \x52\xA3 c1 arg1] $arg1 } {1 82} test binary-26.5 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 c0 arg1] $arg1 + list [binary scan \x52\xA3 c0 arg1] $arg1 } {1 {}} test binary-26.6 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 c2 arg1] $arg1 + list [binary scan \x52\xA3 c2 arg1] $arg1 } {1 {82 -93}} test binary-26.7 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \xff c arg1] $arg1 + list [binary scan \xFF c arg1] $arg1 } {1 -1} test binary-26.8 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -1006,15 +1006,15 @@ test binary-26.10 {Tcl_BinaryObjCmd: scan} { } {2 {112 -121} 5} test binary-26.11 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 cu* arg1] $arg1 + list [binary scan \x52\xA3 cu* arg1] $arg1 } {1 {82 163}} test binary-26.12 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 cu arg1] $arg1 + list [binary scan \x52\xA3 cu arg1] $arg1 } {1 82} test binary-26.13 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \xff cu arg1] $arg1 + list [binary scan \xFF cu arg1] $arg1 } {1 255} test binary-26.14 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 @@ -1034,23 +1034,23 @@ test binary-27.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-27.2 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 s* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 s* arg1] $arg1 } {1 {-23726 21587}} test binary-27.3 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 s arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 s arg1] $arg1 } {1 -23726} test binary-27.4 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 s1 arg1] $arg1 + list [binary scan \x52\xA3 s1 arg1] $arg1 } {1 -23726} test binary-27.5 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 s0 arg1] $arg1 + list [binary scan \x52\xA3 s0 arg1] $arg1 } {1 {}} test binary-27.6 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 s2 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 s2 arg1] $arg1 } {1 {-23726 21587}} test binary-27.7 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -1067,23 +1067,23 @@ test binary-27.9 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x52\xa3\x53\x54\x05 s2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x52\xA3\x53\x54\x05 s2c* arg1 arg2] $arg1 $arg2 } {2 {-23726 21587} 5} test binary-27.10 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 su* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 su* arg1] $arg1 } {1 {41810 21587}} test binary-27.11 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \xff\xff\xff\xff sus arg1 arg2] $arg1 $arg2 + list [binary scan \xFF\xFF\xFF\xFF sus arg1 arg2] $arg1 $arg2 } {2 65535 -1} test binary-27.12 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \xff\xff\xff\xff ssu arg1 arg2] $arg1 $arg2 + list [binary scan \xFF\xFF\xFF\xFF ssu arg1 arg2] $arg1 $arg2 } {2 -1 65535} test binary-28.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { @@ -1091,23 +1091,23 @@ test binary-28.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-28.2 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 S* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 S* arg1] $arg1 } {1 {21155 21332}} test binary-28.3 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 S arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 S arg1] $arg1 } {1 21155} test binary-28.4 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 S1 arg1] $arg1 + list [binary scan \x52\xA3 S1 arg1] $arg1 } {1 21155} test binary-28.5 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3 S0 arg1] $arg1 + list [binary scan \x52\xA3 S0 arg1] $arg1 } {1 {}} test binary-28.6 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 S2 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 S2 arg1] $arg1 } {1 {21155 21332}} test binary-28.7 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -1124,15 +1124,15 @@ test binary-28.9 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x52\xa3\x53\x54\x05 S2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x52\xA3\x53\x54\x05 S2c* arg1 arg2] $arg1 $arg2 } {2 {21155 21332} 5} test binary-28.10 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 Su* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 Su* arg1] $arg1 } {1 {21155 21332}} test binary-28.11 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \xa3\x52\x54\x53 Su* arg1] $arg1 + list [binary scan \xA3\x52\x54\x53 Su* arg1] $arg1 } {1 {41810 21587}} test binary-29.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { @@ -1140,23 +1140,23 @@ test binary-29.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-29.2 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 i* arg1] $arg1 } {1 {1414767442 67305985}} test binary-29.3 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 i arg1] $arg1 } {1 1414767442} test binary-29.4 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 i1 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 i1 arg1] $arg1 } {1 1414767442} test binary-29.5 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53 i0 arg1] $arg1 + list [binary scan \x52\xA3\x53 i0 arg1] $arg1 } {1 {}} test binary-29.6 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i2 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 i2 arg1] $arg1 } {1 {1414767442 67305985}} test binary-29.7 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -1173,15 +1173,15 @@ test binary-29.9 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 i2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04\x05 i2c* arg1 arg2] $arg1 $arg2 } {2 {1414767442 67305985} 5} test binary-29.10 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 - list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff iui arg1 arg2] $arg1 $arg2 + list [binary scan \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF iui arg1 arg2] $arg1 $arg2 } {2 4294967295 -1} test binary-29.11 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 - list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff iiu arg1 arg2] $arg1 $arg2 + list [binary scan \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF iiu arg1 arg2] $arg1 $arg2 } {2 -1 4294967295} test binary-29.12 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 @@ -1193,23 +1193,23 @@ test binary-30.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-30.2 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 I* arg1] $arg1 } {1 {1386435412 16909060}} test binary-30.3 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 I arg1] $arg1 } {1 1386435412} test binary-30.4 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 I1 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 I1 arg1] $arg1 } {1 1386435412} test binary-30.5 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53 I0 arg1] $arg1 + list [binary scan \x52\xA3\x53 I0 arg1] $arg1 } {1 {}} test binary-30.6 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I2 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 I2 arg1] $arg1 } {1 {1386435412 16909060}} test binary-30.7 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -1226,15 +1226,15 @@ test binary-30.9 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 I2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04\x05 I2c* arg1 arg2] $arg1 $arg2 } {2 {1386435412 16909060} 5} test binary-30.10 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 - list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff IuI arg1 arg2] $arg1 $arg2 + list [binary scan \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF IuI arg1 arg2] $arg1 $arg2 } {2 4294967295 -1} test binary-30.11 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 - list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff IIu arg1 arg2] $arg1 $arg2 + list [binary scan \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF IIu arg1 arg2] $arg1 $arg2 } {2 -1 4294967295} test binary-30.12 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 arg2 @@ -1246,43 +1246,43 @@ test binary-31.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-31.2 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f* arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD\x40\x59\x99\x9A f* arg1] $arg1 } {1 {1.600000023841858 3.4000000953674316}} test binary-31.3 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f* arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 f* arg1] $arg1 } {1 {1.600000023841858 3.4000000953674316}} test binary-31.4 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD\x40\x59\x99\x9A f arg1] $arg1 } {1 1.600000023841858} test binary-31.5 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 f arg1] $arg1 } {1 1.600000023841858} test binary-31.6 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd f1 arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD f1 arg1] $arg1 } {1 1.600000023841858} test binary-31.7 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f f1 arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F f1 arg1] $arg1 } {1 1.600000023841858} test binary-31.8 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd f0 arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD f0 arg1] $arg1 } {1 {}} test binary-31.9 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f f0 arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F f0 arg1] $arg1 } {1 {}} test binary-31.10 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f2 arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD\x40\x59\x99\x9A f2 arg1] $arg1 } {1 {1.600000023841858 3.4000000953674316}} test binary-31.11 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f2 arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 f2 arg1] $arg1 } {1 {1.600000023841858 3.4000000953674316}} test binary-31.12 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -1293,19 +1293,19 @@ test binary-31.13 {Tcl_BinaryObjCmd: scan} -setup { unset -nocomplain arg1 } -returnCodes error -body { set arg1 1 - binary scan \x3f\xcc\xcc\xcd f1 arg1(a) + binary scan \x3F\xCC\xCC\xCD f1 arg1(a) } -result {can't set "arg1(a)": variable isn't array} test binary-31.14 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a\x05 f2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x3F\xCC\xCC\xCD\x40\x59\x99\x9A\x05 f2c* arg1 arg2] $arg1 $arg2 } {2 {1.600000023841858 3.4000000953674316} 5} test binary-31.15 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40\x05 f2c* arg1 arg2] $arg1 $arg2 + list [binary scan \xCD\xCC\xCC\x3F\x9A\x99\x59\x40\x05 f2c* arg1 arg2] $arg1 $arg2 } {2 {1.600000023841858 3.4000000953674316} 5} test binary-32.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { @@ -1313,43 +1313,43 @@ test binary-32.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-32.2 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d* arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 d* arg1] $arg1 } {1 {1.6 3.4}} test binary-32.3 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d* arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 d* arg1] $arg1 } {1 {1.6 3.4}} test binary-32.4 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 d arg1] $arg1 } {1 1.6} test binary-32.5 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 d arg1] $arg1 } {1 1.6} test binary-32.6 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d1 arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A d1 arg1] $arg1 } {1 1.6} test binary-32.7 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f d1 arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F d1 arg1] $arg1 } {1 1.6} test binary-32.8 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d0 arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A d0 arg1] $arg1 } {1 {}} test binary-32.9 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f d0 arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F d0 arg1] $arg1 } {1 {}} test binary-32.10 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d2 arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 d2 arg1] $arg1 } {1 {1.6 3.4}} test binary-32.11 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d2 arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 d2 arg1] $arg1 } {1 {1.6 3.4}} test binary-32.12 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -1360,19 +1360,19 @@ test binary-32.13 {Tcl_BinaryObjCmd: scan} -setup { unset -nocomplain arg1 } -returnCodes error -body { set arg1 1 - binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d1 arg1(a) + binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A d1 arg1(a) } -result {can't set "arg1(a)": variable isn't array} test binary-32.14 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33\x05 d2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33\x05 d2c* arg1 arg2] $arg1 $arg2 } {2 {1.6 3.4} 5} test binary-32.15 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40\x05 d2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40\x05 d2c* arg1 arg2] $arg1 $arg2 } {2 {1.6 3.4} 5} test binary-33.1 {Tcl_BinaryObjCmd: scan} { @@ -1543,20 +1543,20 @@ test binary-38.4 {FormatNumber: word alignment} { } \x01\x00\x00\x00\x01 test binary-38.5 {FormatNumber: word alignment} bigEndian { set x [binary format c1d1 1 1.6] -} \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a +} \x01\x3F\xF9\x99\x99\x99\x99\x99\x9A test binary-38.6 {FormatNumber: word alignment} littleEndian { set x [binary format c1d1 1 1.6] -} \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f +} \x01\x9A\x99\x99\x99\x99\x99\xF9\x3F test binary-38.7 {FormatNumber: word alignment} bigEndian { set x [binary format c1f1 1 1.6] -} \x01\x3f\xcc\xcc\xcd +} \x01\x3F\xCC\xCC\xCD test binary-38.8 {FormatNumber: word alignment} littleEndian { set x [binary format c1f1 1 1.6] -} \x01\xcd\xcc\xcc\x3f +} \x01\xCD\xCC\xCC\x3F test binary-39.1 {ScanNumber: sign extension} { unset -nocomplain arg1 - list [binary scan \x52\xa3 c2 arg1] $arg1 + list [binary scan \x52\xA3 c2 arg1] $arg1 } {1 {82 -93}} test binary-39.2 {ScanNumber: sign extension} { unset -nocomplain arg1 @@ -1576,7 +1576,7 @@ test binary-39.5 {ScanNumber: sign extension} { } {1 {16843010 -2130640639 25297153 16876033 16843137}} test binary-39.6 {ScanNumber: no sign extension} { unset -nocomplain arg1 - list [binary scan \x52\xa3 cu2 arg1] $arg1 + list [binary scan \x52\xA3 cu2 arg1] $arg1 } {1 {82 163}} test binary-39.7 {ScanNumber: no sign extension} { unset -nocomplain arg1 @@ -1597,11 +1597,11 @@ test binary-39.10 {ScanNumber: no sign extension} { test binary-40.3 {ScanNumber: NaN} -body { unset -nocomplain arg1 - list [binary scan \xff\xff\xff\xff f1 arg1] $arg1 + list [binary scan \xFF\xFF\xFF\xFF f1 arg1] $arg1 } -match glob -result {1 -NaN*} test binary-40.4 {ScanNumber: NaN} -body { unset -nocomplain arg1 - list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff d arg1] $arg1 + list [binary scan \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF d arg1] $arg1 } -match glob -result {1 -NaN*} test binary-41.1 {ScanNumber: word alignment} -setup { @@ -1627,22 +1627,22 @@ test binary-41.4 {ScanNumber: word alignment} -setup { test binary-41.5 {ScanNumber: word alignment} -setup { unset -nocomplain arg1 arg2 } -constraints bigEndian -body { - list [binary scan \x01\x3f\xcc\xcc\xcd c1f1 arg1 arg2] $arg1 $arg2 + list [binary scan \x01\x3F\xCC\xCC\xCD c1f1 arg1 arg2] $arg1 $arg2 } -result {2 1 1.600000023841858} test binary-41.6 {ScanNumber: word alignment} -setup { unset -nocomplain arg1 arg2 } -constraints littleEndian -body { - list [binary scan \x01\xcd\xcc\xcc\x3f c1f1 arg1 arg2] $arg1 $arg2 + list [binary scan \x01\xCD\xCC\xCC\x3F c1f1 arg1 arg2] $arg1 $arg2 } -result {2 1 1.600000023841858} test binary-41.7 {ScanNumber: word alignment} -setup { unset -nocomplain arg1 arg2 } -constraints bigEndian -body { - list [binary scan \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a c1d1 arg1 arg2] $arg1 $arg2 + list [binary scan \x01\x3F\xF9\x99\x99\x99\x99\x99\x9A c1d1 arg1 arg2] $arg1 $arg2 } -result {2 1 1.6} test binary-41.8 {ScanNumber: word alignment} -setup { unset -nocomplain arg1 arg2 } -constraints littleEndian -body { - list [binary scan \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f c1d1 arg1 arg2] $arg1 $arg2 + list [binary scan \x01\x9A\x99\x99\x99\x99\x99\xF9\x3F c1d1 arg1 arg2] $arg1 $arg2 } -result {2 1 1.6} test binary-42.1 {Tcl_BinaryObjCmd: bad arguments} -constraints {} -body { @@ -1713,26 +1713,26 @@ test binary-45.2 {Tcl_BinaryObjCmd: combined wide int handling} { } {66 64 0 0 0 0 127 -1 -1 -1 65 76} test binary-46.1 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} { - binary format a* \u20ac -} \u00ac + binary format a* € +} \xAC test binary-46.2 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} { - list [binary scan [binary format a* \u20ac\u20bd] s x] $x + list [binary scan [binary format a* €₽] s x] $x } {1 -16980} test binary-46.3 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} { set x {} set y {} set z {} - list [binary scan [binary format a* \u20ac\u20bd] aaa x y z] $x $y $z -} "2 \u00ac \u00bd {}" + list [binary scan [binary format a* €₽] aaa x y z] $x $y $z +} "2 \xAC \xBD {}" test binary-46.4 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} { - set x [encoding convertto iso8859-15 \u20ac] + set x [encoding convertto iso8859-15 €] set y [binary format a* $x] list $x $y -} "\u00a4 \u00a4" +} "\xA4 \xA4" test binary-46.5 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} { - set x [binary scan \u00a4 a* y] + set x [binary scan \xA4 a* y] list $x $y [encoding convertfrom iso8859-15 $y] -} "1 \u00a4 \u20ac" +} "1 \xA4 €" test binary-47.1 {Tcl_BinaryObjCmd: number cache reference count handling} { # This test is only reliable when memory debugging is turned on, but @@ -1898,28 +1898,28 @@ test binary-51.3 {Tcl_BinaryObjCmd: format} { } {} test binary-51.4 {Tcl_BinaryObjCmd: format} {} { binary format Q 1.6 -} \x3f\xf9\x99\x99\x99\x99\x99\x9a +} \x3F\xF9\x99\x99\x99\x99\x99\x9A test binary-51.5 {Tcl_BinaryObjCmd: format} {} { binary format q 1.6 -} \x9a\x99\x99\x99\x99\x99\xf9\x3f +} \x9A\x99\x99\x99\x99\x99\xF9\x3F test binary-51.6 {Tcl_BinaryObjCmd: format} {} { binary format Q* {1.6 3.4} -} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 +} \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 test binary-51.7 {Tcl_BinaryObjCmd: format} {} { binary format q* {1.6 3.4} -} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 +} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 test binary-51.8 {Tcl_BinaryObjCmd: format} {} { binary format Q2 {1.6 3.4} -} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 +} \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 test binary-51.9 {Tcl_BinaryObjCmd: format} {} { binary format q2 {1.6 3.4} -} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 +} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 test binary-51.10 {Tcl_BinaryObjCmd: format} {} { binary format Q2 {1.6 3.4 5.6} -} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 +} \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 test binary-51.11 {Tcl_BinaryObjCmd: format} {} { binary format q2 {1.6 3.4 5.6} -} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 +} \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 test binary-51.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body { binary format q2 {1.6} } -result {number of elements in list does not match count} @@ -1930,11 +1930,11 @@ test binary-51.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body { test binary-51.16 {Tcl_BinaryObjCmd: format} {} { set a {1.6 3.4} binary format Q1 $a -} \x3f\xf9\x99\x99\x99\x99\x99\x9a +} \x3F\xF9\x99\x99\x99\x99\x99\x9A test binary-51.17 {Tcl_BinaryObjCmd: format} {} { set a {1.6 3.4} binary format q1 $a -} \x9a\x99\x99\x99\x99\x99\xf9\x3f +} \x9A\x99\x99\x99\x99\x99\xF9\x3F # format R/r test binary-53.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body { @@ -1948,34 +1948,34 @@ test binary-53.3 {Tcl_BinaryObjCmd: format} { } {} test binary-53.4 {Tcl_BinaryObjCmd: format} {} { binary format R 1.6 -} \x3f\xcc\xcc\xcd +} \x3F\xCC\xCC\xCD test binary-53.5 {Tcl_BinaryObjCmd: format} {} { binary format r 1.6 -} \xcd\xcc\xcc\x3f +} \xCD\xCC\xCC\x3F test binary-53.6 {Tcl_BinaryObjCmd: format} {} { binary format R* {1.6 3.4} -} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a +} \x3F\xCC\xCC\xCD\x40\x59\x99\x9A test binary-53.7 {Tcl_BinaryObjCmd: format} {} { binary format r* {1.6 3.4} -} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 +} \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 test binary-53.8 {Tcl_BinaryObjCmd: format} {} { binary format R2 {1.6 3.4} -} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a +} \x3F\xCC\xCC\xCD\x40\x59\x99\x9A test binary-53.9 {Tcl_BinaryObjCmd: format} {} { binary format r2 {1.6 3.4} -} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 +} \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 test binary-53.10 {Tcl_BinaryObjCmd: format} {} { binary format R2 {1.6 3.4 5.6} -} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a +} \x3F\xCC\xCC\xCD\x40\x59\x99\x9A test binary-53.11 {Tcl_BinaryObjCmd: format} {} { binary format r2 {1.6 3.4 5.6} -} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 +} \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 test binary-53.12 {Tcl_BinaryObjCmd: float overflow} {} { binary format R -3.402825e+38 -} \xff\x7f\xff\xff +} \xFF\x7F\xFF\xFF test binary-53.13 {Tcl_BinaryObjCmd: float overflow} {} { binary format r -3.402825e+38 -} \xff\xff\x7f\xff +} \xFF\xFF\x7F\xFF test binary-53.14 {Tcl_BinaryObjCmd: float underflow} {} { binary format R -3.402825e-100 } \x80\x00\x00\x00 @@ -1992,11 +1992,11 @@ test binary-53.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body { test binary-53.18 {Tcl_BinaryObjCmd: format} {} { set a {1.6 3.4} binary format R1 $a -} \x3f\xcc\xcc\xcd +} \x3F\xCC\xCC\xCD test binary-53.19 {Tcl_BinaryObjCmd: format} {} { set a {1.6 3.4} binary format r1 $a -} \xcd\xcc\xcc\x3f +} \xCD\xCC\xCC\x3F # scan t (s) test binary-54.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { @@ -2004,23 +2004,23 @@ test binary-54.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-54.2 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 t* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 t* arg1] $arg1 } {1 {-23726 21587}} test binary-54.3 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 t arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 t arg1] $arg1 } {1 -23726} test binary-54.4 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3 t1 arg1] $arg1 + list [binary scan \x52\xA3 t1 arg1] $arg1 } {1 -23726} test binary-54.5 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3 t0 arg1] $arg1 + list [binary scan \x52\xA3 t0 arg1] $arg1 } {1 {}} test binary-54.6 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 t2 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 t2 arg1] $arg1 } {1 {-23726 21587}} test binary-54.7 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 @@ -2037,7 +2037,7 @@ test binary-54.9 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x52\xa3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x52\xA3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2 } {2 {-23726 21587} 5} test binary-54.10 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 arg2 @@ -2058,23 +2058,23 @@ test binary-55.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-55.2 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 t* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 t* arg1] $arg1 } {1 {21155 21332}} test binary-55.3 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 t arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 t arg1] $arg1 } {1 21155} test binary-55.4 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3 t1 arg1] $arg1 + list [binary scan \x52\xA3 t1 arg1] $arg1 } {1 21155} test binary-55.5 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3 t0 arg1] $arg1 + list [binary scan \x52\xA3 t0 arg1] $arg1 } {1 {}} test binary-55.6 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 t2 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 t2 arg1] $arg1 } {1 {21155 21332}} test binary-55.7 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 @@ -2091,7 +2091,7 @@ test binary-55.9 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x52\xa3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x52\xA3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2 } {2 {21155 21332} 5} test binary-55.10 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 arg2 @@ -2112,23 +2112,23 @@ test binary-56.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-56.2 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1 } {1 {1414767442 67305985}} test binary-56.3 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 n arg1] $arg1 } {1 1414767442} test binary-56.4 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 n1 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 n1 arg1] $arg1 } {1 1414767442} test binary-56.5 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53 n0 arg1] $arg1 + list [binary scan \x52\xA3\x53 n0 arg1] $arg1 } {1 {}} test binary-56.6 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1 } {1 {1414767442 67305985}} test binary-56.7 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 @@ -2145,7 +2145,7 @@ test binary-56.9 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2 } {2 {1414767442 67305985} 5} test binary-56.10 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 arg2 @@ -2166,23 +2166,23 @@ test binary-57.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-57.2 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1 } {1 {1386435412 16909060}} test binary-57.3 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 n arg1] $arg1 } {1 1386435412} test binary-57.4 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54 n1 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54 n1 arg1] $arg1 } {1 1386435412} test binary-57.5 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53 n0 arg1] $arg1 + list [binary scan \x52\xA3\x53 n0 arg1] $arg1 } {1 {}} test binary-57.6 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1 } {1 {1386435412 16909060}} test binary-57.7 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 @@ -2199,7 +2199,7 @@ test binary-57.9 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x52\xA3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2 } {2 {1386435412 16909060} 5} test binary-57.10 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 arg2 @@ -2220,43 +2220,43 @@ test binary-58.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-58.2 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q* arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 Q* arg1] $arg1 } {1 {1.6 3.4}} test binary-58.3 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q* arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 q* arg1] $arg1 } {1 {1.6 3.4}} test binary-58.4 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 Q arg1] $arg1 } {1 1.6} test binary-58.5 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 q arg1] $arg1 } {1 1.6} test binary-58.6 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a Q1 arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A Q1 arg1] $arg1 } {1 1.6} test binary-58.7 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f q1 arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F q1 arg1] $arg1 } {1 1.6} test binary-58.8 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a Q0 arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A Q0 arg1] $arg1 } {1 {}} test binary-58.9 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f q0 arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F q0 arg1] $arg1 } {1 {}} test binary-58.10 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q2 arg1] $arg1 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33 Q2 arg1] $arg1 } {1 {1.6 3.4}} test binary-58.11 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q2 arg1] $arg1 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40 q2 arg1] $arg1 } {1 {1.6 3.4}} test binary-58.12 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -2267,19 +2267,19 @@ test binary-58.13 {Tcl_BinaryObjCmd: scan} -setup { unset -nocomplain arg1 } -returnCodes error -body { set arg1 1 - binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a q1 arg1(a) + binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A q1 arg1(a) } -result {can't set "arg1(a)": variable isn't array} test binary-58.14 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33\x05 Q2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x3F\xF9\x99\x99\x99\x99\x99\x9A\x40\x0B\x33\x33\x33\x33\x33\x33\x05 Q2c* arg1 arg2] $arg1 $arg2 } {2 {1.6 3.4} 5} test binary-58.15 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40\x05 q2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x9A\x99\x99\x99\x99\x99\xF9\x3F\x33\x33\x33\x33\x33\x33\x0B\x40\x05 q2c* arg1 arg2] $arg1 $arg2 } {2 {1.6 3.4} 5} # scan R/r @@ -2288,43 +2288,43 @@ test binary-59.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { } -result {not enough arguments for all format specifiers} test binary-59.2 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R* arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD\x40\x59\x99\x9A R* arg1] $arg1 } {1 {1.600000023841858 3.4000000953674316}} test binary-59.3 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r* arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 r* arg1] $arg1 } {1 {1.600000023841858 3.4000000953674316}} test binary-59.4 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD\x40\x59\x99\x9A R arg1] $arg1 } {1 1.600000023841858} test binary-59.5 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 r arg1] $arg1 } {1 1.600000023841858} test binary-59.6 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd R1 arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD R1 arg1] $arg1 } {1 1.600000023841858} test binary-59.7 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f r1 arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F r1 arg1] $arg1 } {1 1.600000023841858} test binary-59.8 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd R0 arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD R0 arg1] $arg1 } {1 {}} test binary-59.9 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f r0 arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F r0 arg1] $arg1 } {1 {}} test binary-59.10 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 - list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R2 arg1] $arg1 + list [binary scan \x3F\xCC\xCC\xCD\x40\x59\x99\x9A R2 arg1] $arg1 } {1 {1.600000023841858 3.4000000953674316}} test binary-59.11 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 - list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r2 arg1] $arg1 + list [binary scan \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 r2 arg1] $arg1 } {1 {1.600000023841858 3.4000000953674316}} test binary-59.12 {Tcl_BinaryObjCmd: scan} { unset -nocomplain arg1 @@ -2335,19 +2335,19 @@ test binary-59.13 {Tcl_BinaryObjCmd: scan} -setup { unset -nocomplain arg1 } -returnCodes error -body { set arg1 1 - binary scan \x3f\xcc\xcc\xcd r1 arg1(a) + binary scan \x3F\xCC\xCC\xCD r1 arg1(a) } -result {can't set "arg1(a)": variable isn't array} test binary-59.14 {Tcl_BinaryObjCmd: scan} bigEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a\x05 R2c* arg1 arg2] $arg1 $arg2 + list [binary scan \x3F\xCC\xCC\xCD\x40\x59\x99\x9A\x05 R2c* arg1 arg2] $arg1 $arg2 } {2 {1.600000023841858 3.4000000953674316} 5} test binary-59.15 {Tcl_BinaryObjCmd: scan} littleEndian { unset -nocomplain arg1 arg2 set arg1 foo set arg2 bar - list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40\x05 r2c* arg1 arg2] $arg1 $arg2 + list [binary scan \xCD\xCC\xCC\x3F\x9A\x99\x59\x40\x05 r2c* arg1 arg2] $arg1 $arg2 } {2 {1.600000023841858 3.4000000953674316} 5} test binary-60.1 {[binary format] with NaN} -body { @@ -2496,7 +2496,7 @@ test binary-70.4 {binary encode hex} -body { binary encode hex [string repeat a 20] } -result [string repeat 61 20] test binary-70.5 {binary encode hex} -body { - binary encode hex \0\1\2\3\4\0\1\2\3\4 + binary encode hex \x00\x01\x02\x03\x04\x00\x01\x02\x03\x04 } -result {00010203040001020304} test binary-71.1 {binary decode hex} -body { @@ -2513,7 +2513,7 @@ test binary-71.4 {binary decode hex} -body { } -result [string repeat a 20] test binary-71.5 {binary decode hex} -body { binary decode hex 00010203040001020304 -} -result "\0\1\2\3\4\0\1\2\3\4" +} -result "\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04" test binary-71.6 {binary decode hex} -body { binary decode hex "61 61" } -result {aa} @@ -2572,19 +2572,19 @@ test binary-72.4 {binary encode base64} -body { binary encode base64 [string repeat abc 20] } -result [string repeat YWJj 20] test binary-72.5 {binary encode base64} -body { - binary encode base64 \0\1\2\3\4\0\1\2\3 + binary encode base64 \x00\x01\x02\x03\x04\x00\x01\x02\x03 } -result {AAECAwQAAQID} test binary-72.6 {binary encode base64} -body { - binary encode base64 \0 + binary encode base64 \x00 } -result {AA==} test binary-72.7 {binary encode base64} -body { - binary encode base64 \0\0 + binary encode base64 \x00\x00 } -result {AAA=} test binary-72.8 {binary encode base64} -body { - binary encode base64 \0\0\0 + binary encode base64 \x00\x00\x00 } -result {AAAA} test binary-72.9 {binary encode base64} -body { - binary encode base64 \0\0\0\0 + binary encode base64 \x00\x00\x00\x00 } -result {AAAAAA==} test binary-72.10 {binary encode base64} -body { binary encode base64 -maxlen 0 -wrapchar : abcabcabc @@ -2644,7 +2644,7 @@ test binary-72.28 {binary encode base64} -body { binary encode base64 -maxlen 6 -wrapchar 0123456789 abcabcabc } -result {YWJjYW0123456789JjYWJj} test binary-72.29 {binary encode base64} { - string length [binary encode base64 -maxlen 3 -wrapchar \xca abc] + string length [binary encode base64 -maxlen 3 -wrapchar \xCA abc] } 5 test binary-73.1 {binary decode base64} -body { @@ -2661,19 +2661,19 @@ test binary-73.4 {binary decode base64} -body { } -result [string repeat abc 20] test binary-73.5 {binary decode base64} -body { binary decode base64 AAECAwQAAQID -} -result "\0\1\2\3\4\0\1\2\3" +} -result "\x00\x01\x02\x03\x04\x00\x01\x02\x03" test binary-73.6 {binary decode base64} -body { binary decode base64 AA== -} -result "\0" +} -result "\x00" test binary-73.7 {binary decode base64} -body { binary decode base64 AAA= -} -result "\0\0" +} -result "\x00\x00" test binary-73.8 {binary decode base64} -body { binary decode base64 AAAA -} -result "\0\0\0" +} -result "\x00\x00\x00" test binary-73.9 {binary decode base64} -body { binary decode base64 AAAAAA== -} -result "\0\0\0\0" +} -result "\x00\x00\x00\x00" test binary-73.10 {binary decode base64} -body { set s "[string repeat YWJj 10]\n[string repeat YWJj 10]" binary decode base64 $s @@ -2791,22 +2791,22 @@ test binary-74.4 {binary encode uuencode} -body { binary encode uuencode [string repeat abc 20] } -result "M[string repeat 86)C 15]\n/[string repeat 86)C 5]\n" test binary-74.5 {binary encode uuencode} -body { - binary encode uuencode \0\1\2\3\4\0\1\2\3 + binary encode uuencode \x00\x01\x02\x03\x04\x00\x01\x02\x03 } -result ")``\$\"`P0``0(#\n" test binary-74.6 {binary encode uuencode} -body { binary encode uuencode \0 } -result {!`` } test binary-74.7 {binary encode uuencode} -body { - binary encode uuencode \0\0 + binary encode uuencode \x00\x00 } -result "\"``` " test binary-74.8 {binary encode uuencode} -body { - binary encode uuencode \0\0\0 + binary encode uuencode \x00\x00\x00 } -result {#```` } test binary-74.9 {binary encode uuencode} -body { - binary encode uuencode \0\0\0\0 + binary encode uuencode \x00\x00\x00\x00 } -result {$`````` } test binary-74.10 {binary encode uuencode} -returnCodes error -body { @@ -2842,7 +2842,7 @@ test binary-75.4 {binary decode uuencode} -body { } -result [string repeat abc 20] test binary-75.5 {binary decode uuencode} -body { binary decode uuencode ")``\$\"`P0``0(#" -} -result "\0\1\2\3\4\0\1\2\3" +} -result "\x00\x01\x02\x03\x04\x00\x01\x02\x03" test binary-75.6 {binary decode uuencode} -body { string length [binary decode uuencode "`\n"] } -result 0 @@ -2948,18 +2948,18 @@ test binary-79.1 {Tcl_SetByteArrayLength} testsetbytearraylength { testsetbytearraylength [string cat A B C] 1 } A test binary-79.2 {Tcl_SetByteArrayLength} testsetbytearraylength { - testsetbytearraylength [string cat \u0141 B C] 1 + testsetbytearraylength [string cat Ł B C] 1 } A test binary-80.1 {TclGetBytesFromObj} -constraints testbytestring -returnCodes 1 -body { - testbytestring "\u4E4E" -} -result "expected byte sequence but character 0 was '\u4E4E' (U+004E4E)" + testbytestring "乎" +} -result "expected byte sequence but character 0 was '乎' (U+004E4E)" test binary-80.2 {TclGetBytesFromObj} -constraints testbytestring -returnCodes 1 -body { testbytestring [testbytestring "\x00\xA0\xA0\xA0\xE4\xB9\x8E"] -} -result "expected byte sequence but character 4 was '\u4E4E' (U+004E4E)" +} -result "expected byte sequence but character 4 was '乎' (U+004E4E)" test binary-80.3 {TclGetBytesFromObj} -constraints testbytestring -returnCodes 1 -body { testbytestring [testbytestring "\xC0\x80\xA0\xA0\xA0\xE4\xB9\x8E"] -} -result "expected byte sequence but character 4 was '\u4E4E' (U+004E4E)" +} -result "expected byte sequence but character 4 was '乎' (U+004E4E)" test binary-80.4 {TclGetBytesFromObj} -constraints testbytestring -returnCodes 1 -body { testbytestring [testbytestring "\xC0\x80\xA0\xA0\xA0\xF0\x9F\x98\x81"] } -result "expected byte sequence but character 4 was '\U01F601' (U+01F601)" diff --git a/tests/chan.test b/tests/chan.test index 3e65433..92846d5 100644 --- a/tests/chan.test +++ b/tests/chan.test @@ -48,10 +48,10 @@ test chan-4.1 {chan command: configure subcommand} -body { chan configure } -returnCodes error -result "wrong # args: should be \"chan configure channelId ?-option value ...?\"" test chan-4.2 {chan command: [Bug 800753]} -body { - chan configure stdout -eofchar \u0100 + chan configure stdout -eofchar Ā } -returnCodes error -match glob -result {bad value*} test chan-4.3 {chan command: [Bug 800753]} -body { - chan configure stdout -eofchar \u0000 + chan configure stdout -eofchar \x00 } -returnCodes error -match glob -result {bad value*} test chan-4.4 {chan command: check valid inValue, no outValue} -body { chan configure stdout -eofchar [list \x27 {}] diff --git a/tests/chanio.test b/tests/chanio.test index 04f0e3f..8dfefb7 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -79,7 +79,7 @@ namespace eval ::tcl::test::io { if {$argv != ""} { set f [open [lindex $argv 0]] } - chan configure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a + chan configure $f -encoding binary -translation lf -blocking 0 -eofchar \x1A chan configure stdout -encoding binary -translation lf -buffering none chan event $f readable "foo $f" proc foo {f} { @@ -115,17 +115,17 @@ set path(test1) [makeFile {} test1] test chan-io-1.6 {Tcl_WriteChars: WriteBytes} { set f [open $path(test1) w] chan configure $f -encoding binary - chan puts -nonewline $f "a\u4e4d\0" + chan puts -nonewline $f "a乍\x00" chan close $f contents $path(test1) -} "a\x4d\x00" +} "aM\x00" test chan-io-1.7 {Tcl_WriteChars: WriteChars} { set f [open $path(test1) w] chan configure $f -encoding shiftjis - chan puts -nonewline $f "a\u4e4d\0" + chan puts -nonewline $f "a乍\x00" chan close $f contents $path(test1) -} "a\x93\xe1\x00" +} "a\x93\xE1\x00" set path(test2) [makeFile {} test2] test chan-io-1.8 {Tcl_WriteChars: WriteChars} { # This test written for SF bug #506297. @@ -138,7 +138,7 @@ test chan-io-1.8 {Tcl_WriteChars: WriteChars} { chan puts -nonewline $f [format %s%c [string repeat " " 4] 12399] chan close $f contents $path(test2) -} " \x1b\$B\$O\x1b(B" +} " \x1B\$B\$O\x1B(B" test chan-io-1.9 {Tcl_WriteChars: WriteChars} { # When closing a channel with an encoding that appends escape bytes, check # for the case where the escape bytes overflow the current IO buffer. The @@ -273,13 +273,13 @@ test chan-io-3.6 {WriteChars: (stageRead + dstWrote == 0)} { # to the beginning of that UTF-8 character and try again. # # Translate the first 16 bytes, produce 14 bytes of output, 2 left over - # (first two bytes of \uff21 in UTF-8). Given those two bytes try + # (first two bytes of A in UTF-8). Given those two bytes try # translating them again, find that no bytes are read produced, and break # to outer loop where those two bytes will have the remaining 4 bytes (the - # last byte of \uff21 plus the all of \uff22) appended. + # last byte of A plus the all of B) appended. set f [open $path(test1) w] chan configure $f -encoding shiftjis -buffersize 16 - chan puts -nonewline $f "12345678901234\uff21\uff22" + chan puts -nonewline $f "12345678901234AB" set x [list [contents $path(test1)]] chan close $f lappend x [contents $path(test1)] @@ -421,7 +421,7 @@ test chan-io-6.3 {Tcl_GetsObj: how many have we used?} -body { test chan-io-6.4 {Tcl_GetsObj: encoding == NULL} -body { set f [open $path(test1) w] chan configure $f -translation binary - chan puts $f "\x81\u1234\0" + chan puts $f "\x81\u1234\x00" chan close $f set f [open $path(test1)] chan configure $f -translation binary @@ -432,14 +432,14 @@ test chan-io-6.4 {Tcl_GetsObj: encoding == NULL} -body { test chan-io-6.5 {Tcl_GetsObj: encoding != NULL} -body { set f [open $path(test1) w] chan configure $f -translation binary - chan puts $f "\x88\xea\x92\x9a" + chan puts $f "\x88\xEA\x92\x9A" chan close $f set f [open $path(test1)] chan configure $f -encoding shiftjis list [chan gets $f line] $line } -cleanup { chan close $f -} -result [list 2 "\u4e00\u4e01"] +} -result [list 2 "一丁"] set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" append a $a append a $a @@ -467,20 +467,20 @@ test chan-io-6.7 {Tcl_GetsObj: error in input} -constraints stdio -body { } -result {-1} test chan-io-6.8 {Tcl_GetsObj: remember if EOF is seen} -body { set f [open $path(test1) w] - chan puts $f "abcdef\x1aghijk\nwombat" + chan puts $f "abcdef\x1Aghijk\nwombat" chan close $f set f [open $path(test1)] - chan configure $f -eofchar \x1a + chan configure $f -eofchar \x1A list [chan gets $f line] $line [chan gets $f line] $line } -cleanup { chan close $f } -result {6 abcdef -1 {}} test chan-io-6.9 {Tcl_GetsObj: remember if EOF is seen} -body { set f [open $path(test1) w] - chan puts $f "abcdefghijk\nwom\u001abat" + chan puts $f "abcdefghijk\nwom\x1Abat" chan close $f set f [open $path(test1)] - chan configure $f -eofchar \x1a + chan configure $f -eofchar \x1A list [chan gets $f line] $line [chan gets $f line] $line } -cleanup { chan close $f @@ -865,7 +865,7 @@ test chan-io-6.43 {Tcl_GetsObj: input saw cr} -setup { chan configure $f -blocking 0 lappend x [chan gets $f line] $line [testchannel queuedcr $f] chan configure $f -blocking 1 - chan puts -nonewline $f "\nabcd\refg\x1a" + chan puts -nonewline $f "\nabcd\refg\x1A" lappend x [chan gets $f line] $line [testchannel queuedcr $f] lappend x [chan gets $f line] $line } -cleanup { @@ -883,7 +883,7 @@ test chan-io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} -setup { chan configure $f -blocking 0 lappend x [chan gets $f line] $line [testchannel queuedcr $f] chan configure $f -blocking 1 - chan puts -nonewline $f "abcd\refg\x1a" + chan puts -nonewline $f "abcd\refg\x1A" lappend x [chan gets $f line] $line [testchannel queuedcr $f] lappend x [chan gets $f line] $line } -cleanup { @@ -919,7 +919,7 @@ test chan-io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eo chan configure $f -blocking 0 lappend x [chan gets $f line] $line [testchannel queuedcr $f] chan configure $f -blocking 1 - chan puts -nonewline $f "\n\x1a" + chan puts -nonewline $f "\n\x1A" lappend x [chan gets $f line] $line [testchannel queuedcr $f] } -cleanup { chan close $f @@ -985,10 +985,10 @@ test chan-io-6.52 {Tcl_GetsObj: saw EOF character} -constraints {testchannel} -b # if (eof != NULL) set f [open $path(test1) w] chan configure $f -translation lf - chan puts -nonewline $f "123456\x1ak9012345\r" + chan puts -nonewline $f "123456\x1Ak9012345\r" chan close $f set f [open $path(test1)] - chan configure $f -eofchar \x1a + chan configure $f -eofchar \x1A list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f] } -cleanup { chan close $f @@ -1016,14 +1016,14 @@ test chan-io-6.55 {Tcl_GetsObj: overconverted} -body { # Tcl_ExternalToUtf(), make sure state updated set f [open $path(test1) w] chan configure $f -encoding iso2022-jp - chan puts $f "there\u4e00ok\n\u4e01more bytes\nhere" + chan puts $f "there一ok\n丁more bytes\nhere" chan close $f set f [open $path(test1)] chan configure $f -encoding iso2022-jp list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line } -cleanup { chan close $f -} -result [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"] +} -result [list 8 "there一ok" 11 "丁more bytes" 4 "here"] test chan-io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} -setup { update variable x {} @@ -1057,19 +1057,19 @@ test chan-io-7.1 {FilterInputBytes: split up character at end of buffer} -body { # (result == TCL_CONVERT_MULTIBYTE) set f [open $path(test1) w] chan configure $f -encoding shiftjis - chan puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend" + chan puts $f "123456789012301234\nend" chan close $f set f [open $path(test1)] chan configure $f -encoding shiftjis -buffersize 16 chan gets $f } -cleanup { chan close $f -} -result "1234567890123\uff10\uff11\uff12\uff13\uff14" +} -result "123456789012301234" test chan-io-7.2 {FilterInputBytes: split up character in middle of buffer} -body { # (bufPtr->nextAdded < bufPtr->bufLength) set f [open $path(test1) w] chan configure $f -encoding binary - chan puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82" + chan puts -nonewline $f "1234567890\n123\x82\x4F\x82\x50\x82" chan close $f set f [open $path(test1)] chan configure $f -encoding shiftjis @@ -1082,7 +1082,7 @@ test chan-io-7.3 {FilterInputBytes: split up character at EOF} -setup { } -constraints {testchannel} -body { set f [open $path(test1) w] chan configure $f -encoding binary - chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82" + chan puts -nonewline $f "1234567890123\x82\x4F\x82\x50\x82" chan close $f set f [open $path(test1)] chan configure $f -encoding shiftjis @@ -1091,13 +1091,13 @@ test chan-io-7.3 {FilterInputBytes: split up character at EOF} -setup { lappend x [chan gets $f line] $line } -cleanup { chan close $f -} -result [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""] +} -result [list 15 "123456789012301" 18 0 1 -1 ""] test chan-io-7.4 {FilterInputBytes: recover from split up character} -setup { variable x "" } -constraints {stdio fileevent} -body { set f [openpipe w+ $path(cat)] chan configure $f -encoding binary -buffering none - chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82" + chan puts -nonewline $f "1234567890123\x82\x4F\x82\x50\x82" chan configure $f -encoding shiftjis -blocking 0 chan event $f read [namespace code { lappend x [chan gets $f line] $line [chan blocked $f] @@ -1110,7 +1110,7 @@ test chan-io-7.4 {FilterInputBytes: recover from split up character} -setup { return $x } -cleanup { chan close $f -} -result [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0] +} -result [list -1 "" 1 17 "12345678901230123" 0] test chan-io-8.1 {PeekAhead: only go to device if no more cached data} -constraints {testchannel} -body { # (bufPtr->nextPtr == NULL) @@ -1205,7 +1205,7 @@ test chan-io-8.7 {PeekAhead: cleanup} -setup { chan puts -nonewline $f "abcdefghijklmno\r" # here lappend x [chan gets $f line] $line [testchannel queuedcr $f] - chan puts -nonewline $f "\x1a" + chan puts -nonewline $f "\x1A" lappend x [chan gets $f line] $line } -cleanup { chan close $f @@ -1361,22 +1361,22 @@ test chan-io-12.4 {ReadChars: split-up char} -setup { chan configure $f -encoding shiftjis vwait [namespace which -variable x] chan configure $f -encoding binary -blocking 1 - chan puts -nonewline $f "\x7b" + chan puts -nonewline $f "\x7B" after 500 ;# Give the cat process time to catch up chan configure $f -encoding shiftjis -blocking 0 vwait [namespace which -variable x] return $x } -cleanup { chan close $f -} -result [list "123456789012345" 1 "\u672c" 0] +} -result [list "123456789012345" 1 "本" 0] test chan-io-12.5 {ReadChars: chan events on partial characters} -setup { variable x {} } -constraints {stdio fileevent} -body { set path(test1) [makeFile { chan configure stdout -encoding binary -buffering none - chan gets stdin; chan puts -nonewline "\xe7" + chan gets stdin; chan puts -nonewline "\xE7" chan gets stdin; chan puts -nonewline "\x89" - chan gets stdin; chan puts -nonewline "\xa6" + chan gets stdin; chan puts -nonewline "\xA6" } test1] set f [openpipe r+ $path(test1)] chan event $f readable [namespace code { @@ -1401,7 +1401,7 @@ test chan-io-12.5 {ReadChars: chan events on partial characters} -setup { vwait [namespace which -variable x] vwait [namespace which -variable x] lappend x [catch {chan close $f} msg] $msg -} -result "{} timeout {} timeout \u7266 {} eof 0 {}" +} -result "{} timeout {} timeout 牦 {} eof 0 {}" test chan-io-13.1 {TranslateInputEOL: cr mode} -body { set f [open $path(test1) w] @@ -1530,7 +1530,7 @@ test chan-io-13.10 {TranslateInputEOL: auto mode: \n} -body { chan close $f } -result "abcd\ndef" test chan-io-13.11 {TranslateInputEOL: EOF char} -body { - # (*chanPtr->inEofChar != '\0') + # (*chanPtr->inEofChar != '\x00') set f [open $path(test1) w] chan configure $f -translation lf chan puts -nonewline $f "abcd\ndefgh" @@ -1542,7 +1542,7 @@ test chan-io-13.11 {TranslateInputEOL: EOF char} -body { chan close $f } -result "abcd\nd" test chan-io-13.12 {TranslateInputEOL: find EOF char in src} -body { - # (*chanPtr->inEofChar != '\0') + # (*chanPtr->inEofChar != '\x00') set f [open $path(test1) w] chan configure $f -translation lf chan puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n" @@ -1878,7 +1878,7 @@ test chan-io-20.2 {Tcl_CreateChannel: initial settings} -constraints {win} -body list [chan configure $f -eofchar] [chan configure $f -translation] } -cleanup { chan close $f -} -result [list [list \x1a ""] {auto crlf}] +} -result [list [list \x1A ""] {auto crlf}] test chan-io-20.3 {Tcl_CreateChannel: initial settings} -constraints {unix} -body { set f [open $path(test1) w+] list [chan configure $f -eofchar] [chan configure $f -translation] @@ -3091,10 +3091,10 @@ test chan-io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} -setup { } -body { set f [open $path(test1) w] chan configure $f -translation lf - chan puts -nonewline $f hello\nthere\nand\rhere\n\x1a + chan puts -nonewline $f hello\nthere\nand\rhere\n\x1A chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A chan read $f } -cleanup { chan close $f @@ -3107,11 +3107,11 @@ test chan-io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} -setup { file delete $path(test1) } -constraints {win} -body { set f [open $path(test1) w] - chan configure $f -eofchar \x1a -translation lf + chan configure $f -translation lf -eofchar \x1A chan puts $f hello\nthere\nand\rhere chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A chan read $f } -cleanup { chan close $f @@ -3129,7 +3129,7 @@ test chan-io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} -setup { chan puts $f $s chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A set l "" lappend l [chan gets $f] lappend l [chan gets $f] @@ -3150,7 +3150,7 @@ test chan-io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} -setup { chan puts $f $s chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A set l "" lappend l [chan gets $f] lappend l [chan gets $f] @@ -3183,7 +3183,7 @@ test chan-io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} -setup { lappend l [chan eof $f] } -cleanup { chan close $f -} -result "abc def 0 \x1aghi 0 qrs 0 {} 1" +} -result "abc def 0 \x1Aghi 0 qrs 0 {} 1" test chan-io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} -setup { file delete $path(test1) set l "" @@ -3195,7 +3195,7 @@ test chan-io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} -setup { set f [open $path(test1) r] chan configure $f -translation cr -eofchar {} set x [chan gets $f] - lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"] + lappend l [string equal $x "abc\ndef\n\x1Aghi\nqrs\n"] lappend l [chan eof $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -3213,7 +3213,7 @@ test chan-io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} -setup { set f [open $path(test1) r] chan configure $f -translation crlf -eofchar {} set x [chan gets $f] - lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"] + lappend l [string equal $x "abc\ndef\n\x1Aghi\nqrs\n"] lappend l [chan eof $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -3228,7 +3228,7 @@ test chan-io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} -setup { chan puts $f [format abc\ndef\n%cqrs\ntuv 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A list [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -3242,7 +3242,7 @@ test chan-io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} -setup { chan puts $f $c chan close $f set f [open $path(test1) r] - chan configure $f -translation lf -eofchar \x1a + chan configure $f -translation lf -eofchar \x1A list [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -3256,7 +3256,7 @@ test chan-io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} -setup { chan puts $f $c chan close $f set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A list [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -3270,7 +3270,7 @@ test chan-io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} -setup { chan puts $f $c chan close $f set f [open $path(test1) r] - chan configure $f -translation cr -eofchar \x1a + chan configure $f -translation cr -eofchar \x1A list [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -3284,7 +3284,7 @@ test chan-io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} -setup { chan puts $f $c chan close $f set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A list [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -3298,7 +3298,7 @@ test chan-io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} -setup { chan puts $f $c chan close $f set f [open $path(test1) r] - chan configure $f -translation crlf -eofchar \x1a + chan configure $f -translation crlf -eofchar \x1A list [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -3649,7 +3649,7 @@ test chan-io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} -setup { chan puts $f [format "hello\nthere\nand\rhere\n\%c" 26] chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan gets $f] @@ -3665,11 +3665,11 @@ test chan-io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} -setup { set l "" } -body { set f [open $path(test1) w] - chan configure $f -eofchar \x1a -translation lf + chan configure $f -translation lf -eofchar \x1A chan puts $f hello\nthere\nand\rhere chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan gets $f] @@ -3689,8 +3689,7 @@ test chan-io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} -setup { chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26] chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a - chan configure $f -translation auto + chan configure $f -translation auto -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -3708,7 +3707,7 @@ test chan-io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26] chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -3738,7 +3737,7 @@ test chan-io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} -setup { lappend l [chan eof $f] } -cleanup { chan close $f -} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1" +} -result "abc def 0 \x1Aqrs 0 tuv 0 {} 1" test chan-io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} -setup { file delete $path(test1) set l "" @@ -3760,7 +3759,7 @@ test chan-io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} -setup { lappend l [chan eof $f] } -cleanup { chan close $f -} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1" +} -result "abc def 0 \x1Aqrs 0 tuv 0 {} 1" test chan-io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} -setup { file delete $path(test1) set l "" @@ -3782,7 +3781,7 @@ test chan-io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} -setup { lappend l [chan eof $f] } -cleanup { chan close $f -} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1" +} -result "abc def 0 \x1Aqrs 0 tuv 0 {} 1" test chan-io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} -setup { file delete $path(test1) set l "" @@ -3792,7 +3791,7 @@ test chan-io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} -setup { chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -3810,7 +3809,7 @@ test chan-io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} -setup { chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation lf -eofchar \x1a + chan configure $f -translation lf -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -3828,7 +3827,7 @@ test chan-io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} -setup { chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -3846,7 +3845,7 @@ test chan-io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} -setup { chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation cr -eofchar \x1a + chan configure $f -translation cr -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -3864,7 +3863,7 @@ test chan-io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} -setup { chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -3882,7 +3881,7 @@ test chan-io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} -setup { chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation crlf -eofchar \x1a + chan configure $f -translation crlf -eofchar \x1A lappend l [chan gets $f] lappend l [chan gets $f] lappend l [chan eof $f] @@ -4638,12 +4637,12 @@ test chan-io-35.6 {Tcl_Eof, eof char, lf write, auto read} -setup { file delete $path(test1) } -body { set f [open $path(test1) w] - chan configure $f -translation lf -eofchar \x1a + chan configure $f -translation lf -eofchar \x1A chan puts $f abc\ndef chan close $f set s [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A list $s [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4652,12 +4651,12 @@ test chan-io-35.7 {Tcl_Eof, eof char, lf write, lf read} -setup { file delete $path(test1) } -body { set f [open $path(test1) w] - chan configure $f -translation lf -eofchar \x1a + chan configure $f -translation lf -eofchar \x1A chan puts $f abc\ndef chan close $f set s [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation lf -eofchar \x1a + chan configure $f -translation lf -eofchar \x1A list $s [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4666,12 +4665,12 @@ test chan-io-35.8 {Tcl_Eof, eof char, cr write, auto read} -setup { file delete $path(test1) } -body { set f [open $path(test1) w] - chan configure $f -translation cr -eofchar \x1a + chan configure $f -translation cr -eofchar \x1A chan puts $f abc\ndef chan close $f set s [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A list $s [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4680,12 +4679,12 @@ test chan-io-35.9 {Tcl_Eof, eof char, cr write, cr read} -setup { file delete $path(test1) } -body { set f [open $path(test1) w] - chan configure $f -translation cr -eofchar \x1a + chan configure $f -translation cr -eofchar \x1A chan puts $f abc\ndef chan close $f set s [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation cr -eofchar \x1a + chan configure $f -translation cr -eofchar \x1A list $s [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4694,12 +4693,12 @@ test chan-io-35.10 {Tcl_Eof, eof char, crlf write, auto read} -setup { file delete $path(test1) } -body { set f [open $path(test1) w] - chan configure $f -translation crlf -eofchar \x1a + chan configure $f -translation crlf -eofchar \x1A chan puts $f abc\ndef chan close $f set s [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A list $s [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4708,12 +4707,12 @@ test chan-io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} -setup { file delete $path(test1) } -body { set f [open $path(test1) w] - chan configure $f -translation crlf -eofchar \x1a + chan configure $f -translation crlf -eofchar \x1A chan puts $f abc\ndef chan close $f set s [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation crlf -eofchar \x1a + chan configure $f -translation crlf -eofchar \x1A list $s [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4727,7 +4726,7 @@ test chan-io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} -setup { chan close $f set c [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A list $c [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4741,7 +4740,7 @@ test chan-io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} -setup { chan close $f set c [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation lf -eofchar \x1a + chan configure $f -translation lf -eofchar \x1A list $c [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4755,7 +4754,7 @@ test chan-io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} -setup { chan close $f set c [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A list $c [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4769,7 +4768,7 @@ test chan-io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} -setup { chan close $f set c [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation cr -eofchar \x1a + chan configure $f -translation cr -eofchar \x1A list $c [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4783,7 +4782,7 @@ test chan-io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} -setup { chan close $f set c [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A list $c [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -4797,7 +4796,7 @@ test chan-io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} -setup { chan close $f set c [file size $path(test1)] set f [open $path(test1) r] - chan configure $f -translation crlf -eofchar \x1a + chan configure $f -translation crlf -eofchar \x1A list $c [string length [chan read $f]] [chan eof $f] } -cleanup { chan close $f @@ -5167,27 +5166,27 @@ test chan-io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup { } -body { set f [open $path(test1) w] chan configure $f -encoding {} - chan puts -nonewline $f \xe7\x89\xa6 + chan puts -nonewline $f \xE7\x89\xA6 chan close $f set f [open $path(test1) r] chan configure $f -encoding utf-8 chan read $f } -cleanup { chan close $f -} -result \u7266 +} -result 牦 test chan-io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup { file delete $path(test1) } -body { set f [open $path(test1) w] chan configure $f -encoding binary - chan puts -nonewline $f \xe7\x89\xa6 + chan puts -nonewline $f \xE7\x89\xA6 chan close $f set f [open $path(test1) r] chan configure $f -encoding utf-8 chan read $f } -cleanup { chan close $f -} -result \u7266 +} -result 牦 test chan-io-39.16 {Tcl_SetChannelOption: -encoding, errors} -setup { file delete $path(test1) set f [open $path(test1) w] @@ -5201,7 +5200,7 @@ test chan-io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_ } -constraints {stdio fileevent} -body { set f [openpipe r+ $path(cat)] chan configure $f -encoding binary - chan puts -nonewline $f "\xe7" + chan puts -nonewline $f "\xE7" chan flush $f chan configure $f -encoding utf-8 -blocking 0 chan event $f readable [namespace code { lappend x [chan read $f] }] @@ -5219,7 +5218,7 @@ test chan-io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_ return $x } -cleanup { chan close $f -} -result "{} timeout {} timeout \xe7 timeout" +} -result "{} timeout {} timeout \xE7 timeout" test chan-io-39.18 {Tcl_SetChannelOption, setting read mode independently} \ -constraints {socket} -body { proc accept {s a p} {chan close $s} @@ -5533,11 +5532,11 @@ test chan-io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} { } {{first script} {new script} {yet another} {}} test chan-io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} { set result {} - chan event $f r "first scr\0ipt" + chan event $f r "first scr\x00ipt" lappend result [string length [chan event $f readable]] - chan event $f r "new scr\0ipt" + chan event $f r "new scr\x00ipt" lappend result [string length [chan event $f readable]] - chan event $f r "yet ano\0ther" + chan event $f r "yet ano\x00ther" lappend result [string length [chan event $f readable]] chan event $f r "" lappend result [chan event $f readable] @@ -5983,7 +5982,7 @@ test chan-io-48.4 {lf write, testing readability, ^Z termination, auto read mode chan puts -nonewline $f [format "abc\ndef\n%c" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6007,7 +6006,7 @@ test chan-io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26] chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6031,7 +6030,7 @@ test chan-io-48.6 {cr write, testing readability, ^Z termination, auto read mode chan puts -nonewline $f [format "abc\ndef\n%c" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6055,7 +6054,7 @@ test chan-io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26] chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6079,7 +6078,7 @@ test chan-io-48.8 {crlf write, testing readability, ^Z termination, auto read mo chan puts -nonewline $f [format "abc\ndef\n%c" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation auto -eofchar \x1a + chan configure $f -translation auto -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6103,7 +6102,7 @@ test chan-io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26] chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation auto + chan configure $f -translation auto -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6127,7 +6126,7 @@ test chan-io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} - chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26] chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation lf + chan configure $f -translation lf -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6151,7 +6150,7 @@ test chan-io-48.11 {lf write, testing readability, ^Z termination, lf read mode} chan puts -nonewline $f [format "abc\ndef\n%c" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation lf -eofchar \x1a + chan configure $f -translation lf -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6175,7 +6174,7 @@ test chan-io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} - chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26] chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation cr + chan configure $f -translation cr -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6199,7 +6198,7 @@ test chan-io-48.13 {cr write, testing readability, ^Z termination, cr read mode} chan puts -nonewline $f [format "abc\ndef\n%c" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation cr -eofchar \x1a + chan configure $f -translation cr -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6223,7 +6222,7 @@ test chan-io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mod chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26] chan close $f set f [open $path(test1) r] - chan configure $f -eofchar \x1a -translation crlf + chan configure $f -translation crlf -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6247,7 +6246,7 @@ test chan-io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} - chan puts -nonewline $f [format "abc\ndef\n%c" 26] chan close $f set f [open $path(test1) r] - chan configure $f -translation crlf -eofchar \x1a + chan configure $f -translation crlf -eofchar \x1A chan event $f readable [namespace code { if {[chan eof $f]} { set x done @@ -6784,7 +6783,7 @@ set path(utf8-rp.txt) [makeFile {} utf8-rp.txt] # Create kyrillic file, use lf translation to avoid os eol issues set out [open $path(kyrillic.txt) w] chan configure $out -encoding koi8-r -translation lf -chan puts $out "\u0410\u0410" +chan puts $out "АА" chan close $out test chan-io-52.9 {TclCopyChannel & encodings} {fcopy} { # Copy kyrillic to UTF-8, using chan copy. @@ -6822,7 +6821,7 @@ test chan-io-52.10 {TclCopyChannel & encodings} {fcopy} { test chan-io-52.11 {TclCopyChannel & encodings} -setup { set f [open $path(utf8-fcopy.txt) w] fconfigure $f -encoding utf-8 -translation lf - puts $f "\u0410\u0410" + puts $f "АА" close $f } -constraints {fcopy} -body { # binary to encoding => the input has to be in utf-8 to make sense to the @@ -7496,7 +7495,7 @@ test chan-io-60.1 {writing illegal utf sequences} {fileevent testbytestring} { set out [open $path(script) w] chan puts $out "catch {load $::tcltestlib Tcltest}" chan puts $out { - chan puts [testbytestring \xe2] + chan puts [testbytestring \xE2] exit 1 } proc readit {pipe} { diff --git a/tests/clock.test b/tests/clock.test index 37c8066..2a53259 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -234,7 +234,7 @@ namespace eval ::testClock { Bias 300 \ StandardBias 0 \ DaylightBias -60 \ - StandardStart \x00\x00\x0b\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00 \ + StandardStart \x00\x00\x0B\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00 \ DaylightStart \x00\x00\x03\x00\x02\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00]] } @@ -36789,16 +36789,16 @@ test clock-58.1 {clock l10n - Japanese localisation} {*}{ -body { set trouble {} foreach {date jdate} { - 1872-12-31 \u897f\u66a61872\u5e7412\u670831\u65e5 - 1873-01-01 \u660e\u6cbb06\u5e7401\u670801\u65e5 - 1912-07-29 \u660e\u6cbb45\u5e7407\u670829\u65e5 - 1912-07-30 \u5927\u6b6301\u5e7407\u670830\u65e5 - 1926-12-24 \u5927\u6b6315\u5e7412\u670824\u65e5 - 1926-12-25 \u662d\u548c01\u5e7412\u670825\u65e5 - 1989-01-07 \u662d\u548c64\u5e7401\u670807\u65e5 - 1989-01-08 \u5e73\u621001\u5e7401\u670808\u65e5 - 2019-04-30 \u5e73\u621031\u5e7404\u670830\u65e5 - 2019-05-01 \u4ee4\u548c01\u5e7405\u670801\u65e5 + 1872-12-31 西暦1872年12月31日 + 1873-01-01 明治06年01月01日 + 1912-07-29 明治45年07月29日 + 1912-07-30 大正01年07月30日 + 1926-12-24 大正15年12月24日 + 1926-12-25 昭和01年12月25日 + 1989-01-07 昭和64年01月07日 + 1989-01-08 平成01年01月08日 + 2019-04-30 平成31年04月30日 + 2019-05-01 令和01年05月01日 } { set status [catch { set secs [clock scan $date \ diff --git a/tests/cmdAH.test b/tests/cmdAH.test index baa148e..5fefbeb 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -149,10 +149,10 @@ test cmdAH-2.6.2 {cd} -constraints {unix nonPortable} -setup { test cmdAH-2.6.3 {Tcl_CdObjCmd, bug #3118489} -setup { set dir [pwd] } -returnCodes error -body { - cd .\0 + cd .\x00 } -cleanup { cd $dir -} -match glob -result "couldn't change working directory to \".\0\": *" +} -match glob -result "couldn't change working directory to \".\x00\": *" test cmdAH-2.7 {Tcl_ConcatObjCmd} { concat } {} @@ -186,7 +186,7 @@ test cmdAH-4.5 {Tcl_EncodingObjCmd} -setup { set system [encoding system] } -body { encoding system jis0208 - encoding convertto \u4e4e + encoding convertto 乎 } -cleanup { encoding system $system } -result 8C @@ -194,7 +194,7 @@ test cmdAH-4.6 {Tcl_EncodingObjCmd} -setup { set system [encoding system] } -body { encoding system iso8859-1 - encoding convertto jis0208 \u4e4e + encoding convertto jis0208 乎 } -cleanup { encoding system $system } -result 8C @@ -211,7 +211,7 @@ test cmdAH-4.9 {Tcl_EncodingObjCmd} -setup { encoding convertfrom 8C } -cleanup { encoding system $system -} -result \u4e4e +} -result 乎 test cmdAH-4.10 {Tcl_EncodingObjCmd} -setup { set system [encoding system] } -body { @@ -219,7 +219,7 @@ test cmdAH-4.10 {Tcl_EncodingObjCmd} -setup { encoding convertfrom jis0208 8C } -cleanup { encoding system $system -} -result \u4e4e +} -result 乎 test cmdAH-4.11 {Tcl_EncodingObjCmd} -returnCodes error -body { encoding names foo } -result {wrong # args: should be "encoding names"} @@ -1221,7 +1221,7 @@ test cmdAH-24.9 {Tcl_FileObjCmd: mtime touch with non-ascii chars} -setup { set oldfile $file } -constraints unix -body { # introduce some non-ascii characters. - append file \u2022 + append file • file delete -force $file file rename $oldfile $file set mtime [file mtime $file] @@ -1246,7 +1246,7 @@ test cmdAH-24.11 {Tcl_FileObjCmd: mtime touch with non-ascii chars} -setup { set oldfile $file } -constraints win -body { # introduce some non-ascii characters. - append file \u2022 + append file • file delete -force $file file rename $oldfile $file set mtime [file mtime $file] diff --git a/tests/cmdIL.test b/tests/cmdIL.test index 83fe80e..063750c 100644 --- a/tests/cmdIL.test +++ b/tests/cmdIL.test @@ -151,17 +151,17 @@ test cmdIL-1.36 {lsort -stride and -index: Bug 2918962} { } } {{{b i g} 12345} {{d e m o} 34512} {{c o d e} 54321} {{b l a h} 94729}} test cmdIL-1.37 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} { - lsort -ascii [list \0 \x7f \x80 \uffff] -} [list \0 \x7f \x80 \uffff] + lsort -ascii [list \x00 \x7F \x80 \uFFFF] +} [list \x00 \x7F \x80 \uFFFF] test cmdIL-1.38 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} { - lsort -ascii -nocase [list \0 \x7f \x80 \uffff] -} [list \0 \x7f \x80 \uffff] + lsort -ascii -nocase [list \x00 \x7F \x80 \uFFFF] +} [list \x00 \x7F \x80 \uFFFF] test cmdIL-1.39 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} { - lsort -ascii [list \0 \x7f \x80 \U01ffff \uffff] -} [list \0 \x7f \x80 \uffff \U01ffff] + lsort -ascii [list \x00 \x7F \x80 \U01ffff \uFFFF] +} [list \x00 \x7F \x80 \uFFFF \U01ffff] test cmdIL-1.40 {Tcl_LsortObjCmd procedure, Bug 8e1e31eac0fd6b6c} { - lsort -ascii -nocase [list \0 \x7f \x80 \U01ffff \uffff] -} [list \0 \x7f \x80 \uffff \U01ffff] + lsort -ascii -nocase [list \x00 \x7F \x80 \U01ffff \uFFFF] +} [list \x00 \x7F \x80 \uFFFF \U01FFFF] test cmdIL-1.41 {lsort -stride and -index} -body { lsort -stride 2 -index -2 {a 2 b 1} } -returnCodes error -result {index "-2" out of range} @@ -177,7 +177,7 @@ test cmdIL-2.1 {MergeSort and MergeLists procedures} -setup { set r 1435753299 proc rand {} { global r - set r [expr {(16807 * $r) % (0x7fffffff)}] + set r [expr {(16807 * $r) % (0x7FFFFFFF)}] } } -body { for {set i 0} {$i < 150} {incr i} { @@ -396,16 +396,16 @@ test cmdIL-4.23 {DictionaryCompare procedure, case} { } {ABcd AbCd} test cmdIL-4.24 {DictionaryCompare procedure, international characters} {hasIsoLocale} { ::tcltest::set_iso8859_1_locale - set result [lsort -dictionary "a b c A B C \xe3 \xc4"] + set result [lsort -dictionary "a b c A B C ã Ä"] ::tcltest::restore_locale set result -} "A a B b C c \xe3 \xc4" +} "A a B b C c ã Ä" test cmdIL-4.25 {DictionaryCompare procedure, international characters} {hasIsoLocale} { ::tcltest::set_iso8859_1_locale - set result [lsort -dictionary "a23\xe3 a23\xc5 a23\xe4"] + set result [lsort -dictionary "a23ã a23Å a23ä"] ::tcltest::restore_locale set result -} "a23\xe3 a23\xe4 a23\xc5" +} "a23ã a23ä a23Å" test cmdIL-4.26 {DefaultCompare procedure, signed characters} { set l [lsort [list "abc\200" "abc"]] set viewlist {} @@ -472,10 +472,10 @@ test cmdIL-4.36 {SortCompare procedure, UTF-8 with -nocase option} { scan [lsort -ascii -nocase [list \u101 \u100]] %c%c%c } {257 32 256} test cmdIL-4.37 {SortCompare procedure, UTF-8 with -nocase option} { - scan [lsort -ascii -nocase [list a\u0000a a]] %c%c%c%c%c + scan [lsort -ascii -nocase [list a\x00a a]] %c%c%c%c%c } {97 32 97 0 97} test cmdIL-4.38 {SortCompare procedure, UTF-8 with -nocase option} { - scan [lsort -ascii -nocase [list a a\u0000a]] %c%c%c%c%c + scan [lsort -ascii -nocase [list a a\x00a]] %c%c%c%c%c } {97 32 97 0 97} test cmdIL-5.1 {lsort with list style index} { diff --git a/tests/cmdMZ.test b/tests/cmdMZ.test index ef9790f..a1cb6c2 100644 --- a/tests/cmdMZ.test +++ b/tests/cmdMZ.test @@ -299,19 +299,19 @@ test cmdMZ-4.10 {Tcl_SplitObjCmd: basic split commands} { } {]\n} test cmdMZ-4.11 {Tcl_SplitObjCmd: basic split commands} { apply {{} { - set x ab\000c + set x ab\x00c set y [split $x {}] binary scan $y c* z return $z }} } {97 32 98 32 0 32 99} test cmdMZ-4.12 {Tcl_SplitObjCmd: basic split commands} { - split "a0ab1b2bbb3\000c4" ab\000c + split "a0ab1b2bbb3\x00c4" ab\x00c } {{} 0 {} 1 2 {} {} 3 {} 4} test cmdMZ-4.13 {Tcl_SplitObjCmd: basic split commands} { - # if not UTF-8 aware, result is "a {} {} b qw\xe5 {} N wq" - split "a\u4e4eb qw\u5e4e\x4e wq" " \u4e4e" -} "a b qw\u5e4eN wq" + # if not UTF-8 aware, result is "a {} {} b qwå {} N wq" + split "a乎b qw幎N wq" " 乎" +} "a b qw幎N wq" # The tests for Tcl_StringObjCmd are in string.test # The tests for Tcl_SubstObjCmd are in subst.test diff --git a/tests/compExpr-old.test b/tests/compExpr-old.test index 03c5dc9..b70e65c 100644 --- a/tests/compExpr-old.test +++ b/tests/compExpr-old.test @@ -29,9 +29,9 @@ proc testIEEE {} { switch -exact -- $c { {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} { # little endian - binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xFF d \ ieeeValues(-Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xBF d \ ieeeValues(-Normal) binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \ ieeeValues(-Subnormal) @@ -41,19 +41,19 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \ ieeeValues(+Subnormal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x3F d \ ieeeValues(+Normal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x7F d \ ieeeValues(+Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF8\x7F d \ ieeeValues(NaN) set ieeeValues(littleEndian) 1 return 1 } {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} { - binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xFF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Infinity) - binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xBF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Normal) binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Subnormal) @@ -63,11 +63,11 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Subnormal) - binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x3F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Normal) - binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Infinity) - binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF8\x00\x00\x00\x00\x00\x00 d \ ieeeValues(NaN) set ieeeValues(littleEndian) 0 return 1 diff --git a/tests/compile.test b/tests/compile.test index 23d81dd..31af2e2 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -286,10 +286,10 @@ test compile-7.1 {TclCompileWhileCmd: command substituted test expression} { } {4} test compile-8.1 {CollectArgInfo: binary data} { - list [catch "string length \000foo" msg] $msg + list [catch "string length \x00foo" msg] $msg } {0 4} test compile-8.2 {CollectArgInfo: binary data} { - list [catch "string length foo\000" msg] $msg + list [catch "string length foo\x00" msg] $msg } {0 4} test compile-8.3 {CollectArgInfo: handle "]" at end of command properly} { set x ] diff --git a/tests/encoding.test b/tests/encoding.test index b1150c6..c8daed6 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -183,7 +183,7 @@ test encoding-7.2 {Tcl_UtfToExternalDString: big buffer} { test encoding-8.1 {Tcl_ExternalToUtf} { set f [open [file join [temporaryDirectory] dummy] w] fconfigure $f -translation binary -encoding iso8859-1 - puts -nonewline $f "ab\x8c\xc1g" + puts -nonewline $f "ab\x8C\xC1g" close $f set f [open [file join [temporaryDirectory] dummy] r] fconfigure $f -translation binary -encoding shiftjis @@ -219,7 +219,7 @@ test encoding-10.1 {Tcl_UtfToExternal} { close $f file delete [file join [temporaryDirectory] dummy] return $x -} "ab\x8c\xc1g" +} "ab\x8C\xC1g" proc viewable {str} { set res "" @@ -227,7 +227,7 @@ proc viewable {str} { if {[string is print $c] && [string is ascii $c]} { append res $c } else { - append res "\\u[format %4.4x [scan $c %c]]" + append res "\\u[format %4.4X [scan $c %c]]" } } return "$str ($res)" @@ -258,7 +258,7 @@ test encoding-11.5 {LoadEncodingFile: escape file} { } [viewable "\x1B\$B8C\x1B(B"] test encoding-11.5.1 {LoadEncodingFile: escape file} { viewable [encoding convertto iso2022-jp 乎] -} [viewable "\x1b\$B8C\x1b(B"] +} [viewable "\x1B\$B8C\x1B(B"] test encoding-11.6 {LoadEncodingFile: invalid file} -constraints {testencoding} -setup { set system [encoding system] set path [encoding dirs] @@ -283,24 +283,24 @@ test encoding-11.6 {LoadEncodingFile: invalid file} -constraints {testencoding} } -result {invalid encoding file "splat"} test encoding-11.8 {encoding: extended Unicode UTF-16} { viewable [encoding convertto utf-16le 😹] -} {=Ø9Þ (=\u00d89\u00de)} +} {=Ø9Þ (=\u00D89\u00DE)} test encoding-11.9 {encoding: extended Unicode UTF-16} { viewable [encoding convertto utf-16be 😹] -} {Ø=Þ9 (\u00d8=\u00de9)} +} {Ø=Þ9 (\u00D8=\u00DE9)} # OpenEncodingFile is fully tested by the rest of the tests in this file. test encoding-12.1 {LoadTableEncoding: normal encoding} { - set x [encoding convertto iso8859-3 \u0120] - append x [encoding convertto iso8859-3 \xD5] - append x [encoding convertfrom iso8859-3 \xD5] -} "\xD5?\u120" + set x [encoding convertto iso8859-3 Ġ] + append x [encoding convertto iso8859-3 Õ] + append x [encoding convertfrom iso8859-3 Õ] +} "Õ?Ġ" test encoding-12.2 {LoadTableEncoding: single-byte encoding} { - set x [encoding convertto iso8859-3 ab\u0120g] - append x [encoding convertfrom iso8859-3 ab\xD5g] -} "ab\xD5gab\u120g" + set x [encoding convertto iso8859-3 abĠg] + append x [encoding convertfrom iso8859-3 abÕg] +} "abÕgabĠg" test encoding-12.3 {LoadTableEncoding: multi-byte encoding} { set x [encoding convertto shiftjis ab乎g] - append x [encoding convertfrom shiftjis ab\x8c\xc1g] + append x [encoding convertfrom shiftjis ab\x8C\xC1g] } "ab\x8C\xC1gab乎g" test encoding-12.4 {LoadTableEncoding: double-byte encoding} { set x [encoding convertto jis0208 乎α] @@ -317,7 +317,7 @@ test encoding-13.1 {LoadEscapeTable} { } [viewable "ab\x1B\$B8C\x1B\$\(DD%\x1B(Bg"] test encoding-15.1 {UtfToUtfProc} { - encoding convertto utf-8 \xA3 + encoding convertto utf-8 £ } "\xC2\xA3" test encoding-15.2 {UtfToUtfProc null character output} testbytestring { binary scan [testbytestring [encoding convertto utf-8 \x00]] H* z @@ -351,8 +351,8 @@ test encoding-15.7 {UtfToUtfProc emoji character output} { list [string length $x] [string length $y] $z } {3 9 edb882eda0bdeda0bd} test encoding-15.8 {UtfToUtfProc emoji character output} { - set x \uDE02\uD83D\xE9 - set y [encoding convertto utf-8 \uDE02\uD83D\xE9] + 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 edb882eda0bdc3a9} @@ -363,14 +363,14 @@ test encoding-15.9 {UtfToUtfProc emoji character output} { list [string length $x] [string length $y] $z } {3 7 edb882eda0bd58} test encoding-15.10 {UtfToUtfProc high surrogate character output} { - set x \uDE02\xE9 - set y [encoding convertto utf-8 \uDE02\xE9] + 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 edb882c3a9} test encoding-15.11 {UtfToUtfProc low surrogate character output} { - set x \uDA02\xE9 - set y [encoding convertto utf-8 \uDA02\xE9] + 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 eda882c3a9} @@ -425,7 +425,7 @@ test encoding-16.3 {Utf16ToUtfProc} -body { test encoding-16.4 {Ucs2ToUtfProc} -body { set val [encoding convertfrom ucs-2 NN] list $val [format %x [scan $val %c]] -} -result "\u4E4E 4e4e" +} -result "乎 4e4e" test encoding-16.4 {Ucs2ToUtfProc} -body { set val [encoding convertfrom ucs-2 "\xD8\xD8\xDC\xDC"] list $val [format %x [scan $val %c]] @@ -459,18 +459,18 @@ test encoding-21.1 {EscapeToUtfProc} { test encoding-22.1 {EscapeFromUtfProc} { } {} -set iso2022encData "\u001b\$B;d\$I\$b\$G\$O!\"%A%C%W\$49XF~;~\$K\$4EPO?\$\$\$?\$@\$\$\$?\$4=;=j\$r%-%c%C%7%e%\"%&%H\$N:]\$N\u001b(B -\u001b\$B>.@Z.@Z> 8) | 0x80}] [expr {($code & 0xff) | 0x80}] + [expr {($code >> 8) | 0x80}] [expr {($code & 0xFF) | 0x80}] } proc gen-jisx0208-iso2022-jp {code} { binary format a3cca3 \ - "\x1b\$B" [expr {$code >> 8}] [expr {$code & 0xff}] "\x1b(B" + "\x1B\$B" [expr {$code >> 8}] [expr {$code & 0xFF}] "\x1B(B" } proc gen-jisx0208-cp932 {code} { set c1 [expr {($code >> 8) | 0x80}] set c2 [expr {($code & 0xff)| 0x80}] if {$c1 % 2} { - set c1 [expr {($c1 >> 1) + ($c1 < 0xdf ? 0x31 : 0x71)}] - incr c2 [expr {- (0x60 + ($c2 < 0xe0))}] + set c1 [expr {($c1 >> 1) + ($c1 < 0xDF ? 0x31 : 0x71)}] + incr c2 [expr {- (0x60 + ($c2 < 0xE0))}] } else { - set c1 [expr {($c1 >> 1) + ($c1 < 0xdf ? 0x30 : 0x70)}] + set c1 [expr {($c1 >> 1) + ($c1 < 0xDF ? 0x30 : 0x70)}] incr c2 -2 } binary format cc $c1 $c2 diff --git a/tests/exec.test b/tests/exec.test index 412cd4c..6e4718a 100644 --- a/tests/exec.test +++ b/tests/exec.test @@ -169,19 +169,19 @@ test exec-2.6 {redirecting input from immediate source, with UTF} -setup { encoding system iso8859-1 proc quotenonascii s { regsub -all {\[|\\|\]} $s {\\&} s - regsub -all "\[\u007f-\uffff\]" $s \ - {[apply {c {format {\u%04x} [scan $c %c]}} &]} s + regsub -all "\[\x7F-\xFF\]" $s \ + {[apply {c {format {\x%02X} [scan $c %c]}} &]} s return [subst -novariables $s] } } -constraints {exec} -body { - # If this fails, it may give back: "\uC3\uA9\uC3\uA0\uC3\uBC\uC3\uB1" + # If this fails, it may give back: "\xC3\xA9\xC3\xA0\xC3\xBC\xC3\xB1" # If it does, this means that the UTF -> external conversion did not occur # before writing out the temp file. - quotenonascii [exec [interpreter] $path(cat) << "\uE9\uE0\uFC\uF1"] + quotenonascii [exec [interpreter] $path(cat) << "\xE9\xE0\xFC\xF1"] } -cleanup { encoding system $sysenc rename quotenonascii {} -} -result {\u00e9\u00e0\u00fc\u00f1} +} -result {\xE9\xE0\xFC\xF1} # I/O redirection: output to file. diff --git a/tests/execute.test b/tests/execute.test index f22747c..d86ad0e 100644 --- a/tests/execute.test +++ b/tests/execute.test @@ -1066,7 +1066,7 @@ test execute-9.1 {Interp result resetting [Bug 1522803]} { } SUCCESS test execute-10.1 {TclExecuteByteCode, INST_CONCAT1, bytearrays} { - apply {s {binary scan $s c x; list $x [scan $s$s %c%c]}} \u0130 + apply {s {binary scan $s c x; list $x [scan $s$s %c%c]}} İ } {48 {304 304}} test execute-10.2 {Bug 2802881} -setup { interp create child diff --git a/tests/expr-old.test b/tests/expr-old.test index 50fbba7..676443a 100644 --- a/tests/expr-old.test +++ b/tests/expr-old.test @@ -35,9 +35,9 @@ proc testIEEE {} { switch -exact -- $c { {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} { # little endian - binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xFF d \ ieeeValues(-Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xBF d \ ieeeValues(-Normal) binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \ ieeeValues(-Subnormal) @@ -47,19 +47,19 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \ ieeeValues(+Subnormal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x3F d \ ieeeValues(+Normal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x7F d \ ieeeValues(+Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF8\x7F d \ ieeeValues(NaN) set ieeeValues(littleEndian) 1 return 1 } {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} { - binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xFF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Infinity) - binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xBF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Normal) binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Subnormal) @@ -69,11 +69,11 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Subnormal) - binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x3F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Normal) - binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Infinity) - binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF8\x00\x00\x00\x00\x00\x00 d \ ieeeValues(NaN) set ieeeValues(littleEndian) 0 return 1 diff --git a/tests/expr.test b/tests/expr.test index 8d2f668..32706d9 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -33,9 +33,9 @@ proc testIEEE {} { switch -exact -- $c { {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} { # little endian - binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xFF d \ ieeeValues(-Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xBF d \ ieeeValues(-Normal) binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \ ieeeValues(-Subnormal) @@ -45,21 +45,21 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \ ieeeValues(+Subnormal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x3F d \ ieeeValues(+Normal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x7F d \ ieeeValues(+Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF8\x7F d \ ieeeValues(NaN) - binary scan \x00\x00\x00\x00\x00\x00\xf8\xff d \ + binary scan \x00\x00\x00\x00\x00\x00\xF8\xFF d \ ieeeValues(-NaN) set ieeeValues(littleEndian) 1 return 1 } {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} { - binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xFF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Infinity) - binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xBF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Normal) binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Subnormal) @@ -69,13 +69,13 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Subnormal) - binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x3F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Normal) - binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Infinity) - binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF8\x00\x00\x00\x00\x00\x00 d \ ieeeValues(NaN) - binary scan \xff\xf8\x00\x00\x00\x00\x00\x00 d \ + binary scan \xFF\xF8\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-NaN) set ieeeValues(littleEndian) 0 return 1 @@ -351,7 +351,7 @@ test expr-8.11 {CompileEqualityExpr: error compiling equality arm} -body { expr 2!=x } -returnCodes error -match glob -result * test expr-8.12 {CompileBitAndExpr: equality expr} {expr {"a"eq"a"}} 1 -test expr-8.13 {CompileBitAndExpr: equality expr} {expr {"\374" eq [set s \u00fc]}} 1 +test expr-8.13 {CompileBitAndExpr: equality expr} {expr {"\374" eq [set s \xFC]}} 1 test expr-8.14 {CompileBitAndExpr: equality expr} {expr 3eq2} 0 test expr-8.15 {CompileBitAndExpr: equality expr} {expr 2.0eq2} 0 test expr-8.16 {CompileBitAndExpr: equality expr} {expr 3.2ne2.2} 1 diff --git a/tests/fCmd.test b/tests/fCmd.test index 6a909f8..d1d1930 100644 --- a/tests/fCmd.test +++ b/tests/fCmd.test @@ -271,7 +271,7 @@ test fCmd-3.14 {FileCopyRename: FileBasename fails} -setup { file mkdir td1 file rename ~_totally_bogus_user td1 } -result {user "_totally_bogus_user" doesn't exist} -test fCmd-3.15 {FileCopyRename: source[0] == '\0'} -setup { +test fCmd-3.15 {FileCopyRename: source[0] == '\x00'} -setup { cleanup } -constraints {notRoot unixOrWin} -returnCodes error -body { file mkdir td1 @@ -313,7 +313,7 @@ test fCmd-4.4 {TclFileMakeDirsCmd: Tcl_TranslateFileName fails} -setup { } -constraints {notRoot} -returnCodes error -body { file mkdir ~_totally_bogus_user } -result {user "_totally_bogus_user" doesn't exist} -test fCmd-4.5 {TclFileMakeDirsCmd: Tcl_SplitPath returns 0: *name == '\0'} -setup { +test fCmd-4.5 {TclFileMakeDirsCmd: Tcl_SplitPath returns 0: *name == '\x00'} -setup { cleanup } -constraints {notRoot} -returnCodes error -body { file mkdir "" diff --git a/tests/fileSystemEncoding.test b/tests/fileSystemEncoding.test index 848b570..c9d36d2 100644 --- a/tests/fileSystemEncoding.test +++ b/tests/fileSystemEncoding.test @@ -13,7 +13,7 @@ namespace eval ::tcl::test::fileSystemEncoding { namespace import -force ::tcltest::* } - variable fname1 \u767b\u9e1b\u9d72\u6a13 + variable fname1 登鸛鵲樓 proc autopath {} { global auto_path diff --git a/tests/format.test b/tests/format.test index 9a62193..c7a8a10 100644 --- a/tests/format.test +++ b/tests/format.test @@ -105,17 +105,17 @@ test format-2.4 {string formatting} { format "%s %s %% %c %s" abcd {This is a very long test string.} 120 x } {abcd This is a very long test string. % x x} test format-2.5 {string formatting, embedded nulls} { - format "%10s" abc\0def -} " abc\0def" + format "%10s" abc\x00def +} " abc\x00def" test format-2.6 {string formatting, international chars} { - format "%10s" abc\ufeffdef -} " abc\ufeffdef" + format "%10s" abc\uFEFFdef +} " abc\uFEFFdef" test format-2.7 {string formatting, international chars} { - format "%.5s" abc\ufeffdef -} "abc\ufeffd" + format "%.5s" abc\uFEFFdef +} "abc\uFEFFd" test format-2.8 {string formatting, international chars} { - format "foo\ufeffbar%s" baz -} "foo\ufeffbarbaz" + format "foo\uFEFFbar%s" baz +} "foo\uFEFFbarbaz" test format-2.9 {string formatting, width} { format "a%5sa" f } "a fa" @@ -148,8 +148,8 @@ test format-3.1 {Tcl_FormatObjCmd: character formatting} { format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 65 65 65 65 65 65 3 65 -4 65 } "|A|A|A|A|A | A| A|A |" test format-3.2 {Tcl_FormatObjCmd: international character formatting} { - format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 0xa2 0x4e4e 0x25a 0xc3 0xff08 0 3 0x6575 -4 0x4e4f -} "|\ua2|\u4e4e|\u25a|\uc3|\uff08 | \0| \u6575|\u4e4f |" + format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 0xA2 0x4E4E 0x25A 0xC3 0xFF08 0 3 0x6575 -4 0x4E4F +} "|¢|乎|ɚ|Ã|( | \x00| 敵|乏 |" test format-4.1 {e and f formats} {eformat} { format "%e %e %e %e" 34.2e12 68.514 -.125 -16000. .000053 diff --git a/tests/http.test b/tests/http.test index ff9fb78..2fd5af4 100644 --- a/tests/http.test +++ b/tests/http.test @@ -42,7 +42,7 @@ proc bgerror {args} { # Name resolution is often a problem on OSX; not focus of HTTP package anyway. # Also a problem on other platforms for http-4.14 (test with bad port number). set HOST localhost -set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null" +set bindata "This is binary data\x0D\x0Amore\x0Dmore\x0Amore\x00null" catch {unset data} # Ensure httpd file exists @@ -620,12 +620,12 @@ test http-5.3 {http::formatQuery} { http::formatQuery lines "line1\nline2\nline3" } {lines=line1%0D%0Aline2%0D%0Aline3} test http-5.4 {http::formatQuery} { - http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2 + http::formatQuery name1 ~bwelch name2 ¡¢¢ } {name1=~bwelch&name2=%C2%A1%C2%A2%C2%A2} test http-5.5 {http::formatQuery} { set enc [http::config -urlencoding] http::config -urlencoding iso8859-1 - set res [http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2] + set res [http::formatQuery name1 ~bwelch name2 ¡¢¢] http::config -urlencoding $enc set res } {name1=~bwelch&name2=%A1%A2%A2} @@ -650,24 +650,24 @@ test http-7.1 {http::mapReply} { test http-7.2 {http::mapReply} { # RFC 2718 specifies that we pass urlencoding on utf-8 chars by default, # so make sure this gets converted to utf-8 then urlencoded. - http::mapReply "\u2208" + http::mapReply "∈" } {%E2%88%88} test http-7.3 {http::formatQuery} -setup { set enc [http::config -urlencoding] } -returnCodes error -body { # this would be reverting to http <=2.4 behavior http::config -urlencoding "" - http::mapReply "\u2208" + http::mapReply "∈" } -cleanup { http::config -urlencoding $enc -} -result "can't read \"formMap(\u2208)\": no such element in array" +} -result "can't read \"formMap(∈)\": no such element in array" test http-7.4 {http::formatQuery} -setup { set enc [http::config -urlencoding] } -body { # this would be reverting to http <=2.4 behavior w/o errors # (unknown chars become '?') http::config -urlencoding "iso8859-1" - http::mapReply "\u2208" + http::mapReply "∈" } -cleanup { http::config -urlencoding $enc } -result {%3F} @@ -715,37 +715,37 @@ test http-idna-2.1 {puny encode: functional test} { ::tcl::idna puny encode abc } abc- test http-idna-2.2 {puny encode: functional test} { - ::tcl::idna puny encode a\u20acb\u20acc + ::tcl::idna puny encode a€b€c } abc-k50ab test http-idna-2.3 {puny encode: functional test} { ::tcl::idna puny encode ABC } ABC- test http-idna-2.4 {puny encode: functional test} { - ::tcl::idna puny encode A\u20ACB\u20ACC + ::tcl::idna puny encode A€B€C } ABC-k50ab test http-idna-2.5 {puny encode: functional test} { ::tcl::idna puny encode ABC 0 } abc- test http-idna-2.6 {puny encode: functional test} { - ::tcl::idna puny encode A\u20ACB\u20ACC 0 + ::tcl::idna puny encode A€B€C 0 } abc-k50ab test http-idna-2.7 {puny encode: functional test} { ::tcl::idna puny encode ABC 1 } ABC- test http-idna-2.8 {puny encode: functional test} { - ::tcl::idna puny encode A\u20ACB\u20ACC 1 + ::tcl::idna puny encode A€B€C 1 } ABC-k50ab test http-idna-2.9 {puny encode: functional test} { ::tcl::idna puny encode abc 0 } abc- test http-idna-2.10 {puny encode: functional test} { - ::tcl::idna puny encode a\u20ACb\u20ACc 0 + ::tcl::idna puny encode a€b€c 0 } abc-k50ab test http-idna-2.11 {puny encode: functional test} { ::tcl::idna puny encode abc 1 } ABC- test http-idna-2.12 {puny encode: functional test} { - ::tcl::idna puny encode a\u20ACb\u20ACc 1 + ::tcl::idna puny encode a€b€c 1 } ABC-k50ab test http-idna-2.13 {puny encode: edge cases} { ::tcl::idna puny encode "" @@ -875,43 +875,43 @@ test http-idna-3.1 {puny decode: functional test} { } abc test http-idna-3.2 {puny decode: functional test} { ::tcl::idna puny decode abc-k50ab -} a\u20acb\u20acc +} a€b€c test http-idna-3.3 {puny decode: functional test} { ::tcl::idna puny decode ABC- } ABC test http-idna-3.4 {puny decode: functional test} { ::tcl::idna puny decode ABC-k50ab -} A\u20ACB\u20ACC +} A€B€C test http-idna-3.5 {puny decode: functional test} { ::tcl::idna puny decode ABC-K50AB -} A\u20ACB\u20ACC +} A€B€C test http-idna-3.6 {puny decode: functional test} { ::tcl::idna puny decode abc-K50AB -} a\u20ACb\u20ACc +} a€b€c test http-idna-3.7 {puny decode: functional test} { ::tcl::idna puny decode ABC- 0 } abc test http-idna-3.8 {puny decode: functional test} { ::tcl::idna puny decode ABC-K50AB 0 -} a\u20ACb\u20ACc +} a€b€c test http-idna-3.9 {puny decode: functional test} { ::tcl::idna puny decode ABC- 1 } ABC test http-idna-3.10 {puny decode: functional test} { ::tcl::idna puny decode ABC-K50AB 1 -} A\u20ACB\u20ACC +} A€B€C test http-idna-3.11 {puny decode: functional test} { ::tcl::idna puny decode abc- 0 } abc test http-idna-3.12 {puny decode: functional test} { ::tcl::idna puny decode abc-k50ab 0 -} a\u20ACb\u20ACc +} a€b€c test http-idna-3.13 {puny decode: functional test} { ::tcl::idna puny decode abc- 1 } ABC test http-idna-3.14 {puny decode: functional test} { ::tcl::idna puny decode abc-k50ab 1 -} A\u20ACB\u20ACC +} A€B€C test http-idna-3.15 {puny decode: edge cases and errors} { # Is this case actually correct? binary encode hex [encoding convertto utf-8 [::tcl::idna puny decode abc]] @@ -1045,16 +1045,16 @@ test http-idna-4.1 {IDNA encoding} { ::tcl::idna encode abc.def } abc.def test http-idna-4.2 {IDNA encoding} { - ::tcl::idna encode a\u20acb\u20acc.def + ::tcl::idna encode a€b€c.def } xn--abc-k50ab.def test http-idna-4.3 {IDNA encoding} { - ::tcl::idna encode def.a\u20acb\u20acc + ::tcl::idna encode def.a€b€c } def.xn--abc-k50ab test http-idna-4.4 {IDNA encoding} { ::tcl::idna encode ABC.DEF } ABC.DEF test http-idna-4.5 {IDNA encoding} { - ::tcl::idna encode A\u20acB\u20acC.def + ::tcl::idna encode A€B€C.def } xn--ABC-k50ab.def test http-idna-4.6 {IDNA encoding: invalid edge case} { # Should this be an error? @@ -1084,7 +1084,7 @@ test http-idna-4.9.1 {IDNA encoding: max lengths from RFC 5890} { } {IDNA OVERLONG_PART xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c} unset overlong test http-idna-4.10 {IDNA encoding: edge cases} { - ::tcl::idna encode pass\u00e9.example.com + ::tcl::idna encode passé.example.com } xn--pass-epa.example.com test http-idna-5.1 {IDNA decoding} { diff --git a/tests/init.test b/tests/init.test index 0074625..4acad3d 100644 --- a/tests/init.test +++ b/tests/init.test @@ -155,7 +155,7 @@ foreach arg [subst -nocommands -novariables { error stack cannot be uniquely determined. foo bar "} - {argument that contains non-ASCII character, \u20ac, and which is of such great length that it will be longer than 150 bytes so it will be truncated by the Tcl C library} + {argument that contains non-ASCII character, €, and which is of such great length that it will be longer than 150 bytes so it will be truncated by the Tcl C library} }] { ;# emacs needs -> " test init-4.$count.0 {::errorInfo produced by [unknown]} -setup { diff --git a/tests/io.test b/tests/io.test index 0d75116..e0a2389 100644 --- a/tests/io.test +++ b/tests/io.test @@ -108,17 +108,17 @@ set path(test1) [makeFile {} test1] test io-1.6 {Tcl_WriteChars: WriteBytes} { set f [open $path(test1) w] fconfigure $f -encoding binary - puts -nonewline $f "a\u4e4d\0" + puts -nonewline $f "a乍\x00" close $f contents $path(test1) -} "a\x4d\x00" +} "a\x4D\x00" test io-1.7 {Tcl_WriteChars: WriteChars} { set f [open $path(test1) w] fconfigure $f -encoding shiftjis - puts -nonewline $f "a\u4e4d\0" + puts -nonewline $f "a乍\x00" close $f contents $path(test1) -} "a\x93\xe1\x00" +} "a\x93\xE1\x00" set path(test2) [makeFile {} test2] test io-1.8 {Tcl_WriteChars: WriteChars} { # This test written for SF bug #506297. @@ -132,7 +132,7 @@ test io-1.8 {Tcl_WriteChars: WriteChars} { puts -nonewline $f [format %s%c [string repeat " " 4] 12399] close $f contents $path(test2) -} " \x1b\$B\$O\x1b(B" +} " \x1B\$B\$O\x1B(B" test io-1.9 {Tcl_WriteChars: WriteChars} { # When closing a channel with an encoding that appends @@ -295,14 +295,14 @@ test io-3.6 {WriteChars: (stageRead + dstWrote == 0)} { # in src to the beginning of that UTF-8 character and try again. # # Translate the first 16 bytes, produce 14 bytes of output, 2 left over - # (first two bytes of \uff21 in UTF-8). Given those two bytes try + # (first two bytes of A in UTF-8). Given those two bytes try # translating them again, find that no bytes are read produced, and break # to outer loop where those two bytes will have the remaining 4 bytes - # (the last byte of \uff21 plus the all of \uff22) appended. + # (the last byte of A plus the all of B) appended. set f [open $path(test1) w] fconfigure $f -encoding shiftjis -buffersize 16 - puts -nonewline $f "12345678901234\uff21\uff22" + puts -nonewline $f "12345678901234AB" set x [list [contents $path(test1)]] close $f lappend x [contents $path(test1)] @@ -451,7 +451,7 @@ test io-6.3 {Tcl_GetsObj: how many have we used?} { test io-6.4 {Tcl_GetsObj: encoding == NULL} { set f [open $path(test1) w] fconfigure $f -translation binary - puts $f "\x81\u1234\0" + puts $f "\x81\u1234\x00" close $f set f [open $path(test1)] fconfigure $f -translation binary @@ -462,14 +462,14 @@ test io-6.4 {Tcl_GetsObj: encoding == NULL} { test io-6.5 {Tcl_GetsObj: encoding != NULL} { set f [open $path(test1) w] fconfigure $f -translation binary - puts $f "\x88\xea\x92\x9a" + puts $f "\x88\xEA\x92\x9A" close $f set f [open $path(test1)] fconfigure $f -encoding shiftjis set x [list [gets $f line] $line] close $f set x -} [list 2 "\u4e00\u4e01"] +} [list 2 "一丁"] set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" append a $a append a $a @@ -509,7 +509,7 @@ test io-6.8 {Tcl_GetsObj: remember if EOF is seen} { } {6 abcdef -1 {}} test io-6.9 {Tcl_GetsObj: remember if EOF is seen} { set f [open $path(test1) w] - puts $f "abcdefghijk\nwom\u001abat" + puts $f "abcdefghijk\nwom\x1Abat" close $f set f [open $path(test1)] fconfigure $f -eofchar \x1A @@ -1052,14 +1052,14 @@ test io-6.55 {Tcl_GetsObj: overconverted} { set f [open $path(test1) w] fconfigure $f -encoding iso2022-jp - puts $f "there\u4e00ok\n\u4e01more bytes\nhere" + puts $f "there一ok\n丁more bytes\nhere" close $f set f [open $path(test1)] fconfigure $f -encoding iso2022-jp set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line] close $f set x -} [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"] +} [list 8 "there一ok" 11 "丁more bytes" 4 "here"] test io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} {stdio fileevent} { update set f [open "|[list [interpreter] $path(cat)]" w+] @@ -1086,20 +1086,20 @@ test io-7.1 {FilterInputBytes: split up character at end of buffer} { set f [open $path(test1) w] fconfigure $f -encoding shiftjis - puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend" + puts $f "123456789012301234\nend" close $f set f [open $path(test1)] fconfigure $f -encoding shiftjis -buffersize 16 set x [gets $f] close $f set x -} "1234567890123\uff10\uff11\uff12\uff13\uff14" +} "123456789012301234" test io-7.2 {FilterInputBytes: split up character in middle of buffer} { # (bufPtr->nextAdded < bufPtr->bufLength) set f [open $path(test1) w] fconfigure $f -encoding binary - puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82" + puts -nonewline $f "1234567890\n123\x82\x4F\x82\x50\x82" close $f set f [open $path(test1)] fconfigure $f -encoding shiftjis @@ -1110,7 +1110,7 @@ test io-7.2 {FilterInputBytes: split up character in middle of buffer} { test io-7.3 {FilterInputBytes: split up character at EOF} {testchannel} { set f [open $path(test1) w] fconfigure $f -encoding binary - puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82" + puts -nonewline $f "1234567890123\x82\x4F\x82\x50\x82" close $f set f [open $path(test1)] fconfigure $f -encoding shiftjis @@ -1119,11 +1119,11 @@ test io-7.3 {FilterInputBytes: split up character at EOF} {testchannel} { lappend x [gets $f line] $line close $f set x -} [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""] +} [list 15 "123456789012301" 18 0 1 -1 ""] test io-7.4 {FilterInputBytes: recover from split up character} {stdio fileevent} { set f [open "|[list [interpreter] $path(cat)]" w+] fconfigure $f -encoding binary -buffering none - puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82" + puts -nonewline $f "1234567890123\x82\x4F\x82\x50\x82" fconfigure $f -encoding shiftjis -blocking 0 fileevent $f read [namespace code "ready $f"] variable x {} @@ -1138,7 +1138,7 @@ test io-7.4 {FilterInputBytes: recover from split up character} {stdio fileevent vwait [namespace which -variable x] close $f set x -} [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0] +} [list -1 "" 1 17 "12345678901230123" 0] test io-8.1 {PeekAhead: only go to device if no more cached data} {testchannel} { # (bufPtr->nextPtr == NULL) @@ -1415,19 +1415,19 @@ test io-12.4 {ReadChars: split-up char} {stdio testchannel fileevent} { fconfigure $f -encoding shiftjis vwait [namespace which -variable x] fconfigure $f -encoding binary -blocking 1 - puts -nonewline $f "\x7b" + puts -nonewline $f "\x7B" after 500 ;# Give the cat process time to catch up fconfigure $f -encoding shiftjis -blocking 0 vwait [namespace which -variable x] close $f set x -} [list "123456789012345" 1 "\u672c" 0] +} [list "123456789012345" 1 "本" 0] test io-12.5 {ReadChars: fileevents on partial characters} {stdio fileevent} { set path(test1) [makeFile { fconfigure stdout -encoding binary -buffering none - gets stdin; puts -nonewline "\xe7" + gets stdin; puts -nonewline "\xE7" gets stdin; puts -nonewline "\x89" - gets stdin; puts -nonewline "\xa6" + gets stdin; puts -nonewline "\xA6" } test1] set f [open "|[list [interpreter] $path(test1)]" r+] fileevent $f readable [namespace code { @@ -1454,7 +1454,7 @@ test io-12.5 {ReadChars: fileevents on partial characters} {stdio fileevent} { vwait [namespace which -variable x] lappend x [catch {close $f} msg] $msg set x -} "{} timeout {} timeout \u7266 {} eof 0 {}" +} "{} timeout {} timeout 牦 {} eof 0 {}" test io-12.6 {ReadChars: too many chars read} { proc driver {cmd args} { variable buffer @@ -1464,7 +1464,7 @@ test io-12.6 {ReadChars: too many chars read} { initialize { set index($chan) 0 set buffer($chan) [encoding convertto utf-8 \ - [string repeat \uBEEF 20][string repeat . 20]] + [string repeat 뻯 20][string repeat . 20]] return {initialize finalize watch read} } finalize { @@ -1497,7 +1497,7 @@ test io-12.7 {ReadChars: too many chars read [bc5b790099]} { initialize { set index($chan) 0 set buffer($chan) [encoding convertto utf-8 \ - [string repeat \uBEEF 10]....\uBEEF] + [string repeat 뻯 10]....뻯] return {initialize finalize watch read} } finalize { @@ -1524,7 +1524,7 @@ test io-12.7 {ReadChars: too many chars read [bc5b790099]} { test io-12.8 {ReadChars: multibyte chars split} { set f [open $path(test1) w] fconfigure $f -translation binary - puts -nonewline $f [string repeat a 9]\xc2\xa0 + puts -nonewline $f [string repeat a 9]\xC2\xA0 close $f set f [open $path(test1)] fconfigure $f -encoding utf-8 -buffersize 10 @@ -1535,7 +1535,7 @@ test io-12.8 {ReadChars: multibyte chars split} { test io-12.9 {ReadChars: multibyte chars split} { set f [open $path(test1) w] fconfigure $f -translation binary - puts -nonewline $f [string repeat a 9]\xc2 + puts -nonewline $f [string repeat a 9]\xC2 close $f set f [open $path(test1)] fconfigure $f -encoding utf-8 -buffersize 10 @@ -1546,7 +1546,7 @@ test io-12.9 {ReadChars: multibyte chars split} { test io-12.10 {ReadChars: multibyte chars split} { set f [open $path(test1) w] fconfigure $f -translation binary - puts -nonewline $f [string repeat a 9]\xc2 + puts -nonewline $f [string repeat a 9]\xC2 close $f set f [open $path(test1)] fconfigure $f -encoding utf-8 -buffersize 11 @@ -1732,7 +1732,7 @@ test io-13.10 {TranslateInputEOL: auto mode: \n} { set x } "abcd\ndef" test io-13.11 {TranslateInputEOL: EOF char} { - # (*chanPtr->inEofChar != '\0') + # (*chanPtr->inEofChar != '\x00') set f [open $path(test1) w] fconfigure $f -translation lf @@ -1745,7 +1745,7 @@ test io-13.11 {TranslateInputEOL: EOF char} { set x } "abcd\nd" test io-13.12 {TranslateInputEOL: find EOF char in src} { - # (*chanPtr->inEofChar != '\0') + # (*chanPtr->inEofChar != '\x00') set f [open $path(test1) w] fconfigure $f -translation lf @@ -3202,7 +3202,7 @@ test io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} { puts -nonewline $f hello\nthere\nand\rhere\n\x1A close $f set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A set c [read $f] close $f set c @@ -3214,11 +3214,11 @@ here test io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} {win} { file delete $path(test1) set f [open $path(test1) w] - fconfigure $f -eofchar \x1A -translation lf + fconfigure $f -translation lf -eofchar \x1A puts $f hello\nthere\nand\rhere close $f set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A set c [read $f] close $f set c @@ -3235,7 +3235,7 @@ test io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} { puts $f $s close $f set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A set l "" lappend l [gets $f] lappend l [gets $f] @@ -3255,7 +3255,7 @@ test io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} { puts $f $s close $f set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A set l "" lappend l [gets $f] lappend l [gets $f] @@ -3736,7 +3736,7 @@ test io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} { puts $f $s close $f set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A set l "" lappend l [gets $f] lappend l [gets $f] @@ -3751,11 +3751,11 @@ test io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} { test io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} { file delete $path(test1) set f [open $path(test1) w] - fconfigure $f -eofchar \x1A -translation lf + fconfigure $f -translation lf -eofchar \x1A puts $f hello\nthere\nand\rhere close $f set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A set l "" lappend l [gets $f] lappend l [gets $f] @@ -3775,8 +3775,7 @@ test io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} { puts $f $s close $f set f [open $path(test1) r] - fconfigure $f -eofchar \x1A - fconfigure $f -translation auto + fconfigure $f -translation auto -eofchar \x1A set l "" lappend l [gets $f] lappend l [gets $f] @@ -3794,7 +3793,7 @@ test io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} { puts $f $s close $f set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A set l "" lappend l [gets $f] lappend l [gets $f] @@ -5479,26 +5478,26 @@ test io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} { file delete $path(test1) set f [open $path(test1) w] fconfigure $f -encoding {} - puts -nonewline $f \xe7\x89\xa6 + puts -nonewline $f \xE7\x89\xA6 close $f set f [open $path(test1) r] fconfigure $f -encoding utf-8 set x [read $f] close $f set x -} \u7266 +} 牦 test io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} { file delete $path(test1) set f [open $path(test1) w] fconfigure $f -encoding binary - puts -nonewline $f \xe7\x89\xa6 + puts -nonewline $f \xE7\x89\xA6 close $f set f [open $path(test1) r] fconfigure $f -encoding utf-8 set x [read $f] close $f set x -} \u7266 +} 牦 test io-39.16 {Tcl_SetChannelOption: -encoding, errors} { file delete $path(test1) set f [open $path(test1) w] @@ -5509,7 +5508,7 @@ test io-39.16 {Tcl_SetChannelOption: -encoding, errors} { test io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} {stdio fileevent} { set f [open "|[list [interpreter] $path(cat)]" r+] fconfigure $f -encoding binary - puts -nonewline $f "\xe7" + puts -nonewline $f "\xE7" flush $f fconfigure $f -encoding utf-8 -blocking 0 variable x {} @@ -5527,7 +5526,7 @@ test io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} vwait [namespace which -variable x] close $f set x -} "{} timeout {} timeout \xe7 timeout" +} "{} timeout {} timeout \xE7 timeout" test io-39.18 {Tcl_SetChannelOption, setting read mode independently} \ {socket} { proc accept {s a p} {close $s} @@ -5830,11 +5829,11 @@ test io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} { } {{first script} {new script} {yet another} {}} test io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} { set result {} - fileevent $f r "first scr\0ipt" + fileevent $f r "first scr\x00ipt" lappend result [string length [fileevent $f readable]] - fileevent $f r "new scr\0ipt" + fileevent $f r "new scr\x00ipt" lappend result [string length [fileevent $f readable]] - fileevent $f r "yet ano\0ther" + fileevent $f r "yet ano\x00ther" lappend result [string length [fileevent $f readable]] fileevent $f r "" lappend result [fileevent $f readable] @@ -6391,7 +6390,7 @@ test io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} {file set c 0 set l "" set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A fileevent $f readable [namespace code [list consume $f]] variable x vwait [namespace which -variable x] @@ -6447,7 +6446,7 @@ test io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} {file set c 0 set l "" set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A fileevent $f readable [namespace code [list consume $f]] variable x vwait [namespace which -variable x] @@ -6503,7 +6502,7 @@ test io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} {fi set c 0 set l "" set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation auto + fconfigure $f -translation auto -eofchar \x1A fileevent $f readable [namespace code [list consume $f]] variable x vwait [namespace which -variable x] @@ -6531,7 +6530,7 @@ test io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} {filee set c 0 set l "" set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation lf + fconfigure $f -translation lf -eofchar \x1A fileevent $f readable [namespace code [list consume $f]] variable x vwait [namespace which -variable x] @@ -6587,7 +6586,7 @@ test io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} {filee set c 0 set l "" set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation cr + fconfigure $f -translation cr -eofchar \x1A fileevent $f readable [namespace code [list consume $f]] variable x vwait [namespace which -variable x] @@ -6643,7 +6642,7 @@ test io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} {f set c 0 set l "" set f [open $path(test1) r] - fconfigure $f -eofchar \x1A -translation crlf + fconfigure $f -translation crlf -eofchar \x1A fileevent $f readable [namespace code [list consume $f]] variable x vwait [namespace which -variable x] @@ -7218,7 +7217,7 @@ set path(utf8-rp.txt) [makeFile {} utf8-rp.txt] # Create kyrillic file, use lf translation to avoid os eol issues set out [open $path(kyrillic.txt) w] fconfigure $out -encoding koi8-r -translation lf -puts $out "\u0410\u0410" +puts $out "АА" close $out test io-52.9 {TclCopyChannel & encodings} {fcopy} { # Copy kyrillic to UTF-8, using fcopy. @@ -7270,7 +7269,7 @@ test io-52.10 {TclCopyChannel & encodings} {fcopy} { test io-52.11 {TclCopyChannel & encodings} -setup { set out [open $path(utf8-fcopy.txt) w] fconfigure $out -encoding utf-8 -translation lf - puts $out "\u0410\u0410" + puts $out "АА" close $out } -constraints {fcopy} -body { # binary to encoding => the input has to be @@ -8390,7 +8389,7 @@ test io-60.1 {writing illegal utf sequences} {fileevent testbytestring} { set out [open $path(script) w] puts $out "catch {load $::tcltestlib Tcltest}" puts $out { - puts [testbytestring \xe2] + puts [testbytestring \xE2] exit 1 } proc readit {pipe} { @@ -8748,7 +8747,7 @@ test io-73.5 {effect of eof on encoding end flags} -setup { read $rfd } -body { set result [eof $rfd] - puts -nonewline $wfd "more\u00c2\u00a0data" + puts -nonewline $wfd "more\xC2\xA0data" lappend result [eof $rfd] lappend result [read $rfd] lappend result [eof $rfd] @@ -8756,7 +8755,7 @@ test io-73.5 {effect of eof on encoding end flags} -setup { close $wfd close $rfd removeFile io-73.5 -} -result [list 1 1 more\u00a0data 1] +} -result [list 1 1 more\xA0data 1] test io-74.1 {[104f2885bb] improper cache validity check} -setup { set fn [makeFile {} io-74.1] diff --git a/tests/ioCmd.test b/tests/ioCmd.test index bdf162d..dbca866 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -494,14 +494,14 @@ test iocmd-12.10 {POSIX open access modes: BINARY} { } 5 test iocmd-12.11 {POSIX open access modes: BINARY} { set f [open $path(test1) {WRONLY BINARY TRUNC}] - puts $f \u0248 ;# gets truncated to \u0048 + puts $f Ɉ ;# gets truncated to H close $f set f [open $path(test1) r] fconfigure $f -translation binary set result [read -nonewline $f] close $f set result -} \u0048 +} H test iocmd-13.1 {errors in open command} { list [catch {open} msg] $msg diff --git a/tests/list.test b/tests/list.test index 4cd3a75..905a3d3 100644 --- a/tests/list.test +++ b/tests/list.test @@ -45,23 +45,23 @@ test list-1.24 {basic tests} {list} {} test list-1.25 {basic tests} {list # #} {{#} #} test list-1.26 {basic tests} {list #\{ #\{} {\#\{ #\{} test list-1.27 {basic null treatment} { - set l [list "" "\0" "\0\0"] - set e "{} \0 \0\0" + set l [list "" "\x00" "\x00\x00"] + set e "{} \x00 \x00\x00" string equal $l $e } 1 test list-1.28 {basic null treatment} { - set result "\0a\0b" + set result "\x00a\x00b" list $result [string length $result] -} "\0a\0b 4" +} "\x00a\x00b 4" test list-1.29 {basic null treatment} { - set result "\0a\0b" + set result "\x00a\x00b" set srep "$result 4" set lrep [list $result [string length $result]] string equal $srep $lrep } 1 test list-1.30 {basic null treatment} { - set l [list "\0abc" "xyz"] - set e "\0abc xyz" + set l [list "\x00abc" "xyz"] + set e "\x00abc xyz" string equal $l $e } 1 diff --git a/tests/lsearch.test b/tests/lsearch.test index 06f3ae4..7c1402d 100644 --- a/tests/lsearch.test +++ b/tests/lsearch.test @@ -102,13 +102,13 @@ test lsearch-3.7 {lsearch errors} -returnCodes error -body { } -result {-subindices cannot be used without -index option} test lsearch-4.1 {binary data} { - lsearch -exact [list foo one\000two bar] bar + lsearch -exact [list foo one\x00two bar] bar } 2 test lsearch-4.2 {binary data} { set x one append x \x00 append x two - lsearch -exact [list foo one\000two bar] $x + lsearch -exact [list foo one\x00two bar] $x } 1 # Make a sorted list diff --git a/tests/main.test b/tests/main.test index 37f87b4..2d3f63c 100644 --- a/tests/main.test +++ b/tests/main.test @@ -68,56 +68,56 @@ namespace eval ::tcl::test::main { stdio } -setup { makeFile {puts [list $argv0 $argv $tcl_interactive]} script - catch {set f [open "|[list [interpreter] script \u00c0]" r]} + catch {set f [open "|[list [interpreter] script À]" r]} } -body { read $f } -cleanup { close $f removeFile script } -result [list script [list [encoding convertfrom [encoding system] \ - [encoding convertto [encoding system] \u00c0]]] 0]\n + [encoding convertto [encoding system] À]]] 0]\n test Tcl_Main-1.4 { } -constraints { stdio } -setup { makeFile {puts [list $argv0 $argv $tcl_interactive]} script - catch {set f [open "|[list [interpreter] script \u20ac]" r]} + catch {set f [open "|[list [interpreter] script €]" r]} } -body { read $f } -cleanup { close $f removeFile script } -result [list script [list [encoding convertfrom [encoding system] \ - [encoding convertto [encoding system] \u20ac]]] 0]\n + [encoding convertto [encoding system] €]]] 0]\n test Tcl_Main-1.5 { } -constraints { stdio } -setup { - makeFile {puts [list $argv0 $argv $tcl_interactive]} \u00c0 - catch {set f [open "|[list [interpreter] \u00c0]" r]} + makeFile {puts [list $argv0 $argv $tcl_interactive]} À + catch {set f [open "|[list [interpreter] À]" r]} } -body { read $f } -cleanup { close $f - removeFile \u00c0 + removeFile À } -result [list [list [encoding convertfrom [encoding system] \ - [encoding convertto [encoding system] \u00c0]]] {} 0]\n + [encoding convertto [encoding system] À]]] {} 0]\n test Tcl_Main-1.6 { } -constraints { stdio } -setup { - makeFile {puts [list $argv0 $argv $tcl_interactive]} \u20ac - catch {set f [open "|[list [interpreter] \u20ac]" r]} + makeFile {puts [list $argv0 $argv $tcl_interactive]} € + catch {set f [open "|[list [interpreter] €]" r]} } -body { read $f } -cleanup { close $f - removeFile \u20ac + removeFile € } -result [list [list [encoding convertfrom [encoding system] \ - [encoding convertto [encoding system] \u20ac]]] {} 0]\n + [encoding convertto [encoding system] €]]] {} 0]\n test Tcl_Main-1.7 { Tcl_Main: startup script - -encoding option @@ -129,8 +129,8 @@ namespace eval ::tcl::test::main { set f [open $script w] chan configure $f -encoding utf-8 puts $f {puts [list $argv0 $argv $tcl_interactive]} - puts -nonewline $f {puts [string equal \u20ac } - puts $f "\u20ac]" + puts -nonewline $f {puts [string equal € } + puts $f "€]" close $f catch {set f [open "|[list [interpreter] -encoding utf-8 script]" r]} } -body { @@ -151,7 +151,7 @@ namespace eval ::tcl::test::main { chan configure $f -encoding utf-8 puts $f {puts [list $argv0 $argv $tcl_interactive]} puts -nonewline $f {puts [string equal \u20ac } - puts $f "\u20ac]" + puts $f "€]" close $f catch {set f [open "|[list [interpreter] -encoding ascii script]" r]} } -body { @@ -172,7 +172,7 @@ namespace eval ::tcl::test::main { chan configure $f -encoding utf-8 puts $f {puts [list $argv0 $argv $tcl_interactive]} puts -nonewline $f {puts [string equal \u20ac } - puts $f "\u20ac]" + puts $f "€]" close $f catch {set f [open "|[list [interpreter] -enc utf-8 script]" r+]} } -body { @@ -606,8 +606,8 @@ namespace eval ::tcl::test::main { catch {set f [open "|[list [interpreter]]" w+]} catch {chan configure $f -blocking 0} } -body { - type $f "chan configure stdin -eofchar \"\\032 {}\" - if 1 \{\n\032" + type $f "chan configure stdin -eofchar \"\\x1A {}\" + if 1 \{\n\x1A" variable wait chan event $f readable \ [list set [namespace which -variable wait] "child exit"] diff --git a/tests/obj.test b/tests/obj.test index a2976de..4fa8d3a 100644 --- a/tests/obj.test +++ b/tests/obj.test @@ -251,10 +251,10 @@ test obj-13.7 {SetBooleanFromAny, error converting from "empty string"} testobj } {{} 1 {expected boolean value but got ""}} test obj-13.8 {SetBooleanFromAny, unicode strings} testobj { set result "" - lappend result [teststringobj set 1 1\u7777] + lappend result [teststringobj set 1 1睷] lappend result [catch {testbooleanobj not 1} msg] lappend result $msg -} "1\u7777 1 {expected boolean value but got \"1\u7777\"}" +} "1睷 1 {expected boolean value but got \"1睷\"}" test obj-14.1 {UpdateStringOfBoolean} testobj { set result "" diff --git a/tests/parse.test b/tests/parse.test index 3bf0de9..b0c051b 100644 --- a/tests/parse.test +++ b/tests/parse.test @@ -31,7 +31,7 @@ testConstraint testevent [llength [info commands testevent]] testConstraint memory [llength [info commands memory]] test parse-1.1 {Tcl_ParseCommand procedure, computing string length} {testparser testbytestring} { - testparser [testbytestring "foo\0 bar"] -1 + testparser [testbytestring "foo\x00 bar"] -1 } {- foo 1 simple foo 1 text foo 0 {}} test parse-1.2 {Tcl_ParseCommand procedure, computing string length} testparser { testparser "foo bar" -1 @@ -300,8 +300,8 @@ test parse-6.15 {ParseTokens procedure, backslash-newline} testparser { testparser "\"b\\\nc\"" 0 } {- \"b\\\nc\" 1 word \"b\\\nc\" 3 text b 0 backslash \\\n 0 text c 0 {}} test parse-6.16 {ParseTokens procedure, backslash substitution} testparser { - testparser {\n\a\x7f} 0 -} {- {\n\a\x7f} 1 word {\n\a\x7f} 3 backslash {\n} 0 backslash {\a} 0 backslash {\x7f} 0 {}} + testparser {\n\a\x7F} 0 +} {- {\n\a\x7F} 1 word {\n\a\x7F} 3 backslash {\n} 0 backslash {\a} 0 backslash {\x7F} 0 {}} test parse-6.17 {ParseTokens procedure, null characters} {testparser testbytestring} { expr {[testparser [testbytestring "foo\0zz"] 0] eq "- [testbytestring foo\0zz] 1 word [testbytestring foo\0zz] 3 text foo 0 text [testbytestring \0] 0 text zz 0 {}" @@ -707,7 +707,7 @@ test parse-13.6 {Tcl_ParseVar memory leak} -constraints {testparsevar memory} -s } -result 0 test parse-14.1 {Tcl_ParseBraces procedure, computing string length} {testparser testbytestring} { - testparser [testbytestring "foo\0 bar"] -1 + testparser [testbytestring "foo\x00 bar"] -1 } {- foo 1 simple foo 1 text foo 0 {}} test parse-14.2 {Tcl_ParseBraces procedure, computing string length} testparser { testparser "foo bar" -1 @@ -744,7 +744,7 @@ test parse-14.12 {Tcl_ParseBraces procedure, missing close brace} testparser { } {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{xy\\\nz\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\{xy\\\\\\nz\"\ 0\"} test parse-15.1 {Tcl_ParseQuotedString procedure, computing string length} {testparser testbytestring} { - testparser [testbytestring "foo\0 bar"] -1 + testparser [testbytestring "foo\x00 bar"] -1 } {- foo 1 simple foo 1 text foo 0 {}} test parse-15.2 {Tcl_ParseQuotedString procedure, computing string length} testparser { testparser "foo bar" -1 @@ -910,10 +910,10 @@ test parse-15.54 {CommandComplete procedure} " info complete \"foo bar;# \{\" " 1 test parse-15.55 {CommandComplete procedure} testbytestring { - info complete "set x [testbytestring \0]; puts hi" + info complete "set x [testbytestring \x00]; puts hi" } 1 test parse-15.56 {CommandComplete procedure} testbytestring { - info complete "set x [testbytestring \0]; \{" + info complete "set x [testbytestring \x00]; \{" } 0 test parse-15.57 {CommandComplete procedure} { info complete "# Comment should be complete command" diff --git a/tests/parseExpr.test b/tests/parseExpr.test index 99ada39..c70c5e3 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -32,9 +32,9 @@ proc testIEEE {} { switch -exact -- $c { {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} { # little endian - binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xFF d \ ieeeValues(-Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xBF d \ ieeeValues(-Normal) binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \ ieeeValues(-Subnormal) @@ -44,19 +44,19 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \ ieeeValues(+Subnormal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x3F d \ ieeeValues(+Normal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x7F d \ ieeeValues(+Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF8\x7F d \ ieeeValues(NaN) set ieeeValues(littleEndian) 1 return 1 } {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} { - binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xFF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Infinity) - binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xBF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Normal) binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Subnormal) @@ -66,11 +66,11 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Subnormal) - binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x3F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Normal) - binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Infinity) - binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF8\x00\x00\x00\x00\x00\x00 d \ ieeeValues(NaN) set ieeeValues(littleEndian) 0 return 1 @@ -85,7 +85,7 @@ testConstraint ieeeFloatingPoint [testIEEE] ###################################################################### test parseExpr-1.1 {Tcl_ParseExpr procedure, computing string length} {testexprparser testbytestring} { - testexprparser [testbytestring "1+2\0 +3"] -1 + testexprparser [testbytestring "1+2\x00 +3"] -1 } {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}} test parseExpr-1.2 {Tcl_ParseExpr procedure, computing string length} testexprparser { testexprparser "1 + 2" -1 @@ -882,17 +882,17 @@ test parseExpr-21.36 {error messages} -body { } -returnCodes error -result {invalid character "@" in expression "...fghijklmnopqrstuvwxyz"@"abcdefghijklmnopqrstu..."} test parseExpr-21.37 {error messages} -body { - expr [format {"%s" @ 0} [string repeat \u00a7 25]] + expr [format {"%s" @ 0} [string repeat \xA7 25]] } -returnCodes error -result [format {invalid character "@" -in expression "...%s" @ 0"} [string repeat \u00a7 10]] +in expression "...%s" @ 0"} [string repeat \xA7 10]] test parseExpr-21.38 {error messages} -body { - expr [format {0 @ "%s"} [string repeat \u00a7 25]] + expr [format {0 @ "%s"} [string repeat \xA7 25]] } -returnCodes error -result [format {invalid character "@" -in expression "0 @ "%s..."} [string repeat \u00a7 10]] +in expression "0 @ "%s..."} [string repeat \xA7 10]] test parseExpr-21.39 {error messages} -body { - expr [format {"%s" @ "%s"} [string repeat \u00a7 25] [string repeat \u00a7 25]] + expr [format {"%s" @ "%s"} [string repeat \xA7 25] [string repeat \xA7 25]] } -returnCodes error -result [format {invalid character "@" -in expression "...%s" @ "%s..."} [string repeat \u00a7 10] [string repeat \u00a7 10]] +in expression "...%s" @ "%s..."} [string repeat \xA7 10] [string repeat \xA7 10]] test parseExpr-21.40 {error messages} -body { catch {expr {"abcdefghijklmnopqrstuvwxyz"@0}} m o dict get $o -errorinfo @@ -902,13 +902,13 @@ in expression "...fghijklmnopqrstuvwxyz"@0" invoked from within "expr {"abcdefghijklmnopqrstuvwxyz"@0}"} test parseExpr-21.41 {error messages} -body { - catch {expr [format {"%s" @ 0} [string repeat \u00a7 25]]} m o + catch {expr [format {"%s" @ 0} [string repeat \xA7 25]]} m o dict get $o -errorinfo } -result [format {invalid character "@" in expression "...%s" @ 0" (parsing expression ""%s...") invoked from within -"expr [format {"%%s" @ 0} [string repeat \u00a7 25]]"} [string repeat \u00a7 10] [string repeat \u00a7 10]] +"expr [format {"%%s" @ 0} [string repeat \xA7 25]]"} [string repeat \xA7 10] [string repeat \xA7 10]] test parseExpr-21.42 {error message} -body { expr {123456789012345678901234567890*"abcdefghijklmnopqrstuvwxyz} } -returnCodes error -result {missing " @@ -1066,13 +1066,13 @@ test parseExpr-22.18 {Bug 3401704} -constraints testexprparser -body { } -result {TCL PARSE EXPR BADNUMBER BINARY} test parseExpr-22.19 {Bug d2ffcca163} -constraints testexprparser -body { - testexprparser \u0433 -1 + testexprparser г -1 } -returnCodes error -match glob -result {*invalid character*} test parseExpr-22.20 {Bug d2ffcca163} -constraints testexprparser -body { - testexprparser \u043f -1 + testexprparser п -1 } -returnCodes error -match glob -result {*invalid character*} test parseExpr-22.21 {Bug d2ffcca163} -constraints testexprparser -body { - testexprparser in\u0433(0) -1 + testexprparser inг(0) -1 } -returnCodes error -match glob -result {missing operand*} test parseExpr-23.1 {TIP 582: comments} -constraints testexprparser -body { diff --git a/tests/parseOld.test b/tests/parseOld.test index f8caf24..853f5b5 100644 --- a/tests/parseOld.test +++ b/tests/parseOld.test @@ -264,14 +264,14 @@ test parseOld-7.10 {backslash substitution} { test parseOld-7.11 {backslash substitution} { eval "list a \"b c\"\\\nd e" } {a {b c} d e} -test parseOld-7.12 {backslash substitution} testbytestring { - expr {[list \ua2] eq [testbytestring "\xc2\xa2"]} +test parseOld-7.12 {backslash substitution} { + expr {[list \uA2] eq "¢"} } 1 -test parseOld-7.13 {backslash substitution} testbytestring { - expr {[list \u4e21] eq [testbytestring "\xe4\xb8\xa1"]} +test parseOld-7.13 {backslash substitution} { + expr {[list \u4E21] eq "両"} } 1 -test parseOld-7.14 {backslash substitution} testbytestring { - expr {[list \u4e2k] eq [testbytestring "\xd3\xa2k"]} +test parseOld-7.14 {backslash substitution} { + expr {[list \u4E2k] eq "Ӣk"} } 1 # Semi-colon. diff --git a/tests/reg.test b/tests/reg.test index 5ebc2f9..b6198d8 100644 --- a/tests/reg.test +++ b/tests/reg.test @@ -514,8 +514,8 @@ expectMatch 9.40 eE {a[\\]b} "a\\b" "a\\b" expectMatch 9.41 bE {a[\\]b} "a\\b" "a\\b" expectError 9.42 - {a[\Z]b} EESCAPE expectMatch 9.43 & {a[[b]c} "a\[c" "a\[c" -expectMatch 9.44 EMP* {a[\u00fe-\u0507][\u00ff-\u0300]b} \ - "a\u0102\u02ffb" "a\u0102\u02ffb" +expectMatch 9.44 EMP* {a[\xFE-\u0507][\xFF-\u0300]b} \ + "a\u0102\u02FFb" "a\u0102\u02FFb" doing 10 "anchors and newlines" @@ -643,8 +643,8 @@ expectMatch 13.29 P "a\\U0001234x" "a\u1234x" "a\u1234x" expectMatch 13.30 P {a\U0001234x} "a\u1234x" "a\u1234x" expectMatch 13.31 P "a\\U000012345x" "a\u12345x" "a\u12345x" expectMatch 13.32 P {a\U000012345x} "a\u12345x" "a\u12345x" -expectMatch 13.33 P "a\\U1000000x" "a\ufffd0x" "a\ufffd0x" -expectMatch 13.34 P {a\U1000000x} "a\ufffd0x" "a\ufffd0x" +expectMatch 13.33 P "a\\U1000000x" "a\uFFFD0x" "a\uFFFD0x" +expectMatch 13.34 P {a\U1000000x} "a\uFFFD0x" "a\uFFFD0x" doing 14 "back references" diff --git a/tests/regexp.test b/tests/regexp.test index 842789e..e788b7f 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -54,8 +54,8 @@ test regexp-1.6 {basic regexp operation} { } {0 1} test regexp-1.7 {regexp utf compliance} { # if not UTF-8 aware, result is "0 1" - set foo "\u4e4eb q" - regexp "\u4e4eb q" "a\u4e4eb qw\u5e4e\x4e wq" bar + set foo "乎b q" + regexp "乎b q" "a乎b qw幎N wq" bar list [string compare $foo $bar] [regexp 4 $bar] } {0 0} test regexp-1.8 {regexp ***= metasyntax} { @@ -194,14 +194,14 @@ test regexp-3.7 {getting substrings back from regexp} { } {1 {1 2} {1 1} {-1 -1} {2 2}} test regexp-3.8a {-indices by multi-byte utf-8} { regexp -inline -indices {(\w+)-(\w+)} \ - "gr\u00FC\u00DF-\u043F\u0440\u0438\u0432\u0435\u0442" + "grüß-привет" } {{0 10} {0 3} {5 10}} test regexp-3.8b {-indices by multi-byte utf-8, from -start position} { list\ [regexp -inline -indices -start 3 {(\w+)-(\w+)} \ - "gr\u00FC\u00DF-\u043F\u0440\u0438\u0432\u0435\u0442"] \ + "grüß-привет"] \ [regexp -inline -indices -start 4 {(\w+)-(\w+)} \ - "gr\u00FC\u00DF-\u043F\u0440\u0438\u0432\u0435\u0442"] + "grüß-привет"] } {{{3 10} {3 3} {5 10}} {}} test regexp-4.1 {-nocase option to regexp} { @@ -352,8 +352,8 @@ test regexp-7.16 {basic regsub operation} { } {0 {}} test regexp-7.17 {regsub utf compliance} { # if not UTF-8 aware, result is "0 1" - set foo "xyz555ijka\u4e4ebpqr" - regsub a\u4e4eb xyza\u4e4ebijka\u4e4ebpqr 555 bar + set foo "xyz555ijka乎bpqr" + regsub a乎b xyza乎bijka乎bpqr 555 bar list [string compare $foo $bar] [regexp 4 $bar] } {0 0} test regexp-7.18 {basic regsub replacement} { diff --git a/tests/regexpComp.test b/tests/regexpComp.test index 4dfc2e6..76e708d 100644 --- a/tests/regexpComp.test +++ b/tests/regexpComp.test @@ -62,8 +62,8 @@ test regexpComp-1.6 {basic regexp operation} { test regexpComp-1.7 {regexp utf compliance} { # if not UTF-8 aware, result is "0 1" evalInProc { - set foo "\u4e4eb q" - regexp "\u4e4eb q" "a\u4e4eb qw\u5e4e\x4e wq" bar + set foo "乎b q" + regexp "乎b q" "a乎b qw幎N wq" bar list [string compare $foo $bar] [regexp 4 $bar] } } {0 0} @@ -447,8 +447,8 @@ test regexpComp-7.16 {basic regsub operation} { test regexpComp-7.17 {regsub utf compliance} { evalInProc { # if not UTF-8 aware, result is "0 1" - set foo "xyz555ijka\u4e4ebpqr" - regsub a\u4e4eb xyza\u4e4ebijka\u4e4ebpqr 555 bar + set foo "xyz555ijka乎bpqr" + regsub a乎b xyza乎bijka乎bpqr 555 bar list [string compare $foo $bar] [regexp 4 $bar] } } {0 0} diff --git a/tests/scan.test b/tests/scan.test index c125080..c6e7922 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -32,9 +32,9 @@ proc testIEEE {} { switch -exact -- $c { {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} { # little endian - binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xFF d \ ieeeValues(-Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xBF d \ ieeeValues(-Normal) binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \ ieeeValues(-Subnormal) @@ -44,19 +44,19 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \ ieeeValues(+Subnormal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x3F d \ ieeeValues(+Normal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x7F d \ ieeeValues(+Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF8\x7F d \ ieeeValues(NaN) set ieeeValues(littleEndian) 1 return 1 } {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} { - binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xFF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Infinity) - binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xBF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Normal) binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Subnormal) @@ -66,11 +66,11 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Subnormal) - binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x3F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Normal) - binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Infinity) - binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF8\x00\x00\x00\x00\x00\x00 d \ ieeeValues(NaN) set ieeeValues(littleEndian) 0 return 1 @@ -639,18 +639,18 @@ test scan-7.5 {string and character scanning} -setup { test scan-7.6 {string and character scanning, unicode} -setup { set a {}; set b {}; set c {}; set d {} } -body { - list [scan "abc d\u00c7fghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d -} -result "4 abc d\u00c7f ghijk dum" + list [scan "abc dÇfghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d +} -result "4 abc dÇf ghijk dum" test scan-7.7 {string and character scanning, unicode} -setup { set a {}; set b {} } -body { - list [scan "ab\u00c7cdef" "ab%c%c" a b] $a $b + list [scan "abÇcdef" "ab%c%c" a b] $a $b } -result "2 199 99" test scan-7.8 {string and character scanning, unicode} -setup { set a {}; set b {} } -body { - list [scan "ab\ufeffdef" "%\[ab\ufeff\]" a] $a -} -result "1 ab\ufeff" + list [scan "ab\uFEFFdef" "%\[ab\uFEFF\]" a] $a +} -result "1 ab\uFEFF" test scan-8.1 {error conditions} -body { scan a diff --git a/tests/source.test b/tests/source.test index 47f1486..eee03ec 100644 --- a/tests/source.test +++ b/tests/source.test @@ -111,7 +111,7 @@ test source-2.7 {utf-8 with BOM} -setup { } -body { set out [open $sourcefile w] fconfigure $out -encoding utf-8 - puts $out "\ufeffset y new-y" + puts $out "\uFEFFset y new-y" close $out set y old-y source -encoding utf-8 $sourcefile @@ -199,7 +199,7 @@ test source-4.1 {continuation line parsing} -setup { test source-6.1 {source is binary ok} -setup { # Note [makeFile] writes in the system encoding. # [source] defaults to reading in the system encoding. - set sourcefile [makeFile [list set x "a b\0c"] source.file] + set sourcefile [makeFile [list set x "a b\x00c"] source.file] } -body { set x {} source $sourcefile @@ -208,7 +208,7 @@ test source-6.1 {source is binary ok} -setup { removeFile source.file } -result 5 test source-6.2 {source skips everything after Ctrl-Z: Bug 2040} -setup { - set sourcefile [makeFile "set x ab\32c" source.file] + set sourcefile [makeFile "set x ab\x1Ac" source.file] } -body { set x {} source $sourcefile @@ -222,7 +222,7 @@ test source-7.1 {source -encoding test} -setup { file delete $sourcefile set f [open $sourcefile w] fconfigure $f -encoding utf-8 - puts $f "set symbol(square-root) \u221A; set x correct" + puts $f "set symbol(square-root) √; set x correct" close $f } -body { set x unset @@ -233,15 +233,15 @@ test source-7.1 {source -encoding test} -setup { } -result correct test source-7.2 {source -encoding test} -setup { # This tests for bad interactions between [source -encoding] - # and use of the Control-Z character (\u001A) as a cross-platform + # and use of the Control-Z character (\x1A) as a cross-platform # EOF character by [source]. Here we write out and the [source] a - # file that contains the byte \x1A, although not the character \u001A in + # file that contains the byte \x1A, although not the character \x1A in # the indicated encoding. set sourcefile [makeFile {} source.file] file delete $sourcefile set f [open $sourcefile w] fconfigure $f -encoding utf-16 - puts $f "set symbol(square-root) \u221A; set x correct" + puts $f "set symbol(square-root) √; set x correct" close $f } -body { set x unset @@ -266,25 +266,25 @@ test source-7.5 {source -encoding: correct operation} -setup { file delete $sourcefile set f [open $sourcefile w] fconfigure $f -encoding utf-8 - puts $f "proc \u20ac {} {return foo}" + puts $f "proc € {} {return foo}" close $f } -body { source -encoding utf-8 $sourcefile - \u20ac + € } -cleanup { removeFile source.file - rename \u20ac {} + rename € {} } -result foo test source-7.6 {source -encoding: mismatch encoding error} -setup { set sourcefile [makeFile {} source.file] file delete $sourcefile set f [open $sourcefile w] fconfigure $f -encoding utf-8 - puts $f "proc \u20ac {} {return foo}" + puts $f "proc € {} {return foo}" close $f } -body { source -encoding ascii $sourcefile - \u20ac + € } -cleanup { removeFile source.file } -returnCodes error -match glob -result {invalid command name*} diff --git a/tests/split.test b/tests/split.test index 74879cf..a34c49d 100644 --- a/tests/split.test +++ b/tests/split.test @@ -49,20 +49,20 @@ test split-1.8 {basic split commands} { } {]\n} test split-1.9 {basic split commands} { proc foo {} { - set x ab\000c + set x ab\x00c set y [split $x {}] return $y } foo -} "a b \000 c" +} "a b \x00 c" test split-1.10 {basic split commands} { - split "a0ab1b2bbb3\000c4" ab\000c + split "a0ab1b2bbb3\x00c4" ab\x00c } {{} 0 {} 1 2 {} {} 3 {} 4} test split-1.11 {basic split commands} { split "12,3,45" {,} } {12 3 45} test split-1.12 {basic split commands} { - split "\u0001ab\u0001cd\u0001\u0001ef\u0001" \1 + split "\x01ab\x01cd\x01\x01ef\x01" \x01 } {{} ab cd {} ef {}} test split-1.13 {basic split commands} { split "12,34,56," {,} @@ -71,10 +71,10 @@ test split-1.14 {basic split commands} { split ",12,,,34,56," {,} } {{} 12 {} {} 34 56 {}} test split-1.15 {basic split commands} -body { - split "a\U1F4A9b" {} -} -result "a \U1F4A9 b" + split "a💩b" {} +} -result "a 💩 b" test split-1.16 {basic split commands} -body { - split "a\U1F4A9b" \U1F4A9 + split "a💩b" 💩 } -result "a b" test split-2.1 {split errors} { diff --git a/tests/string.test b/tests/string.test index 0eaa3da..b55a497 100644 --- a/tests/string.test +++ b/tests/string.test @@ -119,16 +119,16 @@ test string-2.10.$noComp {string compare with special index} { list [catch {run {string compare -length end-3 abcde abxyz}} msg] $msg } {1 {expected integer but got "end-3"}} test string-2.11.$noComp {string compare, unicode} { - run {string compare ab\u7266 ab\u7267} + run {string compare ab牦 ab牧} } -1 test string-2.11.1.$noComp {string compare, unicode} { - run {string compare \334 \xDC} + run {string compare Ü Ü} } 0 test string-2.11.2.$noComp {string compare, unicode} { - run {string compare \334 \xFC} + run {string compare Ü ü} } -1 test string-2.11.3.$noComp {string compare, unicode} { - run {string compare \334\334\334\374\374 \334\334\334\334\334} + run {string compare ÜÜÜüü ÜÜÜÜÜ} } 1 test string-2.12.$noComp {string compare, high bit} { # This test will fail if the underlying comparison @@ -152,10 +152,10 @@ test string-2.15.$noComp {string compare -nocase} { run {string compare -nocase abcde abcde} } 0 test string-2.15.1.$noComp {string compare -nocase} { - run {string compare -nocase \334 \xDC} + run {string compare -nocase Ü Ü} } 0 test string-2.15.2.$noComp {string compare -nocase} { - run {string compare -nocase \334\334\334\374\xFC \334\334\334\334\334} + run {string compare -nocase ÜÜÜüü ÜÜÜÜÜ} } 0 test string-2.16.$noComp {string compare -nocase with length} { run {string compare -length 2 -nocase abcde Abxyz} @@ -172,7 +172,7 @@ test string-2.19.$noComp {string compare -nocase with excessive length} { test string-2.20.$noComp {string compare -len unicode} { # These are strings that are 6 BYTELENGTH long, but the length # shouldn't make a different because there are actually 3 CHARS long - run {string compare -len 5 \334\334\334 \334\334\374} + run {string compare -len 5 ÜÜÜ ÜÜü} } -1 test string-2.21.$noComp {string compare -nocase with special index} { list [catch {run {string compare -nocase -length end-3 Abcde abxyz}} msg] $msg @@ -237,7 +237,7 @@ test string-3.3.$noComp {string equal} { run {string equal abcde abcde} } 1 test string-3.4.$noComp {string equal -nocase} { - run {string equal -nocase \334\334\334\334\374\374\374\374 \334\334\334\334\334\334\334\334} + run {string equal -nocase ÜÜÜÜüüüü ÜÜÜÜÜÜÜÜ} } 1 test string-3.5.$noComp {string equal -nocase} { run {string equal -nocase abcde abdef} @@ -274,19 +274,19 @@ test string-3.15.$noComp {string equal with special index} { } {1 {expected integer but got "end-3"}} test string-3.16.$noComp {string equal, unicode} { - run {string equal ab\u7266 ab\u7267} + run {string equal ab牦 ab牧} } 0 test string-3.17.$noComp {string equal, unicode} { - run {string equal \334 \xDC} + run {string equal Ü Ü} } 1 test string-3.18.$noComp {string equal, unicode} { - run {string equal \334 \xFC} + run {string equal Ü ü} } 0 test string-3.19.$noComp {string equal, unicode} { - run {string equal \334\334\334\374\374 \334\334\334\334\334} + run {string equal ÜÜÜüü ÜÜÜÜÜ} } 0 test string-3.20.$noComp {string equal, high bit} { - # This test will fail if the underlying comparaison + # This test will fail if the underlying comparison # is using signed chars instead of unsigned chars. # (like SunOS's default memcmp thus the compat/memcmp.c) run {string equal "\x80" "@"} @@ -298,10 +298,10 @@ test string-3.21.$noComp {string equal -nocase} { run {string equal -nocase abcde Abdef} } 0 test string-3.22.$noComp {string equal, -nocase unicode} { - run {string equal -nocase \334 \xDC} + run {string equal -nocase Ü Ü} } 1 test string-3.23.$noComp {string equal, -nocase unicode} { - run {string equal -nocase \334\334\334\374\xFC \334\334\334\334\334} + run {string equal -nocase ÜÜÜüü ÜÜÜÜÜ} } 1 test string-3.24.$noComp {string equal -nocase with length} { run {string equal -length 2 -nocase abcde Abxyz} @@ -318,7 +318,7 @@ test string-3.27.$noComp {string equal -nocase with excessive length} { test string-3.28.$noComp {string equal -len unicode} { # These are strings that are 6 BYTELENGTH long, but the length # shouldn't make a different because there are actually 3 CHARS long - run {string equal -len 5 \334\334\334 \334\334\374} + run {string equal -len 5 ÜÜÜ ÜÜü} } 0 test string-3.29.$noComp {string equal -nocase with special index} { list [catch {run {string equal -nocase -length end-3 Abcde abxyz}} msg] $msg @@ -391,19 +391,19 @@ test string-4.8.$noComp {string first} { run {string first "" x123xx345xxx789xxx012} } -1 test string-4.9.$noComp {string first, unicode} { - run {string first x abc\u7266x} + run {string first x abc牦x} } 4 test string-4.10.$noComp {string first, unicode} { - run {string first \u7266 abc\u7266x} + run {string first 牦 abc牦x} } 3 test string-4.11.$noComp {string first, start index} { - run {string first \u7266 abc\u7266x 3} + run {string first 牦 abc牦x 3} } 3 test string-4.12.$noComp {string first, start index} -body { - run {string first \u7266 abc\u7266x 4} + run {string first 牦 abc牦x 4} } -result -1 test string-4.13.$noComp {string first, start index} -body { - run {string first \u7266 abc\u7266x end-2} + run {string first 牦 abc牦x end-2} } -result 3 test string-4.14.$noComp {string first, negative start index} -body { run {string first b abc -1} @@ -412,7 +412,7 @@ test string-4.15.$noComp {string first, ability to two-byte encoded utf-8 chars} # Test for a bug in Tcl 8.3 where test for all-single-byte-encoded # strings was incorrect, leading to an index returned by [string first] # which pointed past the end of the string. - set uchar \u057E ;# character with two-byte encoding in utf-8 + set uchar վ ;# character with two-byte encoding in utf-8 run {string first % %#$uchar$uchar#$uchar$uchar#% 3} } -result 8 test string-4.16.$noComp {string first, normal string vs pure unicode string} -body { @@ -469,13 +469,13 @@ test string-5.9.$noComp {string index} { run {string index abc end-1} } b test string-5.10.$noComp {string index, unicode} { - run {string index abc\u7266d 4} + run {string index abc牦d 4} } d test string-5.11.$noComp {string index, unicode} { - run {string index abc\u7266d 3} -} \u7266 + run {string index abc牦d 3} +} 牦 test string-5.12.$noComp {string index, unicode over char length, under byte length} -body { - run {string index \334\374\334\374 6} + run {string index ÜüÜü 6} } -result {} test string-5.13.$noComp {string index, bytearray object} { run {string index [binary format a5 fuz] 0} @@ -551,7 +551,7 @@ test string-6.12.$noComp {string is alnum, true} { test string-6.13.$noComp {string is alnum, false} { list [run {string is alnum -failindex var abc1.23}] $var } {0 4} -test string-6.14.$noComp {string is alnum, unicode} "run {string is alnum abc\xFC}" 1 +test string-6.14.$noComp {string is alnum, unicode} "run {string is alnum abcü}" 1 test string-6.15.$noComp {string is alpha, true} { run {string is alpha abc} } 1 @@ -559,7 +559,7 @@ test string-6.16.$noComp {string is alpha, false} { list [run {string is alpha -fail var a1bcde}] $var } {0 1} test string-6.17.$noComp {string is alpha, unicode} { - run {string is alpha abc\374} + run {string is alpha abcü} } 1 test string-6.18.$noComp {string is ascii, true} { run {string is ascii abc\x7Fend\x00} @@ -583,7 +583,7 @@ test string-6.24.$noComp {string is digit, true} { run {string is digit 0123456789} } 1 test string-6.25.$noComp {string is digit, false} { - list [run {string is digit -fail var 0123\xDC567}] $var + list [run {string is digit -fail var 0123Ü567}] $var } {0 4} test string-6.26.$noComp {string is digit, false} { list [run {string is digit -fail var +123567}] $var @@ -706,7 +706,7 @@ test string-6.60.$noComp {string is lower, true} { run {string is lower abc} } 1 test string-6.61.$noComp {string is lower, unicode true} { - run {string is lower abc\xFCue} + run {string is lower abcüue} } 1 test string-6.62.$noComp {string is lower, false} { list [run {string is lower -fail var aBc}] $var @@ -715,7 +715,7 @@ test string-6.63.$noComp {string is lower, false} { list [run {string is lower -fail var abc1}] $var } {0 3} test string-6.64.$noComp {string is lower, unicode false} { - list [run {string is lower -fail var ab\xDCUE}] $var + list [run {string is lower -fail var abÜUE}] $var } {0 2} test string-6.65.$noComp {string is space, true} { run {string is space " \t\n\v\f"} @@ -753,7 +753,7 @@ test string-6.75.$noComp {string is upper, true} { run {string is upper ABC} } 1 test string-6.76.$noComp {string is upper, unicode true} { - run {string is upper ABC\xDCUE} + run {string is upper ABCÜUE} } 1 test string-6.77.$noComp {string is upper, false} { list [run {string is upper -fail var AbC}] $var @@ -762,13 +762,13 @@ test string-6.78.$noComp {string is upper, false} { list [run {string is upper -fail var AB2C}] $var } {0 2} test string-6.79.$noComp {string is upper, unicode false} { - list [run {string is upper -fail var ABC\xFCue}] $var + list [run {string is upper -fail var ABCüue}] $var } {0 3} test string-6.80.$noComp {string is wordchar, true} { run {string is wordchar abc_123} } 1 test string-6.81.$noComp {string is wordchar, unicode true} { - run {string is wordchar abc\xFCab\xDCAB\u5001\U1D7CA} + run {string is wordchar abcüabÜAB倁\U1D7CA} } 1 test string-6.82.$noComp {string is wordchar, false} { list [run {string is wordchar -fail var abcd.ef}] $var @@ -981,22 +981,22 @@ test string-7.6.$noComp {string last} { run {string las x xxxx123xx345x678} } 12 test string-7.7.$noComp {string last, unicode} { - run {string las x xxxx12\u7266xx345x678} + run {string las x xxxx12牦xx345x678} } 12 test string-7.8.$noComp {string last, unicode} { - run {string las \u7266 xxxx12\u7266xx345x678} + run {string las 牦 xxxx12牦xx345x678} } 6 test string-7.9.$noComp {string last, stop index} { - run {string las \u7266 xxxx12\u7266xx345x678} + run {string las 牦 xxxx12牦xx345x678} } 6 test string-7.10.$noComp {string last, unicode} { - run {string las \u7266 xxxx12\u7266xx345x678} + run {string las 牦 xxxx12牦xx345x678} } 6 test string-7.11.$noComp {string last, start index} { - run {string last \u7266 abc\u7266x 3} + run {string last 牦 abc牦x 3} } 3 test string-7.12.$noComp {string last, start index} { - run {string last \u7266 abc\u7266x 2} + run {string last 牦 abc牦x 2} } -1 test string-7.13.$noComp {string last, start index} { ## Constrain to last 'a' should work @@ -1007,10 +1007,10 @@ test string-7.14.$noComp {string last, start index} { run {string last ba badbad end-2} } 0 test string-7.15.$noComp {string last, start index} { - run {string last \334a \334ad\334ad 0} + run {string last Üa ÜadÜad 0} } -1 test string-7.16.$noComp {string last, start index} { - run {string last \334a \334ad\334ad end-1} + run {string last Üa ÜadÜad end-1} } 3 test string-8.1.$noComp {string bytelength} { @@ -1039,7 +1039,7 @@ test string-9.4.$noComp {string length} { run {string le ""} } 0 test string-9.5.$noComp {string length, unicode} { - run {string le "abcd\u7266"} + run {string le "abcd牦"} } 5 test string-9.6.$noComp {string length, bytearray object} { run {string length [binary format a5 foo]} @@ -1082,11 +1082,11 @@ test string-10.11.$noComp {string map, nulls} { run {string map {\x00 NULL blah \x00nix} {qwerty}} } {qwerty} test string-10.12.$noComp {string map, unicode} { - run {string map [list \374 ue UE \334] "a\374ueUE\000EU"} -} aueue\334\0EU + run {string map [list ü ue UE Ü] "aüueUE\x00EU"} +} aueueÜ\x00EU test string-10.13.$noComp {string map, -nocase unicode} { - run {string map -nocase [list \374 ue UE \334] "a\374ueUE\000EU"} -} aue\334\334\0EU + run {string map -nocase [list ü ue UE Ü] "aüueUE\x00EU"} +} aueÜÜ\x00EU test string-10.14.$noComp {string map, -nocase null arguments} { run {string map -nocase {{} abc} foo} } foo @@ -1290,7 +1290,7 @@ test string-11.32.$noComp {string match nocase} { run {string match -n a A} } 1 test string-11.33.$noComp {string match nocase} { - run {string match -nocase a\334 A\374} + run {string match -nocase aÜ Aü} } 1 test string-11.34.$noComp {string match nocase} { run {string match -nocase a*f ABCDEf} @@ -1457,11 +1457,11 @@ test string-12.16.$noComp {string range} { run {string range abcdefghijklmnop end end-1} } {} test string-12.17.$noComp {string range, unicode} { - run {string range ab\u7266cdefghijklmnop 5 5} + run {string range ab牦cdefghijklmnop 5 5} } e test string-12.18.$noComp {string range, unicode} { - run {string range ab\u7266cdefghijklmnop 2 3} -} \u7266c + run {string range ab牦cdefghijklmnop 2 3} +} 牦c test string-12.19.$noComp {string range, bytearray object} { set b [binary format I* {0x50515253 0x52}] set r1 [run {string range $b 1 end-1}] @@ -1544,15 +1544,15 @@ test string-13.11.$noComp {string repeat} { run {string repeat def 1} } def test string-13.12.$noComp {string repeat} { - run {string repeat ab\u7266cd 3} -} ab\u7266cdab\u7266cdab\u7266cd + run {string repeat ab牦cd 3} +} ab牦cdab牦cdab牦cd test string-13.13.$noComp {string repeat} { run {string repeat \x00 3} } \x00\x00\x00 test string-13.14.$noComp {string repeat} { # The string range will ensure us that string repeat gets a unicode string - run {string repeat [run {string range ab\u7266cd 2 3}] 3} -} \u7266c\u7266c\u7266c + run {string repeat [run {string range ab牦cd 2 3}] 3} +} 牦c牦c牦c test string-14.1.$noComp {string replace} { list [catch {run {string replace}} msg] $msg @@ -1846,7 +1846,7 @@ test string-20.8.$noComp {[c61818e4c9] [string trimright] fails when UtfPrev is lappend result [string map $m [run {string trimright $b [testbytestring \xA0]}]] lappend result [string map $m [run {string trimright $b \xE8\xA0}]] lappend result [string map $m [run {string trimright $b [testbytestring \xE8\xA0]}]] - lappend result [string map $m [run {string trimright $b \u0000}]] + lappend result [string map $m [run {string trimright $b \x00}]] } [list {*}[lrepeat 4 fooUV] {*}[lrepeat 2 fooU] {*}[lrepeat 2 foo] fooUV] test string-21.1.$noComp {string wordend} -body { diff --git a/tests/stringObj.test b/tests/stringObj.test index 9937fa4..135830c 100644 --- a/tests/stringObj.test +++ b/tests/stringObj.test @@ -208,19 +208,19 @@ test stringObj-8.1 {DupStringInternalRep procedure} testobj { [teststringobj maxchars 2] [teststringobj get 2] } {5 10 0 abcde 5 5 0 abcde} test stringObj-8.2 {DupUnicodeInternalRep, mixed width chars} testobj { - set x abc\u00ef\u00bf\u00aeghi + set x abc\xEF\xBF\xAEghi string length $x set y $x - list [testobj objtype $x] [testobj objtype $y] [append x "\u00ae\u00bf\u00ef"] \ + list [testobj objtype $x] [testobj objtype $y] [append x "\xAE\xBF\xEF"] \ [set y] [testobj objtype $x] [testobj objtype $y] -} "string string abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef abc\u00ef\u00bf\u00aeghi string string" +} "string string abc\xEF\xBF\xAEghi\xAE\xBF\xEF abc\xEF\xBF\xAEghi string string" test stringObj-8.3 {DupUnicodeInternalRep, mixed width chars} testobj { - set x abc\u00ef\u00bf\u00aeghi + set x abc\xEF\xBF\xAEghi set y $x string length $x - list [testobj objtype $x] [testobj objtype $y] [append x "\u00ae\u00bf\u00ef"] \ + list [testobj objtype $x] [testobj objtype $y] [append x "\xAE\xBF\xEF"] \ [set y] [testobj objtype $x] [testobj objtype $y] -} "string string abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef abc\u00ef\u00bf\u00aeghi string string" +} "string string abc\xEF\xBF\xAEghi\xAE\xBF\xEF abc\xEF\xBF\xAEghi string string" test stringObj-8.4 {DupUnicodeInternalRep, all byte-size chars} testobj { set x abcdefghi string length $x @@ -237,31 +237,31 @@ test stringObj-8.5 {DupUnicodeInternalRep, all byte-size chars} testobj { } {string string abcdefghijkl abcdefghi string string} test stringObj-9.1 {TclAppendObjToObj, mixed src & dest} {testobj testdstring} { - set x abc\u00ef\u00bf\u00aeghi + set x abc\xEF\xBF\xAEghi testdstring free - testdstring append \u00ae\u00bf\u00ef -1 + testdstring append \xAE\xBF\xEF -1 set y [testdstring get] string length $x list [testobj objtype $x] [testobj objtype $y] [append x $y] \ [set y] [testobj objtype $x] [testobj objtype $y] -} "string none abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef \u00ae\u00bf\u00ef string none" +} "string none abc\xEF\xBF\xAEghi\xAE\xBF\xEF \xAE\xBF\xEF string none" test stringObj-9.2 {TclAppendObjToObj, mixed src & dest} testobj { - set x abc\u00ef\u00bf\u00aeghi + set x abc\xEF\xBF\xAEghi string length $x list [testobj objtype $x] [append x $x] [testobj objtype $x] \ [append x $x] [testobj objtype $x] -} "string abc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghi string\ -abc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghi\ +} "string abc\xEF\xBF\xAEghiabc\xEF\xBF\xAEghi string\ +abc\xEF\xBF\xAEghiabc\xEF\xBF\xAEghiabc\xEF\xBF\xAEghiabc\xEF\xBF\xAEghi\ string" test stringObj-9.3 {TclAppendObjToObj, mixed src & 1-byte dest} {testobj testdstring} { set x abcdefghi testdstring free - testdstring append \u00ae\u00bf\u00ef -1 + testdstring append \xAE\xBF\xEF -1 set y [testdstring get] string length $x list [testobj objtype $x] [testobj objtype $y] [append x $y] \ [set y] [testobj objtype $x] [testobj objtype $y] -} "string none abcdefghi\u00ae\u00bf\u00ef \u00ae\u00bf\u00ef string none" +} "string none abcdefghi\xAE\xBF\xEF \xAE\xBF\xEF string none" test stringObj-9.4 {TclAppendObjToObj, 1-byte src & dest} {testobj testdstring} { set x abcdefghi testdstring free @@ -279,14 +279,14 @@ test stringObj-9.5 {TclAppendObjToObj, 1-byte src & dest} testobj { } {string abcdefghiabcdefghi string abcdefghiabcdefghiabcdefghiabcdefghi\ string} test stringObj-9.6 {TclAppendObjToObj, 1-byte src & mixed dest} {testobj testdstring} { - set x abc\u00ef\u00bf\u00aeghi + set x abc\xEF\xBF\xAEghi testdstring free testdstring append jkl -1 set y [testdstring get] string length $x list [testobj objtype $x] [testobj objtype $y] [append x $y] \ [set y] [testobj objtype $x] [testobj objtype $y] -} "string none abc\u00ef\u00bf\u00aeghijkl jkl string none" +} "string none abc\xEF\xBF\xAEghijkl jkl string none" test stringObj-9.7 {TclAppendObjToObj, integer src & dest} testobj { set x [expr {4 * 5}] set y [expr {4 + 5}] @@ -307,19 +307,19 @@ test stringObj-9.9 {TclAppendObjToObj, integer src & 1-byte dest} testobj { [set y] [testobj objtype $x] [testobj objtype $y] } {string int abcdefghi9 9 string int} test stringObj-9.10 {TclAppendObjToObj, integer src & mixed dest} testobj { - set x abc\u00ef\u00bf\u00aeghi + set x abc\xEF\xBF\xAEghi set y [expr {4 + 5}] string length $x list [testobj objtype $x] [testobj objtype $y] [append x $y] \ [set y] [testobj objtype $x] [testobj objtype $y] -} "string int abc\u00ef\u00bf\u00aeghi9 9 string int" +} "string int abc\xEF\xBF\xAEghi9 9 string int" test stringObj-9.11 {TclAppendObjToObj, mixed src & 1-byte dest index check} testobj { # bug 2678, in <=8.2.0, the second obj (the one to append) in # Tcl_AppendObjToObj was not correctly checked to see if it was all one # byte chars, so a unicode string would be added as one byte chars. set x abcdef set len [string length $x] - set y a\u00fcb\u00e5c\u00ef + set y a\xFCb\xE5c\xEF set len [string length $y] append x $y string length $x @@ -328,7 +328,7 @@ test stringObj-9.11 {TclAppendObjToObj, mixed src & 1-byte dest index check} tes lappend q [string index $x $i] } set q -} "a b c d e f a \u00fc b \u00e5 c \u00ef" +} "a b c d e f a \xFC b \xE5 c \xEF" test stringObj-10.1 {Tcl_GetRange with all byte-size chars} {testobj testdstring} { testdstring free @@ -338,41 +338,30 @@ test stringObj-10.1 {Tcl_GetRange with all byte-size chars} {testobj testdstring [testobj objtype $x] [testobj objtype $y] } [list none bcde string string] test stringObj-10.2 {Tcl_GetRange with some mixed width chars} {testobj testdstring} { - # Because this test does not use \uXXXX notation below instead of - # hardcoding the values, it may fail in multibyte locales. However, we - # need to test that the parser produces untyped objects even when there - # are high-ASCII characters in the input (like "ï"). I don't know what - # else to do but inline those characters here. testdstring free - testdstring append "abc\u00ef\u00efdef" -1 + testdstring append "abcïïdef" -1 set x [testdstring get] list [testobj objtype $x] [set y [string range $x 1 end-1]] \ [testobj objtype $x] [testobj objtype $y] -} [list none "bc\u00EF\u00EFde" string string] +} [list none "bcïïde" string string] test stringObj-10.3 {Tcl_GetRange with some mixed width chars} testobj { - # set x "abcïïdef" - # Use \uXXXX notation below instead of hardcoding the values, otherwise - # the test will fail in multibyte locales. - set x "abc\u00EF\u00EFdef" + set x "abcïïdef" string length $x list [testobj objtype $x] [set y [string range $x 1 end-1]] \ [testobj objtype $x] [testobj objtype $y] -} [list string "bc\u00EF\u00EFde" string string] +} [list string "bcïïde" string string] test stringObj-10.4 {Tcl_GetRange with some mixed width chars} testobj { - # set a "ïa¿b®cï¿d®" - # Use \uXXXX notation below instead of hardcoding the values, otherwise - # the test will fail in multibyte locales. - set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE" + set a "ïa¿b®cï¿d®" set result [list] while {[string length $a] > 0} { set a [string range $a 1 end-1] lappend result $a } set result -} [list a\u00BFb\u00AEc\u00EF\u00BFd \ - \u00BFb\u00AEc\u00EF\u00BF \ - b\u00AEc\u00EF \ - \u00AEc \ +} [list a\xBFb\xAEc\xEF\xBFd \ + \xBFb\xAEc\xEF\xBF \ + b\xAEc\xEF \ + \xAEc \ {}] test stringObj-11.1 {UpdateStringOfString} testobj { @@ -394,15 +383,15 @@ test stringObj-12.3 {Tcl_GetUniChar with byte-size chars} testobj { list [string index $x end] [string index $x end-1] } {i h} test stringObj-12.4 {Tcl_GetUniChar with mixed width chars} testobj { - string index "\u00efa\u00bfb\u00aec\u00ae\u00bfd\u00ef" 0 -} "\u00ef" + string index "\xEFa\xBFb\xAEc\xAE\xBFd\xEF" 0 +} "\xEF" test stringObj-12.5 {Tcl_GetUniChar} testobj { - set x "\u00efa\u00bfb\u00aec\u00ae\u00bfd\u00ef" + set x "\xEFa\xBFb\xAEc\xAE\xBFd\xEF" list [string index $x 4] [string index $x 0] -} "\u00ae \u00ef" +} "\xAE \xEF" test stringObj-12.6 {Tcl_GetUniChar} testobj { - string index "\u00efa\u00bfb\u00aec\u00ef\u00bfd\u00ae" end -} "\u00ae" + string index "\xEFa\xBFb\xAEc\xEF\xBFd\xAE" end +} "\xAE" test stringObj-13.1 {Tcl_GetCharLength with byte-size chars} testobj { set a "" @@ -416,19 +405,19 @@ test stringObj-13.3 {Tcl_GetCharLength with byte-size chars} testobj { list [string length $a] [string length $a] } {6 6} test stringObj-13.4 {Tcl_GetCharLength with mixed width chars} testobj { - string length "\u00ae" + string length "\xAE" } 1 test stringObj-13.5 {Tcl_GetCharLength with mixed width chars} testobj { # string length "○○" # Use \uXXXX notation below instead of hardcoding the values, otherwise # the test will fail in multibyte locales. - string length "\u00EF\u00BF\u00AE\u00EF\u00BF\u00AE" + string length "\xEF\xBF\xAE\xEF\xBF\xAE" } 6 test stringObj-13.6 {Tcl_GetCharLength with mixed width chars} testobj { # set a "ïa¿b®cï¿d®" # Use \uXXXX notation below instead of hardcoding the values, otherwise # the test will fail in multibyte locales. - set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE" + set a "\xEFa\xBFb\xAEc\xEF\xBFd\xAE" list [string length $a] [string length $a] } {10 10} test stringObj-13.7 {Tcl_GetCharLength with identity nulls} {testobj testbytestring} { diff --git a/tests/subst.test b/tests/subst.test index 03a1ce2..da59c3b 100644 --- a/tests/subst.test +++ b/tests/subst.test @@ -48,7 +48,7 @@ test subst-3.2 {backslash substitutions with utf chars} { # 'j' is just a char that doesn't mean anything, and \344 is 'ä' # that also doesn't mean anything, but is multi-byte in UTF-8. list [subst \j] [subst \\j] [subst \\344] [subst \\\344] -} "j j \344 \344" +} "j j ä ä" test subst-4.1 {variable substitutions} { set a 44 diff --git a/tests/timer.test b/tests/timer.test index 1ad17ae..52c0b8a 100644 --- a/tests/timer.test +++ b/tests/timer.test @@ -367,7 +367,7 @@ test timer-6.23 {Tcl_AfterCmd procedure, no option, script with NUL} -setup { } } -body { set x "hello world" - after 1 "set x ab\0cd" + after 1 "set x ab\x00cd" after 10 update string length $x @@ -378,7 +378,7 @@ test timer-6.24 {Tcl_AfterCmd procedure, no option, script with NUL} -setup { } } -body { set x "hello world" - after 1 set x ab\0cd + after 1 set x ab\x00cd after 10 update string length $x @@ -389,8 +389,8 @@ test timer-6.25 {Tcl_AfterCmd procedure, cancel option, script with NUL} -setup } } -body { set x "hello world" - after 1 set x ab\0cd - after cancel "set x ab\0ef" + after 1 set x ab\x00cd + after cancel "set x ab\x00ef" llength [after info] } -cleanup { foreach i [after info] { @@ -403,8 +403,8 @@ test timer-6.26 {Tcl_AfterCmd procedure, cancel option, script with NUL} -setup } } -body { set x "hello world" - after 1 set x ab\0cd - after cancel set x ab\0ef + after 1 set x ab\x00cd + after cancel set x ab\x00ef llength [after info] } -cleanup { foreach i [after info] { @@ -417,7 +417,7 @@ test timer-6.27 {Tcl_AfterCmd procedure, idle option, script with NUL} -setup { } } -body { set x "hello world" - after idle "set x ab\0cd" + after idle "set x ab\x00cd" update string length $x } -result {5} @@ -427,7 +427,7 @@ test timer-6.28 {Tcl_AfterCmd procedure, idle option, script with NUL} -setup { } } -body { set x "hello world" - after idle set x ab\0cd + after idle set x ab\x00cd update string length $x } -result {5} @@ -438,7 +438,7 @@ test timer-6.29 {Tcl_AfterCmd procedure, info option, script with NUL} -setup { } -body { set x "hello world" set id junk - set id [after 10 set x ab\0cd] + set id [after 10 set x ab\x00cd] update string length [lindex [lindex [after info $id] 0] 2] } -cleanup { diff --git a/tests/unixInit.test b/tests/unixInit.test index aa3d50a..2ea7d8e 100644 --- a/tests/unixInit.test +++ b/tests/unixInit.test @@ -126,7 +126,7 @@ test unixInit-2.2 {TclpInitLibraryPath: TCL_LIBRARY} -setup { set oldlibrary $env(TCL_LIBRARY) } } -body { - # ((str != NULL) && (str[0] != '\0')) + # ((str != NULL) && (str[0] != '\x00')) set env(TCL_LIBRARY) sparkly lindex [getlibpath] 0 } -cleanup { @@ -158,7 +158,7 @@ test unixInit-2.4 {TclpInitLibraryPath: TCL_LIBRARY: INTL} -setup { } } -body { # Child process translates env variable from native encoding. - set env(TCL_LIBRARY) "\xa7" + set env(TCL_LIBRARY) "§" lindex [getlibpath] 0 } -cleanup { unset -nocomplain env(TCL_LIBRARY) env(LANG) @@ -166,7 +166,7 @@ test unixInit-2.4 {TclpInitLibraryPath: TCL_LIBRARY: INTL} -setup { set env(TCL_LIBRARY) $oldlibrary unset oldlibrary } -} -result "\xa7" +} -result "§" test unixInit-2.5 {TclpInitLibraryPath: compiled-in library path} { # cannot test } {} diff --git a/tests/utf.test b/tests/utf.test index b4e34d6..3262214 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -49,7 +49,7 @@ test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} testbytestring { expr {"\xE0" eq [testbytestring \xC3\xA0]} } 1 test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} testbytestring { - expr {"\u4E4E" eq [testbytestring \xE4\xB9\x8E]} + expr {"乎" eq [testbytestring \xE4\xB9\x8E]} } 1 test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} testbytestring { expr {[format %c 0x110000] eq [testbytestring \xEF\xBF\xBD]} @@ -57,10 +57,10 @@ test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} testbytestring { test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} testbytestring { expr {[format %c -1] eq [testbytestring \xEF\xBF\xBD]} } 1 -test utf-1.7.0 {Tcl_UniCharToUtf: 4 byte sequences} {fullutf Uesc testbytestring} { +test utf-1.7.0 {Tcl_UniCharToUtf: 4 byte sequences} {fullutf testbytestring} { expr {"\U014E4E" eq [testbytestring \xF0\x94\xB9\x8E]} } 1 -test utf-1.7.1 {Tcl_UniCharToUtf: 4 byte sequences} {ucs2 Uesc testbytestring} { +test utf-1.7.1 {Tcl_UniCharToUtf: 4 byte sequences} {Uesc ucs2 testbytestring} { expr {"\U014E4E" eq [testbytestring \xF0\x94\xB9\x8E]} } 0 test utf-1.8 {Tcl_UniCharToUtf: 3 byte sequence, high surrogate} testbytestring { @@ -81,7 +81,7 @@ test utf-1.12 {Tcl_UniCharToUtf: 4 byte sequence, high/low surrogate} {pairsTo4b test utf-1.13.0 {Tcl_UniCharToUtf: Invalid surrogate} {Uesc ucs2} { expr {"\UD842" eq "\uD842"} } 1 -test utf-1.13.1 {Tcl_UniCharToUtf: Invalid surrogate} {Uesc testbytestring fullutf} { +test utf-1.13.1 {Tcl_UniCharToUtf: Invalid surrogate} {fullutf testbytestring} { expr {"\UD842" eq [testbytestring \xEF\xBF\xBD]} } 1 @@ -106,22 +106,22 @@ test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} testbytestrin test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} testbytestring { string length [testbytestring \xE4\xB9\x8E] } 1 -test utf-2.8.0 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {testbytestring ucs2} { +test utf-2.8.0 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {ucs2 testbytestring} { string length [testbytestring \xF0\x90\x80\x80] } 2 -test utf-2.8.1 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {Uesc utf16} { - string length \U010000 +test utf-2.8.1 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} utf16 { + string length 𐀀 } 2 -test utf-2.8.2 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {Uesc ucs4} { - string length \U010000 +test utf-2.8.2 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} ucs4 { + string length 𐀀 } 1 -test utf-2.9.0 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {testbytestring ucs2} { +test utf-2.9.0 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {ucs2 testbytestring} { string length [testbytestring \xF4\x8F\xBF\xBF] } 2 -test utf-2.9.1 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {Uesc utf16} { +test utf-2.9.1 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} utf16 { string length \U10FFFF } 2 -test utf-2.9.2 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} {Uesc ucs4} { +test utf-2.9.2 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} ucs4 { string length \U10FFFF } 1 test utf-2.10 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail, underflow} testbytestring { @@ -354,7 +354,7 @@ test utf-6.50 {Tcl_UtfNext} {testutfnext testbytestring} { testutfnext [testbytestring \xE8\xA0]G } 1 test utf-6.51 {Tcl_UtfNext} testutfnext { - testutfnext \u8820 + testutfnext 蠠 } 3 test utf-6.52 {Tcl_UtfNext} {testutfnext testbytestring} { testutfnext [testbytestring \xE8\xA0\xD0] @@ -387,22 +387,22 @@ test utf-6.61 {Tcl_UtfNext} {testutfnext testbytestring} { testutfnext [testbytestring \xF2\xA0\xF8] } 1 test utf-6.62 {Tcl_UtfNext} testutfnext { - testutfnext \u8820G + testutfnext 蠠G } 3 test utf-6.63 {Tcl_UtfNext} {testutfnext testbytestring} { - testutfnext \u8820[testbytestring \xA0] + testutfnext 蠠[testbytestring \xA0] } 3 test utf-6.64 {Tcl_UtfNext} {testutfnext testbytestring} { - testutfnext \u8820[testbytestring \xD0] + testutfnext 蠠[testbytestring \xD0] } 3 test utf-6.65 {Tcl_UtfNext} {testutfnext testbytestring} { - testutfnext \u8820[testbytestring \xE8] + testutfnext 蠠[testbytestring \xE8] } 3 test utf-6.66 {Tcl_UtfNext} {testutfnext testbytestring} { - testutfnext \u8820[testbytestring \xF2] + testutfnext 蠠[testbytestring \xF2] } 3 test utf-6.67 {Tcl_UtfNext} {testutfnext testbytestring} { - testutfnext \u8820[testbytestring \xF8] + testutfnext 蠠[testbytestring \xF8] } 3 test utf-6.68 {Tcl_UtfNext} {testutfnext testbytestring} { testutfnext [testbytestring \xF2\xA0\xA0]G @@ -565,7 +565,7 @@ test utf-7.6 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A[testbytestring \xE8] } 1 test utf-7.6.1 {Tcl_UtfPrev} {testutfprev testbytestring} { - testutfprev A\u8820[testbytestring \xA0] 2 + testutfprev A蠠[testbytestring \xA0] 2 } 1 test utf-7.6.2 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A[testbytestring \xE8\xF8\xA0\xA0] 2 @@ -619,7 +619,7 @@ test utf-7.11 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A[testbytestring \xE8\xA0] } 1 test utf-7.11.1 {Tcl_UtfPrev} {testutfprev testbytestring} { - testutfprev A\u8820[testbytestring \xA0] 3 + testutfprev A蠠[testbytestring \xA0] 3 } 1 test utf-7.11.2 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A[testbytestring \xE8\xA0\xF8\xA0] 3 @@ -673,13 +673,13 @@ test utf-7.15.5 {Tcl_UtfPrev} {testutfprev testbytestring fullutf} { testutfprev A[testbytestring \xF2\xA0\xA0\xF8] 4 } 1 test utf-7.16 {Tcl_UtfPrev} testutfprev { - testutfprev A\u8820 + testutfprev A蠠 } 1 test utf-7.16.1 {Tcl_UtfPrev} {testutfprev testbytestring} { - testutfprev A\u8820[testbytestring \xA0] 4 + testutfprev A蠠[testbytestring \xA0] 4 } 1 test utf-7.16.2 {Tcl_UtfPrev} {testutfprev testbytestring} { - testutfprev A\u8820[testbytestring \xF8] 4 + testutfprev A蠠[testbytestring \xF8] 4 } 1 test utf-7.17 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A[testbytestring \xD0\xA0\xA0] @@ -709,7 +709,7 @@ test utf-7.20.1 {Tcl_UtfPrev} {testutfprev testbytestring fullutf} { testutfprev A[testbytestring \xF2\xA0\xA0\xA0] } 1 test utf-7.21 {Tcl_UtfPrev} {testutfprev testbytestring} { - testutfprev A\u8820[testbytestring \xA0] + testutfprev A蠠[testbytestring \xA0] } 4 test utf-7.22 {Tcl_UtfPrev} {testutfprev testbytestring} { testutfprev A[testbytestring \xD0\xA0\xA0\xA0] @@ -805,7 +805,7 @@ test utf-7.47 {Tcl_UtfPrev, pointing to 3th byte of 3-byte valid sequence} {test testutfprev [testbytestring \xE8\xA0] } 0 test utf-7.47.1 {Tcl_UtfPrev, pointing to 3th byte of 3-byte valid sequence} testutfprev { - testutfprev \u8820 2 + testutfprev 蠠 2 } 0 test utf-7.47.2 {Tcl_UtfPrev, pointing to 3th byte of 3-byte invalid sequence} {testutfprev testbytestring} { testutfprev [testbytestring \xE8\xA0\x00] 2 @@ -848,14 +848,14 @@ test utf-8.1 {Tcl_UniCharAtIndex: index = 0} { string index abcd 0 } a test utf-8.2 {Tcl_UniCharAtIndex: index = 0} { - string index \u4E4E\u25A 0 -} \u4E4E + string index 乎ɚ 0 +} 乎 test utf-8.3 {Tcl_UniCharAtIndex: index > 0} { string index abcd 2 } c test utf-8.4 {Tcl_UniCharAtIndex: index > 0} { - string index \u4E4E\u25A\xFF\u543 2 -} \xFF + string index 乎ɚÿՃ 2 +} ÿ test utf-8.5.0 {Tcl_UniCharAtIndex: high surrogate} ucs2 { string index \uD842 0 } \uD842 @@ -872,116 +872,116 @@ test utf-8.7.0 {Tcl_UniCharAtIndex: Emoji} ucs2 { string index \uD83D\uDE00G 0 } \uD83D test utf-8.7.1 {Tcl_UniCharAtIndex: Emoji} ucs4 { - string index \uD83D\uDE00G 0 -} \U1F600 + string index 😀G 0 +} 😀 test utf-8.7.2 {Tcl_UniCharAtIndex: Emoji} utf16 { - string index \uD83D\uDE00G 0 -} \U1F600 + string index 😀G 0 +} 😀 test utf-8.8.0 {Tcl_UniCharAtIndex: Emoji} ucs2 { string index \uD83D\uDE00G 1 } \uDE00 test utf-8.8.1 {Tcl_UniCharAtIndex: Emoji} ucs4 { - string index \uD83D\uDE00G 1 + string index 😀G 1 } G test utf-8.8.2 {Tcl_UniCharAtIndex: Emoji} utf16 { - string index \uD83D\uDE00G 1 + string index 😀G 1 } {} test utf-8.9.0 {Tcl_UniCharAtIndex: Emoji} ucs2 { string index \uD83D\uDE00G 2 } G test utf-8.9.1 {Tcl_UniCharAtIndex: Emoji} ucs4 { - string index \uD83D\uDE00G 2 + string index 😀G 2 } {} test utf-8.9.2 {Tcl_UniCharAtIndex: Emoji} utf16 { - string index \uD83D\uDE00G 2 + string index 😀G 2 } G -test utf-8.10.0 {Tcl_UniCharAtIndex: Emoji} {Uesc ucs2} { - string index \U1F600G 0 +test utf-8.10.0 {Tcl_UniCharAtIndex: Emoji} ucs2 { + string index 😀G 0 } \uFFFD -test utf-8.10.1 {Tcl_UniCharAtIndex: Emoji} {Uesc ucs4} { - string index \U1F600G 0 -} \U1F600 -test utf-8.10.2 {Tcl_UniCharAtIndex: Emoji} {Uesc utf16} { - string index \U1F600G 0 -} \U1F600 -test utf-8.11.0 {Tcl_UniCharAtIndex: Emoji} {Uesc ucs2} { - string index \U1F600G 1 +test utf-8.10.1 {Tcl_UniCharAtIndex: Emoji} ucs4 { + string index 😀G 0 +} 😀 +test utf-8.10.2 {Tcl_UniCharAtIndex: Emoji} utf16 { + string index 😀G 0 +} 😀 +test utf-8.11.0 {Tcl_UniCharAtIndex: Emoji} ucs2 { + string index 😀G 1 } G -test utf-8.11.1 {Tcl_UniCharAtIndex: Emoji} {Uesc ucs4} { - string index \U1F600G 1 +test utf-8.11.1 {Tcl_UniCharAtIndex: Emoji} ucs4 { + string index 😀G 1 } G -test utf-8.11.2 {Tcl_UniCharAtIndex: Emoji} {Uesc utf16} { - string index \U1F600G 1 +test utf-8.11.2 {Tcl_UniCharAtIndex: Emoji} utf16 { + string index 😀G 1 } {} -test utf-8.12.0 {Tcl_UniCharAtIndex: Emoji} {Uesc ucs2} { - string index \U1F600G 2 +test utf-8.12.0 {Tcl_UniCharAtIndex: Emoji} ucs2 { + string index 😀G 2 } {} -test utf-8.12.1 {Tcl_UniCharAtIndex: Emoji} {Uesc ucs4} { - string index \U1F600G 2 +test utf-8.12.1 {Tcl_UniCharAtIndex: Emoji} ucs4 { + string index 😀G 2 } {} -test utf-8.12.2 {Tcl_UniCharAtIndex: Emoji} {Uesc utf16} { - string index \U1F600G 2 +test utf-8.12.2 {Tcl_UniCharAtIndex: Emoji} utf16 { + string index 😀G 2 } G test utf-9.1 {Tcl_UtfAtIndex: index = 0} { string range abcd 0 2 } abc test utf-9.2 {Tcl_UtfAtIndex: index > 0} { - string range \u4E4E\u25A\xFF\u543klmnop 1 5 -} \u25A\xFF\u543kl + string range 乎ɚÿՃklmnop 1 5 +} ɚÿՃkl test utf-9.3.0 {Tcl_UtfAtIndex: index = 0, Emoji} ucs2 { string range \uD83D\uDE00G 0 0 } \uD83D test utf-9.3.1 {Tcl_UtfAtIndex: index = 0, Emoji} ucs4 { - string range \uD83D\uDE00G 0 0 -} \U1F600 + string range 😀G 0 0 +} 😀 test utf-9.3.2 {Tcl_UtfAtIndex: index = 0, Emoji} utf16 { - string range \uD83D\uDE00G 0 0 -} \U1F600 + string range 😀G 0 0 +} 😀 test utf-9.4.0 {Tcl_UtfAtIndex: index > 0, Emoji} ucs2 { string range \uD83D\uDE00G 1 1 } \uDE00 test utf-9.4.1 {Tcl_UtfAtIndex: index > 0, Emoji} ucs4 { - string range \uD83D\uDE00G 1 1 + string range 😀G 1 1 } G test utf-9.4.2 {Tcl_UtfAtIndex: index > 0, Emoji} utf16 { - string range \uD83D\uDE00G 1 1 + string range 😀G 1 1 } {} test utf-9.5.0 {Tcl_UtfAtIndex: index > 0, Emoji} ucs2 { string range \uD83D\uDE00G 2 2 } G test utf-9.5.1 {Tcl_UtfAtIndex: index > 0, Emoji} ucs4 { - string range \uD83D\uDE00G 2 2 + string range 😀G 2 2 } {} test utf-9.5.2 {Tcl_UtfAtIndex: index > 0, Emoji} utf16 { - string range \uD83D\uDE00G 2 2 + string range 😀G 2 2 } G -test utf-9.6.0 {Tcl_UtfAtIndex: index = 0, Emoji} {Uesc ucs2} { - string range \U1f600G 0 0 +test utf-9.6.0 {Tcl_UtfAtIndex: index = 0, Emoji} ucs2 { + string range 😀G 0 0 } \uFFFD -test utf-9.6.1 {Tcl_UtfAtIndex: index = 0, Emoji} {Uesc ucs4} { - string range \U1f600G 0 0 -} \U1F600 -test utf-9.6.2 {Tcl_UtfAtIndex: index = 0, Emoji} {Uesc utf16} { - string range \U1f600G 0 0 -} \U1F600 -test utf-9.7.0 {Tcl_UtfAtIndex: index > 0, Emoji} {Uesc ucs2} { - string range \U1f600G 1 1 +test utf-9.6.1 {Tcl_UtfAtIndex: index = 0, Emoji} ucs4 { + string range 😀G 0 0 +} 😀 +test utf-9.6.2 {Tcl_UtfAtIndex: index = 0, Emoji} utf16 { + string range 😀G 0 0 +} 😀 +test utf-9.7.0 {Tcl_UtfAtIndex: index > 0, Emoji} ucs2 { + string range 😀G 1 1 } G -test utf-9.7.1 {Tcl_UtfAtIndex: index > 0, Emoji} {Uesc ucs4} { - string range \U1f600G 1 1 +test utf-9.7.1 {Tcl_UtfAtIndex: index > 0, Emoji} ucs4 { + string range 😀G 1 1 } G -test utf-9.7.2 {Tcl_UtfAtIndex: index > 0, Emoji} {Uesc utf16} { - string range \U1f600G 1 1 +test utf-9.7.2 {Tcl_UtfAtIndex: index > 0, Emoji} utf16 { + string range 😀G 1 1 } {} -test utf-9.8.0 {Tcl_UtfAtIndex: index > 0, Emoji} {Uesc ucs2} { - string range \U1f600G 2 2 +test utf-9.8.0 {Tcl_UtfAtIndex: index > 0, Emoji} ucs2 { + string range 😀G 2 2 } {} -test utf-9.8.1 {Tcl_UtfAtIndex: index > 0, Emoji} {Uesc ucs4} { - string range \U1f600G 2 2 +test utf-9.8.1 {Tcl_UtfAtIndex: index > 0, Emoji} ucs4 { + string range 😀G 2 2 } {} -test utf-9.8.2 {Tcl_UtfAtIndex: index > 0, Emoji} {Uesc utf16} { - string range \U1f600G 2 2 +test utf-9.8.2 {Tcl_UtfAtIndex: index > 0, Emoji} utf16 { + string range 😀G 2 2 } G test utf-10.1 {Tcl_UtfBackslash: dst == NULL} { @@ -1000,10 +1000,10 @@ test utf-10.4 {Tcl_UtfBackslash: stops at first non-hex} testbytestring { test utf-10.5 {Tcl_UtfBackslash: stops after 4 hex chars} testbytestring { expr {"\u4E216" eq "[testbytestring \xE4\xB8\xA1]6"} } 1 -test utf-10.6 {Tcl_UtfBackslash: stops after 5 hex chars} {Uesc fullutf testbytestring} { +test utf-10.6 {Tcl_UtfBackslash: stops after 5 hex chars} {fullutf testbytestring} { expr {"\U1E2165" eq "[testbytestring \xF0\x9E\x88\x96]5"} } 1 -test utf-10.7 {Tcl_UtfBackslash: stops after 6 hex chars} {Uesc fullutf testbytestring} { +test utf-10.7 {Tcl_UtfBackslash: stops after 6 hex chars} {fullutf testbytestring} { expr {"\U10E2165" eq "[testbytestring \xF4\x8E\x88\x96]5"} } 1 @@ -1066,13 +1066,13 @@ bsCheck \U4E21 20001 Uesc bsCheck \U004E21 20001 Uesc bsCheck \U00004E21 20001 Uesc bsCheck \U0000004E21 78 Uesc -bsCheck \U00110000 69632 {Uesc fullutf} -bsCheck \U01100000 69632 {Uesc fullutf} -bsCheck \U11000000 69632 {Uesc fullutf} -bsCheck \U0010FFFF 1114111 {Uesc fullutf} -bsCheck \U010FFFF0 1114111 {Uesc fullutf} -bsCheck \U10FFFF00 1114111 {Uesc fullutf} -bsCheck \UFFFFFFFF 1048575 {Uesc fullutf} +bsCheck \U00110000 69632 fullutf +bsCheck \U01100000 69632 fullutf +bsCheck \U11000000 69632 fullutf +bsCheck \U0010FFFF 1114111 fullutf +bsCheck \U010FFFF0 1114111 fullutf +bsCheck \U10FFFF00 1114111 fullutf +bsCheck \UFFFFFFFF 1048575 fullutf test utf-11.1 {Tcl_UtfToUpper} { string toupper {} @@ -1084,17 +1084,17 @@ test utf-11.3 {Tcl_UtfToUpper} { string toupper \xE3gh } \xC3GH test utf-11.4 {Tcl_UtfToUpper} { - string toupper \u01E3gh -} \u01E2GH + string toupper ǣgh +} ǢGH test utf-11.5 {Tcl_UtfToUpper Georgian (new in Unicode 11)} { - string toupper \u10D0\u1C90 -} \u1C90\u1C90 -test utf-11.6 {Tcl_UtfToUpper beyond U+FFFF} {Uesc fullutf} { - string toupper \U10428 -} \U10400 + string toupper აᲐ +} ᲐᲐ +test utf-11.6 {Tcl_UtfToUpper beyond U+FFFF} fullutf { + string toupper 𐐨 +} 𐐀 test utf-11.7 {Tcl_UtfToUpper beyond U+FFFF} fullutf { - string toupper \uD801\uDC28 -} \uD801\uDC00 + string toupper 𐐨 +} 𐐀 test utf-11.8 {Tcl_UtfToUpper low/high surrogate)} { string toupper \uDC24\uD824 } \uDC24\uD824 @@ -1106,23 +1106,23 @@ test utf-12.2 {Tcl_UtfToLower} { string tolower ABC } abc test utf-12.3 {Tcl_UtfToLower} { - string tolower \xC3GH -} \xE3gh + string tolower ÃGH +} ãgh test utf-12.4 {Tcl_UtfToLower} { - string tolower \u01E2GH -} \u01E3gh + string tolower ǢGH +} ǣgh test utf-12.5 {Tcl_UtfToLower Georgian (new in Unicode 11)} { - string tolower \u10D0\u1C90 -} \u10D0\u10D0 + string tolower აᲐ +} აა test utf-12.6 {Tcl_UtfToLower low/high surrogate)} { string tolower \uDC24\uD824 } \uDC24\uD824 -test utf-12.7 {Tcl_UtfToLower beyond U+FFFF} {Uesc fullutf} { - string tolower \U10400 -} \U10428 +test utf-12.7 {Tcl_UtfToLower beyond U+FFFF} fullutf { + string tolower 𐐀 +} 𐐨 test utf-12.8 {Tcl_UtfToLower beyond U+FFFF} fullutf { - string tolower \uD801\uDC00 -} \uD801\uDC28 + string tolower 𐐀 +} 𐐨 test utf-13.1 {Tcl_UtfToTitle} { string totitle {} @@ -1131,26 +1131,26 @@ test utf-13.2 {Tcl_UtfToTitle} { string totitle abc } Abc test utf-13.3 {Tcl_UtfToTitle} { - string totitle \xE3GH -} \xC3gh + string totitle ãGH +} Ãgh test utf-13.4 {Tcl_UtfToTitle} { - string totitle \u01F3AB -} \u01F2ab + string totitle dzAB +} Dzab test utf-13.5 {Tcl_UtfToTitle Georgian (new in Unicode 11)} { - string totitle \u10D0\u1C90 -} \u10D0\u1C90 + string totitle აᲐ +} აᲐ test utf-13.6 {Tcl_UtfToTitle Georgian (new in Unicode 11)} { - string totitle \u1C90\u10D0 -} \u1C90\u10D0 + string totitle Აა +} Აა test utf-13.7 {Tcl_UtfToTitle low/high surrogate)} { string totitle \uDC24\uD824 } \uDC24\uD824 -test utf-13.8 {Tcl_UtfToTitle beyond U+FFFF} {Uesc fullutf} { - string totitle \U10428\U10400 -} \U10400\U10428 +test utf-13.8 {Tcl_UtfToTitle beyond U+FFFF} fullutf { + string totitle 𐐨𐐀 +} 𐐀𐐨 test utf-13.9 {Tcl_UtfToTitle beyond U+FFFF} fullutf { - string totitle \uD801\uDC28\uD801\uDC00 -} \uD801\uDC00\uD801\uDC28 + string totitle 𐐨𐐀 +} 𐐀𐐨 test utf-14.1 {Tcl_UtfNcasecmp} { string compare -nocase a b @@ -1169,8 +1169,8 @@ test utf-15.1 {Tcl_UniCharToUpper, negative delta} { string toupper aA } AA test utf-15.2 {Tcl_UniCharToUpper, positive delta} { - string toupper \u0178\xFF -} \u0178\u0178 + string toupper Ÿÿ +} ŸŸ test utf-15.3 {Tcl_UniCharToUpper, no delta} { string toupper ! } ! @@ -1179,25 +1179,25 @@ test utf-16.1 {Tcl_UniCharToLower, negative delta} { string tolower aA } aa test utf-16.2 {Tcl_UniCharToLower, positive delta} { - string tolower \u0178\xFF\uA78D\u01C5 -} \xFF\xFF\u0265\u01C6 + string tolower ŸÿꞍDž +} ÿÿɥdž test utf-17.1 {Tcl_UniCharToLower, no delta} { string tolower ! } ! test utf-18.1 {Tcl_UniCharToTitle, add one for title} { - string totitle \u01C4 -} \u01C5 + string totitle DŽ +} Dž test utf-18.2 {Tcl_UniCharToTitle, subtract one for title} { - string totitle \u01C6 -} \u01C5 + string totitle dž +} Dž test utf-18.3 {Tcl_UniCharToTitle, subtract delta for title (positive)} { - string totitle \u017F -} \x53 + string totitle ſ +} S test utf-18.4 {Tcl_UniCharToTitle, subtract delta for title (negative)} { - string totitle \xFF -} \u0178 + string totitle ÿ +} Ÿ test utf-18.5 {Tcl_UniCharToTitle, no delta} { string totitle ! } ! @@ -1223,23 +1223,23 @@ test utf-20.2 {[4c591fa487] TclUniCharNcmp/TclUtfNcmp} { test utf-21.1 {TclUniCharIsAlnum} { # this returns 1 with Unicode 7 compliance - string is alnum \u1040\u021F\u0220 + string is alnum ၀ȟȠ } 1 test utf-21.2 {unicode alnum char in regc_locale.c} { # this returns 1 with Unicode 7 compliance - list [regexp {^[[:alnum:]]+$} \u1040\u021F\u0220] [regexp {^\w+$} \u1040\u021F\u0220_\u203F\u2040\u2054\uFE33\uFE34\uFE4D\uFE4E\uFE4F\uFF3F] + list [regexp {^[[:alnum:]]+$} ၀ȟȠ] [regexp {^\w+$} ၀ȟȠ_‿⁀⁔︳︴﹍﹎﹏_] } {1 1} test utf-21.3 {unicode print char in regc_locale.c} { # this returns 1 with Unicode 7 compliance - regexp {^[[:print:]]+$} \uFBC1 + regexp {^[[:print:]]+$} ﯁ } 1 test utf-21.4 {TclUniCharIsGraph} { # [Bug 3464428] - string is graph \u0120 + string is graph Ġ } 1 test utf-21.5 {unicode graph char in regc_locale.c} { # [Bug 3464428] - regexp {^[[:graph:]]+$} \u0120 + regexp {^[[:graph:]]+$} Ġ } 1 test utf-21.6 {TclUniCharIsGraph} { # [Bug 3464428] @@ -1274,25 +1274,25 @@ test utf-22.1 {TclUniCharIsWordChar} { string wordend "xyz123_bar fg" 0 } 10 test utf-22.2 {TclUniCharIsWordChar} { - string wordend "x\u5080z123_bar\u203C fg" 0 + string wordend "x傀z123_bar‼ fg" 0 } 10 test utf-23.1 {TclUniCharIsAlpha} { # this returns 1 with Unicode 7 compliance - string is alpha \u021F\u0220\u037F\u052F + string is alpha ȟȠͿԯ } 1 test utf-23.2 {unicode alpha char in regc_locale.c} { # this returns 1 with Unicode 7 compliance - regexp {^[[:alpha:]]+$} \u021F\u0220\u037F\u052F + regexp {^[[:alpha:]]+$} ȟȠͿԯ } 1 test utf-24.1 {TclUniCharIsDigit} { # this returns 1 with Unicode 7 compliance - string is digit \u1040\uABF0 + string is digit ၀꯰ } 1 test utf-24.2 {unicode digit char in regc_locale.c} { # this returns 1 with Unicode 7 compliance - list [regexp {^[[:digit:]]+$} \u1040\uABF0] [regexp {^\d+$} \u1040\uABF0] + list [regexp {^[[:digit:]]+$} ၀꯰] [regexp {^\d+$} ၀꯰] } {1 1} test utf-24.3 {TclUniCharIsSpace} { @@ -1339,9 +1339,9 @@ UniCharCaseCmpTest > b a UniCharCaseCmpTest > B a UniCharCaseCmpTest > aBcB abca UniCharCaseCmpTest < \uFFFF [format %c 0x10000] ucs4 -UniCharCaseCmpTest < \uFFFF \U10000 {Uesc ucs4} +UniCharCaseCmpTest < \uFFFF \U10000 ucs4 UniCharCaseCmpTest > [format %c 0x10000] \uFFFF ucs4 -UniCharCaseCmpTest > \U10000 \uFFFF {Uesc ucs4} +UniCharCaseCmpTest > \U10000 \uFFFF ucs4 test utf-26.1 {Tcl_UniCharDString} -setup { diff --git a/tests/util.test b/tests/util.test index 29cf651..f610762 100644 --- a/tests/util.test +++ b/tests/util.test @@ -33,9 +33,9 @@ proc testIEEE {} { switch -exact -- $c { {0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} { # little endian - binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xFF d \ ieeeValues(-Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\xBF d \ ieeeValues(-Normal) binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \ ieeeValues(-Subnormal) @@ -45,23 +45,23 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \ ieeeValues(+Subnormal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x3F d \ ieeeValues(+Normal) - binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF0\x7F d \ ieeeValues(+Infinity) - binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \ + binary scan \x00\x00\x00\x00\x00\x00\xF8\x7F d \ ieeeValues(NaN) - binary scan \x00\x00\x00\x00\x00\x00\xf8\xff d \ + binary scan \x00\x00\x00\x00\x00\x00\xF8\xFF d \ ieeeValues(-NaN) - binary scan \xef\xcd\xab\x89\x67\x45\xfb\xff d \ + binary scan \xEF\xCD\xAB\x89\x67\x45\xFB\xFF d \ ieeeValues(-NaN(3456789abcdef)) set ieeeValues(littleEndian) 1 return 1 } {-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} { - binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xFF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Infinity) - binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \xBF\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Normal) binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-Subnormal) @@ -71,15 +71,15 @@ proc testIEEE {} { ieeeValues(+0) binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Subnormal) - binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x3F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Normal) - binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF0\x00\x00\x00\x00\x00\x00 d \ ieeeValues(+Infinity) - binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \ + binary scan \x7F\xF8\x00\x00\x00\x00\x00\x00 d \ ieeeValues(NaN) - binary scan \xff\xf8\x00\x00\x00\x00\x00\x00 d \ + binary scan \xFF\xF8\x00\x00\x00\x00\x00\x00 d \ ieeeValues(-NaN) - binary scan \xff\xfb\x45\x67\x89\xab\xcd\xef d \ + binary scan \xFF\xFB\x45\x67\x89\xAB\xCD\xEF d \ ieeeValues(-NaN(3456789abcdef)) set ieeeValues(littleEndian) 0 return 1 @@ -207,9 +207,9 @@ test util-4.5 {Tcl_ConcatObj - backslash-space at end of argument} { concat a { } c } {a c} test util-4.6 {Tcl_ConcatObj - utf-8 sequence with "whitespace" char} { - # Check for Bug #227512. If this violates C isspace, then it returns \xc3. - concat \xe0 -} \xe0 + # Check for Bug #227512. If this violates C isspace, then it returns \xC3. + concat \xE0 +} \xE0 test util-4.7 {Tcl_ConcatObj - refCount safety} testconcatobj { # Check for Bug #1447328 (actually, bugs in its original "fix"). One of the # symptoms was Bug #2055782. @@ -239,14 +239,14 @@ test util-5.6 {Tcl_StringMatch} { Wrapper_Tcl_StringMatch *3*6*9 01234567890 } 0 test util-5.7 {Tcl_StringMatch: UTF-8} { - Wrapper_Tcl_StringMatch *u \u4e4fu + Wrapper_Tcl_StringMatch *u 乏u } 1 test util-5.8 {Tcl_StringMatch} { Wrapper_Tcl_StringMatch a?c abc } 1 test util-5.9 {Tcl_StringMatch: UTF-8} { # skip one character in string - Wrapper_Tcl_StringMatch a?c a\u4e4fc + Wrapper_Tcl_StringMatch a?c a乏c } 1 test util-5.10 {Tcl_StringMatch} { Wrapper_Tcl_StringMatch a??c abc @@ -259,15 +259,15 @@ test util-5.12 {Tcl_StringMatch} { } 1 test util-5.13 {Tcl_StringMatch: UTF-8} { # string += Tcl_UtfToUniChar(string, &ch); - Wrapper_Tcl_StringMatch "\[\u4e4fxy\]bc" "\u4e4fbc" + Wrapper_Tcl_StringMatch "\[乏xy\]bc" "乏bc" } 1 test util-5.14 {Tcl_StringMatch} { - # if ((*pattern == ']') || (*pattern == '\0')) + # if ((*pattern == ']') || (*pattern == '\x00')) # badly formed pattern Wrapper_Tcl_StringMatch {[]} {[]} } 0 test util-5.15 {Tcl_StringMatch} { - # if ((*pattern == ']') || (*pattern == '\0')) + # if ((*pattern == ']') || (*pattern == '\x00')) # badly formed pattern Wrapper_Tcl_StringMatch {[} {[} } 0 @@ -277,17 +277,17 @@ test util-5.16 {Tcl_StringMatch} { test util-5.17 {Tcl_StringMatch: UTF-8} { # pattern += Tcl_UtfToUniChar(pattern, &endChar); # get 1 UTF-8 character - Wrapper_Tcl_StringMatch "a\[a\u4e4fc]c" "a\u4e4fc" + Wrapper_Tcl_StringMatch "a\[a乏c]c" "a乏c" } 1 test util-5.18 {Tcl_StringMatch: UTF-8} testbytestring { # pattern += Tcl_UtfToUniChar(pattern, &endChar); - # proper advance: wrong answer would match on UTF trail byte of \u4e4f - Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} [testbytestring a\x8fc] + # proper advance: wrong answer would match on UTF trail byte of 乏 + Wrapper_Tcl_StringMatch {a[a乏c]c} [testbytestring a\x8Fc] } 0 test util-5.19 {Tcl_StringMatch: UTF-8} { # pattern += Tcl_UtfToUniChar(pattern, &endChar); # proper advance. - Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} "acc" + Wrapper_Tcl_StringMatch {a[a乏c]c} "acc" } 1 test util-5.20 {Tcl_StringMatch} { Wrapper_Tcl_StringMatch {a[xyz]c} abc @@ -296,13 +296,13 @@ test util-5.21 {Tcl_StringMatch} { Wrapper_Tcl_StringMatch {12[2-7]45} 12345 } 1 test util-5.22 {Tcl_StringMatch: UTF-8 range} { - Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "0" + Wrapper_Tcl_StringMatch "\[一-乏]" "0" } 0 test util-5.23 {Tcl_StringMatch: UTF-8 range} { - Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "\u4e33" + Wrapper_Tcl_StringMatch "\[一-乏]" "丳" } 1 test util-5.24 {Tcl_StringMatch: UTF-8 range} { - Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "\uff08" + Wrapper_Tcl_StringMatch "\[一-乏]" "(" } 0 test util-5.25 {Tcl_StringMatch} { Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12345 @@ -356,16 +356,16 @@ test util-5.41 {Tcl_StringMatch: skip correct number of ']'} { Wrapper_Tcl_StringMatch {[A-]]x} Ax } 1 test util-5.42 {Tcl_StringMatch: skip correct number of ']'} { - Wrapper_Tcl_StringMatch {[A-]]x} \ue1x + Wrapper_Tcl_StringMatch {[A-]]x} \xE1x } 0 test util-5.43 {Tcl_StringMatch: skip correct number of ']'} { - Wrapper_Tcl_StringMatch \[A-]\ue1]x \ue1x + Wrapper_Tcl_StringMatch \[A-]\xE1]x \xE1x } 1 test util-5.44 {Tcl_StringMatch: skip correct number of ']'} { Wrapper_Tcl_StringMatch {[A-]h]x} hx } 1 test util-5.45 {Tcl_StringMatch} { - # if (*pattern == '\0') + # if (*pattern == '\x00') # badly formed pattern, still treats as a set Wrapper_Tcl_StringMatch {[a} a } 1 @@ -388,7 +388,7 @@ test util-5.51 {Tcl_StringMatch} { Wrapper_Tcl_StringMatch "" "" } 1 test util-5.52 {Tcl_StringMatch} { - Wrapper_Tcl_StringMatch \[a\u0000 a\x80 + Wrapper_Tcl_StringMatch \[a\x00 a\x80 } 0 @@ -483,27 +483,27 @@ test util-8.1 {TclNeedSpace - correct utf-8 handling} { # which calls on TclNeedSpace(). If [interp target] # is ever updated, this test will no longer test # TclNeedSpace. - interp create \u5420 - interp create [list \u5420 foo] - interp alias {} fooset [list \u5420 foo] set + interp create 吠 + interp create [list 吠 foo] + interp alias {} fooset [list 吠 foo] set set result [interp target {} fooset] - interp delete \u5420 + interp delete 吠 set result -} "\u5420 foo" +} "吠 foo" test util-8.2 {TclNeedSpace - correct utf-8 handling} testdstring { # Bug 411825 # This tests the same bug as the previous test, but # should be more future-proof, as the DString # operations will likely continue to call TclNeedSpace testdstring free - testdstring append \u5420 -1 + testdstring append 吠 -1 testdstring element foo llength [testdstring get] } 2 test util-8.3 {TclNeedSpace - correct utf-8 handling} testdstring { # Bug 411825 - new variant reported by Dossy Shiobara testdstring free - testdstring append \u00A0 -1 + testdstring append \xA0 -1 testdstring element foo llength [testdstring get] } 2 diff --git a/tests/var.test b/tests/var.test index a8d4b84..3ca1a76 100644 --- a/tests/var.test +++ b/tests/var.test @@ -203,27 +203,27 @@ test var-1.19 {TclLookupVar, right error message when parsing variable name} -bo [format set] thisvar(doesntexist) } -returnCodes error -result {can't read "thisvar(doesntexist)": no such variable} test var-1.20 {TclLookupVar, regression on utf-8 variable names} -setup { - proc p [list \u20ac \xe4] {info vars} + proc p [list € ä] {info vars} } -body { # test variable with non-ascii name is available (euro and a-uml chars here): list \ [p 1 2] \ - [apply [list [list \u20ac \xe4] {info vars}] 1 2] \ - [apply [list [list [list \u20ac \u20ac] [list \xe4 \xe4]] {info vars}]] \ + [apply [list [list € ä] {info vars}] 1 2] \ + [apply [list [list [list € €] [list ä ä]] {info vars}]] \ } -cleanup { rename p {} -} -result [lrepeat 3 [list \u20ac \xe4]] +} -result [lrepeat 3 [list € ä]] test var-1.21 {TclLookupVar, regression on utf-8 variable names} -setup { - proc p [list [list \u20ac v\u20ac] [list \xe4 v\xe4]] {list [set \u20ac] [set \xe4]} + proc p [list [list € v€] [list ä vä]] {list [set €] [set ä]} } -body { # test variable with non-ascii name (and default) is resolvable (euro and a-uml chars here): list \ [p] \ - [apply [list [list \u20ac \xe4] {list [set \u20ac] [set \xe4]}] v\u20ac v\xe4] \ - [apply [list [list [list \u20ac v\u20ac] [list \xe4 v\xe4]] {list [set \u20ac] [set \xe4]}]] \ + [apply [list [list € ä] {list [set €] [set ä]}] v€ vä] \ + [apply [list [list [list € v€] [list ä vä]] {list [set €] [set ä]}]] \ } -cleanup { rename p {} -} -result [lrepeat 3 [list v\u20ac v\xe4]] +} -result [lrepeat 3 [list v€ vä]] test var-2.1 {Tcl_LappendObjCmd, create var if new} { catch {unset x} diff --git a/tests/winPipe.test b/tests/winPipe.test index 6252f96..28d4f5b 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -174,7 +174,7 @@ test winpipe-1.21 {32 bit comprehensive tests: read/write application} \ {win exec cat32} { set f [open "|[list $cat32]" r+] puts $f $big - puts $f \032 + puts $f \x1A flush $f set r [read $f 64] catch {close $f} diff --git a/tests/zipfs.test b/tests/zipfs.test index 40655b4..bf9c969 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -272,7 +272,7 @@ test zipfs-3.4 {zipfs in child interpreters} -constraints zipfs -setup { } -result {not allowed to invoke subcommand mkzip of zipfs} test zipfs-4.1 {zipfs lmkimg} -constraints zipfs -setup { - set baseImage [makeFile "return sourceWorking\n\x1a" base] + set baseImage [makeFile "return sourceWorking\n\x1A" base] set targetImage [makeFile "" target] set addFile [makeFile "return mountWorking" add.data] file delete $targetImage @@ -290,7 +290,7 @@ test zipfs-4.1 {zipfs lmkimg} -constraints zipfs -setup { removeFile $addFile } -result {sourceWorking mountWorking} test zipfs-4.2 {zipfs lmkimg: making an image from an image} -constraints zipfs -setup { - set baseImage [makeFile "return sourceWorking\n\x1a" base_image.tcl] + set baseImage [makeFile "return sourceWorking\n\x1A" base_image.tcl] set midImage [makeFile "" mid_image.tcl] set targetImage [makeFile "" target_image.tcl] set addFile [makeFile "return mountWorking" add.data] @@ -316,7 +316,7 @@ test zipfs-4.2 {zipfs lmkimg: making an image from an image} -constraints zipfs removeFile $addFile } -result {ok.tcl equal} test zipfs-4.3 {zipfs lmkimg: stripping password} -constraints zipfs -setup { - set baseImage [makeFile "return sourceWorking\n\x1a" base_image.tcl] + set baseImage [makeFile "return sourceWorking\n\x1A" base_image.tcl] set midImage [makeFile "" mid_image.tcl] set targetImage [makeFile "" target_image.tcl] set addFile [makeFile "return mountWorking" add.data] @@ -338,7 +338,7 @@ test zipfs-4.3 {zipfs lmkimg: stripping password} -constraints zipfs -setup { removeFile $addFile } -result {ok.tcl} test zipfs-4.4 {zipfs lmkimg: final password} -constraints zipfs -setup { - set baseImage [makeFile "return sourceWorking\n\x1a" base_image.tcl] + set baseImage [makeFile "return sourceWorking\n\x1A" base_image.tcl] set midImage [makeFile "" mid_image.tcl] set targetImage [makeFile "" target_image.tcl] set addFile [makeFile "return mountWorking" add.data] @@ -360,7 +360,7 @@ test zipfs-4.4 {zipfs lmkimg: final password} -constraints zipfs -setup { removeFile $addFile } -result {ok.tcl} test zipfs-4.5 {zipfs lmkimg: making image from mounted} -constraints zipfs -setup { - set baseImage [makeFile "return sourceWorking\n\x1a" base_image.tcl] + set baseImage [makeFile "return sourceWorking\n\x1A" base_image.tcl] set midImage [makeFile "" mid_image.tcl] set targetImage [makeFile "" target_image.tcl] set addFile [makeFile "return mountWorking" add.data] -- cgit v0.12 From 2dab8fa488cce34d6dc5538612f1b1fba01c8ab5 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 30 Mar 2021 08:22:26 +0000 Subject: Refactoring, ahoy --- generic/tclInt.h | 49 ++- generic/tclNotify.c | 286 +++++++++++++++++- macosx/tclMacOSXNotify.c | 244 +++++++-------- unix/Makefile.in | 9 +- unix/tclEpollNotfy.c | 153 ++-------- unix/tclKqueueNotfy.c | 463 ++++++++++++---------------- unix/tclSelectNotfy.c | 767 +++++++++++++++++++++++------------------------ unix/tclUnixEvent.c | 2 +- unix/tclUnixNotfy.c | 139 ++++++--- unix/tclUnixTime.c | 51 ++-- unix/tclXtNotify.c | 8 +- win/tclWinNotify.c | 493 +++++++++++++++--------------- win/tclWinTime.c | 468 ++++++++++++++++++----------- 13 files changed, 1719 insertions(+), 1413 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 4c3977a..dd3a3a6 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2739,7 +2739,6 @@ MODULE_SCOPE char *tclNativeExecutableName; MODULE_SCOPE int tclFindExecutableSearchDone; MODULE_SCOPE char *tclMemDumpFileName; MODULE_SCOPE TclPlatformType tclPlatform; -MODULE_SCOPE Tcl_NotifierProcs tclNotifierHooks; MODULE_SCOPE Tcl_Encoding tclIdentityEncoding; @@ -3133,12 +3132,21 @@ MODULE_SCOPE int TclProcessReturn(Tcl_Interp *interp, int code, int level, Tcl_Obj *returnOpts); MODULE_SCOPE int TclpObjLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); MODULE_SCOPE Tcl_Obj * TclpTempFileName(void); -MODULE_SCOPE Tcl_Obj * TclpTempFileNameForLibrary(Tcl_Interp *interp, Tcl_Obj* pathPtr); +MODULE_SCOPE Tcl_Obj * TclpTempFileNameForLibrary(Tcl_Interp *interp, + Tcl_Obj* pathPtr); MODULE_SCOPE Tcl_Obj * TclNewFSPathObj(Tcl_Obj *dirPtr, const char *addStrRep, int len); +MODULE_SCOPE void TclpAlertNotifier(ClientData clientData); +MODULE_SCOPE void TclpServiceModeHook(int mode); +MODULE_SCOPE void TclpSetTimer(const Tcl_Time *timePtr); +MODULE_SCOPE int TclpWaitForEvent(const Tcl_Time *timePtr); +MODULE_SCOPE void TclpCreateFileHandler(int fd, int mask, + Tcl_FileProc *proc, ClientData clientData); MODULE_SCOPE int TclpDeleteFile(const void *path); +MODULE_SCOPE void TclpDeleteFileHandler(int fd); MODULE_SCOPE void TclpFinalizeCondition(Tcl_Condition *condPtr); MODULE_SCOPE void TclpFinalizeMutex(Tcl_Mutex *mutexPtr); +MODULE_SCOPE void TclpFinalizeNotifier(ClientData clientData); MODULE_SCOPE void TclpFinalizePipes(void); MODULE_SCOPE void TclpFinalizeSockets(void); MODULE_SCOPE int TclCreateSocketAddress(Tcl_Interp *interp, @@ -3152,6 +3160,7 @@ MODULE_SCOPE int TclpFindVariable(const char *name, int *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, unsigned int *lengthPtr, Tcl_Encoding *encodingPtr); MODULE_SCOPE void TclpInitLock(void); +MODULE_SCOPE ClientData TclpInitNotifier(void); MODULE_SCOPE void TclpInitPlatform(void); MODULE_SCOPE void TclpInitUnlock(void); MODULE_SCOPE Tcl_Obj * TclpObjListVolumes(void); @@ -3178,8 +3187,9 @@ MODULE_SCOPE int TclpObjChdir(Tcl_Obj *pathPtr); MODULE_SCOPE Tcl_Channel TclpOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); -MODULE_SCOPE void TclPkgFileSeen(Tcl_Interp *interp, const char *fileName); -MODULE_SCOPE void *TclInitPkgFiles(Tcl_Interp *interp); +MODULE_SCOPE void TclPkgFileSeen(Tcl_Interp *interp, + const char *fileName); +MODULE_SCOPE void * TclInitPkgFiles(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclPathPart(Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_PathPart portion); MODULE_SCOPE char * TclpReadlink(const char *fileName, @@ -4212,6 +4222,37 @@ MODULE_SCOPE int TclIndexDecode(int encoded, int endValue); #define TCL_INDEX_START (0) /* + *---------------------------------------------------------------------- + * + * TclScaleTime -- + * + * TIP #233 (Virtualized Time): Wrapper around the time virutalisation + * rescale function to hide the binding of the clientData. + * + * This is static inline code; it's like a macro, but a function. It's + * used because this is a piece of code that ends up in places that are a + * bit performance sensitive. + * + * Results: + * None + * + * Side effects: + * Updates the time structure (given as an argument) with what the time + * should be after virtualisation. + * + *---------------------------------------------------------------------- + */ + +static inline void +TclScaleTime( + Tcl_Time *timePtr) +{ + if (timePtr != NULL) { + tclScaleTimeProcPtr(timePtr, tclTimeClientData); + } +} + +/* *---------------------------------------------------------------- * Macros used by the Tcl core to create and release Tcl objects. * TclNewObj(objPtr) creates a new object denoting an empty string. diff --git a/generic/tclNotify.c b/generic/tclNotify.c index b43413d..fbf8360 100644 --- a/generic/tclNotify.c +++ b/generic/tclNotify.c @@ -10,6 +10,7 @@ * Copyright © 1995-1997 Sun Microsystems, Inc. * Copyright © 1998 Scriptics Corporation. * Copyright © 2003 Kevin B. Kenny. All rights reserved. + * Copyright © 2021 Donal K. Fellows * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -18,11 +19,11 @@ #include "tclInt.h" /* - * Module-scope struct of notifier hooks that are checked in the default + * Notifier hooks that are checked in the public wrappers for the default * notifier functions (for overriding via Tcl_SetNotifier). */ -Tcl_NotifierProcs tclNotifierHooks = { +static Tcl_NotifierProcs tclNotifierHooks = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; @@ -174,7 +175,8 @@ TclFinalizeNotifier(void) Tcl_Event *evPtr, *hold; if (!tsdPtr->initialized) { - return; /* Notifier not initialized for the current thread */ + return; /* Notifier not initialized for the current + * thread. */ } Tcl_MutexLock(&(tsdPtr->queueMutex)); @@ -227,6 +229,36 @@ Tcl_SetNotifier( Tcl_NotifierProcs *notifierProcPtr) { tclNotifierHooks = *notifierProcPtr; + + /* + * Don't allow hooks to refer to the hook point functions; avoids infinite + * loop. + */ + + if (tclNotifierHooks.createFileHandlerProc == Tcl_CreateFileHandler) { + tclNotifierHooks.createFileHandlerProc = NULL; + } + if (tclNotifierHooks.deleteFileHandlerProc == Tcl_DeleteFileHandler) { + tclNotifierHooks.deleteFileHandlerProc = NULL; + } + if (tclNotifierHooks.setTimerProc == Tcl_SetTimer) { + tclNotifierHooks.setTimerProc = NULL; + } + if (tclNotifierHooks.waitForEventProc == Tcl_WaitForEvent) { + tclNotifierHooks.waitForEventProc = NULL; + } + if (tclNotifierHooks.initNotifierProc == Tcl_InitNotifier) { + tclNotifierHooks.initNotifierProc = NULL; + } + if (tclNotifierHooks.finalizeNotifierProc == Tcl_FinalizeNotifier) { + tclNotifierHooks.finalizeNotifierProc = NULL; + } + if (tclNotifierHooks.alertNotifierProc == Tcl_AlertNotifier) { + tclNotifierHooks.alertNotifierProc = NULL; + } + if (tclNotifierHooks.serviceModeHookProc == Tcl_ServiceModeHook) { + tclNotifierHooks.serviceModeHookProc = NULL; + } } /* @@ -276,7 +308,7 @@ Tcl_CreateEventSource( * checkProc. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - EventSource *sourcePtr = (EventSource *)ckalloc(sizeof(EventSource)); + EventSource *sourcePtr = (EventSource *) ckalloc(sizeof(EventSource)); sourcePtr->setupProc = setupProc; sourcePtr->checkProc = checkProc; @@ -794,7 +826,7 @@ Tcl_SetServiceMode( void Tcl_SetMaxBlockTime( - const Tcl_Time *timePtr) /* Specifies a maximum elapsed time for the + const Tcl_Time *timePtr) /* Specifies a maximum elapsed time for the * next blocking operation in the event * tsdPtr-> */ { @@ -1133,6 +1165,250 @@ Tcl_ThreadAlert( } /* + *---------------------------------------------------------------------- + * + * Tcl_InitNotifier -- + * + * Initializes the platform specific notifier state. Forwards to the + * platform implementation when the hook is not enabled. + * + * Results: + * Returns a handle to the notifier state for this thread.. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +ClientData +Tcl_InitNotifier(void) +{ + if (tclNotifierHooks.initNotifierProc) { + return tclNotifierHooks.initNotifierProc(); + } else { + return TclpInitNotifier(); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_FinalizeNotifier -- + * + * This function is called to cleanup the notifier state before a thread + * is terminated. Forwards to the platform implementation when the hook + * is not enabled. + * + * Results: + * None. + * + * Side effects: + * If no finalizeNotifierProc notifier hook exists, TclpFinalizeNotifier + * is called. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_FinalizeNotifier( + ClientData clientData) +{ + if (tclNotifierHooks.finalizeNotifierProc) { + tclNotifierHooks.finalizeNotifierProc(clientData); + } else { + TclpFinalizeNotifier(clientData); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_CreateFileHandler -- + * + * This function registers a file descriptor handler with the notifier. + * Forwards to the platform implementation when the hook is not enabled. + * + * Results: + * None. + * + * Side effects: + * Creates a new file handler structure. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_CreateFileHandler( + int fd, /* Handle of stream to watch. */ + int mask, /* OR'ed combination of TCL_READABLE, + * TCL_WRITABLE, and TCL_EXCEPTION: indicates + * conditions under which proc should be + * called. */ + Tcl_FileProc *proc, /* Function to call for each selected + * event. */ + ClientData clientData) /* Arbitrary data to pass to proc. */ +{ + if (tclNotifierHooks.createFileHandlerProc) { + tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData); + } else { + TclpCreateFileHandler(fd, mask, proc, clientData); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_DeleteFileHandler -- + * + * Cancel a previously-arranged callback arrangement for a file + * descriptor. Forwards to the platform implementation when the hook is + * not enabled. + * + * Results: + * None. + * + * Side effects: + * If a callback was previously registered on the file descriptor, remove + * it. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_DeleteFileHandler( + int fd) /* Stream id for which to remove callback + * function. */ +{ + if (tclNotifierHooks.deleteFileHandlerProc) { + tclNotifierHooks.deleteFileHandlerProc(fd); + } else { + TclpDeleteFileHandler(fd); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AlertNotifier -- + * + * Wake up the specified notifier from any thread. This routine is called + * by the platform independent notifier code whenever the Tcl_ThreadAlert + * routine is called. This routine is guaranteed not to be called by Tcl + * on a given notifier after Tcl_FinalizeNotifier is called for that + * notifier. This routine is typically called from a thread other than + * the notifier's thread. Forwards to the platform implementation when + * the hook is not enabled. + * + * Results: + * None. + * + * Side effects: + * See the platform-specific implementations. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_AlertNotifier( + ClientData clientData) /* Pointer to thread data. */ +{ + if (tclNotifierHooks.alertNotifierProc) { + tclNotifierHooks.alertNotifierProc(clientData); + } else { + TclpAlertNotifier(clientData); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_ServiceModeHook -- + * + * This function is invoked whenever the service mode changes. Forwards + * to the platform implementation when the hook is not enabled. + * + * Results: + * None. + * + * Side effects: + * See the platform-specific implementations. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_ServiceModeHook( + int mode) /* Either TCL_SERVICE_ALL, or + * TCL_SERVICE_NONE. */ +{ + if (tclNotifierHooks.serviceModeHookProc) { + tclNotifierHooks.serviceModeHookProc(mode); + } else { + TclpServiceModeHook(mode); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_SetTimer -- + * + * This function sets the current notifier timer value. Forwards to the + * platform implementation when the hook is not enabled. + * + * Results: + * None. + * + * Side effects: + * See the platform-specific implementations. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_SetTimer( + const Tcl_Time *timePtr) /* Timeout value, may be NULL. */ +{ + if (tclNotifierHooks.setTimerProc) { + tclNotifierHooks.setTimerProc(timePtr); + } else { + TclpSetTimer(timePtr); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_WaitForEvent -- + * + * This function is called by Tcl_DoOneEvent to wait for new events on + * the notifier's message queue. If the block time is 0, then + * Tcl_WaitForEvent just polls without blocking. Forwards to the + * platform implementation when the hook is not enabled. + * + * Results: + * Returns -1 if the wait would block forever, 1 if an out-of-loop source + * was processed (see platform-specific notes) and otherwise returns 0. + * + * Side effects: + * Queues file events that are detected by the notifier. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_WaitForEvent( + const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ +{ + if (tclNotifierHooks.waitForEventProc) { + return tclNotifierHooks.waitForEventProc(timePtr); + } else { + return TclpWaitForEvent(timePtr); + } +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/macosx/tclMacOSXNotify.c b/macosx/tclMacOSXNotify.c index 5bdc5a3..c870a36 100644 --- a/macosx/tclMacOSXNotify.c +++ b/macosx/tclMacOSXNotify.c @@ -534,7 +534,58 @@ MODULE_SCOPE long tclMacOSXDarwinRelease; /* *---------------------------------------------------------------------- * - * Tcl_InitNotifier -- + * LookUpFileHandler -- + * + * Look up the file handler structure (and optionally the previous one in + * the chain) associated with a file descriptor. + * + * Returns: + * A pointer to the file handler, or NULL if it can't be found. + * + * Side effects: + * If prevPtrPtr is non-NULL, it will be written to if the file handler + * is found. + * + *---------------------------------------------------------------------- + */ + +static inline FileHandler * +LookUpFileHandler( + ThreadSpecificData *tsdPtr, /* Where to look things up. */ + int fd, /* What we are looking for. */ + FileHandler **prevPtrPtr) /* If non-NULL, where to report the previous + * pointer. */ +{ + FileHandler *filePtr, *prevPtr; + + /* + * Find the entry for the given file (and return if there isn't one). + */ + + for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; + prevPtr = filePtr, filePtr = filePtr->nextPtr) { + if (filePtr == NULL) { + return NULL; + } + if (filePtr->fd == fd) { + break; + } + } + + /* + * Report what we've found to our caller. + */ + + if (prevPtrPtr) { + *prevPtrPtr = prevPtr; + } + return filePtr; +} + +/* + *---------------------------------------------------------------------- + * + * TclpInitNotifier -- * * Initializes the platform specific notifier state. * @@ -548,22 +599,16 @@ MODULE_SCOPE long tclMacOSXDarwinRelease; */ ClientData -Tcl_InitNotifier(void) +TclpInitNotifier(void) { - ThreadSpecificData *tsdPtr; - - if (tclNotifierHooks.initNotifierProc) { - return tclNotifierHooks.initNotifierProc(); - } - - tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); #ifdef WEAK_IMPORT_SPINLOCKLOCK /* * Initialize support for weakly imported spinlock API. */ if (pthread_once(&spinLockLockInitControl, SpinLockLockInit)) { - Tcl_Panic("Tcl_InitNotifier: pthread_once failed"); + Tcl_Panic("Tcl_InitNotifier: %s", "pthread_once failed"); } #endif @@ -590,7 +635,8 @@ Tcl_InitNotifier(void) runLoopSource = CFRunLoopSourceCreate(NULL, LONG_MIN, &runLoopSourceContext); if (!runLoopSource) { - Tcl_Panic("Tcl_InitNotifier: could not create CFRunLoopSource"); + Tcl_Panic("Tcl_InitNotifier: %s", + "could not create CFRunLoopSource"); } CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopCommonModes); CFRunLoopAddSource(runLoop, runLoopSource, tclEventsOnlyRunLoopMode); @@ -602,8 +648,8 @@ Tcl_InitNotifier(void) LONG_MIN, UpdateWaitingListAndServiceEvents, &runLoopObserverContext); if (!runLoopObserver) { - Tcl_Panic("Tcl_InitNotifier: could not create " - "CFRunLoopObserver"); + Tcl_Panic("Tcl_InitNotifier: %s", + "could not create CFRunLoopObserver"); } CFRunLoopAddObserver(runLoop, runLoopObserver, kCFRunLoopCommonModes); @@ -620,8 +666,8 @@ Tcl_InitNotifier(void) LONG_MIN, UpdateWaitingListAndServiceEvents, &runLoopObserverContext); if (!runLoopObserverTcl) { - Tcl_Panic("Tcl_InitNotifier: could not create " - "CFRunLoopObserver"); + Tcl_Panic("Tcl_InitNotifier: %s", + "could not create CFRunLoopObserver"); } CFRunLoopAddObserver(runLoop, runLoopObserverTcl, tclEventsOnlyRunLoopMode); @@ -650,7 +696,7 @@ Tcl_InitNotifier(void) int result = pthread_atfork(AtForkPrepare, AtForkParent, AtForkChild); if (result) { - Tcl_Panic("Tcl_InitNotifier: pthread_atfork failed"); + Tcl_Panic("Tcl_InitNotifier: %s", "pthread_atfork failed"); } atForkInit = 1; } @@ -663,20 +709,20 @@ Tcl_InitNotifier(void) */ if (pipe(fds) != 0) { - Tcl_Panic("Tcl_InitNotifier: could not create trigger pipe"); + Tcl_Panic("Tcl_InitNotifier: %s", "could not create trigger pipe"); } status = fcntl(fds[0], F_GETFL); status |= O_NONBLOCK; if (fcntl(fds[0], F_SETFL, status) < 0) { - Tcl_Panic("Tcl_InitNotifier: could not make receive pipe non " - "blocking"); + Tcl_Panic("Tcl_InitNotifier: %s", + "could not make receive pipe non-blocking"); } status = fcntl(fds[1], F_GETFL); status |= O_NONBLOCK; if (fcntl(fds[1], F_SETFL, status) < 0) { - Tcl_Panic("Tcl_InitNotifier: could not make trigger pipe non " - "blocking"); + Tcl_Panic("Tcl_InitNotifier: %s", + "could not make trigger pipe non-blocking"); } receivePipe = fds[0]; @@ -762,7 +808,7 @@ StartNotifierThread(void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_attr_setstacksize(&attr, 60 * 1024); result = pthread_create(¬ifierThread, &attr, - (void * (*)(void *))NotifierThreadProc, NULL); + (void * (*)(void *)) NotifierThreadProc, NULL); pthread_attr_destroy(&attr); if (result) { Tcl_Panic("StartNotifierThread: unable to start notifier thread"); @@ -776,7 +822,7 @@ StartNotifierThread(void) /* *---------------------------------------------------------------------- * - * Tcl_FinalizeNotifier -- + * TclpFinalizeNotifier -- * * This function is called to cleanup the notifier state before a thread * is terminated. @@ -792,17 +838,10 @@ StartNotifierThread(void) */ void -Tcl_FinalizeNotifier( - ClientData clientData) +TclpFinalizeNotifier( + TCL_UNUSED(ClientData)) { - ThreadSpecificData *tsdPtr; - - if (tclNotifierHooks.finalizeNotifierProc) { - tclNotifierHooks.finalizeNotifierProc(clientData); - return; - } - - tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); LOCK_NOTIFIER_INIT; notifierCount--; @@ -876,7 +915,7 @@ Tcl_FinalizeNotifier( /* *---------------------------------------------------------------------- * - * Tcl_AlertNotifier -- + * TclpAlertNotifier -- * * Wake up the specified notifier from any thread. This routine is called * by the platform independent notifier code whenever the Tcl_ThreadAlert @@ -893,15 +932,10 @@ Tcl_FinalizeNotifier( */ void -Tcl_AlertNotifier( +TclpAlertNotifier( ClientData clientData) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *)clientData; - - if (tclNotifierHooks.alertNotifierProc) { - tclNotifierHooks.alertNotifierProc(clientData); - return; - } + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; LOCK_NOTIFIER_TSD; if (tsdPtr->runLoop) { @@ -914,7 +948,7 @@ Tcl_AlertNotifier( /* *---------------------------------------------------------------------- * - * Tcl_SetTimer -- + * TclpSetTimer -- * * This function sets the current notifier timer value. * @@ -928,18 +962,13 @@ Tcl_AlertNotifier( */ void -Tcl_SetTimer( +TclpSetTimer( const Tcl_Time *timePtr) /* Timeout value, may be NULL. */ { ThreadSpecificData *tsdPtr; CFRunLoopTimerRef runLoopTimer; CFTimeInterval waitTime; - if (tclNotifierHooks.setTimerProc) { - tclNotifierHooks.setTimerProc(timePtr); - return; - } - tsdPtr = TCL_TSD_INIT(&dataKey); runLoopTimer = tsdPtr->runLoopTimer; if (!runLoopTimer) { @@ -949,7 +978,7 @@ Tcl_SetTimer( Tcl_Time vTime = *timePtr; if (vTime.sec != 0 || vTime.usec != 0) { - tclScaleTimeProcPtr(&vTime, tclTimeClientData); + TclScaleTime(&vTime); waitTime = vTime.sec + 1.0e-6 * vTime.usec; } else { waitTime = 0; @@ -988,7 +1017,7 @@ TimerWakeUp( /* *---------------------------------------------------------------------- * - * Tcl_ServiceModeHook -- + * TclpServiceModeHook -- * * This function is invoked whenever the service mode changes. * @@ -1002,18 +1031,11 @@ TimerWakeUp( */ void -Tcl_ServiceModeHook( +TclpServiceModeHook( int mode) /* Either TCL_SERVICE_ALL, or * TCL_SERVICE_NONE. */ { - ThreadSpecificData *tsdPtr; - - if (tclNotifierHooks.serviceModeHookProc) { - tclNotifierHooks.serviceModeHookProc(mode); - return; - } - - tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (mode == TCL_SERVICE_ALL && !tsdPtr->runLoopTimer) { if (!tsdPtr->runLoop) { @@ -1033,9 +1055,9 @@ Tcl_ServiceModeHook( /* *---------------------------------------------------------------------- * - * Tcl_CreateFileHandler -- + * TclpCreateFileHandler -- * - * This function registers a file handler with the select notifier. + * This function registers a file handler with the notifier. * * Results: * None. @@ -1047,7 +1069,7 @@ Tcl_ServiceModeHook( */ void -Tcl_CreateFileHandler( +TclpCreateFileHandler( int fd, /* Handle of stream to watch. */ int mask, /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: indicates @@ -1057,24 +1079,11 @@ Tcl_CreateFileHandler( * event. */ ClientData clientData) /* Arbitrary data to pass to proc. */ { - ThreadSpecificData *tsdPtr; - FileHandler *filePtr; - - if (tclNotifierHooks.createFileHandlerProc) { - tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData); - return; - } - - tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + FileHandler *filePtr = LookUpFileHandler(tsdPtr, fd, NULL); - for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; - filePtr = filePtr->nextPtr) { - if (filePtr->fd == fd) { - break; - } - } if (filePtr == NULL) { - filePtr = (FileHandler *)ckalloc(sizeof(FileHandler)); + filePtr = (FileHandler *) ckalloc(sizeof(FileHandler)); filePtr->fd = fd; filePtr->readyMask = 0; filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; @@ -1113,7 +1122,7 @@ Tcl_CreateFileHandler( /* *---------------------------------------------------------------------- * - * Tcl_DeleteFileHandler -- + * TclpDeleteFileHandler -- * * Cancel a previously-arranged callback arrangement for a file. * @@ -1127,47 +1136,34 @@ Tcl_CreateFileHandler( */ void -Tcl_DeleteFileHandler( +TclpDeleteFileHandler( int fd) /* Stream id for which to remove callback * function. */ { FileHandler *filePtr, *prevPtr; - int i, numFdBits; - ThreadSpecificData *tsdPtr; - - if (tclNotifierHooks.deleteFileHandlerProc) { - tclNotifierHooks.deleteFileHandlerProc(fd); - return; - } - - tsdPtr = TCL_TSD_INIT(&dataKey); - numFdBits = -1; + int i, numFdBits = -1; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* * Find the entry for the given file (and return if there isn't one). */ - for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; - prevPtr = filePtr, filePtr = filePtr->nextPtr) { - if (filePtr == NULL) { - return; - } - if (filePtr->fd == fd) { - break; - } + filePtr = LookUpFileHandler(tsdPtr, fd, &prevPtr); + if (filePtr == NULL) { + return; } /* * Find current max fd. */ - if (fd+1 == tsdPtr->numFdBits) { + if (fd + 1 == tsdPtr->numFdBits) { numFdBits = 0; - for (i = fd-1; i >= 0; i--) { + for (i = fd - 1; i >= 0; i--) { if (FD_ISSET(i, &tsdPtr->checkMasks.readable) || FD_ISSET(i, &tsdPtr->checkMasks.writable) || FD_ISSET(i, &tsdPtr->checkMasks.exceptional)) { - numFdBits = i+1; + numFdBits = i + 1; break; } } @@ -1250,12 +1246,8 @@ FileHandlerEventProc( */ tsdPtr = TCL_TSD_INIT(&dataKey); - for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; - filePtr = filePtr->nextPtr) { - if (filePtr->fd != fileEvPtr->fd) { - continue; - } - + filePtr = LookUpFileHandler(tsdPtr, fileEvPtr->fd, NULL); + if (filePtr != NULL) { /* * The code is tricky for two reasons: * 1. The file handler's desired events could have changed since the @@ -1284,7 +1276,6 @@ FileHandlerEventProc( UNLOCK_NOTIFIER_TSD; filePtr->proc(filePtr->clientData, mask); } - break; } return 1; } @@ -1292,7 +1283,7 @@ FileHandlerEventProc( /* *---------------------------------------------------------------------- * - * Tcl_WaitForEvent -- + * TclpWaitForEvent -- * * This function is called by Tcl_DoOneEvent to wait for new events on * the message queue. If the block time is 0, then Tcl_WaitForEvent just @@ -1309,7 +1300,7 @@ FileHandlerEventProc( */ int -Tcl_WaitForEvent( +TclpWaitForEvent( const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ { int result, polling, runLoopRunning; @@ -1317,9 +1308,6 @@ Tcl_WaitForEvent( SInt32 runLoopStatus; ThreadSpecificData *tsdPtr; - if (tclNotifierHooks.waitForEventProc) { - return tclNotifierHooks.waitForEventProc(timePtr); - } result = -1; polling = 0; waitTime = CF_TIMEINTERVAL_FOREVER; @@ -1343,10 +1331,9 @@ Tcl_WaitForEvent( */ if (vTime.sec != 0 || vTime.usec != 0) { - tclScaleTimeProcPtr(&vTime, tclTimeClientData); + TclScaleTime(&vTime); waitTime = vTime.sec + 1.0e-6 * vTime.usec; } else { - /* * The max block time was set to 0. * @@ -1357,8 +1344,8 @@ Tcl_WaitForEvent( * or timers are ready to fire immediately, only one (possibly two * if one is a version 0 source) will be fired, regardless of the * value of returnAfterSourceHandled." This can cause some chanio - * tests to fail. So we use a small positive waitTime unless there - * is another RunLoop running. + * tests to fail. So we use a small positive waitTime unless + * there is another RunLoop running. */ polling = 1; @@ -1431,7 +1418,7 @@ QueueFileEvents( { SelectMasks readyMasks; FileHandler *filePtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *)info; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) info; /* * Queue all detected file events. @@ -1470,7 +1457,8 @@ QueueFileEvents( */ if (filePtr->readyMask == 0) { - FileHandlerEvent *fileEvPtr = (FileHandlerEvent *)ckalloc(sizeof(FileHandlerEvent)); + FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) + ckalloc(sizeof(FileHandlerEvent)); fileEvPtr->header.proc = FileHandlerEventProc; fileEvPtr->fd = filePtr->fd; @@ -1485,8 +1473,8 @@ QueueFileEvents( * * UpdateWaitingListAndServiceEvents -- * - * CFRunLoopObserver callback for updating waitingList and - * servicing Tcl events. + * CFRunLoopObserver callback for updating waitingList and servicing Tcl + * events. * * Results: * None. @@ -1503,7 +1491,8 @@ UpdateWaitingListAndServiceEvents( CFRunLoopActivity activity, void *info) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *)info; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) info; + if (tsdPtr->sleeping) { return; } @@ -1626,8 +1615,7 @@ Tcl_Sleep( vdelay.sec = ms / 1000; vdelay.usec = (ms % 1000) * 1000; - tclScaleTimeProcPtr(&vdelay, tclTimeClientData); - + TclScaleTime(&vdelay); if (tsdPtr->runLoop) { CFTimeInterval waitTime; @@ -1853,7 +1841,7 @@ TclUnixWaitForFile( * * Result: * None. Once started, this routine never exits. It dies with the overall - * process. + * process or terminates its own thread (on notifier termination). * * Side effects: * The trigger pipe used to signal the notifier thread is created when @@ -2090,9 +2078,9 @@ AtForkChild(void) ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* - * If a child process unlocks an os_unfair_lock that was created in its parent - * the child will exit with an illegal instruction error. So we reinitialize - * the lock in the child rather than attempt to unlock it. + * If a child process unlocks an os_unfair_lock that was created in its + * parent the child will exit with an illegal instruction error. So we + * reinitialize the lock in the child rather than attempt to unlock it. */ #if defined(USE_OS_UNFAIR_LOCK) diff --git a/unix/Makefile.in b/unix/Makefile.in index 30e2104..5a06a1d 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -671,7 +671,8 @@ UNIX_SRCS = \ NOTIFY_SRCS = \ $(UNIX_DIR)/tclEpollNotfy.c \ $(UNIX_DIR)/tclKqueueNotfy.c \ - $(UNIX_DIR)/tclSelectNotfy.c + $(UNIX_DIR)/tclSelectNotfy.c \ + $(UNIX_DIR)/tclUnixNotfy.c DL_SRCS = \ $(UNIX_DIR)/tclLoadAix.c \ @@ -1772,13 +1773,13 @@ tclUnixFCmd.o: $(UNIX_DIR)/tclUnixFCmd.c tclUnixFile.o: $(UNIX_DIR)/tclUnixFile.c $(FSHDR) $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixFile.c -tclEpollNotfy.o: $(UNIX_DIR)/tclEpollNotfy.c +tclEpollNotfy.o: $(UNIX_DIR)/tclEpollNotfy.c $(UNIX_DIR)/tclUnixNotfy.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclEpollNotfy.c -tclKqueueNotfy.o: $(UNIX_DIR)/tclKqueueNotfy.c +tclKqueueNotfy.o: $(UNIX_DIR)/tclKqueueNotfy.c $(UNIX_DIR)/tclUnixNotfy.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclKqueueNotfy.c -tclSelectNotfy.o: $(UNIX_DIR)/tclSelectNotfy.c +tclSelectNotfy.o: $(UNIX_DIR)/tclSelectNotfy.c $(UNIX_DIR)/tclUnixNotfy.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclSelectNotfy.c tclUnixPipe.o: $(UNIX_DIR)/tclUnixPipe.c diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c index 5de6c90..23c88b2 100644 --- a/unix/tclEpollNotfy.c +++ b/unix/tclEpollNotfy.c @@ -97,7 +97,7 @@ typedef struct ThreadSpecificData { * that are ready for I/O. */ pthread_mutex_t notifierMutex; /* Mutex protecting notifier termination in - * PlatformEventsFinalize. */ + * TclpFinalizeNotifier. */ #ifdef HAVE_EVENTFD int triggerEventFd; /* eventfd(2) used by other threads to wake * up this thread for inter-thread IPC. */ @@ -119,20 +119,15 @@ static Tcl_ThreadDataKey dataKey; * Forward declarations. */ -static void PlatformCreateFileHandler(int fd, int mask, - Tcl_FileProc *proc, ClientData clientData); -static void PlatformDeleteFileHandler(int fd) static void PlatformEventsControl(FileHandler *filePtr, ThreadSpecificData *tsdPtr, int op, int isNew); -static void PlatformEventsFinalize(void); static void PlatformEventsInit(void); static int PlatformEventsTranslate(struct epoll_event *event); static int PlatformEventsWait(struct epoll_event *events, size_t numEvents, struct timeval *timePtr); -static int PlatformWaitForEvent(const Tcl_Time *timePtr); - + /* - * Incorporate the base notifier API. + * Incorporate the base notifier implementation. */ #include "tclUnixNotfy.c" @@ -140,7 +135,7 @@ static int PlatformWaitForEvent(const Tcl_Time *timePtr); /* *---------------------------------------------------------------------- * - * Tcl_InitNotifier -- + * TclpInitNotifier -- * * Initializes the platform specific notifier state. * @@ -155,47 +150,14 @@ static int PlatformWaitForEvent(const Tcl_Time *timePtr); */ ClientData -Tcl_InitNotifier(void) +TclpInitNotifier(void) { - if (tclNotifierHooks.initNotifierProc) { - return tclNotifierHooks.initNotifierProc(); - } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - PlatformEventsInit(); - return tsdPtr; - } + PlatformEventsInit(); + return tsdPtr; } -/* - *---------------------------------------------------------------------- - * - * Tcl_FinalizeNotifier -- - * - * This function is called to cleanup the notifier state before a thread - * is terminated. - * - * Results: - * None. - * - * Side effects: - * If no finalizeNotifierProc notifier hook exists, PlatformEvents- - * Finalize is called. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_FinalizeNotifier( - ClientData clientData) -{ - if (tclNotifierHooks.finalizeNotifierProc) { - tclNotifierHooks.finalizeNotifierProc(clientData); - return; - } else { - PlatformEventsFinalize(); - } -} /* *---------------------------------------------------------------------- @@ -282,7 +244,7 @@ PlatformEventsControl( /* *---------------------------------------------------------------------- * - * PlatformEventsFinalize -- + * TclpFinalizeNotifier -- * * This function closes the eventfd and the epoll file descriptor and * frees the epoll_event structs owned by the thread of the caller. The @@ -303,8 +265,9 @@ PlatformEventsControl( *---------------------------------------------------------------------- */ -static void -PlatformEventsFinalize(void) +void +TclpFinalizeNotifier( + TCL_UNUSED(ClientData)) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -376,7 +339,7 @@ PlatformEventsInit(void) if (errno) { Tcl_Panic("Tcl_InitNotifier: %s", "could not create mutex"); } - filePtr = (FileHandler *)ckalloc(sizeof(FileHandler)); + filePtr = (FileHandler *) ckalloc(sizeof(FileHandler)); #ifdef HAVE_EVENTFD tsdPtr->triggerEventFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (tsdPtr->triggerEventFd <= 0) { @@ -484,9 +447,9 @@ PlatformEventsWait( } else if (!timePtr->tv_sec && !timePtr->tv_usec) { timeout = 0; } else { - timeout = (int)timePtr->tv_sec * 1000; + timeout = (int) timePtr->tv_sec * 1000; if (timePtr->tv_usec) { - timeout += (int)timePtr->tv_usec / 1000; + timeout += (int) timePtr->tv_usec / 1000; } } @@ -497,7 +460,7 @@ PlatformEventsWait( */ gettimeofday(&tv0, NULL); - numFound = epoll_wait(tsdPtr->eventsFd, events, (int)numEvents, timeout); + numFound = epoll_wait(tsdPtr->eventsFd, events, (int) numEvents, timeout); gettimeofday(&tv1, NULL); if (timePtr && (timePtr->tv_sec && timePtr->tv_usec)) { timersub(&tv1, &tv0, &tv_delta); @@ -514,7 +477,7 @@ PlatformEventsWait( /* *---------------------------------------------------------------------- * - * Tcl_CreateFileHandler, CreateFileHandler -- + * TclpCreateFileHandler -- * * This function registers a file handler with the epoll notifier of the * thread of the caller. @@ -530,27 +493,7 @@ PlatformEventsWait( */ void -Tcl_CreateFileHandler( - int fd, /* Handle of stream to watch. */ - int mask, /* OR'ed combination of TCL_READABLE, - * TCL_WRITABLE, and TCL_EXCEPTION: indicates - * conditions under which proc should be - * called. */ - Tcl_FileProc *proc, /* Function to call for each selected - * event. */ - ClientData clientData) /* Arbitrary data to pass to proc. */ -{ - int isNew; - - if (tclNotifierHooks.createFileHandlerProc) { - tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData); - } else { - PlatformCreateFileHandler(fd, mask, proc, clientData); - } -} - -static void -PlatformCreateFileHandler( +TclpCreateFileHandler( int fd, /* Handle of stream to watch. */ int mask, /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: indicates @@ -561,23 +504,15 @@ PlatformCreateFileHandler( ClientData clientData) /* Arbitrary data to pass to proc. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - FileHandler *filePtr; + FileHandler *filePtr = LookUpFileHandler(tsdPtr, fd, NULL); + int isNew = (filePtr == NULL); - for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; - filePtr = filePtr->nextPtr) { - if (filePtr->fd == fd) { - break; - } - } - if (filePtr == NULL) { + if (isNew) { filePtr = (FileHandler *) ckalloc(sizeof(FileHandler)); filePtr->fd = fd; filePtr->readyMask = 0; filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; tsdPtr->firstFileHandlerPtr = filePtr; - isNew = 1; - } else { - isNew = 0; } filePtr->proc = proc; filePtr->clientData = clientData; @@ -590,7 +525,7 @@ PlatformCreateFileHandler( /* *---------------------------------------------------------------------- * - * Tcl_DeleteFileHandler, PlatformDeleteFileHandler -- + * TclpDeleteFileHandler -- * * Cancel a previously-arranged callback arrangement for a file on the * epoll file descriptor of the thread of the caller. @@ -608,19 +543,7 @@ PlatformCreateFileHandler( */ void -Tcl_DeleteFileHandler( - int fd) /* Stream id for which to remove callback - * function. */ -{ - if (tclNotifierHooks.deleteFileHandlerProc) { - tclNotifierHooks.deleteFileHandlerProc(fd); - } else { - PlatformDeleteFileHandler(fd); - } -} - -static void -PlatformDeleteFileHandler( +TclpDeleteFileHandler( int fd) /* Stream id for which to remove callback * function. */ { @@ -631,14 +554,9 @@ PlatformDeleteFileHandler( * Find the entry for the given file (and return if there isn't one). */ - for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; - prevPtr = filePtr, filePtr = filePtr->nextPtr) { - if (filePtr == NULL) { - return; - } - if (filePtr->fd == fd) { - break; - } + filePtr = LookUpFileHandler(tsdPtr, fd, &prevPtr); + if (filePtr == NULL) { + return; } /* @@ -665,10 +583,10 @@ PlatformDeleteFileHandler( /* *---------------------------------------------------------------------- * - * Tcl_WaitForEvent, PlatformWaitForEvent -- + * TclpWaitForEvent -- * * This function is called by Tcl_DoOneEvent to wait for new events on - * the message queue. If the block time is 0, then Tcl_WaitForEvent just + * the message queue. If the block time is 0, then TclpWaitForEvent just * polls without blocking. * * The waiting logic is implemented in PlatformEventsWait. @@ -684,18 +602,7 @@ PlatformDeleteFileHandler( */ int -Tcl_WaitForEvent( - const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ -{ - if (tclNotifierHooks.waitForEventProc) { - return tclNotifierHooks.waitForEventProc(timePtr); - } else { - return PlatformWaitForEvent(timePtr); - } -} - -static int -PlatformWaitForEvent( +TclpWaitForEvent( const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ { FileHandler *filePtr; @@ -726,7 +633,7 @@ PlatformWaitForEvent( if (timePtr->sec != 0 || timePtr->usec != 0) { vTime = *timePtr; - tclScaleTimeProcPtr(&vTime, tclTimeClientData); + TclScaleTime(&vTime); timePtr = &vTime; } timeout.tv_sec = timePtr->sec; diff --git a/unix/tclKqueueNotfy.c b/unix/tclKqueueNotfy.c index fbd38dc..7cacde2 100644 --- a/unix/tclKqueueNotfy.c +++ b/unix/tclKqueueNotfy.c @@ -31,7 +31,8 @@ struct PlatformEventData; typedef struct FileHandler { - int fd; + int fd; /* File descriptor that this is describing a + * handler for. */ int mask; /* Mask of desired events: TCL_READABLE, * etc. */ int readyMask; /* Mask of events that have been seen since @@ -93,7 +94,7 @@ typedef struct ThreadSpecificData { * that are ready for I/O. */ pthread_mutex_t notifierMutex; /* Mutex protecting notifier termination in - * PlatformEventsFinalize. */ + * TclpFinalizeNotifier. */ int triggerPipe[2]; /* pipe(2) used by other threads to wake * up this thread for inter-thread IPC. */ int eventsFd; /* kqueue(2) file descriptor used to wait for @@ -111,73 +112,15 @@ static Tcl_ThreadDataKey dataKey; static void PlatformEventsControl(FileHandler *filePtr, ThreadSpecificData *tsdPtr, int op, int isNew); -static void PlatformEventsFinalize(void); -static void PlatformEventsInit(void); static int PlatformEventsTranslate(struct kevent *eventPtr); static int PlatformEventsWait(struct kevent *events, size_t numEvents, struct timeval *timePtr); - -#include "tclUnixNotfy.c" - -/* - *---------------------------------------------------------------------- - * - * Tcl_InitNotifier -- - * - * Initializes the platform specific notifier state. - * - * Results: - * Returns a handle to the notifier state for this thread. - * - * Side effects: - * If no initNotifierProc notifier hook exists, PlatformEventsInit - * is called. - * - *---------------------------------------------------------------------- - */ - -ClientData -Tcl_InitNotifier(void) -{ - if (tclNotifierHooks.initNotifierProc) { - return tclNotifierHooks.initNotifierProc(); - } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - PlatformEventsInit(); - return tsdPtr; - } -} /* - *---------------------------------------------------------------------- - * - * Tcl_FinalizeNotifier -- - * - * This function is called to cleanup the notifier state before a thread - * is terminated. - * - * Results: - * None. - * - * Side effects: - * If no finalizeNotifierProc notifier hook exists, PlatformEvents- - * Finalize is called. - * - *---------------------------------------------------------------------- + * Incorporate the base notifier implementation. */ -void -Tcl_FinalizeNotifier( - ClientData clientData) -{ - if (tclNotifierHooks.finalizeNotifierProc) { - tclNotifierHooks.finalizeNotifierProc(clientData); - return; - } else { - PlatformEventsFinalize(); - } -} +#include "tclUnixNotfy.c" /* *---------------------------------------------------------------------- @@ -258,12 +201,12 @@ PlatformEventsControl( switch (op) { case EV_ADD: if (filePtr->mask & (TCL_READABLE | TCL_EXCEPTION)) { - EV_SET(&changeList[numChanges], (uintptr_t)filePtr->fd, + EV_SET(&changeList[numChanges], (uintptr_t) filePtr->fd, EVFILT_READ, op, 0, 0, filePtr->pedPtr); numChanges++; } if (filePtr->mask & TCL_WRITABLE) { - EV_SET(&changeList[numChanges], (uintptr_t)filePtr->fd, + EV_SET(&changeList[numChanges], (uintptr_t) filePtr->fd, EVFILT_WRITE, op, 0, 0, filePtr->pedPtr); numChanges++; } @@ -285,13 +228,13 @@ PlatformEventsControl( * As one of these calls can fail, two separate kevent(2) calls are * made for EVFILT_{READ,WRITE}. */ - EV_SET(&changeList[0], (uintptr_t)filePtr->fd, EVFILT_READ, op, 0, 0, + EV_SET(&changeList[0], (uintptr_t) filePtr->fd, EVFILT_READ, op, 0, 0, NULL); if ((kevent(tsdPtr->eventsFd, changeList, 1, NULL, 0, NULL) == -1) && (errno != ENOENT)) { Tcl_Panic("kevent: %s", strerror(errno)); } - EV_SET(&changeList[0], (uintptr_t)filePtr->fd, EVFILT_WRITE, op, 0, 0, + EV_SET(&changeList[0], (uintptr_t) filePtr->fd, EVFILT_WRITE, op, 0, 0, NULL); if ((kevent(tsdPtr->eventsFd, changeList, 1, NULL, 0, NULL) == -1) && (errno != ENOENT)) { @@ -304,7 +247,7 @@ PlatformEventsControl( /* *---------------------------------------------------------------------- * - * PlatformEventsFinalize -- + * TclpFinalizeNotifier -- * * This function closes the pipe and the kqueue file descriptors and * frees the kevent structs owned by the thread of the caller. The above @@ -325,8 +268,9 @@ PlatformEventsControl( *---------------------------------------------------------------------- */ -static void -PlatformEventsFinalize(void) +void +TclpFinalizeNotifier( + TCL_UNUSED(ClientData)) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -356,14 +300,16 @@ PlatformEventsFinalize(void) /* *---------------------------------------------------------------------- * - * PlatformEventsInit -- + * TclpInitNotifier -- + * + * Initializes the platform specific notifier state. * * This function abstracts creating a kqueue fd via the kqueue system * call and allocating memory for the kevents structs in tsdPtr for the * thread of the caller. * * Results: - * None. + * Returns a handle to the notifier state for this thread. * * Side effects: * The following per-thread entities are initialised: @@ -380,8 +326,8 @@ PlatformEventsFinalize(void) *---------------------------------------------------------------------- */ -static void -PlatformEventsInit(void) +ClientData +TclpInitNotifier(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); int i, fdFl; @@ -409,16 +355,18 @@ PlatformEventsInit(void) } else if (fcntl(tsdPtr->eventsFd, F_SETFD, FD_CLOEXEC) == -1) { Tcl_Panic("fcntl: %s", strerror(errno)); } - filePtr = (FileHandler *)ckalloc(sizeof(FileHandler)); + filePtr = (FileHandler *) ckalloc(sizeof(FileHandler)); filePtr->fd = tsdPtr->triggerPipe[0]; filePtr->mask = TCL_READABLE; PlatformEventsControl(filePtr, tsdPtr, EV_ADD, 1); if (!tsdPtr->readyEvents) { tsdPtr->maxReadyEvents = 512; - tsdPtr->readyEvents = (struct kevent *)ckalloc( + tsdPtr->readyEvents = (struct kevent *) ckalloc( tsdPtr->maxReadyEvents * sizeof(tsdPtr->readyEvents[0])); } LIST_INIT(&tsdPtr->firstReadyFileHandlerPtr); + + return tsdPtr; } /* @@ -538,7 +486,7 @@ PlatformEventsWait( /* *---------------------------------------------------------------------- * - * Tcl_CreateFileHandler -- + * TclpCreateFileHandler -- * * This function registers a file handler with the kqueue notifier * of the thread of the caller. @@ -554,7 +502,7 @@ PlatformEventsWait( */ void -Tcl_CreateFileHandler( +TclpCreateFileHandler( int fd, /* Handle of stream to watch. */ int mask, /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: indicates @@ -564,43 +512,28 @@ Tcl_CreateFileHandler( * event. */ ClientData clientData) /* Arbitrary data to pass to proc. */ { - int isNew; - - if (tclNotifierHooks.createFileHandlerProc) { - tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData); - return; - } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - FileHandler *filePtr; - - for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; - filePtr = filePtr->nextPtr) { - if (filePtr->fd == fd) { - break; - } - } - if (filePtr == NULL) { - filePtr = (FileHandler *)ckalloc(sizeof(FileHandler)); - filePtr->fd = fd; - filePtr->readyMask = 0; - filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; - tsdPtr->firstFileHandlerPtr = filePtr; - isNew = 1; - } else { - isNew = 0; - } - filePtr->proc = proc; - filePtr->clientData = clientData; - filePtr->mask = mask; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + FileHandler *filePtr = LookUpFileHandler(tsdPtr, fd, NULL); + int isNew = (filePtr == NULL); - PlatformEventsControl(filePtr, tsdPtr, EV_ADD, isNew); + if (isNew) { + filePtr = (FileHandler *) ckalloc(sizeof(FileHandler)); + filePtr->fd = fd; + filePtr->readyMask = 0; + filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; + tsdPtr->firstFileHandlerPtr = filePtr; } -} + filePtr->proc = proc; + filePtr->clientData = clientData; + filePtr->mask = mask; + + PlatformEventsControl(filePtr, tsdPtr, EV_ADD, isNew); +} /* *---------------------------------------------------------------------- * - * Tcl_DeleteFileHandler -- + * TclpDeleteFileHandler -- * * Cancel a previously-arranged callback arrangement for a file on the * kqueue of the thread of the caller. @@ -618,60 +551,50 @@ Tcl_CreateFileHandler( */ void -Tcl_DeleteFileHandler( +TclpDeleteFileHandler( int fd) /* Stream id for which to remove callback * function. */ { - if (tclNotifierHooks.deleteFileHandlerProc) { - tclNotifierHooks.deleteFileHandlerProc(fd); - return; - } else { - FileHandler *filePtr, *prevPtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + FileHandler *filePtr, *prevPtr; - /* - * Find the entry for the given file (and return if there isn't one). - */ + /* + * Find the entry for the given file (and return if there isn't one). + */ - for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; - prevPtr = filePtr, filePtr = filePtr->nextPtr) { - if (filePtr == NULL) { - return; - } - if (filePtr->fd == fd) { - break; - } - } + filePtr = LookUpFileHandler(tsdPtr, fd, &prevPtr); + if (filePtr == NULL) { + return; + } - /* - * Update the check masks for this file. - */ + /* + * Update the check masks for this file. + */ - PlatformEventsControl(filePtr, tsdPtr, EV_DELETE, 0); - if (filePtr->pedPtr) { - ckfree(filePtr->pedPtr); - } + PlatformEventsControl(filePtr, tsdPtr, EV_DELETE, 0); + if (filePtr->pedPtr) { + ckfree(filePtr->pedPtr); + } - /* - * Clean up information in the callback record. - */ + /* + * Clean up information in the callback record. + */ - if (prevPtr == NULL) { - tsdPtr->firstFileHandlerPtr = filePtr->nextPtr; - } else { - prevPtr->nextPtr = filePtr->nextPtr; - } - ckfree(filePtr); + if (prevPtr == NULL) { + tsdPtr->firstFileHandlerPtr = filePtr->nextPtr; + } else { + prevPtr->nextPtr = filePtr->nextPtr; } + ckfree(filePtr); } /* *---------------------------------------------------------------------- * - * Tcl_WaitForEvent -- + * TclpWaitForEvent -- * * This function is called by Tcl_DoOneEvent to wait for new events on - * the message queue. If the block time is 0, then Tcl_WaitForEvent just + * the message queue. If the block time is 0, then TclpWaitForEvent just * polls without blocking. * * The waiting logic is implemented in PlatformEventsWait. @@ -687,158 +610,152 @@ Tcl_DeleteFileHandler( */ int -Tcl_WaitForEvent( - const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ +TclpWaitForEvent( + const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ { - if (tclNotifierHooks.waitForEventProc) { - return tclNotifierHooks.waitForEventProc(timePtr); - } else { - FileHandler *filePtr; - int mask; - Tcl_Time vTime; - /* - * Impl. notes: timeout & timeoutPtr are used if, and only if threads - * are not enabled. They are the arguments for the regular epoll_wait() - * used when the core is not thread-enabled. - */ + FileHandler *filePtr; + int mask; + Tcl_Time vTime; + struct timeval timeout, *timeoutPtr; + /* Impl. notes: timeout & timeoutPtr are used + * if, and only if threads are not enabled. + * They are the arguments for the regular + * epoll_wait() used when the core is not + * thread-enabled. */ + int numFound, numEvent; + struct PlatformEventData *pedPtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + int numQueued; + ssize_t i; + char buf[1]; - struct timeval timeout, *timeoutPtr; - int numFound, numEvent; - struct PlatformEventData *pedPtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - int numQueued; - ssize_t i; - char buf[1]; + /* + * Set up the timeout structure. Note that if there are no events to check + * for, we return with a negative result rather than blocking forever. + */ + if (timePtr != NULL) { /* - * Set up the timeout structure. Note that if there are no events to - * check for, we return with a negative result rather than blocking - * forever. + * TIP #233 (Virtualized Time). Is virtual time in effect? And do we + * actually have something to scale? If yes to both then we call the + * handler to do this scaling. */ - if (timePtr != NULL) { - /* - * TIP #233 (Virtualized Time). Is virtual time in effect? And do - * we actually have something to scale? If yes to both then we - * call the handler to do this scaling. - */ - - if (timePtr->sec != 0 || timePtr->usec != 0) { - vTime = *timePtr; - tclScaleTimeProcPtr(&vTime, tclTimeClientData); - timePtr = &vTime; - } - timeout.tv_sec = timePtr->sec; - timeout.tv_usec = timePtr->usec; - timeoutPtr = &timeout; - } else { - timeoutPtr = NULL; + if (timePtr->sec != 0 || timePtr->usec != 0) { + vTime = *timePtr; + TclScaleTime(&vTime); + timePtr = &vTime; + } + timeout.tv_sec = timePtr->sec; + timeout.tv_usec = timePtr->usec; + timeoutPtr = &timeout; + } else { + timeoutPtr = NULL; + } + + /* + * Walk the list of FileHandlers associated with regular files (S_IFREG) + * belonging to tsdPtr, queue Tcl events for them, and update their mask + * of events of interest. + * + * kqueue(2), unlike epoll(7), does support regular files, but EVFILT_READ + * only `[r]eturns when the file pointer is not at the end of file' as + * opposed to unconditionally. While FreeBSD 11.0-RELEASE adds support for + * this mode (NOTE_FILE_POLL,) this is not used for reasons of + * compatibility. + * + * Therefore, the behaviour of {select,poll}(2) is simply simulated here: + * fds associated with regular files are added to this list by + * PlatformEventsControl() and processed here before calling (and possibly + * blocking) on PlatformEventsWait(). + */ + + numQueued = 0; + LIST_FOREACH(filePtr, &tsdPtr->firstReadyFileHandlerPtr, readyNode) { + mask = 0; + if (filePtr->mask & TCL_READABLE) { + mask |= TCL_READABLE; + } + if (filePtr->mask & TCL_WRITABLE) { + mask |= TCL_WRITABLE; } /* - * Walk the list of FileHandlers associated with regular files - * (S_IFREG) belonging to tsdPtr, queue Tcl events for them, and - * update their mask of events of interest. - * - * kqueue(2), unlike epoll(7), does support regular files, but - * EVFILT_READ only `[r]eturns when the file pointer is not at the end - * of file' as opposed to unconditionally. While FreeBSD 11.0-RELEASE - * adds support for this mode (NOTE_FILE_POLL,) this is not used for - * reasons of compatibility. - * - * Therefore, the behaviour of {select,poll}(2) is simply simulated - * here: fds associated with regular files are added to this list by - * PlatformEventsControl() and processed here before calling (and - * possibly blocking) on PlatformEventsWait(). + * Don't bother to queue an event if the mask was previously non-zero + * since an event must still be on the queue. */ - numQueued = 0; - LIST_FOREACH(filePtr, &tsdPtr->firstReadyFileHandlerPtr, readyNode) { - mask = 0; - if (filePtr->mask & TCL_READABLE) { - mask |= TCL_READABLE; - } - if (filePtr->mask & TCL_WRITABLE) { - mask |= TCL_WRITABLE; - } + if (filePtr->readyMask == 0) { + FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) + ckalloc(sizeof(FileHandlerEvent)); - /* - * Don't bother to queue an event if the mask was previously - * non-zero since an event must still be on the queue. - */ + fileEvPtr->header.proc = FileHandlerEventProc; + fileEvPtr->fd = filePtr->fd; + Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); + numQueued++; + } + filePtr->readyMask = mask; + } - if (filePtr->readyMask == 0) { - FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) - ckalloc(sizeof(FileHandlerEvent)); + /* + * If any events were queued in the above loop, force PlatformEventsWait() + * to poll as there already are events that need to be processed at this + * point. + */ - fileEvPtr->header.proc = FileHandlerEventProc; - fileEvPtr->fd = filePtr->fd; - Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); - numQueued++; - } - filePtr->readyMask = mask; - } + if (numQueued) { + timeout.tv_sec = 0; + timeout.tv_usec = 0; + timeoutPtr = &timeout; + } - /* - * If any events were queued in the above loop, force PlatformEvents- - * Wait() to poll as there already are events that need to be processed - * at this point. - */ + /* + * Wait or poll for new events, queue Tcl events for the FileHandlers + * corresponding to them, and update the FileHandlers' mask of events of + * interest registered by the last call to Tcl_CreateFileHandler(). + * + * Events for the trigger pipe are processed here in order to facilitate + * inter-thread IPC. If another thread intends to wake up this thread + * whilst it's blocking on PlatformEventsWait(), it write(2)s to the other + * end of the pipe (see Tcl_AlertNotifier(),) which in turn will cause + * PlatformEventsWait() to return immediately. + */ - if (numQueued) { - timeout.tv_sec = 0; - timeout.tv_usec = 0; - timeoutPtr = &timeout; + numFound = PlatformEventsWait(tsdPtr->readyEvents, + tsdPtr->maxReadyEvents, timeoutPtr); + for (numEvent = 0; numEvent < numFound; numEvent++) { + pedPtr = (struct PlatformEventData *) + tsdPtr->readyEvents[numEvent].udata; + filePtr = pedPtr->filePtr; + mask = PlatformEventsTranslate(&tsdPtr->readyEvents[numEvent]); + if (filePtr->fd == tsdPtr->triggerPipe[0]) { + i = read(tsdPtr->triggerPipe[0], buf, 1); + if ((i == -1) && (errno != EAGAIN)) { + Tcl_Panic("Tcl_WaitForEvent: read from %p->triggerPipe: %s", + (void *) tsdPtr, strerror(errno)); + } + continue; + } + if (!mask) { + continue; } /* - * Wait or poll for new events, queue Tcl events for the FileHandlers - * corresponding to them, and update the FileHandlers' mask of events - * of interest registered by the last call to Tcl_CreateFileHandler(). - * - * Events for the trigger pipe are processed here in order to facilitate - * inter-thread IPC. If another thread intends to wake up this thread - * whilst it's blocking on PlatformEventsWait(), it write(2)s to the - * other end of the pipe (see Tcl_AlertNotifier(),) which in turn will - * cause PlatformEventsWait() to return immediately. + * Don't bother to queue an event if the mask was previously non-zero + * since an event must still be on the queue. */ - numFound = PlatformEventsWait(tsdPtr->readyEvents, - tsdPtr->maxReadyEvents, timeoutPtr); - for (numEvent = 0; numEvent < numFound; numEvent++) { - pedPtr = (struct PlatformEventData *) - tsdPtr->readyEvents[numEvent].udata; - filePtr = pedPtr->filePtr; - mask = PlatformEventsTranslate(&tsdPtr->readyEvents[numEvent]); - if (filePtr->fd == tsdPtr->triggerPipe[0]) { - i = read(tsdPtr->triggerPipe[0], buf, 1); - if ((i == -1) && (errno != EAGAIN)) { - Tcl_Panic("Tcl_WaitForEvent: read from %p->triggerPipe: %s", - (void *) tsdPtr, strerror(errno)); - } - continue; - } - if (!mask) { - continue; - } - - /* - * Don't bother to queue an event if the mask was previously - * non-zero since an event must still be on the queue. - */ + if (filePtr->readyMask == 0) { + FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) + ckalloc(sizeof(FileHandlerEvent)); - if (filePtr->readyMask == 0) { - FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) - ckalloc(sizeof(FileHandlerEvent)); - - fileEvPtr->header.proc = FileHandlerEventProc; - fileEvPtr->fd = filePtr->fd; - Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); - } - filePtr->readyMask |= mask; + fileEvPtr->header.proc = FileHandlerEventProc; + fileEvPtr->fd = filePtr->fd; + Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); } - return 0; + filePtr->readyMask |= mask; } + return 0; } #endif /* NOTIFIER_KQUEUE && TCL_THREADS */ diff --git a/unix/tclSelectNotfy.c b/unix/tclSelectNotfy.c index e40997f..72567e5 100644 --- a/unix/tclSelectNotfy.c +++ b/unix/tclSelectNotfy.c @@ -271,14 +271,17 @@ static unsigned int __stdcall NotifierProc(void *hwnd, unsigned int message, } #endif #endif /* TCL_THREADS && __CYGWIN__ */ - +/* + * Incorporate the base notifier implementation. + */ + #include "tclUnixNotfy.c" /* *---------------------------------------------------------------------- * - * Tcl_InitNotifier -- + * TclpInitNotifier -- * * Initializes the platform specific notifier state. * @@ -292,75 +295,72 @@ static unsigned int __stdcall NotifierProc(void *hwnd, unsigned int message, */ ClientData -Tcl_InitNotifier(void) +TclpInitNotifier(void) { - if (tclNotifierHooks.initNotifierProc) { - return tclNotifierHooks.initNotifierProc(); - } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); #if TCL_THREADS - tsdPtr->eventReady = 0; + tsdPtr->eventReady = 0; - /* - * Initialize thread specific condition variable for this thread. - */ - if (tsdPtr->waitCVinitialized == 0) { + /* + * Initialize thread specific condition variable for this thread. + */ + + if (tsdPtr->waitCVinitialized == 0) { #ifdef __CYGWIN__ - WNDCLASSW clazz; - - clazz.style = 0; - clazz.cbClsExtra = 0; - clazz.cbWndExtra = 0; - clazz.hInstance = TclWinGetTclInstance(); - clazz.hbrBackground = NULL; - clazz.lpszMenuName = NULL; - clazz.lpszClassName = className; - clazz.lpfnWndProc = (void *)NotifierProc; - clazz.hIcon = NULL; - clazz.hCursor = NULL; - - RegisterClassW(&clazz); - tsdPtr->hwnd = CreateWindowExW(NULL, clazz.lpszClassName, - clazz.lpszClassName, 0, 0, 0, 0, 0, NULL, NULL, - clazz.hInstance, NULL); - tsdPtr->event = CreateEventW(NULL, 1 /* manual */, - 0 /* !signaled */, NULL); -#else - pthread_cond_init(&tsdPtr->waitCV, NULL); + WNDCLASSW clazz; + + clazz.style = 0; + clazz.cbClsExtra = 0; + clazz.cbWndExtra = 0; + clazz.hInstance = TclWinGetTclInstance(); + clazz.hbrBackground = NULL; + clazz.lpszMenuName = NULL; + clazz.lpszClassName = className; + clazz.lpfnWndProc = (void *) NotifierProc; + clazz.hIcon = NULL; + clazz.hCursor = NULL; + + RegisterClassW(&clazz); + tsdPtr->hwnd = CreateWindowExW(NULL, clazz.lpszClassName, + clazz.lpszClassName, 0, 0, 0, 0, 0, NULL, NULL, + clazz.hInstance, NULL); + tsdPtr->event = CreateEventW(NULL, 1 /* manual */, + 0 /* !signaled */, NULL); +#else /* !__CYGWIN__ */ + pthread_cond_init(&tsdPtr->waitCV, NULL); #endif /* __CYGWIN__ */ - tsdPtr->waitCVinitialized = 1; - } + tsdPtr->waitCVinitialized = 1; + } - pthread_mutex_lock(¬ifierInitMutex); + pthread_mutex_lock(¬ifierInitMutex); #if defined(HAVE_PTHREAD_ATFORK) - /* - * Install pthread_atfork handlers to clean up the notifier in the - * child of a fork. - */ + /* + * Install pthread_atfork handlers to clean up the notifier in the child + * of a fork. + */ - if (!atForkInit) { - int result = pthread_atfork(NULL, NULL, AtForkChild); + if (!atForkInit) { + int result = pthread_atfork(NULL, NULL, AtForkChild); - if (result) { - Tcl_Panic("Tcl_InitNotifier: pthread_atfork failed"); - } - atForkInit = 1; + if (result) { + Tcl_Panic("Tcl_InitNotifier: %s", "pthread_atfork failed"); } + atForkInit = 1; + } #endif /* HAVE_PTHREAD_ATFORK */ - notifierCount++; - pthread_mutex_unlock(¬ifierInitMutex); - + notifierCount++; + pthread_mutex_unlock(¬ifierInitMutex); #endif /* TCL_THREADS */ - return tsdPtr; - } + + return tsdPtr; } /* *---------------------------------------------------------------------- * - * Tcl_FinalizeNotifier -- + * TclpFinalizeNotifier -- * * This function is called to cleanup the notifier state before a thread * is terminated. @@ -376,67 +376,62 @@ Tcl_InitNotifier(void) */ void -Tcl_FinalizeNotifier( +TclpFinalizeNotifier( ClientData clientData) { - if (tclNotifierHooks.finalizeNotifierProc) { - tclNotifierHooks.finalizeNotifierProc(clientData); - return; - } else { #if TCL_THREADS - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - pthread_mutex_lock(¬ifierInitMutex); - notifierCount--; + pthread_mutex_lock(¬ifierInitMutex); + notifierCount--; - /* - * If this is the last thread to use the notifier, close the notifier - * pipe and wait for the background thread to terminate. - */ + /* + * If this is the last thread to use the notifier, close the notifier pipe + * and wait for the background thread to terminate. + */ - if (notifierCount == 0 && triggerPipe != -1) { - if (write(triggerPipe, "q", 1) != 1) { - Tcl_Panic("Tcl_FinalizeNotifier: %s", - "unable to write 'q' to triggerPipe"); - } - close(triggerPipe); - pthread_mutex_lock(¬ifierMutex); - while(triggerPipe != -1) { - pthread_cond_wait(¬ifierCV, ¬ifierMutex); - } - pthread_mutex_unlock(¬ifierMutex); - if (notifierThreadRunning) { - int result = pthread_join((pthread_t) notifierThread, NULL); + if (notifierCount == 0 && triggerPipe != -1) { + if (write(triggerPipe, "q", 1) != 1) { + Tcl_Panic("Tcl_FinalizeNotifier: %s", + "unable to write 'q' to triggerPipe"); + } + close(triggerPipe); + pthread_mutex_lock(¬ifierMutex); + while(triggerPipe != -1) { + pthread_cond_wait(¬ifierCV, ¬ifierMutex); + } + pthread_mutex_unlock(¬ifierMutex); + if (notifierThreadRunning) { + int result = pthread_join((pthread_t) notifierThread, NULL); - if (result) { - Tcl_Panic("Tcl_FinalizeNotifier: %s", - "unable to join notifier thread"); - } - notifierThreadRunning = 0; + if (result) { + Tcl_Panic("Tcl_FinalizeNotifier: %s", + "unable to join notifier thread"); } + notifierThreadRunning = 0; } + } - /* - * Clean up any synchronization objects in the thread local storage. - */ + /* + * Clean up any synchronization objects in the thread local storage. + */ #ifdef __CYGWIN__ - DestroyWindow(tsdPtr->hwnd); - CloseHandle(tsdPtr->event); -#else /* __CYGWIN__ */ - pthread_cond_destroy(&tsdPtr->waitCV); + DestroyWindow(tsdPtr->hwnd); + CloseHandle(tsdPtr->event); +#else /* !__CYGWIN__ */ + pthread_cond_destroy(&tsdPtr->waitCV); #endif /* __CYGWIN__ */ - tsdPtr->waitCVinitialized = 0; + tsdPtr->waitCVinitialized = 0; - pthread_mutex_unlock(¬ifierInitMutex); + pthread_mutex_unlock(¬ifierInitMutex); #endif /* TCL_THREADS */ - } } /* *---------------------------------------------------------------------- * - * Tcl_CreateFileHandler -- + * TclpCreateFileHandler -- * * This function registers a file handler with the select notifier. * @@ -450,7 +445,7 @@ Tcl_FinalizeNotifier( */ void -Tcl_CreateFileHandler( +TclpCreateFileHandler( int fd, /* Handle of stream to watch. */ int mask, /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: indicates @@ -460,59 +455,48 @@ Tcl_CreateFileHandler( * event. */ ClientData clientData) /* Arbitrary data to pass to proc. */ { - if (tclNotifierHooks.createFileHandlerProc) { - tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData); - return; - } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - FileHandler *filePtr; - - for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL; - filePtr = filePtr->nextPtr) { - if (filePtr->fd == fd) { - break; - } - } - if (filePtr == NULL) { - filePtr = (FileHandler *)ckalloc(sizeof(FileHandler)); - filePtr->fd = fd; - filePtr->readyMask = 0; - filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; - tsdPtr->firstFileHandlerPtr = filePtr; - } - filePtr->proc = proc; - filePtr->clientData = clientData; - filePtr->mask = mask; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + FileHandler *filePtr = LookUpFileHandler(tsdPtr, fd, NULL); + + if (filePtr == NULL) { + filePtr = (FileHandler *) ckalloc(sizeof(FileHandler)); + filePtr->fd = fd; + filePtr->readyMask = 0; + filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; + tsdPtr->firstFileHandlerPtr = filePtr; + } + filePtr->proc = proc; + filePtr->clientData = clientData; + filePtr->mask = mask; - /* - * Update the check masks for this file. - */ + /* + * Update the check masks for this file. + */ - if (mask & TCL_READABLE) { - FD_SET(fd, &tsdPtr->checkMasks.readable); - } else { - FD_CLR(fd, &tsdPtr->checkMasks.readable); - } - if (mask & TCL_WRITABLE) { - FD_SET(fd, &tsdPtr->checkMasks.writable); - } else { - FD_CLR(fd, &tsdPtr->checkMasks.writable); - } - if (mask & TCL_EXCEPTION) { - FD_SET(fd, &tsdPtr->checkMasks.exception); - } else { - FD_CLR(fd, &tsdPtr->checkMasks.exception); - } - if (tsdPtr->numFdBits <= fd) { - tsdPtr->numFdBits = fd + 1; - } + if (mask & TCL_READABLE) { + FD_SET(fd, &tsdPtr->checkMasks.readable); + } else { + FD_CLR(fd, &tsdPtr->checkMasks.readable); + } + if (mask & TCL_WRITABLE) { + FD_SET(fd, &tsdPtr->checkMasks.writable); + } else { + FD_CLR(fd, &tsdPtr->checkMasks.writable); + } + if (mask & TCL_EXCEPTION) { + FD_SET(fd, &tsdPtr->checkMasks.exception); + } else { + FD_CLR(fd, &tsdPtr->checkMasks.exception); + } + if (tsdPtr->numFdBits <= fd) { + tsdPtr->numFdBits = fd + 1; } } /* *---------------------------------------------------------------------- * - * Tcl_DeleteFileHandler -- + * TclpDeleteFileHandler -- * * Cancel a previously-arranged callback arrangement for a file. * @@ -526,75 +510,65 @@ Tcl_CreateFileHandler( */ void -Tcl_DeleteFileHandler( +TclpDeleteFileHandler( int fd) /* Stream id for which to remove callback * function. */ { - if (tclNotifierHooks.deleteFileHandlerProc) { - tclNotifierHooks.deleteFileHandlerProc(fd); - return; - } else { - FileHandler *filePtr, *prevPtr; - int i; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + FileHandler *filePtr, *prevPtr; + int i; - /* - * Find the entry for the given file (and return if there isn't one). - */ + /* + * Find the entry for the given file (and return if there isn't one). + */ - for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; - prevPtr = filePtr, filePtr = filePtr->nextPtr) { - if (filePtr == NULL) { - return; - } - if (filePtr->fd == fd) { - break; - } - } + filePtr = LookUpFileHandler(tsdPtr, fd, &prevPtr); + if (filePtr == NULL) { + return; + } - /* - * Update the check masks for this file. - */ + /* + * Update the check masks for this file. + */ - if (filePtr->mask & TCL_READABLE) { - FD_CLR(fd, &tsdPtr->checkMasks.readable); - } - if (filePtr->mask & TCL_WRITABLE) { - FD_CLR(fd, &tsdPtr->checkMasks.writable); - } - if (filePtr->mask & TCL_EXCEPTION) { - FD_CLR(fd, &tsdPtr->checkMasks.exception); - } + if (filePtr->mask & TCL_READABLE) { + FD_CLR(fd, &tsdPtr->checkMasks.readable); + } + if (filePtr->mask & TCL_WRITABLE) { + FD_CLR(fd, &tsdPtr->checkMasks.writable); + } + if (filePtr->mask & TCL_EXCEPTION) { + FD_CLR(fd, &tsdPtr->checkMasks.exception); + } - /* - * Find current max fd. - */ + /* + * Find current max fd. + */ - if (fd+1 == tsdPtr->numFdBits) { - int numFdBits = 0; + if (fd + 1 == tsdPtr->numFdBits) { + int numFdBits = 0; - for (i = fd - 1; i >= 0; i--) { - if (FD_ISSET(i, &tsdPtr->checkMasks.readable) - || FD_ISSET(i, &tsdPtr->checkMasks.writable) - || FD_ISSET(i, &tsdPtr->checkMasks.exception)) { - numFdBits = i + 1; - break; - } + for (i = fd - 1; i >= 0; i--) { + if (FD_ISSET(i, &tsdPtr->checkMasks.readable) + || FD_ISSET(i, &tsdPtr->checkMasks.writable) + || FD_ISSET(i, &tsdPtr->checkMasks.exception)) { + numFdBits = i + 1; + break; } - tsdPtr->numFdBits = numFdBits; } + tsdPtr->numFdBits = numFdBits; + } - /* - * Clean up information in the callback record. - */ + /* + * Clean up information in the callback record. + */ - if (prevPtr == NULL) { - tsdPtr->firstFileHandlerPtr = filePtr->nextPtr; - } else { - prevPtr->nextPtr = filePtr->nextPtr; - } - ckfree(filePtr); + if (prevPtr == NULL) { + tsdPtr->firstFileHandlerPtr = filePtr->nextPtr; + } else { + prevPtr->nextPtr = filePtr->nextPtr; } + ckfree(filePtr); } #if defined(__CYGWIN__) @@ -625,7 +599,7 @@ NotifierProc( /* *---------------------------------------------------------------------- * - * Tcl_WaitForEvent -- + * TclpWaitForEvent -- * * This function is called by Tcl_DoOneEvent to wait for new events on * the message queue. If the block time is 0, then Tcl_WaitForEvent just @@ -641,265 +615,261 @@ NotifierProc( */ int -Tcl_WaitForEvent( +TclpWaitForEvent( const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ { - if (tclNotifierHooks.waitForEventProc) { - return tclNotifierHooks.waitForEventProc(timePtr); - } else { - FileHandler *filePtr; - int mask; - Tcl_Time vTime; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + FileHandler *filePtr; + int mask; + Tcl_Time vTime; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); #if TCL_THREADS - int waitForFiles; + int waitForFiles; # ifdef __CYGWIN__ - MSG msg; + MSG msg; # endif /* __CYGWIN__ */ #else /* !TCL_THREADS */ - /* - * Impl. notes: timeout & timeoutPtr are used if, and only if threads - * are not enabled. They are the arguments for the regular select() - * used when the core is not thread-enabled. - */ + /* + * Impl. notes: timeout & timeoutPtr are used if, and only if threads are + * not enabled. They are the arguments for the regular select() used when + * the core is not thread-enabled. + */ - struct timeval timeout, *timeoutPtr; - int numFound; + struct timeval timeout, *timeoutPtr; + int numFound; #endif /* TCL_THREADS */ + /* + * Set up the timeout structure. Note that if there are no events to check + * for, we return with a negative result rather than blocking forever. + */ + + if (timePtr != NULL) { /* - * Set up the timeout structure. Note that if there are no events to - * check for, we return with a negative result rather than blocking - * forever. + * TIP #233 (Virtualized Time). Is virtual time in effect? And do we + * actually have something to scale? If yes to both then we call the + * handler to do this scaling. */ - if (timePtr != NULL) { - /* - * TIP #233 (Virtualized Time). Is virtual time in effect? And do - * we actually have something to scale? If yes to both then we - * call the handler to do this scaling. - */ - - if (timePtr->sec != 0 || timePtr->usec != 0) { - vTime = *timePtr; - tclScaleTimeProcPtr(&vTime, tclTimeClientData); - timePtr = &vTime; - } + if (timePtr->sec != 0 || timePtr->usec != 0) { + vTime = *timePtr; + TclScaleTime(&vTime); + timePtr = &vTime; + } #if !TCL_THREADS - timeout.tv_sec = timePtr->sec; - timeout.tv_usec = timePtr->usec; - timeoutPtr = &timeout; - } else if (tsdPtr->numFdBits == 0) { - /* - * If there are no threads, no timeout, and no fds registered, - * then there are no events possible and we must avoid deadlock. - * Note that this is not entirely correct because there might be a - * signal that could interrupt the select call, but we don't - * handle that case if we aren't using threads. - */ + timeout.tv_sec = timePtr->sec; + timeout.tv_usec = timePtr->usec; + timeoutPtr = &timeout; + } else if (tsdPtr->numFdBits == 0) { + /* + * If there are no threads, no timeout, and no fds registered, then + * there are no events possible and we must avoid deadlock. Note that + * this is not entirely correct because there might be a signal that + * could interrupt the select call, but we don't handle that case if + * we aren't using threads. + */ - return -1; - } else { - timeoutPtr = NULL; + return -1; + } else { + timeoutPtr = NULL; #endif /* !TCL_THREADS */ - } + } #if TCL_THREADS - /* - * Start notifier thread and place this thread on the list of - * interested threads, signal the notifier thread, and wait for a - * response or a timeout. - */ - StartNotifierThread("Tcl_WaitForEvent"); + /* + * Start notifier thread and place this thread on the list of interested + * threads, signal the notifier thread, and wait for a response or a + * timeout. + */ - pthread_mutex_lock(¬ifierMutex); + StartNotifierThread("Tcl_WaitForEvent"); + + pthread_mutex_lock(¬ifierMutex); - if (timePtr != NULL && timePtr->sec == 0 && (timePtr->usec == 0 + if (timePtr != NULL && timePtr->sec == 0 && (timePtr->usec == 0 #if defined(__APPLE__) && defined(__LP64__) - /* - * On 64-bit Darwin, pthread_cond_timedwait() appears to have - * a bug that causes it to wait forever when passed an - * absolute time which has already been exceeded by the system - * time; as a workaround, when given a very brief timeout, - * just do a poll. [Bug 1457797] - */ - || timePtr->usec < 10 -#endif /* __APPLE__ && __LP64__ */ - )) { /* - * Cannot emulate a polling select with a polling condition - * variable. Instead, pretend to wait for files and tell the - * notifier thread what we are doing. The notifier thread makes - * sure it goes through select with its select mask in the same - * state as ours currently is. We block until that happens. + * On 64-bit Darwin, pthread_cond_timedwait() appears to have a + * bug that causes it to wait forever when passed an absolute time + * which has already been exceeded by the system time; as a + * workaround, when given a very brief timeout, just do a poll. + * [Bug 1457797] */ + || timePtr->usec < 10 +#endif /* __APPLE__ && __LP64__ */ + )) { + /* + * Cannot emulate a polling select with a polling condition variable. + * Instead, pretend to wait for files and tell the notifier thread + * what we are doing. The notifier thread makes sure it goes through + * select with its select mask in the same state as ours currently is. + * We block until that happens. + */ - waitForFiles = 1; - tsdPtr->pollState = POLL_WANT; - timePtr = NULL; - } else { - waitForFiles = (tsdPtr->numFdBits > 0); - tsdPtr->pollState = 0; - } + waitForFiles = 1; + tsdPtr->pollState = POLL_WANT; + timePtr = NULL; + } else { + waitForFiles = (tsdPtr->numFdBits > 0); + tsdPtr->pollState = 0; + } - if (waitForFiles) { - /* - * Add the ThreadSpecificData structure of this thread to the list - * of ThreadSpecificData structures of all threads that are - * waiting on file events. - */ + if (waitForFiles) { + /* + * Add the ThreadSpecificData structure of this thread to the list of + * ThreadSpecificData structures of all threads that are waiting on + * file events. + */ - tsdPtr->nextPtr = waitingListPtr; - if (waitingListPtr) { - waitingListPtr->prevPtr = tsdPtr; - } - tsdPtr->prevPtr = 0; - waitingListPtr = tsdPtr; - tsdPtr->onList = 1; + tsdPtr->nextPtr = waitingListPtr; + if (waitingListPtr) { + waitingListPtr->prevPtr = tsdPtr; + } + tsdPtr->prevPtr = 0; + waitingListPtr = tsdPtr; + tsdPtr->onList = 1; - if ((write(triggerPipe, "", 1) == -1) && (errno != EAGAIN)) { - Tcl_Panic("Tcl_WaitForEvent: %s", - "unable to write to triggerPipe"); - } + if ((write(triggerPipe, "", 1) == -1) && (errno != EAGAIN)) { + Tcl_Panic("Tcl_WaitForEvent: %s", + "unable to write to triggerPipe"); } + } - FD_ZERO(&tsdPtr->readyMasks.readable); - FD_ZERO(&tsdPtr->readyMasks.writable); - FD_ZERO(&tsdPtr->readyMasks.exception); + FD_ZERO(&tsdPtr->readyMasks.readable); + FD_ZERO(&tsdPtr->readyMasks.writable); + FD_ZERO(&tsdPtr->readyMasks.exception); - if (!tsdPtr->eventReady) { + if (!tsdPtr->eventReady) { #ifdef __CYGWIN__ - if (!PeekMessageW(&msg, NULL, 0, 0, 0)) { - unsigned int timeout; + if (!PeekMessageW(&msg, NULL, 0, 0, 0)) { + unsigned int timeout; - if (timePtr) { - timeout = timePtr->sec * 1000 + timePtr->usec / 1000; - } else { - timeout = 0xFFFFFFFF; - } - pthread_mutex_unlock(¬ifierMutex); - MsgWaitForMultipleObjects(1, &tsdPtr->event, 0, timeout, 1279); - pthread_mutex_lock(¬ifierMutex); + if (timePtr) { + timeout = timePtr->sec * 1000 + timePtr->usec / 1000; + } else { + timeout = 0xFFFFFFFF; } + pthread_mutex_unlock(¬ifierMutex); + MsgWaitForMultipleObjects(1, &tsdPtr->event, 0, timeout, 1279); + pthread_mutex_lock(¬ifierMutex); + } #else /* !__CYGWIN__ */ - if (timePtr != NULL) { - Tcl_Time now; - struct timespec ptime; + if (timePtr != NULL) { + Tcl_Time now; + struct timespec ptime; - Tcl_GetTime(&now); - ptime.tv_sec = timePtr->sec + now.sec + - (timePtr->usec + now.usec) / 1000000; - ptime.tv_nsec = 1000 * ((timePtr->usec + now.usec) % 1000000); + Tcl_GetTime(&now); + ptime.tv_sec = timePtr->sec + now.sec + + (timePtr->usec + now.usec) / 1000000; + ptime.tv_nsec = 1000 * ((timePtr->usec + now.usec) % 1000000); - pthread_cond_timedwait(&tsdPtr->waitCV, ¬ifierMutex, &ptime); - } else { - pthread_cond_wait(&tsdPtr->waitCV, ¬ifierMutex); - } -#endif /* __CYGWIN__ */ + pthread_cond_timedwait(&tsdPtr->waitCV, ¬ifierMutex, &ptime); + } else { + pthread_cond_wait(&tsdPtr->waitCV, ¬ifierMutex); } - tsdPtr->eventReady = 0; +#endif /* __CYGWIN__ */ + } + tsdPtr->eventReady = 0; #ifdef __CYGWIN__ - while (PeekMessageW(&msg, NULL, 0, 0, 0)) { - /* - * Retrieve and dispatch the message. - */ + while (PeekMessageW(&msg, NULL, 0, 0, 0)) { + /* + * Retrieve and dispatch the message. + */ - unsigned int result = GetMessageW(&msg, NULL, 0, 0); + unsigned int result = GetMessageW(&msg, NULL, 0, 0); - if (result == 0) { - PostQuitMessage(msg.wParam); - /* What to do here? */ - } else if (result != (unsigned int) -1) { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } + if (result == 0) { + PostQuitMessage(msg.wParam); + /* What to do here? */ + } else if (result != (unsigned int) -1) { + TranslateMessage(&msg); + DispatchMessageW(&msg); } - ResetEvent(tsdPtr->event); + } + ResetEvent(tsdPtr->event); #endif /* __CYGWIN__ */ - if (waitForFiles && tsdPtr->onList) { - /* - * Remove the ThreadSpecificData structure of this thread from the - * waiting list. Alert the notifier thread to recompute its select - * masks - skipping this caused a hang when trying to close a pipe - * which the notifier thread was still doing a select on. - */ + if (waitForFiles && tsdPtr->onList) { + /* + * Remove the ThreadSpecificData structure of this thread from the + * waiting list. Alert the notifier thread to recompute its select + * masks - skipping this caused a hang when trying to close a pipe + * which the notifier thread was still doing a select on. + */ - if (tsdPtr->prevPtr) { - tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr; - } else { - waitingListPtr = tsdPtr->nextPtr; - } - if (tsdPtr->nextPtr) { - tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; - } - tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; - tsdPtr->onList = 0; - if ((write(triggerPipe, "", 1) == -1) && (errno != EAGAIN)) { - Tcl_Panic("Tcl_WaitForEvent: %s", - "unable to write to triggerPipe"); - } + if (tsdPtr->prevPtr) { + tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr; + } else { + waitingListPtr = tsdPtr->nextPtr; + } + if (tsdPtr->nextPtr) { + tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; } + tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; + tsdPtr->onList = 0; + if ((write(triggerPipe, "", 1) == -1) && (errno != EAGAIN)) { + Tcl_Panic("Tcl_WaitForEvent: %s", + "unable to write to triggerPipe"); + } + } #else /* !TCL_THREADS */ - tsdPtr->readyMasks = tsdPtr->checkMasks; - numFound = select(tsdPtr->numFdBits, &tsdPtr->readyMasks.readable, - &tsdPtr->readyMasks.writable, &tsdPtr->readyMasks.exception, - timeoutPtr); + tsdPtr->readyMasks = tsdPtr->checkMasks; + numFound = select(tsdPtr->numFdBits, &tsdPtr->readyMasks.readable, + &tsdPtr->readyMasks.writable, &tsdPtr->readyMasks.exception, + timeoutPtr); - /* - * Some systems don't clear the masks after an error, so we have to do - * it here. - */ + /* + * Some systems don't clear the masks after an error, so we have to do it + * here. + */ - if (numFound == -1) { - FD_ZERO(&tsdPtr->readyMasks.readable); - FD_ZERO(&tsdPtr->readyMasks.writable); - FD_ZERO(&tsdPtr->readyMasks.exception); - } + if (numFound == -1) { + FD_ZERO(&tsdPtr->readyMasks.readable); + FD_ZERO(&tsdPtr->readyMasks.writable); + FD_ZERO(&tsdPtr->readyMasks.exception); + } #endif /* TCL_THREADS */ - /* - * Queue all detected file events before returning. - */ + /* + * Queue all detected file events before returning. + */ - for (filePtr = tsdPtr->firstFileHandlerPtr; (filePtr != NULL); - filePtr = filePtr->nextPtr) { - mask = 0; - if (FD_ISSET(filePtr->fd, &tsdPtr->readyMasks.readable)) { - mask |= TCL_READABLE; - } - if (FD_ISSET(filePtr->fd, &tsdPtr->readyMasks.writable)) { - mask |= TCL_WRITABLE; - } - if (FD_ISSET(filePtr->fd, &tsdPtr->readyMasks.exception)) { - mask |= TCL_EXCEPTION; - } + for (filePtr = tsdPtr->firstFileHandlerPtr; (filePtr != NULL); + filePtr = filePtr->nextPtr) { + mask = 0; + if (FD_ISSET(filePtr->fd, &tsdPtr->readyMasks.readable)) { + mask |= TCL_READABLE; + } + if (FD_ISSET(filePtr->fd, &tsdPtr->readyMasks.writable)) { + mask |= TCL_WRITABLE; + } + if (FD_ISSET(filePtr->fd, &tsdPtr->readyMasks.exception)) { + mask |= TCL_EXCEPTION; + } - if (!mask) { - continue; - } + if (!mask) { + continue; + } - /* - * Don't bother to queue an event if the mask was previously - * non-zero since an event must still be on the queue. - */ + /* + * Don't bother to queue an event if the mask was previously non-zero + * since an event must still be on the queue. + */ - if (filePtr->readyMask == 0) { - FileHandlerEvent *fileEvPtr = - (FileHandlerEvent *)ckalloc(sizeof(FileHandlerEvent)); + if (filePtr->readyMask == 0) { + FileHandlerEvent *fileEvPtr = + (FileHandlerEvent *) ckalloc(sizeof(FileHandlerEvent)); - fileEvPtr->header.proc = FileHandlerEventProc; - fileEvPtr->fd = filePtr->fd; - Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); - } - filePtr->readyMask = mask; + fileEvPtr->header.proc = FileHandlerEventProc; + fileEvPtr->fd = filePtr->fd; + Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); } + filePtr->readyMask = mask; + } #if TCL_THREADS - pthread_mutex_unlock(¬ifierMutex); + pthread_mutex_unlock(¬ifierMutex); #endif /* TCL_THREADS */ - return 0; - } + return 0; } /* @@ -916,8 +886,9 @@ Tcl_WaitForEvent( * byte to a special pipe that the notifier thread is monitoring. * * Result: - * None. Once started, this routine never exits. It dies with the overall - * process. + * None. Once started, this routine normally never exits and usually dies + * with the overall process, but it can be shut down if the Tcl library + * is finalized. * * Side effects: * The trigger pipe used to signal the notifier thread is created when @@ -1048,7 +1019,7 @@ NotifierThreadProc( for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) { found = 0; - for (i = tsdPtr->numFdBits-1; i >= 0; --i) { + for (i = tsdPtr->numFdBits - 1; i >= 0; --i) { if (FD_ISSET(i, &tsdPtr->checkMasks.readable) && FD_ISSET(i, &readableMask)) { FD_SET(i, &tsdPtr->readyMasks.readable); diff --git a/unix/tclUnixEvent.c b/unix/tclUnixEvent.c index f7545db..0047dd9 100644 --- a/unix/tclUnixEvent.c +++ b/unix/tclUnixEvent.c @@ -64,7 +64,7 @@ Tcl_Sleep( } if ((vdelay.sec != 0) || (vdelay.usec != 0)) { - tclScaleTimeProcPtr(&vdelay, tclTimeClientData); + TclScaleTime(&vdelay); } delay.tv_sec = vdelay.sec; diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index d992d65..0be9ed4 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -2,10 +2,12 @@ * tclUnixNotfy.c -- * * This file contains subroutines shared by all notifier backend - * implementations on *nix platforms. + * implementations on *nix platforms. It is *included* by the epoll, + * kqueue and select notifier implementation files. * * Copyright © 1995-1997 Sun Microsystems, Inc. * Copyright © 2016 Lucio Andrés Illanes Albornoz + * Copyright © 2021 Donal K. Fellows * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -45,8 +47,10 @@ static void AtForkChild(void); * *---------------------------------------------------------------------- */ + static void -StartNotifierThread(const char *proc) +StartNotifierThread( + const char *proc) { if (!notifierThreadRunning) { pthread_mutex_lock(¬ifierInitMutex); @@ -57,6 +61,7 @@ StartNotifierThread(const char *proc) } pthread_mutex_lock(¬ifierMutex); + /* * Wait for the notifier pipe to be created. */ @@ -76,7 +81,7 @@ StartNotifierThread(const char *proc) /* *---------------------------------------------------------------------- * - * Tcl_AlertNotifier -- + * TclpAlertNotifier -- * * Wake up the specified notifier from any thread. This routine is called * by the platform independent notifier code whenever the Tcl_ThreadAlert @@ -99,50 +104,97 @@ StartNotifierThread(const char *proc) */ void -Tcl_AlertNotifier( +TclpAlertNotifier( ClientData clientData) { - if (tclNotifierHooks.alertNotifierProc) { - tclNotifierHooks.alertNotifierProc(clientData); - return; - } else { #ifdef NOTIFIER_SELECT #if TCL_THREADS - ThreadSpecificData *tsdPtr = (ThreadSpecificData *)clientData; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; - pthread_mutex_lock(¬ifierMutex); - tsdPtr->eventReady = 1; + pthread_mutex_lock(¬ifierMutex); + tsdPtr->eventReady = 1; # ifdef __CYGWIN__ - PostMessageW(tsdPtr->hwnd, 1024, 0, 0); + PostMessageW(tsdPtr->hwnd, 1024, 0, 0); # else - pthread_cond_broadcast(&tsdPtr->waitCV); + pthread_cond_broadcast(&tsdPtr->waitCV); # endif /* __CYGWIN__ */ - pthread_mutex_unlock(¬ifierMutex); + pthread_mutex_unlock(¬ifierMutex); #endif /* TCL_THREADS */ #else /* !NOTIFIER_SELECT */ - ThreadSpecificData *tsdPtr = (ThreadSpecificData *)clientData; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; #if defined(NOTIFIER_EPOLL) && defined(HAVE_EVENTFD) - uint64_t eventFdVal = 1; - if (write(tsdPtr->triggerEventFd, &eventFdVal, - sizeof(eventFdVal)) != sizeof(eventFdVal)) { - Tcl_Panic("Tcl_AlertNotifier: unable to write to %p->triggerEventFd", - (void *)tsdPtr); - } + uint64_t eventFdVal = 1; + + if (write(tsdPtr->triggerEventFd, &eventFdVal, + sizeof(eventFdVal)) != sizeof(eventFdVal)) { + Tcl_Panic("Tcl_AlertNotifier: unable to write to %p->triggerEventFd", + (void *) tsdPtr); + } #else - if (write(tsdPtr->triggerPipe[1], "", 1) != 1) { - Tcl_Panic("Tcl_AlertNotifier: unable to write to %p->triggerPipe", - (void *)tsdPtr); - } + if (write(tsdPtr->triggerPipe[1], "", 1) != 1) { + Tcl_Panic("Tcl_AlertNotifier: unable to write to %p->triggerPipe", + (void *) tsdPtr); + } #endif /* NOTIFIER_EPOLL && HAVE_EVENTFD */ #endif /* NOTIFIER_SELECT */ +} + +/* + *---------------------------------------------------------------------- + * + * LookUpFileHandler -- + * + * Look up the file handler structure (and optionally the previous one in + * the chain) associated with a file descriptor. + * + * Returns: + * A pointer to the file handler, or NULL if it can't be found. + * + * Side effects: + * If prevPtrPtr is non-NULL, it will be written to if the file handler + * is found. + * + *---------------------------------------------------------------------- + */ + +static inline FileHandler * +LookUpFileHandler( + ThreadSpecificData *tsdPtr, /* Where to look things up. */ + int fd, /* What we are looking for. */ + FileHandler **prevPtrPtr) /* If non-NULL, where to report the previous + * pointer. */ +{ + FileHandler *filePtr, *prevPtr; + + /* + * Find the entry for the given file (and return if there isn't one). + */ + + for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ; + prevPtr = filePtr, filePtr = filePtr->nextPtr) { + if (filePtr == NULL) { + return NULL; + } + if (filePtr->fd == fd) { + break; + } + } + + /* + * Report what we've found to our caller. + */ + + if (prevPtrPtr) { + *prevPtrPtr = prevPtr; } + return filePtr; } /* *---------------------------------------------------------------------- * - * Tcl_SetTimer -- + * TclpSetTimer -- * * This function sets the current notifier timer value. This interface is * not implemented in this notifier because we are always running inside @@ -158,19 +210,14 @@ Tcl_AlertNotifier( */ void -Tcl_SetTimer( +TclpSetTimer( const Tcl_Time *timePtr) /* Timeout value, may be NULL. */ { - if (tclNotifierHooks.setTimerProc) { - tclNotifierHooks.setTimerProc(timePtr); - return; - } else { - /* - * The interval timer doesn't do anything in this implementation, - * because the only event loop is via Tcl_DoOneEvent, which passes - * timeout values to Tcl_WaitForEvent. - */ - } + /* + * The interval timer doesn't do anything in this implementation, because + * the only event loop is via Tcl_DoOneEvent, which passes timeout values + * to Tcl_WaitForEvent. + */ } /* @@ -190,14 +237,11 @@ Tcl_SetTimer( */ void -Tcl_ServiceModeHook( +TclpServiceModeHook( int mode) /* Either TCL_SERVICE_ALL, or * TCL_SERVICE_NONE. */ { - if (tclNotifierHooks.serviceModeHookProc) { - tclNotifierHooks.serviceModeHookProc(mode); - return; - } else if (mode == TCL_SERVICE_ALL) { + if (mode == TCL_SERVICE_ALL) { #ifdef NOTIFIER_SELECT #if TCL_THREADS StartNotifierThread("Tcl_ServiceModeHook"); @@ -414,12 +458,9 @@ AtForkChild(void) Tcl_InitNotifier(); } #endif /* HAVE_PTHREAD_ATFORK */ - #endif /* TCL_THREADS */ - #endif /* NOTIFIER_SELECT */ -#ifndef HAVE_COREFOUNDATION /* Darwin/Mac OS X CoreFoundation notifier is - * in tclMacOSXNotify.c */ + /* *---------------------------------------------------------------------- * @@ -443,6 +484,9 @@ AtForkChild(void) *---------------------------------------------------------------------- */ +#ifndef HAVE_COREFOUNDATION /* Darwin/Mac OS X CoreFoundation notifier is + * in tclMacOSXNotify.c */ + int TclUnixWaitForFile( int fd, /* Handle for file on which to wait. */ @@ -563,9 +607,8 @@ TclUnixWaitForFile( || (abortTime.sec == now.sec && abortTime.usec > now.usec)); return result; } - #endif /* !HAVE_COREFOUNDATION */ - + /* * Local Variables: * mode: c diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index adeacb68..e0c7ac8 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -61,6 +61,23 @@ Tcl_ScaleTimeProc *tclScaleTimeProcPtr = NativeScaleTime; void *tclTimeClientData = NULL; /* + * Inlined version of Tcl_GetTime. + */ + +static inline void +GetTime( + Tcl_Time *timePtr) +{ + tclGetTimeProcPtr(timePtr, tclTimeClientData); +} + +static inline int +IsTimeNative(void) +{ + return tclGetTimeProcPtr == NativeGetTime; +} + +/* *---------------------------------------------------------------------- * * TclpGetSeconds -- @@ -105,8 +122,8 @@ TclpGetMicroseconds(void) { Tcl_Time time; - tclGetTimeProcPtr(&time, tclTimeClientData); - return ((long long)time.sec)*1000000 + time.usec; + GetTime(&time); + return ((long long) time.sec)*1000000 + time.usec; } /* @@ -134,10 +151,10 @@ TclpGetClicks(void) unsigned long now; #ifdef NO_GETTOD - if (tclGetTimeProcPtr != NativeGetTime) { + if (!IsTimeNative()) { Tcl_Time time; - tclGetTimeProcPtr(&time, tclTimeClientData); + GetTime(&time); now = time.sec*1000000 + time.usec; } else { /* @@ -147,12 +164,12 @@ TclpGetClicks(void) now = (unsigned long) times(&dummy); } -#else +#else /* !NO_GETTOD */ Tcl_Time time; - tclGetTimeProcPtr(&time, tclTimeClientData); + GetTime(&time); now = time.sec*1000000 + time.usec; -#endif +#endif /* NO_GETTOD */ return now; } @@ -182,17 +199,17 @@ TclpGetWideClicks(void) { long long now; - if (tclGetTimeProcPtr != NativeGetTime) { + if (!IsTimeNative()) { Tcl_Time time; - tclGetTimeProcPtr(&time, tclTimeClientData); - now = ((long long)time.sec)*1000000 + time.usec; + GetTime(&time); + now = ((long long) time.sec)*1000000 + time.usec; } else { #ifdef MAC_OSX_TCL now = (long long) (mach_absolute_time() & INT64_MAX); #else #error Wide high-resolution clicks not implemented on this platform -#endif +#endif /* MAC_OSX_TCL */ } return now; @@ -221,7 +238,7 @@ TclpWideClicksToNanoseconds( { double nsec; - if (tclGetTimeProcPtr != NativeGetTime) { + if (!IsTimeNative()) { nsec = clicks * 1000; } else { #ifdef MAC_OSX_TCL @@ -239,7 +256,7 @@ TclpWideClicksToNanoseconds( } #else #error Wide high-resolution clicks not implemented on this platform -#endif +#endif /* MAC_OSX_TCL */ } return nsec; @@ -266,7 +283,7 @@ TclpWideClicksToNanoseconds( double TclpWideClickInMicrosec(void) { - if (tclGetTimeProcPtr != NativeGetTime) { + if (!IsTimeNative()) { return 1.0; } else { #ifdef MAC_OSX_TCL @@ -286,7 +303,7 @@ TclpWideClickInMicrosec(void) } #else #error Wide high-resolution clicks not implemented on this platform -#endif +#endif /* MAC_OSX_TCL */ } } #endif /* TCL_WIDE_CLICKS */ @@ -315,7 +332,7 @@ void Tcl_GetTime( Tcl_Time *timePtr) /* Location to store time information. */ { - tclGetTimeProcPtr(timePtr, tclTimeClientData); + GetTime(timePtr); } /* @@ -578,7 +595,7 @@ SetTZIfNecessary(void) } else { ckfree(lastTZ); } - lastTZ = (char *)ckalloc(strlen(newTZ) + 1); + lastTZ = (char *) ckalloc(strlen(newTZ) + 1); strcpy(lastTZ, newTZ); } Tcl_MutexUnlock(&tmMutex); diff --git a/unix/tclXtNotify.c b/unix/tclXtNotify.c index 68ee578..3d90135 100644 --- a/unix/tclXtNotify.c +++ b/unix/tclXtNotify.c @@ -132,7 +132,7 @@ TclSetAppContext( * after initialization, so we panic. */ - Tcl_Panic("TclSetAppContext: multiple application contexts"); + Tcl_Panic("TclSetAppContext: multiple application contexts"); } } else { /* @@ -359,7 +359,7 @@ CreateFileHandler( } } if (filePtr == NULL) { - filePtr = (FileHandler *)ckalloc(sizeof(FileHandler)); + filePtr = (FileHandler *) ckalloc(sizeof(FileHandler)); filePtr->fd = fd; filePtr->read = 0; filePtr->write = 0; @@ -496,7 +496,7 @@ FileProc( int *fd, XtInputId *id) { - FileHandler *filePtr = (FileHandler *)clientData; + FileHandler *filePtr = (FileHandler *) clientData; FileHandlerEvent *fileEvPtr; int mask = 0; @@ -525,7 +525,7 @@ FileProc( */ filePtr->readyMask |= mask; - fileEvPtr = (FileHandlerEvent *)ckalloc(sizeof(FileHandlerEvent)); + fileEvPtr = (FileHandlerEvent *) ckalloc(sizeof(FileHandlerEvent)); fileEvPtr->header.proc = FileHandlerEventProc; fileEvPtr->fd = filePtr->fd; Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c index fff7910..feb171e 100644 --- a/win/tclWinNotify.c +++ b/win/tclWinNotify.c @@ -77,65 +77,62 @@ static LRESULT CALLBACK NotifierProc(HWND hwnd, UINT message, */ ClientData -Tcl_InitNotifier(void) +TclpInitNotifier(void) { - if (tclNotifierHooks.initNotifierProc) { - return tclNotifierHooks.initNotifierProc(); - } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - TclpGlobalLock(); - if (!initialized) { - initialized = 1; - InitializeCriticalSection(¬ifierMutex); - } - TclpGlobalUnlock(); + TclpGlobalLock(); + if (!initialized) { + initialized = 1; + InitializeCriticalSection(¬ifierMutex); + } + TclpGlobalUnlock(); - /* - * Register Notifier window class if this is the first thread to use - * this module. - */ + /* + * Register Notifier window class if this is the first thread to use this + * module. + */ - EnterCriticalSection(¬ifierMutex); - if (notifierCount == 0) { - WNDCLASSW clazz; - - clazz.style = 0; - clazz.cbClsExtra = 0; - clazz.cbWndExtra = 0; - clazz.hInstance = TclWinGetTclInstance(); - clazz.hbrBackground = NULL; - clazz.lpszMenuName = NULL; - clazz.lpszClassName = className; - clazz.lpfnWndProc = NotifierProc; - clazz.hIcon = NULL; - clazz.hCursor = NULL; - - if (!RegisterClassW(&clazz)) { - Tcl_Panic("Unable to register TclNotifier window class"); - } + EnterCriticalSection(¬ifierMutex); + if (notifierCount == 0) { + WNDCLASSW clazz; + + clazz.style = 0; + clazz.cbClsExtra = 0; + clazz.cbWndExtra = 0; + clazz.hInstance = TclWinGetTclInstance(); + clazz.hbrBackground = NULL; + clazz.lpszMenuName = NULL; + clazz.lpszClassName = className; + clazz.lpfnWndProc = NotifierProc; + clazz.hIcon = NULL; + clazz.hCursor = NULL; + + if (!RegisterClassW(&clazz)) { + Tcl_Panic("Tcl_InitNotifier: %s", + "unable to register TclNotifier window class"); } - notifierCount++; - LeaveCriticalSection(¬ifierMutex); + } + notifierCount++; + LeaveCriticalSection(¬ifierMutex); - tsdPtr->pending = 0; - tsdPtr->timerActive = 0; + tsdPtr->pending = 0; + tsdPtr->timerActive = 0; - InitializeCriticalSection(&tsdPtr->crit); + InitializeCriticalSection(&tsdPtr->crit); - tsdPtr->hwnd = NULL; - tsdPtr->thread = GetCurrentThreadId(); - tsdPtr->event = CreateEventW(NULL, TRUE /* manual */, - FALSE /* !signaled */, NULL); + tsdPtr->hwnd = NULL; + tsdPtr->thread = GetCurrentThreadId(); + tsdPtr->event = CreateEventW(NULL, TRUE /* manual */, + FALSE /* !signaled */, NULL); - return tsdPtr; - } + return tsdPtr; } /* *---------------------------------------------------------------------- * - * Tcl_FinalizeNotifier -- + * TclpFinalizeNotifier -- * * This function is called to cleanup the notifier state before a thread * is terminated. @@ -150,62 +147,57 @@ Tcl_InitNotifier(void) */ void -Tcl_FinalizeNotifier( +TclpFinalizeNotifier( ClientData clientData) /* Pointer to notifier data. */ { - if (tclNotifierHooks.finalizeNotifierProc) { - tclNotifierHooks.finalizeNotifierProc(clientData); - return; - } else { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; - /* - * Only finalize the notifier if a notifier was installed in the - * current thread; there is a route in which this is not guaranteed to - * be true (when tclWin32Dll.c:DllMain() is called with the flag - * DLL_PROCESS_DETACH by the OS, which could be doing so from a thread - * that's never previously been involved with Tcl, e.g. the task - * manager) so this check is important. - * - * Fixes Bug #217982 reported by Hugh Vu and Gene Leache. - */ + /* + * Only finalize the notifier if a notifier was installed in the current + * thread; there is a route in which this is not guaranteed to be true + * (when tclWin32Dll.c:DllMain() is called with the flag + * DLL_PROCESS_DETACH by the OS, which could be doing so from a thread + * that's never previously been involved with Tcl, e.g. the task manager) + * so this check is important. + * + * Fixes Bug #217982 reported by Hugh Vu and Gene Leache. + */ - if (tsdPtr == NULL) { - return; - } + if (tsdPtr == NULL) { + return; + } - DeleteCriticalSection(&tsdPtr->crit); - CloseHandle(tsdPtr->event); + DeleteCriticalSection(&tsdPtr->crit); + CloseHandle(tsdPtr->event); - /* - * Clean up the timer and messaging window for this thread. - */ + /* + * Clean up the timer and messaging window for this thread. + */ - if (tsdPtr->hwnd) { - KillTimer(tsdPtr->hwnd, INTERVAL_TIMER); - DestroyWindow(tsdPtr->hwnd); - } + if (tsdPtr->hwnd) { + KillTimer(tsdPtr->hwnd, INTERVAL_TIMER); + DestroyWindow(tsdPtr->hwnd); + } - /* - * If this is the last thread to use the notifier, unregister the - * notifier window class. - */ + /* + * If this is the last thread to use the notifier, unregister the notifier + * window class. + */ - EnterCriticalSection(¬ifierMutex); - if (notifierCount) { - notifierCount--; - if (notifierCount == 0) { - UnregisterClassW(className, TclWinGetTclInstance()); - } + EnterCriticalSection(¬ifierMutex); + if (notifierCount) { + notifierCount--; + if (notifierCount == 0) { + UnregisterClassW(className, TclWinGetTclInstance()); } - LeaveCriticalSection(¬ifierMutex); } + LeaveCriticalSection(¬ifierMutex); } /* *---------------------------------------------------------------------- * - * Tcl_AlertNotifier -- + * TclpAlertNotifier -- * * Wake up the specified notifier from any thread. This routine is called * by the platform independent notifier code whenever the Tcl_ThreadAlert @@ -225,42 +217,37 @@ Tcl_FinalizeNotifier( */ void -Tcl_AlertNotifier( +TclpAlertNotifier( ClientData clientData) /* Pointer to thread data. */ { - if (tclNotifierHooks.alertNotifierProc) { - tclNotifierHooks.alertNotifierProc(clientData); - return; - } else { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; + /* + * Note that we do not need to lock around access to the hwnd because the + * race condition has no effect since any race condition implies that the + * notifier thread is already awake. + */ + + if (tsdPtr->hwnd) { /* - * Note that we do not need to lock around access to the hwnd because - * the race condition has no effect since any race condition implies - * that the notifier thread is already awake. + * We do need to lock around access to the pending flag. */ - if (tsdPtr->hwnd) { - /* - * We do need to lock around access to the pending flag. - */ - - EnterCriticalSection(&tsdPtr->crit); - if (!tsdPtr->pending) { - PostMessageW(tsdPtr->hwnd, WM_WAKEUP, 0, 0); - } - tsdPtr->pending = 1; - LeaveCriticalSection(&tsdPtr->crit); - } else { - SetEvent(tsdPtr->event); + EnterCriticalSection(&tsdPtr->crit); + if (!tsdPtr->pending) { + PostMessageW(tsdPtr->hwnd, WM_WAKEUP, 0, 0); } + tsdPtr->pending = 1; + LeaveCriticalSection(&tsdPtr->crit); + } else { + SetEvent(tsdPtr->event); } } /* *---------------------------------------------------------------------- * - * Tcl_SetTimer -- + * TclpSetTimer -- * * This procedure sets the current notifier timer value. The notifier * will ensure that Tcl_ServiceAll() is called after the specified @@ -276,54 +263,49 @@ Tcl_AlertNotifier( */ void -Tcl_SetTimer( +TclpSetTimer( const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ { - if (tclNotifierHooks.setTimerProc) { - tclNotifierHooks.setTimerProc(timePtr); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + UINT timeout; + + /* + * We only need to set up an interval timer if we're being called from an + * external event loop. If we don't have a window handle then we just + * return immediately and let Tcl_WaitForEvent handle timeouts. + */ + + if (!tsdPtr->hwnd) { return; - } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - UINT timeout; + } + if (!timePtr) { + timeout = 0; + } else { /* - * We only need to set up an interval timer if we're being called from - * an external event loop. If we don't have a window handle then we - * just return immediately and let Tcl_WaitForEvent handle timeouts. + * Make sure we pass a non-zero value into the timeout argument. + * Windows seems to get confused by zero length timers. */ - if (!tsdPtr->hwnd) { - return; + timeout = timePtr->sec * 1000 + timePtr->usec / 1000; + if (timeout == 0) { + timeout = 1; } + } - if (!timePtr) { - timeout = 0; - } else { - /* - * Make sure we pass a non-zero value into the timeout argument. - * Windows seems to get confused by zero length timers. - */ - - timeout = timePtr->sec * 1000 + timePtr->usec / 1000; - if (timeout == 0) { - timeout = 1; - } - } - if (timeout != 0) { - tsdPtr->timerActive = 1; - SetTimer(tsdPtr->hwnd, INTERVAL_TIMER, - timeout, NULL); - } else { - tsdPtr->timerActive = 0; - KillTimer(tsdPtr->hwnd, INTERVAL_TIMER); - } + if (timeout != 0) { + tsdPtr->timerActive = 1; + SetTimer(tsdPtr->hwnd, INTERVAL_TIMER, timeout, NULL); + } else { + tsdPtr->timerActive = 0; + KillTimer(tsdPtr->hwnd, INTERVAL_TIMER); } } /* *---------------------------------------------------------------------- * - * Tcl_ServiceModeHook -- + * TclpServiceModeHook -- * * This function is invoked whenever the service mode changes. * @@ -338,40 +320,33 @@ Tcl_SetTimer( */ void -Tcl_ServiceModeHook( +TclpServiceModeHook( int mode) /* Either TCL_SERVICE_ALL, or * TCL_SERVICE_NONE. */ { - if (tclNotifierHooks.serviceModeHookProc) { - tclNotifierHooks.serviceModeHookProc(mode); - return; - } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - /* - * If this is the first time that the notifier has been used from a - * modal loop, then create a communication window. Note that after this - * point, the application needs to service events in a timely fashion - * or Windows will hang waiting for the window to respond to - * synchronous system messages. At some point, we may want to consider - * destroying the window if we leave the modal loop, but for now we'll - * leave it around. - */ + /* + * If this is the first time that the notifier has been used from a modal + * loop, then create a communication window. Note that after this point, + * the application needs to service events in a timely fashion or Windows + * will hang waiting for the window to respond to synchronous system + * messages. At some point, we may want to consider destroying the window + * if we leave the modal loop, but for now we'll leave it around. + */ - if (mode == TCL_SERVICE_ALL && !tsdPtr->hwnd) { - tsdPtr->hwnd = CreateWindowW(className, className, - WS_TILED, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), - NULL); + if (mode == TCL_SERVICE_ALL && !tsdPtr->hwnd) { + tsdPtr->hwnd = CreateWindowW(className, className, WS_TILED, + 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL); - /* - * Send an initial message to the window to ensure that we wake up - * the notifier once we get into the modal loop. This will force - * the notifier to recompute the timeout value and schedule a timer - * if one is needed. - */ + /* + * Send an initial message to the window to ensure that we wake up the + * notifier once we get into the modal loop. This will force the + * notifier to recompute the timeout value and schedule a timer if one + * is needed. + */ - Tcl_AlertNotifier(tsdPtr); - } + Tcl_AlertNotifier(tsdPtr); } } @@ -421,7 +396,7 @@ NotifierProc( /* *---------------------------------------------------------------------- * - * Tcl_WaitForEvent -- + * TclpWaitForEvent -- * * This function is called by Tcl_DoOneEvent to wait for new events on * the message queue. If the block time is 0, then Tcl_WaitForEvent just @@ -438,103 +413,99 @@ NotifierProc( */ int -Tcl_WaitForEvent( +TclpWaitForEvent( const Tcl_Time *timePtr) /* Maximum block time, or NULL. */ { - if (tclNotifierHooks.waitForEventProc) { - return tclNotifierHooks.waitForEventProc(timePtr); - } else { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - MSG msg; - DWORD timeout, result; - int status; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + MSG msg; + DWORD timeout, result; + int status; + /* + * Compute the timeout in milliseconds. + */ + + if (timePtr) { /* - * Compute the timeout in milliseconds. + * TIP #233 (Virtualized Time). Convert virtual domain delay to + * real-time. */ - if (timePtr) { - /* - * TIP #233 (Virtualized Time). Convert virtual domain delay to - * real-time. - */ + Tcl_Time myTime; - Tcl_Time myTime; + myTime.sec = timePtr->sec; + myTime.usec = timePtr->usec; - myTime.sec = timePtr->sec; - myTime.usec = timePtr->usec; + if (myTime.sec != 0 || myTime.usec != 0) { + TclScaleTime(&myTime); + } - if (myTime.sec != 0 || myTime.usec != 0) { - tclScaleTimeProcPtr(&myTime, tclTimeClientData); - } + timeout = myTime.sec * 1000 + myTime.usec / 1000; + } else { + timeout = INFINITE; + } - timeout = myTime.sec * 1000 + myTime.usec / 1000; - } else { - timeout = INFINITE; - } + /* + * Check to see if there are any messages in the queue before waiting + * because MsgWaitForMultipleObjects will not wake up if there are events + * currently sitting in the queue. + */ + if (!PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) { /* - * Check to see if there are any messages in the queue before waiting - * because MsgWaitForMultipleObjects will not wake up if there are - * events currently sitting in the queue. + * Wait for something to happen (a signal from another thread, a + * message, or timeout) or loop servicing asynchronous procedure calls + * queued to this thread. */ - if (!PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) { - /* - * Wait for something to happen (a signal from another thread, a - * message, or timeout) or loop servicing asynchronous procedure - * calls queued to this thread. - */ - - again: + do { result = MsgWaitForMultipleObjectsEx(1, &tsdPtr->event, timeout, QS_ALLINPUT, MWMO_ALERTABLE); - if (result == WAIT_IO_COMPLETION) { - goto again; - } else if (result == WAIT_FAILED) { - status = -1; - goto end; - } + } while (result == WAIT_IO_COMPLETION); + + if (result == WAIT_FAILED) { + status = -1; + goto end; } + } + + /* + * Check to see if there are any messages to process. + */ + if (PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) { /* - * Check to see if there are any messages to process. + * Retrieve and dispatch the first message. */ - if (PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) { + result = GetMessageW(&msg, NULL, 0, 0); + if (result == 0) { /* - * Retrieve and dispatch the first message. + * We received a request to exit this thread (WM_QUIT), so + * propagate the quit message and start unwinding. */ - result = GetMessageW(&msg, NULL, 0, 0); - if (result == 0) { - /* - * We received a request to exit this thread (WM_QUIT), so - * propagate the quit message and start unwinding. - */ - - PostQuitMessage((int) msg.wParam); - status = -1; - } else if (result == (DWORD)-1) { - /* - * We got an error from the system. I have no idea why this - * would happen, so we'll just unwind. - */ - - status = -1; - } else { - TranslateMessage(&msg); - DispatchMessageW(&msg); - status = 1; - } + PostQuitMessage((int) msg.wParam); + status = -1; + } else if (result == (DWORD) -1) { + /* + * We got an error from the system. I have no idea why this would + * happen, so we'll just unwind. + */ + + status = -1; } else { - status = 0; + TranslateMessage(&msg); + DispatchMessageW(&msg); + status = 1; } - - end: - ResetEvent(tsdPtr->event); - return status; + } else { + status = 0; } + + end: + ResetEvent(tsdPtr->event); + return status; } /* @@ -588,7 +559,7 @@ Tcl_Sleep( * TIP #233: Scale delay from virtual to real-time. */ - tclScaleTimeProcPtr(&vdelay, tclTimeClientData); + TclScaleTime(&vdelay); sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000; for (;;) { @@ -603,12 +574,52 @@ Tcl_Sleep( vdelay.sec = desired.sec - now.sec; vdelay.usec = desired.usec - now.usec; - tclScaleTimeProcPtr(&vdelay, tclTimeClientData); + TclScaleTime(&vdelay); sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000; } } /* + *---------------------------------------------------------------------- + * + * TclpCreateFileHandler, TclpDeleteFileHandler -- + * + * Stub functions for strictly POSIX-only functionality that panic with a + * failure message; they simply don't work at all on Windows so using + * them on the platform is always a programming bug. + * + * Results: + * None. + * + * Side effects: + * The process will terminate, violently. + * + *---------------------------------------------------------------------- + */ + +void +TclpCreateFileHandler( + int fd, /* Handle of stream to watch. */ + int mask, /* OR'ed combination of TCL_READABLE, + * TCL_WRITABLE, and TCL_EXCEPTION: indicates + * conditions under which proc should be + * called. */ + Tcl_FileProc *proc, /* Function to call for each selected + * event. */ + ClientData clientData) /* Arbitrary data to pass to proc. */ +{ + Tcl_Panic("Tcl_CreateFileHandler not supported on this platform"); +} + +void +Tcl_DeleteFileHandler( + int fd) /* Stream id for which to remove callback + * function. */ +{ + Tcl_Panic("Tcl_DeleteFileHandler not supported on this platform"); +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 64890c4..e05455f 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -53,7 +53,8 @@ typedef struct { * initialized. */ int perfCounterAvailable; /* Flag == 1 if the hardware has a performance * counter. */ - DWORD calibrationInterv; /* Calibration interval in seconds (start 1 sec) */ + DWORD calibrationInterv; /* Calibration interval in seconds (start 1 + * sec) */ HANDLE calibrationThread; /* Handle to the thread that keeps the virtual * clock calibrated. */ HANDLE readyEvent; /* System event used to trigger the requesting @@ -122,7 +123,8 @@ static TimeInfo timeInfo = { */ static struct { int initialized; /* 1 if initialized, 0 otherwise */ - int perfCounter; /* 1 if performance counter usable for wide clicks */ + int perfCounter; /* 1 if performance counter usable for wide + * clicks */ double microsecsScale; /* Denominator scale between clock / microsecs */ } wideClick = {0, 0, 0.0}; @@ -156,6 +158,23 @@ Tcl_ScaleTimeProc *tclScaleTimeProcPtr = NativeScaleTime; ClientData tclTimeClientData = NULL; /* + * Inlined version of Tcl_GetTime. + */ + +static inline void +GetTime( + Tcl_Time *timePtr) +{ + tclGetTimeProcPtr(timePtr, tclTimeClientData); +} + +static inline int +IsTimeNative(void) +{ + return tclGetTimeProcPtr == NativeGetTime; +} + +/* *---------------------------------------------------------------------- * * TclpGetSeconds -- @@ -177,15 +196,16 @@ TclpGetSeconds(void) { long long usecSincePosixEpoch; - /* Try to use high resolution timer */ - if ( tclGetTimeProcPtr == NativeGetTime - && (usecSincePosixEpoch = NativeGetMicroseconds()) - ) { + /* + * Try to use high resolution timer + */ + + if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) { return usecSincePosixEpoch / 1000000; } else { Tcl_Time t; - tclGetTimeProcPtr(&t, tclTimeClientData); /* Tcl_GetTime inlined. */ + GetTime(&t); return t.sec; } } @@ -214,11 +234,12 @@ TclpGetClicks(void) { long long usecSincePosixEpoch; - /* Try to use high resolution timer */ - if ( tclGetTimeProcPtr == NativeGetTime - && (usecSincePosixEpoch = NativeGetMicroseconds()) - ) { - return (unsigned long)usecSincePosixEpoch; + /* + * Try to use high resolution timer. + */ + + if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) { + return (unsigned long) usecSincePosixEpoch; } else { /* * Use the Tcl_GetTime abstraction to get the time in microseconds, as @@ -227,8 +248,8 @@ TclpGetClicks(void) Tcl_Time now; /* Current Tcl time */ - tclGetTimeProcPtr(&now, tclTimeClientData); /* Tcl_GetTime inlined */ - return (unsigned long)(now.sec * 1000000) + now.usec; + GetTime(&now); + return (unsigned long) (now.sec * 1000000) + now.usec; } } @@ -264,6 +285,7 @@ TclpGetWideClicks(void) * is consistent across all processors. Therefore, the frequency need * only be queried upon application initialization. */ + if (QueryPerformanceFrequency(&perfCounterFreq)) { wideClick.perfCounter = 1; wideClick.microsecsScale = 1000000.0 / perfCounterFreq.QuadPart; @@ -310,7 +332,7 @@ double TclpWideClickInMicrosec(void) { if (!wideClick.initialized) { - (void)TclpGetWideClicks(); /* initialize */ + (void) TclpGetWideClicks(); /* initialize */ } return wideClick.microsecsScale; } @@ -337,21 +359,22 @@ TclpGetMicroseconds(void) { long long usecSincePosixEpoch; - /* Try to use high resolution timer */ - if ( tclGetTimeProcPtr == NativeGetTime - && (usecSincePosixEpoch = NativeGetMicroseconds()) - ) { + /* + * Try to use high resolution timer. + */ + + if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) { return usecSincePosixEpoch; } else { /* - * Use the Tcl_GetTime abstraction to get the time in microseconds, as - * nearly as we can, and return it. - */ + * Use the Tcl_GetTime abstraction to get the time in microseconds, as + * nearly as we can, and return it. + */ Tcl_Time now; - tclGetTimeProcPtr(&now, tclTimeClientData); /* Tcl_GetTime inlined */ - return (((long long)now.sec) * 1000000) + now.usec; + GetTime(&now); + return (((long long) now.sec) * 1000000) + now.usec; } } @@ -383,14 +406,15 @@ Tcl_GetTime( { long long usecSincePosixEpoch; - /* Try to use high resolution timer */ - if ( tclGetTimeProcPtr == NativeGetTime - && (usecSincePosixEpoch = NativeGetMicroseconds()) - ) { + /* + * Try to use high resolution timer. + */ + + if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) { timePtr->sec = (long) (usecSincePosixEpoch / 1000000); timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000); } else { - tclGetTimeProcPtr(timePtr, tclTimeClientData); + GetTime(timePtr); } } @@ -424,6 +448,96 @@ NativeScaleTime( /* *---------------------------------------------------------------------- * + * IsPerfCounterAvailable -- + * + * Tests whether the performance counter is available, which is a gnarly + * problem on 32-bit systems. Also retrieves the nominal frequency of the + * performance counter. + * + * Results: + * 1 if the counter is available, 0 if not. + * + * Side effects: + * Updates fields of the timeInfo global. Make sure you hold the lock + * before calling this. + * + *---------------------------------------------------------------------- + */ + +static inline int +IsPerfCounterAvailable(void) +{ + timeInfo.perfCounterAvailable = + QueryPerformanceFrequency(&timeInfo.nominalFreq); + + /* + * Some hardware abstraction layers use the CPU clock in place of the + * real-time clock as a performance counter reference. This results in: + * - inconsistent results among the processors on multi-processor + * systems. + * - unpredictable changes in performance counter frequency on + * "gearshift" processors such as Transmeta and SpeedStep. + * + * There seems to be no way to test whether the performance counter is + * reliable, but a useful heuristic is that if its frequency is 1.193182 + * MHz or 3.579545 MHz, it's derived from a colorburst crystal and is + * therefore the RTC rather than the TSC. + * + * A sloppier but serviceable heuristic is that the RTC crystal is + * normally less than 15 MHz while the TSC crystal is virtually assured to + * be greater than 100 MHz. Since Win98SE appears to fiddle with the + * definition of the perf counter frequency (perhaps in an attempt to + * calibrate the clock?), we use the latter rule rather than an exact + * match. + * + * We also assume (perhaps questionably) that the vendors have gotten + * their act together on Win64, so bypass all this rubbish on that + * platform. + */ + +#if !defined(_WIN64) + if (timeInfo.perfCounterAvailable && + /* + * The following lines would do an exact match on crystal + * frequency: + * + * timeInfo.nominalFreq.QuadPart != (long long) 1193182 && + * timeInfo.nominalFreq.QuadPart != (long long) 3579545 && + */ + timeInfo.nominalFreq.QuadPart > (long long) 15000000) { + /* + * As an exception, if every logical processor on the system is on the + * same chip, we use the performance counter anyway, presuming that + * everyone's TSC is locked to the same oscillator. + */ + + SYSTEM_INFO systemInfo; + int regs[4]; + + GetSystemInfo(&systemInfo); + if (TclWinCPUID(0, regs) == TCL_OK + && regs[1] == 0x756E6547 /* "Genu" */ + && regs[3] == 0x49656E69 /* "ineI" */ + && regs[2] == 0x6C65746E /* "ntel" */ + && TclWinCPUID(1, regs) == TCL_OK + && ((regs[0]&0x00000F00) == 0x00000F00 /* Pentium 4 */ + || ((regs[0] & 0x00F00000) /* Extended family */ + && (regs[3] & 0x10000000))) /* Hyperthread */ + && (((regs[1]&0x00FF0000) >> 16)/* CPU count */ + == (int)sy stemInfo.dwNumberOfProcessors)) { + timeInfo.perfCounterAvailable = TRUE; + } else { + timeInfo.perfCounterAvailable = FALSE; + } + } +#endif /* above code is Win32 only */ + + return timeInfo.perfCounterAvailable; +} + +/* + *---------------------------------------------------------------------- + * * NativeGetMicroseconds -- * * Gets the current system time in microseconds since the beginning @@ -449,10 +563,10 @@ NativeCalc100NsTicks( ULONGLONG fileTimeLastCall, LONGLONG perfCounterLastCall, LONGLONG curCounterFreq, - LONGLONG curCounter -) { + LONGLONG curCounter) +{ return fileTimeLastCall + - ((curCounter - perfCounterLastCall) * 10000000 / curCounterFreq); + ((curCounter - perfCounterLastCall) * 10000000 / curCounterFreq); } static long long @@ -468,83 +582,15 @@ NativeGetMicroseconds(void) if (!timeInfo.initialized) { TclpInitLock(); if (!timeInfo.initialized) { - timeInfo.posixEpoch.LowPart = 0xD53E8000; timeInfo.posixEpoch.HighPart = 0x019DB1DE; - timeInfo.perfCounterAvailable = - QueryPerformanceFrequency(&timeInfo.nominalFreq); - - /* - * Some hardware abstraction layers use the CPU clock in place of - * the real-time clock as a performance counter reference. This - * results in: - * - inconsistent results among the processors on - * multi-processor systems. - * - unpredictable changes in performance counter frequency on - * "gearshift" processors such as Transmeta and SpeedStep. - * - * There seems to be no way to test whether the performance - * counter is reliable, but a useful heuristic is that if its - * frequency is 1.193182 MHz or 3.579545 MHz, it's derived from a - * colorburst crystal and is therefore the RTC rather than the - * TSC. - * - * A sloppier but serviceable heuristic is that the RTC crystal is - * normally less than 15 MHz while the TSC crystal is virtually - * assured to be greater than 100 MHz. Since Win98SE appears to - * fiddle with the definition of the perf counter frequency - * (perhaps in an attempt to calibrate the clock?), we use the - * latter rule rather than an exact match. - * - * We also assume (perhaps questionably) that the vendors have - * gotten their act together on Win64, so bypass all this rubbish - * on that platform. - */ - -#if !defined(_WIN64) - if (timeInfo.perfCounterAvailable - /* - * The following lines would do an exact match on crystal - * frequency: - * && timeInfo.nominalFreq.QuadPart != (long long)1193182 - * && timeInfo.nominalFreq.QuadPart != (long long)3579545 - */ - && timeInfo.nominalFreq.QuadPart > (long long) 15000000){ - /* - * As an exception, if every logical processor on the system - * is on the same chip, we use the performance counter anyway, - * presuming that everyone's TSC is locked to the same - * oscillator. - */ - - SYSTEM_INFO systemInfo; - int regs[4]; - - GetSystemInfo(&systemInfo); - if (TclWinCPUID(0, regs) == TCL_OK - && regs[1] == 0x756E6547 /* "Genu" */ - && regs[3] == 0x49656E69 /* "ineI" */ - && regs[2] == 0x6C65746E /* "ntel" */ - && TclWinCPUID(1, regs) == TCL_OK - && ((regs[0]&0x00000F00) == 0x00000F00 /* Pentium 4 */ - || ((regs[0] & 0x00F00000) /* Extended family */ - && (regs[3] & 0x10000000))) /* Hyperthread */ - && (((regs[1]&0x00FF0000) >> 16)/* CPU count */ - == (int)systemInfo.dwNumberOfProcessors)) { - timeInfo.perfCounterAvailable = TRUE; - } else { - timeInfo.perfCounterAvailable = FALSE; - } - } -#endif /* above code is Win32 only */ - /* * If the performance counter is available, start a thread to * calibrate it. */ - if (timeInfo.perfCounterAvailable) { + if (IsPerfCounterAvailable()) { DWORD id; InitializeCriticalSection(&timeInfo.cs); @@ -578,7 +624,8 @@ NativeGetMicroseconds(void) ULONGLONG fileTimeLastCall; LONGLONG perfCounterLastCall, curCounterFreq; - /* Copy with current data of calibration cycle */ + /* Copy with current data of calibration + * cycle. */ LARGE_INTEGER curCounter; /* Current performance counter. */ @@ -588,6 +635,7 @@ NativeGetMicroseconds(void) /* * Hold time section locked as short as possible */ + EnterCriticalSection(&timeInfo.cs); fileTimeLastCall = timeInfo.fileTimeLastCall.QuadPart; @@ -599,8 +647,12 @@ NativeGetMicroseconds(void) /* * If calibration cycle occurred after we get curCounter */ + if (curCounter.QuadPart <= perfCounterLastCall) { - /* Calibrated file-time is saved from posix in 100-ns ticks */ + /* + * Calibrated file-time is saved from posix in 100-ns ticks + */ + return fileTimeLastCall / 10; } @@ -615,11 +667,14 @@ NativeGetMicroseconds(void) */ if (curCounter.QuadPart - perfCounterLastCall < - 11 * curCounterFreq * timeInfo.calibrationInterv / 10 - ) { - /* Calibrated file-time is saved from posix in 100-ns ticks */ + 11 * curCounterFreq * timeInfo.calibrationInterv / 10) { + /* + * Calibrated file-time is saved from posix in 100-ns ticks. + */ + return NativeCalc100NsTicks(fileTimeLastCall, - perfCounterLastCall, curCounterFreq, curCounter.QuadPart) / 10; + perfCounterLastCall, curCounterFreq, + curCounter.QuadPart) / 10; } } @@ -656,18 +711,20 @@ NativeGetTime( /* * Try to use high resolution timer. */ - if ( (usecSincePosixEpoch = NativeGetMicroseconds()) ) { + + usecSincePosixEpoch = NativeGetMicroseconds(); + if (usecSincePosixEpoch) { timePtr->sec = (long) (usecSincePosixEpoch / 1000000); timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000); } else { /* - * High resolution timer is not available. Just use ftime. - */ + * High resolution timer is not available. Just use ftime. + */ struct _timeb t; _ftime(&t); - timePtr->sec = (long)t.time; + timePtr->sec = (long) t.time; timePtr->usec = t.millitm * 1000; } } @@ -735,9 +792,9 @@ TclpGetDate( struct tm *tmPtr; time_t time; #if defined(_WIN64) || (defined(_USE_64BIT_TIME_T) || (defined(_MSC_VER) && _MSC_VER < 1400)) -# define t2 *t /* no need to cripple time to 32-bit */ +# define t2 *t /* no need to cripple time to 32-bit */ #else - time_t t2 = *(__time32_t *)t; + time_t t2 = *(__time32_t *) t; #endif if (!useGMT) { @@ -789,14 +846,14 @@ TclpGetDate( time -= 60; } - time = tmPtr->tm_min + time/60; + time = tmPtr->tm_min + time / 60; tmPtr->tm_min = (int)(time % 60); if (tmPtr->tm_min < 0) { tmPtr->tm_min += 60; time -= 60; } - time = tmPtr->tm_hour + time/60; + time = tmPtr->tm_hour + time / 60; tmPtr->tm_hour = (int)(time % 24); if (tmPtr->tm_hour < 0) { tmPtr->tm_hour += 24; @@ -804,9 +861,9 @@ TclpGetDate( } time /= 24; - tmPtr->tm_mday += (int)time; - tmPtr->tm_yday += (int)time; - tmPtr->tm_wday = (tmPtr->tm_wday + (int)time) % 7; + tmPtr->tm_mday += (int) time; + tmPtr->tm_yday += (int) time; + tmPtr->tm_wday = (tmPtr->tm_wday + (int) time) % 7; } } else { tmPtr = ComputeGMT(&t2); @@ -847,8 +904,8 @@ ComputeGMT( * Compute the 4 year span containing the specified time. */ - tmp = (long)(*tp / SECSPER4YEAR); - rem = (long)(*tp % SECSPER4YEAR); + tmp = (long) (*tp / SECSPER4YEAR); + rem = (long) (*tp % SECSPER4YEAR); /* * Correct for weird mod semantics so the remainder is always positive. @@ -915,7 +972,7 @@ ComputeGMT( * Compute day of week. Epoch started on a Thursday. */ - tmPtr->tm_wday = (long)(*tp / SECSPERDAY) + 4; + tmPtr->tm_wday = (long) (*tp / SECSPERDAY) + 4; if ((*tp % SECSPERDAY) < 0) { tmPtr->tm_wday--; } @@ -970,7 +1027,11 @@ CalibrationThread( QueryPerformanceFrequency(&timeInfo.curCounterFreq); timeInfo.fileTimeLastCall.LowPart = curFileTime.dwLowDateTime; timeInfo.fileTimeLastCall.HighPart = curFileTime.dwHighDateTime; - /* Calibrated file-time will be saved from posix in 100-ns ticks */ + + /* + * Calibrated file-time will be saved from posix in 100-ns ticks. + */ + timeInfo.fileTimeLastCall.QuadPart -= timeInfo.posixEpoch.QuadPart; ResetCounterSamples(timeInfo.fileTimeLastCall.QuadPart, @@ -1030,10 +1091,11 @@ UpdateTimeEachSecond(void) /* Current value returned from * QueryPerformanceCounter. */ FILETIME curSysTime; /* Current system time. */ - static LARGE_INTEGER lastFileTime; /* File time of the previous calibration */ + static LARGE_INTEGER lastFileTime; + /* File time of the previous calibration */ LARGE_INTEGER curFileTime; /* File time at the time this callback was * scheduled. */ - long long estFreq; /* Estimated perf counter frequency. */ + long long estFreq; /* Estimated perf counter frequency. */ long long vt0; /* Tcl time right now. */ long long vt1; /* Tcl time one second from now. */ long long tdiff; /* Difference between system clock and Tcl @@ -1049,12 +1111,17 @@ UpdateTimeEachSecond(void) curFileTime.LowPart = curSysTime.dwLowDateTime; curFileTime.HighPart = curSysTime.dwHighDateTime; curFileTime.QuadPart -= timeInfo.posixEpoch.QuadPart; - /* If calibration still not needed (check for possible time switch) */ - if ( curFileTime.QuadPart > lastFileTime.QuadPart - && curFileTime.QuadPart < lastFileTime.QuadPart + - (timeInfo.calibrationInterv * 10000000) - ) { - /* again in next one second */ + + /* + * If calibration still not needed (check for possible time switch) + */ + + if (curFileTime.QuadPart > lastFileTime.QuadPart && curFileTime.QuadPart < + lastFileTime.QuadPart + (timeInfo.calibrationInterv * 10000000)) { + /* + * Look again in next one second. + */ + return; } QueryPerformanceCounter(&curPerfCounter); @@ -1110,8 +1177,9 @@ UpdateTimeEachSecond(void) */ vt0 = NativeCalc100NsTicks(timeInfo.fileTimeLastCall.QuadPart, - timeInfo.perfCounterLastCall.QuadPart, timeInfo.curCounterFreq.QuadPart, - curPerfCounter.QuadPart); + timeInfo.perfCounterLastCall.QuadPart, + timeInfo.curCounterFreq.QuadPart, curPerfCounter.QuadPart); + /* * If we've gotten more than a second away from system time, then drifting * the clock is going to be pretty hopeless. Just let it jump. Otherwise, @@ -1120,17 +1188,25 @@ UpdateTimeEachSecond(void) tdiff = vt0 - curFileTime.QuadPart; if (tdiff > 10000000 || tdiff < -10000000) { - /* jump to current system time, use curent estimated frequency */ + /* + * Jump to current system time, use curent estimated frequency. + */ + vt0 = curFileTime.QuadPart; } else { - /* calculate new frequency and estimate drift to the next second */ + /* + * Calculate new frequency and estimate drift to the next second. + */ + vt1 = 20000000 + curFileTime.QuadPart; driftFreq = (estFreq * 20000000 / (vt1 - vt0)); + /* - * Avoid too large drifts (only half of the current difference), - * that allows also be more accurate (aspire to the smallest tdiff), - * so then we can prolong calibration interval by tdiff < 100000 + * Avoid too large drifts (only half of the current difference), that + * allows also be more accurate (aspire to the smallest tdiff), so + * then we can prolong calibration interval by tdiff < 100000 */ + driftFreq = timeInfo.curCounterFreq.QuadPart + (driftFreq - timeInfo.curCounterFreq.QuadPart) / 2; @@ -1138,50 +1214,78 @@ UpdateTimeEachSecond(void) * Average between estimated, 2 current and 5 drifted frequencies, * (do the soft drifting as possible) */ - estFreq = (estFreq + 2 * timeInfo.curCounterFreq.QuadPart + 5 * driftFreq) / 8; + + estFreq = (estFreq + 2 * timeInfo.curCounterFreq.QuadPart + + 5 * driftFreq) / 8; } - /* Avoid too large discrepancy from nominal frequency */ - if (estFreq > 1003*timeInfo.nominalFreq.QuadPart/1000) { - estFreq = 1003*timeInfo.nominalFreq.QuadPart/1000; + /* + * Avoid too large discrepancy from nominal frequency. + */ + + if (estFreq > 1003 * timeInfo.nominalFreq.QuadPart / 1000) { + estFreq = 1003 * timeInfo.nominalFreq.QuadPart / 1000; vt0 = curFileTime.QuadPart; - } else if (estFreq < 997*timeInfo.nominalFreq.QuadPart/1000) { - estFreq = 997*timeInfo.nominalFreq.QuadPart/1000; + } else if (estFreq < 997 * timeInfo.nominalFreq.QuadPart / 1000) { + estFreq = 997 * timeInfo.nominalFreq.QuadPart / 1000; vt0 = curFileTime.QuadPart; } else if (vt0 != curFileTime.QuadPart) { /* - * Be sure the clock ticks never backwards (avoid it by negative drifting) - * just compare native time (in 100-ns) before and hereafter using - * new calibrated values) and do a small adjustment (short time freeze) + * Be sure the clock ticks never backwards (avoid it by negative + * drifting). Just compare native time (in 100-ns) before and + * hereafter using new calibrated values) and do a small adjustment + * (short time freeze). */ + LARGE_INTEGER newPerfCounter; long long nt0, nt1; QueryPerformanceCounter(&newPerfCounter); nt0 = NativeCalc100NsTicks(timeInfo.fileTimeLastCall.QuadPart, - timeInfo.perfCounterLastCall.QuadPart, timeInfo.curCounterFreq.QuadPart, - newPerfCounter.QuadPart); + timeInfo.perfCounterLastCall.QuadPart, + timeInfo.curCounterFreq.QuadPart, newPerfCounter.QuadPart); nt1 = NativeCalc100NsTicks(vt0, - curPerfCounter.QuadPart, estFreq, - newPerfCounter.QuadPart); - if (nt0 > nt1) { /* drifted backwards, try to compensate with new base */ - /* first adjust with a micro jump (short frozen time is acceptable) */ + curPerfCounter.QuadPart, estFreq, newPerfCounter.QuadPart); + if (nt0 > nt1) { + /* + * Drifted backwards, try to compensate with new base. + * + * First adjust with a micro jump (short frozen time is + * acceptable). + */ vt0 += nt0 - nt1; - /* if drift unavoidable (e. g. we had a time switch), then reset it */ + + /* + * If drift unavoidable (e. g. we had a time switch), then reset + * it. + */ + vt1 = vt0 - curFileTime.QuadPart; if (vt1 > 10000000 || vt1 < -10000000) { - /* larger jump resp. shift relative new file-time */ + /* + * Larger jump resp. shift relative new file-time. + */ + vt0 = curFileTime.QuadPart; } } } - /* In lock commit new values to timeInfo (hold lock as short as possible) */ + /* + * In lock commit new values to timeInfo (hold lock as short as possible) + */ + EnterCriticalSection(&timeInfo.cs); - /* grow calibration interval up to 10 seconds (if still precise enough) */ + /* + * Grow calibration interval up to 10 seconds (if still precise enough) + */ + if (tdiff < -100000 || tdiff > 100000) { - /* too long drift - reset calibration interval to 1000 second */ + /* + * Too long drift. Reset calibration interval to 1000 second. + */ + timeInfo.calibrationInterv = 1; } else if (timeInfo.calibrationInterv < 10) { timeInfo.calibrationInterv++; @@ -1215,12 +1319,13 @@ UpdateTimeEachSecond(void) static void ResetCounterSamples( - unsigned long long fileTime, /* Current file time */ + unsigned long long fileTime,/* Current file time */ long long perfCounter, /* Current performance counter */ - long long perfFreq) /* Target performance frequency */ + long long perfFreq) /* Target performance frequency */ { int i; - for (i=SAMPLES-1 ; i>=0 ; --i) { + + for (i = SAMPLES - 1 ; i >= 0 ; --i) { timeInfo.perfCounterSample[i] = perfCounter; timeInfo.fileTimeSample[i] = fileTime; perfCounter -= perfFreq; @@ -1260,15 +1365,17 @@ AccumulateSample( long long perfCounter, unsigned long long fileTime) { - unsigned long long workFTSample; /* File time sample being removed from or + unsigned long long workFTSample; + /* File time sample being removed from or * added to the circular buffer. */ long long workPCSample; /* Performance counter sample being removed * from or added to the circular buffer. */ - unsigned long long lastFTSample; /* Last file time sample recorded */ + unsigned long long lastFTSample; + /* Last file time sample recorded */ long long lastPCSample; /* Last performance counter sample recorded */ long long FTdiff; /* Difference between last FT and current */ long long PCdiff; /* Difference between last PC and current */ - long long estFreq; /* Estimated performance counter frequency */ + long long estFreq; /* Estimated performance counter frequency */ /* * Test for jumps and reset the samples if we have one. @@ -1347,8 +1454,8 @@ TclpGmtime( #if defined(_WIN64) || defined(_USE_64BIT_TIME_T) || (defined(_MSC_VER) && _MSC_VER < 1400) return gmtime(timePtr); #else - return _gmtime32((const __time32_t *)timePtr); -#endif + return _gmtime32((const __time32_t *) timePtr); +#endif /* _WIN64 || _USE_64BIT_TIME_T || _MSC_VER < 1400 */ } /* @@ -1382,8 +1489,8 @@ TclpLocaltime( #if defined(_WIN64) || defined(_USE_64BIT_TIME_T) || (defined(_MSC_VER) && _MSC_VER < 1400) return localtime(timePtr); #else - return _localtime32((const __time32_t *)timePtr); -#endif + return _localtime32((const __time32_t *) timePtr); +#endif /* _WIN64 || _USE_64BIT_TIME_T || _MSC_VER < 1400 */ } #endif /* TCL_NO_DEPRECATED */ @@ -1449,6 +1556,33 @@ Tcl_QueryTimeProc( } /* + *---------------------------------------------------------------------- + * + * TclScaleTime -- + * + * TIP #233 (Virtualized Time): Wrapper around the time virutalisation + * rescale function. + * + * Results: + * None + * + * Side effects: + * Updates the time structure (given as an argument) with what the time + * should be after virtualisation. + * + *---------------------------------------------------------------------- + */ + +void +TclScaleTime( + Tcl_Time *timePtr) +{ + if (timePtr != NULL && tclScaleTimeProcPtr != NULL) { + tclScaleTimeProcPtr(timePtr, tclTimeClientData); + } +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 From 63f4be3aa2f1fe3a2f36da8509a5b02b8381870d Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 30 Mar 2021 09:03:19 +0000 Subject: Improve documentation for exec and open, especially in relation to binary pipelines --- doc/exec.n | 26 ++++++++++++++++++++++++++ doc/open.n | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/doc/exec.n b/doc/exec.n index e40b596..89c6413 100644 --- a/doc/exec.n +++ b/doc/exec.n @@ -23,6 +23,10 @@ of one or more subprocesses to execute. The arguments take the form of a standard shell pipeline where each \fIarg\fR becomes one word of a command, and each distinct command becomes a subprocess. +The result of the command is the standard output of the final subprocess in +the pipeline, interpreted using the system \fBencoding\fR; to use any other +encoding (especially including binary data), the pipeline must be +\fBopen\fRed, configured and read explicitly. .PP If the initial arguments to \fBexec\fR start with \fB\-\fR then they are treated as command-line switches and are not part @@ -369,6 +373,7 @@ The \fBexec\fR command is fully functional and works as described. Here are some examples of the use of the \fBexec\fR command on Unix. .PP To execute a simple program and get its result: +.PP .CS \fBexec\fR uname -a .CE @@ -376,6 +381,7 @@ To execute a simple program and get its result: To execute a program that can return a non-zero result, you should wrap the call to \fBexec\fR in \fBcatch\fR and check the contents of the \fB\-errorcode\fR return option if you have an error: +.PP .CS set status 0 if {[catch {\fBexec\fR grep foo bar.txt} results options]} { @@ -391,10 +397,13 @@ if {[catch {\fBexec\fR grep foo bar.txt} results options]} { When translating a command from a Unix shell invocation, care should be taken over the fact that single quote characters have no special significance to Tcl. Thus: +.PP .CS awk '{sum += $1} END {print sum}' numbers.list .CE +.PP would be translated into something like: +.PP .CS \fBexec\fR awk {{sum += $1} END {print sum}} numbers.list .CE @@ -403,6 +412,7 @@ If you are converting invocations involving shell globbing, you should remember that Tcl does not handle globbing or expand things into multiple arguments by default. Instead you should write things like this: +.PP .CS \fBexec\fR ls -l {*}[glob *.tcl] .CE @@ -411,26 +421,41 @@ Here are some examples of the use of the \fBexec\fR command on Windows. .PP To start an instance of \fInotepad\fR editing a file without waiting for the user to finish editing the file: +.PP .CS \fBexec\fR notepad myfile.txt & .CE .PP To print a text file using \fInotepad\fR: +.PP .CS \fBexec\fR notepad /p myfile.txt .CE .PP +To print a text file in a directory other than the current one using +\fInotepad\fR, you need to use \fBfile nativename\fR to convert the name into +a form that will be understood by the other program: +.PP +.CS +\fBexec\fR notepad /p [file nativename some/dir/myfile.txt] +.CE +.PP If a program calls other programs, such as is common with compilers, then you may need to resort to batch files to hide the console windows that sometimes pop up: +.PP .CS \fBexec\fR cmp.bat somefile.c -o somefile .CE +.PP With the file \fIcmp.bat\fR looking something like: +.PP .CS @gcc %* .CE +.PP or like another variant using single parameters: +.PP .CS @gcc %1 %2 %3 %4 %5 %6 %7 %8 %9 .CE @@ -448,6 +473,7 @@ applies especially when you want to run commands like \fIdir\fR from a Tcl script (if you just want to list filenames, use the \fBglob\fR command.) To do that, use this: +.PP .CS \fBexec\fR {*}[auto_execok dir] *.tcl .CE diff --git a/doc/open.n b/doc/open.n index a9da946..844433e 100644 --- a/doc/open.n +++ b/doc/open.n @@ -68,7 +68,7 @@ reading or writing of binary data. .VE 8.5 .PP In the second form, \fIaccess\fR consists of a list of any of the -following flags, all of which have the standard POSIX meanings. +following flags, most of which have the standard POSIX meanings. One of the flags must be either \fBRDONLY\fR, \fBWRONLY\fR or \fBRDWR\fR. .TP 15 \fBRDONLY\fR @@ -351,7 +351,13 @@ pipe is closed. These problems only occur because both Tcl and the child application are competing for the console at the same time. If the command pipeline is started from a script, so that Tcl is not accessing the console, or if the command pipeline does not use standard input or output, but is -redirected from or to a file, then the above problems do not occur. +redirected from or to a file, then the above problems do not occur. +.PP +Files opened in the +.QW \fBa\fR +mode or with the \fBAPPEND\fR flag set are implemented by seeking immediately +before each write, which is not an atomic operation and does not carry the +guarantee of strict appending that is present on POSIX platforms. .RE .TP \fBUnix\fR\0\0\0\0\0\0\0 @@ -376,8 +382,23 @@ input, but is redirected from a file, then the above problem does not occur. See the \fBPORTABILITY ISSUES\fR section of the \fBexec\fR command for additional information not specific to command pipelines about executing applications on the various platforms -.SH "EXAMPLE" +.SH "EXAMPLES" +Open a file for writing, forcing it to be created and raising an error if it +already exists. +.PP +.CS +set myNewFile [\fBopen\fR filename.txt {WRONLY CREAT EXCL}] +.CE +.PP +Open a file for writing as a log file. +.PP +.CS +set myLogFile [\fBopen\fR filename.log "a"] +fconfigure $myLogFile -buffering line +.CE +.PP Open a command pipeline and catch any errors: +.PP .CS set fl [\fBopen\fR "| ls this_file_does_not_exist"] set data [read $fl] @@ -385,6 +406,18 @@ if {[catch {close $fl} err]} { puts "ls command failed: $err" } .CE +.PP +Open a command pipeline and read binary data from it. Note the unusual form +with +.QW |[list +that handles non-trivial edge cases with arguments that potentially have +spaces in. +.PP +.CS +set fl [\fBopen\fR |[list create_image_data $input] "rb"] +set binData [read $fl] +close $fl +.CE .SH "SEE ALSO" file(n), close(n), filename(n), fconfigure(n), gets(n), read(n), puts(n), exec(n), pid(n), fopen(3) -- cgit v0.12 From 9406745440cf6387d6aaa25d4b595fba069cf5d0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 31 Mar 2021 10:09:32 +0000 Subject: Add 3 undocumented #defines. To be formalized by TIP #595 (currently being voted on) --- generic/tcl.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/generic/tcl.h b/generic/tcl.h index 38dda28..f61981e 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -717,6 +717,11 @@ typedef void (Tcl_ServiceModeHookProc) (int mode); typedef ClientData (Tcl_InitNotifierProc) (void); typedef void (Tcl_FinalizeNotifierProc) (ClientData clientData); typedef void (Tcl_MainLoopProc) (void); + +/* Undocumented. To be formalized by TIP #595 */ +#define Tcl_LibraryInitProc Tcl_PackageInitProc +#define Tcl_LibraryUnloadProc Tcl_PackageUnloadProc +#define Tcl_StaticLibrary Tcl_StaticPackage /* *---------------------------------------------------------------------------- -- cgit v0.12 From 5ca6887e668192a78c3970398c98a574210c6296 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 31 Mar 2021 10:45:40 +0000 Subject: Don't define Tcl_CreateFileHandler or Tcl_DeleteFileHandler on Windows. --- generic/tclNotify.c | 142 ++++++++++++++++++++++++++++------------------------ 1 file changed, 76 insertions(+), 66 deletions(-) diff --git a/generic/tclNotify.c b/generic/tclNotify.c index fbf8360..9b5234b 100644 --- a/generic/tclNotify.c +++ b/generic/tclNotify.c @@ -1224,72 +1224,6 @@ Tcl_FinalizeNotifier( /* *---------------------------------------------------------------------- * - * Tcl_CreateFileHandler -- - * - * This function registers a file descriptor handler with the notifier. - * Forwards to the platform implementation when the hook is not enabled. - * - * Results: - * None. - * - * Side effects: - * Creates a new file handler structure. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_CreateFileHandler( - int fd, /* Handle of stream to watch. */ - int mask, /* OR'ed combination of TCL_READABLE, - * TCL_WRITABLE, and TCL_EXCEPTION: indicates - * conditions under which proc should be - * called. */ - Tcl_FileProc *proc, /* Function to call for each selected - * event. */ - ClientData clientData) /* Arbitrary data to pass to proc. */ -{ - if (tclNotifierHooks.createFileHandlerProc) { - tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData); - } else { - TclpCreateFileHandler(fd, mask, proc, clientData); - } -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_DeleteFileHandler -- - * - * Cancel a previously-arranged callback arrangement for a file - * descriptor. Forwards to the platform implementation when the hook is - * not enabled. - * - * Results: - * None. - * - * Side effects: - * If a callback was previously registered on the file descriptor, remove - * it. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_DeleteFileHandler( - int fd) /* Stream id for which to remove callback - * function. */ -{ - if (tclNotifierHooks.deleteFileHandlerProc) { - tclNotifierHooks.deleteFileHandlerProc(fd); - } else { - TclpDeleteFileHandler(fd); - } -} - -/* - *---------------------------------------------------------------------- - * * Tcl_AlertNotifier -- * * Wake up the specified notifier from any thread. This routine is called @@ -1409,6 +1343,82 @@ Tcl_WaitForEvent( } /* + *---------------------------------------------------------------------- + * + * Tcl_CreateFileHandler -- + * + * This function registers a file descriptor handler with the notifier. + * Forwards to the platform implementation when the hook is not enabled. + * + * This function is not defined on Windows. The OS API there is too + * different. + * + * Results: + * None. + * + * Side effects: + * Creates a new file handler structure. + * + *---------------------------------------------------------------------- + */ + +#ifndef _WIN32 +void +Tcl_CreateFileHandler( + int fd, /* Handle of stream to watch. */ + int mask, /* OR'ed combination of TCL_READABLE, + * TCL_WRITABLE, and TCL_EXCEPTION: indicates + * conditions under which proc should be + * called. */ + Tcl_FileProc *proc, /* Function to call for each selected + * event. */ + ClientData clientData) /* Arbitrary data to pass to proc. */ +{ + if (tclNotifierHooks.createFileHandlerProc) { + tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData); + } else { + TclpCreateFileHandler(fd, mask, proc, clientData); + } +} +#endif /* !_WIN32 */ + +/* + *---------------------------------------------------------------------- + * + * Tcl_DeleteFileHandler -- + * + * Cancel a previously-arranged callback arrangement for a file + * descriptor. Forwards to the platform implementation when the hook is + * not enabled. + * + * This function is not defined on Windows. The OS API there is too + * different. + * + * Results: + * None. + * + * Side effects: + * If a callback was previously registered on the file descriptor, remove + * it. + * + *---------------------------------------------------------------------- + */ + +#ifndef _WIN32 +void +Tcl_DeleteFileHandler( + int fd) /* Stream id for which to remove callback + * function. */ +{ + if (tclNotifierHooks.deleteFileHandlerProc) { + tclNotifierHooks.deleteFileHandlerProc(fd); + } else { + TclpDeleteFileHandler(fd); + } +} +#endif /* !_WIN32 */ + +/* * Local Variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 From 55bb44b8bec17ea6e369820e70c97d8939e1ff70 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 1 Apr 2021 08:18:38 +0000 Subject: Forgot a place to #ifndef out --- generic/tclNotify.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/generic/tclNotify.c b/generic/tclNotify.c index 9b5234b..12b40b1 100644 --- a/generic/tclNotify.c +++ b/generic/tclNotify.c @@ -235,12 +235,6 @@ Tcl_SetNotifier( * loop. */ - if (tclNotifierHooks.createFileHandlerProc == Tcl_CreateFileHandler) { - tclNotifierHooks.createFileHandlerProc = NULL; - } - if (tclNotifierHooks.deleteFileHandlerProc == Tcl_DeleteFileHandler) { - tclNotifierHooks.deleteFileHandlerProc = NULL; - } if (tclNotifierHooks.setTimerProc == Tcl_SetTimer) { tclNotifierHooks.setTimerProc = NULL; } @@ -259,6 +253,14 @@ Tcl_SetNotifier( if (tclNotifierHooks.serviceModeHookProc == Tcl_ServiceModeHook) { tclNotifierHooks.serviceModeHookProc = NULL; } +#ifndef _WIN32 + if (tclNotifierHooks.createFileHandlerProc == Tcl_CreateFileHandler) { + tclNotifierHooks.createFileHandlerProc = NULL; + } + if (tclNotifierHooks.deleteFileHandlerProc == Tcl_DeleteFileHandler) { + tclNotifierHooks.deleteFileHandlerProc = NULL; + } +#endif /* !_WIN32 */ } /* -- cgit v0.12 From e5991250e0ed04102d22556452ad154fac8bf7d6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 1 Apr 2021 09:47:33 +0000 Subject: Follow-up to [15c7b4f93e]: "Implement TCL_ENCODING_STOPONERROR flag for UtfToUtf encoder/decoder". Only do this check when pureNullMode == 0, otherwise we violate EIAS. --- generic/tclEncoding.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 1536f98..686eeb5 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2322,7 +2322,7 @@ UtfToUtfProc( result = TCL_CONVERT_NOSPACE; break; } - if (UCHAR(*src) < 0x80 && !(UCHAR(*src) == 0 && pureNullMode == 0)) { + if (UCHAR(*src) < 0x80 && !((UCHAR(*src) == 0) && (pureNullMode == 0))) { /* * Copy 7bit characters, but skip null-bytes when we are in input * mode, so that they get converted to 0xC080. @@ -2330,8 +2330,8 @@ UtfToUtfProc( *dst++ = *src++; *chPtr = 0; /* reset surrogate handling */ - } else if (pureNullMode == 1 && UCHAR(*src) == 0xC0 && - (src + 1 < srcEnd) && UCHAR(*(src+1)) == 0x80) { + } else if ((UCHAR(*src) == 0xC0) && (src + 1 < srcEnd) + && (UCHAR(src[1]) == 0x80) && (pureNullMode == 1)) { /* * Convert 0xC080 to real nulls when we are in output mode. */ @@ -2347,7 +2347,7 @@ UtfToUtfProc( * unless the user has explicitly asked to be told. */ - if (flags & TCL_ENCODING_STOPONERROR) { + if ((flags & TCL_ENCODING_STOPONERROR) && (pureNullMode == 0)) { result = TCL_CONVERT_MULTIBYTE; break; } @@ -2356,8 +2356,8 @@ UtfToUtfProc( dst += Tcl_UniCharToUtf(*chPtr, dst); } else { size_t len = TclUtfToUniChar(src, chPtr); - if ((len < 2) && (flags & TCL_ENCODING_STOPONERROR) && (*chPtr != 0) - && ((*chPtr & ~0x7FF) != 0xD800)) { + if ((len < 2) && (*chPtr != 0) && (flags & TCL_ENCODING_STOPONERROR) + && ((*chPtr & ~0x7FF) != 0xD800) && (pureNullMode == 0)) { result = TCL_CONVERT_SYNTAX; break; } -- cgit v0.12 From 3628bed3baaae83cb1812e0e2250514376dd8d07 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 2 Apr 2021 18:41:36 +0000 Subject: Don't do double definition; code was moved to tclInt.h previously. --- win/tclWinTime.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/win/tclWinTime.c b/win/tclWinTime.c index e05455f..a137df4 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -1556,33 +1556,6 @@ Tcl_QueryTimeProc( } /* - *---------------------------------------------------------------------- - * - * TclScaleTime -- - * - * TIP #233 (Virtualized Time): Wrapper around the time virutalisation - * rescale function. - * - * Results: - * None - * - * Side effects: - * Updates the time structure (given as an argument) with what the time - * should be after virtualisation. - * - *---------------------------------------------------------------------- - */ - -void -TclScaleTime( - Tcl_Time *timePtr) -{ - if (timePtr != NULL && tclScaleTimeProcPtr != NULL) { - tclScaleTimeProcPtr(timePtr, tclTimeClientData); - } -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 From 171ff16f7d1431ba085c9bb1dd90d64210ffb30c Mon Sep 17 00:00:00 2001 From: pooryorick Date: Fri, 2 Apr 2021 21:20:46 +0000 Subject: New test for OO cleanup: routine for object gets deleted before namespace deletion is complete. --- tests/oo.test | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/oo.test b/tests/oo.test index 168baee..404c6a4 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1734,6 +1734,7 @@ test oo-11.6.3 { } -result 0 -cleanup { } + test oo-11.6.4 { OO: cleanup ReleaseClassContents() where class is mixed into one of its instances @@ -1754,6 +1755,37 @@ test oo-11.6.4 { rename obj1 {} } + +test oo-11.7 { + When an object is deleted its namespace is deleted, and all objects it is + mixed into are also deleted. If the object has been renamed into the + namespace of one of the objects it has been mixed into, the routine for the + object might get entirely deleted before the namespace of the object is + entirely deleted, in which case the C routine the performs the namespace + either must either understand that the handle on the routine for the object + might now be gone, or it must be guaranteed that the handle does not + disappear until that routine is finished. +} -setup { +} -body { + oo::define oo::class { + export createWithNamespace + } + oo::class create class1 + + oo::object create obj1 + oo::objdefine obj1 { + mixin ::class1 + } + set obj1ns [info object namespace obj1] + set class1ns [info object namespace class1] + rename class1 ${obj1ns}::class1 + # No segmentation fault + namespace delete $class1ns +} -cleanup { + rename obj {} +} -result done + + test oo-12.1 {OO: filters} { oo::class create Aclass Aclass create Aobject @@ -1777,6 +1809,8 @@ test oo-12.1 {OO: filters} { Aclass destroy return $result } {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 12345} + + test oo-12.2 {OO: filters} -setup { oo::class create Aclass Aclass create Aobject @@ -4376,12 +4410,13 @@ test oo-35.6 { } -body { rename obj2 {} rename obj1 {} - # doesn't crash + # No segmentation fault return done } -cleanup { rename obj {} } -result done + test oo-36.1 {TIP #470: introspection within oo::define} { oo::define oo::object self } ::oo::object -- cgit v0.12 From 7d6ca39c8fc1416903f2fe01216ed2d7b435feb3 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Fri, 2 Apr 2021 23:02:00 +0000 Subject: OO cleanup fix that passes test 11.7. --- generic/tclOO.c | 23 ++++++++++++----------- tests/oo.test | 13 +++++-------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 4dbe668..559cf0b 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -1184,18 +1184,19 @@ ObjectNamespaceDeleted( * freed memory. */ - if (((Command *) oPtr->command)->flags && CMD_DYING) { - /* - * Something has already started the command deletion process. We can - * go ahead and clean up the the namespace, - */ - } else { - /* - * The namespace must have been deleted directly. Delete the command - * as well. - */ + if (oPtr->command != NULL) { + if (((Command *) oPtr->command)->flags && CMD_DYING) { + /* + * The command is already (being) deleted. Proceed to clean up the the namespace, + */ + } else { + /* + * The namespace must have been deleted directly. Delete the command + * as well. + */ - Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command); + Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command); + } } if (oPtr->myclassCommand) { diff --git a/tests/oo.test b/tests/oo.test index 404c6a4..7980f9e 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1761,15 +1761,12 @@ test oo-11.7 { mixed into are also deleted. If the object has been renamed into the namespace of one of the objects it has been mixed into, the routine for the object might get entirely deleted before the namespace of the object is - entirely deleted, in which case the C routine the performs the namespace - either must either understand that the handle on the routine for the object - might now be gone, or it must be guaranteed that the handle does not - disappear until that routine is finished. + entirely deleted, in which case the C routine that performs the namespace + deletion either must either understand that the handle on the routine for + the object might now be gone, or it must be guaranteed that the handle does + not disappear until that routine is finished. } -setup { } -body { - oo::define oo::class { - export createWithNamespace - } oo::class create class1 oo::object create obj1 @@ -1781,8 +1778,8 @@ test oo-11.7 { rename class1 ${obj1ns}::class1 # No segmentation fault namespace delete $class1ns + return done } -cleanup { - rename obj {} } -result done -- cgit v0.12 From c98ea4af2fac0552f8453c1787028523e1d19117 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Fri, 2 Apr 2021 23:21:50 +0000 Subject: Use TclCleanupCommandMacro instead of just decrementing the reference count. --- generic/tclBasic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index b90e12d..ce8c4ed 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -3662,7 +3662,7 @@ CallCommandTraces( */ cmdPtr->flags &= ~CMD_TRACE_ACTIVE; - cmdPtr->refCount--; + TclCleanupCommandMacro(cmdPtr); iPtr->activeCmdTracePtr = active.nextPtr; Tcl_Release(iPtr); return result; -- cgit v0.12 From aef7e169a724687ab05b72273b5a7fbc2fba22cc Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 3 Apr 2021 10:43:53 +0000 Subject: Remove suspected inadvertent copypasta from test. --- tests/namespace.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/namespace.test b/tests/namespace.test index 3394824..679b468 100644 --- a/tests/namespace.test +++ b/tests/namespace.test @@ -3301,8 +3301,8 @@ test namespace-56.2 {bug f97d4ee020: mutually-entangled deletion} { namespace eval ::testing { namespace eval abc {proc xyz {} {}} namespace eval def {proc xyz {} {}} - trace add command abc::xyz delete "namespace delete ::testing::def {}; #" - trace add command def::xyz delete "namespace delete ::testing::abc {}; #" + trace add command abc::xyz delete "namespace delete ::testing::def; #" + trace add command def::xyz delete "namespace delete ::testing::abc; #" } namespace delete ::testing } {} -- cgit v0.12 From 02855d5980f78e6e42b3a35274a26c978f9af694 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 3 Apr 2021 12:04:21 +0000 Subject: When a namesapce is deleted delete all namespaces under it before making any modifictions to it. --- generic/tclInt.h | 1 + generic/tclNamesp.c | 142 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 84 insertions(+), 59 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 2448b5a..3ac46bb 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2890,6 +2890,7 @@ MODULE_SCOPE Tcl_Command TclCreateEnsembleInNs(Tcl_Interp *interp, const char *name, Tcl_Namespace *nameNamespacePtr, Tcl_Namespace *ensembleNamespacePtr, int flags); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); +MODULE_SCOPE void TclDeleteNamespaceChildren(Namespace *nsPt); MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, const char *dict, int dictLength, const char **elementPtr, const char **nextPtr, diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index b2d717b..607072b 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -917,10 +917,10 @@ Tcl_DeleteNamespace( /* * Give anyone interested - notably TclOO - a chance to use this namespace * normally despite the fact that the namespace is going to go. Allows the - * calling of destructors. Will only be called once (unless re-established + * calling of destructors. Only called once (unless re-established * by the called function). [Bug 2950259] * - * Note that setting this field requires access to the internal definition + * Setting this field requires access to the internal definition * of namespaces, so it should only be accessed by code that knows about * being careful with reentrancy. */ @@ -1065,7 +1065,7 @@ Tcl_DeleteNamespace( } TclNsDecrRefCount(nsPtr); } - + int TclNamespaceDeleted( Namespace *nsPtr) @@ -1073,6 +1073,83 @@ TclNamespaceDeleted( return (nsPtr->flags & NS_DYING) ? 1 : 0; } +void +TclDeleteNamespaceChildren( + Namespace *nsPtr /* Namespace whose children to delete */ +) +{ + Interp *iPtr = (Interp *) nsPtr->interp; + Tcl_HashEntry *entryPtr; + int i, unchecked; + Tcl_HashSearch search; + /* + * Delete all the child namespaces. + * + * BE CAREFUL: When each child is deleted, it divorces itself from its + * parent. The hash table can't be proplery traversed if its elements are + * being deleted. Because of traces (and the desire to avoid the + * quadratic problems of just using Tcl_FirstHashEntry over and over, [Bug + * f97d4ee020]) copy to a temporary array and then delete all those + * namespaces. + * + * Important: leave the hash table itself still live. + */ + +#ifndef BREAK_NAMESPACE_COMPAT + unchecked = (nsPtr->childTable.numEntries > 0); + while (nsPtr->childTable.numEntries > 0 && unchecked) { + int length = nsPtr->childTable.numEntries; + Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, + sizeof(Namespace *) * length); + + i = 0; + for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search); + entryPtr != NULL; + entryPtr = Tcl_NextHashEntry(&search)) { + children[i] = (Namespace *)Tcl_GetHashValue(entryPtr); + children[i]->refCount++; + i++; + } + unchecked = 0; + for (i = 0 ; i < length ; i++) { + if (!(children[i]->flags & NS_DYING)) { + unchecked = 1; + Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); + TclNsDecrRefCount(children[i]); + } + } + TclStackFree((Tcl_Interp *) iPtr, children); + } +#else + if (nsPtr->childTablePtr != NULL) { + unchecked = (nsPtr->childTable.numEntries > 0); + while (nsPtr->childTable.numEntries > 0 && unchecked) { + int length = nsPtr->childTablePtr->numEntries; + Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, + sizeof(Namespace *) * length); + + i = 0; + for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search); + entryPtr != NULL; + entryPtr = Tcl_NextHashEntry(&search)) { + children[i] = (Namespace *)Tcl_GetHashValue(entryPtr); + children[i]->refCount++; + i++; + } + unchecked = 0; + for (i = 0 ; i < length ; i++) { + if (!(children[i]->flags & NS_DYING)) { + unchecked = 1; + Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); + TclNsDecrRefCount(children[i]); + } + } + TclStackFree((Tcl_Interp *) iPtr, children); + } + } +#endif +} + /* *---------------------------------------------------------------------- * @@ -1105,6 +1182,9 @@ TclTeardownNamespace( Tcl_HashSearch search; size_t i; + + TclDeleteNamespaceChildren(nsPtr); + /* * Start by destroying the namespace's variable table, since variables * might trigger traces. Variable table should be cleared but not freed! @@ -1181,62 +1261,6 @@ TclTeardownNamespace( nsPtr->commandPathSourceList = NULL; } - /* - * Delete all the child namespaces. - * - * BE CAREFUL: When each child is deleted, it will divorce itself from its - * parent. You can't traverse a hash table properly if its elements are - * being deleted. Because of traces (and the desire to avoid the - * quadratic problems of just using Tcl_FirstHashEntry over and over, [Bug - * f97d4ee020]) we copy to a temporary array and then delete all those - * namespaces. - * - * Important: leave the hash table itself still live. - */ - -#ifndef BREAK_NAMESPACE_COMPAT - while (nsPtr->childTable.numEntries > 0) { - size_t length = nsPtr->childTable.numEntries; - Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, - sizeof(Namespace *) * length); - - i = 0; - for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search); - entryPtr != NULL; - entryPtr = Tcl_NextHashEntry(&search)) { - children[i] = (Namespace *)Tcl_GetHashValue(entryPtr); - children[i]->refCount++; - i++; - } - for (i = 0 ; i < length ; i++) { - Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); - TclNsDecrRefCount(children[i]); - } - TclStackFree((Tcl_Interp *) iPtr, children); - } -#else - if (nsPtr->childTablePtr != NULL) { - while (nsPtr->childTablePtr->numEntries > 0) { - size_t length = nsPtr->childTablePtr->numEntries; - Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, - sizeof(Namespace *) * length); - - i = 0; - for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search); - entryPtr != NULL; - entryPtr = Tcl_NextHashEntry(&search)) { - children[i] = Tcl_GetHashValue(entryPtr); - children[i]->refCount++; - i++; - } - for (i = 0 ; i < length ; i++) { - Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); - TclNsDecrRefCount(children[i]); - } - TclStackFree((Tcl_Interp *) iPtr, children); - } - } -#endif /* * Free the namespace's export pattern array. -- cgit v0.12 From 1c4c352fe9104950891533992dfbc449e75350aa Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 3 Apr 2021 12:17:40 +0000 Subject: New test for OO cleanup: routine for object gets deleted before namespace deletion is complete. --- tests/oo.test | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/oo.test b/tests/oo.test index 168baee..404c6a4 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1734,6 +1734,7 @@ test oo-11.6.3 { } -result 0 -cleanup { } + test oo-11.6.4 { OO: cleanup ReleaseClassContents() where class is mixed into one of its instances @@ -1754,6 +1755,37 @@ test oo-11.6.4 { rename obj1 {} } + +test oo-11.7 { + When an object is deleted its namespace is deleted, and all objects it is + mixed into are also deleted. If the object has been renamed into the + namespace of one of the objects it has been mixed into, the routine for the + object might get entirely deleted before the namespace of the object is + entirely deleted, in which case the C routine the performs the namespace + either must either understand that the handle on the routine for the object + might now be gone, or it must be guaranteed that the handle does not + disappear until that routine is finished. +} -setup { +} -body { + oo::define oo::class { + export createWithNamespace + } + oo::class create class1 + + oo::object create obj1 + oo::objdefine obj1 { + mixin ::class1 + } + set obj1ns [info object namespace obj1] + set class1ns [info object namespace class1] + rename class1 ${obj1ns}::class1 + # No segmentation fault + namespace delete $class1ns +} -cleanup { + rename obj {} +} -result done + + test oo-12.1 {OO: filters} { oo::class create Aclass Aclass create Aobject @@ -1777,6 +1809,8 @@ test oo-12.1 {OO: filters} { Aclass destroy return $result } {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 12345} + + test oo-12.2 {OO: filters} -setup { oo::class create Aclass Aclass create Aobject @@ -4376,12 +4410,13 @@ test oo-35.6 { } -body { rename obj2 {} rename obj1 {} - # doesn't crash + # No segmentation fault return done } -cleanup { rename obj {} } -result done + test oo-36.1 {TIP #470: introspection within oo::define} { oo::define oo::object self } ::oo::object -- cgit v0.12 From 756e0c234a6a4f1f304b37db96f8b3980aba66fa Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 3 Apr 2021 12:33:00 +0000 Subject: OO cleanup fix that passes test 11.7. --- generic/tclOO.c | 23 ++++++++++++----------- tests/oo.test | 13 +++++-------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 405d5d0..452e2ef 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -1184,18 +1184,19 @@ ObjectNamespaceDeleted( * freed memory. */ - if (((Command *) oPtr->command)->flags && CMD_DYING) { - /* - * Something has already started the command deletion process. We can - * go ahead and clean up the the namespace, - */ - } else { - /* - * The namespace must have been deleted directly. Delete the command - * as well. - */ + if (oPtr->command != NULL) { + if (((Command *) oPtr->command)->flags && CMD_DYING) { + /* + * The command is already (being) deleted. Proceed to clean up the the namespace, + */ + } else { + /* + * The namespace must have been deleted directly. Delete the command + * as well. + */ - Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command); + Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command); + } } if (oPtr->myclassCommand) { diff --git a/tests/oo.test b/tests/oo.test index 404c6a4..7980f9e 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1761,15 +1761,12 @@ test oo-11.7 { mixed into are also deleted. If the object has been renamed into the namespace of one of the objects it has been mixed into, the routine for the object might get entirely deleted before the namespace of the object is - entirely deleted, in which case the C routine the performs the namespace - either must either understand that the handle on the routine for the object - might now be gone, or it must be guaranteed that the handle does not - disappear until that routine is finished. + entirely deleted, in which case the C routine that performs the namespace + deletion either must either understand that the handle on the routine for + the object might now be gone, or it must be guaranteed that the handle does + not disappear until that routine is finished. } -setup { } -body { - oo::define oo::class { - export createWithNamespace - } oo::class create class1 oo::object create obj1 @@ -1781,8 +1778,8 @@ test oo-11.7 { rename class1 ${obj1ns}::class1 # No segmentation fault namespace delete $class1ns + return done } -cleanup { - rename obj {} } -result done -- cgit v0.12 From c494f8045e89b1765e8faef75b2fc169b8e70e56 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 3 Apr 2021 12:33:58 +0000 Subject: Use TclCleanupCommandMacro instead of just decrementing the reference count. --- generic/tclBasic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 56356e2..e18d1b7 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -3740,7 +3740,7 @@ CallCommandTraces( */ cmdPtr->flags &= ~CMD_TRACE_ACTIVE; - cmdPtr->refCount--; + TclCleanupCommandMacro(cmdPtr); iPtr->activeCmdTracePtr = active.nextPtr; Tcl_Release(iPtr); return result; -- cgit v0.12 From 55f8e3ac01b129121e749e40480a67bca8aa0832 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 3 Apr 2021 12:36:10 +0000 Subject: Remove suspected inadvertent copypasta from test. --- tests/namespace.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/namespace.test b/tests/namespace.test index efd00a8..dc0e56d 100644 --- a/tests/namespace.test +++ b/tests/namespace.test @@ -3289,8 +3289,8 @@ test namespace-56.2 {bug f97d4ee020: mutually-entangled deletion} { namespace eval ::testing { namespace eval abc {proc xyz {} {}} namespace eval def {proc xyz {} {}} - trace add command abc::xyz delete "namespace delete ::testing::def {}; #" - trace add command def::xyz delete "namespace delete ::testing::abc {}; #" + trace add command abc::xyz delete "namespace delete ::testing::def; #" + trace add command def::xyz delete "namespace delete ::testing::abc; #" } namespace delete ::testing } {} -- cgit v0.12 From 970479b4ee7ed81756afb201bf22fb663e9fc99a Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 3 Apr 2021 12:48:54 +0000 Subject: When a namesapce is deleted delete all namespaces under it before making any modifictions to it. --- generic/tclInt.h | 1 + generic/tclNamesp.c | 142 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 84 insertions(+), 59 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index fa661d6..e86a0cc 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2958,6 +2958,7 @@ MODULE_SCOPE Tcl_Command TclCreateEnsembleInNs(Tcl_Interp *interp, const char *name, Tcl_Namespace *nameNamespacePtr, Tcl_Namespace *ensembleNamespacePtr, int flags); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); +MODULE_SCOPE void TclDeleteNamespaceChildren(Namespace *nsPt); MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, const char *dict, int dictLength, const char **elementPtr, const char **nextPtr, diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index f57b7e1..bf598d9 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -917,10 +917,10 @@ Tcl_DeleteNamespace( /* * Give anyone interested - notably TclOO - a chance to use this namespace * normally despite the fact that the namespace is going to go. Allows the - * calling of destructors. Will only be called once (unless re-established + * calling of destructors. Only called once (unless re-established * by the called function). [Bug 2950259] * - * Note that setting this field requires access to the internal definition + * Setting this field requires access to the internal definition * of namespaces, so it should only be accessed by code that knows about * being careful with reentrancy. */ @@ -1065,7 +1065,7 @@ Tcl_DeleteNamespace( } TclNsDecrRefCount(nsPtr); } - + int TclNamespaceDeleted( Namespace *nsPtr) @@ -1073,6 +1073,83 @@ TclNamespaceDeleted( return (nsPtr->flags & NS_DYING) ? 1 : 0; } +void +TclDeleteNamespaceChildren( + Namespace *nsPtr /* Namespace whose children to delete */ +) +{ + Interp *iPtr = (Interp *) nsPtr->interp; + Tcl_HashEntry *entryPtr; + int i, unchecked; + Tcl_HashSearch search; + /* + * Delete all the child namespaces. + * + * BE CAREFUL: When each child is deleted, it divorces itself from its + * parent. The hash table can't be proplery traversed if its elements are + * being deleted. Because of traces (and the desire to avoid the + * quadratic problems of just using Tcl_FirstHashEntry over and over, [Bug + * f97d4ee020]) copy to a temporary array and then delete all those + * namespaces. + * + * Important: leave the hash table itself still live. + */ + +#ifndef BREAK_NAMESPACE_COMPAT + unchecked = (nsPtr->childTable.numEntries > 0); + while (nsPtr->childTable.numEntries > 0 && unchecked) { + int length = nsPtr->childTable.numEntries; + Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, + sizeof(Namespace *) * length); + + i = 0; + for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search); + entryPtr != NULL; + entryPtr = Tcl_NextHashEntry(&search)) { + children[i] = (Namespace *)Tcl_GetHashValue(entryPtr); + children[i]->refCount++; + i++; + } + unchecked = 0; + for (i = 0 ; i < length ; i++) { + if (!(children[i]->flags & NS_DYING)) { + unchecked = 1; + Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); + TclNsDecrRefCount(children[i]); + } + } + TclStackFree((Tcl_Interp *) iPtr, children); + } +#else + if (nsPtr->childTablePtr != NULL) { + unchecked = (nsPtr->childTable.numEntries > 0); + while (nsPtr->childTable.numEntries > 0 && unchecked) { + int length = nsPtr->childTablePtr->numEntries; + Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, + sizeof(Namespace *) * length); + + i = 0; + for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search); + entryPtr != NULL; + entryPtr = Tcl_NextHashEntry(&search)) { + children[i] = (Namespace *)Tcl_GetHashValue(entryPtr); + children[i]->refCount++; + i++; + } + unchecked = 0; + for (i = 0 ; i < length ; i++) { + if (!(children[i]->flags & NS_DYING)) { + unchecked = 1; + Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); + TclNsDecrRefCount(children[i]); + } + } + TclStackFree((Tcl_Interp *) iPtr, children); + } + } +#endif +} + /* *---------------------------------------------------------------------- * @@ -1105,6 +1182,9 @@ TclTeardownNamespace( Tcl_HashSearch search; int i; + + TclDeleteNamespaceChildren(nsPtr); + /* * Start by destroying the namespace's variable table, since variables * might trigger traces. Variable table should be cleared but not freed! @@ -1181,62 +1261,6 @@ TclTeardownNamespace( nsPtr->commandPathSourceList = NULL; } - /* - * Delete all the child namespaces. - * - * BE CAREFUL: When each child is deleted, it will divorce itself from its - * parent. You can't traverse a hash table properly if its elements are - * being deleted. Because of traces (and the desire to avoid the - * quadratic problems of just using Tcl_FirstHashEntry over and over, [Bug - * f97d4ee020]) we copy to a temporary array and then delete all those - * namespaces. - * - * Important: leave the hash table itself still live. - */ - -#ifndef BREAK_NAMESPACE_COMPAT - while (nsPtr->childTable.numEntries > 0) { - int length = nsPtr->childTable.numEntries; - Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, - sizeof(Namespace *) * length); - - i = 0; - for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search); - entryPtr != NULL; - entryPtr = Tcl_NextHashEntry(&search)) { - children[i] = (Namespace *)Tcl_GetHashValue(entryPtr); - children[i]->refCount++; - i++; - } - for (i = 0 ; i < length ; i++) { - Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); - TclNsDecrRefCount(children[i]); - } - TclStackFree((Tcl_Interp *) iPtr, children); - } -#else - if (nsPtr->childTablePtr != NULL) { - while (nsPtr->childTablePtr->numEntries > 0) { - int length = nsPtr->childTablePtr->numEntries; - Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, - sizeof(Namespace *) * length); - - i = 0; - for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search); - entryPtr != NULL; - entryPtr = Tcl_NextHashEntry(&search)) { - children[i] = Tcl_GetHashValue(entryPtr); - children[i]->refCount++; - i++; - } - for (i = 0 ; i < length ; i++) { - Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); - TclNsDecrRefCount(children[i]); - } - TclStackFree((Tcl_Interp *) iPtr, children); - } - } -#endif /* * Free the namespace's export pattern array. -- cgit v0.12 From 42c960506de8d8e50f567cd5a0729bb61175fcd7 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 3 Apr 2021 13:20:14 +0000 Subject: Changes to code comments. --- generic/tclNamesp.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index bf598d9..3ec0fb5 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -915,10 +915,11 @@ Tcl_DeleteNamespace( nsPtr->refCount++; /* - * Give anyone interested - notably TclOO - a chance to use this namespace - * normally despite the fact that the namespace is going to go. Allows the - * calling of destructors. Only called once (unless re-established - * by the called function). [Bug 2950259] + * Before marking the namespace as dying, give anyone interested, notably + * TclOO, a chance to use this namespace normally despite the fact that + * the namespace is going to go. Allows the calling of destructors. Only + * called once (unless re-established by the called function). [Bug + * 2950259] * * Setting this field requires access to the internal definition * of namespaces, so it should only be accessed by code that knows about @@ -935,12 +936,12 @@ Tcl_DeleteNamespace( } /* - * Delete all coroutine commands now: break the circular ref cycle between + * Delete all coroutines now, breaking the circular ref cycle between * the namespace and the coroutine command [Bug 2724403]. This code is * essentially duplicated in TclTeardownNamespace() for all other * commands. Don't optimize to Tcl_NextHashEntry() because of traces. * - * NOTE: we could avoid traversing the ns's command list by keeping a + * Maybe later avoid traversing the ns's command list by keeping a * separate list of coros. */ @@ -959,7 +960,7 @@ Tcl_DeleteNamespace( /* * If the namespace has associated ensemble commands, delete them first. * This leaves the actual contents of the namespace alone (unless they are - * linked ensemble commands, of course). Note that this code is actually + * linked ensemble commands, of course). This code is actually * reentrant so command delete traces won't purturb things badly. */ @@ -990,7 +991,7 @@ Tcl_DeleteNamespace( * (NS_DYING is OR'd into its flags): the namespace can't be looked up by * name but its commands and variables are still usable by those active * call frames. When all active call frames referring to the namespace - * have been popped from the Tcl stack, Tcl_PopCallFrame will call this + * have been popped from the Tcl stack, Tcl_PopCallFrame calls this * function again to delete everything in the namespace. If no nsName * objects refer to the namespace (i.e., if its refCount is zero), its * commands and variables are deleted and the storage for its namespace -- cgit v0.12 From 7f4cc308f37a5729cb679b8c859e8dba993095ca Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 3 Apr 2021 17:58:03 +0000 Subject: Update code comments. --- generic/tclNamesp.c | 57 ++++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index 3ec0fb5..1d20a77 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -884,22 +884,20 @@ Tcl_CreateNamespace( * Tcl_DeleteNamespace -- * * Deletes a namespace and all of the commands, variables, and other - * namespaces within it. + * namespaces within it, and disassociates the namespace from its parent. * * Results: * None. * * Side effects: - * When a namespace is deleted, it is automatically removed as a child of - * its parent namespace. Also, all its commands, variables and child - * namespaces are deleted. + * See description. * *---------------------------------------------------------------------- */ void Tcl_DeleteNamespace( - Tcl_Namespace *namespacePtr)/* Points to the namespace to delete. */ + Tcl_Namespace *namespacePtr) /* Points to the namespace to delete. */ { Namespace *nsPtr = (Namespace *) namespacePtr; Interp *iPtr = (Interp *) nsPtr->interp; @@ -917,7 +915,7 @@ Tcl_DeleteNamespace( /* * Before marking the namespace as dying, give anyone interested, notably * TclOO, a chance to use this namespace normally despite the fact that - * the namespace is going to go. Allows the calling of destructors. Only + * the namespace is going to go. Allows the calling of destructors. Only * called once (unless re-established by the called function). [Bug * 2950259] * @@ -936,13 +934,13 @@ Tcl_DeleteNamespace( } /* - * Delete all coroutines now, breaking the circular ref cycle between - * the namespace and the coroutine command [Bug 2724403]. This code is + * Delete all coroutines now to break the circular ref cycle between + * the namespace and any coroutines [Bug 2724403]. This code is * essentially duplicated in TclTeardownNamespace() for all other * commands. Don't optimize to Tcl_NextHashEntry() because of traces. * - * Maybe later avoid traversing the ns's command list by keeping a - * separate list of coros. + * Maybe later avoid traversing the command table by keeping a + * separate list of coroutines. */ for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); @@ -987,20 +985,14 @@ Tcl_DeleteNamespace( } /* - * If the namespace is on the call frame stack, it is marked as "dying" - * (NS_DYING is OR'd into its flags): the namespace can't be looked up by - * name but its commands and variables are still usable by those active - * call frames. When all active call frames referring to the namespace - * have been popped from the Tcl stack, Tcl_PopCallFrame calls this - * function again to delete everything in the namespace. If no nsName - * objects refer to the namespace (i.e., if its refCount is zero), its - * commands and variables are deleted and the storage for its namespace - * structure is freed. Otherwise, if its refCount is nonzero, the - * namespace's commands and variables are deleted but the structure isn't - * freed. Instead, NS_DEAD is OR'd into the structure's flags to allow the - * namespace resolution code to recognize that the namespace is "deleted". - * The structure's storage is freed by FreeNsNameInternalRep when its - * refCount reaches 0. + * If the namespace is on the call frame stack, add the flag NS_DYING, + * after the namesapce can not be reached by name, but its commands and + * variables are still usable from in those active call frames. When all + * active call frames referring to the namespace have been popped from the + * Tcl stack, Tcl_PopCallFrame calls this function again to delete + * everything in the namespace. Its commands and variables are deleted. + * When the structure's refCount reaches 0 FreeNsNameInternalRep frees the + * storage for the structure. */ if (nsPtr->activationCount - (nsPtr == globalNsPtr) > 0) { @@ -1016,11 +1008,10 @@ Tcl_DeleteNamespace( nsPtr->parentPtr = NULL; } else if (!(nsPtr->flags & NS_KILLED)) { /* - * Delete the namespace and everything in it. If this is the global - * namespace, then clear it but don't free its storage unless the - * interpreter is being torn down. Set the NS_KILLED flag to avoid - * recursive calls here - if the namespace is really in the process of - * being deleted, ignore any second call. + * Time to actually delete the namespace and everything in it. If this + * is the global namespace, clear it but don't free its storage unless + * the interpreter is being deleted. Set the NS_KILLED flag to prevent + * additional entry to this section. */ nsPtr->flags |= (NS_DYING|NS_KILLED); @@ -1031,8 +1022,8 @@ Tcl_DeleteNamespace( /* * If this is the global namespace, then it may have residual * "errorInfo" and "errorCode" variables for errors that occurred - * while it was being torn down. Try to clear the variable list - * one last time. + * while it was being torn down. Try one last time to clear the + * variable list. */ TclDeleteNamespaceVars(nsPtr); @@ -1057,8 +1048,8 @@ Tcl_DeleteNamespace( EstablishErrorCodeTraces(NULL, nsPtr->interp, NULL, NULL, 0); /* - * We didn't really kill it, so remove the KILLED marks, so it can - * get killed later, avoiding mem leaks. + * The namespace is not deleted yet. Remove the KILLED marks, so it + * can be deleted later, avoiding mem leaks. */ nsPtr->flags &= ~(NS_DYING|NS_KILLED); -- cgit v0.12 From 226bb13f4e093299c9d975ebd16c6cacb4af6356 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 4 Apr 2021 14:31:43 +0000 Subject: Fix [https://github.com/tcltk/tcl/runs/2263266926|failing test-cases] with --enable-symbols=mem build by reverting the series of commits that caused the memory-leak --- generic/tclBasic.c | 2 +- generic/tclInt.h | 1 - generic/tclNamesp.c | 206 ++++++++++++++++++++++++--------------------------- generic/tclOO.c | 23 +++--- tests/namespace.test | 4 +- tests/oo.test | 34 +-------- 6 files changed, 110 insertions(+), 160 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index e18d1b7..56356e2 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -3740,7 +3740,7 @@ CallCommandTraces( */ cmdPtr->flags &= ~CMD_TRACE_ACTIVE; - TclCleanupCommandMacro(cmdPtr); + cmdPtr->refCount--; iPtr->activeCmdTracePtr = active.nextPtr; Tcl_Release(iPtr); return result; diff --git a/generic/tclInt.h b/generic/tclInt.h index e86a0cc..fa661d6 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2958,7 +2958,6 @@ MODULE_SCOPE Tcl_Command TclCreateEnsembleInNs(Tcl_Interp *interp, const char *name, Tcl_Namespace *nameNamespacePtr, Tcl_Namespace *ensembleNamespacePtr, int flags); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); -MODULE_SCOPE void TclDeleteNamespaceChildren(Namespace *nsPt); MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, const char *dict, int dictLength, const char **elementPtr, const char **nextPtr, diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index 1d20a77..f57b7e1 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -884,20 +884,22 @@ Tcl_CreateNamespace( * Tcl_DeleteNamespace -- * * Deletes a namespace and all of the commands, variables, and other - * namespaces within it, and disassociates the namespace from its parent. + * namespaces within it. * * Results: * None. * * Side effects: - * See description. + * When a namespace is deleted, it is automatically removed as a child of + * its parent namespace. Also, all its commands, variables and child + * namespaces are deleted. * *---------------------------------------------------------------------- */ void Tcl_DeleteNamespace( - Tcl_Namespace *namespacePtr) /* Points to the namespace to delete. */ + Tcl_Namespace *namespacePtr)/* Points to the namespace to delete. */ { Namespace *nsPtr = (Namespace *) namespacePtr; Interp *iPtr = (Interp *) nsPtr->interp; @@ -913,13 +915,12 @@ Tcl_DeleteNamespace( nsPtr->refCount++; /* - * Before marking the namespace as dying, give anyone interested, notably - * TclOO, a chance to use this namespace normally despite the fact that - * the namespace is going to go. Allows the calling of destructors. Only - * called once (unless re-established by the called function). [Bug - * 2950259] + * Give anyone interested - notably TclOO - a chance to use this namespace + * normally despite the fact that the namespace is going to go. Allows the + * calling of destructors. Will only be called once (unless re-established + * by the called function). [Bug 2950259] * - * Setting this field requires access to the internal definition + * Note that setting this field requires access to the internal definition * of namespaces, so it should only be accessed by code that knows about * being careful with reentrancy. */ @@ -934,13 +935,13 @@ Tcl_DeleteNamespace( } /* - * Delete all coroutines now to break the circular ref cycle between - * the namespace and any coroutines [Bug 2724403]. This code is + * Delete all coroutine commands now: break the circular ref cycle between + * the namespace and the coroutine command [Bug 2724403]. This code is * essentially duplicated in TclTeardownNamespace() for all other * commands. Don't optimize to Tcl_NextHashEntry() because of traces. * - * Maybe later avoid traversing the command table by keeping a - * separate list of coroutines. + * NOTE: we could avoid traversing the ns's command list by keeping a + * separate list of coros. */ for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); @@ -958,7 +959,7 @@ Tcl_DeleteNamespace( /* * If the namespace has associated ensemble commands, delete them first. * This leaves the actual contents of the namespace alone (unless they are - * linked ensemble commands, of course). This code is actually + * linked ensemble commands, of course). Note that this code is actually * reentrant so command delete traces won't purturb things badly. */ @@ -985,14 +986,20 @@ Tcl_DeleteNamespace( } /* - * If the namespace is on the call frame stack, add the flag NS_DYING, - * after the namesapce can not be reached by name, but its commands and - * variables are still usable from in those active call frames. When all - * active call frames referring to the namespace have been popped from the - * Tcl stack, Tcl_PopCallFrame calls this function again to delete - * everything in the namespace. Its commands and variables are deleted. - * When the structure's refCount reaches 0 FreeNsNameInternalRep frees the - * storage for the structure. + * If the namespace is on the call frame stack, it is marked as "dying" + * (NS_DYING is OR'd into its flags): the namespace can't be looked up by + * name but its commands and variables are still usable by those active + * call frames. When all active call frames referring to the namespace + * have been popped from the Tcl stack, Tcl_PopCallFrame will call this + * function again to delete everything in the namespace. If no nsName + * objects refer to the namespace (i.e., if its refCount is zero), its + * commands and variables are deleted and the storage for its namespace + * structure is freed. Otherwise, if its refCount is nonzero, the + * namespace's commands and variables are deleted but the structure isn't + * freed. Instead, NS_DEAD is OR'd into the structure's flags to allow the + * namespace resolution code to recognize that the namespace is "deleted". + * The structure's storage is freed by FreeNsNameInternalRep when its + * refCount reaches 0. */ if (nsPtr->activationCount - (nsPtr == globalNsPtr) > 0) { @@ -1008,10 +1015,11 @@ Tcl_DeleteNamespace( nsPtr->parentPtr = NULL; } else if (!(nsPtr->flags & NS_KILLED)) { /* - * Time to actually delete the namespace and everything in it. If this - * is the global namespace, clear it but don't free its storage unless - * the interpreter is being deleted. Set the NS_KILLED flag to prevent - * additional entry to this section. + * Delete the namespace and everything in it. If this is the global + * namespace, then clear it but don't free its storage unless the + * interpreter is being torn down. Set the NS_KILLED flag to avoid + * recursive calls here - if the namespace is really in the process of + * being deleted, ignore any second call. */ nsPtr->flags |= (NS_DYING|NS_KILLED); @@ -1022,8 +1030,8 @@ Tcl_DeleteNamespace( /* * If this is the global namespace, then it may have residual * "errorInfo" and "errorCode" variables for errors that occurred - * while it was being torn down. Try one last time to clear the - * variable list. + * while it was being torn down. Try to clear the variable list + * one last time. */ TclDeleteNamespaceVars(nsPtr); @@ -1048,8 +1056,8 @@ Tcl_DeleteNamespace( EstablishErrorCodeTraces(NULL, nsPtr->interp, NULL, NULL, 0); /* - * The namespace is not deleted yet. Remove the KILLED marks, so it - * can be deleted later, avoiding mem leaks. + * We didn't really kill it, so remove the KILLED marks, so it can + * get killed later, avoiding mem leaks. */ nsPtr->flags &= ~(NS_DYING|NS_KILLED); @@ -1057,7 +1065,7 @@ Tcl_DeleteNamespace( } TclNsDecrRefCount(nsPtr); } - + int TclNamespaceDeleted( Namespace *nsPtr) @@ -1065,83 +1073,6 @@ TclNamespaceDeleted( return (nsPtr->flags & NS_DYING) ? 1 : 0; } -void -TclDeleteNamespaceChildren( - Namespace *nsPtr /* Namespace whose children to delete */ -) -{ - Interp *iPtr = (Interp *) nsPtr->interp; - Tcl_HashEntry *entryPtr; - int i, unchecked; - Tcl_HashSearch search; - /* - * Delete all the child namespaces. - * - * BE CAREFUL: When each child is deleted, it divorces itself from its - * parent. The hash table can't be proplery traversed if its elements are - * being deleted. Because of traces (and the desire to avoid the - * quadratic problems of just using Tcl_FirstHashEntry over and over, [Bug - * f97d4ee020]) copy to a temporary array and then delete all those - * namespaces. - * - * Important: leave the hash table itself still live. - */ - -#ifndef BREAK_NAMESPACE_COMPAT - unchecked = (nsPtr->childTable.numEntries > 0); - while (nsPtr->childTable.numEntries > 0 && unchecked) { - int length = nsPtr->childTable.numEntries; - Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, - sizeof(Namespace *) * length); - - i = 0; - for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search); - entryPtr != NULL; - entryPtr = Tcl_NextHashEntry(&search)) { - children[i] = (Namespace *)Tcl_GetHashValue(entryPtr); - children[i]->refCount++; - i++; - } - unchecked = 0; - for (i = 0 ; i < length ; i++) { - if (!(children[i]->flags & NS_DYING)) { - unchecked = 1; - Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); - TclNsDecrRefCount(children[i]); - } - } - TclStackFree((Tcl_Interp *) iPtr, children); - } -#else - if (nsPtr->childTablePtr != NULL) { - unchecked = (nsPtr->childTable.numEntries > 0); - while (nsPtr->childTable.numEntries > 0 && unchecked) { - int length = nsPtr->childTablePtr->numEntries; - Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, - sizeof(Namespace *) * length); - - i = 0; - for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search); - entryPtr != NULL; - entryPtr = Tcl_NextHashEntry(&search)) { - children[i] = (Namespace *)Tcl_GetHashValue(entryPtr); - children[i]->refCount++; - i++; - } - unchecked = 0; - for (i = 0 ; i < length ; i++) { - if (!(children[i]->flags & NS_DYING)) { - unchecked = 1; - Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); - TclNsDecrRefCount(children[i]); - } - } - TclStackFree((Tcl_Interp *) iPtr, children); - } - } -#endif -} - /* *---------------------------------------------------------------------- * @@ -1174,9 +1105,6 @@ TclTeardownNamespace( Tcl_HashSearch search; int i; - - TclDeleteNamespaceChildren(nsPtr); - /* * Start by destroying the namespace's variable table, since variables * might trigger traces. Variable table should be cleared but not freed! @@ -1253,6 +1181,62 @@ TclTeardownNamespace( nsPtr->commandPathSourceList = NULL; } + /* + * Delete all the child namespaces. + * + * BE CAREFUL: When each child is deleted, it will divorce itself from its + * parent. You can't traverse a hash table properly if its elements are + * being deleted. Because of traces (and the desire to avoid the + * quadratic problems of just using Tcl_FirstHashEntry over and over, [Bug + * f97d4ee020]) we copy to a temporary array and then delete all those + * namespaces. + * + * Important: leave the hash table itself still live. + */ + +#ifndef BREAK_NAMESPACE_COMPAT + while (nsPtr->childTable.numEntries > 0) { + int length = nsPtr->childTable.numEntries; + Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, + sizeof(Namespace *) * length); + + i = 0; + for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search); + entryPtr != NULL; + entryPtr = Tcl_NextHashEntry(&search)) { + children[i] = (Namespace *)Tcl_GetHashValue(entryPtr); + children[i]->refCount++; + i++; + } + for (i = 0 ; i < length ; i++) { + Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); + TclNsDecrRefCount(children[i]); + } + TclStackFree((Tcl_Interp *) iPtr, children); + } +#else + if (nsPtr->childTablePtr != NULL) { + while (nsPtr->childTablePtr->numEntries > 0) { + int length = nsPtr->childTablePtr->numEntries; + Namespace **children = (Namespace **)TclStackAlloc((Tcl_Interp *) iPtr, + sizeof(Namespace *) * length); + + i = 0; + for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search); + entryPtr != NULL; + entryPtr = Tcl_NextHashEntry(&search)) { + children[i] = Tcl_GetHashValue(entryPtr); + children[i]->refCount++; + i++; + } + for (i = 0 ; i < length ; i++) { + Tcl_DeleteNamespace((Tcl_Namespace *) children[i]); + TclNsDecrRefCount(children[i]); + } + TclStackFree((Tcl_Interp *) iPtr, children); + } + } +#endif /* * Free the namespace's export pattern array. diff --git a/generic/tclOO.c b/generic/tclOO.c index 452e2ef..405d5d0 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -1184,19 +1184,18 @@ ObjectNamespaceDeleted( * freed memory. */ - if (oPtr->command != NULL) { - if (((Command *) oPtr->command)->flags && CMD_DYING) { - /* - * The command is already (being) deleted. Proceed to clean up the the namespace, - */ - } else { - /* - * The namespace must have been deleted directly. Delete the command - * as well. - */ + if (((Command *) oPtr->command)->flags && CMD_DYING) { + /* + * Something has already started the command deletion process. We can + * go ahead and clean up the the namespace, + */ + } else { + /* + * The namespace must have been deleted directly. Delete the command + * as well. + */ - Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command); - } + Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command); } if (oPtr->myclassCommand) { diff --git a/tests/namespace.test b/tests/namespace.test index dc0e56d..efd00a8 100644 --- a/tests/namespace.test +++ b/tests/namespace.test @@ -3289,8 +3289,8 @@ test namespace-56.2 {bug f97d4ee020: mutually-entangled deletion} { namespace eval ::testing { namespace eval abc {proc xyz {} {}} namespace eval def {proc xyz {} {}} - trace add command abc::xyz delete "namespace delete ::testing::def; #" - trace add command def::xyz delete "namespace delete ::testing::abc; #" + trace add command abc::xyz delete "namespace delete ::testing::def {}; #" + trace add command def::xyz delete "namespace delete ::testing::abc {}; #" } namespace delete ::testing } {} diff --git a/tests/oo.test b/tests/oo.test index 7980f9e..168baee 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1734,7 +1734,6 @@ test oo-11.6.3 { } -result 0 -cleanup { } - test oo-11.6.4 { OO: cleanup ReleaseClassContents() where class is mixed into one of its instances @@ -1755,34 +1754,6 @@ test oo-11.6.4 { rename obj1 {} } - -test oo-11.7 { - When an object is deleted its namespace is deleted, and all objects it is - mixed into are also deleted. If the object has been renamed into the - namespace of one of the objects it has been mixed into, the routine for the - object might get entirely deleted before the namespace of the object is - entirely deleted, in which case the C routine that performs the namespace - deletion either must either understand that the handle on the routine for - the object might now be gone, or it must be guaranteed that the handle does - not disappear until that routine is finished. -} -setup { -} -body { - oo::class create class1 - - oo::object create obj1 - oo::objdefine obj1 { - mixin ::class1 - } - set obj1ns [info object namespace obj1] - set class1ns [info object namespace class1] - rename class1 ${obj1ns}::class1 - # No segmentation fault - namespace delete $class1ns - return done -} -cleanup { -} -result done - - test oo-12.1 {OO: filters} { oo::class create Aclass Aclass create Aobject @@ -1806,8 +1777,6 @@ test oo-12.1 {OO: filters} { Aclass destroy return $result } {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 12345} - - test oo-12.2 {OO: filters} -setup { oo::class create Aclass Aclass create Aobject @@ -4407,13 +4376,12 @@ test oo-35.6 { } -body { rename obj2 {} rename obj1 {} - # No segmentation fault + # doesn't crash return done } -cleanup { rename obj {} } -result done - test oo-36.1 {TIP #470: introspection within oo::define} { oo::define oo::object self } ::oo::object -- cgit v0.12 From 15b5f31cafb65b5055b670feabbbcf17d7af45f4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 4 Apr 2021 16:56:26 +0000 Subject: Rename exported symbol "Tcl_StaticPackage" to "Tcl_StaticLibrary". Still undocumented, to be formalized by TIP #595. Tcl_StaticPackage() still works the same --- generic/tcl.decls | 4 ++-- generic/tcl.h | 3 ++- generic/tclDecls.h | 10 +++++----- generic/tclInt.decls | 2 +- generic/tclIntDecls.h | 12 ++++++------ generic/tclLoad.c | 6 +++--- generic/tclStubInit.c | 8 ++++---- generic/tclTest.c | 4 ++-- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index c39847b..3c7d92e 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -860,7 +860,7 @@ declare 243 { void Tcl_SplitPath(const char *path, int *argcPtr, const char ***argvPtr) } declare 244 {nostub {Don't use this function in a stub-enabled extension}} { - void Tcl_StaticPackage(Tcl_Interp *interp, const char *prefix, + void Tcl_StaticLibrary(Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } declare 245 {deprecated {No longer in use, changed to macro}} { @@ -2478,7 +2478,7 @@ export { Tcl_Interp *interp) } export { - void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName, + void Tcl_StaticLibrary(Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } export { diff --git a/generic/tcl.h b/generic/tcl.h index f61981e..c7bd1a6 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -721,7 +721,6 @@ typedef void (Tcl_MainLoopProc) (void); /* Undocumented. To be formalized by TIP #595 */ #define Tcl_LibraryInitProc Tcl_PackageInitProc #define Tcl_LibraryUnloadProc Tcl_PackageUnloadProc -#define Tcl_StaticLibrary Tcl_StaticPackage /* *---------------------------------------------------------------------------- @@ -2385,6 +2384,8 @@ EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp, const char *version, int exact); EXTERN void Tcl_InitSubsystems(void); EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); +/* Undocumented. To be formalized by TIP #595 */ +# define Tcl_StaticPackage Tcl_StaticLibrary #ifdef _WIN32 EXTERN int TclZipfs_AppHook(int *argc, wchar_t ***argv); #else diff --git a/generic/tclDecls.h b/generic/tclDecls.h index e509c2b..13c269a 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -749,7 +749,7 @@ EXTERN int Tcl_SplitList(Tcl_Interp *interp, EXTERN void Tcl_SplitPath(const char *path, int *argcPtr, const char ***argvPtr); /* 244 */ -EXTERN void Tcl_StaticPackage(Tcl_Interp *interp, +EXTERN void Tcl_StaticLibrary(Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); @@ -2216,7 +2216,7 @@ typedef struct TclStubs { void (*tcl_SourceRCFile) (Tcl_Interp *interp); /* 241 */ int (*tcl_SplitList) (Tcl_Interp *interp, const char *listStr, int *argcPtr, const char ***argvPtr); /* 242 */ void (*tcl_SplitPath) (const char *path, int *argcPtr, const char ***argvPtr); /* 243 */ - TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tcl_StaticPackage) (Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */ + TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tcl_StaticLibrary) (Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */ TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_StringMatch) (const char *str, const char *pattern); /* 245 */ TCL_DEPRECATED_API("") int (*tcl_TellOld) (Tcl_Channel chan); /* 246 */ TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_TraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 247 */ @@ -3148,8 +3148,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_SplitList) /* 242 */ #define Tcl_SplitPath \ (tclStubsPtr->tcl_SplitPath) /* 243 */ -#define Tcl_StaticPackage \ - (tclStubsPtr->tcl_StaticPackage) /* 244 */ +#define Tcl_StaticLibrary \ + (tclStubsPtr->tcl_StaticLibrary) /* 244 */ #define Tcl_StringMatch \ (tclStubsPtr->tcl_StringMatch) /* 245 */ #define Tcl_TellOld \ @@ -3985,7 +3985,7 @@ extern const TclStubs *tclStubsPtr; # undef Tcl_SetPanicProc # undef Tcl_SetExitProc # undef Tcl_ObjSetVar2 -# undef Tcl_StaticPackage +# undef Tcl_StaticLibrary # define Tcl_CreateInterp() (tclStubsPtr->tcl_CreateInterp()) # define Tcl_GetStringResult(interp) (tclStubsPtr->tcl_GetStringResult(interp)) # define Tcl_Init(interp) (tclStubsPtr->tcl_Init(interp)) diff --git a/generic/tclInt.decls b/generic/tclInt.decls index a9b2276..320eab1 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -1026,7 +1026,7 @@ declare 256 { Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags) } declare 257 { - void TclStaticPackage(Tcl_Interp *interp, const char *prefix, + void TclStaticLibrary(Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index 8097425..da3347a 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -651,7 +651,7 @@ EXTERN int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 257 */ -EXTERN void TclStaticPackage(Tcl_Interp *interp, +EXTERN void TclStaticLibrary(Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); @@ -925,7 +925,7 @@ typedef struct TclIntStubs { Tcl_Obj * (*tclPtrIncrObjVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, const int flags); /* 254 */ int (*tclPtrObjMakeUpvar) (Tcl_Interp *interp, Tcl_Var otherPtr, Tcl_Obj *myNamePtr, int myFlags); /* 255 */ int (*tclPtrUnsetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 256 */ - void (*tclStaticPackage) (Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ + void (*tclStaticLibrary) (Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ Tcl_Obj * (*tclpCreateTemporaryDirectory) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj); /* 258 */ unsigned char * (*tclGetBytesFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *lengthPtr); /* 259 */ void (*tclUnusedStubEntry) (void); /* 260 */ @@ -1370,8 +1370,8 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclPtrObjMakeUpvar) /* 255 */ #define TclPtrUnsetVar \ (tclIntStubsPtr->tclPtrUnsetVar) /* 256 */ -#define TclStaticPackage \ - (tclIntStubsPtr->tclStaticPackage) /* 257 */ +#define TclStaticLibrary \ + (tclIntStubsPtr->tclStaticLibrary) /* 257 */ #define TclpCreateTemporaryDirectory \ (tclIntStubsPtr->tclpCreateTemporaryDirectory) /* 258 */ #define TclGetBytesFromObj \ @@ -1409,8 +1409,8 @@ extern const TclIntStubs *tclIntStubsPtr; # undef TclGetCommandFullName # undef TclCopyChannelOld # undef TclSockMinimumBuffersOld -# undef Tcl_StaticPackage -# define Tcl_StaticPackage (tclIntStubsPtr->tclStaticPackage) +# undef Tcl_StaticLibrary +# define Tcl_StaticLibrary (tclIntStubsPtr->tclStaticLibrary) #endif #undef TclGuessPackageName diff --git a/generic/tclLoad.c b/generic/tclLoad.c index afad897..5f319d3 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -15,7 +15,7 @@ /* * The following structure describes a library that has been loaded either * dynamically (with the "load" command) or statically (as indicated by a call - * to Tcl_StaticPackage). All such libraries are linked together into a + * to Tcl_StaticLibrary). All such libraries are linked together into a * single list for the process. Library are never unloaded, until the * application exits, when TclFinalizeLoad is called, and these structures are * freed. @@ -923,7 +923,7 @@ Tcl_UnloadObjCmd( /* *---------------------------------------------------------------------- * - * Tcl_StaticPackage -- + * Tcl_StaticLibrary -- * * This function is invoked to indicate that a particular library has * been linked statically with an application. @@ -939,7 +939,7 @@ Tcl_UnloadObjCmd( */ void -Tcl_StaticPackage( +Tcl_StaticLibrary( Tcl_Interp *interp, /* If not NULL, it means that the library has * already been loaded into the given * interpreter by calling the appropriate init diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index b66af58..18bc51e 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -65,11 +65,11 @@ #undef TclWinGetSockOpt #undef TclWinSetSockOpt #undef TclWinNToHS -#undef TclStaticPackage +#undef TclStaticLibrary #undef Tcl_BackgroundError #undef TclGuessPackageName #undef TclGetLoadedPackages -#define TclStaticPackage Tcl_StaticPackage +#define TclStaticLibrary Tcl_StaticLibrary #undef Tcl_UniCharToUtfDString #undef Tcl_UtfToUniCharDString #undef Tcl_UtfToUniChar @@ -1032,7 +1032,7 @@ static const TclIntStubs tclIntStubs = { TclPtrIncrObjVar, /* 254 */ TclPtrObjMakeUpvar, /* 255 */ TclPtrUnsetVar, /* 256 */ - TclStaticPackage, /* 257 */ + TclStaticLibrary, /* 257 */ TclpCreateTemporaryDirectory, /* 258 */ TclGetBytesFromObj, /* 259 */ TclUnusedStubEntry, /* 260 */ @@ -1519,7 +1519,7 @@ const TclStubs tclStubs = { Tcl_SourceRCFile, /* 241 */ Tcl_SplitList, /* 242 */ Tcl_SplitPath, /* 243 */ - Tcl_StaticPackage, /* 244 */ + Tcl_StaticLibrary, /* 244 */ Tcl_StringMatch, /* 245 */ Tcl_TellOld, /* 246 */ Tcl_TraceVar, /* 247 */ diff --git a/generic/tclTest.c b/generic/tclTest.c index 3835698..9e4ec57 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -4220,7 +4220,7 @@ TestsetplatformCmd( * TeststaticpkgCmd -- * * This procedure implements the "teststaticpkg" command. - * It is used to test the procedure Tcl_StaticPackage. + * It is used to test the procedure Tcl_StaticLibrary. * * Results: * A standard Tcl result. @@ -4252,7 +4252,7 @@ TeststaticpkgCmd( if (Tcl_GetInt(interp, argv[3], &loaded) != TCL_OK) { return TCL_ERROR; } - Tcl_StaticPackage((loaded) ? interp : NULL, argv[1], + Tcl_StaticLibrary((loaded) ? interp : NULL, argv[1], StaticInitProc, (safe) ? StaticInitProc : NULL); return TCL_OK; } -- cgit v0.12 From 85d1500c5027147c1ab54c07cd64381426932b68 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 5 Apr 2021 17:58:13 +0000 Subject: =?UTF-8?q?tclZipfs.c:1857:33:=20warning:=20request=20for=20implic?= =?UTF-8?q?it=20conversion=20from=20=E2=80=98void=20*=E2=80=99=20to=20?= =?UTF-8?q?=E2=80=98char=20*=E2=80=99=20not=20permitted=20in=20C++=20[-Wc+?= =?UTF-8?q?+-compat]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generic/tclZipfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 0b1963b..4ecce48 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -1854,8 +1854,8 @@ ZipfsSetup(void) Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); ZipFS.idCount = 1; ZipFS.wrmax = DEFAULT_WRITE_MAX_SIZE; - ZipFS.fallbackEntryEncoding = - Tcl_Alloc(strlen(ZIPFS_FALLBACK_ENCODING) + 1); + ZipFS.fallbackEntryEncoding = (char *) + ckalloc(strlen(ZIPFS_FALLBACK_ENCODING) + 1); strcpy(ZipFS.fallbackEntryEncoding, ZIPFS_FALLBACK_ENCODING); ZipFS.utf8 = Tcl_GetEncoding(NULL, "utf-8"); ZipFS.initialized = 1; -- cgit v0.12 From 83025a44e02d61c30fba4f3e017d029a16f0890f Mon Sep 17 00:00:00 2001 From: pooryorick Date: Mon, 5 Apr 2021 21:07:00 +0000 Subject: Replace simple refCount decrement with the proper decrementing function. --- generic/tclBasic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 56356e2..27cbeac 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -3740,7 +3740,7 @@ CallCommandTraces( */ cmdPtr->flags &= ~CMD_TRACE_ACTIVE; - cmdPtr->refCount--; + TclCleanupCommandMacro(cmdPtr); iPtr->activeCmdTracePtr = active.nextPtr; Tcl_Release(iPtr); return result; -- cgit v0.12 From ce1a1c9f1387df9db70689527f74c37b4c3cf7c0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 6 Apr 2021 15:57:35 +0000 Subject: Update rules.vc --- win/rules.vc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/win/rules.vc b/win/rules.vc index 2ec5292..85c37f2 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -1203,9 +1203,16 @@ TCLSH_NATIVE = $(TCLSH) !if $(DOING_TK) || $(NEED_TK) WISHNAMEPREFIX = wish WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe -TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT) -TKSTUBLIBNAME = tkstub$(TK_VERSION).lib +TKLIBNAME8 = tk$(TK_VERSION)$(SUFX).$(EXT) +TKLIBNAME9 = tcl9tk$(TK_VERSION)$(SUFX).$(EXT) +!if $(TCL_MAJOR_VERSION) == 8 +TKLIBNAME = tk$(TK_VERSION)$(SUFX).$(EXT) TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib +!else +TKLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).$(EXT) +TKIMPLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).lib +!endif +TKSTUBLIBNAME = tkstub$(TK_VERSION).lib !if $(DOING_TK) WISH = $(OUT_DIR)\$(WISHNAME) -- cgit v0.12 From a1ab68d1ea255fa6445c92b5178da5bedca3f6a4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 7 Apr 2021 09:01:55 +0000 Subject: Revert previous commit, and add comments why it's wrong. --- generic/tclBasic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 27cbeac..aa6d203 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -3513,6 +3513,8 @@ Tcl_DeleteCommandFromToken( if (cmdPtr->tracePtr != NULL) { CommandTrace *tracePtr; + /* Note that CallCommandTraces() never frees cmdPtr, that's + * done just before Tcl_DeleteCommandFromToken() returns */ CallCommandTraces(iPtr,cmdPtr,NULL,NULL,TCL_TRACE_DELETE); /* @@ -3740,7 +3742,9 @@ CallCommandTraces( */ cmdPtr->flags &= ~CMD_TRACE_ACTIVE; - TclCleanupCommandMacro(cmdPtr); + cmdPtr->refCount--; + /* Don't free cmdPtr here, since the caller of CallCommandTraces() + * is responsible for that. See Tcl_DeleteCommandFromToken() */ iPtr->activeCmdTracePtr = active.nextPtr; Tcl_Release(iPtr); return result; -- cgit v0.12 From 06813163a831a73bcdd74a5341bbc547fbb3e342 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 7 Apr 2021 09:55:24 +0000 Subject: TIP #595 (for Tcl 8.7) part 1: just rename Tcl_StaticPackage to Tcl_StaticLibrary, Tcl_PackageInitProc to Tcl_LibraryInitProc and Tcl_PackageUnloadProc to Tcl_LibraryUnloadProc. Adapt documentation, mentioning that the old names are now deprecated. --- doc/FileSystem.3 | 4 +-- doc/PkgRequire.3 | 2 +- doc/StaticLibrary.3 | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ doc/StaticPkg.3 | 73 ----------------------------------------------- doc/load.n | 8 +++--- doc/unload.n | 2 +- generic/tcl.decls | 8 +++--- generic/tcl.h | 16 ++++++----- generic/tclDecls.h | 12 ++++---- generic/tclIOUtil.c | 6 ++-- generic/tclInt.decls | 10 +++---- generic/tclInt.h | 12 ++++---- generic/tclIntDecls.h | 6 ++-- generic/tclLoad.c | 22 +++++++-------- generic/tclTest.c | 10 +++---- tests/load.test | 62 ++++++++++++++++++++-------------------- tests/safe.test | 2 +- tools/tsdPerf.c | 2 +- unix/tclAppInit.c | 15 ++++++---- unix/tclLoadDyld.c | 6 ++-- unix/tclLoadNext.c | 2 +- unix/tclLoadOSF.c | 4 +-- unix/tclLoadShl.c | 2 +- unix/tclXtTest.c | 2 +- win/rules.vc | 11 ++++++-- win/tclAppInit.c | 20 +++++++------ 26 files changed, 210 insertions(+), 187 deletions(-) create mode 100644 doc/StaticLibrary.3 delete mode 100644 doc/StaticPkg.3 diff --git a/doc/FileSystem.3 b/doc/FileSystem.3 index 4583b22..0a3aeef 100644 --- a/doc/FileSystem.3 +++ b/doc/FileSystem.3 @@ -241,9 +241,9 @@ The structure that contains the result of a stat or lstat operation. Name of a procedure to look up in the file's symbol table .AP "const char" *sym2 in Name of a procedure to look up in the file's symbol table -.AP Tcl_PackageInitProc **proc1Ptr out +.AP Tcl_LibraryInitProc **proc1Ptr out Filled with the init function for this code. -.AP Tcl_PackageInitProc **proc2Ptr out +.AP Tcl_LibraryInitProc **proc2Ptr out Filled with the safe-init function for this code. .AP ClientData *clientDataPtr out Filled with the clientData value to pass to this code's unload diff --git a/doc/PkgRequire.3 b/doc/PkgRequire.3 index 71f3acf..f32c936 100644 --- a/doc/PkgRequire.3 +++ b/doc/PkgRequire.3 @@ -94,4 +94,4 @@ compatibility and translate their invocations to this form. .SH KEYWORDS package, present, provide, require, version .SH "SEE ALSO" -package(n), Tcl_StaticPackage(3) +package(n), Tcl_StaticLibrary(3) diff --git a/doc/StaticLibrary.3 b/doc/StaticLibrary.3 new file mode 100644 index 0000000..9a77ab7 --- /dev/null +++ b/doc/StaticLibrary.3 @@ -0,0 +1,78 @@ +'\" +'\" Copyright (c) 1995-1996 Sun Microsystems, Inc. +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH Tcl_StaticLibrary 3 7.5 Tcl "Tcl Library Procedures" +.so man.macros +.BS +.SH NAME +Tcl_StaticLibrary, Tcl_StaticPackage \- make a statically linked library available via the 'load' command +.SH SYNOPSIS +.nf +\fB#include \fR +.sp +\fBTcl_StaticLibrary\fR(\fIinterp, prefix, initProc, safeInitProc\fR) +.sp +\fBTcl_StaticPackage\fR(\fIinterp, prefix, initProc, safeInitProc\fR) +.SH ARGUMENTS +.AS Tcl_LibraryInitProc *safeInitProc +.AP Tcl_Interp *interp in +If not NULL, points to an interpreter into which the library has +already been incorporated (i.e., the caller has already invoked the +appropriate initialization procedure). NULL means the library +has not yet been incorporated into any interpreter. +.AP "const char" *prefix in +Prefix for library initialization function; should be properly +capitalized (first letter upper-case, all others lower-case). +.AP Tcl_LibraryInitProc *initProc in +Procedure to invoke to incorporate this library into a trusted +interpreter. +.AP Tcl_LibraryInitProc *safeInitProc in +Procedure to call to incorporate this library into a safe interpreter +(one that will execute untrusted scripts). NULL means the library +cannot be used in safe interpreters. +.BE +.SH DESCRIPTION +.PP +This procedure may be invoked to announce that a library has been +linked statically with a Tcl application and, optionally, that it +has already been incorporated into an interpreter. +Once \fBTcl_StaticLibrary\fR has been invoked for a library, it +may be incorporated into interpreters using the \fBload\fR command. +\fBTcl_StaticLibrary\fR is normally invoked only by the \fBTcl_AppInit\fR +procedure for the application, not by libraries for themselves +(\fBTcl_StaticLibrary\fR should only be invoked for statically +linked libraries, and code in the library itself should not need +to know whether the library is dynamically loaded or statically linked). +.PP +When the \fBload\fR command is used later to incorporate the library into +an interpreter, one of \fIinitProc\fR and \fIsafeInitProc\fR will +be invoked, depending on whether the target interpreter is safe +or not. +\fIinitProc\fR and \fIsafeInitProc\fR must both match the +following prototype: +.PP +.CS +typedef int \fBTcl_LibraryInitProc\fR( + Tcl_Interp *\fIinterp\fR); +.CE +.PP +The \fIinterp\fR argument identifies the interpreter in which the library +is to be incorporated. The initialization procedure must return \fBTCL_OK\fR or +\fBTCL_ERROR\fR to indicate whether or not it completed successfully; in +the event of an error it should set the interpreter's result to point to an +error message. The result or error from the initialization procedure will +be returned as the result of the \fBload\fR command that caused the +initialization procedure to be invoked. +.PP +\fBTcl_StaticLibrary\fR was named \fBTcl_StaticPackage\fR in Tcl 8.6 and +earlier, but the old name is deprecated now. +.PP +\fBTcl_StaticLibrary\fR can not be used in stub-enabled extensions. Its symbol +entry in the stub table is deprecated and it will be removed in Tcl 9.0. +.SH KEYWORDS +initialization procedure, package, static linking +.SH "SEE ALSO" +load(n), package(n), Tcl_PkgRequire(3) diff --git a/doc/StaticPkg.3 b/doc/StaticPkg.3 deleted file mode 100644 index 68b2725..0000000 --- a/doc/StaticPkg.3 +++ /dev/null @@ -1,73 +0,0 @@ -'\" -'\" Copyright (c) 1995-1996 Sun Microsystems, Inc. -'\" -'\" See the file "license.terms" for information on usage and redistribution -'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" -.TH Tcl_StaticPackage 3 7.5 Tcl "Tcl Library Procedures" -.so man.macros -.BS -.SH NAME -Tcl_StaticPackage \- make a statically linked package available via the 'load' command -.SH SYNOPSIS -.nf -\fB#include \fR -.sp -\fBTcl_StaticPackage\fR(\fIinterp, prefix, initProc, safeInitProc\fR) -.SH ARGUMENTS -.AS Tcl_PackageInitProc *safeInitProc -.AP Tcl_Interp *interp in -If not NULL, points to an interpreter into which the package has -already been loaded (i.e., the caller has already invoked the -appropriate initialization procedure). NULL means the package -has not yet been incorporated into any interpreter. -.AP "const char" *prefix in -Prefix for library initialization function; should be properly -capitalized (first letter upper-case, all others lower-case). -.AP Tcl_PackageInitProc *initProc in -Procedure to invoke to incorporate this package into a trusted -interpreter. -.AP Tcl_PackageInitProc *safeInitProc in -Procedure to call to incorporate this package into a safe interpreter -(one that will execute untrusted scripts). NULL means the package -cannot be used in safe interpreters. -.BE -.SH DESCRIPTION -.PP -This procedure may be invoked to announce that a package has been -linked statically with a Tcl application and, optionally, that it -has already been loaded into an interpreter. -Once \fBTcl_StaticPackage\fR has been invoked for a package, it -may be loaded into interpreters using the \fBload\fR command. -\fBTcl_StaticPackage\fR is normally invoked only by the \fBTcl_AppInit\fR -procedure for the application, not by packages for themselves -(\fBTcl_StaticPackage\fR should only be invoked for statically -loaded packages, and code in the package itself should not need -to know whether the package is dynamically or statically loaded). -.PP -When the \fBload\fR command is used later to load the package into -an interpreter, one of \fIinitProc\fR and \fIsafeInitProc\fR will -be invoked, depending on whether the target interpreter is safe -or not. -\fIinitProc\fR and \fIsafeInitProc\fR must both match the -following prototype: -.PP -.CS -typedef int \fBTcl_PackageInitProc\fR( - Tcl_Interp *\fIinterp\fR); -.CE -.PP -The \fIinterp\fR argument identifies the interpreter in which the package -is to be loaded. The initialization procedure must return \fBTCL_OK\fR or -\fBTCL_ERROR\fR to indicate whether or not it completed successfully; in -the event of an error it should set the interpreter's result to point to an -error message. The result or error from the initialization procedure will -be returned as the result of the \fBload\fR command that caused the -initialization procedure to be invoked. -.PP -\fBTcl_StaticPackage\fR can not be used in stub-enabled extensions. Its symbol -entry in the stub table is deprecated and it will be removed in Tcl 9.0. -.SH KEYWORDS -initialization procedure, package, static linking -.SH "SEE ALSO" -load(n), package(n), Tcl_PkgRequire(3) diff --git a/doc/load.n b/doc/load.n index 265a9fa..f970024 100644 --- a/doc/load.n +++ b/doc/load.n @@ -56,7 +56,7 @@ on Safe\-Tcl, see the \fBsafe\fR manual entry. The initialization procedure must match the following prototype: .PP .CS -typedef int \fBTcl_PackageInitProc\fR( +typedef int \fBTcl_LibraryInitProc\fR( Tcl_Interp *\fIinterp\fR); .CE .PP @@ -79,7 +79,7 @@ Tcl's unloading mechanism. .PP The \fBload\fR command also supports libraries that are statically linked with the application, if those libraries have been registered -by calling the \fBTcl_StaticPackage\fR procedure. +by calling the \fBTcl_StaticLibrary\fR procedure. If \fIfileName\fR is an empty string, then \fIprefix\fR must be specified. .PP @@ -98,7 +98,7 @@ prefix \fBLast\fR. If \fIfileName\fR is an empty string, then \fIprefix\fR must be specified. The \fBload\fR command first searches for a statically loaded library -(one that has been registered by calling the \fBTcl_StaticPackage\fR +(one that has been registered by calling the \fBTcl_StaticLibrary\fR procedure) by that name; if one is found, it is used. Otherwise, the \fBload\fR command searches for a dynamically loaded library by that name, and uses it if it is found. If several @@ -188,7 +188,7 @@ switch $tcl_platform(platform) { foo .CE .SH "SEE ALSO" -info sharedlibextension, package(n), Tcl_StaticPackage(3), safe(n) +info sharedlibextension, package(n), Tcl_StaticLibrary(3), safe(n) .SH KEYWORDS binary code, dynamic library, load, safe interpreter, shared library '\"Local Variables: diff --git a/doc/unload.n b/doc/unload.n index adf4b2c..00b709b 100644 --- a/doc/unload.n +++ b/doc/unload.n @@ -90,7 +90,7 @@ detached from the process. The unload procedure must match the following prototype: .PP .CS -typedef int \fBTcl_PackageUnloadProc\fR( +typedef int \fBTcl_LibraryUnloadProc\fR( Tcl_Interp *\fIinterp\fR, int \fIflags\fR); .CE diff --git a/generic/tcl.decls b/generic/tcl.decls index 3c7d92e..c831a67 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -861,7 +861,7 @@ declare 243 { } declare 244 {nostub {Don't use this function in a stub-enabled extension}} { void Tcl_StaticLibrary(Tcl_Interp *interp, const char *prefix, - Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) + Tcl_LibraryInitProc *initProc, Tcl_LibraryInitProc *safeInitProc) } declare 245 {deprecated {No longer in use, changed to macro}} { int Tcl_StringMatch(const char *str, const char *pattern) @@ -1581,8 +1581,8 @@ declare 443 { } declare 444 { int Tcl_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *sym1, - const char *sym2, Tcl_PackageInitProc **proc1Ptr, - Tcl_PackageInitProc **proc2Ptr, Tcl_LoadHandle *handlePtr, + const char *sym2, Tcl_LibraryInitProc **proc1Ptr, + Tcl_LibraryInitProc **proc2Ptr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr) } declare 445 { @@ -2479,7 +2479,7 @@ export { } export { void Tcl_StaticLibrary(Tcl_Interp *interp, const char *pkgName, - Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) + Tcl_LibraryInitProc *initProc, Tcl_LibraryInitProc *safeInitProc) } export { void Tcl_SetPanicProc(TCL_NORETURN1 Tcl_PanicProc *panicProc) diff --git a/generic/tcl.h b/generic/tcl.h index c7bd1a6..507342f 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -697,8 +697,8 @@ typedef int (Tcl_MathProc) (ClientData clientData, Tcl_Interp *interp, typedef void (Tcl_NamespaceDeleteProc) (ClientData clientData); typedef int (Tcl_ObjCmdProc) (ClientData clientData, Tcl_Interp *interp, int objc, struct Tcl_Obj *const *objv); -typedef int (Tcl_PackageInitProc) (Tcl_Interp *interp); -typedef int (Tcl_PackageUnloadProc) (Tcl_Interp *interp, int flags); +typedef int (Tcl_LibraryInitProc) (Tcl_Interp *interp); +typedef int (Tcl_LibraryUnloadProc) (Tcl_Interp *interp, int flags); typedef void (Tcl_PanicProc) (const char *format, ...); typedef void (Tcl_TcpAcceptProc) (ClientData callbackData, Tcl_Channel chan, char *address, int port); @@ -718,10 +718,11 @@ typedef ClientData (Tcl_InitNotifierProc) (void); typedef void (Tcl_FinalizeNotifierProc) (ClientData clientData); typedef void (Tcl_MainLoopProc) (void); -/* Undocumented. To be formalized by TIP #595 */ -#define Tcl_LibraryInitProc Tcl_PackageInitProc -#define Tcl_LibraryUnloadProc Tcl_PackageUnloadProc - +#ifndef TCL_NO_DEPRECATED +# define Tcl_PackageInitProc Tcl_LibraryInitProc +# define Tcl_PackageUnloadProc Tcl_LibraryUnloadProc +#endif + /* *---------------------------------------------------------------------------- * The following structure represents a type of object, which is a particular @@ -2384,8 +2385,9 @@ EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp, const char *version, int exact); EXTERN void Tcl_InitSubsystems(void); EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); -/* Undocumented. To be formalized by TIP #595 */ +#ifndef TCL_NO_DEPRECATED # define Tcl_StaticPackage Tcl_StaticLibrary +#endif #ifdef _WIN32 EXTERN int TclZipfs_AppHook(int *argc, wchar_t ***argv); #else diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 13c269a..95824bb 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -751,8 +751,8 @@ EXTERN void Tcl_SplitPath(const char *path, int *argcPtr, /* 244 */ EXTERN void Tcl_StaticLibrary(Tcl_Interp *interp, const char *prefix, - Tcl_PackageInitProc *initProc, - Tcl_PackageInitProc *safeInitProc); + Tcl_LibraryInitProc *initProc, + Tcl_LibraryInitProc *safeInitProc); /* 245 */ TCL_DEPRECATED("No longer in use, changed to macro") int Tcl_StringMatch(const char *str, const char *pattern); @@ -1338,8 +1338,8 @@ EXTERN int Tcl_FSDeleteFile(Tcl_Obj *pathPtr); /* 444 */ EXTERN int Tcl_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *sym1, const char *sym2, - Tcl_PackageInitProc **proc1Ptr, - Tcl_PackageInitProc **proc2Ptr, + Tcl_LibraryInitProc **proc1Ptr, + Tcl_LibraryInitProc **proc2Ptr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr); /* 445 */ @@ -2216,7 +2216,7 @@ typedef struct TclStubs { void (*tcl_SourceRCFile) (Tcl_Interp *interp); /* 241 */ int (*tcl_SplitList) (Tcl_Interp *interp, const char *listStr, int *argcPtr, const char ***argvPtr); /* 242 */ void (*tcl_SplitPath) (const char *path, int *argcPtr, const char ***argvPtr); /* 243 */ - TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tcl_StaticLibrary) (Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */ + TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tcl_StaticLibrary) (Tcl_Interp *interp, const char *prefix, Tcl_LibraryInitProc *initProc, Tcl_LibraryInitProc *safeInitProc); /* 244 */ TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_StringMatch) (const char *str, const char *pattern); /* 245 */ TCL_DEPRECATED_API("") int (*tcl_TellOld) (Tcl_Channel chan); /* 246 */ TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_TraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 247 */ @@ -2416,7 +2416,7 @@ typedef struct TclStubs { int (*tcl_FSCopyDirectory) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); /* 441 */ int (*tcl_FSCreateDirectory) (Tcl_Obj *pathPtr); /* 442 */ int (*tcl_FSDeleteFile) (Tcl_Obj *pathPtr); /* 443 */ - int (*tcl_FSLoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *sym1, const char *sym2, Tcl_PackageInitProc **proc1Ptr, Tcl_PackageInitProc **proc2Ptr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr); /* 444 */ + int (*tcl_FSLoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *sym1, const char *sym2, Tcl_LibraryInitProc **proc1Ptr, Tcl_LibraryInitProc **proc2Ptr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr); /* 444 */ int (*tcl_FSMatchInDirectory) (Tcl_Interp *interp, Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); /* 445 */ Tcl_Obj * (*tcl_FSLink) (Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkAction); /* 446 */ int (*tcl_FSRemoveDirectory) (Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); /* 447 */ diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index fc9989a..698b614 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -3009,7 +3009,7 @@ Tcl_FSLoadFile( const char *sym1, const char *sym2, /* Names of two functions to find in the * dynamic shared object. */ - Tcl_PackageInitProc **proc1Ptr, Tcl_PackageInitProc **proc2Ptr, + Tcl_LibraryInitProc **proc1Ptr, Tcl_LibraryInitProc **proc2Ptr, /* Places to store pointers to the functions * named by sym1 and sym2. */ Tcl_LoadHandle *handlePtr, /* A place to store the token for the loaded @@ -3027,8 +3027,8 @@ Tcl_FSLoadFile( res = Tcl_LoadFile(interp, pathPtr, symbols, 0, procPtrs, handlePtr); if (res == TCL_OK) { - *proc1Ptr = (Tcl_PackageInitProc *) procPtrs[0]; - *proc2Ptr = (Tcl_PackageInitProc *) procPtrs[1]; + *proc1Ptr = (Tcl_LibraryInitProc *) procPtrs[0]; + *proc2Ptr = (Tcl_LibraryInitProc *) procPtrs[1]; } else { *proc1Ptr = *proc2Ptr = NULL; } diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 320eab1..c7ead64 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -240,8 +240,8 @@ declare 55 { # Replaced with TclpLoadFile in 8.1: # declare 56 { # int TclLoadFile(Tcl_Interp *interp, char *fileName, char *sym1, -# char *sym2, Tcl_PackageInitProc **proc1Ptr, -# Tcl_PackageInitProc **proc2Ptr) +# char *sym2, Tcl_LibraryInitProc **proc1Ptr, +# Tcl_LibraryInitProc **proc2Ptr) # } # Signature changed to take a length in 8.1: # declare 57 { @@ -553,8 +553,8 @@ declare 138 { } #declare 139 { # int TclpLoadFile(Tcl_Interp *interp, char *fileName, char *sym1, -# char *sym2, Tcl_PackageInitProc **proc1Ptr, -# Tcl_PackageInitProc **proc2Ptr, void **clientDataPtr) +# char *sym2, Tcl_LibraryInitProc **proc1Ptr, +# Tcl_LibraryInitProc **proc2Ptr, void **clientDataPtr) #} #declare 140 { # int TclLooksLikeInt(const char *bytes, int length) @@ -1027,7 +1027,7 @@ declare 256 { } declare 257 { void TclStaticLibrary(Tcl_Interp *interp, const char *prefix, - Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) + Tcl_LibraryInitProc *initProc, Tcl_LibraryInitProc *safeInitProc) } # TIP 431: temporary directory creation function diff --git a/generic/tclInt.h b/generic/tclInt.h index fa661d6..b8ed3c1 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4798,7 +4798,7 @@ MODULE_SCOPE int TclIsPureByteArray(Tcl_Obj *objPtr); *---------------------------------------------------------------------- */ -MODULE_SCOPE Tcl_PackageInitProc TclTommath_Init; +MODULE_SCOPE Tcl_LibraryInitProc TclTommath_Init; /* *---------------------------------------------------------------------- @@ -4810,11 +4810,11 @@ MODULE_SCOPE Tcl_PackageInitProc TclTommath_Init; *---------------------------------------------------------------------- */ -MODULE_SCOPE Tcl_PackageInitProc TclplatformtestInit; -MODULE_SCOPE Tcl_PackageInitProc TclObjTest_Init; -MODULE_SCOPE Tcl_PackageInitProc TclThread_Init; -MODULE_SCOPE Tcl_PackageInitProc Procbodytest_Init; -MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; +MODULE_SCOPE Tcl_LibraryInitProc TclplatformtestInit; +MODULE_SCOPE Tcl_LibraryInitProc TclObjTest_Init; +MODULE_SCOPE Tcl_LibraryInitProc TclThread_Init; +MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_Init; +MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; /* *---------------------------------------------------------------- diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index da3347a..bfd3102 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -653,8 +653,8 @@ EXTERN int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr, /* 257 */ EXTERN void TclStaticLibrary(Tcl_Interp *interp, const char *prefix, - Tcl_PackageInitProc *initProc, - Tcl_PackageInitProc *safeInitProc); + Tcl_LibraryInitProc *initProc, + Tcl_LibraryInitProc *safeInitProc); /* 258 */ EXTERN Tcl_Obj * TclpCreateTemporaryDirectory(Tcl_Obj *dirObj, Tcl_Obj *basenameObj); @@ -925,7 +925,7 @@ typedef struct TclIntStubs { Tcl_Obj * (*tclPtrIncrObjVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, const int flags); /* 254 */ int (*tclPtrObjMakeUpvar) (Tcl_Interp *interp, Tcl_Var otherPtr, Tcl_Obj *myNamePtr, int myFlags); /* 255 */ int (*tclPtrUnsetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 256 */ - void (*tclStaticLibrary) (Tcl_Interp *interp, const char *prefix, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ + void (*tclStaticLibrary) (Tcl_Interp *interp, const char *prefix, Tcl_LibraryInitProc *initProc, Tcl_LibraryInitProc *safeInitProc); /* 257 */ Tcl_Obj * (*tclpCreateTemporaryDirectory) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj); /* 258 */ unsigned char * (*tclGetBytesFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *lengthPtr); /* 259 */ void (*tclUnusedStubEntry) (void); /* 260 */ diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 5f319d3..c9d1b31 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -33,21 +33,21 @@ typedef struct LoadedLibrary { * passed to (*unLoadProcPtr)() when the file * is no longer needed. If fileName is NULL, * then this field is irrelevant. */ - Tcl_PackageInitProc *initProc; + Tcl_LibraryInitProc *initProc; /* Initialization function to call to * incorporate this library into a trusted * interpreter. */ - Tcl_PackageInitProc *safeInitProc; + Tcl_LibraryInitProc *safeInitProc; /* Initialization function to call to * incorporate this library into a safe * interpreter (one that will execute * untrusted scripts). NULL means the library * can't be used in unsafe interpreters. */ - Tcl_PackageUnloadProc *unloadProc; + Tcl_LibraryUnloadProc *unloadProc; /* Finalization function to unload a library * from a trusted interpreter. NULL means that * the library cannot be unloaded. */ - Tcl_PackageUnloadProc *safeUnloadProc; + Tcl_LibraryUnloadProc *safeUnloadProc; /* Finalization function to unload a library * from a safe interpreter. NULL means that * the library cannot be unloaded. */ @@ -127,7 +127,7 @@ Tcl_LoadObjCmd( InterpLibrary *ipFirstPtr, *ipPtr; int code, namesMatch, filesMatch, offset; const char *symbols[2]; - Tcl_PackageInitProc *initProc; + Tcl_LibraryInitProc *initProc; const char *p, *fullFileName, *prefix; Tcl_LoadHandle loadHandle; Tcl_UniChar ch = 0; @@ -409,13 +409,13 @@ Tcl_LoadObjCmd( memcpy(libraryPtr->prefix, Tcl_DStringValue(&pfx), len); libraryPtr->loadHandle = loadHandle; libraryPtr->initProc = initProc; - libraryPtr->safeInitProc = (Tcl_PackageInitProc *) + libraryPtr->safeInitProc = (Tcl_LibraryInitProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&safeInitName)); - libraryPtr->unloadProc = (Tcl_PackageUnloadProc *) + libraryPtr->unloadProc = (Tcl_LibraryUnloadProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&unloadName)); - libraryPtr->safeUnloadProc = (Tcl_PackageUnloadProc *) + libraryPtr->safeUnloadProc = (Tcl_LibraryUnloadProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&safeUnloadName)); libraryPtr->interpRefCount = 0; @@ -549,7 +549,7 @@ Tcl_UnloadObjCmd( Tcl_Interp *target; /* Which interpreter to unload from. */ LoadedLibrary *libraryPtr, *defaultPtr; Tcl_DString pfx, tmp; - Tcl_PackageUnloadProc *unloadProc; + Tcl_LibraryUnloadProc *unloadProc; InterpLibrary *ipFirstPtr, *ipPtr; int i, index, code, complain = 1, keepLibrary = 0; int trustedRefCount = -1, safeRefCount = -1; @@ -947,10 +947,10 @@ Tcl_StaticLibrary( const char *prefix, /* Prefix (must be properly * capitalized: first letter upper case, * others lower case). */ - Tcl_PackageInitProc *initProc, + Tcl_LibraryInitProc *initProc, /* Function to call to incorporate this * library into a trusted interpreter. */ - Tcl_PackageInitProc *safeInitProc) + Tcl_LibraryInitProc *safeInitProc) /* Function to call to incorporate this * library into a safe interpreter (one that * will execute untrusted scripts). NULL means diff --git a/generic/tclTest.c b/generic/tclTest.c index 9e4ec57..39bd392 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -277,7 +277,7 @@ static Tcl_CmdProc Testset2Cmd; static Tcl_CmdProc TestseterrorcodeCmd; static Tcl_ObjCmdProc TestsetobjerrorcodeCmd; static Tcl_CmdProc TestsetplatformCmd; -static Tcl_CmdProc TeststaticpkgCmd; +static Tcl_CmdProc TeststaticlibraryCmd; static Tcl_CmdProc TesttranslatefilenameCmd; static Tcl_CmdProc TestupvarCmd; static Tcl_ObjCmdProc TestWrongNumArgsObjCmd; @@ -604,7 +604,7 @@ Tcltest_Init( NULL, NULL); Tcl_CreateCommand(interp, "testsocket", TestSocketCmd, NULL, NULL); - Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd, + Tcl_CreateCommand(interp, "teststaticlibrary", TeststaticlibraryCmd, NULL, NULL); Tcl_CreateCommand(interp, "testtranslatefilename", TesttranslatefilenameCmd, NULL, NULL); @@ -4217,9 +4217,9 @@ TestsetplatformCmd( /* *---------------------------------------------------------------------- * - * TeststaticpkgCmd -- + * TeststaticlibraryCmd -- * - * This procedure implements the "teststaticpkg" command. + * This procedure implements the "teststaticlibrary" command. * It is used to test the procedure Tcl_StaticLibrary. * * Results: @@ -4233,7 +4233,7 @@ TestsetplatformCmd( */ static int -TeststaticpkgCmd( +TeststaticlibraryCmd( TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ diff --git a/tests/load.test b/tests/load.test index 0ea96ce..f8458b9 100644 --- a/tests/load.test +++ b/tests/load.test @@ -36,9 +36,9 @@ testConstraint $loaded [expr {![string match *pkga* $alreadyLoaded]}] set alreadyTotalLoaded [info loaded] -# Certain tests require the 'teststaticpkg' command from tcltest +# Certain tests require the 'teststaticlibrary' command from tcltest -testConstraint teststaticpkg [llength [info commands teststaticpkg]] +testConstraint teststaticlibrary [llength [info commands teststaticlibrary]] # Test load-10.1 requires the 'testsimplefilesystem' command from tcltest @@ -150,24 +150,24 @@ test load-6.1 {errors loading file} [list $dll $loaded] { catch {load foo foo} } {1} -test load-7.1 {Tcl_StaticPackage procedure} [list teststaticpkg] { +test load-7.1 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { set x "not loaded" - teststaticpkg Test 1 0 + teststaticlibrary Test 1 0 load {} test load {} test child list [set x] [child eval set x] } {loaded loaded} -test load-7.2 {Tcl_StaticPackage procedure} [list teststaticpkg] { +test load-7.2 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { set x "not loaded" - teststaticpkg Another 0 0 + teststaticlibrary Another 0 0 load {} Another child eval {set x "not loaded"} list [catch {load {} Another child} msg] $msg \ [child eval set x] [set x] } {1 {can't use library in a safe interpreter: no Another_SafeInit procedure} {not loaded} loaded} -test load-7.3 {Tcl_StaticPackage procedure} [list teststaticpkg] { +test load-7.3 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { set x "not loaded" - teststaticpkg More 0 1 + teststaticlibrary More 0 1 load {} more set x } {not loaded} @@ -175,53 +175,53 @@ catch {load [file join $testDir pkga$ext] Pkga} catch {load [file join $testDir pkgb$ext] Pkgb} catch {load [file join $testDir pkge$ext] Pkge} set currentRealPackages [list [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] -test load-7.4 {Tcl_StaticPackage procedure, redundant calls} -setup { - teststaticpkg Test 1 0 - teststaticpkg Another 0 0 - teststaticpkg More 0 1 -} -constraints [list teststaticpkg $dll $loaded] -body { - teststaticpkg Double 0 1 - teststaticpkg Double 0 1 +test load-7.4 {Tcl_StaticLibrary procedure, redundant calls} -setup { + teststaticlibrary Test 1 0 + teststaticlibrary Another 0 0 + teststaticlibrary More 0 1 +} -constraints [list teststaticlibrary $dll $loaded] -body { + teststaticlibrary Double 0 1 + teststaticlibrary Double 0 1 info loaded } -result [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded] -testConstraint teststaticpkg_8.x 0 -if {[testConstraint teststaticpkg]} { +testConstraint teststaticlibrary_8.x 0 +if {[testConstraint teststaticlibrary]} { catch { - teststaticpkg Test 1 1 - teststaticpkg Another 0 1 - teststaticpkg More 0 1 - teststaticpkg Double 0 1 - testConstraint teststaticpkg_8.x 1 + teststaticlibrary Test 1 1 + teststaticlibrary Another 0 1 + teststaticlibrary More 0 1 + teststaticlibrary Double 0 1 + testConstraint teststaticlibrary_8.x 1 } } -test load-8.1 {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { +test load-8.1 {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded] } [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded]] -test load-8.2 {TclGetLoadedPackages procedure} -constraints {teststaticpkg_8.x} -body { +test load-8.2 {TclGetLoadedPackages procedure} -constraints {teststaticlibrary_8.x} -body { info loaded gorp } -returnCodes error -result {could not find interpreter "gorp"} -test load-8.3a {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { +test load-8.3a {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded {}] } [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga] [list [file join $testDir pkgb$ext] Pkgb] {*}$alreadyLoaded]] -test load-8.3b {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { +test load-8.3b {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded child] } [lsort -index 1 [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]] -test load-8.4 {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { +test load-8.4 {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { load [file join $testDir pkgb$ext] Pkgb list [lsort -index 1 [info loaded {}]] [lsort [info commands pkgb_*]] } [list [lsort -index 1 [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded]] {pkgb_demo pkgb_sub pkgb_unsafe}] interp delete child -test load-9.1 {Tcl_StaticPackage, load already-loaded package into another interp} -setup { +test load-9.1 {Tcl_StaticLibrary, load already-loaded package into another interp} -setup { interp create child1 interp create child2 load {} Tcltest child1 load {} Tcltest child2 -} -constraints {teststaticpkg} -body { - child1 eval { teststaticpkg Loadninepointone 0 1 } - child2 eval { teststaticpkg Loadninepointone 0 1 } +} -constraints {teststaticlibrary} -body { + child1 eval { teststaticlibrary Loadninepointone 0 1 } + child2 eval { teststaticlibrary Loadninepointone 0 1 } list [child1 eval { info loaded {} }] \ [child2 eval { info loaded {} }] } -match glob -cleanup { diff --git a/tests/safe.test b/tests/safe.test index 8fca594..f3a6565 100644 --- a/tests/safe.test +++ b/tests/safe.test @@ -1159,7 +1159,7 @@ test safe-9.24 {interpConfigure change the access path; check module loading; st res0 res1 res2} # See comments on lsort after test safe-9.20. -catch {teststaticpkg Safepfx1 0 0} +catch {teststaticlibrary Safepfx1 0 0} test safe-10.1 {testing statics loading} -constraints tcl::test -setup { set i [safe::interpCreate] } -body { diff --git a/tools/tsdPerf.c b/tools/tsdPerf.c index 7a599e0..4c96f28 100644 --- a/tools/tsdPerf.c +++ b/tools/tsdPerf.c @@ -1,6 +1,6 @@ #include -extern DLLEXPORT Tcl_PackageInitProc Tsdperf_Init; +extern DLLEXPORT Tcl_LibraryInitProc Tsdperf_Init; static Tcl_ThreadDataKey key; diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 3587f35..f3caae7 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -15,15 +15,19 @@ #undef BUILD_tcl #undef STATIC_BUILD #include "tcl.h" +#if TCL_MAJOR_VERSION < 9 && TCL_MINOR_VERSION < 7 +# define Tcl_LibraryInitProc Tcl_PackageInitProc +# define Tcl_StaticLibrary Tcl_StaticPackage +#endif #ifdef TCL_TEST -extern Tcl_PackageInitProc Tcltest_Init; -extern Tcl_PackageInitProc Tcltest_SafeInit; +extern Tcl_LibraryInitProc Tcltest_Init; +extern Tcl_LibraryInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ #ifdef TCL_XT_TEST extern void XtToolkitInitialize(void); -extern Tcl_PackageInitProc Tclxttest_Init; +extern Tcl_LibraryInitProc Tclxttest_Init; #endif /* TCL_XT_TEST */ /* @@ -79,7 +83,8 @@ main( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#else +#elif !defined(_WIN32) || defined(UNICODE) + /* This doesn't work on Windows without UNICODE */ TclZipfs_AppHook(&argc, &argv); #endif @@ -124,7 +129,7 @@ Tcl_AppInit( if (Tcltest_Init(interp) == TCL_ERROR) { return TCL_ERROR; } - Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); + Tcl_StaticLibrary(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); #endif /* TCL_TEST */ /* diff --git a/unix/tclLoadDyld.c b/unix/tclLoadDyld.c index 017793d..7cd48f2 100644 --- a/unix/tclLoadDyld.c +++ b/unix/tclLoadDyld.c @@ -336,7 +336,7 @@ FindSymbol( const char *symbol) /* Symbol name to look up. */ { Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *)loadHandle->clientData; - Tcl_PackageInitProc *proc = NULL; + Tcl_LibraryInitProc *proc = NULL; const char *errMsg = NULL; Tcl_DString ds; const char *native; @@ -344,7 +344,7 @@ FindSymbol( native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds); if (dyldLoadHandle->dlHandle) { #if TCL_DYLD_USE_DLFCN - proc = (Tcl_PackageInitProc *)dlsym(dyldLoadHandle->dlHandle, native); + proc = (Tcl_LibraryInitProc *)dlsym(dyldLoadHandle->dlHandle, native); if (!proc) { errMsg = dlerror(); } @@ -400,7 +400,7 @@ FindSymbol( dyldLoadHandle->modulePtr->module, native); } if (nsSymbol) { - proc = (Tcl_PackageInitProc *)NSAddressOfSymbol(nsSymbol); + proc = (Tcl_LibraryInitProc *)NSAddressOfSymbol(nsSymbol); } Tcl_DStringFree(&newName); #endif /* TCL_DYLD_USE_NSMODULE */ diff --git a/unix/tclLoadNext.c b/unix/tclLoadNext.c index ee39326..2055210 100644 --- a/unix/tclLoadNext.c +++ b/unix/tclLoadNext.c @@ -133,7 +133,7 @@ FindSymbol( Tcl_LoadHandle loadHandle, const char *symbol) { - Tcl_PackageInitProc *proc = NULL; + Tcl_LibraryInitProc *proc = NULL; if (symbol) { char sym[strlen(symbol) + 2]; diff --git a/unix/tclLoadOSF.c b/unix/tclLoadOSF.c index 7fd0cf3..bb58871 100644 --- a/unix/tclLoadOSF.c +++ b/unix/tclLoadOSF.c @@ -89,7 +89,7 @@ TclpDlopen( */ native = Tcl_FSGetNativePath(pathPtr); - lm = (Tcl_PackageInitProc *) load(native, LDR_NOFLAGS); + lm = (Tcl_LibraryInitProc *) load(native, LDR_NOFLAGS); if (lm == LDR_NULL_MODULE) { /* @@ -101,7 +101,7 @@ TclpDlopen( Tcl_DString ds; native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); - lm = (Tcl_PackageInitProc *) load(native, LDR_NOFLAGS); + lm = (Tcl_LibraryInitProc *) load(native, LDR_NOFLAGS); Tcl_DStringFree(&ds); } diff --git a/unix/tclLoadShl.c b/unix/tclLoadShl.c index 11eaa83..5bf97eb 100644 --- a/unix/tclLoadShl.c +++ b/unix/tclLoadShl.c @@ -128,7 +128,7 @@ FindSymbol( const char *symbol) { Tcl_DString newName; - Tcl_PackageInitProc *proc = NULL; + Tcl_LibraryInitProc *proc = NULL; shl_t handle = (shl_t) loadHandle->clientData; /* diff --git a/unix/tclXtTest.c b/unix/tclXtTest.c index afac493..4ee7cca 100644 --- a/unix/tclXtTest.c +++ b/unix/tclXtTest.c @@ -16,7 +16,7 @@ #include "tcl.h" static Tcl_ObjCmdProc TesteventloopCmd; -extern DLLEXPORT Tcl_PackageInitProc Tclxttest_Init; +extern DLLEXPORT Tcl_LibraryInitProc Tclxttest_Init; /* * Functions defined in tclXtNotify.c for use by users of the Xt Notifier: diff --git a/win/rules.vc b/win/rules.vc index 2ec5292..85c37f2 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -1203,9 +1203,16 @@ TCLSH_NATIVE = $(TCLSH) !if $(DOING_TK) || $(NEED_TK) WISHNAMEPREFIX = wish WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe -TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT) -TKSTUBLIBNAME = tkstub$(TK_VERSION).lib +TKLIBNAME8 = tk$(TK_VERSION)$(SUFX).$(EXT) +TKLIBNAME9 = tcl9tk$(TK_VERSION)$(SUFX).$(EXT) +!if $(TCL_MAJOR_VERSION) == 8 +TKLIBNAME = tk$(TK_VERSION)$(SUFX).$(EXT) TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib +!else +TKLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).$(EXT) +TKIMPLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).lib +!endif +TKSTUBLIBNAME = tkstub$(TK_VERSION).lib !if $(DOING_TK) WISH = $(OUT_DIR)\$(WISHNAME) diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 52ead8e..a10f8db 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -23,16 +23,20 @@ #include #include #include +#if TCL_MAJOR_VERSION < 9 && TCL_MINOR_VERSION < 7 +# define Tcl_LibraryInitProc Tcl_PackageInitProc +# define Tcl_StaticLibrary Tcl_StaticPackage +#endif #ifdef TCL_TEST -extern Tcl_PackageInitProc Tcltest_Init; -extern Tcl_PackageInitProc Tcltest_SafeInit; +extern Tcl_LibraryInitProc Tcltest_Init; +extern Tcl_LibraryInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ #if defined(STATIC_BUILD) -extern Tcl_PackageInitProc Registry_Init; -extern Tcl_PackageInitProc Dde_Init; -extern Tcl_PackageInitProc Dde_SafeInit; +extern Tcl_LibraryInitProc Registry_Init; +extern Tcl_LibraryInitProc Dde_Init; +extern Tcl_LibraryInitProc Dde_SafeInit; #endif #if defined(__GNUC__) || defined(TCL_BROKEN_MAINARGS) @@ -168,19 +172,19 @@ Tcl_AppInit( if (Registry_Init(interp) == TCL_ERROR) { return TCL_ERROR; } - Tcl_StaticPackage(interp, "Registry", Registry_Init, NULL); + Tcl_StaticLibrary(interp, "Registry", Registry_Init, NULL); if (Dde_Init(interp) == TCL_ERROR) { return TCL_ERROR; } - Tcl_StaticPackage(interp, "Dde", Dde_Init, Dde_SafeInit); + Tcl_StaticLibrary(interp, "Dde", Dde_Init, Dde_SafeInit); #endif #ifdef TCL_TEST if (Tcltest_Init(interp) == TCL_ERROR) { return TCL_ERROR; } - Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); + Tcl_StaticLibrary(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); #endif /* TCL_TEST */ /* -- cgit v0.12 From 6792b8a53cf009d7e497d071481a593bb4db9914 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 7 Apr 2021 10:44:29 +0000 Subject: A few missing renamings --- generic/tcl.decls | 2 +- macosx/Tcl.xcode/project.pbxproj | 4 ++-- macosx/Tcl.xcodeproj/project.pbxproj | 4 ++-- win/tcl.dsp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index c831a67..23b9e26 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2478,7 +2478,7 @@ export { Tcl_Interp *interp) } export { - void Tcl_StaticLibrary(Tcl_Interp *interp, const char *pkgName, + void Tcl_StaticLibrary(Tcl_Interp *interp, const char *prefix, Tcl_LibraryInitProc *initProc, Tcl_LibraryInitProc *safeInitProc) } export { diff --git a/macosx/Tcl.xcode/project.pbxproj b/macosx/Tcl.xcode/project.pbxproj index eba62f2..0746261 100644 --- a/macosx/Tcl.xcode/project.pbxproj +++ b/macosx/Tcl.xcode/project.pbxproj @@ -394,7 +394,7 @@ F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = ""; }; F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = ""; }; F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = ""; }; - F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = ""; }; + F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticLibrary.3; sourceTree = ""; }; F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = ""; }; F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = ""; }; F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = ""; }; @@ -1141,7 +1141,7 @@ F96D3EA208F272A7004A47F5 /* split.n */, F96D3EA308F272A7004A47F5 /* SplitList.3 */, F96D3EA408F272A7004A47F5 /* SplitPath.3 */, - F96D3EA508F272A7004A47F5 /* StaticPkg.3 */, + F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */, F96D3EA608F272A7004A47F5 /* StdChannels.3 */, F96D3EA708F272A7004A47F5 /* string.n */, F96D3EA808F272A7004A47F5 /* StringObj.3 */, diff --git a/macosx/Tcl.xcodeproj/project.pbxproj b/macosx/Tcl.xcodeproj/project.pbxproj index c20e83a..6bb3417 100644 --- a/macosx/Tcl.xcodeproj/project.pbxproj +++ b/macosx/Tcl.xcodeproj/project.pbxproj @@ -393,7 +393,7 @@ F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = ""; }; F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = ""; }; F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = ""; }; - F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = ""; }; + F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticLibrary.3; sourceTree = ""; }; F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = ""; }; F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = ""; }; F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = ""; }; @@ -1141,7 +1141,7 @@ F96D3EA208F272A7004A47F5 /* split.n */, F96D3EA308F272A7004A47F5 /* SplitList.3 */, F96D3EA408F272A7004A47F5 /* SplitPath.3 */, - F96D3EA508F272A7004A47F5 /* StaticPkg.3 */, + F96D3EA508F272A7004A47F5 /* StaticLibrary.3 */, F96D3EA608F272A7004A47F5 /* StdChannels.3 */, F96D3EA708F272A7004A47F5 /* string.n */, F96D3EA808F272A7004A47F5 /* StringObj.3 */, diff --git a/win/tcl.dsp b/win/tcl.dsp index 750aac9..cc9d173 100644 --- a/win/tcl.dsp +++ b/win/tcl.dsp @@ -824,7 +824,7 @@ SOURCE=..\doc\SplitPath.3 # End Source File # Begin Source File -SOURCE=..\doc\StaticPkg.3 +SOURCE=..\doc\StaticLibrary.3 # End Source File # Begin Source File -- cgit v0.12 From 79fd04384ae4ba428a1565cc136ca09d2481ab56 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 7 Apr 2021 11:50:03 +0000 Subject: A few more Package -> Library renamings (testcases only) --- tests/load.test | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/load.test b/tests/load.test index f8458b9..40901e5 100644 --- a/tests/load.test +++ b/tests/load.test @@ -174,7 +174,7 @@ test load-7.3 {Tcl_StaticLibrary procedure} [list teststaticlibrary] { catch {load [file join $testDir pkga$ext] Pkga} catch {load [file join $testDir pkgb$ext] Pkgb} catch {load [file join $testDir pkge$ext] Pkge} -set currentRealPackages [list [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] +set currentRealLibraries [list [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]] test load-7.4 {Tcl_StaticLibrary procedure, redundant calls} -setup { teststaticlibrary Test 1 0 teststaticlibrary Another 0 0 @@ -183,7 +183,7 @@ test load-7.4 {Tcl_StaticLibrary procedure, redundant calls} -setup { teststaticlibrary Double 0 1 teststaticlibrary Double 0 1 info loaded -} -result [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded] +} -result [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealLibraries {*}$alreadyTotalLoaded] testConstraint teststaticlibrary_8.x 0 if {[testConstraint teststaticlibrary]} { @@ -196,19 +196,19 @@ if {[testConstraint teststaticlibrary]} { } } -test load-8.1 {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { +test load-8.1 {TclGetLoadedLibraries procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded] -} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded]] -test load-8.2 {TclGetLoadedPackages procedure} -constraints {teststaticlibrary_8.x} -body { +} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealLibraries {*}$alreadyTotalLoaded]] +test load-8.2 {TclGetLoadedLibraries procedure} -constraints {teststaticlibrary_8.x} -body { info loaded gorp } -returnCodes error -result {could not find interpreter "gorp"} -test load-8.3a {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { +test load-8.3a {TclGetLoadedLibraries procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded {}] } [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga] [list [file join $testDir pkgb$ext] Pkgb] {*}$alreadyLoaded]] -test load-8.3b {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { +test load-8.3b {TclGetLoadedLibraries procedure} [list teststaticlibrary_8.x $dll $loaded] { lsort -index 1 [info loaded child] } [lsort -index 1 [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]] -test load-8.4 {TclGetLoadedPackages procedure} [list teststaticlibrary_8.x $dll $loaded] { +test load-8.4 {TclGetLoadedLibraries procedure} [list teststaticlibrary_8.x $dll $loaded] { load [file join $testDir pkgb$ext] Pkgb list [lsort -index 1 [info loaded {}]] [lsort [info commands pkgb_*]] } [list [lsort -index 1 [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded]] {pkgb_demo pkgb_sub pkgb_unsafe}] -- cgit v0.12 From 6c72d33ef125ca3d477f90241f92be52c6132c58 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 8 Apr 2021 07:56:45 +0000 Subject: Make "registry" and "dde" dll's for 8.x and 9.0 installable in the same directory. See TIP #595 --- library/dde/pkgIndex.tcl | 8 +++++++- library/registry/pkgIndex.tcl | 9 +++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/library/dde/pkgIndex.tcl b/library/dde/pkgIndex.tcl index 5d1727d..00a356e 100644 --- a/library/dde/pkgIndex.tcl +++ b/library/dde/pkgIndex.tcl @@ -1,3 +1,9 @@ if {![package vsatisfies [package provide Tcl] 8.5-]} return if {[info sharedlibextension] != ".dll"} return -package ifneeded dde 1.4.4 [list load [file join $dir tcldde14.dll] Dde] +if {[package vsatisfies [package provide Tcl] 9.0-]} { + package ifneeded dde 1.4.4 \ + [list load [file join $dir tcl9dde14.dll] Dde] +} else { + package ifneeded dde 1.4.4 \ + [list load [file join $dir tcldde14.dll] Dde] +} diff --git a/library/registry/pkgIndex.tcl b/library/registry/pkgIndex.tcl index 5c73f30..765f02a 100644 --- a/library/registry/pkgIndex.tcl +++ b/library/registry/pkgIndex.tcl @@ -1,4 +1,9 @@ if {![package vsatisfies [package provide Tcl] 8.5-]} return if {[info sharedlibextension] != ".dll"} return -package ifneeded registry 1.3.6 \ - [list load [file join $dir tclregistry13.dll] Registry] +if {[package vsatisfies [package provide Tcl] 9.0-]} { + package ifneeded registry 1.3.6 \ + [list load [file join $dir tcl9registry13.dll] Registry] +} else { + package ifneeded registry 1.3.6 \ + [list load [file join $dir tclregistry13.dll] Registry] +} -- cgit v0.12 From a463bf5525ce6e43141d98abc3b996e0226b8fe0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 8 Apr 2021 08:45:12 +0000 Subject: Backport dde 1.4.4 from Tcl 8.7. Doesn't conflict with installed Tcl 9.0 version of dde any more. (don't bother doing this for the "registry" extension, because the Tcl 8.7+ version installs in a different directory) --- changes | 4 ++-- library/dde/pkgIndex.tcl | 13 +++++++++---- tests/winDde.test | 4 ++-- win/Makefile.in | 2 +- win/makefile.vc | 2 +- win/tclWinDde.c | 2 +- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/changes b/changes index f662037..f41dd58 100644 --- a/changes +++ b/changes @@ -8972,8 +8972,8 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich) 2020-02-25 (bug) release refs when setting class's superclasses fails (dkf) 2020-02-26 (bug) C++ compiler compatibility for registry and dde (nijtmans) -=> registry 1.4.3 -=> dde 1.3.5 +=> registry 1.3.5 +=> dde 1.4.3 2020-03-05 (new) Update to Unicode-13 (nijtmans) diff --git a/library/dde/pkgIndex.tcl b/library/dde/pkgIndex.tcl index 1ca9c5a..18ac517 100644 --- a/library/dde/pkgIndex.tcl +++ b/library/dde/pkgIndex.tcl @@ -1,7 +1,12 @@ -if {![package vsatisfies [package provide Tcl] 8.5]} return if {[info sharedlibextension] != ".dll"} return -if {[::tcl::pkgconfig get debug]} { - package ifneeded dde 1.4.3 [list load [file join $dir tcldde14g.dll] Dde] +if {[package vsatisfies [package provide Tcl] 9.0-]} { + package ifneeded dde 1.4.4 \ + [list load [file join $dir tcl9dde14.dll] Dde] +} elseif {![package vsatisfies [package provide Tcl] 8.7] + && [::tcl::pkgconfig get debug]} { + package ifneeded dde 1.4.4 \ + [list load [file join $dir tcldde14g.dll] Dde] } else { - package ifneeded dde 1.4.3 [list load [file join $dir tcldde14.dll] Dde] + package ifneeded dde 1.4.4 \ + [list load [file join $dir tcldde14.dll] Dde] } diff --git a/tests/winDde.test b/tests/winDde.test index 9b5fd9e..d97ff84 100644 --- a/tests/winDde.test +++ b/tests/winDde.test @@ -20,7 +20,7 @@ testConstraint dde 0 if {[testConstraint win]} { if {![catch { ::tcltest::loadTestedCommands - set ::ddever [package require dde 1.4.3] + set ::ddever [package require dde 1.4.4] set ::ddelib [info loaded "" Dde]}]} { testConstraint dde 1 } @@ -104,7 +104,7 @@ proc createChildProcess {ddeServerName args} { # ------------------------------------------------------------------------- test winDde-1.0 {check if we are testing the right dll} {win dde} { set ::ddever -} {1.4.3} +} {1.4.4} test winDde-1.1 {Settings the server's topic name} -constraints dde -body { list [dde servername foobar] [dde servername] [dde servername self] diff --git a/win/Makefile.in b/win/Makefile.in index 7af6901..688135f 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -155,7 +155,7 @@ REG_LIB_FILE = @LIBPREFIX@tclreg$(REGVER)${DLLSUFFIX}${LIBSUFFIX} TEST_DLL_FILE = tcltest$(VER)${DLLSUFFIX} TEST_EXE_FILE = tcltest${EXESUFFIX} TEST_LIB_FILE = @LIBPREFIX@tcltest$(VER)${DLLSUFFIX}${LIBSUFFIX} -TEST_LOAD_PRMS = package ifneeded dde 1.4.3 [list load [file normalize ${DDE_DLL_FILE}] Dde];\ +TEST_LOAD_PRMS = package ifneeded dde 1.4.4 [list load [file normalize ${DDE_DLL_FILE}] Dde];\ package ifneeded registry 1.3.5 [list load [file normalize ${REG_DLL_FILE}] Registry] TEST_LOAD_FACILITIES = package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}]];\ $(TEST_LOAD_PRMS) diff --git a/win/makefile.vc b/win/makefile.vc index 60b6bf0..ad20fd1 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -451,7 +451,7 @@ test: test-core test-pkgs test-core: setup $(TCLTEST) dlls $(CAT32) set TCL_LIBRARY=$(ROOT:\=/)/library $(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << - package ifneeded dde 1.4.3 [list load "$(TCLDDELIB:\=/)" Dde] + package ifneeded dde 1.4.4 [list load "$(TCLDDELIB:\=/)" Dde] package ifneeded registry 1.3.5 [list load "$(TCLREGLIB:\=/)" Registry] << diff --git a/win/tclWinDde.c b/win/tclWinDde.c index 2fc4990..2570954 100644 --- a/win/tclWinDde.c +++ b/win/tclWinDde.c @@ -79,7 +79,7 @@ static DWORD ddeInstance; /* The application instance handle given to us * by DdeInitialize. */ static int ddeIsServer = 0; -#define TCL_DDE_VERSION "1.4.3" +#define TCL_DDE_VERSION "1.4.4" #define TCL_DDE_PACKAGE_NAME "dde" #define TCL_DDE_SERVICE_NAME L"TclEval" #define TCL_DDE_EXECUTE_RESULT L"$TCLEVAL$EXECUTE$RESULT" -- cgit v0.12 From e287e351053621a7372984d40a4612c949bd4513 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 8 Apr 2021 11:36:19 +0000 Subject: Fix compiler warning when using select notifier --- unix/tclSelectNotfy.c | 2 +- unix/tclUnixNotfy.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/tclSelectNotfy.c b/unix/tclSelectNotfy.c index 72567e5..82f2ef7 100644 --- a/unix/tclSelectNotfy.c +++ b/unix/tclSelectNotfy.c @@ -377,7 +377,7 @@ TclpInitNotifier(void) void TclpFinalizeNotifier( - ClientData clientData) + TCL_UNUSED(void *)) { #if TCL_THREADS ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index 0be9ed4..c1f00d5 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -211,7 +211,7 @@ LookUpFileHandler( void TclpSetTimer( - const Tcl_Time *timePtr) /* Timeout value, may be NULL. */ + TCL_UNUSED(const Tcl_Time *)) /* Timeout value, may be NULL. */ { /* * The interval timer doesn't do anything in this implementation, because -- cgit v0.12 From 3ed1f7b0557b8d9bd7c22f66594fe480359a199a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 8 Apr 2021 12:29:49 +0000 Subject: Remove TclpCreateFileHandler/TclpDeleteFileHandler on windows. The linker should complain when even trying to create something calling those functions. --- win/tclWinNotify.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c index feb171e..068675c 100644 --- a/win/tclWinNotify.c +++ b/win/tclWinNotify.c @@ -580,46 +580,6 @@ Tcl_Sleep( } /* - *---------------------------------------------------------------------- - * - * TclpCreateFileHandler, TclpDeleteFileHandler -- - * - * Stub functions for strictly POSIX-only functionality that panic with a - * failure message; they simply don't work at all on Windows so using - * them on the platform is always a programming bug. - * - * Results: - * None. - * - * Side effects: - * The process will terminate, violently. - * - *---------------------------------------------------------------------- - */ - -void -TclpCreateFileHandler( - int fd, /* Handle of stream to watch. */ - int mask, /* OR'ed combination of TCL_READABLE, - * TCL_WRITABLE, and TCL_EXCEPTION: indicates - * conditions under which proc should be - * called. */ - Tcl_FileProc *proc, /* Function to call for each selected - * event. */ - ClientData clientData) /* Arbitrary data to pass to proc. */ -{ - Tcl_Panic("Tcl_CreateFileHandler not supported on this platform"); -} - -void -Tcl_DeleteFileHandler( - int fd) /* Stream id for which to remove callback - * function. */ -{ - Tcl_Panic("Tcl_DeleteFileHandler not supported on this platform"); -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 From 122c6b2c017a836a95ce18c26dfda8ae065bc1b1 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 8 Apr 2021 15:04:11 +0000 Subject: Remove TclWinConvertError from internal stub table. No longer necessary, since it's in the external stub table now. --- generic/tclInt.decls | 7 ++++--- generic/tclIntPlatDecls.h | 26 +++++++++----------------- generic/tclStubInit.c | 14 +++++++------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/generic/tclInt.decls b/generic/tclInt.decls index e843b0e..452749e 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -602,9 +602,10 @@ interface tclIntPlat ################################ # Platform specific functions -declare 0 {unix win} { - void TclWinConvertError(unsigned errCode) -} +# Removed in 9.0 +#declare 0 {unix win} { +# void TclWinConvertError(unsigned errCode) +#} declare 1 {unix win} { int TclpCloseFile(TclFile file) } diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index 02ab5f4..3f6ee7ee 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -41,8 +41,7 @@ extern "C" { */ #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ -/* 0 */ -EXTERN void TclWinConvertError(unsigned errCode); +/* Slot 0 is reserved */ /* 1 */ EXTERN int TclpCloseFile(TclFile file); /* 2 */ @@ -108,8 +107,7 @@ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *resultingNameObj); #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ -/* 0 */ -EXTERN void TclWinConvertError(unsigned errCode); +/* Slot 0 is reserved */ /* 1 */ EXTERN int TclpCloseFile(TclFile file); /* 2 */ @@ -179,8 +177,7 @@ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *resultingNameObj); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ -/* 0 */ -EXTERN void TclWinConvertError(unsigned errCode); +/* Slot 0 is reserved */ /* 1 */ EXTERN int TclpCloseFile(TclFile file); /* 2 */ @@ -251,7 +248,7 @@ typedef struct TclIntPlatStubs { void *hooks; #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ - void (*tclWinConvertError) (unsigned errCode); /* 0 */ + void (*reserved0)(void); int (*tclpCloseFile) (TclFile file); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ @@ -284,7 +281,7 @@ typedef struct TclIntPlatStubs { int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ - void (*tclWinConvertError) (unsigned errCode); /* 0 */ + void (*reserved0)(void); int (*tclpCloseFile) (TclFile file); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ @@ -317,7 +314,7 @@ typedef struct TclIntPlatStubs { int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ - void (*tclWinConvertError) (unsigned errCode); /* 0 */ + void (*reserved0)(void); int (*tclpCloseFile) (TclFile file); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ @@ -364,8 +361,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; */ #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ -#define TclWinConvertError \ - (tclIntPlatStubsPtr->tclWinConvertError) /* 0 */ +/* Slot 0 is reserved */ #define TclpCloseFile \ (tclIntPlatStubsPtr->tclpCloseFile) /* 1 */ #define TclpCreateCommandChannel \ @@ -419,8 +415,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */ #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ -#define TclWinConvertError \ - (tclIntPlatStubsPtr->tclWinConvertError) /* 0 */ +/* Slot 0 is reserved */ #define TclpCloseFile \ (tclIntPlatStubsPtr->tclpCloseFile) /* 1 */ #define TclpCreateCommandChannel \ @@ -477,8 +472,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; (tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ -#define TclWinConvertError \ - (tclIntPlatStubsPtr->tclWinConvertError) /* 0 */ +/* Slot 0 is reserved */ #define TclpCloseFile \ (tclIntPlatStubsPtr->tclpCloseFile) /* 1 */ #define TclpCreateCommandChannel \ @@ -538,9 +532,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT -#undef TclWinConvertWSAError #define TclWinConvertWSAError Tcl_WinConvertError -#undef TclWinConvertError #define TclWinConvertError Tcl_WinConvertError #ifdef MAC_OSX_TCL /* not accessable on Win32/UNIX */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 773936e..9d8f12e 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -67,8 +67,10 @@ #undef Tcl_UtfToUniCharDString #undef Tcl_UtfToUniChar #define TclUnusedStubEntry 0 -#undef TclWinConvertError -#define TclWinConvertError 0 +#if !defined(_WIN32) && !defined(__CYGWIN__) +#undef Tcl_WinConvertError +#define Tcl_WinConvertError 0 +#endif #if TCL_UTF_MAX <= 3 @@ -270,8 +272,6 @@ static int utfNcasecmp(const char *s1, const char *s2, unsigned int n){ #else /* __CYGWIN__ */ # define TclWinGetTclInstance (void *(*)(void))(void *)TclpCreateProcess # define TclpGetPid (size_t(*)(Tcl_Pid))(void *)TclUnixWaitForFile -# undef TclWinConvertError -# define TclWinConvertError (void(*)(int))(void *)TclGetAndDetachPids # define TclWinFlushDirtyChannels 0 # define TclWinNoBackslash 0 # define TclWinAddProcess 0 @@ -566,7 +566,7 @@ static const TclIntPlatStubs tclIntPlatStubs = { TCL_STUB_MAGIC, 0, #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ - TclWinConvertError, /* 0 */ + 0, /* 0 */ TclpCloseFile, /* 1 */ TclpCreateCommandChannel, /* 2 */ TclpCreatePipe, /* 3 */ @@ -599,7 +599,7 @@ static const TclIntPlatStubs tclIntPlatStubs = { TclUnixOpenTemporaryFile, /* 30 */ #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ - TclWinConvertError, /* 0 */ + 0, /* 0 */ TclpCloseFile, /* 1 */ TclpCreateCommandChannel, /* 2 */ TclpCreatePipe, /* 3 */ @@ -632,7 +632,7 @@ static const TclIntPlatStubs tclIntPlatStubs = { TclUnixOpenTemporaryFile, /* 30 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ - TclWinConvertError, /* 0 */ + 0, /* 0 */ TclpCloseFile, /* 1 */ TclpCreateCommandChannel, /* 2 */ TclpCreatePipe, /* 3 */ -- cgit v0.12