summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authorstanton <stanton>1998-09-24 23:58:14 (GMT)
committerstanton <stanton>1998-09-24 23:58:14 (GMT)
commit9995355714bc90faf7c2e345b3d6a1d041447097 (patch)
tree2ad97c5b1994495118cef4df947cf16b55e326f2 /win
parente13392595faf8e8d0d1c3c514ce160cfadc3d372 (diff)
downloadtcl-9995355714bc90faf7c2e345b3d6a1d041447097.zip
tcl-9995355714bc90faf7c2e345b3d6a1d041447097.tar.gz
tcl-9995355714bc90faf7c2e345b3d6a1d041447097.tar.bz2
merging changes from 8.0.3 into 8.1a2
Diffstat (limited to 'win')
-rw-r--r--win/README111
-rw-r--r--win/cat.c2
-rw-r--r--win/makefile.bc3
-rw-r--r--win/makefile.vc178
-rw-r--r--win/mkd.bat20
-rw-r--r--win/pkgIndex.tcl2
-rw-r--r--win/rmd.bat20
-rw-r--r--win/stub16.c2
-rw-r--r--win/tcl.rc2
-rw-r--r--win/tcl16.rc2
-rw-r--r--win/tclAppInit.c2
-rw-r--r--win/tclWin16.c2
-rw-r--r--win/tclWin32Dll.c103
-rw-r--r--win/tclWinChan.c8
-rw-r--r--win/tclWinError.c2
-rw-r--r--win/tclWinFCmd.c2
-rw-r--r--win/tclWinFile.c3
-rw-r--r--win/tclWinInit.c22
-rw-r--r--win/tclWinInt.h11
-rw-r--r--win/tclWinLoad.c2
-rw-r--r--win/tclWinMtherr.c2
-rw-r--r--win/tclWinNotify.c2
-rw-r--r--win/tclWinPipe.c18
-rw-r--r--win/tclWinPort.h14
-rw-r--r--win/tclWinReg.c63
-rw-r--r--win/tclWinSock.c211
-rw-r--r--win/tclWinTest.c2
-rw-r--r--win/tclWinTime.c2
-rw-r--r--win/tclsh.rc2
-rw-r--r--win/winDumpExts.c2
30 files changed, 589 insertions, 228 deletions
diff --git a/win/README b/win/README
index 60f15ab..80473bf 100644
--- a/win/README
+++ b/win/README
@@ -1,6 +1,10 @@
Tcl 8.1a2 for Windows
-SCCS: @(#) README 1.28 98/02/18 15:11:13
+by Scott Stanton
+Scriptics Corporation
+scott.stanton@scriptics.com
+
+RCS: @(#) $Id: README,v 1.1.2.2 1998/09/24 23:59:48 stanton Exp $
1. Introduction
---------------
@@ -18,7 +22,7 @@ common source release. The binary distribution is a self-extracting
archive with a built-in installation script.
Look for the binary release in the same location as the source release
-(ftp.sunlabs.com:/pub/tcl or any of the mirror sites). For most users,
+(ftp.scriptics.com:/pub/tcl or any of the mirror sites). For most users,
the binary release will be much easier to install and use. You only
need the source release if you plan to modify the core of Tcl, or if
you need to compile with a different compiler. With the addition of
@@ -34,8 +38,10 @@ In order to compile Tcl for Windows, you need the following items:
Borland C++ 4.52 (both 16-bit and 32-bit compilers)
or
- Visual C++ 2.x/4.x
- Visual C++ 1.5 (to build tcl1681.dll for Win32s support of exec)
+ Visual C++ 2.x/4.x/5.x
+ Visual C++ 1.5 (to build tcl1680.dll for Win32s support of exec)
+
+In practice, the 8.1.a2 release is built with Visual C++ 5.0
In the "win" subdirectory of the source release, you will find two
files called "makefile.bc" and "makefile.vc". These are the makefiles
@@ -55,11 +61,10 @@ find them. Tcl looks in one of three places for the library files:
as specified in the registry:
For Windows NT & 95:
- HKEY_LOCAL_MACHINE\SOFTWARE\Sun\Tcl\8.1
- Value Name is "Root"
+ HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.1
For Win32s:
- HKEY_CLASSES_ROOT\SOFTWARE\Sun\Tcl\8.1\
+ HKEY_CLASSES_ROOT\SOFTWARE\Scriptics\Tcl\8.1\
3) Relative to the directory containing the current .exe.
Tcl will look for a directory "..\lib\tcl8.1" relative to the
@@ -69,7 +74,90 @@ Note that in order to run tclsh81.exe, you must ensure that tcl81.dll
and tclpip81.dll (plus tcl1681.dll under Win32s) are on your path, in
the system directory, or in the directory containing tclsh81.exe.
-4. Test suite
+4. Building Extensions
+----------------------
+
+With the Windows compilers you have to worry about how you export symbols
+from DLLs. tcl.h defines a few macros to help solve this problem:
+EXTERN - all Tcl_ function prototypes use this macro, which implies
+ they are exported. You'll see this used in tcl.h and tk.h.
+ You should use this in your exported procedures.
+ However, this is not the whole story.
+TCL_STORAGE_CLASS - this is really an import/export flag, depending on if you are
+ importing symbols from a DLL (i.e., a user of the DLL), or if
+ you are exporting symbols from the DLL (i.e., you are building it.)
+ The EXTERN macro includes TCL_STORAGE_CLASS.
+ TCL_STORAGE_CLASS is defined to be either DLLIMPORT or DLLEXPORT as
+ described below.
+STATIC_BUILD - define this if you are *not* building a DLL
+ (e.g., a main program)
+DLL_BUILD - define this if you *are* building a DLL
+DLLIMPORT - If STATIC_BUILD is defined, this becomes nothing.
+ (On UNIX, DLLIMPORT is defined to be empty)
+ Otherwise, this this expands to __declspec(dllimport)
+DLLEXPORT - If STATIC_BUILD is defined, this becomes nothing.
+ (On UNIX, DLLEXPORT is defined to be empty)
+ Otherwise, this this expands to __declspec(dllexport)
+
+EXPORT(type, func)
+ For the Borland compiler, you need to export functions differently.
+ The DLLEXPORT macro is empty, and instead you need to use
+ EXPORT because they had a different order. Your declaration will
+ look like
+ EXTERN EXPORT(int, Foo_Init)(Tcl_Interp *interp);
+We have not defined EXPORT anywhere. You can paste this into your C file:
+#ifndef STATIC_BUILD
+#if defined(_MSC_VER)
+# define EXPORT(a,b) __declspec(dllexport) a b
+# define DllEntryPoint DllMain
+#else
+# if defined(__BORLANDC__)
+# define EXPORT(a,b) a _export b
+# else
+# define EXPORT(a,b) a b
+# endif
+#endif
+#endif
+
+
+How to use these:
+
+Assume your extension is named Foo. In its Makefile, define
+BUILD_Foo so that you know you are building Foo and not using it.
+Then, in your main header file, foo.h, conditionally define
+EXPORT to be either DLLIMPORT or DLLEXPORT based on the
+presense of BUILD_Foo, like this:
+
+#ifndef _FOO
+#define _FOO
+#include "tcl.h"
+/* Additional includes go here */
+/*
+ * if the BUILD_foo macro is defined, the assumption is that we are
+ * building the dynamic library.
+ */
+#ifdef BUILD_Foo
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLEXPORT
+#endif
+/*
+ * Function prototypes for this module.
+ */
+EXTERN int Foo_Init _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN int Foo_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
+/* Additional prototypes go here */
+/*
+ * end of foo.h
+ * reset TCL_STORAGE_CLASS to DLLIMPORT.
+ */
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLIMPORT
+#endif /* _FOO */
+
+In your C file, put EXTERN before then functions you need to export.
+If you use Borland, you'll need to use the old EXPORT macro, too.
+
+5. Test suite
-------------
This distribution contains an extensive test suite for Tcl. Some of
@@ -81,7 +169,7 @@ In order to run the test suite, you build the "test" target using the
appropriate makefile for your compiler.
-5. Known Bugs
+6. Known Bugs
-------------
Here is the current list of known bugs/missing features for the
@@ -98,6 +186,11 @@ Windows version of Tcl:
- Environment variables containing international characters aren't
imported correctly.
+If you have comments or bug reports for the Windows version of Tcl,
+please direct them to:
+
+<bugs@scriptics.com>
+
If you have comments or bug reports for the Windows version of Tk,
please direct them to the comp.lang.tcl newsgroup or the wintcl
mailing list (see http://sunscript.sun.com/win/wintcl-list.html for
diff --git a/win/cat.c b/win/cat.c
index 0ce550f..2c3f7e3 100644
--- a/win/cat.c
+++ b/win/cat.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) cat.c 1.3 96/09/18 15:15:32
+ * RCS: @(#) $Id: cat.c,v 1.1.2.1 1998/09/24 23:59:48 stanton Exp $
*/
#include <stdio.h>
diff --git a/win/makefile.bc b/win/makefile.bc
index 3436b5c..cb0a936 100644
--- a/win/makefile.bc
+++ b/win/makefile.bc
@@ -1,5 +1,5 @@
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
-# SCCS: @(#) makefile.bc 1.88 98/02/19 16:49:06
+# RCS: @(#) $Id: makefile.bc,v 1.1.2.2 1998/09/24 23:59:49 stanton Exp $
#
# Borland C++ 4.5 makefile
#
@@ -105,6 +105,7 @@ TCLOBJS = \
$(TMPDIR)\tclPreserve.obj \
$(TMPDIR)\tclProc.obj \
$(TMPDIR)\tclRegexp.obj \
+ $(TMPDIR)\tclResolve.obj \
$(TMPDIR)\tclResult.obj \
$(TMPDIR)\tclStringObj.obj \
$(TMPDIR)\tclThread.obj \
diff --git a/win/makefile.vc b/win/makefile.vc
index 7bdfff4..5ded8d6 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -4,7 +4,7 @@
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
-# SCCS: @(#) makefile.vc 1.91 98/02/18 15:07:56
+# RCS: @(#) $Id: makefile.vc,v 1.1.2.2 1998/09/24 23:59:49 stanton Exp $
# Does not depend on the presence of any environment variables in
# order to compile tcl; all needed information is derived from
@@ -30,13 +30,17 @@
# will return an error.
# B. A 16-bit program to test the behavior of the exec
# command under NT and 95 will not be built.
+# INSTALLDIR = where the install- targets should copy the binaries and
+# support files
#
ROOT = ..
-TMPDIR = .
-TOOLS32 = c:\msdev
+TOOLS32 = c:\progra~1\devstudio\vc
+TOOLS32_rc = c:\progra~1\devstudio\sharedide
TOOLS16 = c:\msvc
+INSTALLDIR = c:\progra~1\Tcl
+
# Set this to the appropriate value of /MACHINE: for your platform
MACHINE = IX86
@@ -46,6 +50,9 @@ MACHINE = IX86
# Uncomment the following line to compile with thread support
#THREADDEFINES = -DTCL_THREADS=1
+# Set NODEBUG to 0 to compile with symbols
+NODEBUG = 1
+
# The following defines can be added to enable various options in the
# way Tcl is built:
#
@@ -59,21 +66,44 @@ MACHINE = IX86
# Do not modify below this line
######################################################################
-VERSION = 81
+NAMEPREFIX = tcl
+DOTVERSION = 8.0
+VERSION = 80
-TCLLIB = tcl$(VERSION).lib
-TCLDLL = tcl$(VERSION).dll
-TCLPLUGINLIB = tcl$(VERSION)p.lib
-TCLPLUGINDLL = tcl$(VERSION)p.dll
-TCL16DLL = tcl16$(VERSION).dll
-TCLSH = tclsh$(VERSION).exe
-TCLSHP = tclshp$(VERSION).exe
-TCLTEST = tcltest.exe
+BINROOT = .
+!IF "$(NODEBUG)" == "1"
+TMPDIRNAME = Release
+DBGX =
+!ELSE
+TMPDIRNAME = Debug
+DBGX = d
+!ENDIF
+TMPDIR = $(BINROOT)\$(TMPDIRNAME)
+OUTDIRNAME = $(TMPDIRNAME)
+OUTDIR = $(TMPDIR)
+
+TCLLIB = $(OUTDIR)\$(NAMEPREFIX)$(VERSION)$(DBGX).lib
+TCLDLLNAME = $(NAMEPREFIX)$(VERSION)$(DBGX).dll
+TCLDLL = $(OUTDIR)\$(TCLDLLNAME)
+TCLPLUGINLIB = $(OUTDIR)\$(NAMEPREFIX)$(VERSION)p$(DBGX).lib
+TCLPLUGINDLLNAME= $(NAMEPREFIX)$(VERSION)p$(DBGX).dll
+TCLPLUGINDLL = $(OUTDIR)\$(TCLPLUGINDLLNAME)
+TCL16DLL = $(OUTDIR)\$(NAMEPREFIX)16$(VERSION)$(DBGX).dll
+TCLSH = $(OUTDIR)\$(NAMEPREFIX)sh$(VERSION)$(DBGX).exe
+TCLSHP = $(OUTDIR)\$(NAMEPREFIX)shp$(VERSION)$(DBGX).exe
+TCLPIPEDLLNAME = $(NAMEPREFIX)pip$(VERSION)$(DBGX).dll
+TCLPIPEDLL = $(OUTDIR)\$(TCLPIPEDLLNAME)
+TCLREGDLLNAME = $(NAMEPREFIX)reg$(VERSION)$(DBGX).dll
+TCLREGDLL = $(OUTDIR)\$(TCLREGDLLNAME)
+TCLTEST = $(OUTDIR)\$(NAMEPREFIX)test.exe
DUMPEXTS = $(TMPDIR)\dumpexts.exe
-TCLPIPEDLL = tclpip$(VERSION).dll
-TCLREGDLL = tclreg$(VERSION).dll
-CAT16 = cat16.exe
-CAT32 = cat32.exe
+CAT16 = $(TMPDIR)\cat16.exe
+CAT32 = $(TMPDIR)\cat32.exe
+
+LIB_INSTALL_DIR = $(INSTALLDIR)\lib
+BIN_INSTALL_DIR = $(INSTALLDIR)\bin
+SCRIPT_INSTALL_DIR = $(INSTALLDIR)\lib\tcl$(DOTVERSION)
+INCLUDE_INSTALL_DIR = $(INSTALLDIR)\include
TCLSHOBJS = \
$(TMPDIR)\tclAppInit.obj
@@ -132,6 +162,7 @@ TCLOBJS = \
$(TMPDIR)\tclPkg.obj \
$(TMPDIR)\tclPosixStr.obj \
$(TMPDIR)\tclPreserve.obj \
+ $(TMPDIR)\tclResolve.obj \
$(TMPDIR)\tclProc.obj \
$(TMPDIR)\tclRegexp.obj \
$(TMPDIR)\tclResult.obj \
@@ -157,7 +188,7 @@ TCLOBJS = \
cc32 = $(TOOLS32)\bin\cl.exe
link32 = $(TOOLS32)\bin\link.exe
-rc32 = $(TOOLS32)\bin\rc.exe
+rc32 = $(TOOLS32_rc)\bin\rc.exe
include32 = -I$(TOOLS32)\include
cc16 = $(TOOLS16)\bin\cl.exe
@@ -181,9 +212,7 @@ DLL16_CFLAGS = $(cdebug) $(cflags) $(include16) -ALw
# Link flags
######################################################################
-!IF "$(DEBUG)" == "1"
-ldebug = -debug:full -debugtype:cv
-!ELSE
+!IF "$(NODEBUG)" == "1"
ldebug = /RELEASE
!ENDIF
@@ -193,7 +222,7 @@ lcommon = /NODEFAULTLIB /RELEASE /NOLOGO
# declarations for use on Intel i386, i486, and Pentium systems
!IF "$(MACHINE)" == "IX86"
DLLENTRY = @12
-lflags = $(lcommon) -align:0x1000 /MACHINE:$(MACHINE)
+lflags = $(lcommon) /MACHINE:$(MACHINE)
!ELSE
lflags = $(lcommon) /MACHINE:$(MACHINE)
!ENDIF
@@ -222,15 +251,19 @@ conlibsdll = $(libcdll) $(baselibs)
# Compile flags
######################################################################
-!IF "$(DEBUG)" == "1"
-#cdebug = -Z7 -Od -WX
-cdebug = -Z7 -Od
+!IF "$(NODEBUG)" == "1"
+!IF "$(MACHINE)" == "ALPHA"
+# MSVC on Alpha doesn't understand -Ot
+cdebug = -O2i -Gs -GD
!ELSE
cdebug = -Oti -Gs -GD
!ENDIF
+!ELSE
+cdebug = -Z7 -Od -WX
+!ENDIF
# declarations common to all compiler options
-ccommon = -c -W3 -nologo -YX -Dtry=__try -Dexcept=__except
+ccommon = -c -W3 -nologo -YX -Fp$(TMPDIR)\ -Dtry=__try -Dexcept=__except
!IF "$(MACHINE)" == "IX86"
cflags = $(ccommon) -D_X86_=1
@@ -252,21 +285,32 @@ cvars = -DWIN32 -D_WIN32
cvarsmt = $(cvars) -D_MT
cvarsdll = $(cvarsmt) -D_DLL
+!IF "$(NODEBUG)" == "1"
+cvarsdll = $(cvars) -MD
+!ELSE
+cvarsdll = $(cvars) -MDd
+!ENDIF
+
######################################################################
# Project specific targets
######################################################################
-release: $(TCLSH) dlls
-dlls: $(TCL16DLL) $(TCLPIPEDLL) $(TCLREGDLL)
-all: $(TCLSH) dlls $(CAT16) $(CAT32)
-tcltest: $(TCLTEST) dlls $(CAT16) $(CAT32)
-plugin: $(TCLPLUGINDLL) $(TCLSHP)
-test: $(TCLTEST) dlls $(CAT16) $(CAT32)
+release: setup $(TCLSH) dlls
+dlls: setup $(TCL16DLL) $(TCLPIPEDLL) $(TCLREGDLL)
+all: setup $(TCLSH) dlls $(CAT16) $(CAT32)
+tcltest: setup $(TCLTEST) dlls $(CAT16) $(CAT32)
+plugin: setup $(TCLPLUGINDLL) $(TCLSHP)
+install: install-binaries install-libraries
+test: setup $(TCLTEST) dlls $(CAT16) $(CAT32)
$(TCLTEST) <<
cd ../tests
source all
<<
+setup:
+ @mkd $(TMPDIR)
+ @mkd $(OUTDIR)
+
$(DUMPEXTS): $(WINDIR)\winDumpExts.c
$(cc32) $(CON_CFLAGS) -Fo$(TMPDIR)\ $?
set LIB=$(TOOLS32)\lib
@@ -351,44 +395,96 @@ $(CAT16): $(WINDIR)\cat.c
$(TMPDIR)\cat.obj,$@,nul,llibce.lib,nul
$(TMPDIR)\tcl.def: $(DUMPEXTS) $(TCLOBJS)
- $(DUMPEXTS) -o $@ $(TCLDLL) @<<
+ $(DUMPEXTS) -o $@ $(TCLDLLNAME) @<<
$(TCLOBJS)
<<
$(TMPDIR)\plugin.def: $(DUMPEXTS) $(TCLOBJS)
- $(DUMPEXTS) -o $@ $(TCLPLUGINDLL) @<<
+ $(DUMPEXTS) -o $@ $(TCLPLUGINDLLNAME) @<<
$(TCLOBJS)
<<
+install-binaries: $(TCLSH)
+ @mkd $(BIN_INSTALL_DIR)
+ @mkd $(LIB_INSTALL_DIR)
+ @echo installing $(TCLDLLNAME)
+ @copy $(TCLDLL) $(BIN_INSTALL_DIR)
+ @echo installing $(TCLSH)
+ @copy $(TCLSH) $(BIN_INSTALL_DIR)
+
+install-libraries:
+ @mkd $(LIB_INSTALL_DIR)
+ @mkd $(INCLUDE_INSTALL_DIR)
+ @mkd $(SCRIPT_INSTALL_DIR)
+ @mkd $(SCRIPT_INSTALL_DIR)\http1.0
+ @copy $(ROOT)\library\http1.0\http.tcl $(SCRIPT_INSTALL_DIR)\http1.0
+ @copy $(ROOT)\library\http1.0\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)\http1.0
+ @mkd $(SCRIPT_INSTALL_DIR)\http2.0
+ @copy $(ROOT)\library\http2.0\http.tcl $(SCRIPT_INSTALL_DIR)\http2.0
+ @copy $(ROOT)\library\http2.0\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)\http2.0
+ @mkd $(SCRIPT_INSTALL_DIR)\opt0.1
+ @copy $(ROOT)\library\opt0.1\optparse.tcl $(SCRIPT_INSTALL_DIR)\opt0.1
+ @copy $(ROOT)\library\opt0.1\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)\opt0.1
+ @copy $(GENERICDIR)\tcl.h $(INCLUDE_INSTALL_DIR)
+ @copy $(ROOT)\library\history.tcl $(SCRIPT_INSTALL_DIR)
+ @copy $(ROOT)\library\init.tcl $(SCRIPT_INSTALL_DIR)
+ @copy $(ROOT)\library\ldAout.tcl $(SCRIPT_INSTALL_DIR)
+ @copy $(ROOT)\library\parray.tcl $(SCRIPT_INSTALL_DIR)
+ @copy $(ROOT)\library\safe.tcl $(SCRIPT_INSTALL_DIR)
+ @copy $(ROOT)\library\tclIndex $(SCRIPT_INSTALL_DIR)
+ @copy $(ROOT)\library\word.tcl $(SCRIPT_INSTALL_DIR)
+
#
# Special case object file targets
#
+$(TMPDIR)\tclWinInit.obj: $(WINDIR)\tclWinInit.c
+ $(cc32) -DDLL_BUILD -DBUILD_tcl $(TCL_CFLAGS) $(EXTFLAGS) \
+ -Fo$(TMPDIR)\ $?
+
$(TMPDIR)\testMain.obj: $(WINDIR)\tclAppInit.c
- $(cc32) $(TCL_CFLAGS) -DTCL_TEST -Fo$(TMPDIR)\testMain.obj $?
+ $(cc32) $(TCL_CFLAGS) -DSTATIC_BUILD -DTCL_TEST \
+ -Fo$(TMPDIR)\testMain.obj $?
+
+$(TMPDIR)\tclTest.obj: $(GENERICDIR)\tclTest.c
+ $(cc32) $(TCL_CFLAGS) -Fo$@ $?
+
+$(TMPDIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c
+ $(cc32) $(TCL_CFLAGS) -Fo$@ $?
+
+$(TMPDIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c
+ $(cc32) $(TCL_CFLAGS) -Fo$@ $?
+
+$(TMPDIR)\tclAppInit.obj : $(WINDIR)\tclAppInit.c
+ $(cc32) $(TCL_CFLAGS) -DSTATIC_BUILD -Fo$@ $?
#
# Implicit rules
#
{$(WINDIR)}.c{$(TMPDIR)}.obj:
- $(cc32) $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<
+ $(cc32) -DDLL_BUILD -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<
{$(GENERICDIR)}.c{$(TMPDIR)}.obj:
- $(cc32) $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<
+ $(cc32) -DDLL_BUILD -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<
{$(ROOT)\compat}.c{$(TMPDIR)}.obj:
- $(cc32) $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<
+ $(cc32) -DDLL_BUILD -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<
{$(WINDIR)}.rc{$(TMPDIR)}.res:
$(rc32) -fo $@ -r -i $(GENERICDIR) -i $(WINDIR) -D__WIN32__ \
$(TCL_DEFINES) $<
clean:
- -@del *.exp
- -@del *.lib
- -@del *.dll
- -@del *.exe
+ -@del $(OUTDIR)\*.exp
+ -@del $(OUTDIR)\*.lib
+ -@del $(OUTDIR)\*.dll
+ -@del $(OUTDIR)\*.exe
+ -@del $(OUTDIR)\*.pdb
+ -@del $(TMPDIR)\*.pch
-@del $(TMPDIR)\*.obj
-@del $(TMPDIR)\*.res
-@del $(TMPDIR)\*.def
+ -@del $(TMPDIR)\*.exe
+ -@rmd $(OUTDIR)
+ -@rmd $(TMPDIR)
diff --git a/win/mkd.bat b/win/mkd.bat
new file mode 100644
index 0000000..3cc90f1
--- /dev/null
+++ b/win/mkd.bat
@@ -0,0 +1,20 @@
+@echo off
+rem RCS: @(#) $Id: mkd.bat,v 1.1.2.1 1998/09/24 23:59:49 stanton Exp $
+
+if exist %1 goto end
+
+if %OS% == Windows_NT goto winnt
+
+echo Add support for Win 95 please
+goto end
+
+goto success
+
+:winnt
+md %1
+if errorlevel 1 goto end
+
+:success
+echo created directory %1
+
+:end
diff --git a/win/pkgIndex.tcl b/win/pkgIndex.tcl
index be61b0a..aafe17f 100644
--- a/win/pkgIndex.tcl
+++ b/win/pkgIndex.tcl
@@ -6,6 +6,6 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# SCCS: @(#) pkgIndex.tcl 1.2 97/08/22 11:13:05
+# RCS: @(#) $Id: pkgIndex.tcl,v 1.1.2.2 1998/09/24 23:59:49 stanton Exp $
package ifneeded registry 1.0 [list tclPkgSetup $dir registry 1.0 {{tclreg81.dll load registry}}]
diff --git a/win/rmd.bat b/win/rmd.bat
new file mode 100644
index 0000000..c7fb74b
--- /dev/null
+++ b/win/rmd.bat
@@ -0,0 +1,20 @@
+@echo off
+rem RCS: @(#) $Id: rmd.bat,v 1.1.2.1 1998/09/24 23:59:49 stanton Exp $
+
+if not exist %1 goto end
+
+if %OS% == Windows_NT goto winnt
+
+echo Add support for Win 95 please
+goto end
+
+goto success
+
+:winnt
+rmdir %1 /s /q
+if errorlevel 1 goto end
+
+:success
+echo deleted directory %1
+
+:end
diff --git a/win/stub16.c b/win/stub16.c
index 5fafd29..32e1e9e 100644
--- a/win/stub16.c
+++ b/win/stub16.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) stub16.c 1.5 96/12/11 20:01:58
+ * RCS: @(#) $Id: stub16.c,v 1.1.2.1 1998/09/24 23:59:49 stanton Exp $
*/
#define STRICT
diff --git a/win/tcl.rc b/win/tcl.rc
index dfc6cac..34bc66c 100644
--- a/win/tcl.rc
+++ b/win/tcl.rc
@@ -1,4 +1,4 @@
-// SCCS: @(#) tcl.rc 1.26 98/01/20 19:38:38
+// RCS: @(#) $Id: tcl.rc,v 1.1.2.2 1998/09/24 23:59:50 stanton Exp $
//
// Version
//
diff --git a/win/tcl16.rc b/win/tcl16.rc
index 5e4498e..a202c3c 100644
--- a/win/tcl16.rc
+++ b/win/tcl16.rc
@@ -1,4 +1,4 @@
-// SCCS: @(#) tcl16.rc 1.17 96/09/18 18:19:00
+// RCS: @(#) $Id: tcl16.rc,v 1.1.2.1 1998/09/24 23:59:50 stanton Exp $
//
// Version
//
diff --git a/win/tclAppInit.c b/win/tclAppInit.c
index a84e9c4..1dd2e96 100644
--- a/win/tclAppInit.c
+++ b/win/tclAppInit.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclAppInit.c 1.20 98/02/19 15:23:43
+ * RCS: @(#) $Id: tclAppInit.c,v 1.1.2.2 1998/09/24 23:59:50 stanton Exp $
*/
#include "tcl.h"
diff --git a/win/tclWin16.c b/win/tclWin16.c
index d8ea801..c4802de 100644
--- a/win/tclWin16.c
+++ b/win/tclWin16.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWin16.c 1.18 97/05/23 13:13:32
+ * RCS: @(#) $Id: tclWin16.c,v 1.1.2.1 1998/09/24 23:59:50 stanton Exp $
*/
#define STRICT
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c
index acb431f..2584b71 100644
--- a/win/tclWin32Dll.c
+++ b/win/tclWin32Dll.c
@@ -1,4 +1,5 @@
/*
+
* tclWin32Dll.c --
*
* This file contains the DLL entry point which sets up the 32-to-16-bit
@@ -9,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWin32Dll.c 1.37 98/02/02 22:07:20
+ * RCS: @(#) $Id: tclWin32Dll.c,v 1.1.2.2 1998/09/24 23:59:50 stanton Exp $
*/
#include "tclWinInt.h"
@@ -121,12 +122,16 @@ TclWinProcs *tclWinProcs;
static Tcl_Encoding tclWinTCharEncoding;
/*
- * Declarations for functions that are only used in this file.
+ * The following declaration is for the VC++ DLL entry point.
*/
BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
LPVOID reserved);
+
+#ifdef __WIN32__
+#ifndef STATIC_BUILD
+
/*
*----------------------------------------------------------------------
@@ -178,8 +183,6 @@ DllMain(hInst, reason, reserved)
DWORD reason; /* Reason this function is being called. */
LPVOID reserved; /* Not used. */
{
- OSVERSIONINFO os;
-
switch (reason) {
case DLL_PROCESS_ATTACH:
if (hInstance != NULL) {
@@ -194,12 +197,7 @@ DllMain(hInst, reason, reserved)
return FALSE;
}
- hInstance = hInst;
- os.dwOSVersionInfoSize = sizeof(os);
- GetVersionEx(&os);
- platformId = os.dwPlatformId;
-
- tclWinProcs = &asciiProcs;
+ TclWinInit(hInst);
return TRUE;
case DLL_PROCESS_DETACH:
@@ -211,6 +209,9 @@ DllMain(hInst, reason, reserved)
return TRUE;
}
+
+#endif /* !STATIC_BUILD */
+#endif /* __WIN32__ */
/*
*----------------------------------------------------------------------
@@ -311,6 +312,88 @@ TclWinGetTclInstance()
/*
*----------------------------------------------------------------------
*
+ * TclWinInit --
+ *
+ * This function initializes the internal state of the tcl library.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Initializes the 16-bit thunking library, and the tclPlatformId
+ * variable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclWinInit(hInst)
+ HINSTANCE hInst; /* Library instance handle. */
+{
+ OSVERSIONINFO os;
+
+ tclInstance = hInst;
+ os.dwOSVersionInfoSize = sizeof(os);
+ GetVersionEx(&os);
+ tclPlatformId = os.dwPlatformId;
+
+ /*
+ * The following code stops Windows 3.x from automatically putting
+ * up Sharing Violation dialogs, e.g, when someone tries to
+ * access a file that is locked or a drive with no disk in it.
+ * Tcl already returns the appropriate error to the caller, and they
+ * can decide to put up their own dialog in response to that failure.
+ *
+ * Under 95 and NT, the system doesn't automatically put up dialogs
+ * when the above operations fail.
+ */
+
+ if (tclPlatformId == VER_PLATFORM_WIN32s) {
+ SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS);
+ }
+
+ tclWinProcs = &asciiProcs;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpFinalize --
+ *
+ * Clean up the Windows specific library state.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Unloads any DLLs and cleans up the thunking library, if
+ * necessary.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpFinalize()
+{
+ /*
+ * Unregister the Tcl thunk.
+ */
+
+ if (UTUnRegister != NULL) {
+ UTUnRegister(tclInstance);
+ UTUnRegister = NULL;
+ }
+
+ /*
+ * Cleanup any dynamically loaded libraries.
+ */
+
+ UnloadLibraries();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclWinGetPlatformId --
*
* Determines whether running under NT, 95, or Win32s, to allow
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index 913d547..1f08f51 100644
--- a/win/tclWinChan.c
+++ b/win/tclWinChan.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinChan.c 1.83 98/02/19 14:12:21
+ * RCS: @(#) $Id: tclWinChan.c,v 1.1.2.2 1998/09/24 23:59:51 stanton Exp $
*/
#include "tclWinInt.h"
@@ -840,7 +840,7 @@ ComGetOptionProc(instanceData, interp, optionName, dsPtr)
/*
*----------------------------------------------------------------------
*
- * Tcl_OpenFileChannel --
+ * TclpOpenFileChannel --
*
* Open an File based channel on Unix systems.
*
@@ -856,7 +856,7 @@ ComGetOptionProc(instanceData, interp, optionName, dsPtr)
*/
Tcl_Channel
-Tcl_OpenFileChannel(interp, fileName, modeString, permissions)
+TclpOpenFileChannel(interp, fileName, modeString, permissions)
Tcl_Interp *interp; /* Interpreter for error reporting;
* can be NULL. */
char *fileName; /* Name of file to open. */
@@ -905,7 +905,7 @@ Tcl_OpenFileChannel(interp, fileName, modeString, permissions)
channelPermissions = (TCL_READABLE | TCL_WRITABLE);
break;
default:
- panic("Tcl_OpenFileChannel: invalid mode value");
+ panic("TclpOpenFileChannel: invalid mode value");
break;
}
diff --git a/win/tclWinError.c b/win/tclWinError.c
index 8e67b34..d0bf5d2 100644
--- a/win/tclWinError.c
+++ b/win/tclWinError.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinError.c 1.8 97/10/29 09:47:13
+ * RCS: @(#) $Id: tclWinError.c,v 1.1.2.2 1998/09/24 23:59:51 stanton Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c
index 97986c9..97826e5 100644
--- a/win/tclWinFCmd.c
+++ b/win/tclWinFCmd.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinFCmd.c 1.34 98/02/11 17:39:47
+ * RCS: @(#) $Id: tclWinFCmd.c,v 1.1.2.2 1998/09/24 23:59:51 stanton Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinFile.c b/win/tclWinFile.c
index 889994c1..99a20c7 100644
--- a/win/tclWinFile.c
+++ b/win/tclWinFile.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinFile.c 1.59 98/02/02 22:07:09
+ * RCS: @(#) $Id: tclWinFile.c,v 1.1.2.2 1998/09/24 23:59:51 stanton Exp $
*/
#include "tclWinInt.h"
@@ -952,4 +952,3 @@ TclWinResolveShortcut(bufferPtr)
return 0;
}
#endif
-
diff --git a/win/tclWinInit.c b/win/tclWinInit.c
index 98eda3f..ec0acea 100644
--- a/win/tclWinInit.c
+++ b/win/tclWinInit.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinInit.c 1.48 98/02/17 17:17:19
+ * RCS: @(#) $Id: tclWinInit.c,v 1.1.2.2 1998/09/24 23:59:52 stanton Exp $
*/
#include "tclWinInt.h"
@@ -17,6 +17,15 @@
#include <winbase.h>
/*
+ * The following macro can be defined at compile time to specify
+ * the root of the Tcl registry keys.
+ */
+
+#ifndef TCL_REGISTRY_KEY
+#define TCL_REGISTRY_KEY "Software\\Scriptics\\Tcl\\" TCL_VERSION
+#endif
+
+/*
* The following declaration is a workaround for some Microsoft brain damage.
* The SYSTEM_INFO structure is different in various releases, even though the
* layout is the same. So we overlay our own structure on top of it so we
@@ -68,8 +77,8 @@ static char* processors[NUMPROCESSORS] = {
* The Init script (common to Windows and Unix platforms) is
* defined in tkInitScript.h
*/
-#include "tclInitScript.h"
+#include "tclInitScript.h"
static void AppendEnvironment(Tcl_Obj *listPtr, CONST char *lib);
static void AppendPath(Tcl_Obj *listPtr, HMODULE hModule,
@@ -329,13 +338,10 @@ AppendRegistry(
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32s) {
key = HKEY_CLASSES_ROOT;
- subKey = "";
} else {
key = HKEY_LOCAL_MACHINE;
- subKey = "Root";
}
- result = RegOpenKeyExA(key, "Software\\Sun\\Tcl\\" TCL_VERSION, 0,
- KEY_QUERY_VALUE, &key);
+ result = RegOpenKeyExA(key, TCL_REGISTRY_KEY, 0, KEY_QUERY_VALUE, &key);
if (result != ERROR_SUCCESS) {
return;
}
@@ -349,13 +355,13 @@ AppendRegistry(
len = MAX_PATH;
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
- MultiByteToWideChar(CP_ACP, 0, subKey, -1, wBuf, MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, "", -1, wBuf, MAX_PATH);
result = RegQueryValueExW(key, wBuf, NULL, NULL, (LPBYTE) wBuf, &len);
if (result == ERROR_SUCCESS) {
len = ToUtf(wBuf, buf);
}
} else {
- result = RegQueryValueExA(key, subKey, NULL, NULL, (LPBYTE) buf, &len);
+ result = RegQueryValueExA(key, "", NULL, NULL, (LPBYTE) buf, &len);
}
if (result == ERROR_SUCCESS) {
if (buf[len - 1] != '\\') {
diff --git a/win/tclWinInt.h b/win/tclWinInt.h
index 19d3fb6..2d3f5a0 100644
--- a/win/tclWinInt.h
+++ b/win/tclWinInt.h
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinInt.h 1.17 98/02/02 22:07:26
+ * RCS: @(#) $Id: tclWinInt.h,v 1.1.2.2 1998/09/24 23:59:52 stanton Exp $
*/
#ifndef _TCLWININT
@@ -29,6 +29,11 @@
#define TCL_WIN_STACK_THRESHOLD 0x2000
+#ifdef BUILD_tcl
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLEXPORT
+#endif
+
/*
* Some versions of Borland C have a define for the OSVERSIONINFO for
* Win32s and for NT, but not for Windows 95.
@@ -93,14 +98,16 @@ EXTERN Tcl_Encoding tclWinTCharEncoding;
EXTERN TclPlatformType *TclWinGetPlatform(void);
EXTERN int TclWinGetPlatformId(void);
+EXTERN void TclWinInit(HINSTANCE hInst);
EXTERN char * TclWinNoBackslash(char *path);
EXTERN void TclWinSetInterfaces(int);
EXTERN int TclWinSynchSpawn(void *args, int type, void **trans,
Tcl_Pid *pidPtr);
-
EXTERN TCHAR * Tcl_WinUtfToTChar(CONST char *string, int len,
Tcl_DString *dsPtr);
EXTERN char * Tcl_WinTCharToUtf(CONST TCHAR *string, int len,
Tcl_DString *dsPtr);
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLIMPORT
#endif /* _TCLWININT */
diff --git a/win/tclWinLoad.c b/win/tclWinLoad.c
index b49cb1c..a488cf1 100644
--- a/win/tclWinLoad.c
+++ b/win/tclWinLoad.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinLoad.c 1.10 98/01/20 22:42:13
+ * RCS: @(#) $Id: tclWinLoad.c,v 1.1.2.2 1998/09/24 23:59:52 stanton Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinMtherr.c b/win/tclWinMtherr.c
index f630767..2a28411 100644
--- a/win/tclWinMtherr.c
+++ b/win/tclWinMtherr.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinMtherr.c 1.4 98/02/13 15:35:39
+ * RCS: @(#) $Id: tclWinMtherr.c,v 1.1.2.2 1998/09/24 23:59:52 stanton Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c
index 99eb641..71b592e 100644
--- a/win/tclWinNotify.c
+++ b/win/tclWinNotify.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinNotify.c 1.20 98/02/12 19:04:16
+ * RCS: @(#) $Id: tclWinNotify.c,v 1.1.2.2 1998/09/24 23:59:52 stanton Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c
index 0c1d8a9..6b6ecdb 100644
--- a/win/tclWinPipe.c
+++ b/win/tclWinPipe.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinPipe.c 1.63 98/02/19 14:12:31
+ * RCS: @(#) $Id: tclWinPipe.c,v 1.1.2.2 1998/09/24 23:59:52 stanton Exp $
*/
#include "tclWinInt.h"
@@ -1743,13 +1743,19 @@ BuildCommandLine(
}
quote = 0;
- for (start = arg; *start != '\0'; start++) {
- if (isspace(*start)) { /* INTL: ISO space. */
- quote = 1;
- Tcl_DStringAppend(&ds, "\"", 1);
- break;
+ if (argv[i][0] == '\0') {
+ quote = 1;
+ } else {
+ for (start = argv[i]; *start != '\0'; start++) {
+ if (isspace(*start)) { /* INTL: ISO space. */
+ quote = 1;
+ break;
+ }
}
}
+ if (quote) {
+ Tcl_DStringAppend(linePtr, "\"", 1);
+ }
start = arg;
for (special = arg; ; ) {
diff --git a/win/tclWinPort.h b/win/tclWinPort.h
index 7452739..18b4996 100644
--- a/win/tclWinPort.h
+++ b/win/tclWinPort.h
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinPort.h 1.62 98/02/18 14:00:22
+ * RCS: @(#) $Id: tclWinPort.h,v 1.1.2.2 1998/09/24 23:59:53 stanton Exp $
*/
#ifndef _TCLWINPORT
@@ -62,6 +62,11 @@ typedef float *TCHAR;
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
+#ifdef BUILD_tcl
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLEXPORT
+#endif
+
/*
* Define EINPROGRESS in terms of WSAEINPROGRESS.
*/
@@ -414,6 +419,10 @@ EXTERN size_t TclStrftime _ANSI_ARGS_((char *s, size_t maxsize,
EXTERN int TclpStat _ANSI_ARGS_((CONST char *path,
struct stat *buf));
+EXTERN int TclpAccess _ANSI_ARGS_((CONST char *path,
+ int mode));
+
+#define TclpReleaseFile(file) ckfree((char *) file)
/*
* Declarations for Windows-only functions.
@@ -451,4 +460,7 @@ typedef int TclpMutex;
#define TclpMutexUnlock(a)
#endif /* TCL_THREADS */
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLIMPORT
+
#endif /* _TCLWINPORT */
diff --git a/win/tclWinReg.c b/win/tclWinReg.c
index 718aa65..2fae2b2 100644
--- a/win/tclWinReg.c
+++ b/win/tclWinReg.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinReg.c 1.12 98/02/11 17:41:21
+ * RCS: @(#) $Id: tclWinReg.c,v 1.1.2.2 1998/09/24 23:59:53 stanton Exp $
*/
#include <tcl.h>
@@ -21,21 +21,23 @@
#undef WIN32_LEAN_AND_MEAN
/*
+ * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the
+ * Registry_Init declaration is in the source file itself, which is only
+ * accessed when we are building a library.
+ */
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+
+/*
* VC++ has an alternate entry point called DllMain, so we need to rename
* our entry point.
*/
-#ifndef STATIC_BUILD
-#if defined(_MSC_VER)
-# define EXPORT(a,b) __declspec(dllexport) a b
-# define DllEntryPoint DllMain
-#else
-# if defined(__BORLANDC__)
-# define EXPORT(a,b) a _export b
-# else
-# define EXPORT(a,b) a b
-# endif
-#endif
+#ifdef DLL_BUILD
+# if defined(_MSC_VER)
+# define DllEntryPoint DllMain
+# endif
#endif
/*
@@ -79,7 +81,7 @@ static char *typeNames[] = {
"dword_big_endian", "link", "multi_sz", "resource_list", NULL
};
-static DWORD lastType = REG_RESOURCE_REQUIREMENTS_LIST;
+static DWORD lastType = REG_RESOURCE_LIST;
/*
@@ -114,7 +116,7 @@ static int SetValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,
Tcl_Obj *valueNameObj, Tcl_Obj *dataObj,
Tcl_Obj *typeObj);
-EXTERN EXPORT(int,Registry_Init)(Tcl_Interp *interp);
+EXTERN int Registry_Init(Tcl_Interp *interp);
/*
*----------------------------------------------------------------------
@@ -136,7 +138,7 @@ EXTERN EXPORT(int,Registry_Init)(Tcl_Interp *interp);
*/
#ifdef __WIN32__
-#ifndef STATIC_BUILD
+#ifdef DLL_BUILD
BOOL APIENTRY
DllEntryPoint(
HINSTANCE hInst, /* Library instance handle. */
@@ -164,7 +166,8 @@ DllEntryPoint(
*----------------------------------------------------------------------
*/
-EXPORT(int,Registry_Init)(
+int
+Registry_Init(
Tcl_Interp *interp)
{
Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd, NULL, NULL);
@@ -542,7 +545,7 @@ GetType(
* If we don't know about the type, just use the numeric value.
*/
- if (type > lastType) {
+ if (type > lastType || type < 0) {
Tcl_SetIntObj(resultPtr, type);
} else {
Tcl_SetStringObj(resultPtr, typeNames[type], -1);
@@ -590,19 +593,27 @@ GetValue(
}
/*
- * Get the value once to determine the length then again to store
- * the data in the buffer.
+ * Initialize a Dstring to maximum statically allocated size
+ * we could get one more byte by avoiding Tcl_DStringSetLength()
+ * and just setting length to TCL_DSTRING_STATIC_SIZE, but this
+ * should be safer if the implementation Dstrings changes.
+ *
+ * This allows short values to be read from the registy in one call.
+ * Longer values need a second call with an expanded DString.
*/
Tcl_DStringInit(&data);
- resultPtr = Tcl_GetObjResult(interp);
+ Tcl_DStringSetLength(&data, length = TCL_DSTRING_STATIC_SIZE - 1);
- valueName = Tcl_GetStringFromObj(valueNameObj, (int*) &length);
- result = RegQueryValueEx(key, valueName, NULL, &type, NULL, &length);
- if (result == ERROR_SUCCESS) {
- Tcl_DStringSetLength(&data, length);
- result = RegQueryValueEx(key, valueName, NULL, &type,
- (LPBYTE) Tcl_DStringValue(&data), &length);
+ resultPtr = Tcl_GetObjResult(interp);
+
+ valueName = Tcl_GetStringFromObj(valueNameObj, NULL);
+ result = RegQueryValueEx(key, valueName, NULL, &type,
+ (LPBYTE) Tcl_DStringValue(&data), &length);
+ if (result == ERROR_MORE_DATA) {
+ Tcl_DStringSetLength(&data, length);
+ result = RegQueryValueEx(key, valueName, NULL, &type,
+ (LPBYTE) Tcl_DStringValue(&data), &length);
}
RegCloseKey(key);
if (result != ERROR_SUCCESS) {
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index c6e6273..3b0ba15 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinSock.c 1.93 98/02/19 15:21:32
+ * RCS: @(#) $Id: tclWinSock.c,v 1.1.2.2 1998/09/24 23:59:53 stanton Exp $
*/
#include "tclWinInt.h"
@@ -51,6 +51,9 @@ static struct {
int (PASCAL FAR *listen)(SOCKET s, int backlog);
u_short (PASCAL FAR *ntohs)(u_short netshort);
int (PASCAL FAR *recv)(SOCKET s, char FAR * buf, int len, int flags);
+ int (PASCAL FAR *select)(int nfds, fd_set FAR * readfds,
+ fd_set FAR * writefds, fd_set FAR * exceptfds,
+ const struct timeval FAR * tiemout);
int (PASCAL FAR *send)(SOCKET s, const char FAR * buf, int len, int flags);
int (PASCAL FAR *setsockopt)(SOCKET s, int level, int optname,
const char FAR * optval, int optlen);
@@ -292,7 +295,8 @@ InitSockets()
const struct sockaddr FAR *name, int namelen))
GetProcAddress(winSock.hInstance, "connect");
winSock.ioctlsocket = (int (PASCAL FAR *)(SOCKET s, long cmd,
- u_long FAR *argp)) GetProcAddress(winSock.hInstance, "ioctlsocket");
+ u_long FAR *argp))
+ GetProcAddress(winSock.hInstance, "ioctlsocket");
winSock.getsockopt = (int (PASCAL FAR *)(SOCKET s,
int level, int optname, char FAR * optval, int FAR *optlen))
GetProcAddress(winSock.hInstance, "getsockopt");
@@ -308,6 +312,10 @@ InitSockets()
GetProcAddress(winSock.hInstance, "ntohs");
winSock.recv = (int (PASCAL FAR *)(SOCKET s, char FAR * buf,
int len, int flags)) GetProcAddress(winSock.hInstance, "recv");
+ winSock.select = (int (PASCAL FAR *)(int nfds, fd_set FAR * readfds,
+ fd_set FAR * writefds, fd_set FAR * exceptfds,
+ const struct timeval FAR * tiemout))
+ GetProcAddress(winSock.hInstance, "select");
winSock.send = (int (PASCAL FAR *)(SOCKET s, const char FAR * buf,
int len, int flags)) GetProcAddress(winSock.hInstance, "send");
winSock.setsockopt = (int (PASCAL FAR *)(SOCKET s, int level,
@@ -362,6 +370,7 @@ InitSockets()
(winSock.listen == NULL) ||
(winSock.ntohs == NULL) ||
(winSock.recv == NULL) ||
+ (winSock.select == NULL) ||
(winSock.send == NULL) ||
(winSock.setsockopt == NULL) ||
(winSock.socket == NULL) ||
@@ -686,8 +695,7 @@ SocketEventProc(evPtr, flags)
SocketInfo *infoPtr;
SocketEvent *eventPtr = (SocketEvent *) evPtr;
int mask = 0;
- u_long nBytes;
- int status, events;
+ int events;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
@@ -747,33 +755,30 @@ SocketEventProc(evPtr, flags)
Tcl_SetMaxBlockTime(&blockTime);
mask |= TCL_READABLE;
} else if (events & FD_READ) {
+ fd_set readFds;
+ struct timeval timeout;
+
/*
* We must check to see if data is really available, since someone
- * could have consumed the data in the meantime.
+ * could have consumed the data in the meantime. Turn off async
+ * notification so select will work correctly. If the socket is
+ * still readable, notify the channel driver, otherwise reset the
+ * async select handler and keep waiting.
*/
- nBytes = 0;
- status = (*winSock.ioctlsocket)(infoPtr->socket, FIONREAD,
- &nBytes);
- if ((status != SOCKET_ERROR) && (nBytes > 0)) {
+ (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd, 0, 0);
+
+ FD_ZERO(&readFds);
+ FD_SET(infoPtr->socket, &readFds);
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 0;
+
+ if ((*winSock.select)(0, &readFds, NULL, NULL, &timeout) != 0) {
mask |= TCL_READABLE;
} else {
- /*
- * We are in a strange state, probably because someone
- * besides Tcl is reading from this socket. Try to
- * recover by clearing the read event.
- */
-
+ (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
+ SOCKET_MESSAGE, infoPtr->selectEvents);
infoPtr->readyEvents &= ~(FD_READ);
-
- /*
- * Re-issue WSAAsyncSelect() since we are gobbling up an
- * event, without letting the reader do any I/O to re-enable
- * the notification.
- */
-
- (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
- SOCKET_MESSAGE, infoPtr->selectEvents);
}
}
if (events & FD_WRITE) {
@@ -1094,6 +1099,7 @@ CreateSocket(interp, port, host, server, myaddr, myport, async)
* automatically places the socket into non-blocking mode.
*/
+ (*winSock.ioctlsocket)(sock, FIONBIO, &flag);
(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
SOCKET_MESSAGE, infoPtr->selectEvents);
@@ -1219,51 +1225,42 @@ WaitForSocketEvent(infoPtr, events, errorCodePtr)
oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
- while (!(infoPtr->readyEvents & events)) {
- if (infoPtr->flags & SOCKET_ASYNC) {
- if (!PeekMessage(&msg, winSock.hwnd, SOCKET_MESSAGE,
- SOCKET_MESSAGE, PM_REMOVE)) {
- *errorCodePtr = EWOULDBLOCK;
- result = 0;
- break;
- }
- } else {
- /*
- * Look for a socket event. Note that we will be getting
- * events for all of Tcl's sockets, not just the one we wanted.
- */
-
- result = GetMessage(&msg, winSock.hwnd, SOCKET_MESSAGE,
- SOCKET_MESSAGE);
- if (result == -1) {
- TclWinConvertError(GetLastError());
- *errorCodePtr = Tcl_GetErrno();
- result = 0;
- break;
- }
-
- /*
- * I don't think we can get a WM_QUIT during a tight modal
- * loop, but just in case...
- */
+ /*
+ * Reset WSAAsyncSelect so we have a fresh set of events pending.
+ */
- if (result == 0) {
- panic("WaitForSocketEvent: Got WM_QUIT during modal loop!");
- }
- }
+ (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd, 0, 0);
+ (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
+ SOCKET_MESSAGE, infoPtr->selectEvents);
+ while (1) {
/*
- * Dispatch the message and then check for an error on the socket.
+ * Process all outstanding messages on the socket window.
*/
- infoPtr->lastError = 0;
- DispatchMessage(&msg);
+ while (PeekMessage(&msg, winSock.hwnd, 0, 0, PM_REMOVE)) {
+ DispatchMessage(&msg);
+ }
+
if (infoPtr->lastError) {
*errorCodePtr = infoPtr->lastError;
result = 0;
break;
+ } else if (infoPtr->readyEvents & events) {
+ break;
+ } else if (infoPtr->flags & SOCKET_ASYNC) {
+ *errorCodePtr = EWOULDBLOCK;
+ result = 0;
+ break;
}
+
+ /*
+ * Wait until something happens.
+ */
+
+ WaitMessage();
}
+
(void) Tcl_SetServiceMode(oldMode);
return result;
@@ -1595,45 +1592,43 @@ TcpInputProc(instanceData, buf, toRead, errorCodePtr)
*/
while (1) {
- if (infoPtr->readyEvents & (FD_CLOSE|FD_READ)) {
- bytesRead = (*winSock.recv)(infoPtr->socket, buf, toRead, 0);
- infoPtr->readyEvents &= ~(FD_READ);
-
- /*
- * Check for end-of-file condition or successful read.
- */
-
- if (bytesRead == 0) {
- infoPtr->flags |= SOCKET_EOF;
- }
- if (bytesRead != SOCKET_ERROR) {
- return bytesRead;
- }
-
- /*
- * If an error occurs after the FD_CLOSE has arrived,
- * then ignore the error and report an EOF.
- */
-
- if (infoPtr->readyEvents & FD_CLOSE) {
- infoPtr->flags |= SOCKET_EOF;
- return 0;
- }
-
- /*
- * Check for error condition or underflow in non-blocking case.
- */
-
- error = (*winSock.WSAGetLastError)();
- if ((infoPtr->flags & SOCKET_ASYNC) || (error != WSAEWOULDBLOCK)) {
- TclWinConvertWSAError(error);
- *errorCodePtr = Tcl_GetErrno();
- return -1;
- }
-
- } else if (infoPtr->flags & SOCKET_ASYNC) {
- *errorCodePtr = EWOULDBLOCK;
- return -1;
+ (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
+ 0, 0);
+ bytesRead = (*winSock.recv)(infoPtr->socket, buf, toRead, 0);
+ infoPtr->readyEvents &= ~(FD_READ);
+
+ /*
+ * Check for end-of-file condition or successful read.
+ */
+
+ if (bytesRead == 0) {
+ infoPtr->flags |= SOCKET_EOF;
+ }
+ if (bytesRead != SOCKET_ERROR) {
+ break;
+ }
+
+ /*
+ * If an error occurs after the FD_CLOSE has arrived,
+ * then ignore the error and report an EOF.
+ */
+
+ if (infoPtr->readyEvents & FD_CLOSE) {
+ infoPtr->flags |= SOCKET_EOF;
+ bytesRead = 0;
+ break;
+ }
+
+ /*
+ * Check for error condition or underflow in non-blocking case.
+ */
+
+ error = (*winSock.WSAGetLastError)();
+ if ((infoPtr->flags & SOCKET_ASYNC) || (error != WSAEWOULDBLOCK)) {
+ TclWinConvertWSAError(error);
+ *errorCodePtr = Tcl_GetErrno();
+ bytesRead = -1;
+ break;
}
/*
@@ -1642,9 +1637,14 @@ TcpInputProc(instanceData, buf, toRead, errorCodePtr)
*/
if (!WaitForSocketEvent(infoPtr, FD_READ|FD_CLOSE, errorCodePtr)) {
- return -1;
- }
+ bytesRead = -1;
+ break;
+ }
}
+
+ (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
+ SOCKET_MESSAGE, infoPtr->selectEvents);
+ return bytesRead;
}
/*
@@ -1699,6 +1699,8 @@ TcpOutputProc(instanceData, buf, toWrite, errorCodePtr)
}
while (1) {
+ (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
+ 0, 0);
bytesWritten = (*winSock.send)(infoPtr->socket, buf, toWrite, 0);
if (bytesWritten != SOCKET_ERROR) {
/*
@@ -1726,12 +1728,14 @@ TcpOutputProc(instanceData, buf, toWrite, errorCodePtr)
infoPtr->readyEvents &= ~(FD_WRITE);
if (infoPtr->flags & SOCKET_ASYNC) {
*errorCodePtr = EWOULDBLOCK;
- return -1;
+ bytesWritten = -1;
+ break;
}
} else {
TclWinConvertWSAError(error);
*errorCodePtr = Tcl_GetErrno();
- return -1;
+ bytesWritten = -1;
+ break;
}
/*
@@ -1740,10 +1744,13 @@ TcpOutputProc(instanceData, buf, toWrite, errorCodePtr)
*/
if (!WaitForSocketEvent(infoPtr, FD_WRITE|FD_CLOSE, errorCodePtr)) {
- return -1;
+ bytesWritten = -1;
+ break;
}
}
+ (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
+ SOCKET_MESSAGE, infoPtr->selectEvents);
return bytesWritten;
}
diff --git a/win/tclWinTest.c b/win/tclWinTest.c
index b4d7687..5aed1f0 100644
--- a/win/tclWinTest.c
+++ b/win/tclWinTest.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinTest.c 1.3 97/07/28 15:27:32
+ * RCS: @(#) $Id: tclWinTest.c,v 1.1.2.2 1998/09/24 23:59:54 stanton Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinTime.c b/win/tclWinTime.c
index 8570e65..fcb61e8 100644
--- a/win/tclWinTime.c
+++ b/win/tclWinTime.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclWinTime.c 1.11 98/02/19 14:30:36
+ * RCS: @(#) $Id: tclWinTime.c,v 1.1.2.2 1998/09/24 23:59:54 stanton Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclsh.rc b/win/tclsh.rc
index b340a1a..5ff2b05 100644
--- a/win/tclsh.rc
+++ b/win/tclsh.rc
@@ -1,4 +1,4 @@
-// SCCS: @(#) tclsh.rc 1.18 98/01/20 19:38:48
+// RCS: @(#) $Id: tclsh.rc,v 1.1.2.2 1998/09/24 23:59:54 stanton Exp $
//
// Version
//
diff --git a/win/winDumpExts.c b/win/winDumpExts.c
index 8bc496e..36b03c3 100644
--- a/win/winDumpExts.c
+++ b/win/winDumpExts.c
@@ -19,7 +19,7 @@
* compiler other than Visual C++.
*----------------------------------------------------------------------
*
- * SCCS: @(#) winDumpExts.c 1.11 96/09/18 15:25:11
+ * RCS: @(#) $Id: winDumpExts.c,v 1.1.2.1 1998/09/24 23:59:54 stanton Exp $
*/
#include <windows.h>