diff options
-rw-r--r-- | ChangeLog | 55 | ||||
-rw-r--r-- | doc/coroutine.n | 56 | ||||
-rw-r--r-- | generic/tcl.decls | 2 | ||||
-rw-r--r-- | generic/tclBasic.c | 11 | ||||
-rw-r--r-- | generic/tclDecls.h | 4 | ||||
-rw-r--r-- | generic/tclEnsemble.c | 6 | ||||
-rw-r--r-- | generic/tclFileName.c | 85 | ||||
-rw-r--r-- | generic/tclHash.c | 4 | ||||
-rw-r--r-- | generic/tclIOSock.c | 29 | ||||
-rw-r--r-- | generic/tclInt.decls | 36 | ||||
-rw-r--r-- | generic/tclIntDecls.h | 22 | ||||
-rw-r--r-- | generic/tclIntPlatDecls.h | 51 | ||||
-rw-r--r-- | generic/tclLoad.c | 32 | ||||
-rw-r--r-- | generic/tclOO.c | 23 | ||||
-rw-r--r-- | generic/tclOOInt.h | 15 | ||||
-rw-r--r-- | generic/tclPanic.c | 12 | ||||
-rw-r--r-- | generic/tclPathObj.c | 33 | ||||
-rw-r--r-- | generic/tclStubInit.c | 69 | ||||
-rw-r--r-- | generic/tclThreadAlloc.c | 8 | ||||
-rw-r--r-- | generic/tclTomMath.decls | 6 | ||||
-rw-r--r-- | generic/tclTomMathDecls.h | 12 | ||||
-rw-r--r-- | generic/tclUtil.c | 11 | ||||
-rw-r--r-- | generic/tclVar.c | 4 | ||||
-rw-r--r-- | tests/coroutine.test | 49 | ||||
-rw-r--r-- | tests/oo.test | 50 | ||||
-rwxr-xr-x | unix/configure | 138 | ||||
-rwxr-xr-x | win/configure | 1505 | ||||
-rw-r--r-- | win/tclWinError.c | 64 | ||||
-rw-r--r-- | win/tclWinLoad.c | 229 | ||||
-rw-r--r-- | win/tclWinSock.c | 435 |
30 files changed, 1555 insertions, 1501 deletions
@@ -1,13 +1,52 @@ +2012-04-04 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclOO.c (Tcl_NewObjectInstance, TclNRNewObjectInstance): + [Bug 3514761]: Fixed bogosity with automated argument description + handling when constructing an instance of a class that is itself a + member of an ensemble. Thanks to Andreas Kupries for identifying that + this was a problem case at all! + (Tcl_CopyObjectInstance): Fix potential bleed-over of ensemble + information into [oo::copy]. + +2012-04-04 Jan Nijtmans <nijtmans@users.sf.net> + + * win/tclWinSock.c: [Bug 510001]: TclSockMinimumBuffers needs plat imp + * generic/tclIOSock.c: + * generic/tclInt.decls: + * generic/tclIntDecls.h: + * generic/tclStubInit.c: + +2012-04-03 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/tclStubInit.c: Remove the TclpGetTZName implementation for + * generic/tclIntDecls.h: Cygwin (from 2012-04-02 commit), re-generated + * generic/tclIntPlatDecls.h: + +2012-04-02 Donal K. Fellows <dkf@users.sf.net> + + IMPLEMENTATION OF TIP#396. + + * generic/tclBasic.c (builtInCmds, TclNRYieldToObjCmd): Convert the + formerly-unsupported yieldm and yieldTo commands into [yieldto]. + +2012-04-02 Jan Nijtmans <nijtmans@users.sf.net> + + * generic/tclInt.decls: [Bug 3508771]: load tclreg.dll in cygwin tclsh + * generic/tclIntPlatDecls.h: Implement TclWinGetTclInstance, + * generic/tclStubInit.c: TclpGetTZName, and various more + win32-specific internal functions for Cygwin, so win32 extensions + using those can be loaded in the cygwin version of tclsh. + 2012-03-30 Jan Nijtmans <nijtmans@users.sf.net> - * unix/tcl.m4: [Bug 3511806] Compiler checks too early - * unix/configure.in: This change allows to build the cygwin - * unix/tclUnixPort.h: and mingw32 ports of Tcl/Tk to build - * win/tcl.m4: out-of-the-box using a native or cross- - * win/configure.in: compiler. - * win/tclWinPort.h: (autoconf still to be run!) - * win/README Document how to build win32 or win64 - executables with Linux, Cygwin or Darwin. + * unix/tcl.m4: [Bug 3511806]: Compiler checks too early + * unix/configure.in: This change allows to build the cygwin and + * unix/tclUnixPort.h: mingw32 ports of Tcl/Tk to build out-of-the-box + * win/tcl.m4: using a native or cross-compiler. + * win/configure.in: + * win/tclWinPort.h: + * win/README Document how to build win32 or win64 executables + with Linux, Cygwin or Darwin. 2012-03-29 Jan Nijtmans <nijtmans@users.sf.net> diff --git a/doc/coroutine.n b/doc/coroutine.n index f4b5d5b..035d58a 100644 --- a/doc/coroutine.n +++ b/doc/coroutine.n @@ -9,12 +9,15 @@ .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME -coroutine, yield \- Create and produce values from coroutines +coroutine, yield, yieldto \- Create and produce values from coroutines .SH SYNOPSIS .nf \fBcoroutine \fIname command\fR ?\fIarg...\fR? \fByield\fR ?\fIvalue\fR? -\fIname\fR ?\fIvalue\fR? +.VS TIP396 +\fByieldto\fR \fIcommand\fR ?\fIarg...\fR? +\fIname\fR ?\fIvalue...\fR? +.VE TIP396 .fi .BE .SH DESCRIPTION @@ -30,11 +33,37 @@ Within the context, values may be generated as results by using the When that is called, the context will suspend execution and the \fBcoroutine\fR command will return the argument to \fByield\fR. The execution of the context can then be resumed by calling the context command, optionally -passing in the value to use as the result of the \fByield\fR call that caused +passing in the \fIsingle\fR value to use as the result of the \fByield\fR call +that caused the context to be suspended. If the coroutine context never yields and instead returns conventionally, the result of the \fBcoroutine\fR command will be the result of the evaluation of the context. .PP +.VS TIP396 +The coroutine may also suspend its execution by use of the \fByieldto\fR +command, which instead of returning, cedes execution to some command called +\fIcommand\fR (resolved in the context of the coroutine) and to which \fIany +number\fR of arguments may be passed. Since every coroutine has a context +command, \fByieldto\fR can be used to transfer control directly from one +coroutine to another (this is only advisable if the two coroutines are +expecting this to happen) but \fIany\fR command may be the target. If a +coroutine is suspended by this mechanism, the coroutine processing can be +resumed by calling the context command optionally passing in an arbitrary +number of arguments. The return value of the \fByieldto\fR call will be the +list of arguments passed to the context command; it is up to the caller to +decide what to do with those values. +.PP +The recommended way of writing a version of \fByield\fR that allows resumption +with multiple arguments is by using \fByieldto\fR and the \fBreturn\fR +command, like this: +.PP +.CS +proc yieldm {value} { + \fByieldto\fR return -level 0 $value +} +.CE +.VE TIP396 +.PP The coroutine can also be deleted by destroying the command \fIname\fR, and the name of the current coroutine can be retrieved by using \fBinfo coroutine\fR. @@ -108,6 +137,27 @@ for {set i 1} {$i <= 20} {incr i} { puts "prime#$i = [\fIeratosthenes\fR]" } .CE +.PP +.VS TIP396 +This example shows how a value can be passed around a group of three +coroutines that yield to each other: +.PP +.CS +proc juggler {name target {value ""}} { + if {$value eq ""} { + set value [\fByield\fR [info coroutine]] + } + while {$value ne ""} { + puts "$name : $value" + set value [string range $value 0 end-1] + lassign [\fByieldto\fR $target $value] value + } +} +\fBcoroutine\fR j1 juggler Larry [ + \fBcoroutine\fR j2 juggler Curly [ + \fBcoroutine\fR j3 juggler Moe j1]] "Nyuck!Nyuck!Nyuck!" +.CE +.VE TIP396 .SS "DETAILED SEMANTICS" .PP This example demonstrates that coroutines start from the global namespace, and diff --git a/generic/tcl.decls b/generic/tcl.decls index bb9f71e..c6cbe96 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2311,7 +2311,7 @@ declare 627 { Tcl_LoadHandle *handlePtr) } declare 628 { - void* Tcl_FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle handle, + void *Tcl_FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol) } declare 629 { diff --git a/generic/tclBasic.c b/generic/tclBasic.c index c07fa70..280290c 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -258,6 +258,7 @@ static const CmdInfo builtInCmds[] = { {"variable", Tcl_VariableObjCmd, TclCompileVariableCmd, NULL, 1}, {"while", Tcl_WhileObjCmd, TclCompileWhileCmd, TclNRWhileObjCmd, 1}, {"yield", NULL, NULL, TclNRYieldObjCmd, 1}, + {"yieldto", NULL, NULL, TclNRYieldToObjCmd, 1}, /* * Commands in the OS-interface. Note that many of these are unsafe. @@ -830,10 +831,6 @@ Tcl_CreateInterp(void) TclNRAssembleObjCmd, NULL, NULL); cmdPtr->compileProc = &TclCompileAssembleCmd; - Tcl_NRCreateCommand(interp, "::tcl::unsupported::yieldTo", NULL, - TclNRYieldToObjCmd, NULL, NULL); - Tcl_NRCreateCommand(interp, "::tcl::unsupported::yieldm", NULL, - TclNRYieldObjCmd, INT2PTR(CORO_ACTIVATE_YIELDM), NULL); Tcl_NRCreateCommand(interp, "::tcl::unsupported::inject", NULL, NRCoroInjectObjCmd, NULL, NULL); @@ -8511,7 +8508,7 @@ TclNRYieldToObjCmd( } if (!corPtr) { - Tcl_SetResult(interp, "yieldTo can only be called in a coroutine", + Tcl_SetResult(interp, "yieldto can only be called in a coroutine", TCL_STATIC); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL); return TCL_ERROR; @@ -8529,7 +8526,7 @@ TclNRYieldToObjCmd( nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1); if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr)) || (nsPtr != ns1Ptr)) { - Tcl_Panic("yieldTo failed to find the proper namespace"); + Tcl_Panic("yieldto failed to find the proper namespace"); } Tcl_IncrRefCount(nsObjPtr); @@ -8542,7 +8539,7 @@ TclNRYieldToObjCmd( NULL); iPtr->execEnvPtr = corPtr->eePtr; - return TclNRYieldObjCmd(clientData, interp, 1, objv); + return TclNRYieldObjCmd(INT2PTR(CORO_ACTIVATE_YIELDM), interp, 1, objv); } static int diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 1d6a866..0c1dedf 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1802,7 +1802,7 @@ EXTERN int Tcl_LoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 628 */ -EXTERN void* Tcl_FindSymbol(Tcl_Interp *interp, +EXTERN void * Tcl_FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 629 */ EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp, @@ -2472,7 +2472,7 @@ typedef struct TclStubs { int (*tcl_NRExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *resultPtr); /* 625 */ int (*tcl_NRSubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 626 */ int (*tcl_LoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 627 */ - void* (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ + void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void* (*tcl_ZlibStreamGetZstreamp) (Tcl_ZlibStream zshandle); /* 630 */ } TclStubs; diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 1283446..f33ad31 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -1823,11 +1823,6 @@ NsEnsembleImplementationCmdNR( * count both as inserted and removed arguments. */ -#if 0 - if (TclInitRewriteEnsemble(interp, 2 + ensemblePtr->numParameters, prefixObjc + ensemblePtr->numParameters, objv)) { - TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL); - } -#else if (iPtr->ensembleRewrite.sourceObjs == NULL) { iPtr->ensembleRewrite.sourceObjs = objv; iPtr->ensembleRewrite.numRemovedObjs = @@ -1848,7 +1843,6 @@ NsEnsembleImplementationCmdNR( iPtr->ensembleRewrite.numInsertedObjs += prefixObjc-2; } } -#endif /* * Hand off to the target command. diff --git a/generic/tclFileName.c b/generic/tclFileName.c index adfa2fd..b6b89dd 100644 --- a/generic/tclFileName.c +++ b/generic/tclFileName.c @@ -2160,67 +2160,6 @@ DoGlob( } /* - * This block of code is not exercised by the Tcl test suite as of Tcl - * 8.5a0. Simplifications to the calling paths suggest it may not be - * necessary any more, since path separators are handled elsewhere. It is - * left in place in case new bugs are reported. - */ - -#if 0 /* PROBABLY_OBSOLETE */ - /* - * Deal with path separators. - */ - - if (pathPtr == NULL) { - /* - * Length used to be the length of the prefix, and lastChar the - * lastChar of the prefix. But, none of this is used any more. - */ - - int length = 0; - char lastChar = 0; - - switch (tclPlatform) { - case TCL_PLATFORM_WINDOWS: - /* - * If this is a drive relative path, add the colon and the - * trailing slash if needed. Otherwise add the slash if this is - * the first absolute element, or a later relative element. Add an - * extra slash if this is a UNC path. - */ - - if (*name == ':') { - Tcl_DStringAppend(&append, ":", 1); - if (count > 1) { - Tcl_DStringAppend(&append, "/", 1); - } - } else if ((*pattern != '\0') && (((length > 0) - && (strchr(separators, lastChar) == NULL)) - || ((length == 0) && (count > 0)))) { - Tcl_DStringAppend(&append, "/", 1); - if ((length == 0) && (count > 1)) { - Tcl_DStringAppend(&append, "/", 1); - } - } - - break; - case TCL_PLATFORM_UNIX: - /* - * Add a separator if this is the first absolute element, or a - * later relative element. - */ - - if ((*pattern != '\0') && (((length > 0) - && (strchr(separators, lastChar) == NULL)) - || ((length == 0) && (count > 0)))) { - Tcl_DStringAppend(&append, "/", 1); - } - break; - } - } -#endif /* PROBABLY_OBSOLETE */ - - /* * Look for the first matching pair of braces or the first directory * separator that is not inside a pair of braces. */ @@ -2278,8 +2217,8 @@ DoGlob( if (openBrace != NULL) { char *element; - Tcl_DString newName; + Tcl_DStringInit(&newName); /* @@ -2328,12 +2267,13 @@ DoGlob( */ if (*p != '\0') { + char savedChar = *p; + /* * Note that we are modifying the string in place. This won't work if * the string is a static. */ - char savedChar = *p; *p = '\0'; firstSpecialChar = strpbrk(pattern, "*[]?\\"); *p = savedChar; @@ -2398,6 +2338,7 @@ DoGlob( const char *bytes; int numBytes; Tcl_Obj *fixme, *newObj; + Tcl_ListObjIndex(NULL, matchesObj, repair, &fixme); bytes = Tcl_GetStringFromObj(fixme, &numBytes); newObj = Tcl_NewStringObj(bytes+2, numBytes-2); @@ -2418,6 +2359,9 @@ DoGlob( */ if (*p == '\0') { + int length; + Tcl_DString append; + /* * This is the code path reached by a command like 'glob foo'. * @@ -2430,9 +2374,6 @@ DoGlob( * approach). */ - int length; - Tcl_DString append; - Tcl_DStringInit(&append); Tcl_DStringAppend(&append, pattern, p-pattern); @@ -2453,15 +2394,6 @@ DoGlob( } } -#if defined(__CYGWIN__) && defined(__WIN32__) - { - char winbuf[MAX_PATH+1]; - - cygwin_conv_to_win32_path(Tcl_DStringValue(&append), winbuf); - Tcl_DStringFree(&append); - Tcl_DStringAppend(&append, winbuf, -1); - } -#endif /* __CYGWIN__ && __WIN32__ */ break; case TCL_PLATFORM_UNIX: @@ -2473,8 +2405,9 @@ DoGlob( } } #if defined(__CYGWIN__) && !defined(__WIN32__) - DLLIMPORT extern int cygwin_conv_to_posix_path(const char *, char *); { + DLLIMPORT extern int cygwin_conv_to_posix_path(const char *, + char *); char winbuf[MAXPATHLEN+1]; cygwin_conv_to_posix_path(Tcl_DStringValue(&append), winbuf); diff --git a/generic/tclHash.c b/generic/tclHash.c index c8dc939..90be511 100644 --- a/generic/tclHash.c +++ b/generic/tclHash.c @@ -46,7 +46,9 @@ static int CompareArrayKeys(void *keyPtr, Tcl_HashEntry *hPtr); static unsigned int HashArrayKey(Tcl_HashTable *tablePtr, void *keyPtr); /* - * Prototypes for the one word hash key methods. + * Prototypes for the one word hash key methods. Not actually declared because + * this is a critical path that is implemented in the core hash table access + * function. */ #if 0 diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index 768428f..7b7b647 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -87,30 +87,29 @@ TclSockGetPort( *---------------------------------------------------------------------- */ -#ifdef _WIN32 -# define PTR2SOCK(a) (SOCKET)a -#else -# define PTR2SOCK(a) PTR2INT(a) +#ifndef _WIN32 +# define SOCKET size_t #endif + int TclSockMinimumBuffers( - ClientData sock, /* Socket file descriptor */ + void *sock, /* Socket file descriptor */ int size) /* Minimum buffer size */ { int current; socklen_t len; len = sizeof(int); - getsockopt(PTR2SOCK(sock), SOL_SOCKET, SO_SNDBUF, (char *)¤t, &len); + getsockopt((SOCKET)sock, SOL_SOCKET, SO_SNDBUF, (char *)¤t, &len); if (current < size) { len = sizeof(int); - setsockopt(PTR2SOCK(sock), SOL_SOCKET, SO_SNDBUF, (char *)&size, len); + setsockopt((SOCKET)sock, SOL_SOCKET, SO_SNDBUF, (char *)&size, len); } len = sizeof(int); - getsockopt(PTR2SOCK(sock), SOL_SOCKET, SO_RCVBUF, (char *)¤t, &len); + getsockopt((SOCKET)sock, SOL_SOCKET, SO_RCVBUF, (char *)¤t, &len); if (current < size) { len = sizeof(int); - setsockopt(PTR2SOCK(sock), SOL_SOCKET, SO_RCVBUF, (char *)&size, len); + setsockopt((SOCKET)sock, SOL_SOCKET, SO_RCVBUF, (char *)&size, len); } return TCL_OK; } @@ -178,6 +177,7 @@ TclCreateSocketAddress( } hints.ai_socktype = SOCK_STREAM; + #if 0 /* * We found some problems when using AI_ADDRCONFIG, e.g. on systems that @@ -185,15 +185,16 @@ TclCreateSocketAddress( * localhost. See bugs 3385024, 3382419, 3382431. As the advantage of * using AI_ADDRCONFIG in situations where it works, is probably low, * we'll leave it out for now. After all, it is just an optimisation. - */ -#if defined(AI_ADDRCONFIG) && !defined(_AIX) && !defined(__hpux) - /* + * * Missing on: OpenBSD, NetBSD. * Causes failure when used on AIX 5.1 and HP-UX */ + +#if defined(AI_ADDRCONFIG) && !defined(_AIX) && !defined(__hpux) hints.ai_flags |= AI_ADDRCONFIG; -#endif -#endif +#endif /* AI_ADDRCONFIG && !_AIX && !__hpux */ +#endif /* 0 */ + if (willBind) { hints.ai_flags |= AI_PASSIVE; } diff --git a/generic/tclInt.decls b/generic/tclInt.decls index cb01b22..ff4afea 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -126,8 +126,8 @@ declare 25 { # } # Removed in 8.5 #declare 27 { -# int TclGetDate(char *p, unsigned long now, long zone, -# unsigned long *timePtr) +# int TclGetDate(char *p, Tcl_WideInt now, long zone, +# Tcl_WideInt *timePtr) #} declare 28 { Tcl_Channel TclpGetDefaultStdChannel(int type) @@ -420,7 +420,10 @@ declare 103 { int *portPtr) } declare 104 { - int TclSockMinimumBuffers(ClientData sock, int size) + int TclSockMinimumBuffersOld(int sock, int size) +} +declare 110 { + int TclSockMinimumBuffers(void *sock, int size) } # Replaced by Tcl_FSStat in 8.4: #declare 105 { @@ -735,16 +738,6 @@ declare 177 { # Tcl_Obj *Tcl_GetStartupScript(const char **encodingNamePtr) #} -# REMOVED -# Allocate lists without copying arrays -# declare 180 { -# Tcl_Obj *TclNewListObjDirect(int objc, Tcl_Obj **objv) -# } -#declare 181 { -# Tcl_Obj *TclDbNewListObjDirect(int objc, Tcl_Obj **objv, -# const char *file, int line) -#} - # TclpGmtime and TclpLocaltime promoted to the generic interface from unix declare 182 { @@ -995,8 +988,8 @@ declare 248 { } declare 249 { - char* TclDoubleDigits(double dv, int ndigits, int flags, - int* decpt, int* signum, char** endPtr) + char *TclDoubleDigits(double dv, int ndigits, int flags, + int *decpt, int *signum, char **endPtr) } # TIP #285: Script cancellation support. declare 250 { @@ -1025,7 +1018,7 @@ declare 2 win { } declare 3 win { int TclWinGetSockOpt(SOCKET s, int level, int optname, - char FAR *optval, int FAR *optlen) + char *optval, int *optlen) } declare 4 win { HINSTANCE TclWinGetTclInstance(void) @@ -1039,7 +1032,7 @@ declare 6 win { } declare 7 win { int TclWinSetSockOpt(SOCKET s, int level, int optname, - const char FAR *optval, int optlen) + const char *optval, int optlen) } declare 8 win { unsigned long TclpGetPid(Tcl_Pid pid) @@ -1149,7 +1142,7 @@ declare 3 unix { } # On non-cygwin, this is actually a reference to TclpCreateProcess declare 4 unix { - int TclWinGetTclInstance(void) + void *TclWinGetTclInstance(void) } # Signature changed in 8.1: # declare 5 unix { @@ -1162,7 +1155,7 @@ declare 6 unix { } # On non-cygwin, this is actually a reference to TclpOpenFile declare 7 unix { - int TclWinSetSockOpt(int s, int level, int optname, + int TclWinSetSockOpt(void *s, int level, int optname, const char *optval, int optlen) } declare 8 unix { @@ -1229,14 +1222,11 @@ declare 19 {unix macosx} { void TclMacOSXNotifierAddRunLoopMode(const void *runLoopMode) } declare 20 unix { - void TclWinAddProcess(void *hProcess, unsigned long id) + void TclWinAddProcess(void *hProcess, unsigned int id) } declare 22 unix { TclFile TclpCreateTempFile(const char *contents) } -declare 23 unix { - char *TclpGetTZName(int isdst) -} declare 24 unix { char *TclWinNoBackslash(char *path) } diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index b294e4f..f74cc26 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -263,7 +263,7 @@ EXTERN void TclSetupEnv(Tcl_Interp *interp); EXTERN int TclSockGetPort(Tcl_Interp *interp, const char *str, const char *proto, int *portPtr); /* 104 */ -EXTERN int TclSockMinimumBuffers(ClientData sock, int size); +EXTERN int TclSockMinimumBuffersOld(int sock, int size); /* Slot 105 is reserved */ /* Slot 106 is reserved */ /* Slot 107 is reserved */ @@ -271,7 +271,8 @@ EXTERN int TclSockMinimumBuffers(ClientData sock, int size); EXTERN void TclTeardownNamespace(Namespace *nsPtr); /* 109 */ EXTERN int TclUpdateReturnInfo(Interp *iPtr); -/* Slot 110 is reserved */ +/* 110 */ +EXTERN int TclSockMinimumBuffers(void *sock, int size); /* 111 */ EXTERN void Tcl_AddInterpResolvers(Tcl_Interp *interp, const char *name, @@ -596,8 +597,8 @@ EXTERN int TclCopyChannel(Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, Tcl_WideInt toRead, Tcl_Obj *cmdPtr); /* 249 */ -EXTERN char* TclDoubleDigits(double dv, int ndigits, int flags, - int*decpt, int*signum, char**endPtr); +EXTERN char * TclDoubleDigits(double dv, int ndigits, int flags, + int *decpt, int *signum, char **endPtr); /* 250 */ EXTERN void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags, int force); @@ -710,13 +711,13 @@ typedef struct TclIntStubs { CONST86 char * (*tclSetPreInitScript) (const char *string); /* 101 */ void (*tclSetupEnv) (Tcl_Interp *interp); /* 102 */ int (*tclSockGetPort) (Tcl_Interp *interp, const char *str, const char *proto, int *portPtr); /* 103 */ - int (*tclSockMinimumBuffers) (ClientData sock, int size); /* 104 */ + int (*tclSockMinimumBuffersOld) (int sock, int size); /* 104 */ void (*reserved105)(void); void (*reserved106)(void); void (*reserved107)(void); void (*tclTeardownNamespace) (Namespace *nsPtr); /* 108 */ int (*tclUpdateReturnInfo) (Interp *iPtr); /* 109 */ - void (*reserved110)(void); + int (*tclSockMinimumBuffers) (void *sock, int size); /* 110 */ void (*tcl_AddInterpResolvers) (Tcl_Interp *interp, const char *name, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); /* 111 */ int (*tcl_AppendExportList) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *objPtr); /* 112 */ Tcl_Namespace * (*tcl_CreateNamespace) (Tcl_Interp *interp, const char *name, ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc); /* 113 */ @@ -855,7 +856,7 @@ typedef struct TclIntStubs { int (*tclInitRewriteEnsemble) (Tcl_Interp *interp, int numRemoved, int numInserted, Tcl_Obj *const *objv); /* 246 */ void (*tclResetRewriteEnsemble) (Tcl_Interp *interp, int isRootEnsemble); /* 247 */ int (*tclCopyChannel) (Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, Tcl_WideInt toRead, Tcl_Obj *cmdPtr); /* 248 */ - char* (*tclDoubleDigits) (double dv, int ndigits, int flags, int*decpt, int*signum, char**endPtr); /* 249 */ + char * (*tclDoubleDigits) (double dv, int ndigits, int flags, int *decpt, int *signum, char **endPtr); /* 249 */ void (*tclSetSlaveCancelFlags) (Tcl_Interp *interp, int flags, int force); /* 250 */ } TclIntStubs; @@ -1034,8 +1035,8 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclSetupEnv) /* 102 */ #define TclSockGetPort \ (tclIntStubsPtr->tclSockGetPort) /* 103 */ -#define TclSockMinimumBuffers \ - (tclIntStubsPtr->tclSockMinimumBuffers) /* 104 */ +#define TclSockMinimumBuffersOld \ + (tclIntStubsPtr->tclSockMinimumBuffersOld) /* 104 */ /* Slot 105 is reserved */ /* Slot 106 is reserved */ /* Slot 107 is reserved */ @@ -1043,7 +1044,8 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclTeardownNamespace) /* 108 */ #define TclUpdateReturnInfo \ (tclIntStubsPtr->tclUpdateReturnInfo) /* 109 */ -/* Slot 110 is reserved */ +#define TclSockMinimumBuffers \ + (tclIntStubsPtr->tclSockMinimumBuffers) /* 110 */ #define Tcl_AddInterpResolvers \ (tclIntStubsPtr->tcl_AddInterpResolvers) /* 111 */ #define Tcl_AppendExportList \ diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index 5d3e2ab..a222403 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -58,12 +58,12 @@ EXTERN Tcl_Channel TclpCreateCommandChannel(TclFile readFile, /* 3 */ EXTERN int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe); /* 4 */ -EXTERN int TclWinGetTclInstance(void); +EXTERN void * TclWinGetTclInstance(void); /* Slot 5 is reserved */ /* 6 */ EXTERN unsigned short TclWinNToHS(unsigned short ns); /* 7 */ -EXTERN int TclWinSetSockOpt(int s, int level, int optname, +EXTERN int TclWinSetSockOpt(void *s, int level, int optname, const char *optval, int optlen); /* 8 */ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout); @@ -96,12 +96,11 @@ EXTERN int TclMacOSXMatchType(Tcl_Interp *interp, EXTERN void TclMacOSXNotifierAddRunLoopMode( const void *runLoopMode); /* 20 */ -EXTERN void TclWinAddProcess(void *hProcess, unsigned long id); +EXTERN void TclWinAddProcess(void *hProcess, unsigned int id); /* Slot 21 is reserved */ /* 22 */ EXTERN TclFile TclpCreateTempFile(const char *contents); -/* 23 */ -EXTERN char * TclpGetTZName(int isdst); +/* Slot 23 is reserved */ /* 24 */ EXTERN char * TclWinNoBackslash(char *path); /* Slot 25 is reserved */ @@ -129,7 +128,7 @@ EXTERN struct servent * TclWinGetServByName(const char *nm, const char *proto); /* 3 */ EXTERN int TclWinGetSockOpt(SOCKET s, int level, int optname, - char FAR *optval, int FAR *optlen); + char *optval, int *optlen); /* 4 */ EXTERN HINSTANCE TclWinGetTclInstance(void); /* Slot 5 is reserved */ @@ -137,7 +136,7 @@ EXTERN HINSTANCE TclWinGetTclInstance(void); EXTERN u_short TclWinNToHS(u_short ns); /* 7 */ EXTERN int TclWinSetSockOpt(SOCKET s, int level, int optname, - const char FAR *optval, int optlen); + const char *optval, int optlen); /* 8 */ EXTERN unsigned long TclpGetPid(Tcl_Pid pid); /* 9 */ @@ -196,12 +195,12 @@ EXTERN Tcl_Channel TclpCreateCommandChannel(TclFile readFile, /* 3 */ EXTERN int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe); /* 4 */ -EXTERN int TclWinGetTclInstance(void); +EXTERN void * TclWinGetTclInstance(void); /* Slot 5 is reserved */ /* 6 */ EXTERN unsigned short TclWinNToHS(unsigned short ns); /* 7 */ -EXTERN int TclWinSetSockOpt(int s, int level, int optname, +EXTERN int TclWinSetSockOpt(void *s, int level, int optname, const char *optval, int optlen); /* 8 */ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout); @@ -240,12 +239,11 @@ EXTERN int TclMacOSXMatchType(Tcl_Interp *interp, EXTERN void TclMacOSXNotifierAddRunLoopMode( const void *runLoopMode); /* 20 */ -EXTERN void TclWinAddProcess(void *hProcess, unsigned long id); +EXTERN void TclWinAddProcess(void *hProcess, unsigned int id); /* Slot 21 is reserved */ /* 22 */ EXTERN TclFile TclpCreateTempFile(const char *contents); -/* 23 */ -EXTERN char * TclpGetTZName(int isdst); +/* Slot 23 is reserved */ /* 24 */ EXTERN char * TclWinNoBackslash(char *path); /* Slot 25 is reserved */ @@ -273,10 +271,10 @@ typedef struct TclIntPlatStubs { void (*tclWinConvertWSAError) (unsigned int errCode); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ - int (*tclWinGetTclInstance) (void); /* 4 */ + void * (*tclWinGetTclInstance) (void); /* 4 */ void (*reserved5)(void); unsigned short (*tclWinNToHS) (unsigned short ns); /* 6 */ - int (*tclWinSetSockOpt) (int s, int level, int optname, const char *optval, int optlen); /* 7 */ + int (*tclWinSetSockOpt) (void *s, int level, int optname, const char *optval, int optlen); /* 7 */ int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */ int (*tclWinGetPlatformId) (void); /* 9 */ Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */ @@ -289,10 +287,10 @@ typedef struct TclIntPlatStubs { void (*reserved17)(void); int (*tclMacOSXMatchType) (Tcl_Interp *interp, const char *pathName, const char *fileName, Tcl_StatBuf *statBufPtr, Tcl_GlobTypeData *types); /* 18 */ void (*tclMacOSXNotifierAddRunLoopMode) (const void *runLoopMode); /* 19 */ - void (*tclWinAddProcess) (void *hProcess, unsigned long id); /* 20 */ + void (*tclWinAddProcess) (void *hProcess, unsigned int id); /* 20 */ void (*reserved21)(void); TclFile (*tclpCreateTempFile) (const char *contents); /* 22 */ - char * (*tclpGetTZName) (int isdst); /* 23 */ + void (*reserved23)(void); char * (*tclWinNoBackslash) (char *path); /* 24 */ void (*reserved25)(void); void (*tclWinSetInterfaces) (int wide); /* 26 */ @@ -306,11 +304,11 @@ typedef struct TclIntPlatStubs { void (*tclWinConvertError) (DWORD errCode); /* 0 */ void (*tclWinConvertWSAError) (DWORD errCode); /* 1 */ struct servent * (*tclWinGetServByName) (const char *nm, const char *proto); /* 2 */ - int (*tclWinGetSockOpt) (SOCKET s, int level, int optname, char FAR *optval, int FAR *optlen); /* 3 */ + int (*tclWinGetSockOpt) (SOCKET s, int level, int optname, char *optval, int *optlen); /* 3 */ HINSTANCE (*tclWinGetTclInstance) (void); /* 4 */ void (*reserved5)(void); u_short (*tclWinNToHS) (u_short ns); /* 6 */ - int (*tclWinSetSockOpt) (SOCKET s, int level, int optname, const char FAR *optval, int optlen); /* 7 */ + int (*tclWinSetSockOpt) (SOCKET s, int level, int optname, const char *optval, int optlen); /* 7 */ unsigned long (*tclpGetPid) (Tcl_Pid pid); /* 8 */ int (*tclWinGetPlatformId) (void); /* 9 */ void (*reserved10)(void); @@ -339,10 +337,10 @@ typedef struct TclIntPlatStubs { void (*tclWinConvertWSAError) (unsigned int errCode); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */ int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */ - int (*tclWinGetTclInstance) (void); /* 4 */ + void * (*tclWinGetTclInstance) (void); /* 4 */ void (*reserved5)(void); unsigned short (*tclWinNToHS) (unsigned short ns); /* 6 */ - int (*tclWinSetSockOpt) (int s, int level, int optname, const char *optval, int optlen); /* 7 */ + int (*tclWinSetSockOpt) (void *s, int level, int optname, const char *optval, int optlen); /* 7 */ int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */ int (*tclWinGetPlatformId) (void); /* 9 */ Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */ @@ -355,10 +353,10 @@ typedef struct TclIntPlatStubs { int (*tclMacOSXCopyFileAttributes) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr); /* 17 */ int (*tclMacOSXMatchType) (Tcl_Interp *interp, const char *pathName, const char *fileName, Tcl_StatBuf *statBufPtr, Tcl_GlobTypeData *types); /* 18 */ void (*tclMacOSXNotifierAddRunLoopMode) (const void *runLoopMode); /* 19 */ - void (*tclWinAddProcess) (void *hProcess, unsigned long id); /* 20 */ + void (*tclWinAddProcess) (void *hProcess, unsigned int id); /* 20 */ void (*reserved21)(void); TclFile (*tclpCreateTempFile) (const char *contents); /* 22 */ - char * (*tclpGetTZName) (int isdst); /* 23 */ + void (*reserved23)(void); char * (*tclWinNoBackslash) (char *path); /* 24 */ void (*reserved25)(void); void (*tclWinSetInterfaces) (int wide); /* 26 */ @@ -427,8 +425,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; /* Slot 21 is reserved */ #define TclpCreateTempFile \ (tclIntPlatStubsPtr->tclpCreateTempFile) /* 22 */ -#define TclpGetTZName \ - (tclIntPlatStubsPtr->tclpGetTZName) /* 23 */ +/* Slot 23 is reserved */ #define TclWinNoBackslash \ (tclIntPlatStubsPtr->tclWinNoBackslash) /* 24 */ /* Slot 25 is reserved */ @@ -546,8 +543,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; /* Slot 21 is reserved */ #define TclpCreateTempFile \ (tclIntPlatStubsPtr->tclpCreateTempFile) /* 22 */ -#define TclpGetTZName \ - (tclIntPlatStubsPtr->tclpGetTZName) /* 23 */ +/* Slot 23 is reserved */ #define TclWinNoBackslash \ (tclIntPlatStubsPtr->tclWinNoBackslash) /* 24 */ /* Slot 25 is reserved */ @@ -573,6 +569,9 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; #define TCL_STORAGE_CLASS DLLIMPORT #undef TclpLocaltime_unix #undef TclpGmtime_unix +#undef TclWinConvertWSAError +#define TclWinConvertWSAError TclWinConvertError + #if !defined(__WIN32__) && defined(USE_TCL_STUBS) # ifdef __CYGWIN__ diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 202e66a..008a99d 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -873,40 +873,10 @@ Tcl_UnloadObjCmd( done: Tcl_DStringFree(&pkgName); Tcl_DStringFree(&tmp); - if (!complain && code!=TCL_OK) { + if (!complain && (code != TCL_OK)) { code = TCL_OK; Tcl_ResetResult(interp); } - if (code == TCL_OK) { -#if 0 - /* - * Result of [unload] was not documented in TIP#100, so force to be - * the empty string by commenting this out. DKF. - */ - - Tcl_Obj *resultObjPtr, *objPtr[2]; - - /* - * Our result is the two reference counts. - */ - - TclNewIntObj(objPtr[0], trustedRefCount); - TclNewIntObj(objPtr[1], safeRefCount); - if (objPtr[0] == NULL || objPtr[1] == NULL) { - if (objPtr[0]) { - Tcl_DecrRefCount(objPtr[0]); - } - if (objPtr[1]) { - Tcl_DecrRefCount(objPtr[1]); - } - } else { - TclNewListObj(resultObjPtr, 2, objPtr); - if (resultObjPtr != NULL) { - Tcl_SetObjResult(interp, resultObjPtr); - } - } -#endif - } return code; } diff --git a/generic/tclOO.c b/generic/tclOO.c index 9dd8162..1d1276d 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -1624,6 +1624,15 @@ Tcl_NewObjectInstance( state = Tcl_SaveInterpState(interp, TCL_OK); contextPtr->callPtr->flags |= CONSTRUCTOR; contextPtr->skip = skip; + + /* + * Adjust the ensmble tracking record if necessary. [Bug 3514761] + */ + + if (((Interp*) interp)->ensembleRewrite.sourceObjs) { + ((Interp*) interp)->ensembleRewrite.numInsertedObjs += skip-1; + ((Interp*) interp)->ensembleRewrite.numRemovedObjs += skip-1; + } result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr, objc, objv); @@ -1742,6 +1751,15 @@ TclNRNewObjectInstance( contextPtr->skip = skip; /* + * Adjust the ensmble tracking record if necessary. [Bug 3514761] + */ + + if (((Interp *) interp)->ensembleRewrite.sourceObjs) { + ((Interp *) interp)->ensembleRewrite.numInsertedObjs += skip - 1; + ((Interp *) interp)->ensembleRewrite.numRemovedObjs += skip - 1; + } + + /* * Fire off the constructors non-recursively. */ @@ -2050,6 +2068,7 @@ Tcl_CopyObjectInstance( } } + TclResetRewriteEnsemble(interp, 1); contextPtr = TclOOGetCallContext(o2Ptr, oPtr->fPtr->clonedName, 0, NULL); if (contextPtr) { args[0] = TclOOObjectName(interp, o2Ptr); @@ -2064,6 +2083,10 @@ Tcl_CopyObjectInstance( TclDecrRefCount(args[1]); TclDecrRefCount(args[2]); TclOODeleteContext(contextPtr); + if (result == TCL_ERROR) { + Tcl_AddErrorInfo(interp, + "\n (while performing post-copy callback)"); + } if (result != TCL_OK) { Tcl_DeleteCommandFromToken(interp, o2Ptr->command); return NULL; diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 2d6f324..7988452 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -381,21 +381,6 @@ typedef struct CallContext { #define DESTRUCTOR 0x10 /* This is a destructor. */ /* - * Assorted flags for call frames. Note that bits 1 and 2 are already taken by - * Tcl itself. - */ - -#if 0 -#define FRAME_IS_METHOD 0x4 /* The frame is a method body, and the frame's - * clientData field contains a CallContext - * reference. */ -#define FRAME_IS_OO_DEFINE 0x8 /* The frame is part of the inside workings of - * the [oo::define] command; the clientData - * field contains an Object reference that has - * been confirmed to refer to a class. */ -#endif - -/* * Structure containing definition information about basic class methods. */ diff --git a/generic/tclPanic.c b/generic/tclPanic.c index 2cb8aff..84a9136 100644 --- a/generic/tclPanic.c +++ b/generic/tclPanic.c @@ -14,7 +14,7 @@ */ #include "tclInt.h" -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) MODULE_SCOPE void tclWinDebugPanic(const char *format, ...); #endif @@ -23,7 +23,11 @@ * procedure. */ +#if defined(__CYGWIN__) +static Tcl_PanicProc *panicProc = tclWinDebugPanic; +#else static Tcl_PanicProc *panicProc = NULL; +#endif /* *---------------------------------------------------------------------- @@ -45,7 +49,7 @@ void Tcl_SetPanicProc( Tcl_PanicProc *proc) { -#ifdef _WIN32 +#if defined(_WIN32) /* tclWinDebugPanic only installs if there is no panicProc yet. */ if ((proc != tclWinDebugPanic) || (panicProc == NULL)) #endif @@ -100,7 +104,7 @@ Tcl_PanicVA( fflush(stderr); } /* In case the users panic proc does not abort, we do it here */ -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) # if defined(__GNUC__) __builtin_trap(); # elif defined(_WIN64) @@ -110,6 +114,8 @@ Tcl_PanicVA( # else DebugBreak(); # endif +#endif +#if defined(_WIN32) ExitProcess(1); #else abort(); diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index 7ab8a4e..ba07808 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -2346,9 +2346,6 @@ SetFsPathFromAny( FsPath *fsPathPtr; Tcl_Obj *transPtr; char *name; -#if defined(__CYGWIN__) && defined(__WIN32__) - int copied = 0; -#endif ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); if (pathPtr->typePtr == &tclFsPathType) { @@ -2496,30 +2493,6 @@ SetFsPathFromAny( transPtr = TclJoinPath(1, &pathPtr); } -#if defined(__CYGWIN__) && defined(__WIN32__) - { - char winbuf[MAX_PATH+1]; - - /* - * In the Cygwin world, call conv_to_win32_path in order to use the - * mount table to translate the file name into something Windows will - * understand. Take care when converting empty strings! - */ - - name = Tcl_GetStringFromObj(transPtr, &len); - if (len > 0) { - cygwin_conv_to_win32_path(name, winbuf); - TclWinNoBackslash(winbuf); - if (Tcl_IsShared(transPtr)) { - copied = 1; - transPtr = Tcl_DuplicateObj(transPtr); - Tcl_IncrRefCount(transPtr); - } - Tcl_SetStringObj(transPtr, winbuf, -1); - } - } -#endif /* __CYGWIN__ && __WIN32__ */ - /* * Now we have a translated filename in 'transPtr'. This will have forward * slashes on Windows, and will not contain any ~user sequences. @@ -2545,12 +2518,6 @@ SetFsPathFromAny( SETPATHOBJ(pathPtr, fsPathPtr); PATHFLAGS(pathPtr) = 0; pathPtr->typePtr = &tclFsPathType; -#if defined(__CYGWIN__) && defined(__WIN32__) - if (copied) { - Tcl_DecrRefCount(transPtr); - } -#endif - return TCL_OK; } diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index eec540c..3f2f929 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -39,19 +39,37 @@ #undef Tcl_CreateHashEntry #undef Tcl_Panic #undef Tcl_FindExecutable +#undef TclSockMinimumBuffers + +/* See bug 510001: TclSockMinimumBuffers needs plat imp */ +#ifdef _WIN64 +# define TclSockMinimumBuffersOld 0 +#else +#define TclSockMinimumBuffersOld sockMinimumBuffersOld +static int TclSockMinimumBuffersOld(sock, size) + int sock; + int size; +{ + return TclSockMinimumBuffers(INT2PTR(sock), size); +} +#endif #ifdef __CYGWIN__ +/* Trick, so we don't have to include <windows.h> here, which + * - b.t.w. - lacks this function anyway */ +#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 0x00000004 +int __stdcall GetModuleHandleExW(unsigned int, const char *, void *); + #define TclWinGetPlatformId winGetPlatformId #define Tcl_WinUtfToTChar winUtfToTChar #define Tcl_WinTCharToUtf winTCharToUtf #define TclWinGetTclInstance winGetTclInstance #define TclWinNToHS winNToHS #define TclWinSetSockOpt winSetSockOpt -#define TclWinAddProcess winAddProcess -#define TclpGetTZName pGetTZName #define TclWinNoBackslash winNoBackslash -#define TclWinSetInterfaces (void (*) _ANSI_ARGS_((int))) doNothing +#define TclWinSetInterfaces (void (*) (int)) doNothing +#define TclWinAddProcess (void (*) (void *, unsigned int)) doNothing #define TclWinFlushDirtyChannels doNothing #define TclWinResetInterfaces doNothing @@ -65,38 +83,25 @@ TclWinGetPlatformId() return 2; /* VER_PLATFORM_WIN32_NT */; } -static int TclWinGetTclInstance() +static void *TclWinGetTclInstance() { - Tcl_Panic("TclWinGetTclInstance not yet implemented for CYGWIN"); - return 0; + void *hInstance = NULL; + GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (const char *)&winTCharEncoding, &hInstance); + return hInstance; } static unsigned short TclWinNToHS(unsigned short ns) { - Tcl_Panic("TclWinNToHS not yet implemented for CYGWIN"); - return (unsigned short) -1; + return ntohs(ns); } + static int -TclWinSetSockOpt(int s, int level, int optname, +TclWinSetSockOpt(void *s, int level, int optname, const char *optval, int optlen) { - Tcl_Panic("TclWinSetSockOpt not yet implemented for CYGWIN"); - return -1; -} - -static void -TclWinAddProcess(void *hProcess, unsigned long id) -{ - Tcl_Panic("TclWinAddProcess not yet implemented for CYGWIN"); -} - -static char * -TclpGetTZName(int isdst) -{ - /* TODO: implementation */ - Tcl_Panic("TclpGetTZName not yet implemented for CYGWIN"); - return 0; + return setsockopt((int) s, level, optname, optval, optlen); } static char * @@ -158,13 +163,13 @@ Tcl_WinTCharToUtf( #elif !defined(__WIN32__) /* UNIX and MAC */ # define TclWinConvertError (void (*) _ANSI_ARGS_((unsigned int))) TclGetAndDetachPids +# undef TclWinConvertWSAError # define TclWinConvertWSAError (void (*) _ANSI_ARGS_((unsigned int))) TclpCloseFile # define TclWinGetPlatformId (int (*)()) TclpCreateTempFile -# define TclWinGetTclInstance (int (*)()) TclpCreateProcess +# define TclWinGetTclInstance (void *(*)()) TclpCreateProcess # define TclWinNToHS (unsigned short (*) _ANSI_ARGS_((unsigned short ns))) TclpMakeFile -# define TclWinSetSockOpt (int (*) _ANSI_ARGS_((int, int, int, const char *, int))) TclpOpenFile +# define TclWinSetSockOpt (int (*) _ANSI_ARGS_((void *, int, int, const char *, int))) TclpOpenFile # define TclWinAddProcess 0 -# define TclpGetTZName 0 # define TclWinNoBackslash 0 # define TclWinSetInterfaces 0 # define TclWinFlushDirtyChannels 0 @@ -298,13 +303,13 @@ static const TclIntStubs tclIntStubs = { TclSetPreInitScript, /* 101 */ TclSetupEnv, /* 102 */ TclSockGetPort, /* 103 */ - TclSockMinimumBuffers, /* 104 */ + TclSockMinimumBuffersOld, /* 104 */ 0, /* 105 */ 0, /* 106 */ 0, /* 107 */ TclTeardownNamespace, /* 108 */ TclUpdateReturnInfo, /* 109 */ - 0, /* 110 */ + TclSockMinimumBuffers, /* 110 */ Tcl_AddInterpResolvers, /* 111 */ Tcl_AppendExportList, /* 112 */ Tcl_CreateNamespace, /* 113 */ @@ -474,7 +479,7 @@ static const TclIntPlatStubs tclIntPlatStubs = { TclWinAddProcess, /* 20 */ 0, /* 21 */ TclpCreateTempFile, /* 22 */ - TclpGetTZName, /* 23 */ + 0, /* 23 */ TclWinNoBackslash, /* 24 */ 0, /* 25 */ TclWinSetInterfaces, /* 26 */ @@ -540,7 +545,7 @@ static const TclIntPlatStubs tclIntPlatStubs = { TclWinAddProcess, /* 20 */ 0, /* 21 */ TclpCreateTempFile, /* 22 */ - TclpGetTZName, /* 23 */ + 0, /* 23 */ TclWinNoBackslash, /* 24 */ 0, /* 25 */ TclWinSetInterfaces, /* 26 */ diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index ad1d510..e4261d6 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -812,15 +812,7 @@ LockBucket( Cache *cachePtr, int bucket) { -#if 0 - if (Tcl_MutexTryLock(bucketInfo[bucket].lockPtr) != TCL_OK) { - Tcl_MutexLock(bucketInfo[bucket].lockPtr); - cachePtr->buckets[bucket].numWaits++; - sharedPtr->buckets[bucket].numWaits++; - } -#else Tcl_MutexLock(bucketInfo[bucket].lockPtr); -#endif cachePtr->buckets[bucket].numLocks++; sharedPtr->buckets[bucket].numLocks++; } diff --git a/generic/tclTomMath.decls b/generic/tclTomMath.decls index 29a6a03..ea3abb1 100644 --- a/generic/tclTomMath.decls +++ b/generic/tclTomMath.decls @@ -213,11 +213,11 @@ declare 60 { int TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c) } declare 61 { - int TclBN_mp_init_set_int(mp_int* a, unsigned long i) + int TclBN_mp_init_set_int(mp_int *a, unsigned long i) } declare 62 { - int TclBN_mp_set_int(mp_int* a, unsigned long i) + int TclBN_mp_set_int(mp_int *a, unsigned long i) } declare 63 { - int TclBN_mp_cnt_lsb(const mp_int* a) + int TclBN_mp_cnt_lsb(const mp_int *a) } diff --git a/generic/tclTomMathDecls.h b/generic/tclTomMathDecls.h index feaefb3..4f6c3bf 100644 --- a/generic/tclTomMathDecls.h +++ b/generic/tclTomMathDecls.h @@ -270,11 +270,11 @@ EXTERN int TclBN_s_mp_sqr(mp_int *a, mp_int *b); /* 60 */ EXTERN int TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c); /* 61 */ -EXTERN int TclBN_mp_init_set_int(mp_int*a, unsigned long i); +EXTERN int TclBN_mp_init_set_int(mp_int *a, unsigned long i); /* 62 */ -EXTERN int TclBN_mp_set_int(mp_int*a, unsigned long i); +EXTERN int TclBN_mp_set_int(mp_int *a, unsigned long i); /* 63 */ -EXTERN int TclBN_mp_cnt_lsb(const mp_int*a); +EXTERN int TclBN_mp_cnt_lsb(const mp_int *a); typedef struct TclTomMathStubs { int magic; @@ -341,9 +341,9 @@ typedef struct TclTomMathStubs { int (*tclBN_s_mp_mul_digs) (mp_int *a, mp_int *b, mp_int *c, int digs); /* 58 */ int (*tclBN_s_mp_sqr) (mp_int *a, mp_int *b); /* 59 */ int (*tclBN_s_mp_sub) (mp_int *a, mp_int *b, mp_int *c); /* 60 */ - int (*tclBN_mp_init_set_int) (mp_int*a, unsigned long i); /* 61 */ - int (*tclBN_mp_set_int) (mp_int*a, unsigned long i); /* 62 */ - int (*tclBN_mp_cnt_lsb) (const mp_int*a); /* 63 */ + int (*tclBN_mp_init_set_int) (mp_int *a, unsigned long i); /* 61 */ + int (*tclBN_mp_set_int) (mp_int *a, unsigned long i); /* 62 */ + int (*tclBN_mp_cnt_lsb) (const mp_int *a); /* 63 */ } TclTomMathStubs; #ifdef __cplusplus diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 6ce430b..a1c1996 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -4121,20 +4121,9 @@ TclReToGlob( *exactPtr = (anchorLeft && anchorRight); } -#if 0 - fprintf(stderr, "INPUT RE '%.*s' OUTPUT GLOB '%s' anchor %d:%d \n", - reStrLen, reStr, - Tcl_DStringValue(dsPtr), anchorLeft, anchorRight); - fflush(stderr); -#endif return TCL_OK; invalidGlob: -#if 0 - fprintf(stderr, "INPUT RE '%.*s' NO OUTPUT GLOB %s (%c)\n", - reStrLen, reStr, msg, *p); - fflush(stderr); -#endif if (interp != NULL) { Tcl_AppendResult(interp, msg, NULL); Tcl_SetErrorCode(interp, "TCL", "RE2GLOB", code, NULL); diff --git a/generic/tclVar.c b/generic/tclVar.c index 4df5d43..1bf4abc 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -762,7 +762,7 @@ TclObjLookupVarEx( } donePart1: -#if 0 +#if 0 /* ENABLE_NS_VARNAME_CACHING perhaps? */ if (varPtr == NULL) { if (flags & TCL_LEAVE_ERR_MSG) { part1 = TclGetString(part1Ptr); @@ -1892,7 +1892,7 @@ TclPtrSetVar( varPtr->value.objPtr = NULL; } if (flags & (TCL_APPEND_VALUE|TCL_LIST_ELEMENT)) { -#if 0 +#if 0 /* ENABLE_NS_VARNAME_CACHING perhaps? */ /* * Can't happen now! */ diff --git a/tests/coroutine.test b/tests/coroutine.test index 7d5169b..7f40a7b 100644 --- a/tests/coroutine.test +++ b/tests/coroutine.test @@ -557,12 +557,25 @@ test coroutine-6.3 {coroutine nargs} -body { } -cleanup { rename a {} } -returnCodes error -result {wrong # args: should be "a ?arg?"} -test coroutine-6.4 {unsupported: multi-argument yield} -body { + +test coroutine-7.1 {yieldto} -body { + coroutine c apply {{} { + yield + yieldto return -level 0 -code 1 quux + return quuy + }} + set res [list [catch c msg] $msg] + lappend res [catch c msg] $msg + lappend res [catch c msg] $msg +} -cleanup { + unset res +} -result [list 1 quux 0 quuy 1 {invalid command name "c"}] +test coroutine-7.2 {multi-argument yielding with yieldto} -body { proc corobody {} { set a 1 while 1 { set a [yield $a] - set a [::tcl::unsupported::yieldm $a] + set a [yieldto return -level 0 $a] lappend a [llength $a] } } @@ -573,20 +586,26 @@ test coroutine-6.4 {unsupported: multi-argument yield} -body { } -cleanup { rename corobody {} } -result {x {y z 2} \{p {\{q r 2} {} 0 {} ok {}} - -test coroutine-7.1 {yieldTo} -body { - coroutine c apply {{} { - yield - tcl::unsupported::yieldTo return -level 0 -code 1 quux - return quuy - }} - set res [list [catch c msg] $msg] - lappend res [catch c msg] $msg - lappend res [catch c msg] $msg +test coroutine-7.3 {yielding between coroutines} -body { + proc juggler {target {value ""}} { + if {$value eq ""} { + set value [yield [info coroutine]] + } + while {[llength $value]} { + lappend ::result $value [info coroutine] + set value [lrange $value 0 end-1] + lassign [yieldto $target $value] value + } + # Clear nested collection of coroutines + catch $target + } + set result "" + coroutine j1 juggler [coroutine j2 juggler [coroutine j3 juggler j1]]\ + {a b c d e} + list $result [info command j1] [info command j2] [info command j3] } -cleanup { - unset res -} -result [list 1 quux 0 quuy 1 {invalid command name "c"}] - + catch {rename juggler ""} +} -result {{{a b c d e} ::j1 {a b c d} ::j2 {a b c} ::j3 {a b} ::j1 a ::j2} {} {} {}} # cleanup unset lambda diff --git a/tests/oo.test b/tests/oo.test index 150bc97..8c5aeb3 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -337,6 +337,45 @@ test oo-2.6 {OO constructor and tailcall - Bug 2414858} -setup { } -cleanup { foo destroy } -result good +test oo-2.7 {construction, method calls and ensembles - Bug 3514761} -setup { + namespace eval k {} +} -body { + namespace eval k { + oo::class create s { + constructor {j} { + # nothing + } + } + namespace export s + namespace ensemble create + } + k s create X +} -returnCodes error -cleanup { + namespace delete k +} -result {wrong # args: should be "k s create X j"} +test oo-2.8 {construction, method calls and ensembles - Bug 3514761} -setup { + namespace eval k {} +} -body { + namespace eval k { + oo::class create s { + constructor {j} { + # nothing + } + } + oo::class create t { + superclass s + constructor args { + k next {*}$args + } + } + interp alias {} ::k::next {} ::oo::Helpers::next + namespace export t next + namespace ensemble create + } + k t create X +} -returnCodes error -cleanup { + namespace delete k +} -result {wrong # args: should be "k next j"} test oo-3.1 {basic test of OO functionality: destructor} -setup { # This is a bit complex because it needs to run in a sub-interp as we're @@ -1726,6 +1765,17 @@ test oo-15.8 {OO: intercept object cloning} -setup { } -cleanup { Foo destroy } -result {cloned ::foo ::bar check ::foo ok check ::bar ok} +test oo-15.9 {ensemble rewriting must not bleed through oo::copy} -setup { + oo::class create Foo +} -body { + oo::define Foo { + method <cloned> {a b} {} + } + interp alias {} Bar {} oo::copy [Foo create foo] + Bar bar +} -returnCodes error -cleanup { + Foo destroy +} -result {wrong # args: should be "::bar <cloned> a b"} test oo-16.1 {OO: object introspection} -body { info object diff --git a/unix/configure b/unix/configure index e737bd5..64ff7e6 100755 --- a/unix/configure +++ b/unix/configure @@ -7053,7 +7053,7 @@ fi CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; - CYGWIN_*) + CYGWIN_*|MINGW32*) SHLIB_CFLAGS="" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".dll" @@ -7064,6 +7064,69 @@ fi TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a' TCL_SHLIB_LD_EXTRAS='-Wl,--out-implib,$@.a' + echo "$as_me:$LINENO: checking for Cygwin version of gcc" >&5 +echo $ECHO_N "checking for Cygwin version of gcc... $ECHO_C" >&6 +if test "${ac_cv_cygwin+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #ifdef __CYGWIN__ + #error cygwin + #endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_cygwin=no +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_cygwin=yes +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5 +echo "${ECHO_T}$ac_cv_cygwin" >&6 + if test "$ac_cv_cygwin" = "no"; then + { { echo "$as_me:$LINENO: error: ${CC} is not a cygwin compiler." >&5 +echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;} + { (exit 1); exit 1; }; } + fi ;; dgux*) SHLIB_CFLAGS="-K PIC" @@ -9033,7 +9096,7 @@ fi case $system in AIX-*) ;; BSD/OS*) ;; - CYGWIN_*) ;; + CYGWIN_*|MINGW32_*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*|OpenBSD-*) ;; Darwin-*) ;; @@ -9131,6 +9194,75 @@ 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. + + echo "$as_me:$LINENO: checking for cast to union support" >&5 +echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6 +if test "${tcl_cv_cast_to_union+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + union foo { int i; double d; }; + union foo f = (union foo) (int) 0; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_cast_to_union=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cast_to_union=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5 +echo "${ECHO_T}$tcl_cv_cast_to_union" >&6 + if test "$tcl_cv_cast_to_union" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CAST_TO_UNION 1 +_ACEOF + + fi + # FIXME: This subst was left in only because the TCL_DL_LIBS # entry in tclConfig.sh uses it. It is not clear why someone # would use TCL_DL_LIBS instead of TCL_LIBS. @@ -14255,6 +14387,7 @@ _ACEOF # lack blkcnt_t. #-------------------------------------------------------------------- +if test "$ac_cv_cygwin" != "yes"; then echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5 echo $ECHO_N "checking for struct stat.st_blocks... $ECHO_C" >&6 if test "${ac_cv_member_struct_stat_st_blocks+set}" = set; then @@ -14474,6 +14607,7 @@ _ACEOF fi +fi echo "$as_me:$LINENO: checking for blkcnt_t" >&5 echo $ECHO_N "checking for blkcnt_t... $ECHO_C" >&6 if test "${ac_cv_type_blkcnt_t+set}" = set; then diff --git a/win/configure b/win/configure index 0ed0012..aa153a2 100755 --- a/win/configure +++ b/win/configure @@ -3043,729 +3043,6 @@ fi #-------------------------------------------------------------------- -# Perform additinal compiler tests. -#-------------------------------------------------------------------- - - -echo "$as_me:$LINENO: checking for SEH support in compiler" >&5 -echo $ECHO_N "checking for SEH support in compiler... $ECHO_C" >&6 -if test "${tcl_cv_seh+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - tcl_cv_seh=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN - -int main(int argc, char** argv) { - int a, b = 0; - __try { - a = 666 / b; - } - __except (EXCEPTION_EXECUTE_HANDLER) { - return 0; - } - return 1; -} - -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_seh=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -tcl_cv_seh=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - -fi -echo "$as_me:$LINENO: result: $tcl_cv_seh" >&5 -echo "${ECHO_T}$tcl_cv_seh" >&6 -if test "$tcl_cv_seh" = "no" ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_NO_SEH 1 -_ACEOF - -fi - -# -# Check to see if the excpt.h include file provided contains the -# definition for EXCEPTION_DISPOSITION; if not, which is the case -# with Cygwin's version as of 2002-04-10, define it to be int, -# sufficient for getting the current code to work. -# -echo "$as_me:$LINENO: checking for EXCEPTION_DISPOSITION support in include files" >&5 -echo $ECHO_N "checking for EXCEPTION_DISPOSITION support in include files... $ECHO_C" >&6 -if test "${tcl_cv_eh_disposition+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN - -int -main () -{ - - EXCEPTION_DISPOSITION x; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_eh_disposition=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_eh_disposition=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_eh_disposition" >&5 -echo "${ECHO_T}$tcl_cv_eh_disposition" >&6 -if test "$tcl_cv_eh_disposition" = "no" ; then - -cat >>confdefs.h <<\_ACEOF -#define EXCEPTION_DISPOSITION int -_ACEOF - -fi - - -# Check to see if the winsock2.h include file provided contains -# typedefs like LPFN_ACCEPT and friends. -# -echo "$as_me:$LINENO: checking for LPFN_ACCEPT support in winsock2.h" >&5 -echo $ECHO_N "checking for LPFN_ACCEPT support in winsock2.h... $ECHO_C" >&6 -if test "${tcl_cv_lpfn_decls+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#include <winsock2.h> - -int -main () -{ - - LPFN_ACCEPT accept; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_lpfn_decls=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_lpfn_decls=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_lpfn_decls" >&5 -echo "${ECHO_T}$tcl_cv_lpfn_decls" >&6 -if test "$tcl_cv_lpfn_decls" = "no" ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_NO_LPFN_DECLS 1 -_ACEOF - -fi - -# Check to see if winnt.h defines CHAR, SHORT, and LONG -# even if VOID has already been #defined. The win32api -# used by mingw and cygwin is known to do this. - -echo "$as_me:$LINENO: checking for winnt.h that ignores VOID define" >&5 -echo $ECHO_N "checking for winnt.h that ignores VOID define... $ECHO_C" >&6 -if test "${tcl_cv_winnt_ignore_void+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#define VOID void -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN - -int -main () -{ - - CHAR c; - SHORT s; - LONG l; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_winnt_ignore_void=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_winnt_ignore_void=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_winnt_ignore_void" >&5 -echo "${ECHO_T}$tcl_cv_winnt_ignore_void" >&6 -if test "$tcl_cv_winnt_ignore_void" = "yes" ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_WINNT_IGNORE_VOID 1 -_ACEOF - -fi - -# Check to see if malloc.h is missing the alloca function -# declaration. This is known to be a problem with Mingw. -# If we compiled without the function declaration, it -# would work but we would get a warning message from gcc. -# If we add the function declaration ourselves, it -# would not compile correctly because the _alloca -# function expects the argument to be passed in a -# register and not on the stack. Instead, we just -# call it from inline asm code. - -echo "$as_me:$LINENO: checking for alloca declaration in malloc.h" >&5 -echo $ECHO_N "checking for alloca declaration in malloc.h... $ECHO_C" >&6 -if test "${tcl_cv_malloc_decl_alloca+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include <malloc.h> - -int -main () -{ - - size_t arg = 0; - void* ptr; - ptr = alloca; - ptr = alloca(arg); - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_malloc_decl_alloca=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_malloc_decl_alloca=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_malloc_decl_alloca" >&5 -echo "${ECHO_T}$tcl_cv_malloc_decl_alloca" >&6 -if test "$tcl_cv_malloc_decl_alloca" = "no" && - test "${GCC}" = "yes" ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_ALLOCA_GCC_INLINE 1 -_ACEOF - -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. - -echo "$as_me:$LINENO: checking for cast to union support" >&5 -echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6 -if test "${tcl_cv_cast_to_union+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - union foo { int i; double d; }; - union foo f = (union foo) (int) 0; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_cast_to_union=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cast_to_union=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5 -echo "${ECHO_T}$tcl_cv_cast_to_union" >&6 -if test "$tcl_cv_cast_to_union" = "yes"; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_CAST_TO_UNION 1 -_ACEOF - -fi - -# See if declarations like FINDEX_INFO_LEVELS are -# missing from winbase.h. This is known to be -# a problem with VC++ 5.2. - -echo "$as_me:$LINENO: checking for FINDEX_INFO_LEVELS in winbase.h" >&5 -echo $ECHO_N "checking for FINDEX_INFO_LEVELS in winbase.h... $ECHO_C" >&6 -if test "${tcl_cv_findex_enums+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN - -int -main () -{ - - FINDEX_INFO_LEVELS i; - FINDEX_SEARCH_OPS j; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_findex_enums=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_findex_enums=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_findex_enums" >&5 -echo "${ECHO_T}$tcl_cv_findex_enums" >&6 -if test "$tcl_cv_findex_enums" = "no"; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_NO_FINDEX_ENUMS 1 -_ACEOF - -fi - -# See if MWMO_ALERTABLE is missing from winuser.h -# This is known to be a problem with Mingw. - -echo "$as_me:$LINENO: checking for MWMO_ALERTABLE in winuser.h" >&5 -echo $ECHO_N "checking for MWMO_ALERTABLE in winuser.h... $ECHO_C" >&6 -if test "${tcl_cv_mwmo_alertable+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN - -int -main () -{ - - int i = MWMO_ALERTABLE; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_mwmo_alertable=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_mwmo_alertable=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_mwmo_alertable" >&5 -echo "${ECHO_T}$tcl_cv_mwmo_alertable" >&6 -if test "$tcl_cv_mwmo_alertable" = "no"; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_NO_MWMO_ALERTABLE 1 -_ACEOF - -fi - -# See if the compiler supports intrinsics. - -echo "$as_me:$LINENO: checking for intrinsics support in compiler" >&5 -echo $ECHO_N "checking for intrinsics support in compiler... $ECHO_C" >&6 -if test "${tcl_cv_intrinsics+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#include <intrin.h> - -int -main () -{ - - __cpuidex(0,0,0); - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_intrinsics=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_intrinsics=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_cv_intrinsics" >&5 -echo "${ECHO_T}$tcl_cv_intrinsics" >&6 -if test "$tcl_cv_intrinsics" = "yes"; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_INTRIN_H 1 -_ACEOF - -fi - -# See if the <wspiapi.h> header file is present - -echo "$as_me:$LINENO: checking for wspiapi.h" >&5 -echo $ECHO_N "checking for wspiapi.h... $ECHO_C" >&6 -if test "${tcl_have_wspiapi_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include <wspiapi.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_have_wspiapi_h=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_have_wspiapi_h=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -echo "$as_me:$LINENO: result: $tcl_have_wspiapi_h" >&5 -echo "${ECHO_T}$tcl_have_wspiapi_h" >&6 -if test "$tcl_have_wspiapi_h" = "yes"; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_WSPIAPI_H 1 -_ACEOF - -fi - -#-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- @@ -4045,6 +3322,87 @@ fi # which requires x86|amd64|ia64. MACHINE="X86" + if test "$GCC" = "yes"; then + + echo "$as_me:$LINENO: checking for cross-compile version of gcc" >&5 +echo $ECHO_N "checking for cross-compile version of gcc... $ECHO_C" >&6 +if test "${ac_cv_cross+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #ifdef __WIN32__ + #error cross-compiler + #endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_cross=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_cross=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $ac_cv_cross" >&5 +echo "${ECHO_T}$ac_cv_cross" >&6 + + if test "$ac_cv_cross" = "yes"; then + case "$do64bit" in + amd64|x64|yes) + CC="x86_64-w64-mingw32-gcc" + LD="x86_64-w64-mingw32-ld" + AR="x86_64-w64-mingw32-ar" + RANLIB="x86_64-w64-mingw32-ranlib" + RC="x86_64-w64-mingw32-windres" + ;; + *) + CC="i686-w64-mingw32-gcc" + LD="i686-w64-mingw32-ld" + AR="i686-w64-mingw32-ar" + RANLIB="i686-w64-mingw32-ranlib" + RC="i686-w64-mingw32-windres" + ;; + esac + fi + fi + # Check for a bug in gcc's windres that causes the # compile to fail when a Windows native path is # passed into windres. The mingw toolchain requires @@ -4078,9 +3436,18 @@ echo "${ECHO_T}yes" >&6 cyg_conftest= fi - echo "$as_me:$LINENO: checking for Cygwin version of gcc" >&5 -echo $ECHO_N "checking for Cygwin version of gcc... $ECHO_C" >&6 -if test "${ac_cv_cygwin+set}" = set; then + if test "$CYGPATH" = "echo"; then + DEPARG='"$<"' + else + DEPARG='"$(shell $(CYGPATH) $<)"' + fi + + # set various compiler flags depending on whether we are using gcc or cl + + if test "${GCC}" = "yes" ; then + echo "$as_me:$LINENO: checking for mingw32 version of gcc" >&5 +echo $ECHO_N "checking for mingw32 version of gcc... $ECHO_C" >&6 +if test "${ac_cv_win32+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF @@ -4090,9 +3457,9 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #ifdef __CYGWIN__ - #error cygwin - #endif + #ifdef __WIN32__ + #error win32 + #endif int main () @@ -4124,73 +3491,26 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - ac_cv_cygwin=no + ac_cv_win32=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_cygwin=yes +ac_cv_win32=yes fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5 -echo "${ECHO_T}$ac_cv_cygwin" >&6 - if test "$ac_cv_cygwin" = "yes" ; then - { echo "$as_me:$LINENO: WARNING: Compiling under Cygwin is not currently supported. -If you are not sure you want this, see the README -file for information about building with Mingw." >&5 -echo "$as_me: WARNING: Compiling under Cygwin is not currently supported. -If you are not sure you want this, see the README -file for information about building with Mingw." >&2;} - fi - if test "$CYGPATH" = "echo" || test "$ac_cv_cygwin" = "yes"; then - DEPARG='"$<"' - else - DEPARG='"$(shell $(CYGPATH) $<)"' - fi - - # set various compiler flags depending on whether we are using gcc or cl - - echo "$as_me:$LINENO: checking compiler flags" >&5 -echo $ECHO_N "checking compiler flags... $ECHO_C" >&6 - if test "${GCC}" = "yes" ; then - SHLIB_LD="" - SHLIB_LD_LIBS='${LIBS}' - LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -lws2_32" - # mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't - LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32" - STLIB_LD='${AR} cr' - RC_OUT=-o - RC_TYPE= - RC_INCLUDE=--include - RC_DEFINE=--define - RES=res.o - MAKE_LIB="\${STLIB_LD} \$@" - POST_MAKE_LIB="\${RANLIB} \$@" - MAKE_EXE="\${CC} -o \$@" - LIBPREFIX="lib" - - extra_cflags="-pipe" - extra_ldflags="-pipe" - - if test "$ac_cv_cygwin" = "yes"; then - touch ac$$.c - if ${CC} -c -mwin32 ac$$.c >/dev/null 2>&1; then - case "$extra_cflags" in - *-mwin32*) ;; - *) extra_cflags="-mwin32 $extra_cflags" ;; - esac - case "$extra_ldflags" in - *-mwin32*) ;; - *) extra_ldflags="-mwin32 $extra_ldflags" ;; - esac - fi - rm -f ac$$.o ac$$.c +echo "$as_me:$LINENO: result: $ac_cv_win32" >&5 +echo "${ECHO_T}$ac_cv_win32" >&6 + if test "$ac_cv_win32" != "yes"; then + { { echo "$as_me:$LINENO: error: ${CC} cannot produce win32 executables." >&5 +echo "$as_me: error: ${CC} cannot produce win32 executables." >&2;} + { (exit 1); exit 1; }; } fi hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain" - echo "$as_me:$LINENO: checking for working -municode linker flag" >&5 + echo "$as_me:$LINENO: checking for working -municode linker flag" >&5 echo $ECHO_N "checking for working -municode linker flag... $ECHO_C" >&6 if test "${ac_cv_municode+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -4202,8 +3522,8 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #include <windows.h> - int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;} + #include <windows.h> + int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;} int main () @@ -4248,13 +3568,36 @@ rm -f conftest.err conftest.$ac_objext \ fi echo "$as_me:$LINENO: result: $ac_cv_municode" >&5 echo "${ECHO_T}$ac_cv_municode" >&6 - CFLAGS=$hold_cflags - if test "$ac_cv_municode" = "yes" ; then - extra_ldflags="$extra_ldflags -municode" - else - extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS" + CFLAGS=$hold_cflags + if test "$ac_cv_municode" = "yes" ; then + extra_ldflags="$extra_ldflags -municode" + else + extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS" + fi fi + echo "$as_me:$LINENO: checking compiler flags" >&5 +echo $ECHO_N "checking compiler flags... $ECHO_C" >&6 + if test "${GCC}" = "yes" ; then + SHLIB_LD="" + SHLIB_LD_LIBS='${LIBS}' + LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -lws2_32" + # mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't + LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32" + STLIB_LD='${AR} cr' + RC_OUT=-o + RC_TYPE= + RC_INCLUDE=--include + RC_DEFINE=--define + RES=res.o + MAKE_LIB="\${STLIB_LD} \$@" + POST_MAKE_LIB="\${RANLIB} \$@" + MAKE_EXE="\${CC} -o \$@" + LIBPREFIX="lib" + + extra_ldflags="$extra_ldflags -pipe" + extra_cflags="$extra_cflags -pipe" + if test "${SHARED_BUILD}" = "0" ; then # static echo "$as_me:$LINENO: result: using static flags" >&5 @@ -4344,9 +3687,9 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #ifdef _WIN64 + #ifdef _WIN64 #error 64-bit - #endif + #endif int main () @@ -4691,6 +4034,291 @@ _ACEOF fi + if test "${GCC}" = "yes" ; then + echo "$as_me:$LINENO: checking for SEH support in compiler" >&5 +echo $ECHO_N "checking for SEH support in compiler... $ECHO_C" >&6 +if test "${tcl_cv_seh+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + tcl_cv_seh=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #define WIN32_LEAN_AND_MEAN + #include <windows.h> + #undef WIN32_LEAN_AND_MEAN + + int main(int argc, char** argv) { + int a, b = 0; + __try { + a = 666 / b; + } + __except (EXCEPTION_EXECUTE_HANDLER) { + return 0; + } + return 1; + } + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_seh=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +tcl_cv_seh=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + +fi +echo "$as_me:$LINENO: result: $tcl_cv_seh" >&5 +echo "${ECHO_T}$tcl_cv_seh" >&6 + if test "$tcl_cv_seh" = "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_NO_SEH 1 +_ACEOF + + fi + + # + # Check to see if the excpt.h include file provided contains the + # definition for EXCEPTION_DISPOSITION; if not, which is the case + # with Cygwin's version as of 2002-04-10, define it to be int, + # sufficient for getting the current code to work. + # + echo "$as_me:$LINENO: checking for EXCEPTION_DISPOSITION support in include files" >&5 +echo $ECHO_N "checking for EXCEPTION_DISPOSITION support in include files... $ECHO_C" >&6 +if test "${tcl_cv_eh_disposition+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +# undef WIN32_LEAN_AND_MEAN + +int +main () +{ + + EXCEPTION_DISPOSITION x; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_eh_disposition=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_eh_disposition=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $tcl_cv_eh_disposition" >&5 +echo "${ECHO_T}$tcl_cv_eh_disposition" >&6 + if test "$tcl_cv_eh_disposition" = "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define EXCEPTION_DISPOSITION int +_ACEOF + + fi + + # Check to see if winnt.h defines CHAR, SHORT, and LONG + # even if VOID has already been #defined. The win32api + # used by mingw and cygwin is known to do this. + + echo "$as_me:$LINENO: checking for winnt.h that ignores VOID define" >&5 +echo $ECHO_N "checking for winnt.h that ignores VOID define... $ECHO_C" >&6 +if test "${tcl_cv_winnt_ignore_void+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #define VOID void + #define WIN32_LEAN_AND_MEAN + #include <windows.h> + #undef WIN32_LEAN_AND_MEAN + +int +main () +{ + + CHAR c; + SHORT s; + LONG l; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_winnt_ignore_void=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_winnt_ignore_void=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $tcl_cv_winnt_ignore_void" >&5 +echo "${ECHO_T}$tcl_cv_winnt_ignore_void" >&6 + if test "$tcl_cv_winnt_ignore_void" = "yes" ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WINNT_IGNORE_VOID 1 +_ACEOF + + 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. + + echo "$as_me:$LINENO: checking for cast to union support" >&5 +echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6 +if test "${tcl_cv_cast_to_union+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + union foo { int i; double d; }; + union foo f = (union foo) (int) 0; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_cast_to_union=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cast_to_union=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5 +echo "${ECHO_T}$tcl_cv_cast_to_union" >&6 + if test "$tcl_cv_cast_to_union" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CAST_TO_UNION 1 +_ACEOF + + fi + fi + # DL_LIBS is empty, but then we match the Unix version @@ -5028,6 +4656,295 @@ _ACEOF fi + +#-------------------------------------------------------------------- +# Perform additinal compiler tests. +#-------------------------------------------------------------------- + +# See if declarations like FINDEX_INFO_LEVELS are +# missing from winbase.h. This is known to be +# a problem with VC++ 5.2. + +echo "$as_me:$LINENO: checking for FINDEX_INFO_LEVELS in winbase.h" >&5 +echo $ECHO_N "checking for FINDEX_INFO_LEVELS in winbase.h... $ECHO_C" >&6 +if test "${tcl_cv_findex_enums+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#undef WIN32_LEAN_AND_MEAN + +int +main () +{ + + FINDEX_INFO_LEVELS i; + FINDEX_SEARCH_OPS j; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_findex_enums=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_findex_enums=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $tcl_cv_findex_enums" >&5 +echo "${ECHO_T}$tcl_cv_findex_enums" >&6 +if test "$tcl_cv_findex_enums" = "no"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_NO_FINDEX_ENUMS 1 +_ACEOF + +fi + +# See if the compiler supports intrinsics. + +echo "$as_me:$LINENO: checking for intrinsics support in compiler" >&5 +echo $ECHO_N "checking for intrinsics support in compiler... $ECHO_C" >&6 +if test "${tcl_cv_intrinsics+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#undef WIN32_LEAN_AND_MEAN +#include <intrin.h> + +int +main () +{ + + __cpuidex(0,0,0); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_intrinsics=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_intrinsics=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $tcl_cv_intrinsics" >&5 +echo "${ECHO_T}$tcl_cv_intrinsics" >&6 +if test "$tcl_cv_intrinsics" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_INTRIN_H 1 +_ACEOF + +fi + +# See if the <wspiapi.h> header file is present + +echo "$as_me:$LINENO: checking for wspiapi.h" >&5 +echo $ECHO_N "checking for wspiapi.h... $ECHO_C" >&6 +if test "${tcl_cv_wspiapi_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include <wspiapi.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_wspiapi_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_wspiapi_h=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $tcl_cv_wspiapi_h" >&5 +echo "${ECHO_T}$tcl_cv_wspiapi_h" >&6 +if test "$tcl_cv_wspiapi_h" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WSPIAPI_H 1 +_ACEOF + +fi + +# See if declarations like FINDEX_INFO_LEVELS are +# missing from winbase.h. This is known to be +# a problem with VC++ 5.2. + +echo "$as_me:$LINENO: checking for FINDEX_INFO_LEVELS in winbase.h" >&5 +echo $ECHO_N "checking for FINDEX_INFO_LEVELS in winbase.h... $ECHO_C" >&6 +if test "${tcl_cv_findex_enums+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#undef WIN32_LEAN_AND_MEAN + +int +main () +{ + + FINDEX_INFO_LEVELS i; + FINDEX_SEARCH_OPS j; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_findex_enums=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_findex_enums=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $tcl_cv_findex_enums" >&5 +echo "${ECHO_T}$tcl_cv_findex_enums" >&6 +if test "$tcl_cv_findex_enums" = "no"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_NO_FINDEX_ENUMS 1 +_ACEOF + +fi + #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols # option. This macro depends on C flags, and should be called diff --git a/win/tclWinError.c b/win/tclWinError.c index 1b59dbe..969780d 100644 --- a/win/tclWinError.c +++ b/win/tclWinError.c @@ -11,15 +11,6 @@ */ #include "tclInt.h" - -#ifndef WSAEWOULDBLOCK -# define WSAEWOULDBLOCK 10035L -#endif - -#ifndef __WIN32__ -# define DWORD unsigned int -#endif - /* * The following table contains the mapping from Win32 errors to errno errors. */ @@ -340,6 +331,11 @@ static const unsigned char wsaErrorTable[] = { EREMOTE /* WSAEREMOTE */ }; +#ifdef __CYGWIN__ +# include <windows.h> +# define DWORD unsigned int +#endif + /* *---------------------------------------------------------------------- * @@ -361,40 +357,66 @@ TclWinConvertError( DWORD errCode) /* Win32 error code. */ { if (errCode >= sizeof(errorTable)/sizeof(errorTable[0])) { - Tcl_SetErrno(EINVAL); + errCode -= WSAEWOULDBLOCK; + if (errCode >= sizeof(wsaErrorTable)/sizeof(wsaErrorTable[0])) { + Tcl_SetErrno(errorTable[1]); + } else { + Tcl_SetErrno(wsaErrorTable[errCode]); + } } else { Tcl_SetErrno(errorTable[errCode]); } } - + +#ifdef __CYGWIN__ /* *---------------------------------------------------------------------- * - * TclWinConvertWSAError -- + * tclWinDebugPanic -- * - * This routine converts a WinSock error into an errno value. + * Display a message. If a debugger is present, present it directly to + * the debugger, otherwise send it to stderr. * * Results: * None. * * Side effects: - * Sets the errno global variable. + * None. * *---------------------------------------------------------------------- */ void -TclWinConvertWSAError( - DWORD errCode) /* Win32 error code. */ +tclWinDebugPanic( + const char *format, ...) { - errCode -= WSAEWOULDBLOCK; - if (errCode >= sizeof(wsaErrorTable)/sizeof(wsaErrorTable[0])) { - Tcl_SetErrno(EINVAL); +#define TCL_MAX_WARN_LEN 1024 + va_list argList; + va_start(argList, format); + + if (IsDebuggerPresent()) { + WCHAR msgString[TCL_MAX_WARN_LEN]; + char buf[TCL_MAX_WARN_LEN * TCL_UTF_MAX]; + + vsnprintf(buf, sizeof(buf), format, argList); + msgString[TCL_MAX_WARN_LEN-1] = L'\0'; + MultiByteToWideChar(CP_UTF8, 0, buf, -1, msgString, TCL_MAX_WARN_LEN); + + /* + * Truncate MessageBox string if it is too long to not overflow the buffer. + */ + + if (msgString[TCL_MAX_WARN_LEN-1] != L'\0') { + memcpy(msgString + (TCL_MAX_WARN_LEN - 5), L" ...", 5 * sizeof(WCHAR)); + } + OutputDebugStringW(msgString); } else { - Tcl_SetErrno(wsaErrorTable[errCode]); + vfprintf(stderr, format, argList); + fprintf(stderr, "\n"); + fflush(stderr); } } - +#endif /* * Local Variables: * mode: c diff --git a/win/tclWinLoad.c b/win/tclWinLoad.c index 3f4d4d9..5848daa 100644 --- a/win/tclWinLoad.c +++ b/win/tclWinLoad.c @@ -14,24 +14,22 @@ #include "tclWinInt.h" /* - * Mutex protecting static data in this file; + * Native name of the directory in the native filesystem where DLLs used in + * this process are copied prior to loading, and mutex used to protect its + * allocation. */ -static Tcl_Mutex loadMutex; +static WCHAR *dllDirectoryName = NULL; +static Tcl_Mutex dllDirectoryNameMutex; /* - * Name of the directory in the native filesystem where DLLs used in this - * process are copied prior to loading. + * Static functions defined within this file. */ -static WCHAR* dllDirectoryName = NULL; - -/* Static functions defined within this file */ - -void* FindSymbol(Tcl_Interp* interp, Tcl_LoadHandle loadHandle, - const char* symbol); -void UnloadFile(Tcl_LoadHandle loadHandle); - +static void * FindSymbol(Tcl_Interp *interp, + Tcl_LoadHandle loadHandle, const char *symbol); +static void InitDLLDirectoryName(void); +static void UnloadFile(Tcl_LoadHandle loadHandle); /* *---------------------------------------------------------------------- @@ -75,8 +73,7 @@ TclpDlopen( */ nativeName = Tcl_FSGetNativePath(pathPtr); - hInstance = LoadLibraryEx(nativeName, NULL, - LOAD_WITH_ALTERED_SEARCH_PATH); + hInstance = LoadLibraryEx(nativeName,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); if (hInstance == NULL) { /* * Let the OS loader examine the binary search path for whatever @@ -85,9 +82,8 @@ TclpDlopen( */ Tcl_DString ds; - const char *fileName = Tcl_GetString(pathPtr); - nativeName = Tcl_WinUtfToTChar(fileName, -1, &ds); + nativeName = Tcl_WinUtfToTChar(Tcl_GetString(pathPtr), -1, &ds); hInstance = LoadLibraryEx(nativeName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); Tcl_DStringFree(&ds); @@ -96,23 +92,6 @@ TclpDlopen( if (hInstance == NULL) { DWORD lastError = GetLastError(); -#if 0 - /* - * It would be ideal if the FormatMessage stuff worked better, but - * unfortunately it doesn't seem to want to... - */ - - LPTSTR lpMsgBuf; - char *buf; - int size; - - size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastError, 0, - (LPTSTR) &lpMsgBuf, 0, NULL); - buf = ckalloc(TCL_INTEGER_SPACE + size + 1); - sprintf(buf, "%d %s", lastError, (char *)lpMsgBuf); -#endif - Tcl_AppendResult(interp, "couldn't load library \"", Tcl_GetString(pathPtr), "\": ", NULL); @@ -185,24 +164,25 @@ TclpDlopen( *---------------------------------------------------------------------- */ -void * +static void * FindSymbol( Tcl_Interp *interp, Tcl_LoadHandle loadHandle, const char *symbol) { + HINSTANCE hInstance = (HINSTANCE) loadHandle->clientData; Tcl_PackageInitProc *proc = NULL; - HINSTANCE hInstance = (HINSTANCE)(loadHandle->clientData); /* * For each symbol, check for both Symbol and _Symbol, since Borland * generates C symbols with a leading '_' by default. */ - proc = (void*) GetProcAddress(hInstance, symbol); + proc = (void *) GetProcAddress(hInstance, symbol); if (proc == NULL) { Tcl_DString ds; - const char* sym2; + const char *sym2; + Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, "_", 1); sym2 = Tcl_DStringAppend(&ds, symbol, -1); @@ -234,7 +214,7 @@ FindSymbol( *---------------------------------------------------------------------- */ -void +static void UnloadFile( Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to * TclpDlopen(). The loadHandle is a token @@ -277,7 +257,7 @@ TclGuessPackageName( } /* - *----------------------------------------------------------------------------- + *---------------------------------------------------------------------- * * TclpTempFileNameForLibrary -- * @@ -287,86 +267,125 @@ TclGuessPackageName( * Returns the constructed file name. * * On Windows, a DLL is identified by the final component of its path name. - * Cross linking among DLL's (and hence, preloading) will not work unless - * this name is preserved when copying a DLL from a VFS to a temp file for - * preloading. For this reason, all DLLs in a given process are copied - * to a temp directory, and their names are preserved. + * Cross linking among DLL's (and hence, preloading) will not work unless this + * name is preserved when copying a DLL from a VFS to a temp file for + * preloading. For this reason, all DLLs in a given process are copied to a + * temp directory, and their names are preserved. * - *----------------------------------------------------------------------------- + *---------------------------------------------------------------------- */ -Tcl_Obj* -TclpTempFileNameForLibrary(Tcl_Interp* interp, /* Tcl interpreter */ - Tcl_Obj* path) /* Path name of the DLL in - * the VFS */ +Tcl_Obj * +TclpTempFileNameForLibrary( + Tcl_Interp *interp, /* Tcl interpreter. */ + Tcl_Obj *path) /* Path name of the DLL in the VFS. */ { - size_t nameLen; /* Length of the temp folder name */ - WCHAR name[MAX_PATH]; /* Path name of the temp folder */ - BOOL status; /* Status from Win32 API calls */ - Tcl_Obj* fileName; /* Name of the temp file */ - Tcl_Obj* tail; /* Tail of the source path */ + Tcl_Obj *fileName; /* Name of the temp file. */ + Tcl_Obj *tail; /* Tail of the source path. */ - /* - * Determine the name of the directory to use, and create it. - * (Keep trying with new names until an attempt to create the directory - * succeeds) - */ - - nameLen = 0; + Tcl_MutexLock(&dllDirectoryNameMutex); if (dllDirectoryName == NULL) { - Tcl_MutexLock(&loadMutex); - if (dllDirectoryName == NULL) { - nameLen = GetTempPathW(MAX_PATH, name); - if (nameLen >= MAX_PATH-12) { - Tcl_SetErrno(ENAMETOOLONG); - nameLen = 0; - } else { - wcscpy(name+nameLen, L"TCLXXXXXXXX"); - nameLen += 11; - } - status = 1; - if (nameLen != 0) { - DWORD id; - int i = 0; - id = GetCurrentProcessId(); - for (;;) { - DWORD lastError; - wsprintfW(name+nameLen-8, L"%08x", id); - status = CreateDirectoryW(name, NULL); - if (status) { - break; - } - if ((lastError = GetLastError()) != ERROR_ALREADY_EXISTS) { - TclWinConvertError(lastError); - break; - } else if (++i > 256) { - TclWinConvertError(lastError); - break; - } - id *= 16777619; - } - } - if (status != 0) { - dllDirectoryName = ckalloc((nameLen+1) * sizeof(WCHAR)); - wcscpy(dllDirectoryName, name); - } + if (InitDLLDirectoryName() == TCL_ERROR) { + Tcl_AppendResult(interp, "couldn't create temporary directory: ", + Tcl_PosixError(interp), NULL); + Tcl_MutexUnlock(&dllDirectoryNameMutex); + return NULL; } - Tcl_MutexUnlock(&loadMutex); - } - if (dllDirectoryName == NULL) { - Tcl_AppendResult(interp, "couldn't create temporary directory: ", - Tcl_PosixError(interp), NULL); } + Tcl_MutexUnlock(&dllDirectoryNameMutex); + + /* + * Now we know where to put temporary DLLs, construct the name. + */ + fileName = TclpNativeToNormalized(dllDirectoryName); tail = TclPathPart(interp, path, TCL_PATH_TAIL); if (tail == NULL) { Tcl_DecrRefCount(fileName); return NULL; - } else { - Tcl_AppendToObj(fileName, "/", 1); - Tcl_AppendObjToObj(fileName, tail); - return fileName; } + Tcl_AppendToObj(fileName, "/", 1); + Tcl_AppendObjToObj(fileName, tail); + return fileName; +} + +/* + *---------------------------------------------------------------------- + * + * InitDLLDirectoryName -- + * + * Helper for TclpTempFileNameForLibrary; builds a temporary directory + * that is specific to the current process. Should only be called once + * per process start. Caller must hold dllDirectoryNameMutex. + * + * Results: + * Tcl result code. + * + * Side-effects: + * Creates temp directory. + * Allocates memory pointed to by dllDirectoryName. + * + *---------------------------------------------------------------------- + * [Candidate for process global?] + */ + +static int +InitDLLDirectoryName(void) +{ + size_t nameLen; /* Length of the temp folder name. */ + WCHAR name[MAX_PATH]; /* Path name of the temp folder. */ + DWORD id; /* The process id. */ + DWORD lastError; /* Last error to happen in Win API. */ + int i; + + /* + * Determine the name of the directory to use, and create it. (Keep + * trying with new names until an attempt to create the directory + * succeeds) + */ + + nameLen = GetTempPathW(MAX_PATH, name); + if (nameLen >= MAX_PATH-12) { + Tcl_SetErrno(ENAMETOOLONG); + return TCL_ERROR; + } + + wcscpy(name+nameLen, L"TCLXXXXXXXX"); + nameLen += 11; + + id = GetCurrentProcessId(); + lastError = ERROR_ALREADY_EXISTS; + + for (i=0 ; i<256 ; i++) { + wsprintfW(name+nameLen-8, L"%08x", id); + if (CreateDirectoryW(name, NULL)) { + /* + * Issue: we don't schedule this directory for deletion by anyone. + * Can we ask the OS to do this for us? There appears to be + * potential for using CreateFile (with the flag + * FILE_FLAG_BACKUP_SEMANTICS) and RemoveDirectory to do this... + */ + + goto copyToGlobalBuffer; + } + lastError = GetLastError(); + if (lastError != ERROR_ALREADY_EXISTS) { + break; + } + id *= 16777619; + } + + TclWinConvertError(lastError); + return TCL_ERROR; + + /* + * Store our computed value in the global. + */ + + copyToGlobalBuffer: + dllDirectoryName = ckalloc((nameLen+1) * sizeof(WCHAR)); + wcscpy(dllDirectoryName, name); + return TCL_OK; } /* diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 60cc313..2f14c17 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -47,6 +47,13 @@ #include "tclWinInt.h" +/* + * Which version of the winsock API do we want? + */ + +#define WSA_VERSION_MAJOR 1 +#define WSA_VERSION_MINOR 1 + #ifdef _MSC_VER # pragma comment (lib, "ws2_32") #endif @@ -91,16 +98,17 @@ static ProcessGlobalValue hostName = { * The following defines declare the messages used on socket windows. */ -#define SOCKET_MESSAGE WM_USER+1 -#define SOCKET_SELECT WM_USER+2 -#define SOCKET_TERMINATE WM_USER+3 -#define SELECT TRUE -#define UNSELECT FALSE +#define SOCKET_MESSAGE WM_USER+1 +#define SOCKET_SELECT WM_USER+2 +#define SOCKET_TERMINATE WM_USER+3 +#define SELECT TRUE +#define UNSELECT FALSE /* * This is needed to comply with the strict aliasing rules of GCC, but it also * simplifies casting between the different sockaddr types. */ + typedef union { struct sockaddr sa; struct sockaddr_in sa4; @@ -206,10 +214,6 @@ static WNDCLASS windowClass; static SocketInfo * CreateSocket(Tcl_Interp *interp, int port, const char *host, int server, const char *myaddr, int myport, int async); -#if 0 -static int CreateSocketAddress(LPSOCKADDR_IN sockaddrPtr, - const char *host, int port); -#endif static void InitSockets(void); static SocketInfo * NewSocketInfo(SOCKET socket); static void SocketExitHandler(ClientData clientData); @@ -284,9 +288,8 @@ static const Tcl_ChannelType tcpChannelType = { static void InitSockets(void) { - DWORD id; + DWORD id, err; WSADATA wsaData; - DWORD err; ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); if (!initialized) { @@ -322,72 +325,73 @@ InitSockets(void) * that it not be less than 1.1. */ -#define WSA_VERSION_MAJOR 1 -#define WSA_VERSION_MINOR 1 -#define WSA_VERSION_REQD MAKEWORD(WSA_VERSION_MAJOR, WSA_VERSION_MINOR) - - err = WSAStartup((WORD)WSA_VERSION_REQD, &wsaData); + err = WSAStartup((WORD) MAKEWORD(WSA_VERSION_MAJOR,WSA_VERSION_MINOR), + &wsaData); if (err != 0) { - TclWinConvertWSAError(err); + TclWinConvertError(err); goto initFailure; } /* - * Note the byte positions are swapped for the comparison, so that - * 0x0002 (2.0, MAKEWORD(2,0)) doesn't look less than 0x0101 (1.1). - * We want the comparison to be 0x0200 < 0x0101. + * Note the byte positions ae swapped for the comparison, so that + * 0x0002 (2.0, MAKEWORD(2,0)) doesn't look less than 0x0101 (1.1). We + * want the comparison to be 0x0200 < 0x0101. */ if (MAKEWORD(HIBYTE(wsaData.wVersion), LOBYTE(wsaData.wVersion)) < MAKEWORD(WSA_VERSION_MINOR, WSA_VERSION_MAJOR)) { - TclWinConvertWSAError(WSAVERNOTSUPPORTED); + TclWinConvertError(WSAVERNOTSUPPORTED); WSACleanup(); goto initFailure; } - -#undef WSA_VERSION_REQD -#undef WSA_VERSION_MAJOR -#undef WSA_VERSION_MINOR } /* * Check for per-thread initialization. */ - if (tsdPtr == NULL) { - tsdPtr = TCL_TSD_INIT(&dataKey); - tsdPtr->socketList = NULL; - tsdPtr->hwnd = NULL; - tsdPtr->threadId = Tcl_GetCurrentThread(); - tsdPtr->readyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if (tsdPtr->readyEvent == NULL) { - goto initFailure; - } - tsdPtr->socketListLock = CreateEvent(NULL, FALSE, TRUE, NULL); - if (tsdPtr->socketListLock == NULL) { - goto initFailure; - } - tsdPtr->socketThread = CreateThread(NULL, 256, SocketThread, tsdPtr, - 0, &id); - if (tsdPtr->socketThread == NULL) { - goto initFailure; - } + if (tsdPtr != NULL) { + return; + } - SetThreadPriority(tsdPtr->socketThread, THREAD_PRIORITY_HIGHEST); + /* + * OK, this thread has never done anything with sockets before. Construct + * a worker thread to handle asynchronous events related to sockets + * assigned to _this_ thread. + */ - /* - * Wait for the thread to signal when the window has been created and - * if it is ready to go. - */ + tsdPtr = TCL_TSD_INIT(&dataKey); + tsdPtr->socketList = NULL; + tsdPtr->hwnd = NULL; + tsdPtr->threadId = Tcl_GetCurrentThread(); + tsdPtr->readyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (tsdPtr->readyEvent == NULL) { + goto initFailure; + } + tsdPtr->socketListLock = CreateEvent(NULL, FALSE, TRUE, NULL); + if (tsdPtr->socketListLock == NULL) { + goto initFailure; + } + tsdPtr->socketThread = CreateThread(NULL, 256, SocketThread, tsdPtr, 0, + &id); + if (tsdPtr->socketThread == NULL) { + goto initFailure; + } - WaitForSingleObject(tsdPtr->readyEvent, INFINITE); + SetThreadPriority(tsdPtr->socketThread, THREAD_PRIORITY_HIGHEST); - if (tsdPtr->hwnd == NULL) { - goto initFailure; /* Trouble creating the window */ - } + /* + * Wait for the thread to signal when the window has been created and if + * it is ready to go. + */ - Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL); + WaitForSingleObject(tsdPtr->readyEvent, INFINITE); + + if (tsdPtr->hwnd == NULL) { + goto initFailure; /* Trouble creating the window. */ } + + Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL); return; initFailure: @@ -417,6 +421,7 @@ static int SocketsEnabled(void) { int enabled; + Tcl_MutexLock(&socketMutex); enabled = (initialized == 1); Tcl_MutexUnlock(&socketMutex); @@ -447,6 +452,7 @@ SocketExitHandler( ClientData clientData) /* Not used. */ { Tcl_MutexLock(&socketMutex); + /* * Make sure the socket event handling window is cleaned-up for, at * most, this thread. @@ -483,32 +489,38 @@ TclpFinalizeSockets(void) { ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); - if (tsdPtr != NULL) { - if (tsdPtr->socketThread != NULL) { - if (tsdPtr->hwnd != NULL) { - PostMessage(tsdPtr->hwnd, SOCKET_TERMINATE, 0, 0); + /* + * Careful! This is a finalizer! + */ - /* - * Wait for the thread to exit. This ensures that we are - * completely cleaned up before we leave this function. - */ + if (tsdPtr == NULL) { + return; + } - WaitForSingleObject(tsdPtr->readyEvent, INFINITE); - tsdPtr->hwnd = NULL; - } - CloseHandle(tsdPtr->socketThread); - tsdPtr->socketThread = NULL; - } - if (tsdPtr->readyEvent != NULL) { - CloseHandle(tsdPtr->readyEvent); - tsdPtr->readyEvent = NULL; - } - if (tsdPtr->socketListLock != NULL) { - CloseHandle(tsdPtr->socketListLock); - tsdPtr->socketListLock = NULL; + if (tsdPtr->socketThread != NULL) { + if (tsdPtr->hwnd != NULL) { + PostMessage(tsdPtr->hwnd, SOCKET_TERMINATE, 0, 0); + + /* + * Wait for the thread to exit. This ensures that we are + * completely cleaned up before we leave this function. + */ + + WaitForSingleObject(tsdPtr->readyEvent, INFINITE); + tsdPtr->hwnd = NULL; } - Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL); + CloseHandle(tsdPtr->socketThread); + tsdPtr->socketThread = NULL; } + if (tsdPtr->readyEvent != NULL) { + CloseHandle(tsdPtr->readyEvent); + tsdPtr->readyEvent = NULL; + } + if (tsdPtr->socketListLock != NULL) { + CloseHandle(tsdPtr->socketListLock); + tsdPtr->socketListLock = NULL; + } + Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL); } /* @@ -677,8 +689,7 @@ SocketEventProc( { SocketInfo *infoPtr; SocketEvent *eventPtr = (SocketEvent *) evPtr; - int mask = 0; - int events; + int mask = 0, events; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); TcpFdList *fds; @@ -739,6 +750,7 @@ SocketEventProc( */ Tcl_Time blockTime = { 0, 0 }; + Tcl_SetMaxBlockTime(&blockTime); mask |= TCL_READABLE|TCL_WRITABLE; } else if (events & FD_READ) { @@ -861,7 +873,7 @@ TcpCloseProc( */ if (closesocket(infoPtr->sockets->fd) == SOCKET_ERROR) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); } } @@ -901,29 +913,29 @@ TcpClose2Proc( int flags) /* Flags that indicate which side to close. */ { SocketInfo *infoPtr = instanceData; - int errorCode = 0; - int sd; + int errorCode = 0, sd; /* * Shutdown the OS socket handle. */ - switch(flags) - { - case TCL_CLOSE_READ: - sd=SD_RECEIVE; - break; - case TCL_CLOSE_WRITE: - sd=SD_SEND; - break; - default: - if (interp) { - Tcl_AppendResult(interp, - "Socket close2proc called bidirectionally", NULL); - } - return TCL_ERROR; + + switch (flags) { + case TCL_CLOSE_READ: + sd = SD_RECEIVE; + break; + case TCL_CLOSE_WRITE: + sd = SD_SEND; + break; + default: + if (interp) { + Tcl_AppendResult(interp, + "Socket close2proc called bidirectionally", NULL); } - if (shutdown(infoPtr->sockets->fd,sd) == SOCKET_ERROR) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + return TCL_ERROR; + } + + if (shutdown(infoPtr->sockets->fd, sd) == SOCKET_ERROR) { + TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); } @@ -1012,8 +1024,10 @@ CreateSocket( int asyncConnect = 0; /* Will be 1 if async connect is in * progress. */ unsigned short chosenport = 0; - struct addrinfo *addrlist = NULL, *addrPtr; /* socket address */ - struct addrinfo *myaddrlist = NULL, *myaddrPtr; /* Socket address for client */ + struct addrinfo *addrlist = NULL, *addrPtr; + /* Socket address to connect to. */ + struct addrinfo *myaddrlist = NULL, *myaddrPtr; + /* Socket address for our side. */ const char *errorMsg = NULL; SOCKET sock = INVALID_SOCKET; SocketInfo *infoPtr = NULL; /* The returned value. */ @@ -1029,19 +1043,26 @@ CreateSocket( return NULL; } - if (!TclCreateSocketAddress(interp, &addrlist, host, port, server, &errorMsg)) { + /* + * Construct the addresses for each end of the socket. + */ + + if (!TclCreateSocketAddress(interp, &addrlist, host, port, server, + &errorMsg)) { goto error; } - if (!TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1, &errorMsg)) { + if (!TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1, + &errorMsg)) { goto error; } if (server) { TcpFdList *fds = NULL, *newfds; + for (addrPtr = addrlist; addrPtr != NULL; addrPtr = addrPtr->ai_next) { sock = socket(addrPtr->ai_family, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + TclWinConvertError((DWORD) WSAGetLastError()); continue; } @@ -1056,7 +1077,7 @@ CreateSocket( * Set kernel space buffering */ - TclSockMinimumBuffers((ClientData)sock, TCP_BUFFER_SIZE); + TclSockMinimumBuffers((void *)sock, TCP_BUFFER_SIZE); /* * Make sure we use the same port when opening two server sockets @@ -1065,9 +1086,10 @@ CreateSocket( * As sockaddr_in6 uses the same offset and size for the port * member as sockaddr_in, we can handle both through the IPv4 API. */ + if (port == 0 && chosenport != 0) { ((struct sockaddr_in *) addrPtr->ai_addr)->sin_port = - htons(chosenport); + htons(chosenport); } /* @@ -1081,31 +1103,33 @@ CreateSocket( */ if (bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen) - == SOCKET_ERROR) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + == SOCKET_ERROR) { + TclWinConvertError((DWORD) WSAGetLastError()); closesocket(sock); continue; } if (port == 0 && chosenport == 0) { address sockname; socklen_t namelen = sizeof(sockname); + /* * Synchronize port numbers when binding to port 0 of multiple * addresses. */ + if (getsockname(sock, &sockname.sa, &namelen) >= 0) { chosenport = ntohs(sockname.sa4.sin_port); } } /* - * Set the maximum number of pending connect requests to the max value - * allowed on each platform (Win32 and Win32s may be different, and - * there may be differences between TCP/IP stacks). + * Set the maximum number of pending connect requests to the max + * value allowed on each platform (Win32 and Win32s may be + * different, and there may be differences between TCP/IP stacks). */ if (listen(sock, SOMAXCONN) == SOCKET_ERROR) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + TclWinConvertError((DWORD) WSAGetLastError()); closesocket(sock); continue; } @@ -1144,13 +1168,14 @@ CreateSocket( * No need to try combinations of local and remote addresses * of different families. */ + if (myaddrPtr->ai_family != addrPtr->ai_family) { continue; } sock = socket(myaddrPtr->ai_family, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + TclWinConvertError((DWORD) WSAGetLastError()); continue; } @@ -1165,27 +1190,25 @@ CreateSocket( * Set kernel space buffering */ - TclSockMinimumBuffers((ClientData)sock, TCP_BUFFER_SIZE); + TclSockMinimumBuffers((void *) sock, TCP_BUFFER_SIZE); /* * Try to bind to a local port. */ if (bind(sock, myaddrPtr->ai_addr, myaddrPtr->ai_addrlen) - == SOCKET_ERROR) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + == SOCKET_ERROR) { + TclWinConvertError((DWORD) WSAGetLastError()); goto looperror; } /* * Set the socket into nonblocking mode if the connect should * be done in the background. */ - if (async) { - if (ioctlsocket(sock, (long) FIONBIO, &flag) + if (async && ioctlsocket(sock, (long) FIONBIO, &flag) == SOCKET_ERROR) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); - goto looperror; - } + TclWinConvertError((DWORD) WSAGetLastError()); + goto looperror; } /* @@ -1193,8 +1216,8 @@ CreateSocket( */ if (connect(sock, addrPtr->ai_addr, addrPtr->ai_addrlen) - == SOCKET_ERROR) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + == SOCKET_ERROR) { + TclWinConvertError((DWORD) WSAGetLastError()); if (Tcl_GetErrno() != EAGAIN) { goto looperror; } @@ -1204,10 +1227,9 @@ CreateSocket( */ asyncConnect = 1; - goto connected; - } else { - goto connected; } + goto connected; + looperror: if (sock != INVALID_SOCKET) { closesocket(sock); @@ -1225,8 +1247,8 @@ CreateSocket( infoPtr = NewSocketInfo(sock); /* - * Set up the select mask for read/write events. If the - * connect attempt has not completed, include connect events. + * Set up the select mask for read/write events. If the connect + * attempt has not completed, include connect events. */ infoPtr->selectEvents = FD_READ | FD_WRITE | FD_CLOSE; @@ -1237,10 +1259,12 @@ CreateSocket( } error: - if (addrlist == NULL) + if (addrlist == NULL) { freeaddrinfo(addrlist); - if (myaddrlist == NULL) + } + if (myaddrlist == NULL) { freeaddrinfo(myaddrlist); + } /* * Register for interest in events in the select mask. Note that this @@ -1249,7 +1273,8 @@ CreateSocket( if (infoPtr != NULL) { ioctlsocket(sock, (long) FIONBIO, &flag); - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) infoPtr); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, + (LPARAM) infoPtr); return infoPtr; } @@ -1264,80 +1289,6 @@ CreateSocket( return NULL; } -#if 0 -/* - *---------------------------------------------------------------------- - * - * CreateSocketAddress -- - * - * This function initializes a sockaddr structure for a host and port. - * - * Results: - * 1 if the host was valid, 0 if the host could not be converted to an IP - * address. - * - * Side effects: - * Fills in the *sockaddrPtr structure. - * - *---------------------------------------------------------------------- - */ - -static int -CreateSocketAddress( - LPSOCKADDR_IN sockaddrPtr, /* Socket address */ - const char *host, /* Host. NULL implies INADDR_ANY */ - int port) /* Port number */ -{ - struct hostent *hostent; /* Host database entry */ - struct in_addr addr; /* For 64/32 bit madness */ - - /* - * Check that WinSock is initialized; do not call it if not, to prevent - * system crashes. This can happen at exit time if the exit handler for - * WinSock ran before other exit handlers that want to use sockets. - */ - - if (!SocketsEnabled()) { - Tcl_SetErrno(EFAULT); - return 0; - } - - ZeroMemory(sockaddrPtr, sizeof(SOCKADDR_IN)); - sockaddrPtr->sin_family = AF_INET; - sockaddrPtr->sin_port = htons((u_short) (port & 0xFFFF)); - if (host == NULL) { - addr.s_addr = INADDR_ANY; - } else { - addr.s_addr = inet_addr(host); - if (addr.s_addr == INADDR_NONE) { - hostent = gethostbyname(host); - if (hostent != NULL) { - memcpy(&addr, hostent->h_addr, (size_t) hostent->h_length); - } else { -#ifdef EHOSTUNREACH - Tcl_SetErrno(EHOSTUNREACH); -#else -#ifdef ENXIO - Tcl_SetErrno(ENXIO); -#endif -#endif - return 0; /* Error. */ - } - } - } - - /* - * NOTE: On 64 bit machines the assignment below is rumored to not do the - * right thing. Please report errors related to this if you observe - * incorrect behavior on 64 bit machines such as DEC Alphas. Should we - * modify this code to do an explicit memcpy? - */ - - sockaddrPtr->sin_addr.s_addr = addr.s_addr; - return 1; /* Success. */ -} -#endif - /* *---------------------------------------------------------------------- * @@ -1377,7 +1328,6 @@ WaitForSocketEvent( SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, (LPARAM) infoPtr); - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) infoPtr); @@ -1452,17 +1402,16 @@ Tcl_OpenTcpClient( infoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, infoPtr, (TCL_READABLE | TCL_WRITABLE)); - if (Tcl_SetChannelOption(interp, infoPtr->channel, "-translation", - "auto crlf") == TCL_ERROR) { - Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel); - return (Tcl_Channel) NULL; - } - if (Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "") - == TCL_ERROR) { - Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel); - return (Tcl_Channel) NULL; + if (TCL_ERROR == Tcl_SetChannelOption(NULL, infoPtr->channel, + "-translation", "auto crlf")) { + Tcl_Close(NULL, infoPtr->channel); + return NULL; + } else if (TCL_ERROR == Tcl_SetChannelOption(NULL, infoPtr->channel, + "-eofchar", "")) { + Tcl_Close(NULL, infoPtr->channel); + return NULL; } - return infoPtr->channel; + return infoPtr->channel } /* @@ -1501,7 +1450,7 @@ Tcl_MakeTcpClientChannel( * Set kernel space buffering and non-blocking. */ - TclSockMinimumBuffers((ClientData) sock, TCP_BUFFER_SIZE); + TclSockMinimumBuffers(sock, TCP_BUFFER_SIZE); infoPtr = NewSocketInfo((SOCKET) sock); @@ -1510,8 +1459,7 @@ Tcl_MakeTcpClientChannel( */ infoPtr->selectEvents = FD_READ | FD_CLOSE | FD_WRITE; - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) SELECT, (LPARAM) infoPtr); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, (LPARAM)infoPtr); sprintf(channelName, "sock%Id", (size_t) infoPtr->sockets->fd); infoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, @@ -1572,8 +1520,8 @@ Tcl_OpenTcpServer( infoPtr, 0); if (Tcl_SetChannelOption(interp, infoPtr->channel, "-eofchar", "") == TCL_ERROR) { - Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel); - return (Tcl_Channel) NULL; + Tcl_Close(NULL, infoPtr->channel); + return NULL; } return infoPtr->channel; @@ -1614,12 +1562,13 @@ TcpAccept( len = sizeof(SOCKADDR_IN); - newSocket = accept(fds->fd, (SOCKADDR *)&addr, &len); + newSocket = accept(fds->fd, (SOCKADDR *) &addr, &len); /* * Protect access to sockets (acceptEventCount, readyEvents) in socketList * by the lock. Fix for SF Tcl Bug 3056775. */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* @@ -1668,20 +1617,20 @@ TcpAccept( */ newInfoPtr->selectEvents = (FD_READ | FD_WRITE | FD_CLOSE); - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) SELECT, (LPARAM) newInfoPtr); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, + (LPARAM) newInfoPtr); sprintf(channelName, "sock%Id", (size_t) newInfoPtr->sockets->fd); newInfoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, newInfoPtr, (TCL_READABLE | TCL_WRITABLE)); if (Tcl_SetChannelOption(NULL, newInfoPtr->channel, "-translation", "auto crlf") == TCL_ERROR) { - Tcl_Close((Tcl_Interp *) NULL, newInfoPtr->channel); + Tcl_Close(NULL, newInfoPtr->channel); return; } if (Tcl_SetChannelOption(NULL, newInfoPtr->channel, "-eofchar", "") == TCL_ERROR) { - Tcl_Close((Tcl_Interp *) NULL, newInfoPtr->channel); + Tcl_Close(NULL, newInfoPtr->channel); return; } @@ -1809,7 +1758,7 @@ TcpInputProc( */ if ((infoPtr->flags & SOCKET_ASYNC) || (error != WSAEWOULDBLOCK)) { - TclWinConvertWSAError(error); + TclWinConvertError(error); *errorCodePtr = Tcl_GetErrno(); bytesRead = -1; break; @@ -1826,8 +1775,7 @@ TcpInputProc( } } - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) SELECT, (LPARAM) infoPtr); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, (LPARAM)infoPtr); return bytesRead; } @@ -1918,7 +1866,7 @@ TcpOutputProc( break; } } else { - TclWinConvertWSAError(error); + TclWinConvertError(error); *errorCodePtr = Tcl_GetErrno(); bytesWritten = -1; break; @@ -1935,8 +1883,7 @@ TcpOutputProc( } } - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) SELECT, (LPARAM) infoPtr); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, (LPARAM)infoPtr); return bytesWritten; } @@ -1998,7 +1945,7 @@ TcpSetOptionProc( rtn = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const char *) &val, sizeof(BOOL)); if (rtn != 0) { - TclWinConvertWSAError(WSAGetLastError()); + TclWinConvertError(WSAGetLastError()); if (interp) { Tcl_AppendResult(interp, "couldn't set socket option: ", Tcl_PosixError(interp), NULL); @@ -2019,7 +1966,7 @@ TcpSetOptionProc( rtn = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *) &val, sizeof(BOOL)); if (rtn != 0) { - TclWinConvertWSAError(WSAGetLastError()); + TclWinConvertError(WSAGetLastError()); if (interp) { Tcl_AppendResult(interp, "couldn't set socket option: ", Tcl_PosixError(interp), NULL); @@ -2103,7 +2050,7 @@ TcpGetOptionProc( err = WSAGetLastError(); } if (err) { - TclWinConvertWSAError(err); + TclWinConvertError(err); Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1); } return TCL_OK; @@ -2117,6 +2064,7 @@ TcpGetOptionProc( (strncmp(optionName, "-peername", len) == 0))) { address peername; socklen_t size = sizeof(peername); + if (getpeername(sock, (LPSOCKADDR) &(peername.sa), &size) == 0) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); @@ -2144,7 +2092,7 @@ TcpGetOptionProc( */ if (len) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + TclWinConvertError((DWORD) WSAGetLastError()); if (interp) { Tcl_AppendResult(interp, "can't get peername: ", Tcl_PosixError(interp), NULL); @@ -2170,8 +2118,8 @@ TcpGetOptionProc( size = sizeof(sockname); if (getsockname(sock, &(sockname.sa), &size) >= 0) { int flags = reverseDNS; - found = 1; + found = 1; getnameinfo(&sockname.sa, size, host, sizeof(host), NULL, 0, NI_NUMERICHOST); Tcl_DStringAppendElement(dsPtr, host); @@ -2210,7 +2158,7 @@ TcpGetOptionProc( } } else { if (interp) { - TclWinConvertWSAError((DWORD) WSAGetLastError()); + TclWinConvertError((DWORD) WSAGetLastError()); Tcl_AppendResult(interp, "can't get sockname: ", Tcl_PosixError(interp), NULL); } @@ -2299,7 +2247,7 @@ TcpWatchProc( /* * Update the watch events mask. Only if the socket is not a server - * socket. Fix for SF Tcl Bug #557878. + * socket. [Bug 557878] */ if (!infoPtr->acceptProc) { @@ -2318,6 +2266,7 @@ TcpWatchProc( if (infoPtr->readyEvents & infoPtr->watchEvents) { Tcl_Time blockTime = { 0, 0 }; + Tcl_SetMaxBlockTime(&blockTime); } } @@ -2379,8 +2328,8 @@ SocketThread( * Create a dummy window receiving socket events. */ - tsdPtr->hwnd = CreateWindow(classname, classname, - WS_TILED, 0, 0, 0, 0, NULL, NULL, windowClass.hInstance, arg); + tsdPtr->hwnd = CreateWindow(classname, classname, WS_TILED, 0, 0, 0, 0, + NULL, NULL, windowClass.hInstance, arg); /* * Signalize thread creator that we are done creating the window. @@ -2518,7 +2467,7 @@ SocketProc( */ if (error != ERROR_SUCCESS) { - TclWinConvertWSAError((DWORD) error); + TclWinConvertError((DWORD) error); infoPtr->lastError = Tcl_GetErrno(); } } @@ -2526,7 +2475,7 @@ SocketProc( if (infoPtr->flags & SOCKET_ASYNC_CONNECT) { infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT); if (error != ERROR_SUCCESS) { - TclWinConvertWSAError((DWORD) error); + TclWinConvertError((DWORD) error); infoPtr->lastError = Tcl_GetErrno(); } infoPtr->readyEvents |= FD_WRITE; @@ -2677,8 +2626,8 @@ TclWinGetSockOpt( SOCKET s, int level, int optname, - char * optval, - int FAR *optlen) + char *optval, + int *optlen) { /* * Check that WinSock is initialized; do not call it if not, to prevent @@ -2698,7 +2647,7 @@ TclWinSetSockOpt( SOCKET s, int level, int optname, - const char * optval, + const char *optval, int optlen) { /* |