diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-04-28 08:00:51 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-04-28 08:00:51 (GMT) |
commit | e5766f95f8b74aa6577cf8dff98d48a71ab9d131 (patch) | |
tree | 6e85f7dd2b98f0c060086540c153617c8b70ae9d | |
parent | 69d1bdb95ef90f112d06b7ece0d6db57c504a030 (diff) | |
parent | 2836feb5d8fbaffcd6371c423cd0a0b0eebac840 (diff) | |
download | tcl-e5766f95f8b74aa6577cf8dff98d48a71ab9d131.zip tcl-e5766f95f8b74aa6577cf8dff98d48a71ab9d131.tar.gz tcl-e5766f95f8b74aa6577cf8dff98d48a71ab9d131.tar.bz2 |
merge core-8-6-branchfix_1997007
-rw-r--r-- | generic/tclBasic.c | 32 | ||||
-rw-r--r-- | generic/tclDisassemble.c | 34 | ||||
-rw-r--r-- | generic/tclExecute.c | 6 | ||||
-rw-r--r-- | generic/tclInt.h | 5 | ||||
-rw-r--r-- | generic/tclProc.c | 35 | ||||
-rw-r--r-- | generic/tclScan.c | 21 | ||||
-rw-r--r-- | generic/tclStringObj.c | 14 | ||||
-rw-r--r-- | generic/tclZlib.c | 34 | ||||
-rw-r--r-- | library/http/http.tcl | 17 | ||||
-rw-r--r-- | tests/chanio.test | 6 | ||||
-rw-r--r-- | tests/coroutine.test | 39 | ||||
-rw-r--r-- | tests/format.test | 40 | ||||
-rw-r--r-- | tests/io.test | 4 | ||||
-rw-r--r-- | tests/scan.test | 15 | ||||
-rw-r--r-- | tests/zlib.test | 2 | ||||
-rw-r--r-- | unix/tclConfig.sh.in | 2 | ||||
-rw-r--r-- | unix/tclUnixInit.c | 58 | ||||
-rw-r--r-- | unix/tclUnixSock.c | 35 | ||||
-rwxr-xr-x | win/configure | 3 | ||||
-rw-r--r-- | win/configure.in | 1 | ||||
-rw-r--r-- | win/makefile.vc | 1 | ||||
-rw-r--r-- | win/tclConfig.sh.in | 3 | ||||
-rw-r--r-- | win/tclWinConsole.c | 6 | ||||
-rw-r--r-- | win/tclWinInit.c | 2 | ||||
-rw-r--r-- | win/tclWinInt.h | 10 | ||||
-rw-r--r-- | win/tclWinPipe.c | 22 | ||||
-rw-r--r-- | win/tclWinSerial.c | 2 |
27 files changed, 299 insertions, 150 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 4bddbce..0486383 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -8748,6 +8748,35 @@ TclNRCoroutineActivateCallback( /* *---------------------------------------------------------------------- * + * TclNREvalList -- + * + * Callback to invoke command as list, used in order to delayed + * processing of canonical list command in sane environment. + * + *---------------------------------------------------------------------- + */ + +static int +TclNREvalList( + ClientData data[], + Tcl_Interp *interp, + int result) +{ + int objc; + Tcl_Obj **objv; + Tcl_Obj *listPtr = data[0]; + + Tcl_IncrRefCount(listPtr); + + TclMarkTailcall(interp); + TclNRAddCallback(interp, TclNRReleaseValues, listPtr, NULL, NULL,NULL); + TclListObjGetElements(NULL, listPtr, &objc, &objv); + return TclNREvalObjv(interp, objc, objv, 0, NULL); +} + +/* + *---------------------------------------------------------------------- + * * NRCoroInjectObjCmd -- * * Implementation of [::tcl::unsupported::inject] command. @@ -8799,7 +8828,8 @@ NRCoroInjectObjCmd( */ iPtr->execEnvPtr = corPtr->eePtr; - TclNREvalObjEx(interp, Tcl_NewListObj(objc-2, objv+2), 0, NULL, INT_MIN); + TclNRAddCallback(interp, TclNREvalList, Tcl_NewListObj(objc-2, objv+2), + NULL, NULL, NULL); iPtr->execEnvPtr = savedEEPtr; return TCL_OK; diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 1d616fb..f62c260 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -27,9 +27,8 @@ static Tcl_Obj * DisassembleByteCodeObj(Tcl_Interp *interp, Tcl_Obj *objPtr); static int FormatInstruction(ByteCode *codePtr, const unsigned char *pc, Tcl_Obj *bufferObj); -static void GetLocationInformation(Tcl_Interp *interp, - Proc *procPtr, Tcl_Obj **fileObjPtr, - int *linePtr); +static void GetLocationInformation(Proc *procPtr, + Tcl_Obj **fileObjPtr, int *linePtr); static void PrintSourceToObj(Tcl_Obj *appendObj, const char *stringPtr, int maxChars); static void UpdateStringOfInstName(Tcl_Obj *objPtr); @@ -73,8 +72,6 @@ static const Tcl_ObjType tclInstNameType = { static void GetLocationInformation( - Tcl_Interp *interp, /* Where to look up the location - * information. */ Proc *procPtr, /* What to look up the information for. */ Tcl_Obj **fileObjPtr, /* Where to write the information about what * file the code came from. Will be written @@ -88,20 +85,21 @@ GetLocationInformation( * either with the line number or with -1 if * the information is not available. */ { - Interp *iPtr = (Interp *) interp; - Tcl_HashEntry *hePtr; - CmdFrame *cfPtr; + CmdFrame *cfPtr = TclGetCmdFrameForProcedure(procPtr); *fileObjPtr = NULL; *linePtr = -1; - if (iPtr != NULL && procPtr != NULL) { - hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, procPtr); - if (hePtr != NULL && (cfPtr = Tcl_GetHashValue(hePtr)) != NULL) { - *linePtr = cfPtr->line[0]; - if (cfPtr->type == TCL_LOCATION_SOURCE) { - *fileObjPtr = cfPtr->data.eval.path; - } - } + if (cfPtr == NULL) { + return; + } + + /* + * Get the source location data out of the CmdFrame. + */ + + *linePtr = cfPtr->line[0]; + if (cfPtr->type == TCL_LOCATION_SOURCE) { + *fileObjPtr = cfPtr->data.eval.path; } } @@ -278,7 +276,7 @@ DisassembleByteCodeObj( Tcl_AppendToObj(bufferObj, " Source ", -1); PrintSourceToObj(bufferObj, codePtr->source, TclMin(codePtr->numSrcBytes, 55)); - GetLocationInformation(interp, codePtr->procPtr, &fileObj, &line); + GetLocationInformation(codePtr->procPtr, &fileObj, &line); if (line > -1 && fileObj != NULL) { Tcl_AppendPrintfToObj(bufferObj, "\n File \"%s\" Line %d", Tcl_GetString(fileObj), line); @@ -1221,7 +1219,7 @@ DisassembleByteCodeAsDicts( * system if it is available. */ - GetLocationInformation(interp, codePtr->procPtr, &file, &line); + GetLocationInformation(codePtr->procPtr, &file, &line); /* * Build the overall result. diff --git a/generic/tclExecute.c b/generic/tclExecute.c index cb4e6dc..d30e757 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -510,8 +510,7 @@ VarHashCreateVar( : (*(tPtr) = TCL_NUMBER_DOUBLE)), \ *(ptrPtr) = (ClientData) \ (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \ - ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \ - (((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \ + (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \ ? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \ TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) #else /* !TCL_WIDE_INT_IS_LONG */ @@ -530,8 +529,7 @@ VarHashCreateVar( : (*(tPtr) = TCL_NUMBER_DOUBLE)), \ *(ptrPtr) = (ClientData) \ (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \ - ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \ - (((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \ + (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \ ? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \ TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) #endif /* TCL_WIDE_INT_IS_LONG */ diff --git a/generic/tclInt.h b/generic/tclInt.h index 1deda3c..fe4fefd 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2940,7 +2940,8 @@ MODULE_SCOPE Tcl_Obj * TclGetBgErrorHandler(Tcl_Interp *interp); MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Channel *chanPtr, int *modePtr, int flags); -MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, +MODULE_SCOPE CmdFrame * TclGetCmdFrameForProcedure(Proc *procPtr); +MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, Tcl_Obj *value, int *code); MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, ClientData *clientDataPtr, @@ -3920,7 +3921,7 @@ MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp, struct CompileEnv *envPtr); /* - * Functions defined in generic/tclVar.c and currenttly exported only for use + * Functions defined in generic/tclVar.c and currently exported only for use * by the bytecode compiler and engine. Some of these could later be placed in * the public interface. */ diff --git a/generic/tclProc.c b/generic/tclProc.c index ae9e7cd..5c68e17 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -2774,6 +2774,41 @@ MakeLambdaError( } /* + *---------------------------------------------------------------------- + * + * TclGetCmdFrameForProcedure -- + * + * How to get the CmdFrame information for a procedure. + * + * Results: + * A pointer to the CmdFrame (only guaranteed to be valid until the next + * Tcl command is processed or the interpreter's state is otherwise + * modified) or a NULL if the information is not available. + * + * Side effects: + * none. + * + *---------------------------------------------------------------------- + */ + +CmdFrame * +TclGetCmdFrameForProcedure( + Proc *procPtr) /* The procedure whose cmd-frame is to be + * looked up. */ +{ + Tcl_HashEntry *hePtr; + + if (procPtr == NULL || procPtr->iPtr == NULL) { + return NULL; + } + hePtr = Tcl_FindHashEntry(procPtr->iPtr->linePBodyPtr, procPtr); + if (hePtr == NULL) { + return NULL; + } + return (CmdFrame *) Tcl_GetHashValue(hePtr); +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tclScan.c b/generic/tclScan.c index 5ea7e46..3edb8be 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -10,7 +10,6 @@ */ #include "tclInt.h" -#include "tommath.h" /* * Flag values used by Tcl_ScanObjCmd. @@ -416,7 +415,14 @@ ValidateFormat( case 'x': case 'X': case 'b': + break; case 'u': + if (flags & SCAN_BIG) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "unsigned bignum scans are invalid", -1)); + Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL); + goto error; + } break; /* * Bracket terms need special checking @@ -930,18 +936,7 @@ Tcl_ScanObjCmd( } else { Tcl_SetWideIntObj(objPtr, wideValue); } - } else if (flags & SCAN_BIG) { - if (flags & SCAN_UNSIGNED) { - mp_int big; - if ((Tcl_GetBignumFromObj(interp, objPtr, &big) != TCL_OK) - || (mp_cmp_d(&big, 0) == MP_LT)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "unsigned bignum scans are invalid", -1)); - Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL); - return TCL_ERROR; - } - } - } else { + } else if (!(flags & SCAN_BIG)) { if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) { if (TclGetString(objPtr)[0] == '-') { value = LONG_MIN; diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 6cce073..4e19750 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1943,6 +1943,11 @@ Tcl_AppendFormatToObj( } case 'u': + if (useBig) { + msg = "unsigned bignum format is invalid"; + errCode = "BADUNSIGNED"; + goto errorMsg; + } case 'd': case 'o': case 'x': @@ -1960,15 +1965,6 @@ Tcl_AppendFormatToObj( goto error; } isNegative = (mp_cmp_d(&big, 0) == MP_LT); - if (ch == 'u') { - if (isNegative) { - msg = "unsigned bignum format is invalid"; - errCode = "BADUNSIGNED"; - goto errorMsg; - } else { - ch = 'd'; - } - } #ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 82486d2..fc20d7e 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -3113,30 +3113,28 @@ ZlibTransformOutput( errorCodePtr); } + /* + * No zero-length writes. Flushes must be explicit. + */ + + if (toWrite == 0) { + return 0; + } + cd->outStream.next_in = (Bytef *) buf; cd->outStream.avail_in = toWrite; - do { + while (cd->outStream.avail_in > 0) { e = Deflate(&cd->outStream, cd->outBuffer, cd->outAllocated, Z_NO_FLUSH, &produced); + if (e != Z_OK || produced == 0) { + break; + } - if ((e == Z_OK && produced > 0) || e == Z_BUF_ERROR) { - /* - * deflate() indicates that it is out of space by returning - * Z_BUF_ERROR *or* by simply returning Z_OK with no remaining - * space; in either case, we must write the whole buffer out and - * retry to compress what is left. - */ - - if (e == Z_BUF_ERROR) { - produced = cd->outAllocated; - e = Z_OK; - } - if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { - *errorCodePtr = Tcl_GetErrno(); - return -1; - } + if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { + *errorCodePtr = Tcl_GetErrno(); + return -1; } - } while (e == Z_OK && produced > 0 && cd->outStream.avail_in > 0); + } if (e == Z_OK) { return toWrite - cd->outStream.avail_in; diff --git a/library/http/http.tcl b/library/http/http.tcl index ccd4cd1..03751a3 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -28,10 +28,19 @@ namespace eval http { # We need a useragent string of this style or various servers will refuse to # send us compressed content even when we ask for it. This follows the # de-facto layout of user-agent strings in current browsers. - set http(-useragent) "Mozilla/5.0\ - ([string totitle $::tcl_platform(platform)]; U;\ - $::tcl_platform(os) $::tcl_platform(osVersion))\ - http/[package provide http] Tcl/[package provide Tcl]" + # Safe interpreters do not have ::tcl_platform(os) or + # ::tcl_platform(osVersion). + if {[interp issafe]} { + set http(-useragent) "Mozilla/5.0\ + (Windows; U;\ + Windows NT 10.0)\ + http/[package provide http] Tcl/[package provide Tcl]" + } else { + set http(-useragent) "Mozilla/5.0\ + ([string totitle $::tcl_platform(platform)]; U;\ + $::tcl_platform(os) $::tcl_platform(osVersion))\ + http/[package provide http] Tcl/[package provide Tcl]" + } } proc init {} { diff --git a/tests/chanio.test b/tests/chanio.test index 31bef36..db2475c 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -5338,7 +5338,7 @@ test chan-io-40.2 {POSIX open access modes: CREAT} -setup { } -constraints {unix} -body { set f [open $path(test3) {WRONLY CREAT} 0600] file stat $path(test3) stats - set x [format "0%o" [expr $stats(mode)&0o777]] + set x [format "%#o" [expr $stats(mode)&0o777]] chan puts $f "line 1" chan close $f set f [open $path(test3) r] @@ -5352,8 +5352,8 @@ test chan-io-40.3 {POSIX open access modes: CREAT} -setup { # This test only works if your umask is 2, like ouster's. chan close [open $path(test3) {WRONLY CREAT}] file stat $path(test3) stats - format "0%o" [expr $stats(mode)&0o777] -} -result [format %04o [expr {0o666 & ~ $umaskValue}]] + format "%#o" [expr $stats(mode)&0o777] +} -result [format %#4o [expr {0o666 & ~ $umaskValue}]] test chan-io-40.4 {POSIX open access modes: CREAT} -setup { file delete $path(test3) } -body { diff --git a/tests/coroutine.test b/tests/coroutine.test index 205da67..fd68567 100644 --- a/tests/coroutine.test +++ b/tests/coroutine.test @@ -741,6 +741,45 @@ test coroutine-7.12 {coro floor above street level #3008307} -body { list } -result {} +test coroutine-8.0.0 {coro inject executed} -body { + coroutine demo apply {{} { foreach i {1 2} yield }} + demo + set ::result none + tcl::unsupported::inject demo set ::result inject-executed + demo + set ::result +} -result {inject-executed} +test coroutine-8.0.1 {coro inject after error} -body { + coroutine demo apply {{} { foreach i {1 2} yield; error test }} + demo + set ::result none + tcl::unsupported::inject demo set ::result inject-executed + lappend ::result [catch {demo} err] $err +} -result {inject-executed 1 test} +test coroutine-8.1.1 {coro inject, ticket 42202ba1e5ff566e} -body { + interp create slave + slave eval { + coroutine demo apply {{} { while {1} yield }} + demo + tcl::unsupported::inject demo set ::result inject-executed + } + interp delete slave +} -result {} +test coroutine-8.1.2 {coro inject with result, ticket 42202ba1e5ff566e} -body { + interp create slave + slave eval { + coroutine demo apply {{} { while {1} yield }} + demo + tcl::unsupported::inject demo set ::result inject-executed + } + slave eval demo + set result [slave eval {set ::result}] + + interp delete slave + set result +} -result {inject-executed} + + # cleanup unset lambda diff --git a/tests/format.test b/tests/format.test index dbf6af0..9afedd9 100644 --- a/tests/format.test +++ b/tests/format.test @@ -52,32 +52,32 @@ test format-1.7.1 {integer formatting} longIs64bit { format "%4x %4x %4x %4x" 6 34 16923 -12 -1 } { 6 22 421b fffffffffffffff4} test format-1.8 {integer formatting} longIs32bit { - format "%#x %#X %#X %#x" 6 34 16923 -12 -1 -} {0x6 0X22 0X421B 0xfffffff4} + format "%#x %#x %#X %#X %#x" 0 6 34 16923 -12 -1 +} {0x0 0x6 0X22 0X421B 0xfffffff4} test format-1.8.1 {integer formatting} longIs64bit { - format "%#x %#X %#X %#x" 6 34 16923 -12 -1 -} {0x6 0X22 0X421B 0xfffffffffffffff4} + format "%#x %#x %#X %#X %#x" 0 6 34 16923 -12 -1 +} {0x0 0x6 0X22 0X421B 0xfffffffffffffff4} test format-1.9 {integer formatting} longIs32bit { - format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1 -} { 0x6 0x22 0x421b 0xfffffff4} + format "%#5x %#20x %#20x %#20x %#20x" 0 6 34 16923 -12 -1 +} { 0x0 0x6 0x22 0x421b 0xfffffff4} test format-1.9.1 {integer formatting} longIs64bit { - format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1 -} { 0x6 0x22 0x421b 0xfffffffffffffff4} + format "%#5x %#20x %#20x %#20x %#20x" 0 6 34 16923 -12 -1 +} { 0x0 0x6 0x22 0x421b 0xfffffffffffffff4} test format-1.10 {integer formatting} longIs32bit { - format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1 -} {0x6 0x22 0x421b 0xfffffff4 } + format "%-#5x %-#20x %-#20x %-#20x %-#20x" 0 6 34 16923 -12 -1 +} {0x0 0x6 0x22 0x421b 0xfffffff4 } test format-1.10.1 {integer formatting} longIs64bit { - format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1 -} {0x6 0x22 0x421b 0xfffffffffffffff4 } + format "%-#5x %-#20x %-#20x %-#20x %-#20x" 0 6 34 16923 -12 -1 +} {0x0 0x6 0x22 0x421b 0xfffffffffffffff4 } test format-1.11 {integer formatting} longIs32bit { - format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1 -} {06 042 041033 037777777764 } + format "%-#5o %-#20o %#-20o %#-20o %#-20o" 0 6 34 16923 -12 -1 +} {0 06 042 041033 037777777764 } test format-1.11.1 {integer formatting} longIs64bit { - format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1 -} {06 042 041033 01777777777777777777764} + format "%-#5o %-#20o %#-20o %#-20o %#-20o" 0 6 34 16923 -12 -1 +} {0 06 042 041033 01777777777777777777764} test format-1.12 {integer formatting} { - format "%b %#b %llb" 5 5 [expr {2**100}] -} {101 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} + format "%b %#b %#b %llb" 5 0 5 [expr {2**100}] +} {101 0b0 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} test format-2.1 {string formatting} { format "%s %s %c %s" abcd {This is a very long test string.} 120 x @@ -528,9 +528,9 @@ test format-17.3 {testing %ld with non-wide} {wideIs64bit} { test format-17.4 {testing %l with non-integer} { format %lf 1 } 1.000000 -test format-17.5 {testing %llu with bignum} { +test format-17.5 {testing %llu with positive bignum} -body { format %llu 0xabcdef0123456789abcdef -} 207698809136909011942886895 +} -returnCodes 1 -result {unsigned bignum format is invalid} test format-17.6 {testing %llu with negative number} -body { format %llu -1 } -returnCodes 1 -result {unsigned bignum format is invalid} diff --git a/tests/io.test b/tests/io.test index e2a05dc..197fc36 100644 --- a/tests/io.test +++ b/tests/io.test @@ -5652,8 +5652,8 @@ 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 "0%o" [expr $stats(mode)&0o777] -} [format %04o [expr {0o666 & ~ $umaskValue}]] + format "%#o" [expr $stats(mode)&0o777] +} [format %#4o [expr {0o666 & ~ $umaskValue}]] test io-40.4 {POSIX open access modes: CREAT} { file delete $path(test3) set f [open $path(test3) w] diff --git a/tests/scan.test b/tests/scan.test index 8ddb595..b36b412 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -542,18 +542,23 @@ test scan-5.16 {Bug be003d570f} { scan 0x40 %b } 0 test scan-5.17 {bigint scanning} -setup { - set a {}; set b {}; set c {}; set d {} + set a {}; set b {}; set c {} } -body { - list [scan "207698809136909011942886895,207698809136909011942886895,abcdef0123456789abcdef,125715736004432126361152746757" \ - %llu,%lld,%llx,%llo a b c d] $a $b $c $d -} -result {4 207698809136909011942886895 207698809136909011942886895 207698809136909011942886895 207698809136909011942886895} + list [scan "207698809136909011942886895,abcdef0123456789abcdef,125715736004432126361152746757" \ + %lld,%llx,%llo a b c] $a $b $c +} -result {3 207698809136909011942886895 207698809136909011942886895 207698809136909011942886895} test scan-5.18 {bigint scanning underflow} -setup { set a {}; } -body { list [scan "-207698809136909011942886895" \ %llu a] $a } -returnCodes 1 -result {unsigned bignum scans are invalid} - +test scan-5.18 {bigint scanning invalid} -setup { + set a {}; +} -body { + list [scan "207698809136909011942886895" \ + %llu a] $a +} -returnCodes 1 -result {unsigned bignum scans are invalid} test scan-6.1 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} diff --git a/tests/zlib.test b/tests/zlib.test index 9f06eb1..c2f7825 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -1004,7 +1004,7 @@ test zlib-12.2 {Patrick Dunnigan's issue} -constraints zlib -setup { } -cleanup { removeFile $filesrc removeFile $filedst -} -result 4152 +} -result 56 ::tcltest::cleanupTests return diff --git a/unix/tclConfig.sh.in b/unix/tclConfig.sh.in index b58e9fd..f768690 100644 --- a/unix/tclConfig.sh.in +++ b/unix/tclConfig.sh.in @@ -81,7 +81,7 @@ TCL_DL_LIBS='@DL_LIBS@' # an executable tclsh or tcltest binary. TCL_LD_FLAGS='@LDFLAGS@' -# Flags to pass to ld, such as "-R /usr/local/tcl/lib", that tell the +# Flags to pass to cc/ld, such as "-R /usr/local/tcl/lib", that tell the # run-time dynamic linker where to look for shared libraries such as # libtcl.so. Used when linking applications. Only works if there # is a variable "LIB_RUNTIME_DIR" defined in the Makefile. diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index badfb36..67e0b65 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -744,6 +744,43 @@ Tcl_GetEncodingNameFromEnvironment( *---------------------------------------------------------------------- */ +#if defined(HAVE_COREFOUNDATION) && MAC_OS_X_VERSION_MAX_ALLOWED > 1020 +/* + * Helper because whether CFLocaleCopyCurrent and CFLocaleGetIdentifier are + * strongly or weakly bound varies by version of OSX, triggering warnings. + */ + +static inline void +InitMacLocaleInfoVar( + CFLocaleRef (*localeCopyCurrent)(void), + CFStringRef (*localeGetIdentifier)(CFLocaleRef), + Tcl_Interp *interp) +{ + CFLocaleRef localeRef; + CFStringRef locale; + char loc[256]; + + if (localeCopyCurrent == NULL || localeGetIdentifier == NULL) { + return; + } + + localeRef = localeCopyCurrent(); + if (!localeRef) { + return; + } + + locale = localeGetIdentifier(localeRef); + if (locale && CFStringGetCString(locale, loc, 256, + kCFStringEncodingUTF8)) { + if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) { + Tcl_ResetResult(interp); + } + Tcl_SetVar(interp, "::tcl::mac::locale", loc, TCL_GLOBAL_ONLY); + } + CFRelease(localeRef); +} +#endif /*defined(HAVE_COREFOUNDATION) && MAC_OS_X_VERSION_MAX_ALLOWED > 1020*/ + void TclpSetVariables( Tcl_Interp *interp) @@ -762,29 +799,12 @@ TclpSetVariables( #ifdef HAVE_COREFOUNDATION char tclLibPath[MAXPATHLEN + 1]; -#if MAC_OS_X_VERSION_MAX_ALLOWED > 1020 /* * Set msgcat fallback locale to current CFLocale identifier. */ - CFLocaleRef localeRef; - - if (&CFLocaleCopyCurrent != NULL && &CFLocaleGetIdentifier != NULL && - (localeRef = CFLocaleCopyCurrent())) { - CFStringRef locale = CFLocaleGetIdentifier(localeRef); - - if (locale) { - char loc[256]; - - if (CFStringGetCString(locale, loc, 256, kCFStringEncodingUTF8)) { - if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) { - Tcl_ResetResult(interp); - } - Tcl_SetVar(interp, "::tcl::mac::locale", loc, TCL_GLOBAL_ONLY); - } - } - CFRelease(localeRef); - } +#if MAC_OS_X_VERSION_MAX_ALLOWED > 1020 + InitMacLocaleInfoVar(CFLocaleCopyCurrent, CFLocaleGetIdentifier, interp); #endif /* MAC_OS_X_VERSION_MAX_ALLOWED > 1020 */ if (MacOSXGetLibraryPath(interp, MAXPATHLEN, tclLibPath) == TCL_OK) { diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index ca8d677..e8767e2 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -698,6 +698,33 @@ TcpClose2Proc( * *---------------------------------------------------------------------- */ + +#ifndef NEED_FAKE_RFC2553 +static inline int +IPv6AddressNeedsNumericRendering( + struct in6_addr addr) +{ + if (IN6_ARE_ADDR_EQUAL(&addr, &in6addr_any)) { + return 1; + } + + /* + * The IN6_IS_ADDR_V4MAPPED macro has a problem with aliasing warnings on + * at least some versions of OSX. + */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" + if (!IN6_IS_ADDR_V4MAPPED(&addr)) { +#pragma GCC diagnostic pop + return 0; + } + + return (addr.s6_addr[12] == 0 && addr.s6_addr[13] == 0 + && addr.s6_addr[14] == 0 && addr.s6_addr[15] == 0); +} +#endif /* NEED_FAKE_RFC2553 */ + static void TcpHostPortList( Tcl_Interp *interp, @@ -723,13 +750,7 @@ TcpHostPortList( } #ifndef NEED_FAKE_RFC2553 } else if (addr.sa.sa_family == AF_INET6) { - if ((IN6_ARE_ADDR_EQUAL(&addr.sa6.sin6_addr, - &in6addr_any)) - || (IN6_IS_ADDR_V4MAPPED(&addr.sa6.sin6_addr) && - addr.sa6.sin6_addr.s6_addr[12] == 0 && - addr.sa6.sin6_addr.s6_addr[13] == 0 && - addr.sa6.sin6_addr.s6_addr[14] == 0 && - addr.sa6.sin6_addr.s6_addr[15] == 0)) { + if (IPv6AddressNeedsNumericRendering(addr.sa6.sin6_addr)) { flags |= NI_NUMERICHOST; } #endif /* NEED_FAKE_RFC2553 */ diff --git a/win/configure b/win/configure index e8e4b87..85dc0ba 100755 --- a/win/configure +++ b/win/configure @@ -309,7 +309,7 @@ ac_includes_default="\ # include <unistd.h> #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING ZLIB_DLL_FILE ZLIB_LIBS ZLIB_OBJS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCL_WIN_VERSION MACHINE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL PKG_CFG_ARGS TCL_EXE TCL_LIB_FILE TCL_LIB_FLAG TCL_STATIC_LIB_FILE TCL_STATIC_LIB_FLAG TCL_IMPORT_LIB_FILE TCL_IMPORT_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_DLL_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX CFG_TCL_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TCL_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TCL_BUILD_LIB_SPEC TCL_LD_SEARCH_FLAGS TCL_NEEDS_EXP_FILE TCL_BUILD_EXP_FILE TCL_EXP_FILE TCL_LIB_VERSIONS_OK TCL_PACKAGE_PATH TCL_DDE_VERSION TCL_DDE_MAJOR_VERSION TCL_DDE_MINOR_VERSION TCL_REG_VERSION TCL_REG_MAJOR_VERSION TCL_REG_MINOR_VERSION RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING ZLIB_DLL_FILE ZLIB_LIBS ZLIB_OBJS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCL_WIN_VERSION MACHINE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL PKG_CFG_ARGS TCL_EXE TCL_LIB_FILE TCL_LIB_FLAG TCL_STATIC_LIB_FILE TCL_STATIC_LIB_FLAG TCL_IMPORT_LIB_FILE TCL_IMPORT_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_DLL_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX CFG_TCL_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TCL_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TCL_BUILD_LIB_SPEC TCL_CC_SEARCH_FLAGS TCL_LD_SEARCH_FLAGS TCL_NEEDS_EXP_FILE TCL_BUILD_EXP_FILE TCL_EXP_FILE TCL_LIB_VERSIONS_OK TCL_PACKAGE_PATH TCL_DDE_VERSION TCL_DDE_MAJOR_VERSION TCL_DDE_MINOR_VERSION TCL_REG_VERSION TCL_REG_MAJOR_VERSION TCL_REG_MINOR_VERSION RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -6010,6 +6010,7 @@ s,@POST_MAKE_LIB@,$POST_MAKE_LIB,;t t s,@MAKE_DLL@,$MAKE_DLL,;t t s,@MAKE_EXE@,$MAKE_EXE,;t t s,@TCL_BUILD_LIB_SPEC@,$TCL_BUILD_LIB_SPEC,;t t +s,@TCL_CC_SEARCH_FLAGS@,$TCL_CC_SEARCH_FLAGS,;t t s,@TCL_LD_SEARCH_FLAGS@,$TCL_LD_SEARCH_FLAGS,;t t s,@TCL_NEEDS_EXP_FILE@,$TCL_NEEDS_EXP_FILE,;t t s,@TCL_BUILD_EXP_FILE@,$TCL_BUILD_EXP_FILE,;t t diff --git a/win/configure.in b/win/configure.in index 8bb9c48..b478d1e 100644 --- a/win/configure.in +++ b/win/configure.in @@ -433,6 +433,7 @@ AC_SUBST(MAKE_EXE) # empty on win, but needs sub'ing AC_SUBST(TCL_BUILD_LIB_SPEC) +AC_SUBST(TCL_CC_SEARCH_FLAGS) AC_SUBST(TCL_LD_SEARCH_FLAGS) AC_SUBST(TCL_NEEDS_EXP_FILE) AC_SUBST(TCL_BUILD_EXP_FILE) diff --git a/win/makefile.vc b/win/makefile.vc index 8cbae2e..ada08cc 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -878,6 +878,7 @@ $(OUT_DIR)\tclConfig.sh: $(WINDIR)\tclConfig.sh.in @SHLIB_SUFFIX@ .dll
@DL_LIBS@
@LDFLAGS@
+@TCL_CC_SEARCH_FLAGS@
@TCL_LD_SEARCH_FLAGS@
@LIBOBJS@
@RANLIB@
diff --git a/win/tclConfig.sh.in b/win/tclConfig.sh.in index 75324b2..6ed06e2 100644 --- a/win/tclConfig.sh.in +++ b/win/tclConfig.sh.in @@ -92,10 +92,11 @@ TCL_DL_LIBS='@DL_LIBS@' # an executable tclsh or tcltest binary. TCL_LD_FLAGS='@LDFLAGS@' -# Flags to pass to ld, such as "-R /usr/local/tcl/lib", that tell the +# Flags to pass to cc/ld, such as "-R /usr/local/tcl/lib", that tell the # run-time dynamic linker where to look for shared libraries such as # libtcl.so. Used when linking applications. Only works if there # is a variable "LIB_RUNTIME_DIR" defined in the Makefile. +TCL_CC_SEARCH_FLAGS='@TCL_CC_SEARCH_FLAGS@' TCL_LD_SEARCH_FLAGS='@TCL_LD_SEARCH_FLAGS@' # Additional object files linked with Tcl to provide compatibility diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 7a0965d..d61a030 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -1106,7 +1106,7 @@ ConsoleReaderThread( HANDLE *handle = NULL; ConsoleThreadInfo *threadInfo = NULL; int done = 0; - + while (!done) { /* * Wait for the main thread to signal before attempting to read. @@ -1205,7 +1205,7 @@ ConsoleWriterThread( DWORD count, toWrite; char *buf; int done = 0; - + while (!done) { /* * Wait for the main thread to signal before attempting to write. @@ -1339,7 +1339,7 @@ TclWinOpenConsoleChannel( infoPtr->reader.readyEvent = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->reader.thread = CreateThread(NULL, 256, ConsoleReaderThread, - TclPipeThreadCreateTI(&infoPtr->reader.TI, infoPtr, + TclPipeThreadCreateTI(&infoPtr->reader.TI, infoPtr, infoPtr->reader.readyEvent), 0, NULL); SetThreadPriority(infoPtr->reader.thread, THREAD_PRIORITY_HIGHEST); } diff --git a/win/tclWinInit.c b/win/tclWinInit.c index 03ef5df..f13e314 100644 --- a/win/tclWinInit.c +++ b/win/tclWinInit.c @@ -166,7 +166,7 @@ TclpInitPlatform(void) */ hInstance = LoadLibraryW(L"kernel32"); if (hInstance != NULL) { - _tclWinProcs.cancelSynchronousIo = + _tclWinProcs.cancelSynchronousIo = (BOOL (WINAPI *)(HANDLE)) GetProcAddress(hInstance, "CancelSynchronousIo"); } diff --git a/win/tclWinInt.h b/win/tclWinInt.h index 86945a9..76f5f68 100644 --- a/win/tclWinInt.h +++ b/win/tclWinInt.h @@ -98,14 +98,14 @@ MODULE_SCOPE void TclpSetAllocCache(void *); /* *---------------------------------------------------------------------- * Declarations of helper-workers threaded facilities for a pipe based channel. - * + * * Corresponding functionality provided in "tclWinPipe.c". *---------------------------------------------------------------------- */ typedef struct TclPipeThreadInfo { HANDLE evControl; /* Auto-reset event used by the main thread to - * signal when the pipe thread should attempt + * signal when the pipe thread should attempt * to do read/write operation. Additionally * used as signal to stop (state set to -1) */ volatile LONG state; /* Indicates current state of the thread */ @@ -122,7 +122,7 @@ typedef struct TclPipeThreadInfo { /* * State of the pipe-worker. - * + * * State PTI_STATE_STOP possible from idle state only, worker owns TI structure. * Otherwise PTI_STATE_END used (main thread hold ownership of the TI). */ @@ -134,8 +134,8 @@ typedef struct TclPipeThreadInfo { #define PTI_STATE_DOWN 8 /* worker is down */ -MODULE_SCOPE -TclPipeThreadInfo * TclPipeThreadCreateTI(TclPipeThreadInfo **pipeTIPtr, +MODULE_SCOPE +TclPipeThreadInfo * TclPipeThreadCreateTI(TclPipeThreadInfo **pipeTIPtr, ClientData clientData, HANDLE wakeEvent); MODULE_SCOPE int TclPipeThreadWaitForSignal(TclPipeThreadInfo **pipeTIPtr); diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index d303f8f..4a1e75a 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -2619,7 +2619,7 @@ WaitForRead( */ /* avoid blocking if pipe-thread exited */ - timeout = (!blocking || !TclPipeThreadIsAlive(&infoPtr->readTI) + timeout = (!blocking || !TclPipeThreadIsAlive(&infoPtr->readTI) || TclInExit() || TclInThreadExit()) ? 0 : INFINITE; if (WaitForSingleObject(infoPtr->readable, timeout) == WAIT_TIMEOUT) { /* @@ -2727,7 +2727,7 @@ PipeReaderThread( HANDLE handle = NULL; DWORD count, err; int done = 0; - + while (!done) { /* * Wait for the main thread to signal before attempting to wait on the @@ -3154,7 +3154,7 @@ TclPipeThreadWaitForSignal( } /* signaled to work */ - return 1; + return 1; end: /* end of work, check the owner of the TI structure */ @@ -3211,7 +3211,7 @@ TclPipeThreadStopSignal( *pipeTIPtr = NULL; case PTI_STATE_DOWN: - + return 1; default: @@ -3308,7 +3308,7 @@ TclPipeThreadStop( if (pipeTI && hThread) { DWORD exitCode; - + /* * The thread may already have closed on its own. Check its exit * code. @@ -3362,22 +3362,22 @@ TclPipeThreadStop( * As a result, all new threads are deadlocked in their initialization phase and never execute, * even though CreateThread() reports successful thread creation. * This results in a very weird process-wide behavior, which is extremely hard to debug. - * + * * THREADS SHOULD NEVER BE TERMINATED. Period. - * + * * But for now, check if thread is exiting, and if so, let it die peacefully. * * Also don't terminate if in exit (otherwise deadlocked in ntdll.dll's). */ if ( pipeTI->state != PTI_STATE_DOWN - && WaitForSingleObject(hThread, - inExit ? 50 : 5000) != WAIT_OBJECT_0 + && WaitForSingleObject(hThread, + inExit ? 50 : 5000) != WAIT_OBJECT_0 ) { /* BUG: this leaks memory */ if (inExit || !TerminateThread(hThread, 0)) { /* in exit or terminate fails, just give thread a chance to exit */ - if (InterlockedExchange(&pipeTI->state, + if (InterlockedExchange(&pipeTI->state, PTI_STATE_STOP) != PTI_STATE_DOWN) { pipeTI = NULL; } @@ -3408,7 +3408,7 @@ TclPipeThreadStop( * * Clean-up for the pipe thread (removes owned TI-structure in worker). * - * Should be executed on worker exit, to inform the main thread or + * Should be executed on worker exit, to inform the main thread or * free TI-structure (if owned). * * After calling of this function, TI-structure pointer given via pipeTIPtr diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c index f78aa5a..fe416ff 100644 --- a/win/tclWinSerial.c +++ b/win/tclWinSerial.c @@ -1470,7 +1470,7 @@ TclWinOpenSerialChannel( infoPtr->osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); infoPtr->evWritable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->writeThread = CreateThread(NULL, 256, SerialWriterThread, - TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr, + TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr, infoPtr->evWritable), 0, NULL); } |