Check-in [0fdb07692d]
Bounty program for improvements to Tcl and certain Tcl packages.
Overview
Comment:Silence 64 bit integer conversion warnings Update build system to support AMD64 target with MSVC8
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0fdb07692dcaa001d356035ec1f67499c2613f07
User & Date: patthoyts on 2007-09-06 21:01:55
Other Links: manifest | tags
Context
2008-03-18
00:40
* tls.tcl (tls::initlib): load tls.tcl first and call * Makefile.in (pkgIndex.tcl): tls::initlib to load library to handle cwd changes. [Bug 1888113] check-in: c55de2b08b user: hobbs2 tags: trunk
2007-09-06
21:01
Silence 64 bit integer conversion warnings Update build system to support AMD64 target with MSVC8 check-in: 0fdb07692d user: patthoyts tags: trunk
2007-06-22
21:20
* tlsIO.c (TlsInputProc, TlsOutputProc, TlsWatchProc): * tls.c (VerifyCallback): add an state flag in the verify callback that prevents possibly recursion (on 'update'). [Bug 1652380] check-in: c692cb9684 user: hobbs2 tags: trunk
Changes

Modified ChangeLog from [0c7fd24fc4] to [59b9d3b9d8].

            1  +2007-09-06  Pat Thoyts  <[email protected]>
            2  +
            3  +	* tls.c:           Silence 64 bit integer conversion warnings
            4  +	* win/nmakehlp.c:  Update build system to support AMD64 target
            5  +	* win/makefile.vc: with MSVC8
            6  +	* win/rules.vc:
            7  +
     1      8   2007-06-22  Jeff Hobbs  <[email protected]>
     2      9   
     3     10   	* tlsIO.c (TlsInputProc, TlsOutputProc, TlsWatchProc): 
     4     11   	* tls.c (VerifyCallback): add an state flag in the verify callback
     5     12   	that prevents possibly recursion (on 'update'). [Bug 1652380]
     6     13   
     7     14   	* tests/ciphers.test: reworked to make test output cleaner to

Modified tls.c from [7da5f18bba] to [0abefbb942].

     1      1   /*
     2      2    * Copyright (C) 1997-1999 Matt Newman <[email protected]>
     3      3    * some modifications:
     4      4    *	Copyright (C) 2000 Ajuba Solutions
     5      5    *	Copyright (C) 2002 ActiveState Corporation
     6      6    *	Copyright (C) 2004 Starfish Systems 
     7      7    *
     8         - * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tls.c,v 1.25 2007/06/22 21:20:38 hobbs2 Exp $
            8  + * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tls.c,v 1.26 2007/09/06 21:01:55 patthoyts Exp $
     9      9    *
    10     10    * TLS (aka SSL) Channel - can be layered on any bi-directional
    11     11    * Tcl_Channel (Note: Requires Trf Core Patch)
    12     12    *
    13     13    * This was built (almost) from scratch based upon observation of
    14     14    * OpenSSL 0.9.2B
    15     15    *
................................................................................
   402    402       Tcl_Obj *cmdPtr;
   403    403       int result;
   404    404   
   405    405       if (statePtr->password == NULL) {
   406    406   	if (Tcl_Eval(interp, "tls::password") == TCL_OK) {
   407    407   	    char *ret = (char *) Tcl_GetStringResult(interp);
   408    408   	    strncpy(buf, ret, (size_t) size);
   409         -	    return strlen(ret);
          409  +	    return (int)strlen(ret);
   410    410   	} else {
   411    411   	    return -1;
   412    412   	}
   413    413       }
   414    414   
   415    415       cmdPtr = Tcl_DuplicateObj(statePtr->password);
   416    416   
................................................................................
   426    426   
   427    427       Tcl_Release((ClientData) statePtr);
   428    428       Tcl_Release((ClientData) statePtr->interp);
   429    429   
   430    430       if (result == TCL_OK) {
   431    431   	char *ret = (char *) Tcl_GetStringResult(interp);
   432    432   	strncpy(buf, ret, (size_t) size);
   433         -	return strlen(ret);
          433  +	return (int)strlen(ret);
   434    434       } else {
   435    435   	return -1;
   436    436       }
   437    437   }
   438    438   #endif
   439    439   
   440    440   /*
................................................................................
   529    529   	    Tcl_ListObjAppendElement( interp, objPtr,
   530    530   		Tcl_NewStringObj( cp, -1) );
   531    531   	}
   532    532       } else {
   533    533   	sk = SSL_get_ciphers(ssl);
   534    534   
   535    535   	for (index = 0; index < sk_SSL_CIPHER_num(sk); index++) {
   536         -	    register int i;
          536  +	    register size_t i;
   537    537   	    SSL_CIPHER_description( sk_SSL_CIPHER_value( sk, index),
   538    538   				    buf, sizeof(buf));
   539    539   	    for (i = strlen(buf) - 1; i ; i--) {
   540    540   		if (buf[i] == ' ' || buf[i] == '\n' ||
   541    541   		    buf[i] == '\r' || buf[i] == '\t') {
   542    542   		    buf[i] = '\0';
   543    543   		} else {

Modified win/makefile.vc from [dc425d4798] to [a8ad16f8ba].

    11     11   # See the file "license.terms" for information on usage and redistribution
    12     12   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    13     13   # 
    14     14   # Copyright (c) 1995-1996 Sun Microsystems, Inc.
    15     15   # Copyright (c) 1998-2000 Ajuba Solutions.
    16     16   # Copyright (c) 2001 ActiveState Corporation.
    17     17   # Copyright (c) 2001-2002 David Gravereaux.
    18         -# Copyright (c) 2003 Pat Thoyts
           18  +# Copyright (c) 2003-2006 Pat Thoyts
    19     19   #
    20     20   #-------------------------------------------------------------------------
    21         -# RCS: @(#)$Id: makefile.vc,v 1.3 2007/02/28 23:33:41 patthoyts Exp $
           21  +# RCS: @(#)$Id: makefile.vc,v 1.4 2007/09/06 21:01:55 patthoyts Exp $
    22     22   #-------------------------------------------------------------------------
    23     23   
    24         -!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCToolkitInstallDir)
           24  +# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
           25  +# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define
           26  +# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another.
           27  +!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir)
    25     28   MSG = ^
    26         -You will need to run vcvars32.bat from Developer Studio, first, to setup^
    27         -the environment.  Jump to this line to read the new instructions.
           29  +You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
           30  +Platform SDK first to setup the environment.  Jump to this line to read^
           31  +the build instructions.
    28     32   !error $(MSG)
    29     33   !endif
    30     34   
    31     35   #------------------------------------------------------------------------------
    32     36   # HOW TO USE this makefile:
    33     37   #
    34     38   # 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
................................................................................
    68     72   #		msvcrt  =  Effects the static option only to switch it from
    69     73   #			   using libcmt(d) as the C runtime [by default] to
    70     74   #			   msvcrt(d). This is useful for static embedding
    71     75   #			   support.
    72     76   #		staticpkg = Effects the static option only to switch
    73     77   #			   tclshXX.exe to have the dde and reg extension linked
    74     78   #			   inside it.
    75         -#		threads =  Turns on full multithreading support.
           79  +#		nothreads = Turns off multithreading support (not recommended)
    76     80   #		thrdalloc = Use the thread allocator (shared global free pool).
    77     81   #		symbols =  Adds symbols for step debugging.
    78     82   #		profile =  Adds profiling hooks.  Map file is assumed.
    79     83   #		loimpact =  Adds a flag for how NT treats the heap to keep memory
    80     84   #			   in use, low.  This is said to impact alloc performance.
    81     85   #
    82     86   #	STATS=memdbg,compdbg,none
................................................................................
    84     88   #		to the core.  The default is for none.  Any combination of the
    85     89   #		above may be used (comma separated).  'none' will over-ride
    86     90   #		everything to nothing.
    87     91   #
    88     92   #		memdbg   = Enables the debugging memory allocator.
    89     93   #		compdbg  = Enables byte compilation logging.
    90     94   #
    91         -#	MACHINE=(IX86|IA64|ALPHA)
           95  +#	MACHINE=(IX86|IA64|ALPHA|AMD64)
    92     96   #		Set the machine type used for the compiler, linker, and
    93     97   #		resource compiler.  This hook is needed to tell the tools
    94     98   #		when alternate platforms are requested.  IX86 is the default
    95         -#		when not specified.
           99  +#		when not specified. If the CPU environment variable has been
          100  +#		set (ie: recent Platform SDK) then MACHINE is set from CPU.
    96    101   #
    97    102   #	TMP_DIR=<path>
    98    103   #	OUT_DIR=<path>
    99    104   #		Hooks to allow the intermediate and output directories to be
   100    105   #		changed.  $(OUT_DIR) is assumed to be 
   101    106   #		$(BINROOT)\(Release|Debug) based on if symbols are requested.
   102    107   #		$(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
................................................................................
   150    155   #
   151    156   # You need to specify the object files that need to be linked into your
   152    157   # binary here.
   153    158   #
   154    159   #-------------------------------------------------------------------------
   155    160   
   156    161   PROJECT = tls
          162  +
          163  +# Uncomment the following line if this is a Tk extension.
          164  +#PROJECT_REQUIRES_TK=1
   157    165   !include "rules.vc"
   158    166   
   159    167   DOTVERSION      = 1.5.1
   160    168   VERSION         = $(DOTVERSION:.=)
   161    169   STUBPREFIX      = $(PROJECT)stub
   162    170   
   163    171   DLLOBJS = \
................................................................................
   168    176   	$(TMP_DIR)\tls.res
   169    177   
   170    178   #-------------------------------------------------------------------------
   171    179   # Locate the OpenSSL library and headers
   172    180   #-------------------------------------------------------------------------
   173    181   
   174    182   !ifndef OPENSSL
   175         -OPENSSL = c:\opt
          183  +OPENSSL = c:\opt\openssl
   176    184   !endif
   177    185   
          186  +!ifndef SSL_INCLUDE_DIR
   178    187   SSL_INCLUDE_DIR = $(OPENSSL)\include
          188  +!endif
          189  +!ifndef SSL_LIB_DIR
   179    190   SSL_LIB_DIR     = $(OPENSSL)\lib
          191  +!endif
   180    192   
   181    193   SSL_LIBS        =-libpath:"$(SSL_LIB_DIR)" ssleay32s.lib libeay32s.lib
   182    194   
   183    195   SSL_CFLAGS      =-DNO_IDEA=1 -DNO_RC5=1
   184    196   
   185    197   !if !exist("$(SSL_LIB_DIR)\ssleay32s.lib")
   186    198   MSG = ^
          199  +Failed to locate "$(SSL_LIB_DIR)\ssleay32s.lib"
   187    200   You must provide the path to your OpenSSL library....
   188    201   !error $(MSG)
   189    202   !endif
   190    203   
   191    204   #-------------------------------------------------------------------------
   192    205   # Target names and paths ( shouldn't need changing )
   193    206   #-------------------------------------------------------------------------
................................................................................
   221    234   #---------------------------------------------------------------------
   222    235   # Compile flags
   223    236   #---------------------------------------------------------------------
   224    237   
   225    238   !if !$(DEBUG)
   226    239   !if $(OPTIMIZING)
   227    240   ### This cranks the optimization level to maximize speed
   228         -cdebug	= -O2 -Op -Gs
          241  +cdebug	= $(OPTIMIZATIONS)
   229    242   !else
   230    243   cdebug	=
   231    244   !endif
   232         -!else if "$(MACHINE)" == "IA64"
          245  +!else if "$(MACHINE)" == "IA64" #|| "$(MACHINE)" == "AMD64"
   233    246   ### Warnings are too many, can't support warnings into errors.
   234         -cdebug	= -Z7 -Od -GZ
          247  +cdebug	= -Zi -Od $(DEBUGFLAGS)
   235    248   !else
   236         -cdebug	= -Z7 -WX -Od -GZ
          249  +cdebug	= -Zi -WX $(DEBUGFLAGS)
   237    250   !endif
   238    251   
   239    252   ### Declarations common to all compiler options
   240         -cflags = -nologo -c -W3 -YX -Fp$(TMP_DIR)^\
          253  +cwarn = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
          254  +cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
   241    255   
   242         -!if $(PENT_0F_ERRATA)
   243         -cflags = $(cflags) -QI0f
   244         -!endif
   245         -
   246         -!if $(ITAN_B_ERRATA)
   247         -cflags = $(cflags) -QIA64_Bx
          256  +# Warning level
          257  +!if $(FULLWARNINGS)
          258  +cflags = $(cflags) -W4
          259  +!else
          260  +cflags = $(cflags) -W3
   248    261   !endif
   249    262   
   250    263   !if $(MSVCRT)
   251         -!if $(DEBUG)
          264  +!if $(DEBUG) && !$(UNCHECKED)
   252    265   crt = -MDd
   253    266   !else
   254    267   crt = -MD
   255    268   !endif
   256    269   !else
   257         -!if $(DEBUG)
          270  +!if $(DEBUG) && !$(UNCHECKED)
   258    271   crt = -MTd
   259    272   !else
   260    273   crt = -MT
   261    274   !endif
   262    275   !endif
          276  +
          277  +!if !$(STATIC_BUILD)
          278  +cflags = $(cflags) -DUSE_TCL_STUBS
          279  +!if defined(TKSTUBLIB)
          280  +cflags = $(cflags) -DUSE_TK_STUBS
          281  +!endif
          282  +!endif
   263    283   
   264    284   INCLUDES	= $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)" \
   265    285   		  -I"$(SSL_INCLUDE_DIR)"
   266         -BASE_CLFAGS	= $(cflags) $(cdebug) $(crt) $(INCLUDES)
          286  +BASE_CFLAGS	= $(cflags) $(cdebug) $(crt) $(INCLUDES)
   267    287   CON_CFLAGS	= $(cflags) $(cdebug) $(crt) -DCONSOLE
   268         -TCL_CFLAGS	= -DUSE_TCL_STUBS -DBUILD_$(PROJECT) $(SSL_CFLAGS) \
          288  +TCL_CFLAGS	= -DPACKAGE_NAME="\"$(PROJECT)\"" \
   269    289   		  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
   270         -                  -DPACKAGE_NAME="\"$(PROJECT)\"" \
   271         -		  $(BASE_CLFAGS) $(OPTDEFINES)
          290  +                  $(SSL_CFLAGS) \
          291  +		  $(BASE_CFLAGS) $(OPTDEFINES)
   272    292   
   273    293   #---------------------------------------------------------------------
   274    294   # Link flags
   275    295   #---------------------------------------------------------------------
   276    296   
   277    297   !if $(DEBUG)
   278    298   ldebug	= -debug:full -debugtype:cv
          299  +!if $(MSVCRT)
          300  +ldebug = $(ldebug) -nodefaultlib:msvcrt
          301  +!endif
   279    302   !else
   280    303   ldebug	= -release -opt:ref -opt:icf,3
   281    304   !endif
   282    305   
   283    306   ### Declarations common to all linker options
   284         -lflags	= -nologo -machine:$(MACHINE) $(ldebug)
          307  +lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
          308  +
          309  +!if $(FULLWARNINGS)
          310  +lflags = $(lflags) -warn:3
          311  +!endif
   285    312   
   286    313   !if $(PROFILE)
   287    314   lflags	= $(lflags) -profile
   288    315   !endif
   289    316   
   290    317   !if $(ALIGN98_HACK) && !$(STATIC_BUILD)
   291    318   ### Align sections for PE size savings.
................................................................................
   298    325   !if $(LOIMPACT)
   299    326   lflags	= $(lflags) -ws:aggressive
   300    327   !endif
   301    328   
   302    329   dlllflags = $(lflags) -dll
   303    330   conlflags = $(lflags) -subsystem:console
   304    331   guilflags = $(lflags) -subsystem:windows
   305         -baselibs  = $(TCLSTUBLIB) $(SSL_LIBS) ws2_32.lib user32.lib gdi32.lib advapi32.lib
          332  +!if !$(STATIC_BUILD)
          333  +baselibs  = $(TCLSTUBLIB)
          334  +!if defined(TKSTUBLIB)
          335  +baselibs  = $(baselibs) $(TKSTUBLIB)
          336  +!endif
          337  +!endif
          338  +
          339  +# Avoid 'unresolved external symbol __security_cookie' errors.
          340  +# c.f. http://support.microsoft.com/?id=894573
          341  +!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
          342  +baselibs   = $(baselibs) bufferoverflowU.lib
          343  +!endif
          344  +
          345  +baselibs  = $(baselibs) $(SSL_LIBS) ws2_32.lib user32.lib gdi32.lib advapi32.lib
   306    346   
   307    347   #---------------------------------------------------------------------
   308    348   # TclTest flags
   309    349   #---------------------------------------------------------------------
   310    350   
   311    351   !IF "$(TESTPAT)" != ""
   312    352   TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
................................................................................
   324    364   # have to handle the output differently on Win9x.
   325    365   #
   326    366   !if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
   327    367   test: setup $(PROJECT)
   328    368           set TCL_LIBRARY=$(ROOT)/library
   329    369           $(TCLSH) <<
   330    370   load $(PRJLIB:\=/)
   331         -source [file normalize [file join $(LIBDIR) tls.tcl]]
          371  +source [file join $(LIBDIR) tls.tcl]
   332    372   cd "$(ROOT)/tests"
   333    373   set argv "$(TESTFLAGS)"
   334    374   source all.tcl
   335    375   <<
   336    376   !else
   337    377   test: setup $(PROJECT)
   338    378           echo Please wait while the test results are collected
................................................................................
   349    389   
   350    390   setup:
   351    391   	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
   352    392   	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
   353    393   
   354    394   # See <tcl>/win/coffbase.txt for extension base addresses.
   355    395   $(PRJLIB): $(DLLOBJS)
          396  +!if $(STATIC_BUILD)
          397  +	$(lib32) -nologo -out:[email protected] @<<
          398  +$**
          399  +<<
          400  +!else
   356    401   	$(link32) $(dlllflags) -base:0x10780000 -out:[email protected] $(baselibs) @<<
   357    402   $**
   358    403   <<
          404  +	$(_VC_MANIFEST_EMBED_DLL)
   359    405   	[email protected] $*.exp
          406  +!endif
   360    407   
   361    408   $(PRJSTUBLIB): $(PRJSTUBOBJS)
   362    409   	$(lib32) -nologo -out:[email protected] $(PRJSTUBOBJS)
   363    410   
   364    411   #---------------------------------------------------------------------
   365    412   # Implicit rules
   366    413   #---------------------------------------------------------------------
................................................................................
   378    425   {$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
   379    426       $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
   380    427   $<
   381    428   <<
   382    429   
   383    430   {$(WINDIR)}.rc{$(TMP_DIR)}.res:
   384    431   	$(rc32) -fo [email protected] -r -i "$(GENERICDIR)" -D__WIN32__ \
   385         -                -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
   386         -                -DDOTVERSION=\"$(DOTVERSION)\" \
   387         -                -DVERSION=\"$(VERSION)$(SUFX)\" \
          432  +		-DCOMMAVERSION=$(DOTVERSION:.=,),0 \
          433  +		-DDOTVERSION=\"$(DOTVERSION)\" \
          434  +		-DVERSION=\"$(VERSION)$(SUFX)\" \
   388    435   !if $(DEBUG)
   389    436   	-d DEBUG \
   390    437   !endif
   391    438   !if $(TCL_THREADS)
   392    439   	-d TCL_THREADS \
   393    440   !endif
   394    441   !if $(STATIC_BUILD)
   395    442   	-d STATIC_BUILD \
   396    443   !endif
   397    444   	$<
   398    445   
   399    446   .SUFFIXES:
   400    447   .SUFFIXES:.c .rc
          448  +
          449  +#-------------------------------------------------------------------------
          450  +# Explicit dependency rules
          451  +#
          452  +#-------------------------------------------------------------------------
          453  +
          454  +$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
          455  +	nmakehlp -s << $** > [email protected]
          456  +@[email protected]    $(DOTVERSION)
          457  +@[email protected]       $(PROJECT)
          458  +@[email protected]       $(PRJLIBNAME)
          459  +<<
   401    460   
   402    461   #---------------------------------------------------------------------
   403    462   # Installation. (EDIT)
   404    463   #
   405    464   # You may need to modify this section to reflect the final distribution
   406    465   # of your files and possibly to generate documentation.
   407    466   #
................................................................................
   429    488   #---------------------------------------------------------------------
   430    489   # Clean up
   431    490   #---------------------------------------------------------------------
   432    491   
   433    492   clean:
   434    493   	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
   435    494   	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
          495  +	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
          496  +	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
          497  +	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
   436    498   
   437    499   realclean: clean
   438    500   	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
   439    501   
   440    502   distclean: realclean
   441    503   	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
   442    504   	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj

Modified win/nmakehlp.c from [5a07dd3536] to [2ea691567c].

     1         -/* ----------------------------------------------------------------------------
            1  +/*
            2  + * ----------------------------------------------------------------------------
     2      3    * nmakehlp.c --
     3      4    *
     4      5    *	This is used to fix limitations within nmake and the environment.
     5      6    *
     6      7    * Copyright (c) 2002 by David Gravereaux.
     7         - * Copyright (c) 2003 by Patrick Thoyts
            8  + * Copyright (c) 2006 by Pat Thoyts
     8      9    *
     9         - * See the file "license.terms" for information on usage and redistribution
    10         - * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
           10  + * See the file "license.terms" for information on usage and redistribution of
           11  + * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    11     12    *
    12     13    * ----------------------------------------------------------------------------
    13         - * RCS: @(#) $Id: nmakehlp.c,v 1.1 2004/12/17 16:02:06 patthoyts Exp $
           14  + * RCS: @(#) $Id: nmakehlp.c,v 1.2 2007/09/06 21:01:55 patthoyts Exp $
    14     15    * ----------------------------------------------------------------------------
    15     16    */
           17  +
           18  +#define _CRT_SECURE_NO_DEPRECATE
    16     19   #include <windows.h>
    17         -#include <stdio.h>
    18     20   #pragma comment (lib, "user32.lib")
    19     21   #pragma comment (lib, "kernel32.lib")
           22  +#include <stdio.h>
           23  +#include <math.h>
           24  +#if defined(_M_IA64) || defined(_M_AMD64)
           25  +#pragma comment(lib, "bufferoverflowU")
           26  +#endif
           27  +
           28  +/* ISO hack for dumb VC++ */
           29  +#ifdef _MSC_VER
           30  +#define   snprintf	_snprintf
           31  +#endif
           32  +
           33  +
    20     34   
    21     35   /* protos */
    22         -int CheckForCompilerFeature (const char *option);
    23         -int CheckForLinkerFeature (const char *option);
    24         -int IsIn (const char *string, const char *substring);
    25         -DWORD WINAPI ReadFromPipe (LPVOID args);
    26         -int GetVersionFromHeader(const char *tclh, const char *tkh);
           36  +
           37  +int		CheckForCompilerFeature(const char *option);
           38  +int		CheckForLinkerFeature(const char *option);
           39  +int		IsIn(const char *string, const char *substring);
           40  +int		GrepForDefine(const char *file, const char *string);
           41  +int		SubstituteFile(const char *substs, const char *filename);
           42  +const char *    GetVersionFromFile(const char *filename, const char *match);
           43  +DWORD WINAPI	ReadFromPipe(LPVOID args);
    27     44   
    28     45   /* globals */
           46  +
           47  +#define CHUNK	25
           48  +#define STATICBUFFERSIZE    1000
    29     49   typedef struct {
    30     50       HANDLE pipe;
    31         -    char buffer[1000];
           51  +    char buffer[STATICBUFFERSIZE];
    32     52   } pipeinfo;
    33     53   
    34     54   pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
    35     55   pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
           56  +
           57  +/*
           58  + * exitcodes: 0 == no, 1 == yes, 2 == error
           59  + */
    36     60   
    37         -
    38         -
    39         -/* exitcodes: 0 == no, 1 == yes, 2 == error */
    40     61   int
    41         -main (int argc, char *argv[])
           62  +main(
           63  +    int argc,
           64  +    char *argv[])
    42     65   {
    43     66       char msg[300];
    44     67       DWORD dwWritten;
    45     68       int chars;
    46     69   
           70  +    /*
           71  +     * Make sure children (cl.exe and link.exe) are kept quiet.
           72  +     */
           73  +
           74  +    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
           75  +
           76  +    /*
           77  +     * Make sure the compiler and linker aren't effected by the outside world.
           78  +     */
           79  +
           80  +    SetEnvironmentVariable("CL", "");
           81  +    SetEnvironmentVariable("LINK", "");
           82  +
    47     83       if (argc > 1 && *argv[1] == '-') {
    48     84   	switch (*(argv[1]+1)) {
    49     85   	case 'c':
    50     86   	    if (argc != 3) {
    51         -		chars = wsprintf(msg, "usage: %s -c <compiler option>\n"
           87  +		chars = snprintf(msg, sizeof(msg) - 1,
           88  +		        "usage: %s -c <compiler option>\n"
    52     89   			"Tests for whether cl.exe supports an option\n"
    53     90   			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
    54         -		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
           91  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
           92  +			&dwWritten, NULL);
    55     93   		return 2;
    56     94   	    }
    57     95   	    return CheckForCompilerFeature(argv[2]);
    58     96   	case 'l':
    59     97   	    if (argc != 3) {
    60         -		chars = wsprintf(msg, "usage: %s -l <linker option>\n"
           98  +		chars = snprintf(msg, sizeof(msg) - 1,
           99  +	       		"usage: %s -l <linker option>\n"
    61    100   			"Tests for whether link.exe supports an option\n"
    62    101   			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
    63         -		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
          102  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          103  +			&dwWritten, NULL);
    64    104   		return 2;
    65    105   	    }
    66    106   	    return CheckForLinkerFeature(argv[2]);
    67    107   	case 'f':
    68    108   	    if (argc == 2) {
    69         -		chars = wsprintf(msg, "usage: %s -f <string> <substring>\n"
    70         -		    "Find a substring within another\n"
    71         -		    "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
    72         -		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
          109  +		chars = snprintf(msg, sizeof(msg) - 1,
          110  +			"usage: %s -f <string> <substring>\n"
          111  +			"Find a substring within another\n"
          112  +			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
          113  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          114  +			&dwWritten, NULL);
    73    115   		return 2;
    74    116   	    } else if (argc == 3) {
    75         -		/* if the string is blank, there is no match */
          117  +		/*
          118  +		 * If the string is blank, there is no match.
          119  +		 */
          120  +
    76    121   		return 0;
    77    122   	    } else {
    78    123   		return IsIn(argv[2], argv[3]);
    79    124   	    }
    80         -	case 'v':
          125  +	case 'g':
          126  +	    if (argc == 2) {
          127  +		chars = snprintf(msg, sizeof(msg) - 1,
          128  +			"usage: %s -g <file> <string>\n"
          129  +			"grep for a #define\n"
          130  +			"exitcodes: integer of the found string (no decimals)\n",
          131  +			argv[0]);
          132  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          133  +			&dwWritten, NULL);
          134  +		return 2;
          135  +	    }
          136  +	    return GrepForDefine(argv[2], argv[3]);
          137  +	case 's':
          138  +	    if (argc == 2) {
          139  +		chars = snprintf(msg, sizeof(msg) - 1,
          140  +			"usage: %s -s <substitutions file> <file>\n"
          141  +			"Perform a set of string map type substutitions on a file\n"
          142  +			"exitcodes: 0\n",
          143  +			argv[0]);
          144  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          145  +			&dwWritten, NULL);
          146  +		return 2;
          147  +	    }
          148  +	    return SubstituteFile(argv[2], argv[3]);
          149  +	case 'V':
    81    150   	    if (argc != 4) {
    82         -		chars = wsprintf(msg, "usage: %s -v <tcl.h> <tk.h>\n"
    83         -		    "Search for versions from the tcl and tk headers.",
          151  +		chars = snprintf(msg, sizeof(msg) - 1,
          152  +		    "usage: %s -V filename matchstring\n"
          153  +		    "Extract a version from a file:\n"
          154  +		    "eg: pkgIndex.tcl \"package ifneeded http\"",
    84    155   		    argv[0]);
    85         -		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
          156  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          157  +		    &dwWritten, NULL);
    86    158   		return 0;
    87    159   	    }
    88         -	    return GetVersionFromHeader(argv[2], argv[3]);
          160  +	    printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
          161  +	    return 0;
    89    162   	}
    90    163       }
    91         -    chars = wsprintf(msg, "usage: %s -c|-l|-f ...\n"
          164  +    chars = snprintf(msg, sizeof(msg) - 1,
          165  +	    "usage: %s -c|-l|-f|-g|-V ...\n"
    92    166   	    "This is a little helper app to equalize shell differences between WinNT and\n"
    93    167   	    "Win9x and get nmake.exe to accomplish its job.\n",
    94    168   	    argv[0]);
    95    169       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
    96    170       return 2;
    97    171   }
    98         -
          172  +
    99    173   int
   100         -CheckForCompilerFeature (const char *option)
          174  +CheckForCompilerFeature(
          175  +    const char *option)
   101    176   {
   102    177       STARTUPINFO si;
   103    178       PROCESS_INFORMATION pi;
   104    179       SECURITY_ATTRIBUTES sa;
   105    180       DWORD threadID;
   106    181       char msg[300];
   107    182       BOOL ok;
................................................................................
   117    192       si.hStdInput = INVALID_HANDLE_VALUE;
   118    193   
   119    194       ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
   120    195       sa.nLength = sizeof(SECURITY_ATTRIBUTES);
   121    196       sa.lpSecurityDescriptor = NULL;
   122    197       sa.bInheritHandle = FALSE;
   123    198   
   124         -    /* create a non-inheritible pipe. */
          199  +    /*
          200  +     * Create a non-inheritible pipe.
          201  +     */
          202  +
   125    203       CreatePipe(&Out.pipe, &h, &sa, 0);
   126    204   
   127         -    /* dupe the write side, make it inheritible, and close the original. */
   128         -    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 
   129         -	    0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          205  +    /*
          206  +     * Dupe the write side, make it inheritible, and close the original.
          207  +     */
   130    208   
   131         -    /* Same as above, but for the error side. */
          209  +    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
          210  +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          211  +
          212  +    /*
          213  +     * Same as above, but for the error side.
          214  +     */
          215  +
   132    216       CreatePipe(&Err.pipe, &h, &sa, 0);
   133         -    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 
   134         -	    0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          217  +    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
          218  +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
   135    219   
   136         -    /* base command line */
   137         -    strcpy(cmdline, "cl.exe -nologo -c -TC -Fdtemp ");
   138         -    /* append our option for testing */
   139         -    strcat(cmdline, option);
   140         -    /* filename to compile, which exists, but is nothing and empty. */
   141         -    strcat(cmdline, " nul");
          220  +    /*
          221  +     * Base command line.
          222  +     */
          223  +
          224  +    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
          225  +
          226  +    /*
          227  +     * Append our option for testing
          228  +     */
          229  +
          230  +    lstrcat(cmdline, option);
          231  +
          232  +    /*
          233  +     * Filename to compile, which exists, but is nothing and empty.
          234  +     */
          235  +
          236  +    lstrcat(cmdline, " .\\nul");
   142    237   
   143    238       ok = CreateProcess(
   144    239   	    NULL,	    /* Module name. */
   145    240   	    cmdline,	    /* Command line. */
   146    241   	    NULL,	    /* Process handle not inheritable. */
   147    242   	    NULL,	    /* Thread handle not inheritable. */
   148    243   	    TRUE,	    /* yes, inherit handles. */
................................................................................
   150    245   	    NULL,	    /* Use parent's environment block. */
   151    246   	    NULL,	    /* Use parent's starting directory. */
   152    247   	    &si,	    /* Pointer to STARTUPINFO structure. */
   153    248   	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */
   154    249   
   155    250       if (!ok) {
   156    251   	DWORD err = GetLastError();
   157         -	int chars = wsprintf(msg, "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
          252  +	int chars = snprintf(msg, sizeof(msg) - 1,
          253  +		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
   158    254   
   159         -	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
   160         -		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID) &msg[chars],
          255  +	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
          256  +		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
   161    257   		(300-chars), 0);
   162         -	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, strlen(msg), &err, NULL);
          258  +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
   163    259   	return 2;
   164    260       }
   165    261   
   166         -    /* close our references to the write handles that have now been inherited. */
          262  +    /*
          263  +     * Close our references to the write handles that have now been inherited.
          264  +     */
          265  +
   167    266       CloseHandle(si.hStdOutput);
   168    267       CloseHandle(si.hStdError);
   169    268   
   170    269       WaitForInputIdle(pi.hProcess, 5000);
   171    270       CloseHandle(pi.hThread);
   172    271   
   173         -    /* start the pipe reader threads. */
          272  +    /*
          273  +     * Start the pipe reader threads.
          274  +     */
          275  +
   174    276       pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
   175    277       pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
   176    278   
   177         -    /* block waiting for the process to end. */
          279  +    /*
          280  +     * Block waiting for the process to end.
          281  +     */
          282  +
   178    283       WaitForSingleObject(pi.hProcess, INFINITE);
   179    284       CloseHandle(pi.hProcess);
   180    285   
   181         -    /* clean up temporary files before returning */
   182         -    DeleteFile("temp.idb");
   183         -    DeleteFile("temp.pdb");
          286  +    /*
          287  +     * Wait for our pipe to get done reading, should it be a little slow.
          288  +     */
   184    289   
   185         -    /* wait for our pipe to get done reading, should it be a little slow. */
   186    290       WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
   187    291       CloseHandle(pipeThreads[0]);
   188    292       CloseHandle(pipeThreads[1]);
   189    293   
   190         -    /* look for the commandline warning code in both streams. */
   191         -    return !(strstr(Out.buffer, "D4002") != NULL || strstr(Err.buffer, "D4002") != NULL);
          294  +    /*
          295  +     * Look for the commandline warning code in both streams.
          296  +     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
          297  +     */
          298  +
          299  +    return !(strstr(Out.buffer, "D4002") != NULL
          300  +             || strstr(Err.buffer, "D4002") != NULL
          301  +             || strstr(Out.buffer, "D9002") != NULL
          302  +             || strstr(Err.buffer, "D9002") != NULL);
   192    303   }
   193         -
          304  +
   194    305   int
   195         -CheckForLinkerFeature (const char *option)
          306  +CheckForLinkerFeature(
          307  +    const char *option)
   196    308   {
   197    309       STARTUPINFO si;
   198    310       PROCESS_INFORMATION pi;
   199    311       SECURITY_ATTRIBUTES sa;
   200    312       DWORD threadID;
   201    313       char msg[300];
   202    314       BOOL ok;
................................................................................
   212    324       si.hStdInput = INVALID_HANDLE_VALUE;
   213    325   
   214    326       ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
   215    327       sa.nLength = sizeof(SECURITY_ATTRIBUTES);
   216    328       sa.lpSecurityDescriptor = NULL;
   217    329       sa.bInheritHandle = TRUE;
   218    330   
   219         -    /* create a non-inheritible pipe. */
          331  +    /*
          332  +     * Create a non-inheritible pipe.
          333  +     */
          334  +
   220    335       CreatePipe(&Out.pipe, &h, &sa, 0);
   221    336   
   222         -    /* dupe the write side, make it inheritible, and close the original. */
   223         -    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 
   224         -	    0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          337  +    /*
          338  +     * Dupe the write side, make it inheritible, and close the original.
          339  +     */
   225    340   
   226         -    /* Same as above, but for the error side. */
          341  +    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
          342  +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          343  +
          344  +    /*
          345  +     * Same as above, but for the error side.
          346  +     */
          347  +
   227    348       CreatePipe(&Err.pipe, &h, &sa, 0);
   228         -    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 
   229         -	    0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          349  +    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
          350  +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
   230    351   
   231         -    /* base command line */
   232         -    strcpy(cmdline, "link.exe -nologo ");
   233         -    /* append our option for testing */
   234         -    strcat(cmdline, option);
   235         -    /* filename to compile, which exists, but is nothing and empty. */
   236         -//    strcat(cmdline, " nul");
          352  +    /*
          353  +     * Base command line.
          354  +     */
          355  +
          356  +    lstrcpy(cmdline, "link.exe -nologo ");
          357  +
          358  +    /*
          359  +     * Append our option for testing.
          360  +     */
          361  +
          362  +    lstrcat(cmdline, option);
   237    363   
   238    364       ok = CreateProcess(
   239    365   	    NULL,	    /* Module name. */
   240    366   	    cmdline,	    /* Command line. */
   241    367   	    NULL,	    /* Process handle not inheritable. */
   242    368   	    NULL,	    /* Thread handle not inheritable. */
   243    369   	    TRUE,	    /* yes, inherit handles. */
................................................................................
   245    371   	    NULL,	    /* Use parent's environment block. */
   246    372   	    NULL,	    /* Use parent's starting directory. */
   247    373   	    &si,	    /* Pointer to STARTUPINFO structure. */
   248    374   	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */
   249    375   
   250    376       if (!ok) {
   251    377   	DWORD err = GetLastError();
   252         -	int chars = wsprintf(msg, "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
          378  +	int chars = snprintf(msg, sizeof(msg) - 1,
          379  +		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
   253    380   
   254         -	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
   255         -		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID) &msg[chars],
          381  +	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
          382  +		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
   256    383   		(300-chars), 0);
   257         -	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, strlen(msg), &err, NULL);
          384  +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
   258    385   	return 2;
   259    386       }
   260    387   
   261         -    /* close our references to the write handles that have now been inherited. */
          388  +    /*
          389  +     * Close our references to the write handles that have now been inherited.
          390  +     */
          391  +
   262    392       CloseHandle(si.hStdOutput);
   263    393       CloseHandle(si.hStdError);
   264    394   
   265    395       WaitForInputIdle(pi.hProcess, 5000);
   266    396       CloseHandle(pi.hThread);
   267    397   
   268         -    /* start the pipe reader threads. */
          398  +    /*
          399  +     * Start the pipe reader threads.
          400  +     */
          401  +
   269    402       pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
   270    403       pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
   271    404   
   272         -    /* block waiting for the process to end. */
          405  +    /*
          406  +     * Block waiting for the process to end.
          407  +     */
          408  +
   273    409       WaitForSingleObject(pi.hProcess, INFINITE);
   274    410       CloseHandle(pi.hProcess);
   275    411   
   276         -    /* wait for our pipe to get done reading, should it be a little slow. */
          412  +    /*
          413  +     * Wait for our pipe to get done reading, should it be a little slow.
          414  +     */
          415  +
   277    416       WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
   278    417       CloseHandle(pipeThreads[0]);
   279    418       CloseHandle(pipeThreads[1]);
   280    419   
   281         -    /* look for the commandline warning code in the stderr stream. */
   282         -    return !(strstr(Out.buffer, "LNK1117") != NULL || strstr(Err.buffer, "LNK1117") != NULL);
          420  +    /*
          421  +     * Look for the commandline warning code in the stderr stream.
          422  +     */
          423  +
          424  +    return !(strstr(Out.buffer, "LNK1117") != NULL ||
          425  +	    strstr(Err.buffer, "LNK1117") != NULL ||
          426  +	    strstr(Out.buffer, "LNK4044") != NULL ||
          427  +	    strstr(Err.buffer, "LNK4044") != NULL);
   283    428   }
   284         -
          429  +
   285    430   DWORD WINAPI
   286         -ReadFromPipe (LPVOID args)
          431  +ReadFromPipe(
          432  +    LPVOID args)
   287    433   {
   288    434       pipeinfo *pi = (pipeinfo *) args;
   289    435       char *lastBuf = pi->buffer;
   290    436       DWORD dwRead;
   291    437       BOOL ok;
   292    438   
   293         -again:
   294         -    ok = ReadFile(pi->pipe, lastBuf, 25, &dwRead, 0L);
          439  +  again:
          440  +    if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
          441  +	CloseHandle(pi->pipe);
          442  +	return (DWORD)-1;
          443  +    }
          444  +    ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
   295    445       if (!ok || dwRead == 0) {
   296    446   	CloseHandle(pi->pipe);
   297    447   	return 0;
   298    448       }
   299    449       lastBuf += dwRead;
   300    450       goto again;
   301    451   
   302    452       return 0;  /* makes the compiler happy */
   303    453   }
   304         -
          454  +
   305    455   int
   306         -IsIn (const char *string, const char *substring)
          456  +IsIn(
          457  +    const char *string,
          458  +    const char *substring)
   307    459   {
   308    460       return (strstr(string, substring) != NULL);
   309    461   }
          462  +
          463  +/*
          464  + * Find a specified #define by name.
          465  + *
          466  + * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
          467  + */
   310    468   
   311         -	
   312         -static double
   313         -ReadVersionFromHeader(const char *file, const char *macro)
          469  +int
          470  +GrepForDefine(
          471  +    const char *file,
          472  +    const char *string)
          473  +{
          474  +    char s1[51], s2[51], s3[51];
          475  +    FILE *f = fopen(file, "rt");
          476  +
          477  +    if (f == NULL) {
          478  +	return 0;
          479  +    }
          480  +
          481  +    do {
          482  +	int r = fscanf(f, "%50s", s1);
          483  +
          484  +	if (r == 1 && !strcmp(s1, "#define")) {
          485  +	    /*
          486  +	     * Get next two words.
          487  +	     */
          488  +
          489  +	    r = fscanf(f, "%50s %50s", s2, s3);
          490  +	    if (r != 2) {
          491  +		continue;
          492  +	    }
          493  +
          494  +	    /*
          495  +	     * Is the first word what we're looking for?
          496  +	     */
          497  +
          498  +	    if (!strcmp(s2, string)) {
          499  +		double d1;
          500  +
          501  +		fclose(f);
          502  +
          503  +		/*
          504  +		 * Add 1 past first double quote char. "8.5"
          505  +		 */
          506  +
          507  +		d1 = atof(s3 + 1);		  /*    8.5  */
          508  +		while (floor(d1) != d1) {
          509  +		    d1 *= 10.0;
          510  +		}
          511  +		return ((int) d1);		  /*    85   */
          512  +	    }
          513  +	}
          514  +    } while (!feof(f));
          515  +
          516  +    fclose(f);
          517  +    return 0;
          518  +}
          519  +
          520  +/*
          521  + * GetVersionFromFile --
          522  + * 	Looks for a match string in a file and then returns the version
          523  + * 	following the match where a version is anything acceptable to
          524  + * 	package provide or package ifneeded.
          525  + */
          526  +
          527  +const char *
          528  +GetVersionFromFile(
          529  +    const char *filename,
          530  +    const char *match)
   314    531   {
   315         -    double d = 0.0;
   316         -    CHAR szBuffer[100];
   317         -    LPSTR p;
   318         -    DWORD cbBuffer = 100;
   319         -    FILE *fp = fopen(file, "r");
          532  +    size_t cbBuffer = 100;
          533  +    static char szBuffer[100];
          534  +    char *szResult = NULL;
          535  +    FILE *fp = fopen(filename, "rt");
          536  +
   320    537       if (fp != NULL) {
          538  +	/*
          539  +	 * Read data until we see our match string.
          540  +	 */
          541  +
   321    542   	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
   322         -	    if ((p = strstr(szBuffer, macro)) != NULL) {
   323         -		while (*p && !isdigit(*p)) ++p;
   324         -		d = strtod(p, NULL);
          543  +	    LPSTR p, q;
          544  +
          545  +	    p = strstr(szBuffer, match);
          546  +	    if (p != NULL) {
          547  +		/*
          548  +		 * Skip to first digit.
          549  +		 */
          550  +
          551  +		while (*p && !isdigit(*p)) {
          552  +		    ++p;
          553  +		}
          554  +
          555  +		/*
          556  +		 * Find ending whitespace.
          557  +		 */
          558  +
          559  +		q = p;
          560  +		while (*q && (isalnum(*q) || *q == '.')) {
          561  +		    ++q;
          562  +		}
          563  +
          564  +		memcpy(szBuffer, p, q - p);
          565  +		szBuffer[q-p] = 0;
          566  +		szResult = szBuffer;
   325    567   		break;
   326    568   	    }
   327    569   	}
   328    570   	fclose(fp);
   329    571       }
   330         -    return d;
          572  +    return szResult;
          573  +}
          574  +
          575  +/*
          576  + * List helpers for the SubstituteFile function
          577  + */
          578  +
          579  +typedef struct list_item_t {
          580  +    struct list_item_t *nextPtr;
          581  +    char * key;
          582  +    char * value;
          583  +} list_item_t;
          584  +
          585  +/* insert a list item into the list (list may be null) */
          586  +static list_item_t *
          587  +list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
          588  +{
          589  +    list_item_t *itemPtr = malloc(sizeof(list_item_t));
          590  +    if (itemPtr) {
          591  +	itemPtr->key = strdup(key);
          592  +	itemPtr->value = strdup(value);
          593  +	itemPtr->nextPtr = NULL;
          594  +
          595  +	while(*listPtrPtr) {
          596  +	    listPtrPtr = &(*listPtrPtr)->nextPtr;
          597  +	}
          598  +	*listPtrPtr = itemPtr;
          599  +    }
          600  +    return itemPtr;
          601  +}
          602  +
          603  +static void
          604  +list_free(list_item_t **listPtrPtr)
          605  +{
          606  +    list_item_t *tmpPtr, *listPtr = *listPtrPtr;
          607  +    while (listPtr) {
          608  +	tmpPtr = listPtr;
          609  +	listPtr = listPtr->nextPtr;
          610  +	free(tmpPtr->key);
          611  +	free(tmpPtr->value);
          612  +	free(tmpPtr);
          613  +    }
   331    614   }
          615  +
          616  +/*
          617  + * SubstituteFile --
          618  + *	As windows doesn't provide anything useful like sed and it's unreliable
          619  + *	to use the tclsh you are building against (consider x-platform builds -
          620  + *	eg compiling AMD64 target from IX86) we provide a simple substitution
          621  + *	option here to handle autoconf style substitutions.
          622  + *	The substitution file is whitespace and line delimited. The file should
          623  + *	consist of lines matching the regular expression:
          624  + *	  \s*\S+\s+\S*$
          625  + *
          626  + *	Usage is something like:
          627  + *	  nmakehlp -S << $** > [email protected]
          628  + *        @[email protected] $(PACKAGE_NAME)
          629  + *        @[email protected] $(PACKAGE_VERSION)
          630  + *        <<
          631  + */
   332    632   
   333    633   int
   334         -GetVersionFromHeader(const char *tclh, const char *tkh)
          634  +SubstituteFile(
          635  +    const char *substitutions,
          636  +    const char *filename)
   335    637   {
   336         -    double dTcl = 0.0, dTk = 0.0;
   337         -    
   338         -    if (tclh != NULL)
   339         -	dTcl = ReadVersionFromHeader(tclh, "TCL_VERSION");
   340         -    if (tkh != NULL)
   341         -	dTk = ReadVersionFromHeader(tkh, "TK_VERSION");
          638  +    size_t cbBuffer = 1024;
          639  +    static char szBuffer[1024], szCopy[1024];
          640  +    char *szResult = NULL;
          641  +    list_item_t *substPtr = NULL;
          642  +    FILE *fp, *sp;
          643  +
          644  +    fp = fopen(filename, "rt");
          645  +    if (fp != NULL) {
          646  +
          647  +	/*
          648  +	 * Build a list of substutitions from the first filename
          649  +	 */
          650  +
          651  +	sp = fopen(substitutions, "rt");
          652  +	if (sp != NULL) {
          653  +	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
          654  +		char *ks, *ke, *vs, *ve;
          655  +		ks = szBuffer;
          656  +		while (ks && *ks && isspace(*ks)) ++ks;
          657  +		ke = ks;
          658  +		while (ke && *ke && !isspace(*ke)) ++ke;
          659  +		vs = ke;
          660  +		while (vs && *vs && isspace(*vs)) ++vs;
          661  +		ve = vs;
          662  +		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
          663  +		*ke = 0, *ve = 0;
          664  +		list_insert(&substPtr, ks, vs);
          665  +	    }
          666  +	    fclose(sp);
          667  +	}
   342    668   
   343         -    if (dTcl > 0 || dTk > 0) {
   344         -	FILE *ofp = fopen("version.vc", "w");
   345         -	if (dTcl > 0)
   346         -	    fprintf(ofp, "TCL_DOTVERSION\t= %0.1f\nTCL_VERSION\t= %u\n",
   347         -		    dTcl, (int)(dTcl * 10.0));
   348         -	if (dTk > 0)
   349         -	    fprintf(ofp, "TK_DOTVERSION\t= %0.1f\nTK_VERSION\t= %u\n",
   350         -		    dTk, (int)(dTk * 10.0));
   351         -	fclose(ofp);
   352         -	return 0;
          669  +	/* debug: dump the list */
          670  +#ifdef _DEBUG
          671  +	{
          672  +	    int n = 0;
          673  +	    list_item_t *p = NULL;
          674  +	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
          675  +		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
          676  +	    }
          677  +	}
          678  +#endif
          679  +	
          680  +	/*
          681  +	 * Run the substitutions over each line of the input
          682  +	 */
          683  +	
          684  +	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
          685  +	    list_item_t *p = NULL;
          686  +	    for (p = substPtr; p != NULL; p = p->nextPtr) {
          687  +		char *m = strstr(szBuffer, p->key);
          688  +		if (m) {
          689  +		    char *cp, *op, *sp;
          690  +		    cp = szCopy;
          691  +		    op = szBuffer;
          692  +		    while (op != m) *cp++ = *op++;
          693  +		    sp = p->value;
          694  +		    while (sp && *sp) *cp++ = *sp++;
          695  +		    op += strlen(p->key);
          696  +		    while (*op) *cp++ = *op++;
          697  +		    *cp = 0;
          698  +		    memcpy(szBuffer, szCopy, sizeof(szCopy));
          699  +		}
          700  +	    }
          701  +	    printf(szBuffer);
          702  +	}
          703  +	
          704  +	list_free(&substPtr);
   353    705       }
   354         -    return 1;
          706  +    fclose(fp);
          707  +    return 0;
   355    708   }
          709  +
          710  +/*
          711  + * Local variables:
          712  + *   mode: c
          713  + *   c-basic-offset: 4
          714  + *   fill-column: 78
          715  + *   indent-tabs-mode: t
          716  + *   tab-width: 8
          717  + * End:
          718  + */

Modified win/rules.vc from [f7a656a7f6] to [ca811b113c].

     7      7   #	This version is modified from the Tcl source version to support
     8      8   #	building extensions using nmake.
     9      9   #
    10     10   # See the file "license.terms" for information on usage and redistribution
    11     11   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    12     12   # 
    13     13   # Copyright (c) 2001-2002 David Gravereaux.
    14         -# Copyright (c) 2003 Patrick Thoyts
           14  +# Copyright (c) 2003-2005 Patrick Thoyts
    15     15   #
    16     16   #------------------------------------------------------------------------------
    17         -# RCS: @(#) $Id: rules.vc,v 1.1 2004/12/17 16:02:06 patthoyts Exp $
           17  +# RCS: @(#) $Id: rules.vc,v 1.2 2007/09/06 21:01:55 patthoyts Exp $
    18     18   #------------------------------------------------------------------------------
    19     19   
    20     20   !ifndef _RULES_VC
    21     21   _RULES_VC = 1
    22     22   
    23     23   cc32		= $(CC)   # built-in default.
    24     24   link32		= link
................................................................................
    30     30   _INSTALLDIR	= C:\Program Files\Tcl
    31     31   !else
    32     32   ### Fix the path separators.
    33     33   _INSTALLDIR	= $(INSTALLDIR:/=\)
    34     34   !endif
    35     35   
    36     36   !ifndef MACHINE
    37         -MACHINE		= IX86
           37  +!if "$(CPU)" == "" || "$(CPU)" == "i386"
           38  +MACHINE         = IX86
           39  +!else
           40  +MACHINE         = $(CPU)
           41  +!endif
    38     42   !endif
    39     43   
    40     44   !ifndef CFG_ENCODING
    41     45   CFG_ENCODING	= \"cp1252\"
    42     46   !endif
    43     47   
    44     48   #----------------------------------------------------------
................................................................................
    45     49   # Set the proper copy method to avoid overwrite questions
    46     50   # to the user when copying files and selecting the right
    47     51   # "delete all" method.
    48     52   #----------------------------------------------------------
    49     53   
    50     54   !if "$(OS)" == "Windows_NT"
    51     55   RMDIR	= rmdir /S /Q
           56  +ERRNULL  = 2>NUL
    52     57   !if ![ver | find "4.0" > nul]
    53         -CPY	= echo y | xcopy /i
           58  +CPY	= echo y | xcopy /i >NUL
           59  +COPY	= copy >NUL
    54     60   !else
    55         -CPY	= xcopy /i /y
           61  +CPY	= xcopy /i /y >NUL
           62  +COPY	= copy /y >NUL
    56     63   !endif
    57         -!else
    58         -CPY	= xcopy /i
           64  +!else # "$(OS)" != "Windows_NT"
           65  +CPY	= xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
           66  +COPY	= copy >_JUNK.OUT # On Win98 NUL does not work here.
    59     67   RMDIR	= deltree /Y
           68  +NULL    = \NUL # Used in testing directory existence
           69  +ERRNULL = >NUL # Win9x shell cannot redirect stderr
    60     70   !endif
    61         -
           71  +MKDIR   = mkdir
    62     72   
    63     73   !message ===============================================================================
    64     74   
    65     75   #----------------------------------------------------------
    66     76   # build the helper app we need to overcome nmake's limiting
    67     77   # environment.
    68     78   #----------------------------------------------------------
    69     79   
    70     80   !if !exist(nmakehlp.exe)
    71         -!if [$(cc32) -nologo -ML nmakehlp.c -link -subsystem:console > nul]
           81  +!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
    72     82   !endif
    73     83   !endif
    74     84   
    75     85   #----------------------------------------------------------
    76     86   # Test for compiler features
    77     87   #----------------------------------------------------------
    78     88   
    79     89   ### test for optimizations
    80         -!if [nmakehlp -c -Otip]
           90  +!if [nmakehlp -c -Ot]
    81     91   !message *** Compiler has 'Optimizations'
    82     92   OPTIMIZING	= 1
    83     93   !else
    84     94   !message *** Compiler doesn't have 'Optimizations'
    85     95   OPTIMIZING	= 0
    86     96   !endif
           97  +
           98  +OPTIMIZATIONS  =
           99  +
          100  +!if [nmakehlp -c -Ot]
          101  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
          102  +!endif
          103  +
          104  +!if [nmakehlp -c -Oi]
          105  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
          106  +!endif
          107  +
          108  +!if [nmakehlp -c -Op]
          109  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
          110  +!endif
          111  +
          112  +!if [nmakehlp -c -fp:strict]
          113  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
          114  +!endif
          115  +
          116  +!if [nmakehlp -c -Gs]
          117  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
          118  +!endif
          119  +
          120  +!if [nmakehlp -c -GS]
          121  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
          122  +!endif
          123  +
          124  +!if [nmakehlp -c -GL]
          125  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
          126  +!endif
          127  +
          128  +DEBUGFLAGS     =
          129  +
          130  +!if [nmakehlp -c -RTC1]
          131  +DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
          132  +!elseif [nmakehlp -c -GZ]
          133  +DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
          134  +!endif
          135  +
          136  +COMPILERFLAGS  =-W3
          137  +
          138  +# In v13 -GL and -YX are incompatible.
          139  +!if [nmakehlp -c -YX]
          140  +!if ![nmakehlp -c -GL]
          141  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
          142  +!endif
          143  +!endif
    87    144   
    88    145   !if "$(MACHINE)" == "IX86"
    89    146   ### test for pentium errata
    90    147   !if [nmakehlp -c -QI0f]
    91    148   !message *** Compiler has 'Pentium 0x0f fix'
    92         -PENT_0F_ERRATA	= 1
          149  +COMPILERFLAGS  = $(COMPILERFLAGSS) -QI0f
    93    150   !else
    94    151   !message *** Compiler doesn't have 'Pentium 0x0f fix'
    95         -PENT_0F_ERRATA	= 0
    96    152   !endif
          153  +!endif
          154  +
          155  +!if "$(MACHINE)" == "IA64"
          156  +### test for Itanium errata
          157  +!if [nmakehlp -c -QIA64_Bx]
          158  +!message *** Compiler has 'B-stepping errata workarounds'
          159  +COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
          160  +!else
          161  +!message *** Compiler does not have 'B-stepping errata workarounds'
          162  +!endif
          163  +!endif
          164  +
          165  +!if "$(MACHINE)" == "IX86"
    97    166   ### test for -align:4096, when align:512 will do.
    98    167   !if [nmakehlp -l -opt:nowin98]
    99    168   !message *** Linker has 'Win98 alignment problem'
   100    169   ALIGN98_HACK	= 1
   101    170   !else
   102    171   !message *** Linker doesn't have 'Win98 alignment problem'
   103    172   ALIGN98_HACK	= 0
   104    173   !endif
   105    174   !else
   106         -PENT_0F_ERRATA	= 0
   107    175   ALIGN98_HACK	= 0
   108    176   !endif
   109    177   
   110         -!if "$(MACHINE)" == "IA64"
   111         -### test for Itanium errata
   112         -!if [nmakehlp -c -QIA64_Bx]
   113         -!message *** Compiler has 'B-stepping errata workarounds'
   114         -ITAN_B_ERRATA	= 1
   115         -!else
   116         -!message *** Compiler doesn't have 'B-stepping errata workarounds'
   117         -ITAN_B_ERRATA	= 0
          178  +LINKERFLAGS     =
          179  +
          180  +!if [nmakehlp -l -ltcg]
          181  +LINKERFLAGS     =-ltcg
   118    182   !endif
   119         -!else
   120         -ITAN_B_ERRATA	= 0
          183  +
          184  +#----------------------------------------------------------
          185  +# MSVC8 (ships with Visual Studio 2005) generates a manifest
          186  +# file that we should link into the binaries. This is how.
          187  +#----------------------------------------------------------
          188  +
          189  +_VC_MANIFEST_EMBED_EXE=
          190  +_VC_MANIFEST_EMBED_DLL=
          191  +VCVER=0
          192  +!if ![echo VCVERSION=_MSC_VER > vercl.x] \
          193  +    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
          194  +!include vercl.i
          195  +!if $(VCVERSION) >= 1400
          196  +VCVER=8
          197  +_VC_MANIFEST_EMBED_EXE=if exist [email protected] mt -nologo -manifest [email protected] -outputresource:[email protected];1
          198  +_VC_MANIFEST_EMBED_DLL=if exist [email protected] mt -nologo -manifest [email protected] -outputresource:[email protected];2
          199  +!elseif $(VCVERSION) >= 1300
          200  +VCVER=7
          201  +!elseif $(VCVERSION) >= 1200
          202  +VCVER=6
          203  +!endif
   121    204   !endif
   122    205   
   123    206   #----------------------------------------------------------
   124    207   # Decode the options requested.
   125    208   #----------------------------------------------------------
   126    209   
   127    210   !if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
   128    211   STATIC_BUILD	= 0
   129         -TCL_THREADS	= 0
          212  +TCL_THREADS	= 1
   130    213   DEBUG		= 0
   131    214   PROFILE		= 0
   132    215   MSVCRT		= 0
   133    216   LOIMPACT	= 0
   134    217   TCL_USE_STATIC_PACKAGES	= 0
   135         -USE_THREAD_ALLOC = 0
          218  +USE_THREAD_ALLOC = 1
          219  +USE_THREAD_STORAGE = 1
          220  +UNCHECKED       = 0
   136    221   !else
   137    222   !if [nmakehlp -f $(OPTS) "static"]
   138    223   !message *** Doing static
   139    224   STATIC_BUILD	= 1
   140    225   !else
   141    226   STATIC_BUILD	= 0
   142    227   !endif
................................................................................
   148    233   !endif
   149    234   !if [nmakehlp -f $(OPTS) "staticpkg"]
   150    235   !message *** Doing staticpkg
   151    236   TCL_USE_STATIC_PACKAGES	= 1
   152    237   !else
   153    238   TCL_USE_STATIC_PACKAGES	= 0
   154    239   !endif
   155         -!if [nmakehlp -f $(OPTS) "threads"]
   156         -!message *** Doing threads
   157         -TCL_THREADS	= 1
   158         -!else
          240  +!if [nmakehlp -f $(OPTS) "nothreads"]
          241  +!message *** Compile explicitly for non-threaded tcl
   159    242   TCL_THREADS	= 0
          243  +!else
          244  +TCL_THREADS     = 1
   160    245   !endif
   161    246   !if [nmakehlp -f $(OPTS) "symbols"]
   162    247   !message *** Doing symbols
   163    248   DEBUG		= 1
   164    249   !else
   165    250   DEBUG		= 0
   166    251   !endif
................................................................................
   178    263   !endif
   179    264   !if [nmakehlp -f $(OPTS) "thrdalloc"]
   180    265   !message *** Doing thrdalloc
   181    266   USE_THREAD_ALLOC = 1
   182    267   !else
   183    268   USE_THREAD_ALLOC = 0
   184    269   !endif
          270  +!if [nmakehlp -f $(OPTS) "thrdstorage"]
          271  +!message *** Doing thrdstorage
          272  +USE_THREAD_STORAGE = 1
          273  +!else
          274  +USE_THREAD_STORAGE = 0
          275  +!endif
          276  +!if [nmakehlp -f $(OPTS) "unchecked"]
          277  +!message *** Doing unchecked
          278  +UNCHECKED = 1
          279  +!else
          280  +UNCHECKED = 0
          281  +!endif
   185    282   !endif
   186    283   
   187    284   
   188    285   !if !$(STATIC_BUILD)
   189    286   # Make sure we don't build overly fat DLLs.
   190    287   MSVCRT		= 1
   191    288   # We shouldn't statically put the extensions inside the shell when dynamic.
................................................................................
   195    292   
   196    293   #----------------------------------------------------------
   197    294   # Figure-out how to name our intermediate and output directories.
   198    295   # We wouldn't want different builds to use the same .obj files
   199    296   # by accident.
   200    297   #----------------------------------------------------------
   201    298   
   202         -SUFX	    = tsgx
          299  +#----------------------------------------
          300  +# Naming convention:
          301  +#   t = full thread support.
          302  +#   s = static library (as opposed to an
          303  +#	import library)
          304  +#   g = linked to the debug enabled C
          305  +#	run-time.
          306  +#   x = special static build when it
          307  +#	links to the dynamic C run-time.
          308  +#----------------------------------------
          309  +SUFX	    = sgx
   203    310   
   204    311   !if $(DEBUG)
   205    312   BUILDDIRTOP = Debug
   206         -DBGX	    = g
   207    313   !else
   208    314   BUILDDIRTOP = Release
   209         -DBGX	    =
          315  +!endif
          316  +
          317  +!if "$(MACHINE)" != "IX86"
          318  +BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
          319  +!endif
          320  +!if $(VCVER) > 6
          321  +BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
          322  +!endif
          323  +
          324  +!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
   210    325   SUFX	    = $(SUFX:g=)
   211    326   !endif
   212    327   
   213    328   TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
   214    329   
   215    330   !if !$(STATIC_BUILD)
   216    331   TMP_DIRFULL = $(TMP_DIRFULL:Static=)
................................................................................
   264    379   !message *** Doing compdbg
   265    380   TCL_COMPILE_DEBUG   = 1
   266    381   !else
   267    382   TCL_COMPILE_DEBUG   = 0
   268    383   !endif
   269    384   !endif
   270    385   
          386  +
          387  +#----------------------------------------------------------
          388  +# Decode the checks requested.
          389  +#----------------------------------------------------------
          390  +
          391  +!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
          392  +TCL_NO_DEPRECATED	    = 0
          393  +FULLWARNINGS		    = 0
          394  +!else
          395  +!if [nmakehlp -f $(CHECKS) "nodep"]
          396  +!message *** Doing nodep check
          397  +TCL_NO_DEPRECATED	    = 1
          398  +!else
          399  +TCL_NO_DEPRECATED	    = 0
          400  +!endif
          401  +!if [nmakehlp -f $(CHECKS) "fullwarn"]
          402  +!message *** Doing full warnings check
          403  +FULLWARNINGS		    = 1
          404  +!else
          405  +FULLWARNINGS		    = 0
          406  +!endif
          407  +!endif
          408  +
   271    409   
   272    410   #----------------------------------------------------------
   273    411   # Set our defines now armed with our options.
   274    412   #----------------------------------------------------------
   275    413   
   276    414   OPTDEFINES	= -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING)
   277    415   
   278    416   !if $(TCL_MEM_DEBUG)
   279         -OPTDEFINES	= -DTCL_MEM_DEBUG
          417  +OPTDEFINES	= $(OPTDEFINES) -DTCL_MEM_DEBUG
   280    418   !endif
   281    419   !if $(TCL_COMPILE_DEBUG)
   282    420   OPTDEFINES	= $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
   283    421   !endif
   284    422   !if $(TCL_THREADS)
   285    423   OPTDEFINES	= $(OPTDEFINES) -DTCL_THREADS=1
   286    424   !if $(USE_THREAD_ALLOC)
   287    425   OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
   288    426   !endif
          427  +!if $(USE_THREAD_STORAGE)
          428  +OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_STORAGE=1
          429  +!endif
   289    430   !endif
   290    431   !if $(STATIC_BUILD)
   291    432   OPTDEFINES	= $(OPTDEFINES) -DSTATIC_BUILD
   292    433   !endif
          434  +!if $(TCL_NO_DEPRECATED)
          435  +OPTDEFINES	= $(OPTDEFINES) -DTCL_NO_DEPRECATED
          436  +!endif
   293    437   
   294    438   !if $(DEBUG)
   295    439   OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DEBUG
   296    440   !elseif $(OPTIMIZING)
   297    441   OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
   298    442   !endif
   299    443   !if $(PROFILE)
................................................................................
   337    481   !else
   338    482   MSG =^
   339    483   Failed to find tcl.h.  The TCLDIR macro does not appear correct.
   340    484   !error $(MSG)
   341    485   !endif
   342    486   !endif
   343    487   
   344         -!if [nmakehlp -v $(_TCL_H) ""] == 0
          488  +!if [echo REM = This file is generated from rules.vc > version.vc]
          489  +!endif
          490  +!if exist("$(_TCL_H)")
          491  +!if [echo TCL_DOTVERSION = \>> version.vc] \
          492  +   && [nmakehlp -V "$(_TCL_H)" TCL_VERSION >> version.vc]
          493  +!endif
          494  +!endif
   345    495   !include version.vc
   346         -!else
   347         -TCL_DOTVERSION  = 8.5
   348    496   TCL_VERSION	= $(TCL_DOTVERSION:.=)
   349         -!endif
   350    497   
   351    498   !if $(TCLINSTALL)
   352    499   TCLSH		= "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
          500  +!if !exist($(TCLSH)) && $(TCL_THREADS)
          501  +TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
          502  +!endif
   353    503   TCLSTUBLIB	= "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
   354    504   TCLIMPLIB	= "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
   355    505   TCL_LIBRARY	= $(_TCLDIR)\lib
   356    506   TCL_INCLUDES    = -I"$(_TCLDIR)\include"
   357    507   !else
   358    508   TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
          509  +!if !exist($(TCLSH)) && $(TCL_THREADS)
          510  +TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
          511  +!endif
   359    512   TCLSTUBLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
   360    513   TCLIMPLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
   361    514   TCL_LIBRARY	= $(_TCLDIR)\library
   362    515   TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
   363    516   !endif
   364    517   
   365    518   !endif
   366    519   
   367    520   #----------------------------------------------------------
   368         -# Get Tk info for building extensions.
          521  +# Optionally check for Tk info for building extensions.
   369    522   #----------------------------------------------------------
   370    523   
          524  +!ifdef PROJECT_REQUIRES_TK
   371    525   !if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
   372    526   
   373    527   !if !defined(TKDIR)
   374    528   !if exist("$(_INSTALLDIR)\..\include\tk.h")
   375    529   TKINSTALL      = 1
   376    530   _TKDIR         = $(_INSTALLDIR)\..
   377    531   _TK_H          = $(_TKDIR)\include\tk.h
   378    532   TKDIR          = $(_TKDIR)
   379    533   !elseif exist("$(_TCLDIR)\include\tk.h")
   380    534   TKINSTALL      = 1
   381    535   _TKDIR         = $(_TCLDIR)
   382    536   _TK_H          = $(_TKDIR)\include\tk.h
   383    537   TKDIR          = $(_TKDIR)
   384         -!else
   385         -MSG =^
   386         -Failed to find tk.h. Set the TKDIR macro.
   387         -!error $(MSG)
   388    538   !endif
   389    539   !else
   390    540   _TKDIR = $(TKDIR:/=\)
   391    541   !if exist("$(_TKDIR)\include\tk.h")
   392    542   TKINSTALL      = 1
   393    543   _TK_H          = $(_TKDIR)\include\tk.h
   394    544   !elseif exist("$(_TKDIR)\generic\tk.h")
................................................................................
   397    547   !else
   398    548   MSG =^
   399    549   Failed to find tk.h. The TKDIR macro does not appear correct.
   400    550   !error $(MSG)
   401    551   !endif
   402    552   !endif
   403    553   
   404         -!if [nmakehlp -v $(_TCL_H) $(_TK_H)] == 0
   405         -!include version.vc
   406         -!else
   407         -TK_DOTVERSION	= 8.5
   408         -TK_VERSION	= $(TK_DOTVERSION:.=)
          554  +!if defined(TKDIR)
          555  +TK_DOTVERSION = 8.4
          556  +!if exist("$(_TK_H)")
          557  +!if [echo TK_DOTVERSION = \>> version.vc] \
          558  +   && [nmakehlp -V "$(_TK_H)" TK_VERSION >> version.vc]
          559  +!endif
   409    560   !endif
          561  +!include version.vc
          562  +TK_VERSION = $(TK_DOTVERSION:.=)
   410    563   
   411    564   !if $(TKINSTALL)
   412    565   WISH		= "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
   413    566   TKSTUBLIB	= "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
   414    567   TKIMPLIB	= "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
   415    568   TK_INCLUDES     = -I"$(_TKDIR)\include"
   416    569   !else
................................................................................
   417    570   WISH		= "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
   418    571   TKSTUBLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
   419    572   TKIMPLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
   420    573   TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
   421    574   !endif
   422    575   
   423    576   !endif
   424         -
   425         -
          577  +!endif
          578  +!endif
   426    579   
   427    580   #----------------------------------------------------------
   428    581   # Display stats being used.
   429    582   #----------------------------------------------------------
   430    583   
   431    584   !message *** Intermediate directory will be '$(TMP_DIR)'
   432    585   !message *** Output directory will be '$(OUT_DIR)'
   433    586   !message *** Suffix for binaries will be '$(SUFX)'
   434    587   !message *** Optional defines are '$(OPTDEFINES)'
          588  +!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
          589  +!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS)'
          590  +!message *** Link options '$(LINKERFLAGS)'
   435    591   
   436    592   !endif