summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
Diffstat (limited to 'win')
-rw-r--r--win/Makefile.in340
-rw-r--r--win/README10
-rw-r--r--win/README.binary141
-rwxr-xr-x[-rw-r--r--]win/buildall.vc.bat95
-rw-r--r--win/cat.c13
-rw-r--r--win/coffbase.txt10
-rwxr-xr-xwin/configure5883
-rw-r--r--win/configure.in158
-rw-r--r--win/makefile.bc94
-rw-r--r--win/makefile.vc525
-rw-r--r--win/nmakehlp.c266
-rw-r--r--win/rules.vc231
-rw-r--r--win/stub16.c65
-rw-r--r--win/tcl.dsp56
-rw-r--r--win/tcl.hpj.in4
-rw-r--r--win/tcl.m492
-rw-r--r--win/tcl.rc8
-rw-r--r--win/tclAppInit.c282
-rw-r--r--win/tclWin32Dll.c760
-rw-r--r--win/tclWinChan.c942
-rw-r--r--win/tclWinConsole.c636
-rw-r--r--win/tclWinDde.c1896
-rw-r--r--win/tclWinError.c23
-rw-r--r--win/tclWinFCmd.c1224
-rw-r--r--win/tclWinFile.c2954
-rw-r--r--win/tclWinInit.c667
-rw-r--r--win/tclWinInt.h89
-rw-r--r--win/tclWinLoad.c191
-rw-r--r--win/tclWinMtherr.c55
-rw-r--r--win/tclWinNotify.c286
-rw-r--r--win/tclWinPipe.c1447
-rw-r--r--win/tclWinPort.h174
-rw-r--r--win/tclWinReg.c546
-rw-r--r--win/tclWinSerial.c1994
-rw-r--r--win/tclWinSock.c1937
-rw-r--r--win/tclWinTest.c726
-rw-r--r--win/tclWinThrd.c708
-rw-r--r--win/tclWinTime.c1003
-rw-r--r--win/tclsh.rc10
39 files changed, 10749 insertions, 15792 deletions
diff --git a/win/Makefile.in b/win/Makefile.in
index b3df47f..f11ef53 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -1,21 +1,24 @@
#
-# This file is a Makefile for Tcl. If it has the name "Makefile.in" then it
-# is a template for a Makefile; to generate the actual Makefile, run
-# "./configure", which is a configuration script generated by the "autoconf"
-# program (constructs like "@foo@" will get replaced in the actual Makefile.
+# This file is a Makefile for Tcl. If it has the name "Makefile.in"
+# then it is a template for a Makefile; to generate the actual Makefile,
+# run "./configure", which is a configuration script generated by the
+# "autoconf" program (constructs like "@foo@" will get replaced in the
+# actual Makefile.
VERSION = @TCL_VERSION@
-#--------------------------------------------------------------------------
-# Things you can change to personalize the Makefile for your own site (you can
-# make these changes in either Makefile.in or Makefile, but changes to
-# Makefile will get lost if you re-run the configuration script).
-#--------------------------------------------------------------------------
+#----------------------------------------------------------------
+# Things you can change to personalize the Makefile for your own
+# site (you can make these changes in either Makefile.in or
+# Makefile, but changes to Makefile will get lost if you re-run
+# the configuration script).
+#----------------------------------------------------------------
-# Default top-level directories in which to install architecture-specific
-# files (exec_prefix) and machine-independent files such as scripts (prefix).
-# The values specified here may be overridden at configure-time with the
-# --exec-prefix and --prefix options to the "configure" script.
+# Default top-level directories in which to install architecture-
+# specific files (exec_prefix) and machine-independent files such
+# as scripts (prefix). The values specified here may be overridden
+# at configure-time with the --exec-prefix and --prefix options
+# to the "configure" script.
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -24,15 +27,16 @@ libdir = @libdir@
includedir = @includedir@
mandir = @mandir@
-# The following definition can be set to non-null for special systems like AFS
-# with replication. It allows the pathnames used for installation to be
-# different than those used for actually reference files at run-time.
-# INSTALL_ROOT is prepended to $prefix and $exec_prefix when installing files.
+# The following definition can be set to non-null for special systems
+# like AFS with replication. It allows the pathnames used for installation
+# to be different than those used for actually reference files at
+# run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix
+# when installing files.
INSTALL_ROOT =
-# Directory from which applications will reference the library of Tcl scripts
-# (note: you can set the TCL_LIBRARY environment variable at run-time to
-# override this value):
+# Directory from which applications will reference the library of Tcl
+# scripts (note: you can set the TCL_LIBRARY environment variable at
+# run-time to override this value):
TCL_LIBRARY = $(prefix)/lib/tcl$(VERSION)
# Path to use at runtime to refer to LIB_INSTALL_DIR:
@@ -59,10 +63,12 @@ MAN_INSTALL_DIR = $(INSTALL_ROOT)$(mandir)
# Directory in which to install manual entry for tclsh:
MAN1_INSTALL_DIR = $(MAN_INSTALL_DIR)/man1
-# Directory in which to install manual entries for Tcl's C library procedures:
+# Directory in which to install manual entries for Tcl's C library
+# procedures:
MAN3_INSTALL_DIR = $(MAN_INSTALL_DIR)/man3
-# Directory in which to install manual entries for the built-in Tcl commands:
+# Directory in which to install manual entries for the built-in
+# Tcl commands:
MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann
# Libraries built with optimization switches have this additional extension
@@ -82,19 +88,18 @@ CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@
#CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE)
CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@
-# To enable compilation debugging reverse the comment characters on one of the
-# following lines.
+# To enable compilation debugging reverse the comment characters on
+# one of the following lines.
COMPILE_DEBUG_FLAGS =
#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_DEBUG
#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
# Special compiler flags to use when building man2tcl on Windows.
-MAN2TCLFLAGS = @MAN2TCLFLAGS@
+MAN2TCLFLAGS = @MAN2TCLFLAGS@
SRC_DIR = @srcdir@
ROOT_DIR = @srcdir@/..
GENERIC_DIR = @srcdir@/../generic
-TOMMATH_DIR = @srcdir@/../libtommath
WIN_DIR = @srcdir@
COMPAT_DIR = @srcdir@/../compat
@@ -102,29 +107,15 @@ COMPAT_DIR = @srcdir@/../compat
CYGPATH = @CYGPATH@
GENERIC_DIR_NATIVE = $(shell $(CYGPATH) '$(GENERIC_DIR)' | sed 's!\\!/!g')
-TOMMATH_DIR_NATIVE = $(shell $(CYGPATH) '$(TOMMATH_DIR)' | sed 's!\\!/!g')
WIN_DIR_NATIVE = $(shell $(CYGPATH) '$(WIN_DIR)' | sed 's!\\!/!g')
ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)' | sed 's!\\!/!g')
-#GENERIC_DIR_NATIVE = $(GENERIC_DIR)
-#TOMMATH_DIR_NATIVE = $(TOMMATH_DIR)
-#WIN_DIR_NATIVE = $(WIN_DIR)
-#ROOT_DIR_NATIVE = $(ROOT_DIR)
-
-# Fully qualify library path so that `make test`
-# does not depend on the current directory.
-LIBRARY_DIR1 = $(shell cd '$(ROOT_DIR_NATIVE)/library' ; pwd)
-LIBRARY_DIR = $(shell $(CYGPATH) '$(LIBRARY_DIR1)' | sed 's!\\!/!g')
+
+LIBRARY_DIR = $(ROOT_DIR_NATIVE)/library
+
DLLSUFFIX = @DLLSUFFIX@
LIBSUFFIX = @LIBSUFFIX@
EXESUFFIX = @EXESUFFIX@
-VER = @TCL_MAJOR_VERSION@@TCL_MINOR_VERSION@
-DOTVER = @TCL_MAJOR_VERSION@.@TCL_MINOR_VERSION@
-DDEVER = @TCL_DDE_MAJOR_VERSION@@TCL_DDE_MINOR_VERSION@
-DDEDOTVER = @TCL_DDE_MAJOR_VERSION@.@TCL_DDE_MINOR_VERSION@
-REGVER = @TCL_REG_MAJOR_VERSION@@TCL_REG_MINOR_VERSION@
-REGDOTVER = @TCL_REG_MAJOR_VERSION@.@TCL_REG_MINOR_VERSION@
-
TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@
TCL_DLL_FILE = @TCL_DLL_FILE@
TCL_LIB_FILE = @TCL_LIB_FILE@
@@ -138,10 +129,11 @@ SHARED_LIBRARIES = $(TCL_DLL_FILE) $(TCL_STUB_LIB_FILE) \
$(DDE_DLL_FILE) $(REG_DLL_FILE) $(PIPE_DLL_FILE)
STATIC_LIBRARIES = $(TCL_LIB_FILE) $(REG_LIB_FILE) $(DDE_LIB_FILE)
-# TCL_EXE is the name of a tclsh executable that is available *BEFORE* running
-# make for the first time. Certain build targets (make genstubs) need it to be
-# available on the PATH. This executable should *NOT* be required just to do a
-# normal build although it can be required to run make dist.
+# TCL_EXE is the name of a tclsh executable that is available *BEFORE*
+# running make for the first time. Certain build targets (make genstubs)
+# need it to be available on the PATH. This executable should *NOT* be
+# required just to do a normal build although it can be required to run
+# make dist.
TCL_EXE = tclsh
TCLSH = tclsh$(VER)${EXESUFFIX}
@@ -151,10 +143,11 @@ MAN2TCL = man2tcl$(EXEEXT)
@SET_MAKE@
-# Setting the VPATH variable to a list of paths will cause the Makefile to
-# look into these paths when resolving .c to .obj dependencies.
+# Setting the VPATH variable to a list of paths will cause the
+# makefile to look into these paths when resolving .c to .obj
+# dependencies.
-VPATH = $(GENERIC_DIR):$(TOMMATH_DIR):$(WIN_DIR):$(COMPAT_DIR)
+VPATH = $(GENERIC_DIR):$(WIN_DIR):$(COMPAT_DIR)
AR = @AR@
RANLIB = @RANLIB@
@@ -175,6 +168,12 @@ SHLIB_LD = @SHLIB_LD@
SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ $(LIBS)
SHLIB_CFLAGS = @SHLIB_CFLAGS@
SHLIB_SUFFIX = @SHLIB_SUFFIX@
+VER = @TCL_MAJOR_VERSION@@TCL_MINOR_VERSION@
+DOTVER = @TCL_MAJOR_VERSION@.@TCL_MINOR_VERSION@
+DDEVER = @TCL_DDE_MAJOR_VERSION@@TCL_DDE_MINOR_VERSION@
+DDEDOTVER = @TCL_DDE_MAJOR_VERSION@.@TCL_DDE_MINOR_VERSION@
+REGVER = @TCL_REG_MAJOR_VERSION@@TCL_REG_MINOR_VERSION@
+REGDOTVER = @TCL_REG_MAJOR_VERSION@.@TCL_REG_MINOR_VERSION@
LIBS = @LIBS@
RMDIR = rm -rf
@@ -184,16 +183,14 @@ RM = rm -f
COPY = cp
CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} \
--I"${GENERIC_DIR_NATIVE}" -DTCL_TOMMATH -DMP_PREC=4 -I"${TOMMATH_DIR_NATIVE}" \
--I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \
+-I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \
${COMPILE_DEBUG_FLAGS}
CC_OBJNAME = @CC_OBJNAME@
CC_EXENAME = @CC_EXENAME@
STUB_CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \
--I"${GENERIC_DIR_NATIVE}" -DTCL_TOMMATH -DMP_PREC=4 -I"${TOMMATH_DIR_NATIVE}" \
--I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \
+-I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \
${COMPILE_DEBUG_FLAGS}
TCLTEST_OBJS = \
@@ -221,9 +218,7 @@ GENERIC_OBJS = \
tclCompCmds.$(OBJEXT) \
tclCompExpr.$(OBJEXT) \
tclCompile.$(OBJEXT) \
- tclConfig.$(OBJEXT) \
tclDate.$(OBJEXT) \
- tclDictObj.$(OBJEXT) \
tclEncoding.$(OBJEXT) \
tclEnv.$(OBJEXT) \
tclEvent.$(OBJEXT) \
@@ -238,7 +233,6 @@ GENERIC_OBJS = \
tclIO.$(OBJEXT) \
tclIOCmd.$(OBJEXT) \
tclIOGT.$(OBJEXT) \
- tclIORChan.$(OBJEXT) \
tclIOSock.$(OBJEXT) \
tclIOUtil.$(OBJEXT) \
tclLink.$(OBJEXT) \
@@ -251,10 +245,9 @@ GENERIC_OBJS = \
tclObj.$(OBJEXT) \
tclPanic.$(OBJEXT) \
tclParse.$(OBJEXT) \
- tclPathObj.$(OBJEXT) \
+ tclParseExpr.$(OBJEXT) \
tclPipe.$(OBJEXT) \
tclPkg.$(OBJEXT) \
- tclPkgConfig.$(OBJEXT) \
tclPosixStr.$(OBJEXT) \
tclPreserve.$(OBJEXT) \
tclProc.$(OBJEXT) \
@@ -263,87 +256,16 @@ GENERIC_OBJS = \
tclResult.$(OBJEXT) \
tclScan.$(OBJEXT) \
tclStringObj.$(OBJEXT) \
- tclStrToD.$(OBJEXT) \
tclStubInit.$(OBJEXT) \
tclStubLib.$(OBJEXT) \
tclThread.$(OBJEXT) \
tclThreadAlloc.$(OBJEXT) \
tclThreadJoin.$(OBJEXT) \
- tclThreadStorage.$(OBJEXT) \
tclTimer.$(OBJEXT) \
- tclTomMathInterface.$(OBJEXT) \
- tclTrace.$(OBJEXT) \
tclUtf.$(OBJEXT) \
tclUtil.$(OBJEXT) \
tclVar.$(OBJEXT)
-TOMMATH_OBJS = \
- bncore.${OBJEXT} \
- bn_reverse.${OBJEXT} \
- bn_fast_s_mp_mul_digs.${OBJEXT} \
- bn_fast_s_mp_sqr.${OBJEXT} \
- bn_mp_add.${OBJEXT} \
- bn_mp_add_d.${OBJEXT} \
- bn_mp_and.${OBJEXT} \
- bn_mp_clamp.${OBJEXT} \
- bn_mp_clear.${OBJEXT} \
- bn_mp_clear_multi.${OBJEXT} \
- bn_mp_cmp.${OBJEXT} \
- bn_mp_cmp_d.${OBJEXT} \
- bn_mp_cmp_mag.${OBJEXT} \
- bn_mp_cnt_lsb.${OBJEXT} \
- bn_mp_copy.${OBJEXT} \
- bn_mp_count_bits.${OBJEXT} \
- bn_mp_div.${OBJEXT} \
- bn_mp_div_d.${OBJEXT} \
- bn_mp_div_2.${OBJEXT} \
- bn_mp_div_2d.${OBJEXT} \
- bn_mp_div_3.${OBJEXT} \
- bn_mp_exch.${OBJEXT} \
- bn_mp_expt_d.${OBJEXT} \
- bn_mp_grow.${OBJEXT} \
- bn_mp_init.${OBJEXT} \
- bn_mp_init_copy.${OBJEXT} \
- bn_mp_init_multi.${OBJEXT} \
- bn_mp_init_set.${OBJEXT} \
- bn_mp_init_set_int.${OBJEXT} \
- bn_mp_init_size.${OBJEXT} \
- bn_mp_karatsuba_mul.${OBJEXT} \
- bn_mp_karatsuba_sqr.$(OBJEXT) \
- bn_mp_lshd.${OBJEXT} \
- bn_mp_mod.${OBJEXT} \
- bn_mp_mod_2d.${OBJEXT} \
- bn_mp_mul.${OBJEXT} \
- bn_mp_mul_2.${OBJEXT} \
- bn_mp_mul_2d.${OBJEXT} \
- bn_mp_mul_d.${OBJEXT} \
- bn_mp_neg.${OBJEXT} \
- bn_mp_or.${OBJEXT} \
- bn_mp_radix_size.${OBJEXT} \
- bn_mp_radix_smap.${OBJEXT} \
- bn_mp_read_radix.${OBJEXT} \
- bn_mp_rshd.${OBJEXT} \
- bn_mp_set.${OBJEXT} \
- bn_mp_set_int.${OBJEXT} \
- bn_mp_shrink.${OBJEXT} \
- bn_mp_sqr.${OBJEXT} \
- bn_mp_sqrt.${OBJEXT} \
- bn_mp_sub.${OBJEXT} \
- bn_mp_sub_d.${OBJEXT} \
- bn_mp_to_unsigned_bin.${OBJEXT} \
- bn_mp_to_unsigned_bin_n.${OBJEXT} \
- bn_mp_toom_mul.${OBJEXT} \
- bn_mp_toom_sqr.${OBJEXT} \
- bn_mp_toradix_n.${OBJEXT} \
- bn_mp_unsigned_bin_size.${OBJEXT} \
- bn_mp_xor.${OBJEXT} \
- bn_mp_zero.${OBJEXT} \
- bn_s_mp_add.${OBJEXT} \
- bn_s_mp_mul_digs.${OBJEXT} \
- bn_s_mp_sqr.${OBJEXT} \
- bn_s_mp_sub.${OBJEXT}
-
-
WIN_OBJS = \
tclWin32Dll.$(OBJEXT) \
tclWinChan.$(OBJEXT) \
@@ -354,11 +276,15 @@ WIN_OBJS = \
tclWinFile.$(OBJEXT) \
tclWinInit.$(OBJEXT) \
tclWinLoad.$(OBJEXT) \
+ tclWinMtherr.$(OBJEXT) \
tclWinNotify.$(OBJEXT) \
tclWinPipe.$(OBJEXT) \
tclWinSock.$(OBJEXT) \
tclWinThrd.$(OBJEXT) \
- tclWinTime.$(OBJEXT)
+ tclWinTime.$(OBJEXT)
+
+COMPAT_OBJS = \
+ strftime.$(OBJEXT) strtoll.$(OBJEXT) strtoull.$(OBJEXT)
PIPE_OBJS = stub16.$(OBJEXT)
@@ -370,7 +296,7 @@ STUB_OBJS = tclStubLib.$(OBJEXT)
TCLSH_OBJS = tclAppInit.$(OBJEXT)
-TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS}
+TCL_OBJS = ${GENERIC_OBJS} ${WIN_OBJS} ${COMPAT_OBJS}
TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n]
@@ -395,12 +321,10 @@ $(MAN2TCL): $(ROOT_DIR)/tools/man2tcl.c
$(TCLSH): $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(TCLSH_OBJS) tclsh.$(RES)
$(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(LIBS) \
tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE)
- @VC_MANIFEST_EMBED_EXE@
$(TCLTEST): $(TCL_LIB_FILE) $(TCLTEST_OBJS) $(CAT32) tclsh.$(RES)
$(CC) $(CFLAGS) $(TCLTEST_OBJS) $(TCL_LIB_FILE) $(LIBS) \
tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE)
- @VC_MANIFEST_EMBED_EXE@
cat32.$(OBJEXT): cat.c
$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)
@@ -408,8 +332,8 @@ cat32.$(OBJEXT): cat.c
$(CAT32): cat32.$(OBJEXT)
$(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE)
-# The following targets are configured by autoconf to generate either a shared
-# library or static library
+# The following targets are configured by autoconf to generate either
+# a shared library or static library
${TCL_STUB_LIB_FILE}: ${STUB_OBJS}
@$(RM) ${TCL_STUB_LIB_FILE}
@@ -419,7 +343,6 @@ ${TCL_STUB_LIB_FILE}: ${STUB_OBJS}
${TCL_DLL_FILE}: ${TCL_OBJS} tcl.$(RES)
@$(RM) ${TCL_DLL_FILE}
@MAKE_DLL@ ${TCL_OBJS} tcl.$(RES) $(SHLIB_LD_LIBS)
- @VC_MANIFEST_EMBED_DLL@
${TCL_LIB_FILE}: ${TCL_OBJS}
@$(RM) ${TCL_LIB_FILE}
@@ -442,13 +365,14 @@ ${REG_LIB_FILE}: ${REG_OBJS} ${TCL_LIB_FILE}
@$(RM) ${REG_LIB_FILE}
@MAKE_LIB@ ${REG_OBJS} ${TCL_LIB_FILE}
-# PIPE_DLL_FILE is actually an executable, don't build it like a DLL.
+# PIPE_DLL_FILE is actually an executable, don't build it
+# like a DLL.
${PIPE_DLL_FILE}: ${PIPE_OBJS}
@$(RM) ${PIPE_DLL_FILE}
@MAKE_EXE@ $(CFLAGS) ${PIPE_OBJS} $(LIBS) $(LDFLAGS_CONSOLE)
-# Add the object extension to the implicit rules. By default .obj is not
+# Add the object extension to the implicit rules. By default .obj is not
# automatically added.
.SUFFIXES: .${OBJEXT}
@@ -487,32 +411,8 @@ tclWinReg.${OBJEXT} : tclWinReg.c
tclWinDde.${OBJEXT} : tclWinDde.c
$(CC) -c $(CC_SWITCHES) -DUSE_TCL_STUBS @DEPARG@ $(CC_OBJNAME)
-# TIP #59, embedding of configuration information into the binary library.
-#
-# Part of Tcl's configuration information are the paths where it was installed
-# and where it will look for its libraries (which can be different). We derive
-# this information from the variables which can be overridden by the user. As
-# every path can be configured separately we do not remember one general
-# prefix/exec_prefix but all the different paths individually.
-
-tclPkgConfig.${OBJEXT}: tclPkgConfig.c
- $(CC) -c $(CC_SWITCHES) \
- -DCFG_INSTALL_LIBDIR=\"$(LIB_INSTALL_DIR)\" \
- -DCFG_INSTALL_BINDIR=\"$(BIN_INSTALL_DIR)\" \
- -DCFG_INSTALL_SCRDIR=\"$(SCRIPT_INSTALL_DIR)\" \
- -DCFG_INSTALL_INCDIR=\"$(INCLUDE_INSTALL_DIR)\" \
- -DCFG_INSTALL_DOCDIR=\"$(MAN_INSTALL_DIR)\" \
- \
- -DCFG_RUNTIME_LIBDIR=\"$(libdir)\" \
- -DCFG_RUNTIME_BINDIR=\"$(bindir)\" \
- -DCFG_RUNTIME_SCRDIR=\"$(TCL_LIBRARY)\" \
- -DCFG_RUNTIME_INCDIR=\"$(includedir)\" \
- -DCFG_RUNTIME_DOCDIR=\"$(mandir)\" \
- -DBUILD_tcl \
- @DEPARG@ $(CC_OBJNAME)
-
-# The following objects are part of the stub library and should not be built
-# as DLL objects but none of the symbols should be exported
+# The following objects are part of the stub library and should not
+# be built as DLL objects but none of the symbols should be exported
tclStubLib.${OBJEXT}: tclStubLib.c
$(CC) -c $(CC_SWITCHES) -DSTATIC_BUILD @DEPARG@ $(CC_OBJNAME)
@@ -520,32 +420,12 @@ tclStubLib.${OBJEXT}: tclStubLib.c
# Implicit rule for all object files that will end up in the Tcl library
-%.${OBJEXT}: %.c
+.c.${OBJEXT}:
$(CC) -c $(CC_SWITCHES) -DBUILD_tcl @DEPARG@ $(CC_OBJNAME)
.rc.$(RES):
$(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(WIN_DIR_NATIVE)" @DEPARG@
-# The following target generates the file generic/tclDate.c from the yacc
-# grammar found in generic/tclGetDate.y. This is only run by hand as yacc is
-# not available in all environments. The name of the .c file is different than
-# the name of the .y file so that make doesn't try to automatically regenerate
-# the .c file.
-
-gendate:
- bison --output-file=$(GENERIC_DIR)/tclDate.c \
- --name-prefix=TclDate \
- --no-lines \
- $(GENERIC_DIR)/tclGetDate.y
-
-# The following target generates the file generic/tclTomMath.h. It needs to be
-# run (and the results checked) after updating to a new release of libtommath.
-
-gentommath_h:
- $(TCL_EXE) "$(ROOT_DIR_NATIVE)\tools\fix_tommath_h.tcl" \
- "$(TOMMATH_DIR_NATIVE)\tommath.h" \
- > "$(GENERIC_DIR_NATIVE)\tclTomMath.h"
-
install: all install-binaries install-libraries install-doc
install-binaries: binaries
@@ -558,7 +438,7 @@ install-binaries: binaries
else true; \
fi; \
done;
- @for i in dde1.3 reg1.2; \
+ @for i in dde1.2 reg1.1; \
do \
if [ ! -d $(LIB_INSTALL_DIR)/$$i ] ; then \
echo "Making directory $(LIB_INSTALL_DIR)/$$i"; \
@@ -582,26 +462,26 @@ install-binaries: binaries
done
@if [ -f $(DDE_DLL_FILE) ]; then \
echo installing $(DDE_DLL_FILE); \
- $(COPY) $(DDE_DLL_FILE) $(LIB_INSTALL_DIR)/dde1.3; \
+ $(COPY) $(DDE_DLL_FILE) $(LIB_INSTALL_DIR)/dde1.2; \
$(COPY) $(ROOT_DIR)/library/dde/pkgIndex.tcl \
- $(LIB_INSTALL_DIR)/dde1.3; \
+ $(LIB_INSTALL_DIR)/dde1.2; \
fi
@if [ -f $(DDE_LIB_FILE) ]; then \
echo installing $(DDE_LIB_FILE); \
- $(COPY) $(DDE_LIB_FILE) $(LIB_INSTALL_DIR)/dde1.3; \
+ $(COPY) $(DDE_LIB_FILE) $(LIB_INSTALL_DIR)/dde1.2; \
fi
@if [ -f $(REG_DLL_FILE) ]; then \
echo installing $(REG_DLL_FILE); \
- $(COPY) $(REG_DLL_FILE) $(LIB_INSTALL_DIR)/reg1.2; \
+ $(COPY) $(REG_DLL_FILE) $(LIB_INSTALL_DIR)/reg1.1; \
$(COPY) $(ROOT_DIR)/library/reg/pkgIndex.tcl \
- $(LIB_INSTALL_DIR)/reg1.2; \
+ $(LIB_INSTALL_DIR)/reg1.1; \
fi
@if [ -f $(REG_LIB_FILE) ]; then \
echo installing $(REG_LIB_FILE); \
- $(COPY) $(REG_LIB_FILE) $(LIB_INSTALL_DIR)/reg1.2; \
+ $(COPY) $(REG_LIB_FILE) $(LIB_INSTALL_DIR)/reg1.1; \
fi
-install-libraries: libraries install-tzdata install-msgs
+install-libraries: libraries
@for i in $(prefix)/lib $(INCLUDE_INSTALL_DIR) \
$(SCRIPT_INSTALL_DIR); \
do \
@@ -611,7 +491,7 @@ install-libraries: libraries install-tzdata install-msgs
else true; \
fi; \
done;
- @for i in http1.0 opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5; \
+ @for i in platform http1.0 http2.5 opt0.4 encoding msgcat1.3 tcltest2.2; \
do \
if [ ! -d $(SCRIPT_INSTALL_DIR)/$$i ] ; then \
echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
@@ -621,9 +501,7 @@ install-libraries: libraries install-tzdata install-msgs
done;
@echo "Installing header files";
@for i in "$(GENERIC_DIR)/tcl.h" "$(GENERIC_DIR)/tclDecls.h" \
- "$(GENERIC_DIR)/tclPlatDecls.h" \
- "$(GENERIC_DIR)/tclTomMath.h" \
- "$(GENERIC_DIR)/tclTomMathDecls.h"; \
+ "$(GENERIC_DIR)/tclPlatDecls.h" ; \
do \
$(COPY) "$$i" "$(INCLUDE_INSTALL_DIR)"; \
done;
@@ -632,43 +510,41 @@ install-libraries: libraries install-tzdata install-msgs
do \
$(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)"; \
done;
+ @echo "Installing library platform directory";
+ @for j in $(ROOT_DIR)/library/platform/*.tcl; \
+ do \
+ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/platform"; \
+ done;
@echo "Installing library http1.0 directory";
@for j in $(ROOT_DIR)/library/http1.0/*.tcl; \
do \
$(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/http1.0"; \
done;
- @echo "Installing package http 2.7.8 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/http-2.7.8.tm;
+ @echo "Installing library http2.5 directory";
+ @for j in $(ROOT_DIR)/library/http/*.tcl; \
+ do \
+ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/http2.5"; \
+ done;
@echo "Installing library opt0.4 directory";
@for j in $(ROOT_DIR)/library/opt/*.tcl; \
do \
$(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \
done;
- @echo "Installing package msgcat 1.4.4 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.4.4.tm;
- @echo "Installing package tcltest 2.3.4 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.3.4.tm;
- @echo "Installing package platform 1.0.10 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.10.tm;
- @echo "Installing package platform::shell 1.1.4 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/platform/shell.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform/shell-1.1.4.tm;
+ @echo "Installing library msgcat1.3 directory";
+ @for j in $(ROOT_DIR)/library/msgcat/*.tcl; \
+ do \
+ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/msgcat1.3"; \
+ done;
+ @echo "Installing library tcltest2.2 directory";
+ @for j in $(ROOT_DIR)/library/tcltest/*.tcl; \
+ do \
+ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/tcltest2.2"; \
+ done;
@echo "Installing encodings";
@for i in $(ROOT_DIR)/library/encoding/*.enc ; do \
$(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)/encoding"; \
done;
-install-tzdata:
- @echo "Installing time zone data"
- @TCL_LIBRARY="${LIBRARY_DIR}"; export TCL_LIBRARY; \
- ./$(TCLSH) "$(ROOT_DIR)/tools/installData.tcl" \
- "$(ROOT_DIR)/library/tzdata" "$(SCRIPT_INSTALL_DIR)/tzdata"
-
-install-msgs:
- @echo "Installing message catalogs"
- @TCL_LIBRARY="${LIBRARY_DIR}"; export TCL_LIBRARY; \
- ./$(TCLSH) "$(ROOT_DIR)/tools/installData.tcl" \
- "$(ROOT_DIR)/library/msgs" "$(SCRIPT_INSTALL_DIR)/msgs"
-
install-doc: doc
# Optional target to install private headers
@@ -678,10 +554,11 @@ install-private-headers: libraries
if [ ! -d $$i ] ; then \
echo "Making directory $$i"; \
$(MKDIR) $$i; \
+ chmod 755 $$i; \
else true; \
fi; \
done;
- @echo "Installing private header files";
+ @echo "Installing private header files to $(PRIVATE_INCLUDE_INSTALL_DIR)/";
@for i in "$(GENERIC_DIR)/tclInt.h" "$(GENERIC_DIR)/tclIntDecls.h" \
"$(GENERIC_DIR)/tclIntPlatDecls.h" "$(GENERIC_DIR)/tclPort.h" \
"$(WIN_DIR)/tclWinPort.h" ; \
@@ -689,24 +566,22 @@ install-private-headers: libraries
$(COPY) "$$i" "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \
done;
-# Specifying TESTFLAGS on the command line is the standard way to pass args to
-# tcltest, i.e.:
+# Specifying TESTFLAGS on the command line is the standard way to pass
+# args to tcltest, ie:
# % make test TESTFLAGS="-verbose bps -file fileName.test"
test: binaries $(TCLTEST)
TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
./$(TCLTEST) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \
- -load "set ::ddelib [file normalize ${DDE_DLL_FILE}]; \
- set ::reglib [file normalize ${REG_DLL_FILE}]" | ./$(CAT32)
+ | ./$(CAT32)
# Useful target to launch a built tcltest with the proper path,...
runtest: binaries $(TCLTEST)
@TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
- ./$(TCLTEST) $(TESTFLAGS) -load "set ::ddelib [file normalize ${DDE_DLL_FILE}]; \
- set ::reglib [file normalize ${REG_DLL_FILE}]" $(SCRIPT)
+ ./$(TCLTEST) $(TESTFLAGS) $(SCRIPT)
-# This target can be used to run tclsh from the build directory via
-# `make shell SCRIPT=foo.tcl`
+# This target can be used to run tclsh from the build directory
+# via `make shell SCRIPT=foo.tcl`
shell: binaries
@TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
./$(TCLSH) $(SCRIPT)
@@ -714,7 +589,7 @@ shell: binaries
# This target can be used to run tclsh inside either gdb or insight
gdb: binaries
@echo "set env TCL_LIBRARY=$(LIBRARY_DIR)" > gdb.run
- gdb ./$(TCLSH) --command=gdb.run
+ gdb ./tclsh --command=gdb.run
rm gdb.run
depend:
@@ -732,7 +607,7 @@ clean: cleanhelp
distclean: clean
$(RM) Makefile config.status config.cache config.log tclConfig.sh \
- tcl.hpj config.status.lineno
+ tcl.hpj
#
# Regenerate the stubs files.
@@ -748,5 +623,4 @@ genstubs:
$(TCL_EXE) "$(ROOT_DIR_NATIVE)\tools\genStubs.tcl" \
"$(GENERIC_DIR_NATIVE)" \
"$(GENERIC_DIR_NATIVE)\tcl.decls" \
- "$(GENERIC_DIR_NATIVE)\tclInt.decls" \
- "$(GENERIC_DIR_NATIVE)\tclTomMath.decls"
+ "$(GENERIC_DIR_NATIVE)\tclInt.decls"
diff --git a/win/README b/win/README
index 1929362..5e3d00f 100644
--- a/win/README
+++ b/win/README
@@ -1,4 +1,4 @@
-Tcl 8.5 for Windows
+Tcl 8.4 for Windows
1. Introduction
---------------
@@ -16,7 +16,7 @@ The information in this file is maintained on the web at:
In order to compile Tcl for Windows, you need the following:
- Tcl 8.5 Source Distribution (plus any patches)
+ Tcl 8.4 Source Distribution (plus any patches)
and
@@ -51,9 +51,9 @@ Use the Makefile "install" target to install Tcl. It will install it
according to the prefix options you provided in the correct directory
structure.
-Note that in order to run tclsh85.exe, you must ensure that tcl85.dll is on
-your path, in the system directory, or in the directory containing
-tclsh85.exe.
+Note that in order to run tclsh84.exe, you must ensure that tcl84.dll
+and tclpip84.dll are on your path, in the system directory, or in the
+directory containing tclsh84.exe.
Note: Tcl no longer provides support for Win32s.
diff --git a/win/README.binary b/win/README.binary
new file mode 100644
index 0000000..8388235
--- /dev/null
+++ b/win/README.binary
@@ -0,0 +1,141 @@
+Tcl/Tk 8.4 for Windows, Binary Distribution
+
+1. Introduction
+---------------
+
+This directory contains the binary distribution of Tcl/Tk 8.4.19 for
+Windows. It was compiled with Microsoft Visual C++ 6.0 using Win32
+API, so that it will run under Windows NT, 95, 98 and 2000.
+
+Tcl provides a powerful platform for creating integration applications
+that tie together diverse applications, protocols, devices, and
+frameworks. When paired with the Tk toolkit, Tcl provides the fastest
+and most powerful way to create GUI applications that run on PCs, Unix,
+and the Macintosh. Tcl can also be used for a variety of web-related
+tasks and for creating powerful command languages for applications.
+
+Tcl is maintained, enhanced, and distributed freely by the Tcl community.
+
+2. Documentation
+----------------
+
+The home of Tcl and Tk sources and bug database on the Web is at:
+ http://tcl.sourceforge.net/
+
+The home page for the Tcl Developer Xchange is at:
+ http://www.tcl.tk/
+
+The home page for the Tcl/Tk 8.4 release is
+ http://www.tcl.tk/software/tcltk/8.4.html
+
+Detailed release notes can be found at the file distributions page
+by clicking on the relevant version.
+ http://sourceforge.net/project/showfiles.php?group_id=10894
+
+Information about Tcl itself can be found at
+ http://www.tcl.tk/scripting/
+
+There are many Tcl books on the market. Most are listed at
+ http://www.tcl.tk/resource/doc/books/
+
+There are notes about compiling Tcl at
+ http://www.tcl.tk/doc/howto/compile.html
+
+3. Installation
+---------------
+
+The binary release is distributed as a self-extracting archive called
+tcl<version>.exe. The setup program which will prompt you for an
+installation directory. It will create the installation heirarchy
+under the specified directory, and install a wish application icon
+under the program manager group of your choice.
+
+We are no longer supporting use of Tcl with 16-bit versions of
+Windows. Microsoft has completely dropped support of the Win32s
+subsystem.
+
+4. Linking against the binary release
+--------------------------------------
+
+In order to link your applications against the .dll files shipped with
+this release, you will need to use the appropriate .lib file for your
+compiler. In the lib directory of the installation directory, there
+are library files for the Microsoft Visual C++ compiler:
+
+ tcl84.lib
+ tk84.lib
+
+5. Building dynamically loadable extensions
+--------------------------------------------
+
+Please refer to the example dynamically loadable extension provided on
+our ftp site:
+
+ ftp://ftp.scriptics.com/pub/tcl/misc/example.zip
+
+This archive contains a template that you can use for building
+extensions that will be loadable on Unix, Windows, and Macintosh
+systems.
+
+6. Reporting Bugs
+-----------------
+If you have comments or bug reports for the Windows version of Tcl,
+please use our online database at:
+
+ http://tcl.sourceforge.net/
+
+or post them to the newsgroup comp.lang.tcl.
+
+7. Tcl newsgroup
+-----------------
+
+There is a network news group "comp.lang.tcl" intended for the exchange
+of information about Tcl, Tk, and related applications. Feel free to use
+the newsgroup both for general information questions and for bug reports.
+We read the newsgroup and will attempt to fix bugs and problems reported
+to it.
+
+When using comp.lang.tcl, please be sure that your e-mail return address
+is correctly set in your postings. This allows people to respond directly
+to you, rather than the entire newsgroup, for answers that are not of
+general interest. A bad e-mail return address may prevent you from
+getting answers to your questions. You may have to reconfigure your news
+reading software to ensure that it is supplying valid e-mail addresses.
+
+8. Tcl contributed archive
+--------------------------
+
+Many people have created exciting packages and applications based on Tcl
+and/or Tk and made them freely available to the Tcl community. An archive
+of these contributions is kept on the machine ftp.neosoft.com. You
+can access the archive using anonymous FTP; the Tcl contributed archive is
+in the directory "/pub/tcl". The archive also contains several FAQ
+("frequently asked questions") documents that provide solutions to problems
+that are commonly encountered by TCL newcomers.
+
+9. Tcl Resource Center
+----------------------
+
+Visit http://www.tcl.tk/resource/ to see an annotated index of
+many Tcl resources available on the World Wide Web. This includes papers,
+books, and FAQs, as well as extensions, applications, binary releases, and
+patches. You can contribute patches by using the Tracker at
+
+ http://tcl.sourceforge.net/
+
+You can also recommend more URLs for the resource center using the forms
+labeled "Add a Resource".
+
+10. Mailing lists
+----------------
+
+Several mailing lists are hosted at SourceForge to discuss development or
+use issues (like Macintosh and Windows topics). For more information and
+to subscribe, visit:
+
+ http://sourceforge.net/projects/tcl/
+
+and go to the Mailing Lists page. There are also Special Interest Groups
+(SIGs) setup for these topics and more at:
+
+ http://www.tcl.tk/
diff --git a/win/buildall.vc.bat b/win/buildall.vc.bat
index 55b29ae..383e774 100644..100755
--- a/win/buildall.vc.bat
+++ b/win/buildall.vc.bat
@@ -1,123 +1,56 @@
@echo off
+
:: This is an example batchfile for building everything. Please
:: edit this (or make your own) for your needs and wants using
:: the instructions for calling makefile.vc found in makefile.vc
-set SYMBOLS=
-
-:OPTIONS
-if "%1" == "/?" goto help
-if /i "%1" == "/help" goto help
-if %1.==symbols. goto SYMBOLS
-if %1.==debug. goto SYMBOLS
-goto OPTIONS_DONE
-
-:SYMBOLS
- set SYMBOLS=symbols
- shift
- goto OPTIONS
-
-:OPTIONS_DONE
-
-:: reset errorlevel
-cd > nul
-
-:: We need to run the development environment batch script that comes
-:: with developer studio (v4,5,6,7,etc...) All have it. These paths
-:: might not be correct. You may need to edit these.
-::
-if not defined MSDevDir (
- call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat"
- ::call "C:\Program Files\Microsoft Developer Studio\vc\bin\vcvars32.bat"
- ::call c:\dev\devstudio60\vc98\bin\vcvars32.bat
- if errorlevel 1 goto no_vcvars
-)
-
-
-echo.
echo Sit back and have a cup of coffee while this grinds through ;)
echo You asked for *everything*, remember?
echo.
-title Building Tcl, please wait...
-
-:: makefile.vc uses this for its default anyways, but show its use here
-:: just to be explicit and convey understanding to the user. Setting
-:: the INSTALLDIR envar prior to running this batchfile affects all builds.
-::
-if "%INSTALLDIR%" == "" set INSTALLDIR=C:\Program Files\Tcl
+title Building Tcl, please wait...
+if "%MSVCDir%" == "" call c:\dev\devstudio60\vc98\bin\vcvars32.bat
+::if "%MSVCDir%" == "" call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat"
+set INSTALLDIR=C:\Program Files\Tcl
:: Build the normal stuff along with the help file.
::
-set OPTS=none
-if not %SYMBOLS%.==. set OPTS=symbols
-nmake -nologo -f makefile.vc release winhelp OPTS=%OPTS% %1
+nmake -nologo -f makefile.vc release winhelp OPTS=none
if errorlevel 1 goto error
:: Build the static core, dlls and shell.
::
-set OPTS=static
-if not %SYMBOLS%.==. set OPTS=symbols,static
-nmake -nologo -f makefile.vc release OPTS=%OPTS% %1
+nmake -nologo -f makefile.vc release OPTS=static
if errorlevel 1 goto error
:: Build the special static libraries that use the dynamic runtime.
::
-set OPTS=static,msvcrt
-if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt
-nmake -nologo -f makefile.vc core dlls OPTS=%OPTS% %1
+nmake -nologo -f makefile.vc core dlls OPTS=static,msvcrt
if errorlevel 1 goto error
:: Build the core and shell for thread support.
::
-set OPTS=threads
-if not %SYMBOLS%.==. set OPTS=symbols,threads
-nmake -nologo -f makefile.vc shell OPTS=%OPTS% %1
+nmake -nologo -f makefile.vc shell OPTS=threads
if errorlevel 1 goto error
-:: Build a static, thread support core library with a shell.
+:: Build a static, thread support core library (no shell).
::
-set OPTS=static,threads
-if not %SYMBOLS%.==. set OPTS=symbols,static,threads
-nmake -nologo -f makefile.vc shell OPTS=%OPTS% %1
+nmake -nologo -f makefile.vc core OPTS=static,threads
if errorlevel 1 goto error
-:: Build the special static libraries that use the dynamic runtime,
+:: Build the special static libraries the use the dynamic runtime,
:: but now with thread support.
::
-set OPTS=static,msvcrt,threads
-if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt,threads
-nmake -nologo -f makefile.vc core dlls OPTS=%OPTS% %1
+nmake -nologo -f makefile.vc core dlls OPTS=static,msvcrt,threads
if errorlevel 1 goto error
-set OPTS=
-set SYMBOLS=
goto end
:error
echo *** BOOM! ***
-goto end
-
-:no_vcvars
-echo vcvars32.bat not found. You'll need to edit this batch script.
-goto out
-
-:help
-title buildall.vc.bat help message
-echo usage:
-echo %0 : builds Tcl for all build types (do this first)
-echo %0 install : installs all the release builds (do this second)
-echo %0 symbols : builds Tcl for all debugging build types
-echo %0 symbols install : install all the debug builds.
-echo.
-goto out
:end
-title Building Tcl, please wait... DONE!
+title Building Tcl, please wait...DONE!
echo DONE!
-goto out
-
-:out
pause
-title Command Prompt
diff --git a/win/cat.c b/win/cat.c
index 2cedd5d..834461e 100644
--- a/win/cat.c
+++ b/win/cat.c
@@ -10,19 +10,15 @@
*/
#include <stdio.h>
-#ifdef __CYGWIN__
-# include <unistd.h>
-#else
-# include <io.h>
-#endif
+#include <io.h>
#include <string.h>
int
-main(void)
-{
+main()
+{
char buf[1024];
int n;
- const char *err;
+ char *err;
while (1) {
n = read(0, buf, sizeof(buf));
@@ -36,3 +32,4 @@ main(void)
return 0;
}
+
diff --git a/win/coffbase.txt b/win/coffbase.txt
index 8d3f84b..35dac3d 100644
--- a/win/coffbase.txt
+++ b/win/coffbase.txt
@@ -22,12 +22,4 @@ itk 0x10580000 0x00080000
bltlite 0x10600000 0x00080000
blt 0x10680000 0x00080000
iocpsock 0x10700000 0x00080000
-tls 0x10780000 0x00100000
-winico 0x10880000 0x00010000
-tile 0x10900000 0x00080000
-memchan 0x109D0000 0x00010000
-tdom 0x109E0000 0x00080000
-tkvideo 0x10B00000 0x00010000
-snack 0x1E000000 0x00400000
-sound 0x1E400000 0x00400000
-snackogg 0x1E800000 0x00200000
+tls 0x10780000 0x00080000
diff --git a/win/configure b/win/configure
index 07a9436..57bc8e6 100755
--- a/win/configure
+++ b/win/configure
@@ -1,325 +1,38 @@
#! /bin/sh
+
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
-# Copyright (C) 2003 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
- set -o posix
-fi
-DUALCASE=1; export DUALCASE # for MKS sh
-
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
-fi
-
-
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- $as_unset $as_var
- fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)$' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
- /^X\/\(\/\/\)$/{ s//\1/; q; }
- /^X\/\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
-
-
-# PATH needs CR, and LINENO needs CR and PATH.
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" || {
- # Find who we are. Look in the path if we contain no path at all
- # relative or not.
- case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
- ;;
- esac
- # We did not find ourselves, most probably we were run as `sh COMMAND'
- # in which case we are not to be found in the path.
- if test "x$as_myself" = x; then
- as_myself=$0
- fi
- if test ! -f "$as_myself"; then
- { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
- { (exit 1); exit 1; }; }
- fi
- case $CONFIG_SHELL in
- '')
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for as_base in sh bash ksh sh5; do
- case $as_dir in
- /*)
- if ("$as_dir/$as_base" -c '
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
- $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
- $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
- CONFIG_SHELL=$as_dir/$as_base
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$0" ${1+"$@"}
- fi;;
- esac
- done
-done
-;;
- esac
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line before each line; the second 'sed' does the real
- # work. The second script uses 'N' to pair each line-number line
- # with the numbered line, and appends trailing '-' during
- # substitution so that $LINENO is not a special case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
- sed '=' <$as_myself |
- sed '
- N
- s,$,-,
- : loop
- s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
- t loop
- s,-$,,
- s,^['$as_cr_digits']*\n,,
- ' >$as_me.lineno &&
- chmod +x $as_me.lineno ||
- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensible to this).
- . ./$as_me.lineno
- # Exit status is that of the last command.
- exit
-}
-
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
- *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T=' ' ;;
- *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
- *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- # We could just check for DJGPP; but this test a) works b) is more generic
- # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
- if test -f conf$$.exe; then
- # Don't use ln at all; we don't have any links
- as_ln_s='cp -p'
- else
- as_ln_s='ln -s'
- fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.file
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-as_executable_p="test -f"
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" $as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-exec 6>&1
-
-#
-# Initializations.
-#
+# Defaults:
+ac_help=
ac_default_prefix=/usr/local
-ac_config_libobj_dir=.
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Maximum number of lines to put in a shell here document.
-# This variable seems obsolete. It should probably be removed, and
-# only ac_max_sed_lines should be used.
-: ${ac_max_here_lines=38}
-
-# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
-
-ac_unique_file="../generic/tcl.h"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#if STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# if HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#if HAVE_STRING_H
-# if !STDC_HEADERS && HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#if HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#else
-# if HAVE_STDINT_H
-# include <stdint.h>
-# endif
-#endif
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_DLL_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX CFG_TCL_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TCL_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TCL_BUILD_LIB_SPEC TCL_LD_SEARCH_FLAGS TCL_NEEDS_EXP_FILE TCL_BUILD_EXP_FILE TCL_EXP_FILE TCL_LIB_VERSIONS_OK TCL_PACKAGE_PATH TCL_DDE_VERSION TCL_DDE_MAJOR_VERSION TCL_DDE_MINOR_VERSION TCL_DDE_PATCH_LEVEL TCL_REG_VERSION TCL_REG_MAJOR_VERSION TCL_REG_MINOR_VERSION TCL_REG_PATCH_LEVEL RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS'
-ac_subst_files=''
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-threads build with threads"
+ac_help="$ac_help
+ --enable-shared build and link with shared libraries [--enable-shared]"
+ac_help="$ac_help
+ --enable-64bit enable 64bit support (where applicable)"
+ac_help="$ac_help
+ --enable-wince enable Win/CE support (where applicable)"
+ac_help="$ac_help
+ --with-celib=DIR use Windows/CE support library from DIR"
+ac_help="$ac_help
+ --enable-symbols build with debugging symbols [--disable-symbols]"
# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
# The variables have the same names as the options, with
# dashes changed to underlines.
-cache_file=/dev/null
+build=NONE
+cache_file=./config.cache
exec_prefix=NONE
+host=NONE
no_create=
+nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
@@ -328,15 +41,10 @@ program_transform_name=s,x,x,
silent=
site=
srcdir=
+target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
@@ -350,9 +58,17 @@ oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
ac_prev=
for ac_option
do
+
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
eval "$ac_prev=\$ac_option"
@@ -360,59 +76,59 @@ do
continue
fi
- ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
# Accept the important Cygnus configure options, so we can diagnose typos.
- case $ac_option in
+ case "$ac_option" in
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
+ bindir="$ac_optarg" ;;
-build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
+ ac_prev=build ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
+ build="$ac_optarg" ;;
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
+ cache_file="$ac_optarg" ;;
-datadir | --datadir | --datadi | --datad | --data | --dat | --da)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
| --da=*)
- datadir=$ac_optarg ;;
+ datadir="$ac_optarg" ;;
-disable-* | --disable-*)
- ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
# Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/-/_/g'`
- eval "enable_$ac_feature=no" ;;
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
-enable-* | --enable-*)
- ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
# Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/-/_/g'`
- case $ac_option in
- *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
*) ac_optarg=yes ;;
esac
- eval "enable_$ac_feature='$ac_optarg'" ;;
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -421,47 +137,95 @@ do
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
+ exec_prefix="$ac_optarg" ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
-host | --host | --hos | --ho)
- ac_prev=host_alias ;;
+ ac_prev=host ;;
-host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
+ host="$ac_optarg" ;;
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
+ includedir="$ac_optarg" ;;
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
+ infodir="$ac_optarg" ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
+ libdir="$ac_optarg" ;;
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
+ libexecdir="$ac_optarg" ;;
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
@@ -470,19 +234,19 @@ do
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* \
| --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir=$ac_optarg ;;
+ localstatedir="$ac_optarg" ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
+ mandir="$ac_optarg" ;;
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
+ | --no-cr | --no-c)
no_create=yes ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
@@ -496,26 +260,26 @@ do
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
+ oldincludedir="$ac_optarg" ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
+ prefix="$ac_optarg" ;;
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
+ program_prefix="$ac_optarg" ;;
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
+ program_suffix="$ac_optarg" ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
@@ -532,7 +296,7 @@ do
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
+ program_transform_name="$ac_optarg" ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
@@ -542,7 +306,7 @@ do
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
+ sbindir="$ac_optarg" ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
@@ -553,57 +317,58 @@ do
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
+ sharedstatedir="$ac_optarg" ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
+ site="$ac_optarg" ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
+ srcdir="$ac_optarg" ;;
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
+ sysconfdir="$ac_optarg" ;;
-target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
+ ac_prev=target ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
+ target="$ac_optarg" ;;
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
-with-* | --with-*)
- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
# Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
- case $ac_option in
- *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ case "$ac_option" in
+ *=*) ;;
*) ac_optarg=yes ;;
esac
- eval "with_$ac_package='$ac_optarg'" ;;
+ eval "with_${ac_package}='$ac_optarg'" ;;
-without-* | --without-*)
- ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
# Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package | sed 's/-/_/g'`
- eval "with_$ac_package=no" ;;
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
--x)
# Obsolete; use --with-x.
@@ -614,110 +379,99 @@ do
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
+ x_includes="$ac_optarg" ;;
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
+ x_libraries="$ac_optarg" ;;
- -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; }
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
;;
- *=*)
- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
- # Reject names that are not valid shell variable names.
- expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
- { (exit 1); exit 1; }; }
- ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
- eval "$ac_envvar='$ac_optarg'"
- export $ac_envvar ;;
-
*)
- # FIXME: should be removed in autoconf 3.0.
- echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
;;
esac
done
if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- { echo "$as_me: error: missing argument to $ac_option" >&2
- { (exit 1); exit 1; }; }
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
fi
-# Be sure to have absolute paths.
-for ac_var in exec_prefix prefix
-do
- eval ac_val=$`echo $ac_var`
- case $ac_val in
- [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
- *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
- { (exit 1); exit 1; }; };;
- esac
-done
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
-# Be sure to have absolute paths.
-for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
- localstatedir libdir includedir oldincludedir infodir mandir
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
do
- eval ac_val=$`echo $ac_var`
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) ;;
- *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
- { (exit 1); exit 1; }; };;
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
esac
done
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used." >&2
- elif test "x$build_alias" != "x$host_alias"; then
- cross_compiling=yes
- fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
-test "$silent" = yes && exec 6>/dev/null
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=../generic/tcl.h
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
# Try the directory containing this script, then its parent.
- ac_confdir=`(dirname "$0") 2>/dev/null ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$0" : 'X\(//\)[^/]' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$0" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
srcdir=$ac_confdir
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
@@ -727,471 +481,13 @@ else
fi
if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
- { (exit 1); exit 1; }; }
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
else
- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
- { (exit 1); exit 1; }; }
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
fi
fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
- { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
- { (exit 1); exit 1; }; }
-srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
-ac_env_build_alias_set=${build_alias+set}
-ac_env_build_alias_value=$build_alias
-ac_cv_env_build_alias_set=${build_alias+set}
-ac_cv_env_build_alias_value=$build_alias
-ac_env_host_alias_set=${host_alias+set}
-ac_env_host_alias_value=$host_alias
-ac_cv_env_host_alias_set=${host_alias+set}
-ac_cv_env_host_alias_value=$host_alias
-ac_env_target_alias_set=${target_alias+set}
-ac_env_target_alias_value=$target_alias
-ac_cv_env_target_alias_set=${target_alias+set}
-ac_cv_env_target_alias_value=$target_alias
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
-ac_env_CPP_set=${CPP+set}
-ac_env_CPP_value=$CPP
-ac_cv_env_CPP_set=${CPP+set}
-ac_cv_env_CPP_value=$CPP
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-_ACEOF
-
- cat <<_ACEOF
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --infodir=DIR info documentation [PREFIX/info]
- --mandir=DIR man documentation [PREFIX/man]
-_ACEOF
-
- cat <<\_ACEOF
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
-
- cat <<\_ACEOF
-
-Optional Features:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-threads build with threads
- --enable-shared build and link with shared libraries --enable-shared
- --enable-64bit enable 64bit support (where applicable)
- --enable-wince enable Win/CE support (where applicable)
- --enable-symbols build with debugging symbols --disable-symbols
- --enable-embedded-manifest
- embed manifest if possible (default: yes)
-
-Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --with-encoding encoding for configuration values
- --with-celib=DIR use Windows/CE support library from DIR
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
- headers in a nonstandard directory <include dir>
- CPP C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-_ACEOF
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- ac_popdir=`pwd`
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d $ac_dir || continue
- ac_builddir=.
-
-if test "$ac_dir" != .; then
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A "../" for each directory in $ac_dir_suffix.
- ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
- ac_dir_suffix= ac_top_builddir=
-fi
-
-case $srcdir in
- .) # No --srcdir option. We are building in place.
- ac_srcdir=.
- if test -z "$ac_top_builddir"; then
- ac_top_srcdir=.
- else
- ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
- fi ;;
- [\\/]* | ?:[\\/]* ) # Absolute path.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir ;;
- *) # Relative path.
- ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
- case "$ac_dir" in
- .) ac_abs_builddir=`pwd`;;
- [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
- *) ac_abs_builddir=`pwd`/"$ac_dir";;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
- case ${ac_top_builddir}. in
- .) ac_abs_top_builddir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
- *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
- case $ac_srcdir in
- .) ac_abs_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
- *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
- case $ac_top_srcdir in
- .) ac_abs_top_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
- *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
- esac;;
-esac
-
- cd $ac_dir
- # Check for guested configure; otherwise get Cygnus style configure.
- if test -f $ac_srcdir/configure.gnu; then
- echo
- $SHELL $ac_srcdir/configure.gnu --help=recursive
- elif test -f $ac_srcdir/configure; then
- echo
- $SHELL $ac_srcdir/configure --help=recursive
- elif test -f $ac_srcdir/configure.ac ||
- test -f $ac_srcdir/configure.in; then
- echo
- $ac_configure --help
- else
- echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi
- cd $ac_popdir
- done
-fi
-
-test -n "$ac_init_help" && exit 0
-if $ac_init_version; then
- cat <<\_ACEOF
-
-Copyright (C) 2003 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
- exit 0
-fi
-exec 5>config.log
-cat >&5 <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by $as_me, which was
-generated by GNU Autoconf 2.59. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- echo "PATH: $as_dir"
-done
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_sep=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
- 2)
- ac_configure_args1="$ac_configure_args1 '$ac_arg'"
- if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
- else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
- # Get rid of the leading space.
- ac_sep=" "
- ;;
- esac
- done
-done
-$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
-$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log. We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Be sure not to use single quotes in there, as some shells,
-# such as our DU 5.0 friend, will then `close' the trap.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- cat <<\_ASBOX
-## ---------------- ##
-## Cache variables. ##
-## ---------------- ##
-_ASBOX
- echo
- # The following way of writing the cache mishandles newlines in values,
-{
- (set) 2>&1 |
- case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- sed -n \
- "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
- ;;
- *)
- sed -n \
- "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
- ;;
- esac;
-}
- echo
-
- cat <<\_ASBOX
-## ----------------- ##
-## Output variables. ##
-## ----------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=$`echo $ac_var`
- echo "$ac_var='"'"'$ac_val'"'"'"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------- ##
-## Output files. ##
-## ------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=$`echo $ac_var`
- echo "$ac_var='"'"'$ac_val'"'"'"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
-## confdefs.h. ##
-## ----------- ##
-_ASBOX
- echo
- sed "/^$/d" confdefs.h | sort
- echo
- fi
- test "$ac_signal" != 0 &&
- echo "$as_me: caught signal $ac_signal"
- echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core &&
- rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
- ' 0
-for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo >confdefs.h
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
# Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then
if test "x$prefix" != xNONE; then
@@ -1202,128 +498,57 @@ if test -z "$CONFIG_SITE"; then
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then
- { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&5
+ echo "loading site script $ac_site_file"
. "$ac_site_file"
fi
done
if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special
- # files actually), so we avoid doing that.
- if test -f "$cache_file"; then
- { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . $cache_file;;
- *) . ./$cache_file;;
- esac
- fi
+ echo "loading cache $cache_file"
+ . $cache_file
else
- { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in `(set) 2>&1 |
- sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val="\$ac_cv_env_${ac_var}_value"
- eval ac_new_val="\$ac_env_${ac_var}_value"
- case $ac_old_set,$ac_new_set in
- set,)
- { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
-echo "$as_me: former value: $ac_old_val" >&2;}
- { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
-echo "$as_me: current value: $ac_new_val" >&2;}
- ac_cache_corrupted=:
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
- ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
- { (exit 1); exit 1; }; }
+ echo "creating cache $cache_file"
+ > $cache_file
fi
ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
-# The following define is needed when building with Cygwin since newer
-# versions of autoconf incorrectly set SHELL to /bin/bash instead of
-# /bin/sh. The bash shell seems to suffer from some strange failures.
-SHELL=/bin/sh
-TCL_VERSION=8.5
+TCL_VERSION=8.4
TCL_MAJOR_VERSION=8
-TCL_MINOR_VERSION=5
-TCL_PATCH_LEVEL=".11"
+TCL_MINOR_VERSION=4
+TCL_PATCH_LEVEL=".19"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
-TCL_DDE_VERSION=1.3
+TCL_DDE_VERSION=1.2
TCL_DDE_MAJOR_VERSION=1
-TCL_DDE_MINOR_VERSION=3
-TCL_DDE_PATCH_LEVEL="2"
+TCL_DDE_MINOR_VERSION=2
DDEVER=$TCL_DDE_MAJOR_VERSION$TCL_DDE_MINOR_VERSION
-TCL_REG_VERSION=1.2
+TCL_REG_VERSION=1.1
TCL_REG_MAJOR_VERSION=1
-TCL_REG_MINOR_VERSION=2
-TCL_REG_PATCH_LEVEL="1"
+TCL_REG_MINOR_VERSION=1
REGVER=$TCL_REG_MAJOR_VERSION$TCL_REG_MINOR_VERSION
#------------------------------------------------------------------------
@@ -1349,659 +574,214 @@ if test "${CFLAGS+set}" != "set" ; then
CFLAGS=""
fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
+# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- CC=$ac_ct_CC
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:581: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
fi
fi
-CC=$ac_cv_prog_CC
+CC="$ac_cv_prog_CC"
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ echo "$ac_t""$CC" 1>&6
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
+ echo "$ac_t""no" 1>&6
fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- CC=$ac_ct_CC
-else
- CC="$ac_cv_prog_CC"
-fi
-
-fi
if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:611: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
set dummy $ac_cv_prog_CC
shift
- if test $# != 0; then
+ if test $# -gt 0; then
# We chose a different compiler from the bogus one.
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
fi
fi
fi
fi
-CC=$ac_cv_prog_CC
+CC="$ac_cv_prog_CC"
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ echo "$ac_t""$CC" 1>&6
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ echo "$ac_t""no" 1>&6
fi
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:662: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
fi
fi
-CC=$ac_cv_prog_CC
+CC="$ac_cv_prog_CC"
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ echo "$ac_t""$CC" 1>&6
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ echo "$ac_t""no" 1>&6
fi
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
+ ;;
+ esac
fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$ac_ct_CC" && break
-done
-
- CC=$ac_ct_CC
-fi
-
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:694: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
- "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
- (eval $ac_compiler --version </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
- (eval $ac_compiler -v </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
- (eval $ac_compiler -V </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
- (eval $ac_link_default) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # Find the output, starting from the most likely. This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
-
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
- ;;
- conftest.$ac_ext )
- # This is the source file.
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- # FIXME: I believe we export ac_cv_exeext for Libtool,
- # but it would be cool to find out if it's true. Does anybody
- # maintain Libtool? --akim.
- export ac_cv_exeext
- break;;
- * )
- break;;
- esac
-done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
-fi
-
-ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
-
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- cross_compiling=no
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 705 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:710: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
- fi
+ ac_cv_prog_cc_cross=yes
fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
-
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- export ac_cv_exeext
- break;;
- * ) break;;
- esac
-done
else
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
fi
-
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:736: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:741: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:750: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ ac_cv_prog_gcc=no
fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-ac_compiler_gnu=no
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:769: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
ac_cv_prog_cc_g=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_prog_cc_g=no
+ ac_cv_prog_cc_g=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest*
+
fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
+ CFLAGS="$ac_save_CFLAGS"
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2"
@@ -2015,1027 +795,143 @@ else
CFLAGS=
fi
fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_prog_cc_stdc=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std1 is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std1. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX -qlanglvl=ansi
-# Ultrix and OSF/1 -std1
-# HP-UX 10.20 and later -Ae
-# HP-UX older versions -Aa -D_HPUX_SOURCE
-# SVR4 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_stdc=$ac_arg
-break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-fi
-rm -f conftest.err conftest.$ac_objext
-done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
+# To properly support cross-compilation, one would
+# need to use these tool checks instead of
+# the ones below and reconfigure with
+# autoconf 2.50. You can also just set
+# the CC, AR, RANLIB, and RC environment
+# variables if you want to cross compile.
-fi
-
-case "x$ac_cv_prog_cc_stdc" in
- x|xno)
- echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
- *)
- echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
- CC="$CC $ac_cv_prog_cc_stdc" ;;
-esac
-
-# Some people use a C++ compiler to compile C. Since we use `exit',
-# in C++ we need to declare it. In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
-cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
- choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- for ac_declaration in \
- '' \
- 'extern "C" void std::exit (int) throw (); using std::exit;' \
- 'extern "C" void std::exit (int); using std::exit;' \
- 'extern "C" void exit (int) throw ();' \
- 'extern "C" void exit (int);' \
- 'void exit (int);'
-do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-continue
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
- echo '#ifdef __cplusplus' >>confdefs.h
- echo $ac_declaration >>confdefs.h
- echo '#endif' >>confdefs.h
-fi
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-echo "$as_me:$LINENO: checking for inline" >&5
-echo $ECHO_N "checking for inline... $ECHO_C" >&6
-if test "${ac_cv_c_inline+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_c_inline=no
-for ac_kw in inline __inline__ __inline; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifndef __cplusplus
-typedef int foo_t;
-static $ac_kw foo_t static_foo () {return 0; }
-$ac_kw foo_t foo () {return 0; }
-#endif
-
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_c_inline=$ac_kw; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
-echo "${ECHO_T}$ac_cv_c_inline" >&6
-
-
-case $ac_cv_c_inline in
- inline | yes) ;;
- *)
- case $ac_cv_c_inline in
- no) ac_val=;;
- *) ac_val=$ac_cv_c_inline;;
- esac
- cat >>confdefs.h <<_ACEOF
-#ifndef __cplusplus
-#define inline $ac_val
-#endif
-_ACEOF
- ;;
-esac
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether non-existent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether non-existent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
-else
- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6
-if test "${ac_cv_prog_egrep+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if echo a | (grep -E '(a|b)') >/dev/null 2>&1
- then ac_cv_prog_egrep='grep -E'
- else ac_cv_prog_egrep='egrep'
- fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
-echo "${ECHO_T}$ac_cv_prog_egrep" >&6
- EGREP=$ac_cv_prog_egrep
-
-
-echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
-if test "${ac_cv_header_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_header_stdc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_header_stdc=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then
- :
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ctype.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- exit(2);
- exit (0);
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_header_stdc=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6
-if test $ac_cv_header_stdc = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
-
-fi
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ar; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+if test "${GCC}" = "yes" ; then
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:812: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$AR"; then
ac_cv_prog_AR="$AR" # Let the user override the test.
else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_AR="${ac_tool_prefix}ar"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AR="ar"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
fi
fi
-AR=$ac_cv_prog_AR
+AR="$ac_cv_prog_AR"
if test -n "$AR"; then
- echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6
+ echo "$ac_t""$AR" 1>&6
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ echo "$ac_t""no" 1>&6
fi
-fi
-if test -z "$ac_cv_prog_AR"; then
- ac_ct_AR=$AR
- # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_AR"; then
- ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_AR="ar"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_AR=$ac_cv_prog_ac_ct_AR
-if test -n "$ac_ct_AR"; then
- echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
-echo "${ECHO_T}$ac_ct_AR" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- AR=$ac_ct_AR
-else
- AR="$ac_cv_prog_AR"
-fi
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:841: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$RANLIB"; then
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
fi
fi
-RANLIB=$ac_cv_prog_RANLIB
+RANLIB="$ac_cv_prog_RANLIB"
if test -n "$RANLIB"; then
- echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6
+ echo "$ac_t""$RANLIB" 1>&6
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
+ echo "$ac_t""no" 1>&6
fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- RANLIB=$ac_ct_RANLIB
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
-set dummy ${ac_tool_prefix}windres; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_RC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ # Extract the first word of "windres", so it can be a program name with args.
+set dummy windres; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:870: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$RC"; then
ac_cv_prog_RC="$RC" # Let the user override the test.
else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_RC="${ac_tool_prefix}windres"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RC="windres"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
fi
fi
-RC=$ac_cv_prog_RC
+RC="$ac_cv_prog_RC"
if test -n "$RC"; then
- echo "$as_me:$LINENO: result: $RC" >&5
-echo "${ECHO_T}$RC" >&6
+ echo "$ac_t""$RC" 1>&6
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ echo "$ac_t""no" 1>&6
fi
-fi
-if test -z "$ac_cv_prog_RC"; then
- ac_ct_RC=$RC
- # Extract the first word of "windres", so it can be a program name with args.
-set dummy windres; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_RC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_RC"; then
- ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_RC="windres"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-fi
-fi
-ac_ct_RC=$ac_cv_prog_ac_ct_RC
-if test -n "$ac_ct_RC"; then
- echo "$as_me:$LINENO: result: $ac_ct_RC" >&5
-echo "${ECHO_T}$ac_ct_RC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- RC=$ac_ct_RC
-else
- RC="$ac_cv_prog_RC"
+ if test "${AR}" = "" ; then
+ { echo "configure: error: Required archive tool 'ar' not found on PATH." 1>&2; exit 1; }
+ fi
+ if test "${RANLIB}" = "" ; then
+ { echo "configure: error: Required archive index tool 'ranlib' not found on PATH." 1>&2; exit 1; }
+ fi
+ if test "${RC}" = "" ; then
+ { echo "configure: error: Required resource tool 'windres' not found on PATH." 1>&2; exit 1; }
+ fi
fi
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
-if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:913: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- cat >conftest.make <<\_ACEOF
+ cat > conftestmake <<\EOF
all:
- @echo 'ac_maketemp="$(MAKE)"'
-_ACEOF
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
if test -n "$ac_maketemp"; then
eval ac_cv_prog_make_${ac_make}_set=yes
else
eval ac_cv_prog_make_${ac_make}_set=no
fi
-rm -f conftest.make
+rm -f conftestmake
fi
if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+ echo "$ac_t""yes" 1>&6
SET_MAKE=
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ echo "$ac_t""no" 1>&6
SET_MAKE="MAKE=${MAKE-make}"
fi
@@ -3044,90 +940,58 @@ fi
# Perform additinal compiler tests.
#--------------------------------------------------------------------
-
-echo "$as_me:$LINENO: checking for Cygwin version of gcc" >&5
-echo $ECHO_N "checking for Cygwin version of gcc... $ECHO_C" >&6
-if test "${ac_cv_cygwin+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:945: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#ifdef __CYGWIN__
-#error cygwin
-#endif
+ cat > conftest.$ac_ext <<EOF
+#line 950 "configure"
+#include "confdefs.h"
-int
-main ()
-{
+int main() {
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:961: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
ac_cv_cygwin=no
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_cygwin=yes
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f conftest*
+rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5
-echo "${ECHO_T}$ac_cv_cygwin" >&6
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+
if test "$ac_cv_cygwin" = "yes" ; then
- { { echo "$as_me:$LINENO: error: Compiling under Cygwin is not currently supported.
+ { echo "configure: error: Compiling under Cygwin is not currently supported.
A maintainer for the Cygwin port of Tcl/Tk is needed. See the README
-file for information about building with Mingw." >&5
-echo "$as_me: error: Compiling under Cygwin is not currently supported.
-A maintainer for the Cygwin port of Tcl/Tk is needed. See the README
-file for information about building with Mingw." >&2;}
- { (exit 1); exit 1; }; }
+file for information about building with Mingw." 1>&2; exit 1; }
fi
-echo "$as_me:$LINENO: checking for SEH support in compiler" >&5
-echo $ECHO_N "checking for SEH support in compiler... $ECHO_C" >&6
-if test "${tcl_cv_seh+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for SEH support in compiler""... $ac_c" 1>&6
+echo "configure:986: checking for SEH support in compiler" >&5
+if eval "test \"`echo '$''{'tcl_cv_seh'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
tcl_cv_seh=no
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+ cat > conftest.$ac_ext <<EOF
+#line 994 "configure"
+#include "confdefs.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -3144,38 +1008,27 @@ int main(int argc, char** argv) {
return 1;
}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+EOF
+if { (eval echo configure:1013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
tcl_cv_seh=yes
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-tcl_cv_seh=no
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tcl_cv_seh=no
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -fr conftest*
fi
+
fi
-echo "$as_me:$LINENO: result: $tcl_cv_seh" >&5
-echo "${ECHO_T}$tcl_cv_seh" >&6
-if test "$tcl_cv_seh" = "no" ; then
-cat >>confdefs.h <<\_ACEOF
+echo "$ac_t""$tcl_cv_seh" 1>&6
+if test "$tcl_cv_seh" = "no" ; then
+ cat >> confdefs.h <<\EOF
#define HAVE_NO_SEH 1
-_ACEOF
+EOF
fi
@@ -3185,71 +1038,43 @@ fi
# with Cygwin's version as of 2002-04-10, define it to be int,
# sufficient for getting the current code to work.
#
-echo "$as_me:$LINENO: checking for EXCEPTION_DISPOSITION support in include files" >&5
-echo $ECHO_N "checking for EXCEPTION_DISPOSITION support in include files... $ECHO_C" >&6
-if test "${tcl_cv_eh_disposition+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for EXCEPTION_DISPOSITION support in include files""... $ac_c" 1>&6
+echo "configure:1043: checking for EXCEPTION_DISPOSITION support in include files" >&5
+if eval "test \"`echo '$''{'tcl_cv_eh_disposition'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+ cat > conftest.$ac_ext <<EOF
+#line 1048 "configure"
+#include "confdefs.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
-int
-main ()
-{
+int main() {
EXCEPTION_DISPOSITION x;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+; return 0; }
+EOF
+if { (eval echo configure:1061: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
tcl_cv_eh_disposition=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_eh_disposition=no
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_cv_eh_disposition=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $tcl_cv_eh_disposition" >&5
-echo "${ECHO_T}$tcl_cv_eh_disposition" >&6
-if test "$tcl_cv_eh_disposition" = "no" ; then
-cat >>confdefs.h <<\_ACEOF
+echo "$ac_t""$tcl_cv_eh_disposition" 1>&6
+if test "$tcl_cv_eh_disposition" = "no" ; then
+ cat >> confdefs.h <<\EOF
#define EXCEPTION_DISPOSITION int
-_ACEOF
+EOF
fi
@@ -3257,72 +1082,44 @@ fi
# Check to see if the winsock2.h include file provided contains
# typedefs like LPFN_ACCEPT and friends.
#
-echo "$as_me:$LINENO: checking for LPFN_ACCEPT support in winsock2.h" >&5
-echo $ECHO_N "checking for LPFN_ACCEPT support in winsock2.h... $ECHO_C" >&6
-if test "${tcl_cv_lpfn_decls+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for LPFN_ACCEPT support in winsock2.h""... $ac_c" 1>&6
+echo "configure:1087: checking for LPFN_ACCEPT support in winsock2.h" >&5
+if eval "test \"`echo '$''{'tcl_cv_lpfn_decls'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+ cat > conftest.$ac_ext <<EOF
+#line 1092 "configure"
+#include "confdefs.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <winsock2.h>
-int
-main ()
-{
+int main() {
LPFN_ACCEPT accept;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+; return 0; }
+EOF
+if { (eval echo configure:1106: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
tcl_cv_lpfn_decls=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_lpfn_decls=no
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_cv_lpfn_decls=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $tcl_cv_lpfn_decls" >&5
-echo "${ECHO_T}$tcl_cv_lpfn_decls" >&6
-if test "$tcl_cv_lpfn_decls" = "no" ; then
-cat >>confdefs.h <<\_ACEOF
+echo "$ac_t""$tcl_cv_lpfn_decls" 1>&6
+if test "$tcl_cv_lpfn_decls" = "no" ; then
+ cat >> confdefs.h <<\EOF
#define HAVE_NO_LPFN_DECLS 1
-_ACEOF
+EOF
fi
@@ -3330,74 +1127,46 @@ fi
# even if VOID has already been #defined. The win32api
# used by mingw and cygwin is known to do this.
-echo "$as_me:$LINENO: checking for winnt.h that ignores VOID define" >&5
-echo $ECHO_N "checking for winnt.h that ignores VOID define... $ECHO_C" >&6
-if test "${tcl_cv_winnt_ignore_void+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for winnt.h that ignores VOID define""... $ac_c" 1>&6
+echo "configure:1132: checking for winnt.h that ignores VOID define" >&5
+if eval "test \"`echo '$''{'tcl_cv_winnt_ignore_void'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+ cat > conftest.$ac_ext <<EOF
+#line 1137 "configure"
+#include "confdefs.h"
#define VOID void
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
-int
-main ()
-{
+int main() {
CHAR c;
SHORT s;
LONG l;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+; return 0; }
+EOF
+if { (eval echo configure:1153: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
tcl_cv_winnt_ignore_void=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_winnt_ignore_void=no
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_cv_winnt_ignore_void=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $tcl_cv_winnt_ignore_void" >&5
-echo "${ECHO_T}$tcl_cv_winnt_ignore_void" >&6
-if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
-cat >>confdefs.h <<\_ACEOF
+echo "$ac_t""$tcl_cv_winnt_ignore_void" 1>&6
+if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+ cat >> confdefs.h <<\EOF
#define HAVE_WINNT_IGNORE_VOID 1
-_ACEOF
+EOF
fi
@@ -3411,73 +1180,45 @@ fi
# register and not on the stack. Instead, we just
# call it from inline asm code.
-echo "$as_me:$LINENO: checking for alloca declaration in malloc.h" >&5
-echo $ECHO_N "checking for alloca declaration in malloc.h... $ECHO_C" >&6
-if test "${tcl_cv_malloc_decl_alloca+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for alloca declaration in malloc.h""... $ac_c" 1>&6
+echo "configure:1185: checking for alloca declaration in malloc.h" >&5
+if eval "test \"`echo '$''{'tcl_cv_malloc_decl_alloca'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+ cat > conftest.$ac_ext <<EOF
+#line 1190 "configure"
+#include "confdefs.h"
#include <malloc.h>
-int
-main ()
-{
+int main() {
size_t arg = 0;
void* ptr;
ptr = alloca;
ptr = alloca(arg);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+; return 0; }
+EOF
+if { (eval echo configure:1204: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
tcl_cv_malloc_decl_alloca=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_malloc_decl_alloca=no
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_cv_malloc_decl_alloca=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $tcl_cv_malloc_decl_alloca" >&5
-echo "${ECHO_T}$tcl_cv_malloc_decl_alloca" >&6
+
+echo "$ac_t""$tcl_cv_malloc_decl_alloca" 1>&6
if test "$tcl_cv_malloc_decl_alloca" = "no" &&
test "${GCC}" = "yes" ; then
-
-cat >>confdefs.h <<\_ACEOF
+ cat >> confdefs.h <<\EOF
#define HAVE_ALLOCA_GCC_INLINE 1
-_ACEOF
+EOF
fi
@@ -3485,220 +1226,132 @@ fi
# This is used to stop gcc from printing a compiler
# warning when initializing a union member.
-echo "$as_me:$LINENO: checking for cast to union support" >&5
-echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6
-if test "${tcl_cv_cast_to_union+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for cast to union support""... $ac_c" 1>&6
+echo "configure:1231: checking for cast to union support" >&5
+if eval "test \"`echo '$''{'tcl_cv_cast_to_union'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+ cat > conftest.$ac_ext <<EOF
+#line 1236 "configure"
+#include "confdefs.h"
-int
-main ()
-{
+int main() {
union foo { int i; double d; };
union foo f = (union foo) (int) 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+; return 0; }
+EOF
+if { (eval echo configure:1246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
tcl_cv_cast_to_union=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cast_to_union=no
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_cv_cast_to_union=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5
-echo "${ECHO_T}$tcl_cv_cast_to_union" >&6
-if test "$tcl_cv_cast_to_union" = "yes"; then
-cat >>confdefs.h <<\_ACEOF
+echo "$ac_t""$tcl_cv_cast_to_union" 1>&6
+if test "$tcl_cv_cast_to_union" = "yes"; then
+ cat >> confdefs.h <<\EOF
#define HAVE_CAST_TO_UNION 1
-_ACEOF
+EOF
fi
-# See if declarations like FINDEX_INFO_LEVELS are
-# missing from winbase.h. This is known to be
-# a problem with VC++ 5.2.
-
-echo "$as_me:$LINENO: checking for FINDEX_INFO_LEVELS in winbase.h" >&5
-echo $ECHO_N "checking for FINDEX_INFO_LEVELS in winbase.h... $ECHO_C" >&6
-if test "${tcl_cv_findex_enums+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-
-int
-main ()
-{
-
- FINDEX_INFO_LEVELS i;
- FINDEX_SEARCH_OPS j;
+#--------------------------------------------------------------------
+# Determines the correct binary file extension (.o, .obj, .exe etc.)
+#--------------------------------------------------------------------
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_findex_enums=yes
+echo $ac_n "checking for object suffix""... $ac_c" 1>&6
+echo "configure:1272: checking for object suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftest*
+echo 'int i = 1;' > conftest.$ac_ext
+if { (eval echo configure:1278: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_findex_enums=no
+ { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $tcl_cv_findex_enums" >&5
-echo "${ECHO_T}$tcl_cv_findex_enums" >&6
-if test "$tcl_cv_findex_enums" = "no"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_NO_FINDEX_ENUMS 1
-_ACEOF
+echo "$ac_t""$ac_cv_objext" 1>&6
+OBJEXT=$ac_cv_objext
+ac_objext=$ac_cv_objext
+
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:1296: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1301 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:1308: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
fi
-# See if MWMO_ALERTABLE is missing from winuser.h
-# This is known to be a problem with Mingw.
-
-echo "$as_me:$LINENO: checking for MWMO_ALERTABLE in winuser.h" >&5
-echo $ECHO_N "checking for MWMO_ALERTABLE in winuser.h... $ECHO_C" >&6
-if test "${tcl_cv_mwmo_alertable+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-
-int
-main ()
-{
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
- int i = MWMO_ALERTABLE;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_mwmo_alertable=yes
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:1327: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_mwmo_alertable=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:1337: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
fi
-echo "$as_me:$LINENO: result: $tcl_cv_mwmo_alertable" >&5
-echo "${ECHO_T}$tcl_cv_mwmo_alertable" >&6
-if test "$tcl_cv_mwmo_alertable" = "no"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_NO_MWMO_ALERTABLE 1
-_ACEOF
-
fi
-#--------------------------------------------------------------------
-# Determines the correct binary file extension (.o, .obj, .exe etc.)
-#--------------------------------------------------------------------
-
-
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
#--------------------------------------------------------------------
@@ -3706,62 +1359,35 @@ fi
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for building with threads" >&5
-echo $ECHO_N "checking for building with threads... $ECHO_C" >&6
+ echo $ac_n "checking for building with threads""... $ac_c" 1>&6
+echo "configure:1364: checking for building with threads" >&5
# Check whether --enable-threads or --disable-threads was given.
if test "${enable_threads+set}" = set; then
enableval="$enable_threads"
tcl_ok=$enableval
else
tcl_ok=no
-fi;
+fi
+
if test "$tcl_ok" = "yes"; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+ echo "$ac_t""yes" 1>&6
TCL_THREADS=1
- cat >>confdefs.h <<\_ACEOF
+ cat >> confdefs.h <<\EOF
#define TCL_THREADS 1
-_ACEOF
+EOF
# USE_THREAD_ALLOC tells us to try the special thread-based
# allocator that significantly reduces lock contention
- cat >>confdefs.h <<\_ACEOF
+ cat >> confdefs.h <<\EOF
#define USE_THREAD_ALLOC 1
-_ACEOF
+EOF
else
TCL_THREADS=0
- echo "$as_me:$LINENO: result: no (default)" >&5
-echo "${ECHO_T}no (default)" >&6
- fi
-
-
-
-#------------------------------------------------------------------------
-# Embedded configuration information, encoding to use for the values, TIP #59
-#------------------------------------------------------------------------
-
-
-
-# Check whether --with-encoding or --without-encoding was given.
-if test "${with_encoding+set}" = set; then
- withval="$with_encoding"
- with_tcencoding=${withval}
-fi;
-
- if test x"${with_tcencoding}" != x ; then
- cat >>confdefs.h <<_ACEOF
-#define TCL_CFGVAL_ENCODING "${with_tcencoding}"
-_ACEOF
-
- else
- # Default encoding on windows is not "iso8859-1"
- cat >>confdefs.h <<\_ACEOF
-#define TCL_CFGVAL_ENCODING "cp1252"
-_ACEOF
-
+ echo "$ac_t""no (default)" 1>&6
fi
+
#--------------------------------------------------------------------
@@ -3770,15 +1396,16 @@ _ACEOF
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking how to build libraries" >&5
-echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6
+ echo $ac_n "checking how to build libraries""... $ac_c" 1>&6
+echo "configure:1401: checking how to build libraries" >&5
# Check whether --enable-shared or --disable-shared was given.
if test "${enable_shared+set}" = set; then
enableval="$enable_shared"
tcl_ok=$enableval
else
tcl_ok=yes
-fi;
+fi
+
if test "${enable_shared+set}" = set; then
enableval="$enable_shared"
@@ -3788,16 +1415,14 @@ fi;
fi
if test "$tcl_ok" = "yes" ; then
- echo "$as_me:$LINENO: result: shared" >&5
-echo "${ECHO_T}shared" >&6
+ echo "$ac_t""shared" 1>&6
SHARED_BUILD=1
else
- echo "$as_me:$LINENO: result: static" >&5
-echo "${ECHO_T}static" >&6
+ echo "$ac_t""static" 1>&6
SHARED_BUILD=0
- cat >>confdefs.h <<\_ACEOF
+ cat >> confdefs.h <<\EOF
#define STATIC_BUILD 1
-_ACEOF
+EOF
fi
@@ -3808,158 +1433,79 @@ _ACEOF
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_Header=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_Header=no"
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
# Step 0: Enable 64 bit support?
- echo "$as_me:$LINENO: checking if 64bit support is requested" >&5
-echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6
+ echo $ac_n "checking if 64bit support is requested""... $ac_c" 1>&6
+echo "configure:1442: checking if 64bit support is requested" >&5
# Check whether --enable-64bit or --disable-64bit was given.
if test "${enable_64bit+set}" = set; then
enableval="$enable_64bit"
do64bit=$enableval
else
do64bit=no
-fi;
- echo "$as_me:$LINENO: result: $do64bit" >&5
-echo "${ECHO_T}$do64bit" >&6
+fi
+
+ echo "$ac_t""$do64bit" 1>&6
# Cross-compiling options for Windows/CE builds
- echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5
-echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6
+ echo $ac_n "checking if Windows/CE build is requested""... $ac_c" 1>&6
+echo "configure:1456: checking if Windows/CE build is requested" >&5
# Check whether --enable-wince or --disable-wince was given.
if test "${enable_wince+set}" = set; then
enableval="$enable_wince"
doWince=$enableval
else
doWince=no
-fi;
- echo "$as_me:$LINENO: result: $doWince" >&5
-echo "${ECHO_T}$doWince" >&6
+fi
- echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5
-echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6
+ echo "$ac_t""$doWince" 1>&6
-# Check whether --with-celib or --without-celib was given.
+ echo $ac_n "checking for Windows/CE celib directory""... $ac_c" 1>&6
+echo "configure:1468: checking for Windows/CE celib directory" >&5
+ # Check whether --with-celib or --without-celib was given.
if test "${with_celib+set}" = set; then
withval="$with_celib"
CELIB_DIR=$withval
else
CELIB_DIR=NO_CELIB
-fi;
- echo "$as_me:$LINENO: result: $CELIB_DIR" >&5
-echo "${ECHO_T}$CELIB_DIR" >&6
+fi
+
+ echo "$ac_t""$CELIB_DIR" 1>&6
# Set some defaults (may get changed below)
EXTRA_CFLAGS=""
# Extract the first word of "cygpath", so it can be a program name with args.
set dummy cygpath; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CYGPATH+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1485: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CYGPATH'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CYGPATH"; then
ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CYGPATH="cygpath -w"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CYGPATH="cygpath -w"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
fi
fi
-CYGPATH=$ac_cv_prog_CYGPATH
+CYGPATH="$ac_cv_prog_CYGPATH"
if test -n "$CYGPATH"; then
- echo "$as_me:$LINENO: result: $CYGPATH" >&5
-echo "${ECHO_T}$CYGPATH" >&6
+ echo "$ac_t""$CYGPATH" 1>&6
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ echo "$ac_t""no" 1>&6
fi
@@ -3982,20 +1528,13 @@ fi
echo "101 \"name\"" >> $conftest
echo "END" >> $conftest
- echo "$as_me:$LINENO: checking for Windows native path bug in windres" >&5
-echo $ECHO_N "checking for Windows native path bug in windres... $ECHO_C" >&6
+ echo $ac_n "checking for Windows native path bug in windres""... $ac_c" 1>&6
+echo "configure:1533: checking for Windows native path bug in windres" >&5
cyg_conftest=`$CYGPATH $conftest`
- if { ac_try='$RC -o conftest.res.o $cyg_conftest'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } ; then
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ if { ac_try='$RC -o conftest.res.o $cyg_conftest'; { (eval echo configure:1535: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } ; then
+ echo "$ac_t""no" 1>&6
else
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+ echo "$ac_t""yes" 1>&6
CYGPATH=echo
fi
conftest=
@@ -4010,14 +1549,13 @@ echo "${ECHO_T}yes" >&6
# set various compiler flags depending on whether we are using gcc or cl
- echo "$as_me:$LINENO: checking compiler flags" >&5
-echo $ECHO_N "checking compiler flags... $ECHO_C" >&6
+ echo $ac_n "checking compiler flags""... $ac_c" 1>&6
+echo "configure:1554: checking compiler flags" >&5
if test "${GCC}" = "yes" ; then
SHLIB_LD=""
SHLIB_LD_LIBS=""
- LIBS="-lws2_32"
- # mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
- LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32"
+ LIBS=""
+ LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32"
STLIB_LD='${AR} cr'
RC_OUT=-o
RC_TYPE=
@@ -4049,8 +1587,7 @@ echo $ECHO_N "checking compiler flags... $ECHO_C" >&6
if test "${SHARED_BUILD}" = "0" ; then
# static
- echo "$as_me:$LINENO: result: using static flags" >&5
-echo "${ECHO_T}using static flags" >&6
+ echo "$ac_t""using static flags" 1>&6
runtime=
MAKE_DLL="echo "
LIBSUFFIX="s\${DBGX}.a"
@@ -4059,16 +1596,12 @@ echo "${ECHO_T}using static flags" >&6
EXESUFFIX="s\${DBGX}.exe"
else
# dynamic
- echo "$as_me:$LINENO: result: using shared flags" >&5
-echo "${ECHO_T}using shared flags" >&6
+ echo "$ac_t""using shared flags" 1>&6
# ad-hoc check to see if CC supports -shared.
if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then
- { { echo "$as_me:$LINENO: error: ${CC} does not support the -shared option.
- You will need to upgrade to a newer version of the toolchain." >&5
-echo "$as_me: error: ${CC} does not support the -shared option.
- You will need to upgrade to a newer version of the toolchain." >&2;}
- { (exit 1); exit 1; }; }
+ { echo "configure: error: ${CC} does not support the -shared option.
+ You will need to upgrade to a newer version of the toolchain." 1>&2; exit 1; }
fi
runtime=
@@ -4095,7 +1628,7 @@ echo "$as_me: error: ${CC} does not support the -shared option.
CFLAGS_DEBUG=-g
CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- CFLAGS_WARNING="-Wall"
+ CFLAGS_WARNING="-Wall -fno-strict-aliasing"
LDFLAGS_DEBUG=
LDFLAGS_OPTIMIZE=
@@ -4123,78 +1656,47 @@ echo "$as_me: error: ${CC} does not support the -shared option.
case "$do64bit" in
amd64|x64|yes)
MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
- echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5
-echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6
+ echo "$ac_t"" Using 64-bit $MACHINE mode" 1>&6
;;
ia64)
MACHINE="IA64"
- echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5
-echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6
+ echo "$ac_t"" Using 64-bit $MACHINE mode" 1>&6
;;
*)
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+ cat > conftest.$ac_ext <<EOF
+#line 1668 "configure"
+#include "confdefs.h"
#ifdef _WIN64
#error 64-bit
#endif
+
+int main() {
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+; return 0; }
+EOF
+if { (eval echo configure:1679: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
tcl_win_64bit=no
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_win_64bit=yes
-
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_win_64bit=yes
+
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest*
if test "$tcl_win_64bit" = "yes" ; then
do64bit=amd64
MACHINE="AMD64"
- echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5
-echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6
+ echo "$ac_t"" Using 64-bit $MACHINE mode" 1>&6
fi
;;
esac
else
if test "${SHARED_BUILD}" = "0" ; then
# static
- echo "$as_me:$LINENO: result: using static flags" >&5
-echo "${ECHO_T}using static flags" >&6
+ echo "$ac_t""using static flags" 1>&6
runtime=-MT
MAKE_DLL="echo "
LIBSUFFIX="s\${DBGX}.lib"
@@ -4204,8 +1706,7 @@ echo "${ECHO_T}using static flags" >&6
SHLIB_LD_LIBS=""
else
# dynamic
- echo "$as_me:$LINENO: result: using shared flags" >&5
-echo "${ECHO_T}using shared flags" >&6
+ echo "$ac_t""using shared flags" 1>&6
runtime=-MD
# Add SHLIB_LD_LIBS to the Make rule, not here.
MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\$@"
@@ -4239,88 +1740,21 @@ echo "${ECHO_T}using shared flags" >&6
;;
esac
if test ! -d "${PATH64}" ; then
- { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
-echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
- { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5
-echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
+ echo "configure: warning: Could not find 64-bit $MACHINE SDK to enable 64bit mode" 1>&2
+ echo "configure: warning: Ensure latest Platform SDK is installed" 1>&2
do64bit="no"
else
- echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5
-echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6
+ echo "$ac_t"" Using 64-bit $MACHINE mode" 1>&6
fi
fi
- LIBS="user32.lib advapi32.lib ws2_32.lib"
+ LIBS="user32.lib advapi32.lib"
if test "$do64bit" != "no" ; then
# The space-based-path will work for the Makefile, but will
# not work if AC_TRY_COMPILE is called. TEA has the
# TEA_PATH_NOSPACE to avoid this issue.
- # Check if _WIN64 is already recognized, and if so we don't
- # need to modify CC.
- echo "$as_me:$LINENO: checking whether _WIN64 is declared" >&5
-echo $ECHO_N "checking whether _WIN64 is declared... $ECHO_C" >&6
-if test "${ac_cv_have_decl__WIN64+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-#ifndef _WIN64
- char *p = (char *) _WIN64;
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_have_decl__WIN64=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_have_decl__WIN64=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_have_decl__WIN64" >&5
-echo "${ECHO_T}$ac_cv_have_decl__WIN64" >&6
-if test $ac_cv_have_decl__WIN64 = yes; then
- :
-else
- CC="\"${PATH64}/cl.exe\" -I\"${MSSDK}/Include\" \
- -I\"${MSSDK}/Include/crt\" \
- -I\"${MSSDK}/Include/crt/sys\""
-fi
-
+ CC="\"${PATH64}/cl.exe\" -I\"${MSSDK}/Include\" \
+ -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
RC="\"${MSSDK}/bin/rc.exe\""
CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d"
# Do not use -O2 for Win64 - this has proved buggy in code gen.
@@ -4382,15 +1816,11 @@ fi
SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
if test ! -d "${CELIB_DIR}/inc"; then
- { { echo "$as_me:$LINENO: error: Invalid celib directory \"${CELIB_DIR}\"" >&5
-echo "$as_me: error: Invalid celib directory \"${CELIB_DIR}\"" >&2;}
- { (exit 1); exit 1; }; }
+ { echo "configure: error: Invalid celib directory "${CELIB_DIR}"" 1>&2; exit 1; }
fi
if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"\
-o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
- { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5
-echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;}
- { (exit 1); exit 1; }; }
+ { echo "configure: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" 1>&2; exit 1; }
else
CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
@@ -4412,28 +1842,28 @@ echo "$as_me: error: could not find PocketPC SDK or target compiler to enable Wi
arch=`echo ${ARCH} | awk '{print tolower($0)}'`
defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _DLL _WINDOWS"
for i in $defs ; do
- cat >>confdefs.h <<_ACEOF
+ cat >> confdefs.h <<EOF
#define $i 1
-_ACEOF
+EOF
done
# if test "${ARCH}" = "X86EM"; then
# AC_DEFINE_UNQUOTED(_WIN32_WCE_EMULATION)
# fi
- cat >>confdefs.h <<_ACEOF
+ cat >> confdefs.h <<EOF
#define _WIN32_WCE $CEVERSION
-_ACEOF
+EOF
- cat >>confdefs.h <<_ACEOF
+ cat >> confdefs.h <<EOF
#define UNDER_CE $CEVERSION
-_ACEOF
+EOF
CFLAGS_DEBUG="-nologo -Zi -Od"
CFLAGS_OPTIMIZE="-nologo -O2"
lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
lflags="-nodefaultlib -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
LINKBIN="\"${CEBINROOT}/link.exe\""
-
+
if test "${CEVERSION}" -lt 400 ; then
LIBS="coredll.lib corelibc.lib winsock.lib"
else
@@ -4444,7 +1874,7 @@ _ACEOF
LIBS="$LIBS \"\${CELIB_DIR}/wince-${ARCH}-pocket-wce300-release/celib.lib\""
LIBS_GUI="commctrl.lib commdlg.lib"
else
- LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"
+ LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib"
fi
SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
@@ -4483,291 +1913,13 @@ _ACEOF
fi
fi
- if test "$do64bit" != "no" ; then
- cat >>confdefs.h <<\_ACEOF
-#define TCL_CFG_DO64BIT 1
-_ACEOF
-
- fi
-
# DL_LIBS is empty, but then we match the Unix version
+
+
+
+
-
-
-
-
-echo "$as_me:$LINENO: checking for intptr_t" >&5
-echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6
-if test "${ac_cv_type_intptr_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-if ((intptr_t *) 0)
- return 0;
-if (sizeof (intptr_t))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_intptr_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_intptr_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5
-echo "${ECHO_T}$ac_cv_type_intptr_t" >&6
-if test $ac_cv_type_intptr_t = yes; then
-
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_INTPTR_T 1
-_ACEOF
-
-else
-
- echo "$as_me:$LINENO: checking for pointer-size signed integer type" >&5
-echo $ECHO_N "checking for pointer-size signed integer type... $ECHO_C" >&6
-if test "${tcl_cv_intptr_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- for tcl_cv_intptr_t in "int" "long" "long long" none; do
- if test "$tcl_cv_intptr_t" != none; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_ok=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_ok=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- test "$tcl_ok" = yes && break; fi
- done
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_intptr_t" >&5
-echo "${ECHO_T}$tcl_cv_intptr_t" >&6
- if test "$tcl_cv_intptr_t" != none; then
-
-cat >>confdefs.h <<_ACEOF
-#define intptr_t $tcl_cv_intptr_t
-_ACEOF
-
- fi
-
-fi
-
-echo "$as_me:$LINENO: checking for uintptr_t" >&5
-echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6
-if test "${ac_cv_type_uintptr_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-if ((uintptr_t *) 0)
- return 0;
-if (sizeof (uintptr_t))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_uintptr_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_uintptr_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5
-echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6
-if test $ac_cv_type_uintptr_t = yes; then
-
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_UINTPTR_T 1
-_ACEOF
-
-else
-
- echo "$as_me:$LINENO: checking for pointer-size unsigned integer type" >&5
-echo $ECHO_N "checking for pointer-size unsigned integer type... $ECHO_C" >&6
-if test "${tcl_cv_uintptr_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \
- none; do
- if test "$tcl_cv_uintptr_t" != none; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_ok=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_ok=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- test "$tcl_ok" = yes && break; fi
- done
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_uintptr_t" >&5
-echo "${ECHO_T}$tcl_cv_uintptr_t" >&6
- if test "$tcl_cv_uintptr_t" != none; then
-
-cat >>confdefs.h <<_ACEOF
-#define uintptr_t $tcl_cv_uintptr_t
-_ACEOF
-
- fi
-
-fi
-
#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option. This macro depends on C flags, and should be called
@@ -4775,68 +1927,56 @@ fi
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for build with symbols" >&5
-echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6
+ echo $ac_n "checking for build with symbols""... $ac_c" 1>&6
+echo "configure:1932: checking for build with symbols" >&5
# Check whether --enable-symbols or --disable-symbols was given.
if test "${enable_symbols+set}" = set; then
enableval="$enable_symbols"
tcl_ok=$enableval
else
tcl_ok=no
-fi;
+fi
+
# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
if test "$tcl_ok" = "no"; then
CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
DBGX=""
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-
- cat >>confdefs.h <<\_ACEOF
-#define TCL_CFG_OPTIMIZED 1
-_ACEOF
-
+ echo "$ac_t""no" 1>&6
else
CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
DBGX=g
if test "$tcl_ok" = "yes"; then
- echo "$as_me:$LINENO: result: yes (standard debugging)" >&5
-echo "${ECHO_T}yes (standard debugging)" >&6
+ echo "$ac_t""yes (standard debugging)" 1>&6
fi
fi
-
-
- cat >>confdefs.h <<\_ACEOF
-#define TCL_CFG_DEBUG 1
-_ACEOF
-
+
+
if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
- cat >>confdefs.h <<\_ACEOF
+ cat >> confdefs.h <<\EOF
#define TCL_MEM_DEBUG 1
-_ACEOF
+EOF
fi
if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then
- cat >>confdefs.h <<\_ACEOF
+ cat >> confdefs.h <<\EOF
#define TCL_COMPILE_DEBUG 1
-_ACEOF
+EOF
- cat >>confdefs.h <<\_ACEOF
+ cat >> confdefs.h <<\EOF
#define TCL_COMPILE_STATS 1
-_ACEOF
+EOF
fi
if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
if test "$tcl_ok" = "all"; then
- echo "$as_me:$LINENO: result: enabled symbols mem compile debugging" >&5
-echo "${ECHO_T}enabled symbols mem compile debugging" >&6
+ echo "$ac_t""enabled symbols mem compile debugging" 1>&6
else
- echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
-echo "${ECHO_T}enabled $tcl_ok debugging" >&6
+ echo "$ac_t""enabled $tcl_ok debugging" 1>&6
fi
fi
@@ -4844,61 +1984,122 @@ echo "${ECHO_T}enabled $tcl_ok debugging" >&6
TCL_DBGX=${DBGX}
#--------------------------------------------------------------------
-# Embed the manifest if we can determine how
+# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------
-
- echo "$as_me:$LINENO: checking whether to embed manifest" >&5
-echo $ECHO_N "checking whether to embed manifest... $ECHO_C" >&6
- # Check whether --enable-embedded-manifest or --disable-embedded-manifest was given.
-if test "${enable_embedded_manifest+set}" = set; then
- enableval="$enable_embedded_manifest"
- embed_ok=$enableval
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1992: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
- embed_ok=yes
-fi;
-
- VC_MANIFEST_EMBED_DLL=
- VC_MANIFEST_EMBED_EXE=
- result=no
- if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \
- -a "$GCC" != "yes" ; then
- # Add the magic to embed the manifest into the dll/exe
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-print("manifest needed")
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "manifest needed" >/dev/null 2>&1; then
-
- # Could do a CHECK_PROG for mt, but should always be with MSVC8+
- # Could add 'if test -f' check, but manifest should be created
- # in this compiler case
- # Add in a manifest argument that may be specified
- # XXX Needs improvement so that the test for existence accounts
- # XXX for a provided (known) manifest
- VC_MANIFEST_EMBED_DLL="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;2 ; fi"
- VC_MANIFEST_EMBED_EXE="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;1 ; fi"
- result=yes
- if test "x" != x ; then
- result="yes ()"
- fi
-
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 2007 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2013: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 2024 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2030: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 2041 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2047: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
fi
rm -f conftest*
-
- fi
- echo "$as_me:$LINENO: result: $result" >&5
-echo "${ECHO_T}$result" >&6
-
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+ac_safe=`echo "errno.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for errno.h""... $ac_c" 1>&6
+echo "configure:2073: checking for errno.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2078 "configure"
+#include "confdefs.h"
+#include <errno.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+MAN2TCLFLAGS="-DNO_ERRNO_H"
+fi
@@ -5049,9 +2250,8 @@ fi
-# win only
-
+# win only
@@ -5067,999 +2267,338 @@ fi
- ac_config_files="$ac_config_files Makefile tclConfig.sh tcl.hpj"
-cat >confcache <<\_ACEOF
+trap '' 1 2 15
+cat > confcache <<\EOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
+EOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
-{
- (set) 2>&1 |
- case `(ac_space=' '; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n \
- "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
- ;;
- esac;
-} |
- sed '
- t clear
- : clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- : end' >>confcache
-if diff $cache_file confcache >/dev/null 2>&1; then :; else
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
if test -w $cache_file; then
- test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
- cat confcache >$cache_file
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
else
echo "not updating unwritable cache $cache_file"
fi
fi
rm -f confcache
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/;
-s/:*\${srcdir}:*/:/;
-s/:*@srcdir@:*/:/;
-s/^\([^=]*=[ ]*\):*/\1/;
-s/:*$//;
-s/^[^=]*=[ ]*$//;
-}'
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
fi
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
-#
-# If the first sed substitution is executed (which looks for macros that
-# take arguments), then we branch to the quote section. Otherwise,
-# look for a macro that doesn't take arguments.
-cat >confdef2opt.sed <<\_ACEOF
-t clear
-: clear
-s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
-t quote
-s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
-t quote
-d
-: quote
-s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
-s,\[,\\&,g
-s,\],\\&,g
-s,\$,$$,g
-p
-_ACEOF
-# We use echo to avoid assuming a particular line-breaking character.
-# The extra dot is to prevent the shell from consuming trailing
-# line-breaks from the sub-command output. A line-break within
-# single-quotes doesn't work because, if this script is created in a
-# platform that uses two characters for line-breaks (e.g., DOS), tr
-# would break.
-ac_LF_and_DOT=`echo; echo .`
-DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
-rm -f confdef2opt.sed
-
-
-ac_libobjs=
-ac_ltlibobjs=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
- # 1. Remove the extension, and $U if already installed.
- ac_i=`echo "$ac_i" |
- sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
- # 2. Add them.
- ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
- ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
: ${CONFIG_STATUS=./config.status}
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
-#! $SHELL
-# Generated by $as_me.
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
- set -o posix
-fi
-DUALCASE=1; export DUALCASE # for MKS sh
+# configure, is in ./config.log if it exists.
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
-fi
-
-
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- $as_unset $as_var
- fi
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
done
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
+ac_given_srcdir=$srcdir
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
+trap 'rm -fr `echo "Makefile tclConfig.sh tcl.hpj" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
+s%@RC@%$RC%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@OBJEXT@%$OBJEXT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@TCL_THREADS@%$TCL_THREADS%g
+s%@CYGPATH@%$CYGPATH%g
+s%@CELIB_DIR@%$CELIB_DIR%g
+s%@DL_LIBS@%$DL_LIBS%g
+s%@CFLAGS_DEBUG@%$CFLAGS_DEBUG%g
+s%@CFLAGS_OPTIMIZE@%$CFLAGS_OPTIMIZE%g
+s%@CFLAGS_WARNING@%$CFLAGS_WARNING%g
+s%@CFLAGS_DEFAULT@%$CFLAGS_DEFAULT%g
+s%@LDFLAGS_DEFAULT@%$LDFLAGS_DEFAULT%g
+s%@CPP@%$CPP%g
+s%@MAN2TCLFLAGS@%$MAN2TCLFLAGS%g
+s%@TCL_VERSION@%$TCL_VERSION%g
+s%@TCL_MAJOR_VERSION@%$TCL_MAJOR_VERSION%g
+s%@TCL_MINOR_VERSION@%$TCL_MINOR_VERSION%g
+s%@TCL_PATCH_LEVEL@%$TCL_PATCH_LEVEL%g
+s%@TCL_LIB_FILE@%$TCL_LIB_FILE%g
+s%@TCL_LIB_FLAG@%$TCL_LIB_FLAG%g
+s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g
+s%@TCL_STUB_LIB_FILE@%$TCL_STUB_LIB_FILE%g
+s%@TCL_STUB_LIB_FLAG@%$TCL_STUB_LIB_FLAG%g
+s%@TCL_STUB_LIB_SPEC@%$TCL_STUB_LIB_SPEC%g
+s%@TCL_STUB_LIB_PATH@%$TCL_STUB_LIB_PATH%g
+s%@TCL_INCLUDE_SPEC@%$TCL_INCLUDE_SPEC%g
+s%@TCL_BUILD_STUB_LIB_SPEC@%$TCL_BUILD_STUB_LIB_SPEC%g
+s%@TCL_BUILD_STUB_LIB_PATH@%$TCL_BUILD_STUB_LIB_PATH%g
+s%@TCL_DLL_FILE@%$TCL_DLL_FILE%g
+s%@TCL_SRC_DIR@%$TCL_SRC_DIR%g
+s%@TCL_BIN_DIR@%$TCL_BIN_DIR%g
+s%@TCL_DBGX@%$TCL_DBGX%g
+s%@CFG_TCL_SHARED_LIB_SUFFIX@%$CFG_TCL_SHARED_LIB_SUFFIX%g
+s%@CFG_TCL_UNSHARED_LIB_SUFFIX@%$CFG_TCL_UNSHARED_LIB_SUFFIX%g
+s%@CFG_TCL_EXPORT_FILE_SUFFIX@%$CFG_TCL_EXPORT_FILE_SUFFIX%g
+s%@EXTRA_CFLAGS@%$EXTRA_CFLAGS%g
+s%@DEPARG@%$DEPARG%g
+s%@CC_OBJNAME@%$CC_OBJNAME%g
+s%@CC_EXENAME@%$CC_EXENAME%g
+s%@LDFLAGS_DEBUG@%$LDFLAGS_DEBUG%g
+s%@LDFLAGS_OPTIMIZE@%$LDFLAGS_OPTIMIZE%g
+s%@LDFLAGS_CONSOLE@%$LDFLAGS_CONSOLE%g
+s%@LDFLAGS_WINDOW@%$LDFLAGS_WINDOW%g
+s%@STLIB_LD@%$STLIB_LD%g
+s%@SHLIB_LD@%$SHLIB_LD%g
+s%@SHLIB_LD_LIBS@%$SHLIB_LD_LIBS%g
+s%@SHLIB_CFLAGS@%$SHLIB_CFLAGS%g
+s%@SHLIB_SUFFIX@%$SHLIB_SUFFIX%g
+s%@TCL_SHARED_BUILD@%$TCL_SHARED_BUILD%g
+s%@LIBS_GUI@%$LIBS_GUI%g
+s%@DLLSUFFIX@%$DLLSUFFIX%g
+s%@LIBPREFIX@%$LIBPREFIX%g
+s%@LIBSUFFIX@%$LIBSUFFIX%g
+s%@EXESUFFIX@%$EXESUFFIX%g
+s%@LIBRARIES@%$LIBRARIES%g
+s%@MAKE_LIB@%$MAKE_LIB%g
+s%@POST_MAKE_LIB@%$POST_MAKE_LIB%g
+s%@MAKE_DLL@%$MAKE_DLL%g
+s%@MAKE_EXE@%$MAKE_EXE%g
+s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g
+s%@TCL_LD_SEARCH_FLAGS@%$TCL_LD_SEARCH_FLAGS%g
+s%@TCL_NEEDS_EXP_FILE@%$TCL_NEEDS_EXP_FILE%g
+s%@TCL_BUILD_EXP_FILE@%$TCL_BUILD_EXP_FILE%g
+s%@TCL_EXP_FILE@%$TCL_EXP_FILE%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@TCL_LIB_VERSIONS_OK@%$TCL_LIB_VERSIONS_OK%g
+s%@TCL_PACKAGE_PATH@%$TCL_PACKAGE_PATH%g
+s%@TCL_DDE_VERSION@%$TCL_DDE_VERSION%g
+s%@TCL_DDE_MAJOR_VERSION@%$TCL_DDE_MAJOR_VERSION%g
+s%@TCL_DDE_MINOR_VERSION@%$TCL_DDE_MINOR_VERSION%g
+s%@TCL_REG_VERSION@%$TCL_REG_VERSION%g
+s%@TCL_REG_MAJOR_VERSION@%$TCL_REG_MAJOR_VERSION%g
+s%@TCL_REG_MINOR_VERSION@%$TCL_REG_MINOR_VERSION%g
+s%@RC_OUT@%$RC_OUT%g
+s%@RC_TYPE@%$RC_TYPE%g
+s%@RC_INCLUDE@%$RC_INCLUDE%g
+s%@RC_DEFINE@%$RC_DEFINE%g
+s%@RC_DEFINES@%$RC_DEFINES%g
+s%@RES@%$RES%g
-# Name of the executable.
-as_me=`$as_basename "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)$' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
- /^X\/\(\/\/\)$/{ s//\1/; q; }
- /^X\/\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
-
-
-# PATH needs CR, and LINENO needs CR and PATH.
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
else
- PATH_SEPARATOR=:
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
fi
- rm -f conf$$.sh
-fi
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" || {
- # Find who we are. Look in the path if we contain no path at all
- # relative or not.
- case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
- ;;
- esac
- # We did not find ourselves, most probably we were run as `sh COMMAND'
- # in which case we are not to be found in the path.
- if test "x$as_myself" = x; then
- as_myself=$0
- fi
- if test ! -f "$as_myself"; then
- { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
-echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
- { (exit 1); exit 1; }; }
- fi
- case $CONFIG_SHELL in
- '')
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for as_base in sh bash ksh sh5; do
- case $as_dir in
- /*)
- if ("$as_dir/$as_base" -c '
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
- $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
- $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
- CONFIG_SHELL=$as_dir/$as_base
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$0" ${1+"$@"}
- fi;;
- esac
- done
-done
-;;
- esac
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line before each line; the second 'sed' does the real
- # work. The second script uses 'N' to pair each line-number line
- # with the numbered line, and appends trailing '-' during
- # substitution so that $LINENO is not a special case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
- sed '=' <$as_myself |
- sed '
- N
- s,$,-,
- : loop
- s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
- t loop
- s,-$,,
- s,^['$as_cr_digits']*\n,,
- ' >$as_me.lineno &&
- chmod +x $as_me.lineno ||
- { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
-echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensible to this).
- . ./$as_me.lineno
- # Exit status is that of the last command.
- exit
-}
-
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
- *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T=' ' ;;
- *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
- *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- # We could just check for DJGPP; but this test a) works b) is more generic
- # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
- if test -f conf$$.exe; then
- # Don't use ln at all; we don't have any links
- as_ln_s='cp -p'
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
else
- as_ln_s='ln -s'
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.file
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-as_executable_p="test -f"
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" $as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
-exec 6>&1
-
-# Open the log real soon, to keep \$[0] and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling. Logging --version etc. is OK.
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-} >&5
-cat >&5 <<_CSEOF
-
-This file was extended by $as_me, which was
-generated by GNU Autoconf 2.59. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-_CSEOF
-echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
-echo >&5
-_ACEOF
-
-# Files that config.status was made for.
-if test -n "$ac_config_files"; then
- echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_headers"; then
- echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_links"; then
- echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_commands"; then
- echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-
-ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
-
-Usage: $0 [OPTIONS] [FILE]...
-
- -h, --help print this help, then exit
- -V, --version print version number, then exit
- -q, --quiet do not print progress messages
- -d, --debug don't remove temporary files
- --recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
-
-Configuration files:
-$config_files
-
-Report bugs to <bug-autoconf@gnu.org>."
-_ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
-ac_cs_version="\\
-config.status
-configured by $0, generated by GNU Autoconf 2.59,
- with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
-
-Copyright (C) 2003 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-srcdir=$srcdir
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value. By we need to know if files were specified by the user.
-ac_need_defaults=:
-while test $# != 0
-do
- case $1 in
- --*=*)
- ac_option=`expr "x$1" : 'x\([^=]*\)='`
- ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
- ac_shift=:
- ;;
- -*)
- ac_option=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- *) # This is not an option, so the user has probably given explicit
- # arguments.
- ac_option=$1
- ac_need_defaults=false;;
- esac
-
- case $ac_option in
- # Handling of the options.
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --vers* | -V )
- echo "$ac_cs_version"; exit 0 ;;
- --he | --h)
- # Conflict between --help and --header
- { { echo "$as_me:$LINENO: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2;}
- { (exit 1); exit 1; }; };;
- --help | --hel | -h )
- echo "$ac_cs_usage"; exit 0 ;;
- --debug | --d* | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- CONFIG_FILES="$CONFIG_FILES $ac_optarg"
- ac_need_defaults=false;;
- --header | --heade | --head | --hea )
- $ac_shift
- CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
- ac_need_defaults=false;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2;}
- { (exit 1); exit 1; }; } ;;
-
- *) ac_config_targets="$ac_config_targets $1" ;;
-
- esac
- shift
done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
fi
+EOF
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-if \$ac_cs_recheck; then
- echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
- exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
-fi
+cat >> $CONFIG_STATUS <<EOF
-_ACEOF
-
-
-
-
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-for ac_config_target in $ac_config_targets
-do
- case "$ac_config_target" in
- # Handling of arguments.
- "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
- "tclConfig.sh" ) CONFIG_FILES="$CONFIG_FILES tclConfig.sh" ;;
- "tcl.hpj" ) CONFIG_FILES="$CONFIG_FILES tcl.hpj" ;;
- *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
- { (exit 1); exit 1; }; };;
+CONFIG_FILES=\${CONFIG_FILES-"Makefile tclConfig.sh tcl.hpj"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
esac
-done
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason to put it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Create a temporary directory, and hook for its removal unless debugging.
-$debug ||
-{
- trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
- trap '{ (exit 1); exit 1; }' 1 2 13 15
-}
-
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
-} ||
-{
- tmp=./confstat$$-$RANDOM
- (umask 077 && mkdir $tmp)
-} ||
-{
- echo "$me: cannot create a temporary directory in ." >&2
- { (exit 1); exit 1; }
-}
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
-#
-# CONFIG_FILES section.
-#
-
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
-if test -n "\$CONFIG_FILES"; then
- # Protect against being on the right side of a sed subst in config.status.
- sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
- s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
-s,@SHELL@,$SHELL,;t t
-s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
-s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
-s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
-s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
-s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
-s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
-s,@exec_prefix@,$exec_prefix,;t t
-s,@prefix@,$prefix,;t t
-s,@program_transform_name@,$program_transform_name,;t t
-s,@bindir@,$bindir,;t t
-s,@sbindir@,$sbindir,;t t
-s,@libexecdir@,$libexecdir,;t t
-s,@datadir@,$datadir,;t t
-s,@sysconfdir@,$sysconfdir,;t t
-s,@sharedstatedir@,$sharedstatedir,;t t
-s,@localstatedir@,$localstatedir,;t t
-s,@libdir@,$libdir,;t t
-s,@includedir@,$includedir,;t t
-s,@oldincludedir@,$oldincludedir,;t t
-s,@infodir@,$infodir,;t t
-s,@mandir@,$mandir,;t t
-s,@build_alias@,$build_alias,;t t
-s,@host_alias@,$host_alias,;t t
-s,@target_alias@,$target_alias,;t t
-s,@DEFS@,$DEFS,;t t
-s,@ECHO_C@,$ECHO_C,;t t
-s,@ECHO_N@,$ECHO_N,;t t
-s,@ECHO_T@,$ECHO_T,;t t
-s,@LIBS@,$LIBS,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
-s,@CPP@,$CPP,;t t
-s,@EGREP@,$EGREP,;t t
-s,@AR@,$AR,;t t
-s,@ac_ct_AR@,$ac_ct_AR,;t t
-s,@RANLIB@,$RANLIB,;t t
-s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
-s,@RC@,$RC,;t t
-s,@ac_ct_RC@,$ac_ct_RC,;t t
-s,@SET_MAKE@,$SET_MAKE,;t t
-s,@TCL_THREADS@,$TCL_THREADS,;t t
-s,@CYGPATH@,$CYGPATH,;t t
-s,@CELIB_DIR@,$CELIB_DIR,;t t
-s,@DL_LIBS@,$DL_LIBS,;t t
-s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t
-s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t
-s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t
-s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t
-s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t
-s,@VC_MANIFEST_EMBED_DLL@,$VC_MANIFEST_EMBED_DLL,;t t
-s,@VC_MANIFEST_EMBED_EXE@,$VC_MANIFEST_EMBED_EXE,;t t
-s,@TCL_VERSION@,$TCL_VERSION,;t t
-s,@TCL_MAJOR_VERSION@,$TCL_MAJOR_VERSION,;t t
-s,@TCL_MINOR_VERSION@,$TCL_MINOR_VERSION,;t t
-s,@TCL_PATCH_LEVEL@,$TCL_PATCH_LEVEL,;t t
-s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t
-s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t
-s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t
-s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t
-s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t
-s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t
-s,@TCL_STUB_LIB_PATH@,$TCL_STUB_LIB_PATH,;t t
-s,@TCL_INCLUDE_SPEC@,$TCL_INCLUDE_SPEC,;t t
-s,@TCL_BUILD_STUB_LIB_SPEC@,$TCL_BUILD_STUB_LIB_SPEC,;t t
-s,@TCL_BUILD_STUB_LIB_PATH@,$TCL_BUILD_STUB_LIB_PATH,;t t
-s,@TCL_DLL_FILE@,$TCL_DLL_FILE,;t t
-s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t
-s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t
-s,@TCL_DBGX@,$TCL_DBGX,;t t
-s,@CFG_TCL_SHARED_LIB_SUFFIX@,$CFG_TCL_SHARED_LIB_SUFFIX,;t t
-s,@CFG_TCL_UNSHARED_LIB_SUFFIX@,$CFG_TCL_UNSHARED_LIB_SUFFIX,;t t
-s,@CFG_TCL_EXPORT_FILE_SUFFIX@,$CFG_TCL_EXPORT_FILE_SUFFIX,;t t
-s,@EXTRA_CFLAGS@,$EXTRA_CFLAGS,;t t
-s,@DEPARG@,$DEPARG,;t t
-s,@CC_OBJNAME@,$CC_OBJNAME,;t t
-s,@CC_EXENAME@,$CC_EXENAME,;t t
-s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t
-s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t
-s,@LDFLAGS_CONSOLE@,$LDFLAGS_CONSOLE,;t t
-s,@LDFLAGS_WINDOW@,$LDFLAGS_WINDOW,;t t
-s,@STLIB_LD@,$STLIB_LD,;t t
-s,@SHLIB_LD@,$SHLIB_LD,;t t
-s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t
-s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t
-s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t
-s,@TCL_SHARED_BUILD@,$TCL_SHARED_BUILD,;t t
-s,@LIBS_GUI@,$LIBS_GUI,;t t
-s,@DLLSUFFIX@,$DLLSUFFIX,;t t
-s,@LIBPREFIX@,$LIBPREFIX,;t t
-s,@LIBSUFFIX@,$LIBSUFFIX,;t t
-s,@EXESUFFIX@,$EXESUFFIX,;t t
-s,@LIBRARIES@,$LIBRARIES,;t t
-s,@MAKE_LIB@,$MAKE_LIB,;t t
-s,@POST_MAKE_LIB@,$POST_MAKE_LIB,;t t
-s,@MAKE_DLL@,$MAKE_DLL,;t t
-s,@MAKE_EXE@,$MAKE_EXE,;t t
-s,@TCL_BUILD_LIB_SPEC@,$TCL_BUILD_LIB_SPEC,;t t
-s,@TCL_LD_SEARCH_FLAGS@,$TCL_LD_SEARCH_FLAGS,;t t
-s,@TCL_NEEDS_EXP_FILE@,$TCL_NEEDS_EXP_FILE,;t t
-s,@TCL_BUILD_EXP_FILE@,$TCL_BUILD_EXP_FILE,;t t
-s,@TCL_EXP_FILE@,$TCL_EXP_FILE,;t t
-s,@TCL_LIB_VERSIONS_OK@,$TCL_LIB_VERSIONS_OK,;t t
-s,@TCL_PACKAGE_PATH@,$TCL_PACKAGE_PATH,;t t
-s,@TCL_DDE_VERSION@,$TCL_DDE_VERSION,;t t
-s,@TCL_DDE_MAJOR_VERSION@,$TCL_DDE_MAJOR_VERSION,;t t
-s,@TCL_DDE_MINOR_VERSION@,$TCL_DDE_MINOR_VERSION,;t t
-s,@TCL_DDE_PATCH_LEVEL@,$TCL_DDE_PATCH_LEVEL,;t t
-s,@TCL_REG_VERSION@,$TCL_REG_VERSION,;t t
-s,@TCL_REG_MAJOR_VERSION@,$TCL_REG_MAJOR_VERSION,;t t
-s,@TCL_REG_MINOR_VERSION@,$TCL_REG_MINOR_VERSION,;t t
-s,@TCL_REG_PATCH_LEVEL@,$TCL_REG_PATCH_LEVEL,;t t
-s,@RC_OUT@,$RC_OUT,;t t
-s,@RC_TYPE@,$RC_TYPE,;t t
-s,@RC_INCLUDE@,$RC_INCLUDE,;t t
-s,@RC_DEFINE@,$RC_DEFINE,;t t
-s,@RC_DEFINES@,$RC_DEFINES,;t t
-s,@RES@,$RES,;t t
-s,@LIBOBJS@,$LIBOBJS,;t t
-s,@LTLIBOBJS@,$LTLIBOBJS,;t t
-CEOF
-
-_ACEOF
-
- cat >>$CONFIG_STATUS <<\_ACEOF
- # Split the substitutions into bite-sized pieces for seds with
- # small command number limits, like on Digital OSF/1 and HP-UX.
- ac_max_sed_lines=48
- ac_sed_frag=1 # Number of current file.
- ac_beg=1 # First line for current file.
- ac_end=$ac_max_sed_lines # Line after last line for current file.
- ac_more_lines=:
- ac_sed_cmds=
- while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
- else
- sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
- fi
- if test ! -s $tmp/subs.frag; then
- ac_more_lines=false
- else
- # The purpose of the label and of the branching condition is to
- # speed up the sed processing (if there are no `@' at all, there
- # is no need to browse any of the substitutions).
- # These are the two extra sed commands mentioned above.
- (echo ':t
- /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
- fi
- ac_sed_frag=`expr $ac_sed_frag + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_lines`
- fi
- done
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
fi
-fi # test -n "$CONFIG_FILES"
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case $ac_file in
- - | *:- | *:-:* ) # input from stdin
- cat >$tmp/stdin
- ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
- *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
- * ) ac_file_in=$ac_file.in ;;
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
esac
- # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
- ac_dir=`(dirname "$ac_file") 2>/dev/null ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
- { if $as_mkdir_p; then
- mkdir -p "$ac_dir"
- else
- as_dir="$ac_dir"
- as_dirs=
- while test ! -d "$as_dir"; do
- as_dirs="$as_dir $as_dirs"
- as_dir=`(dirname "$as_dir") 2>/dev/null ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
- done
- test ! -n "$as_dirs" || mkdir $as_dirs
- fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
- { (exit 1); exit 1; }; }; }
- ac_builddir=.
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
-if test "$ac_dir" != .; then
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A "../" for each directory in $ac_dir_suffix.
- ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
- ac_dir_suffix= ac_top_builddir=
-fi
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
-case $srcdir in
- .) # No --srcdir option. We are building in place.
- ac_srcdir=.
- if test -z "$ac_top_builddir"; then
- ac_top_srcdir=.
- else
- ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
- fi ;;
- [\\/]* | ?:[\\/]* ) # Absolute path.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir ;;
- *) # Relative path.
- ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
- case "$ac_dir" in
- .) ac_abs_builddir=`pwd`;;
- [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
- *) ac_abs_builddir=`pwd`/"$ac_dir";;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
- case ${ac_top_builddir}. in
- .) ac_abs_top_builddir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
- *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
- case $ac_srcdir in
- .) ac_abs_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
- *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
- case $ac_top_srcdir in
- .) ac_abs_top_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
- *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
- esac;;
-esac
-
-
-
- if test x"$ac_file" != x-; then
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- rm -f "$ac_file"
- fi
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- if test x"$ac_file" = x-; then
- configure_input=
- else
- configure_input="$ac_file. "
- fi
- configure_input=$configure_input"Generated from `echo $ac_file_in |
- sed 's,.*/,,'` by configure."
-
- # First look for the input files in the build tree, otherwise in the
- # src tree.
- ac_file_inputs=`IFS=:
- for f in $ac_file_in; do
- case $f in
- -) echo $tmp/stdin ;;
- [\\/$]*)
- # Absolute (can't be DOS-style, as IFS=:)
- test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
- { (exit 1); exit 1; }; }
- echo "$f";;
- *) # Relative
- if test -f "$f"; then
- # Build tree
- echo "$f"
- elif test -f "$srcdir/$f"; then
- # Source tree
- echo "$srcdir/$f"
- else
- # /dev/null tree
- { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
- { (exit 1); exit 1; }; }
- fi;;
- esac
- done` || { (exit 1); exit 1; }
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
- sed "$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s,@configure_input@,$configure_input,;t t
-s,@srcdir@,$ac_srcdir,;t t
-s,@abs_srcdir@,$ac_abs_srcdir,;t t
-s,@top_srcdir@,$ac_top_srcdir,;t t
-s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
-s,@builddir@,$ac_builddir,;t t
-s,@abs_builddir@,$ac_abs_builddir,;t t
-s,@top_builddir@,$ac_top_builddir,;t t
-s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
-" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
- rm -f $tmp/stdin
- if test x"$ac_file" != x-; then
- mv $tmp/out $ac_file
- else
- cat $tmp/out
- rm -f $tmp/out
- fi
+EOF
+cat >> $CONFIG_STATUS <<EOF
-done
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
+EOF
+cat >> $CONFIG_STATUS <<\EOF
-{ (exit 0); exit 0; }
-_ACEOF
+exit 0
+EOF
chmod +x $CONFIG_STATUS
-ac_clean_files=$ac_clean_files_save
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- exec 5>>config.log
- # Use ||, not &&, to avoid exiting from the if with $? = 1, which
- # would make configure fail if this is the last instruction.
- $ac_cs_success || { (exit 1); exit 1; }
-fi
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
diff --git a/win/configure.in b/win/configure.in
index 1b8c25a..3ac39c3 100644
--- a/win/configure.in
+++ b/win/configure.in
@@ -4,29 +4,22 @@
# to configure the system for the local environment.
AC_INIT(../generic/tcl.h)
-AC_PREREQ(2.59)
+AC_PREREQ(2.13)
-# The following define is needed when building with Cygwin since newer
-# versions of autoconf incorrectly set SHELL to /bin/bash instead of
-# /bin/sh. The bash shell seems to suffer from some strange failures.
-SHELL=/bin/sh
-
-TCL_VERSION=8.5
+TCL_VERSION=8.4
TCL_MAJOR_VERSION=8
-TCL_MINOR_VERSION=5
-TCL_PATCH_LEVEL=".11"
+TCL_MINOR_VERSION=4
+TCL_PATCH_LEVEL=".19"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
-TCL_DDE_VERSION=1.3
+TCL_DDE_VERSION=1.2
TCL_DDE_MAJOR_VERSION=1
-TCL_DDE_MINOR_VERSION=3
-TCL_DDE_PATCH_LEVEL="2"
+TCL_DDE_MINOR_VERSION=2
DDEVER=$TCL_DDE_MAJOR_VERSION$TCL_DDE_MINOR_VERSION
-TCL_REG_VERSION=1.2
+TCL_REG_VERSION=1.1
TCL_REG_MAJOR_VERSION=1
-TCL_REG_MINOR_VERSION=2
-TCL_REG_PATCH_LEVEL="1"
+TCL_REG_MINOR_VERSION=1
REGVER=$TCL_REG_MAJOR_VERSION$TCL_REG_MINOR_VERSION
#------------------------------------------------------------------------
@@ -53,12 +46,32 @@ if test "${CFLAGS+set}" != "set" ; then
fi
AC_PROG_CC
-AC_C_INLINE
-AC_HEADER_STDC
-AC_CHECK_TOOL(AR, ar)
-AC_CHECK_TOOL(RANLIB, ranlib)
-AC_CHECK_TOOL(RC, windres)
+# To properly support cross-compilation, one would
+# need to use these tool checks instead of
+# the ones below and reconfigure with
+# autoconf 2.50. You can also just set
+# the CC, AR, RANLIB, and RC environment
+# variables if you want to cross compile.
+dnl AC_CHECK_TOOL(AR, ar)
+dnl AC_CHECK_TOOL(RANLIB, ranlib)
+dnl AC_CHECK_TOOL(RC, windres)
+
+if test "${GCC}" = "yes" ; then
+ AC_CHECK_PROG(AR, ar, ar)
+ AC_CHECK_PROG(RANLIB, ranlib, ranlib)
+ AC_CHECK_PROG(RC, windres, windres)
+
+ if test "${AR}" = "" ; then
+ AC_MSG_ERROR([Required archive tool 'ar' not found on PATH.])
+ fi
+ if test "${RANLIB}" = "" ; then
+ AC_MSG_ERROR([Required archive index tool 'ranlib' not found on PATH.])
+ fi
+ if test "${RC}" = "" ; then
+ AC_MSG_ERROR([Required resource tool 'windres' not found on PATH.])
+ fi
+fi
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
@@ -70,22 +83,8 @@ AC_PROG_MAKE_SET
# Perform additinal compiler tests.
#--------------------------------------------------------------------
-dnl Currently AC_CYGWIN is disabled since it invokes AC_CANONICAL_HOST
-dnl under autoconf 2.5X.
-dnl
-dnl AC_CYGWIN
+AC_CYGWIN
-AC_CACHE_CHECK(for Cygwin version of gcc,
- ac_cv_cygwin,
-AC_TRY_COMPILE([
-#ifdef __CYGWIN__
-#error cygwin
-#endif
-],
-[],
- ac_cv_cygwin=no,
- ac_cv_cygwin=yes)
-)
if test "$ac_cv_cygwin" = "yes" ; then
AC_MSG_ERROR([Compiling under Cygwin is not currently supported.
A maintainer for the Cygwin port of Tcl/Tk is needed. See the README
@@ -241,50 +240,6 @@ if test "$tcl_cv_cast_to_union" = "yes"; then
[Defined when compiler supports casting to union type.])
fi
-# See if declarations like FINDEX_INFO_LEVELS are
-# missing from winbase.h. This is known to be
-# a problem with VC++ 5.2.
-
-AC_CACHE_CHECK(for FINDEX_INFO_LEVELS in winbase.h,
- tcl_cv_findex_enums,
-AC_TRY_COMPILE([
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-],
-[
- FINDEX_INFO_LEVELS i;
- FINDEX_SEARCH_OPS j;
-],
- tcl_cv_findex_enums=yes,
- tcl_cv_findex_enums=no)
-)
-if test "$tcl_cv_findex_enums" = "no"; then
- AC_DEFINE(HAVE_NO_FINDEX_ENUMS, 1,
- [Defined when enums are missing from winbase.h])
-fi
-
-# See if MWMO_ALERTABLE is missing from winuser.h
-# This is known to be a problem with Mingw.
-
-AC_CACHE_CHECK(for MWMO_ALERTABLE in winuser.h,
- tcl_cv_mwmo_alertable,
-AC_TRY_COMPILE([
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-],
-[
- int i = MWMO_ALERTABLE;
-],
- tcl_cv_mwmo_alertable=yes,
- tcl_cv_mwmo_alertable=no)
-)
-if test "$tcl_cv_mwmo_alertable" = "no"; then
- AC_DEFINE(HAVE_NO_MWMO_ALERTABLE, 1,
- [Defined when MWMO_ALERTABLE is missing from winuser.h])
-fi
-
#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
#--------------------------------------------------------------------
@@ -298,12 +253,6 @@ AC_EXEEXT
SC_ENABLE_THREADS
-#------------------------------------------------------------------------
-# Embedded configuration information, encoding to use for the values, TIP #59
-#------------------------------------------------------------------------
-
-SC_TCL_CFG_ENCODING
-
#--------------------------------------------------------------------
# The statements below define a collection of symbols related to
# building libtcl as a shared library instead of a static library.
@@ -319,37 +268,6 @@ SC_ENABLE_SHARED
SC_CONFIG_CFLAGS
-AC_CHECK_TYPE([intptr_t], [
- AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
- AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
- for tcl_cv_intptr_t in "int" "long" "long long" none; do
- if test "$tcl_cv_intptr_t" != none; then
- AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
- [[sizeof (void *) <= sizeof ($tcl_cv_intptr_t)]])],
- [tcl_ok=yes], [tcl_ok=no])
- test "$tcl_ok" = yes && break; fi
- done])
- if test "$tcl_cv_intptr_t" != none; then
- AC_DEFINE_UNQUOTED([intptr_t], [$tcl_cv_intptr_t], [Signed integer
- type wide enough to hold a pointer.])
- fi
-])
-AC_CHECK_TYPE([uintptr_t], [
- AC_DEFINE([HAVE_UINTPTR_T], 1, [Do we have the uintptr_t type?])], [
- AC_CACHE_CHECK([for pointer-size unsigned integer type], tcl_cv_uintptr_t, [
- for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \
- none; do
- if test "$tcl_cv_uintptr_t" != none; then
- AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([AC_INCLUDES_DEFAULT],
- [[sizeof (void *) <= sizeof ($tcl_cv_uintptr_t)]])],
- [tcl_ok=yes], [tcl_ok=no])
- test "$tcl_ok" = yes && break; fi
- done])
- if test "$tcl_cv_uintptr_t" != none; then
- AC_DEFINE_UNQUOTED([uintptr_t], [$tcl_cv_uintptr_t], [Unsigned integer
- type wide enough to hold a pointer.])
- fi
-])
#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option. This macro depends on C flags, and should be called
@@ -361,10 +279,11 @@ SC_ENABLE_SYMBOLS
TCL_DBGX=${DBGX}
#--------------------------------------------------------------------
-# Embed the manifest if we can determine how
+# man2tcl needs this so that it can use errno.h
#--------------------------------------------------------------------
-SC_EMBED_MANIFEST
+AC_CHECK_HEADER(errno.h, , MAN2TCLFLAGS="-DNO_ERRNO_H")
+AC_SUBST(MAN2TCLFLAGS)
#------------------------------------------------------------------------
# tclConfig.sh refers to this by a different name
@@ -510,6 +429,7 @@ AC_SUBST(TCL_NEEDS_EXP_FILE)
AC_SUBST(TCL_BUILD_EXP_FILE)
AC_SUBST(TCL_EXP_FILE)
AC_SUBST(DL_LIBS)
+AC_SUBST(LIBOBJS)
AC_SUBST(TCL_LIB_VERSIONS_OK)
AC_SUBST(TCL_PACKAGE_PATH)
@@ -517,11 +437,9 @@ AC_SUBST(TCL_PACKAGE_PATH)
AC_SUBST(TCL_DDE_VERSION)
AC_SUBST(TCL_DDE_MAJOR_VERSION)
AC_SUBST(TCL_DDE_MINOR_VERSION)
-AC_SUBST(TCL_DDE_PATCH_LEVEL)
AC_SUBST(TCL_REG_VERSION)
AC_SUBST(TCL_REG_MAJOR_VERSION)
AC_SUBST(TCL_REG_MINOR_VERSION)
-AC_SUBST(TCL_REG_PATCH_LEVEL)
AC_SUBST(RC)
AC_SUBST(RC_OUT)
diff --git a/win/makefile.bc b/win/makefile.bc
index 6ba4420..3c0ea73 100644
--- a/win/makefile.bc
+++ b/win/makefile.bc
@@ -7,17 +7,7 @@
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
-
-# TIP #59 information.
-#
-# This makefile does not set the following configuration cpp
-# defines. Behind the defines are the makefile variables listed to set
-# to -D... when that feature is enabled.
#
-# - TCL_CFG_PROFILED PROFDEFINES
-# - TCL_CFG_OPTIMIZED OPTDEFINES
-# - TCL_CFG_DO64BIT SIXFOURDEFINES
-
# Have a look at the complete description on how to build and test Tcl with
# the current Borland compilers at www.ratiosoft.com/tcl/borland.
#
@@ -98,13 +88,6 @@ libpath32 = -L"$(TOOLS32)\lib"
NODEBUG = 1
!endif
-# CFG_ENCODING=encoding
-# name of encoding for configuration information. Defaults
-# to cp1252
-!if !defined(CFG_ENCODING)
-CFG_ENCODING = \"cp1252\"
-!endif
-
# The following defines can be used to control the amount of debugging
# code that is added to the compilation.
#
@@ -124,25 +107,23 @@ CFG_ENCODING = \"cp1252\"
NAMEPREFIX = tcl
STUBPREFIX = $(NAMEPREFIX)stub
-DOTVERSION = 8.5
-VERSION = 85
+DOTVERSION = 8.4
+VERSION = 84
-DDEVERSION = 13
-DDEDOTVERSION = 1.3
+DDEVERSION = 12
+DDEDOTVERSION = 1.2
-REGVERSION = 12
-REGDOTVERSION = 1.2
+REGVERSION = 11
+REGDOTVERSION = 1.1
BINROOT = ..
!IF "$(NODEBUG)" == "1"
TMPDIRNAME = Release
DBGX =
-SYMDEFINES =
!ELSE
TMPDIRNAME = Debug
#DBGX = d
DBGX =
-SYMDEFINES = -DTCL_CFG_DEBUG
!ENDIF
TMPDIR = $(BINROOT)\$(TMPDIRNAME)
OUTDIRNAME = $(TMPDIRNAME)
@@ -193,6 +174,9 @@ TCLOBJS = \
$(TMPDIR)\regexec.obj \
$(TMPDIR)\regfree.obj \
$(TMPDIR)\regerror.obj \
+ $(TMPDIR)\strftime.obj \
+ $(TMPDIR)\strtoll.obj \
+ $(TMPDIR)\strtoull.obj \
$(TMPDIR)\tclAlloc.obj \
$(TMPDIR)\tclAsync.obj \
$(TMPDIR)\tclBasic.obj \
@@ -205,9 +189,7 @@ TCLOBJS = \
$(TMPDIR)\tclCompCmds.obj \
$(TMPDIR)\tclCompExpr.obj \
$(TMPDIR)\tclCompile.obj \
- $(TMPDIR)\tclConfig.obj \
$(TMPDIR)\tclDate.obj \
- $(TMPDIR)\tclDictObj.obj \
$(TMPDIR)\tclEncoding.obj \
$(TMPDIR)\tclEnv.obj \
$(TMPDIR)\tclEvent.obj \
@@ -234,9 +216,9 @@ TCLOBJS = \
$(TMPDIR)\tclObj.obj \
$(TMPDIR)\tclPanic.obj \
$(TMPDIR)\tclParse.obj \
+ $(TMPDIR)\tclParseExpr.obj \
$(TMPDIR)\tclPipe.obj \
$(TMPDIR)\tclPkg.obj \
- $(TMPDIR)\tclPkgConfig.obj \
$(TMPDIR)\tclPosixStr.obj \
$(TMPDIR)\tclPreserve.obj \
$(TMPDIR)\tclProc.obj \
@@ -250,7 +232,6 @@ TCLOBJS = \
$(TMPDIR)\tclThread.obj \
$(TMPDIR)\tclThreadJoin.obj \
$(TMPDIR)\tclTimer.obj \
- $(TMPDIR)\tclTrace.obj \
$(TMPDIR)\tclUtf.obj \
$(TMPDIR)\tclUtil.obj \
$(TMPDIR)\tclVar.obj \
@@ -263,6 +244,7 @@ TCLOBJS = \
$(TMPDIR)\tclWinFile.obj \
$(TMPDIR)\tclWinInit.obj \
$(TMPDIR)\tclWinLoad.obj \
+ $(TMPDIR)\tclWinMtherr.obj \
$(TMPDIR)\tclWinNotify.obj \
$(TMPDIR)\tclWinPipe.obj \
$(TMPDIR)\tclWinSock.obj \
@@ -275,9 +257,7 @@ WINDIR = $(ROOT)\win
GENERICDIR = $(ROOT)\generic
TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-TCL_DEFINES = $(DEBUGDEFINES) $(THREADDEFINES) $(SYMDEFINES) \
- $(PROFDEFINES) $(OPTDEFINES) $(SIXFOURDEFINES) \
- -DTCL_CFGVAL_ENCODING=${CFG_ENCODING}
+TCL_DEFINES = $(DEBUGDEFINES) $(THREADDEFINES)
######################################################################
# Compiler flags
@@ -420,35 +400,30 @@ install-libraries:
-@$(MKDIR) "$(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"
- @echo installing http2.7
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\http2.7"
- -@copy "$(ROOT)\library\http\http.tcl" "$(SCRIPT_INSTALL_DIR)\http2.7"
- -@copy "$(ROOT)\library\http\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\http2.7"
+ @echo installing http2.5
+ -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\http2.5"
+ -@copy "$(ROOT)\library\http\http.tcl" "$(SCRIPT_INSTALL_DIR)\http2.5"
+ -@copy "$(ROOT)\library\http\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\http2.5"
@echo installing opt0.4
-@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\opt0.4"
-@copy "$(ROOT)\library\opt\optparse.tcl" "$(SCRIPT_INSTALL_DIR)\opt0.4"
-@copy "$(ROOT)\library\opt\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\opt0.4"
- @echo installing msgcat1.4
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\msgcat1.4"
- -@copy "$(ROOT)\library\msgcat\msgcat.tcl" "$(SCRIPT_INSTALL_DIR)\msgcat1.4"
- -@copy "$(ROOT)\library\msgcat\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\msgcat1.4"
- @echo installing tcltest2.3
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\tcltest2.3"
- -@copy "$(ROOT)\library\tcltest\tcltest.tcl" "$(SCRIPT_INSTALL_DIR)\tcltest2.3"
- -@copy "$(ROOT)\library\tcltest\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\tcltest2.3"
- @echo installing platform1.0
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\platform1.0"
- -@copy "$(ROOT)\library\platform\platform.tcl" "$(SCRIPT_INSTALL_DIR)\platform1.0"
- -@copy "$(ROOT)\library\platform\shell.tcl" "$(SCRIPT_INSTALL_DIR)\platform1.0"
- -@copy "$(ROOT)\library\platform\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\platform1.0"
+ @echo installing msgcat1.3
+ -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\msgcat1.3"
+ -@copy "$(ROOT)\library\msgcat\msgcat.tcl" "$(SCRIPT_INSTALL_DIR)\msgcat1.3"
+ -@copy "$(ROOT)\library\msgcat\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\msgcat1.3"
+ @echo installing tcltest2.2
+ -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\tcltest2.2"
+ -@copy "$(ROOT)\library\tcltest\tcltest.tcl" "$(SCRIPT_INSTALL_DIR)\tcltest2.2"
+ -@copy "$(ROOT)\library\tcltest\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\tcltest2.2"
@echo installing $(TCLDDEDLLNAME)
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\dde1.3"
- -@copy "$(TCLDDEDLL)" "$(SCRIPT_INSTALL_DIR)\dde1.3"
- -@copy "$(ROOT)\library\dde\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\dde1.3"
+ -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\dde1.1"
+ -@copy "$(TCLDDEDLL)" "$(SCRIPT_INSTALL_DIR)\dde1.1"
+ -@copy "$(ROOT)\library\dde\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\dde1.1"
@echo installing $(TCLREGDLLNAME)
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\reg1.2"
- -@copy "$(TCLREGDLL)" "$(SCRIPT_INSTALL_DIR)\reg1.2"
- -@copy "$(ROOT)\library\reg\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\reg1.2"
+ -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\reg1.1"
+ -@copy "$(TCLREGDLL)" "$(SCRIPT_INSTALL_DIR)\reg1.1"
+ -@copy "$(ROOT)\library\reg\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\reg1.1"
@echo installing encoding files
-@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\encoding"
-@copy "$(ROOT)\library\encoding\*.enc" "$(SCRIPT_INSTALL_DIR)\encoding"
@@ -458,6 +433,7 @@ install-libraries:
-@copy "$(GENERICDIR)\tclPlatDecls.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)"
@@ -514,14 +490,6 @@ $(TMPDIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c
$(TMPDIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c
$(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $?
-$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c
- $(cc32) $(TCL_CFLAGS) \
- -DCFG_INSTALL_EXEC_PREFIX=\"$(INSTALL_EXEC_PREFIX)\" \
- -DCFG_INSTALL_PREFIX=\"$(INSTALL_PREFIX)\" \
- -DCFG_RUNTIME_EXEC_PREFIX=\"$(RUNTIME_EXEC_PREFIX)\" \
- -DCFG_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
- -o$(TMPDIR)\$@ $?
-
$(TMPDIR)\tclAppInit.obj : $(WINDIR)\tclAppInit.c
$(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $?
diff --git a/win/makefile.vc b/win/makefile.vc
index d982284..426c907 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -1,4 +1,4 @@
-#------------------------------------------------------------- -*- makefile -*-
+#------------------------------------------------------------------------------
# makefile.vc --
#
# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
@@ -9,8 +9,7 @@
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2001-2005 ActiveState Corporation.
-# Copyright (c) 2001-2004 David Gravereaux.
-# Copyright (c) 2003-2008 Pat Thoyts.
+# Copyright (c) 2001-2002 David Gravereaux.
#------------------------------------------------------------------------------
# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
@@ -67,30 +66,26 @@ the build instructions.
# Sets where to install Tcl from the built binaries.
# C:\Progra~1\Tcl is assumed when not specified.
#
-# OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,unchecked,none
+# OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
# Sets special options for the core. The default is for none.
# Any combination of the above may be used (comma separated).
# 'none' will over-ride everything to nothing.
#
# static = Builds a static library of the core instead of a
# dll. The shell will be static (and large), as well.
-# msvcrt = Affects the static option only to switch it from
+# msvcrt = Effects the static option only to switch it from
# using libcmt(d) as the C runtime [by default] to
# msvcrt(d). This is useful for static embedding
# support.
-# staticpkg = Affects the static option only to switch
+# staticpkg = Effects the static option only to switch
# tclshXX.exe to have the dde and reg extension linked
# inside it.
# threads = Turns on full multithreading support.
# thrdalloc = Use the thread allocator (shared global free pool).
-# thrdstorage = Use the generic thread storage support.
# symbols = Adds symbols for step debugging.
# profile = Adds profiling hooks. Map file is assumed.
# loimpact = Adds a flag for how NT treats the heap to keep memory
# in use, low. This is said to impact alloc performance.
-# unchecked = Allows a symbols build to not use the debug
-# enabled runtime (msvcrt.dll not msvcrtd.dll
-# or libcmt.lib not libcmtd.lib).
#
# STATS=memdbg,compdbg,none
# Sets optional memory and bytecode compiler debugging code added
@@ -101,15 +96,6 @@ the build instructions.
# memdbg = Enables the debugging memory allocator.
# compdbg = Enables byte compilation logging.
#
-# CHECKS=nodep,fullwarn,64bit,none
-# Sets special macros for checking compatability.
-#
-# nodep = Turns off compatability macros to ensure the core
-# isn't being built with deprecated functions.
-# fullwarn = Builds with full compiler and link warnings enabled.
-# Very verbose.
-# 64bit = Enable 64bit portability warnings (if available)
-#
# MACHINE=(IX86|IA64|AMD64|ALPHA)
# Set the machine type used for the compiler, linker, and
# resource compiler. This hook is needed to tell the tools
@@ -126,10 +112,6 @@ the build instructions.
# TESTPAT=<file>
# Reads the tests requested to be run from this file.
#
-# CFG_ENCODING=encoding
-# name of encoding for configuration information. Defaults
-# to cp1252
-#
# 5) Examples:
#
# Basic syntax of calling nmake looks like this:
@@ -174,14 +156,14 @@ Please `cd` to its location first.
PROJECT = tcl
!include "rules.vc"
-STUBPREFIX = $(PROJECT)stub
-DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+STUBPREFIX = $(PROJECT)stub
+DOTVERSION = 8.4
+VERSION = $(DOTVERSION:.=)
-DDEDOTVERSION = 1.3
+DDEDOTVERSION = 1.2
DDEVERSION = $(DDEDOTVERSION:.=)
-REGDOTVERSION = 1.2
+REGDOTVERSION = 1.1
REGVERSION = $(REGDOTVERSION:.=)
BINROOT = .
@@ -208,15 +190,6 @@ TCLDDELIB = $(OUT_DIR)\$(TCLDDELIBNAME)
TCLTEST = $(OUT_DIR)\$(PROJECT)test.exe
CAT32 = $(OUT_DIR)\cat32.exe
-# Can we run what we build? IX86 runs on all architectures.
-!ifndef TCLSH_NATIVE
-!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
-TCLSH_NATIVE = $(TCLSH)
-!else
-!error You must explicitly set TCLSH_NATIVE for cross-compilation
-!endif
-!endif
-
### Make sure we use backslash only.
LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
@@ -249,6 +222,9 @@ TCLOBJS = \
$(TMP_DIR)\regerror.obj \
$(TMP_DIR)\regexec.obj \
$(TMP_DIR)\regfree.obj \
+ $(TMP_DIR)\strftime.obj \
+ $(TMP_DIR)\strtoll.obj \
+ $(TMP_DIR)\strtoull.obj \
$(TMP_DIR)\tclAlloc.obj \
$(TMP_DIR)\tclAsync.obj \
$(TMP_DIR)\tclBasic.obj \
@@ -261,9 +237,7 @@ TCLOBJS = \
$(TMP_DIR)\tclCompCmds.obj \
$(TMP_DIR)\tclCompExpr.obj \
$(TMP_DIR)\tclCompile.obj \
- $(TMP_DIR)\tclConfig.obj \
$(TMP_DIR)\tclDate.obj \
- $(TMP_DIR)\tclDictObj.obj \
$(TMP_DIR)\tclEncoding.obj \
$(TMP_DIR)\tclEnv.obj \
$(TMP_DIR)\tclEvent.obj \
@@ -280,7 +254,6 @@ TCLOBJS = \
$(TMP_DIR)\tclIOGT.obj \
$(TMP_DIR)\tclIOSock.obj \
$(TMP_DIR)\tclIOUtil.obj \
- $(TMP_DIR)\tclIORChan.obj \
$(TMP_DIR)\tclLink.obj \
$(TMP_DIR)\tclListObj.obj \
$(TMP_DIR)\tclLiteral.obj \
@@ -291,10 +264,9 @@ TCLOBJS = \
$(TMP_DIR)\tclObj.obj \
$(TMP_DIR)\tclPanic.obj \
$(TMP_DIR)\tclParse.obj \
- $(TMP_DIR)\tclPathObj.obj \
+ $(TMP_DIR)\tclParseExpr.obj \
$(TMP_DIR)\tclPipe.obj \
$(TMP_DIR)\tclPkg.obj \
- $(TMP_DIR)\tclPkgConfig.obj \
$(TMP_DIR)\tclPosixStr.obj \
$(TMP_DIR)\tclPreserve.obj \
$(TMP_DIR)\tclProc.obj \
@@ -303,16 +275,12 @@ TCLOBJS = \
$(TMP_DIR)\tclResult.obj \
$(TMP_DIR)\tclScan.obj \
$(TMP_DIR)\tclStringObj.obj \
- $(TMP_DIR)\tclStrToD.obj \
$(TMP_DIR)\tclStubInit.obj \
$(TMP_DIR)\tclStubLib.obj \
$(TMP_DIR)\tclThread.obj \
$(TMP_DIR)\tclThreadAlloc.obj \
$(TMP_DIR)\tclThreadJoin.obj \
- $(TMP_DIR)\tclThreadStorage.obj \
$(TMP_DIR)\tclTimer.obj \
- $(TMP_DIR)\tclTomMathInterface.obj \
- $(TMP_DIR)\tclTrace.obj \
$(TMP_DIR)\tclUtf.obj \
$(TMP_DIR)\tclUtil.obj \
$(TMP_DIR)\tclVar.obj \
@@ -325,75 +293,12 @@ TCLOBJS = \
$(TMP_DIR)\tclWinFile.obj \
$(TMP_DIR)\tclWinInit.obj \
$(TMP_DIR)\tclWinLoad.obj \
+ $(TMP_DIR)\tclWinMtherr.obj \
$(TMP_DIR)\tclWinNotify.obj \
$(TMP_DIR)\tclWinPipe.obj \
$(TMP_DIR)\tclWinSock.obj \
$(TMP_DIR)\tclWinThrd.obj \
$(TMP_DIR)\tclWinTime.obj \
- $(TMP_DIR)\bncore.obj \
- $(TMP_DIR)\bn_reverse.obj \
- $(TMP_DIR)\bn_fast_s_mp_mul_digs.obj \
- $(TMP_DIR)\bn_fast_s_mp_sqr.obj \
- $(TMP_DIR)\bn_mp_add.obj \
- $(TMP_DIR)\bn_mp_add_d.obj \
- $(TMP_DIR)\bn_mp_and.obj \
- $(TMP_DIR)\bn_mp_clamp.obj \
- $(TMP_DIR)\bn_mp_clear.obj \
- $(TMP_DIR)\bn_mp_clear_multi.obj \
- $(TMP_DIR)\bn_mp_cmp.obj \
- $(TMP_DIR)\bn_mp_cmp_d.obj \
- $(TMP_DIR)\bn_mp_cmp_mag.obj \
- $(TMP_DIR)\bn_mp_cnt_lsb.obj \
- $(TMP_DIR)\bn_mp_copy.obj \
- $(TMP_DIR)\bn_mp_count_bits.obj \
- $(TMP_DIR)\bn_mp_div.obj \
- $(TMP_DIR)\bn_mp_div_d.obj \
- $(TMP_DIR)\bn_mp_div_2.obj \
- $(TMP_DIR)\bn_mp_div_2d.obj \
- $(TMP_DIR)\bn_mp_div_3.obj \
- $(TMP_DIR)\bn_mp_exch.obj \
- $(TMP_DIR)\bn_mp_expt_d.obj \
- $(TMP_DIR)\bn_mp_grow.obj \
- $(TMP_DIR)\bn_mp_init.obj \
- $(TMP_DIR)\bn_mp_init_copy.obj \
- $(TMP_DIR)\bn_mp_init_multi.obj \
- $(TMP_DIR)\bn_mp_init_set.obj \
- $(TMP_DIR)\bn_mp_init_set_int.obj \
- $(TMP_DIR)\bn_mp_init_size.obj \
- $(TMP_DIR)\bn_mp_karatsuba_mul.obj \
- $(TMP_DIR)\bn_mp_karatsuba_sqr.obj \
- $(TMP_DIR)\bn_mp_lshd.obj \
- $(TMP_DIR)\bn_mp_mod.obj \
- $(TMP_DIR)\bn_mp_mod_2d.obj \
- $(TMP_DIR)\bn_mp_mul.obj \
- $(TMP_DIR)\bn_mp_mul_2.obj \
- $(TMP_DIR)\bn_mp_mul_2d.obj \
- $(TMP_DIR)\bn_mp_mul_d.obj \
- $(TMP_DIR)\bn_mp_neg.obj \
- $(TMP_DIR)\bn_mp_or.obj \
- $(TMP_DIR)\bn_mp_radix_size.obj \
- $(TMP_DIR)\bn_mp_radix_smap.obj \
- $(TMP_DIR)\bn_mp_read_radix.obj \
- $(TMP_DIR)\bn_mp_rshd.obj \
- $(TMP_DIR)\bn_mp_set.obj \
- $(TMP_DIR)\bn_mp_set_int.obj \
- $(TMP_DIR)\bn_mp_shrink.obj \
- $(TMP_DIR)\bn_mp_sqr.obj \
- $(TMP_DIR)\bn_mp_sqrt.obj \
- $(TMP_DIR)\bn_mp_sub.obj \
- $(TMP_DIR)\bn_mp_sub_d.obj \
- $(TMP_DIR)\bn_mp_to_unsigned_bin.obj \
- $(TMP_DIR)\bn_mp_to_unsigned_bin_n.obj \
- $(TMP_DIR)\bn_mp_toom_mul.obj \
- $(TMP_DIR)\bn_mp_toom_sqr.obj \
- $(TMP_DIR)\bn_mp_toradix_n.obj \
- $(TMP_DIR)\bn_mp_unsigned_bin_size.obj \
- $(TMP_DIR)\bn_mp_xor.obj \
- $(TMP_DIR)\bn_mp_zero.obj \
- $(TMP_DIR)\bn_s_mp_add.obj \
- $(TMP_DIR)\bn_s_mp_mul_digs.obj \
- $(TMP_DIR)\bn_s_mp_sqr.obj \
- $(TMP_DIR)\bn_s_mp_sub.obj \
!if !$(STATIC_BUILD)
$(TMP_DIR)\tcl.res
!endif
@@ -404,7 +309,6 @@ TCLSTUBOBJS = $(TMP_DIR)\tclStubLib.obj
COMPATDIR = $(ROOT)\compat
DOCDIR = $(ROOT)\doc
GENERICDIR = $(ROOT)\generic
-TOMMATHDIR = $(ROOT)\libtommath
TOOLSDIR = $(ROOT)\tools
WINDIR = $(ROOT)\win
@@ -420,9 +324,6 @@ cdebug = -O2 $(OPTIMIZATIONS)
!else
cdebug =
!endif
-!if $(SYMBOLS)
-cdebug = $(cdebug) -Zi
-!endif
!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
### Warnings are too many, can't support warnings into errors.
cdebug = -Zi -Od $(DEBUGFLAGS)
@@ -431,30 +332,34 @@ cdebug = -Zi -WX $(DEBUGFLAGS)
!endif
### Declarations common to all compiler options
-cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
+cwarn = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
-!if $(MSVCRT)
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MDd
+!if $(FULLWARNINGS)
+cflags = $(cflags) -W4
!else
-crt = -MD
+cflags = $(cflags) -W3
!endif
+
+!if $(MSVCRT)
+!if "$(DBGX)" == ""
+crt = -MD
!else
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MTd
+crt = -MDd
+!endif
!else
+!if "$(DBGX)" == ""
crt = -MT
+!else
+crt = -MTd
!endif
!endif
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(TOMMATHDIR)"
-TCL_DEFINES = -DTCL_PIPE_DLL=\"$(TCLPIPEDLLNAME)\" -DTCL_TOMMATH -DMP_PREC=4 -Dinline=__inline
-BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(TCL_INCLUDES) $(TCL_DEFINES)
+TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(TCL_INCLUDES) \
+ -DTCL_PIPE_DLL=\"$(TCLPIPEDLLNAME)\"
CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE
TCL_CFLAGS = $(BASE_CFLAGS) $(OPTDEFINES)
-### Stubs files should not be compiled with -GL
-STUB_CFLAGS = $(cflags) $(cdebug:-GL=) $(OPTDEFINES)
#---------------------------------------------------------------------
@@ -465,14 +370,15 @@ STUB_CFLAGS = $(cflags) $(cdebug:-GL=) $(OPTDEFINES)
ldebug = -debug -debugtype:cv
!else
ldebug = -release -opt:ref -opt:icf,3
-!if $(SYMBOLS)
-ldebug = $(ldebug) -debug -debugtype:cv
-!endif
!endif
### Declarations common to all linker options
lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+!if $(FULLWARNINGS)
+lflags = $(lflags) -warn:3
+!endif
+
!if $(PROFILE)
lflags = $(lflags) -profile
!endif
@@ -493,14 +399,12 @@ dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows
-baselibs = kernel32.lib user32.lib ws2_32.lib
+baselibs = kernel32.lib advapi32.lib user32.lib
# Avoid 'unresolved external symbol __security_cookie' errors.
# c.f. http://support.microsoft.com/?id=894573
!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
-!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
baselibs = $(baselibs) bufferoverflowU.lib
!endif
-!endif
#---------------------------------------------------------------------
# TclTest flags
@@ -527,22 +431,15 @@ install: install-binaries install-libraries install-docs
test: setup $(TCLTEST) dlls $(CAT32)
set TCL_LIBRARY=$(ROOT)/library
!if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE"
- $(TCLTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) -loadfile <<
- set ::ddelib [file normalize $(TCLDDELIB:\=/)]
- set ::reglib [file normalize $(TCLREGLIB:\=/)]
-<<
+ $(TCLTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS)
!else
- @echo Please wait while the tests are collected...
- $(TCLTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) -loadfile << > tests.log
- set ::ddelib [file normalize $(TCLDDELIB:\=/)]
- set ::reglib [file normalize $(TCLREGLIB:\=/)]
-<<
+ $(TCLTEST) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) > tests.log
type tests.log | more
!endif
runtest: setup $(TCLTEST) dlls $(CAT32)
set TCL_LIBRARY=$(ROOT)/library
- $(DEBUGGER) $(TCLTEST)
+ $(TCLTEST)
setup:
@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
@@ -584,7 +481,7 @@ $(TCLPIPEDLL): $(WINDIR)\stub16.c
!if $(STATIC_BUILD)
$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj
- $(lib32) -nologo -out:$@ $**
+ $(lib32) -nologo -out:$@ $(TMP_DIR)\tclWinDde.obj
!else
$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj $(TCLSTUBLIB)
$(link32) $(dlllflags) -base:@$(WINDIR)\coffbase.txt,tcldde -out:$@ \
@@ -596,7 +493,7 @@ $(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj $(TCLSTUBLIB)
!if $(STATIC_BUILD)
$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj
- $(lib32) -nologo -out:$@ $**
+ $(lib32) -nologo -out:$@ $(TMP_DIR)\tclWinReg.obj
!else
$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj $(TCLSTUBLIB)
$(link32) $(dlllflags) -base:@$(WINDIR)\coffbase.txt,tclreg -out:$@ \
@@ -620,27 +517,27 @@ genstubs:
!if !exist($(TCLSH))
@echo Build tclsh first!
!else
- $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \
- $(GENERICDIR:\=/)/tcl.decls $(GENERICDIR:\=/)/tclInt.decls \
- $(GENERICDIR:\=/)/tclTomMath.decls
+ $(TCLSH) $(TOOLSDIR:\=/)\genStubs.tcl $(GENERICDIR:\=/) \
+ $(GENERICDIR:\=/)/tcl.decls $(GENERICDIR:\=/)/tclInt.decls
!endif
-#----------------------------------------------------------------------
-# The following target generates the file generic/tclTomMath.h.
-# It needs to be run (and the results checked) after updating
-# to a new release of libtommath.
-#----------------------------------------------------------------------
+#---------------------------------------------------------------------
+# Generate the makefile depedancies.
+#---------------------------------------------------------------------
-gentommath_h:
+depend:
!if !exist($(TCLSH))
@echo Build tclsh first!
!else
- $(TCLSH) "$(TOOLSDIR:\=/)/fix_tommath_h.tcl" \
- "$(TOMMATHDIR:\=/)/tommath.h" \
- > "$(GENERICDIR)\tclTomMath.h"
+ $(TCLSH) $(TOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \
+ -passthru:"-DBUILD_tcl $(TCL_INCLUDES:"="")" $(GENERICDIR) \
+ $(COMPATDIR) $(WINDIR) @<<
+$(TCLOBJS)
+<<
!endif
+
#---------------------------------------------------------------------
# Build the windows help file.
#---------------------------------------------------------------------
@@ -707,91 +604,17 @@ install-docs:
@$(CPY) "$(HELPCNT)" "$(DOC_INSTALL_DIR)\"
!endif
-#---------------------------------------------------------------------
-# Build tclConfig.sh for the TEA build system.
-#---------------------------------------------------------------------
-
-tclConfig: $(OUT_DIR)\tclConfig.sh
-
-$(OUT_DIR)\tclConfig.sh: $(WINDIR)\tclConfig.sh.in
- @echo Creating tclConfig.sh
- @nmakehlp -s << $** >$@
-@TCL_DLL_FILE@ $(TCLLIBNAME)
-@TCL_VERSION@ $(DOTVERSION)
-@TCL_MAJOR_VERSION@ $(TCL_MAJOR_VERSION)
-@TCL_MINOR_VERSION@ $(TCL_MINOR_VERSION)
-@TCL_PATCH_LEVEL@ $(TCL_PATCH_LEVEL)
-@CC@ $(CC)
-@DEFS@ $(TCL_CFLAGS)
-@CFLAGS_DEBUG@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MDd
-@CFLAGS_OPTIMIZE@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MD
-@LDFLAGS_DEBUG@ -nologo -machine:$(MACHINE) -debug -debugtype:cv
-@LDFLAGS_OPTIMIZE@ -nologo -machine:$(MACHINE) -release -opt:ref -opt:icf,3
-@TCL_DBGX@ $(SUFX)
-@TCL_LIB_FILE@ $(PROJECT)$(VERSION)$(SUFX).lib
-@TCL_NEEDS_EXP_FILE@
-@LIBS@ $(baselibs)
-@prefix@ $(_INSTALLDIR)
-@exec_prefix@ $(BIN_INSTALL_DIR)
-@SHLIB_CFLAGS@
-@STLIB_CFLAGS@
-@CFLAGS_WARNING@ -W3
-@EXTRA_CFLAGS@ -YX
-@SHLIB_LD@ $(link32) $(dlllflags)
-@STLIB_LD@ $(lib32) -nologo
-@SHLIB_LD_LIBS@ $(baselibs)
-@SHLIB_SUFFIX@ .dll
-@DL_LIBS@
-@LDFLAGS@
-@TCL_LD_SEARCH_FLAGS@
-@LIBOBJS@
-@RANLIB@
-@TCL_LIB_FLAG@
-@TCL_BUILD_LIB_SPEC@
-@TCL_LIB_SPEC@ $(LIB_INSTALL_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-@TCL_INCLUDE_SPEC@ -I$(INCLUDE_INSTALL_DIR)
-@TCL_LIB_VERSIONS_OK@
-@TCL_SRC_DIR@ $(ROOT)
-@TCL_PACKAGE_PATH@
-@TCL_STUB_LIB_FILE@ $(TCLSTUBLIBNAME)
-@TCL_STUB_LIB_FLAG@ $(TCLSTUBLIBNAME)
-@TCL_STUB_LIB_SPEC@ -L$(LIB_INSTALL_DIR) $(TCLSTUBLIBNAME)
-@TCL_THREADS@ $(TCL_THREADS)
-@TCL_BUILD_STUB_LIB_SPEC@ -L$(OUT_DIR) $(TCLSTUBLIBNAME)
-@TCL_BUILD_STUB_LIB_PATH@ $(TCLSTUBLIB)
-@TCL_STUB_LIB_PATH@ $(LIB_INSTALL_DIR)\$(TCLSTUBLIBNAME)
-@CFG_TCL_EXPORT_FILE_SUFFIX@ $(VERSION)$(SUFX).lib
-@CFG_TCL_SHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).dll
-@CFG_TCL_UNSHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).lib
-!if $(STATIC_BUILD)
-@TCL_SHARED_BUILD@ 0
-!else
-@TCL_SHARED_BUILD@ 1
-!endif
-<<
-
-
-#---------------------------------------------------------------------
-# The following target generates the file generic/tclDate.c
-# from the yacc grammar found in generic/tclGetDate.y. This is
-# only run by hand as yacc is not available in all environments.
-# The name of the .c file is different than the name of the .y file
-# so that make doesn't try to automatically regenerate the .c file.
-#---------------------------------------------------------------------
-
-gendate:
- bison --output-file=$(GENERICDIR)/tclDate.c \
- --name-prefix=TclDate \
- $(GENERICDIR)/tclGetDate.y
#---------------------------------------------------------------------
# Special case object file targets
#---------------------------------------------------------------------
$(TMP_DIR)\testMain.obj: $(WINDIR)\tclAppInit.c
- $(cc32) $(TCL_CFLAGS) -DTCL_TEST \
- -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
- -Fo$@ $?
+!if $(TCL_USE_STATIC_PACKAGES)
+ $(cc32) $(TCL_CFLAGS) -DTCL_TEST -DTCL_USE_STATIC_PACKAGES -Fo$@ $?
+!else
+ $(cc32) $(TCL_CFLAGS) -DTCL_TEST -Fo$@ $?
+!endif
$(TMP_DIR)\tclTest.obj: $(GENERICDIR)\tclTest.c
$(cc32) $(TCL_CFLAGS) -Fo$@ $?
@@ -802,77 +625,66 @@ $(TMP_DIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c
$(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c
$(cc32) $(TCL_CFLAGS) -Fo$@ $?
-$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c
- $(cc32) -DBUILD_tcl $(TCL_CFLAGS) \
- -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \
- -DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \
- -DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \
- -DCFG_INSTALL_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \
- -DCFG_INSTALL_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \
- -DCFG_RUNTIME_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \
- -DCFG_RUNTIME_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \
- -DCFG_RUNTIME_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \
- -DCFG_RUNTIME_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \
- -DCFG_RUNTIME_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \
- -Fo$@ $?
-
$(TMP_DIR)\tclAppInit.obj: $(WINDIR)\tclAppInit.c
- $(cc32) $(TCL_CFLAGS) \
- -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
- -Fo$@ $?
+!if $(TCL_USE_STATIC_PACKAGES)
+ $(cc32) $(TCL_CFLAGS) -DTCL_USE_STATIC_PACKAGES -Fo$@ $?
+!else
+ $(cc32) $(TCL_CFLAGS) -Fo$@ $?
+!endif
### The following objects should be built using the stub interfaces
### *ALL* extensions need to built with -DTCL_THREADS=1
$(TMP_DIR)\tclWinReg.obj: $(WINDIR)\tclWinReg.c
!if $(STATIC_BUILD)
- $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DSTATIC_BUILD -Fo$@ $?
+ $(cc32) $(BASE_CFLAGS) -DTCL_THREADS=1 -DSTATIC_BUILD -Fo$@ $?
!else
- $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DUSE_TCL_STUBS -Fo$@ $?
+ $(cc32) $(BASE_CFLAGS) -DTCL_THREADS=1 -DUSE_TCL_STUBS -Fo$@ $?
!endif
$(TMP_DIR)\tclWinDde.obj: $(WINDIR)\tclWinDde.c
!if $(STATIC_BUILD)
- $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DSTATIC_BUILD -Fo$@ $?
+ $(cc32) $(BASE_CFLAGS) -DTCL_THREADS=1 -DSTATIC_BUILD -Fo$@ $?
!else
- $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DUSE_TCL_STUBS -Fo$@ $?
+ $(cc32) $(BASE_CFLAGS) -DTCL_THREADS=1 -DUSE_TCL_STUBS -Fo$@ $?
!endif
### The following objects are part of the stub library and should not
-### be built as DLL objects. -Zl is used to avoid a dependency on any
+### be built as DLL objects. -Zl is used to avoid a dependancy on any
### specific C run-time.
$(TMP_DIR)\tclStubLib.obj: $(GENERICDIR)\tclStubLib.c
- $(cc32) $(STUB_CFLAGS) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $?
+ $(cc32) $(cdebug) $(cflags) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $?
-#---------------------------------------------------------------------
-# Generate the source dependencies. Having dependency rules will
-# improve incremental build accuracy without having to resort to a
-# full rebuild just because some non-global header file like
-# tclCompile.h was changed. These rules aren't needed when building
-# from scratch.
-#---------------------------------------------------------------------
-
-depend:
-!if !exist($(TCLSH))
- @echo Build tclsh first!
-!else
- $(TCLSH) $(TOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \
- -passthru:"-DBUILD_tcl $(TCL_INCLUDES)" $(GENERICDIR),$$(GENERICDIR) \
- $(COMPATDIR),$$(COMPATDIR) $(TOMMATHDIR),$$(TOMMATHDIR) $(WINDIR),$$(WINDIR) @<<
-$(TCLOBJS)
-<<
-!endif
#---------------------------------------------------------------------
-# Dependency rules
+# Dedependency rules
#---------------------------------------------------------------------
+$(GENERICDIR)\regcomp.c: \
+ $(GENERICDIR)\regguts.h \
+ $(GENERICDIR)\regc_lex.c \
+ $(GENERICDIR)\regc_color.c \
+ $(GENERICDIR)\regc_nfa.c \
+ $(GENERICDIR)\regc_cvec.c \
+ $(GENERICDIR)\regc_locale.c
+$(GENERICDIR)\regcustom.h: \
+ $(GENERICDIR)\tclInt.h \
+ $(GENERICDIR)\tclPort.h \
+ $(GENERICDIR)\regex.h
+$(GENERICDIR)\regexec.c: \
+ $(GENERICDIR)\rege_dfa.c \
+ $(GENERICDIR)\regguts.h
+$(GENERICDIR)\regerror.c: $(GENERICDIR)\regguts.h
+$(GENERICDIR)\regfree.c: $(GENERICDIR)\regguts.h
+$(GENERICDIR)\regfronts.c: $(GENERICDIR)\regguts.h
+$(GENERICDIR)\regguts.h: $(GENERICDIR)\regcustom.h
+
!if exist("$(OUT_DIR)\depend.mk")
!include "$(OUT_DIR)\depend.mk"
-!message *** Dependency rules in use.
+!message *** Dependency rules in effect.
!else
!message *** Dependency rules are not being used.
!endif
@@ -886,31 +698,32 @@ $(TCLOBJS)
#---------------------------------------------------------------------
{$(WINDIR)}.c{$(TMP_DIR)}.obj::
- $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
-$<
-<<
-
-{$(TOMMATHDIR)}.c{$(TMP_DIR)}.obj::
- $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
+ $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
$<
<<
{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
- $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
+ $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
$<
<<
{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
- $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
+ $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
$<
<<
{$(WINDIR)}.rc{$(TMP_DIR)}.res:
- $(rc32) -fo $@ -r -i "$(GENERICDIR)" \
- -d DEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
- -d TCL_THREADS=$(TCL_THREADS) \
- -d STATIC_BUILD=$(STATIC_BUILD) \
- $<
+ $(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
+!if $(DEBUG)
+ -d DEBUG \
+!endif
+!if $(TCL_THREADS)
+ -d TCL_THREADS \
+!endif
+!if $(STATIC_BUILD)
+ -d STATIC_BUILD \
+!endif
+ $<
.SUFFIXES:
.SUFFIXES:.c .rc
@@ -922,129 +735,79 @@ $<
install-binaries:
@echo Installing to '$(_INSTALLDIR)'
- @echo Installing $(TCLLIBNAME)
+ @echo installing $(TCLLIBNAME)
!if "$(TCLLIB)" != "$(TCLIMPLIB)"
@$(CPY) "$(TCLLIB)" "$(BIN_INSTALL_DIR)\"
!endif
@$(CPY) "$(TCLIMPLIB)" "$(LIB_INSTALL_DIR)\"
!if exist($(TCLSH))
- @echo Installing $(TCLSHNAME)
+ @echo installing $(TCLSHNAME)
@$(CPY) "$(TCLSH)" "$(BIN_INSTALL_DIR)\"
!endif
!if exist($(TCLPIPEDLL))
- @echo Installing $(TCLPIPEDLLNAME)
+ @echo installing $(TCLPIPEDLLNAME)
@$(CPY) "$(TCLPIPEDLL)" "$(BIN_INSTALL_DIR)\"
!endif
- @echo Installing $(TCLSTUBLIBNAME)
+ @echo installing $(TCLSTUBLIBNAME)
@$(CPY) "$(TCLSTUBLIB)" "$(LIB_INSTALL_DIR)\"
-#" emacs fix
-
-install-libraries: tclConfig install-msgs install-tzdata
- @if not exist "$(SCRIPT_INSTALL_DIR)$(NULL)" \
- $(MKDIR) "$(SCRIPT_INSTALL_DIR)"
- @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8$(NULL)" \
- $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8"
- @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.2$(NULL)" \
- $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.2"
- @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.3$(NULL)" \
- $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.3"
- @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4$(NULL)" \
- $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4"
- @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform$(NULL)" \
- $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform"
- @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5$(NULL)" \
- $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5"
- @echo Installing header files
- @$(CPY) "$(GENERICDIR)\tcl.h" "$(INCLUDE_INSTALL_DIR)\"
- @$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\"
- @$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
- @$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\"
- @$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\"
- @$(CPY) "$(TOMMATHDIR)\tommath_class.h" "$(INCLUDE_INSTALL_DIR)\"
- @$(CPY) "$(TOMMATHDIR)\tommath_superclass.h" "$(INCLUDE_INSTALL_DIR)\"
- @echo Installing library files to $(SCRIPT_INSTALL_DIR)
- @$(CPY) "$(ROOT)\library\history.tcl" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\init.tcl" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\clock.tcl" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\tm.tcl" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\parray.tcl" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\safe.tcl" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\tclIndex" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\package.tcl" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\word.tcl" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(ROOT)\library\auto.tcl" "$(SCRIPT_INSTALL_DIR)\"
- @$(CPY) "$(OUT_DIR)\tclConfig.sh" "$(LIB_INSTALL_DIR)\"
- @echo Installing library http1.0 directory
+install-libraries:
+ @echo installing http1.0
@$(CPY) "$(ROOT)\library\http1.0\*.tcl" \
- "$(SCRIPT_INSTALL_DIR)\http1.0\"
- @echo Installing library opt0.4 directory
+ "$(SCRIPT_INSTALL_DIR)\http1.0\"
+ @echo installing http2.5
+ @$(CPY) "$(ROOT)\library\http\*.tcl" \
+ "$(SCRIPT_INSTALL_DIR)\http2.5\"
+ @echo installing opt0.4
@$(CPY) "$(ROOT)\library\opt\*.tcl" \
- "$(SCRIPT_INSTALL_DIR)\opt0.4\"
- @echo Installing package http $(PKG_HTTP_VER) as a Tcl Module
- @$(COPY) "$(ROOT)\library\http\http.tcl" \
- "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\http-$(PKG_HTTP_VER).tm"
- @echo Installing package msgcat $(PKG_MSGCAT_VER) as a Tcl Module
- @$(COPY) "$(ROOT)\library\msgcat\msgcat.tcl" \
- "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\msgcat-$(PKG_MSGCAT_VER).tm"
- @echo Installing package tcltest $(PKG_TCLTEST_VER) as a Tcl Module
- @$(COPY) "$(ROOT)\library\tcltest\tcltest.tcl" \
- "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\tcltest-$(PKG_TCLTEST_VER).tm"
- @echo Installing package platform $(PKG_PLATFORM_VER) as a Tcl Module
- @$(COPY) "$(ROOT)\library\platform\platform.tcl" \
- "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform-$(PKG_PLATFORM_VER).tm"
- @echo Installing package platform::shell $(PKG_SHELL_VER) as a Tcl Module
- @$(COPY) "$(ROOT)\library\platform\shell.tcl" \
- "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform\shell-$(PKG_SHELL_VER).tm"
- @echo Installing $(TCLDDELIBNAME)
+ "$(SCRIPT_INSTALL_DIR)\opt0.4\"
+ @echo installing msgcat1.3
+ @$(CPY) "$(ROOT)\library\msgcat\*.tcl" \
+ "$(SCRIPT_INSTALL_DIR)\msgcat1.3\"
+ @echo installing tcltest2.2
+ @$(CPY) "$(ROOT)\library\tcltest\*.tcl" \
+ "$(SCRIPT_INSTALL_DIR)\tcltest2.2\"
+ @echo installing $(TCLDDELIBNAME)
!if $(STATIC_BUILD)
-!if !$(TCL_USE_STATIC_PACKAGES)
@$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\"
-!endif
!else
@$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\"
@$(CPY) "$(ROOT)\library\dde\pkgIndex.tcl" \
"$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\"
!endif
- @echo Installing $(TCLREGLIBNAME)
+ @echo installing $(TCLREGLIBNAME)
!if $(STATIC_BUILD)
-!if !$(TCL_USE_STATIC_PACKAGES)
@$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\"
-!endif
!else
@$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\"
@$(CPY) "$(ROOT)\library\reg\pkgIndex.tcl" \
"$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\"
!endif
- @echo Installing encodings
+ @echo installing encoding files
@$(CPY) "$(ROOT)\library\encoding\*.enc" \
"$(SCRIPT_INSTALL_DIR)\encoding\"
+ @echo installing library files
+ @$(CPY) "$(GENERICDIR)\tcl.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(ROOT)\library\history.tcl" "$(SCRIPT_INSTALL_DIR)\"
+ @$(CPY) "$(ROOT)\library\init.tcl" "$(SCRIPT_INSTALL_DIR)\"
+ @$(CPY) "$(ROOT)\library\ldAout.tcl" "$(SCRIPT_INSTALL_DIR)\"
+ @$(CPY) "$(ROOT)\library\parray.tcl" "$(SCRIPT_INSTALL_DIR)\"
+ @$(CPY) "$(ROOT)\library\safe.tcl" "$(SCRIPT_INSTALL_DIR)\"
+ @$(CPY) "$(ROOT)\library\tclIndex" "$(SCRIPT_INSTALL_DIR)\"
+ @$(CPY) "$(ROOT)\library\package.tcl" "$(SCRIPT_INSTALL_DIR)\"
+ @$(CPY) "$(ROOT)\library\word.tcl" "$(SCRIPT_INSTALL_DIR)\"
+ @$(CPY) "$(ROOT)\library\auto.tcl" "$(SCRIPT_INSTALL_DIR)\"
-#" emacs fix
-
-install-tzdata:
- @echo Installing time zone data
- @set TCL_LIBRARY=$(ROOT)/library
- @$(TCLSH_NATIVE) "$(ROOT)/tools/installData.tcl" \
- "$(ROOT)/library/tzdata" "$(SCRIPT_INSTALL_DIR)/tzdata"
-
-install-msgs:
- @echo Installing message catalogs
- @set TCL_LIBRARY=$(ROOT)/library
- @$(TCLSH_NATIVE) "$(ROOT)/tools/installData.tcl" \
- "$(ROOT)/library/msgs" "$(SCRIPT_INSTALL_DIR)/msgs"
#---------------------------------------------------------------------
# Clean up
#---------------------------------------------------------------------
tidy:
-!if "$(TCLLIB)" != "$(TCLIMPLIB)"
@echo Removing $(TCLLIB) ...
@if exist $(TCLLIB) del $(TCLLIB)
-!endif
- @echo Removing $(TCLIMPLIB) ...
- @if exist $(TCLIMPLIB) del $(TCLIMPLIB)
@echo Removing $(TCLSH) ...
@if exist $(TCLSH) del $(TCLSH)
@echo Removing $(TCLTEST) ...
@@ -1057,18 +820,6 @@ tidy:
clean:
@echo Cleaning $(TMP_DIR)\* ...
@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
- @echo Cleaning $(WINDIR)\nmakehlp.obj ...
- @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
- @echo Cleaning $(WINDIR)\nmakehlp.exe ...
- @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
- @echo Cleaning $(WINDIR)\_junk.pch ...
- @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
- @echo Cleaning $(WINDIR)\vercl.x ...
- @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
- @echo Cleaning $(WINDIR)\vercl.i ...
- @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
- @echo Cleaning $(WINDIR)\versions.vc ...
- @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
hose:
@echo Hosing $(OUT_DIR)\* ...
diff --git a/win/nmakehlp.c b/win/nmakehlp.c
index f1b5f34..4657c81 100644
--- a/win/nmakehlp.c
+++ b/win/nmakehlp.c
@@ -5,10 +5,9 @@
* This is used to fix limitations within nmake and the environment.
*
* Copyright (c) 2002 by David Gravereaux.
- * Copyright (c) 2006 by Pat Thoyts
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
* ----------------------------------------------------------------------------
*/
@@ -18,15 +17,9 @@
#pragma comment (lib, "kernel32.lib")
#include <stdio.h>
#include <math.h>
-
-/*
- * This library is required for x64 builds with _some_ versions
- */
#if defined(_M_IA64) || defined(_M_AMD64)
-#if _MSC_FULL_VER > 140000000 && _MSC_FULL_VER <= 140040310
#pragma comment(lib, "bufferoverflowU")
#endif
-#endif
/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
@@ -41,8 +34,6 @@ int CheckForCompilerFeature(const char *option);
int CheckForLinkerFeature(const char *option);
int IsIn(const char *string, const char *substring);
int GrepForDefine(const char *file, const char *string);
-int SubstituteFile(const char *substs, const char *filename);
-const char * GetVersionFromFile(const char *filename, const char *match);
DWORD WINAPI ReadFromPipe(LPVOID args);
/* globals */
@@ -137,35 +128,10 @@ main(
return 2;
}
return GrepForDefine(argv[2], argv[3]);
- case 's':
- if (argc == 2) {
- chars = snprintf(msg, sizeof(msg) - 1,
- "usage: %s -s <substitutions file> <file>\n"
- "Perform a set of string map type substutitions on a file\n"
- "exitcodes: 0\n",
- argv[0]);
- WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
- &dwWritten, NULL);
- return 2;
- }
- return SubstituteFile(argv[2], argv[3]);
- case 'V':
- if (argc != 4) {
- chars = snprintf(msg, sizeof(msg) - 1,
- "usage: %s -V filename matchstring\n"
- "Extract a version from a file:\n"
- "eg: pkgIndex.tcl \"package ifneeded http\"",
- argv[0]);
- WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
- &dwWritten, NULL);
- return 0;
- }
- printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
- return 0;
}
}
chars = snprintf(msg, sizeof(msg) - 1,
- "usage: %s -c|-l|-f|-g|-V ...\n"
+ "usage: %s -c|-l|-f ...\n"
"This is a little helper app to equalize shell differences between WinNT and\n"
"Win9x and get nmake.exe to accomplish its job.\n",
argv[0]);
@@ -224,7 +190,7 @@ CheckForCompilerFeature(
* Base command line.
*/
- lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
+ lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X ");
/*
* Append our option for testing
@@ -258,7 +224,7 @@ CheckForCompilerFeature(
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
(300-chars), 0);
- WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
}
@@ -302,9 +268,7 @@ CheckForCompilerFeature(
return !(strstr(Out.buffer, "D4002") != NULL
|| strstr(Err.buffer, "D4002") != NULL
|| strstr(Out.buffer, "D9002") != NULL
- || strstr(Err.buffer, "D9002") != NULL
- || strstr(Out.buffer, "D2021") != NULL
- || strstr(Err.buffer, "D2021") != NULL);
+ || strstr(Err.buffer, "D9002") != NULL);
}
int
@@ -386,7 +350,7 @@ CheckForLinkerFeature(
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
(300-chars), 0);
- WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
}
@@ -427,9 +391,9 @@ CheckForLinkerFeature(
*/
return !(strstr(Out.buffer, "LNK1117") != NULL ||
- strstr(Err.buffer, "LNK1117") != NULL ||
- strstr(Out.buffer, "LNK4044") != NULL ||
- strstr(Err.buffer, "LNK4044") != NULL);
+ strstr(Err.buffer, "LNK1117") != NULL ||
+ strstr(Out.buffer, "LNK4044") != NULL ||
+ strstr(Err.buffer, "LNK4044") != NULL);
}
DWORD WINAPI
@@ -476,16 +440,18 @@ GrepForDefine(
const char *file,
const char *string)
{
+ FILE *f;
char s1[51], s2[51], s3[51];
- FILE *f = fopen(file, "rt");
+ int r = 0;
+ double d1;
+ f = fopen(file, "rt");
if (f == NULL) {
return 0;
}
do {
- int r = fscanf(f, "%50s", s1);
-
+ r = fscanf(f, "%50s", s1);
if (r == 1 && !strcmp(s1, "#define")) {
/*
* Get next two words.
@@ -501,8 +467,6 @@ GrepForDefine(
*/
if (!strcmp(s2, string)) {
- double d1;
-
fclose(f);
/*
@@ -521,203 +485,3 @@ GrepForDefine(
fclose(f);
return 0;
}
-
-/*
- * GetVersionFromFile --
- * Looks for a match string in a file and then returns the version
- * following the match where a version is anything acceptable to
- * package provide or package ifneeded.
- */
-
-const char *
-GetVersionFromFile(
- const char *filename,
- const char *match)
-{
- size_t cbBuffer = 100;
- static char szBuffer[100];
- char *szResult = NULL;
- FILE *fp = fopen(filename, "rt");
-
- if (fp != NULL) {
- /*
- * Read data until we see our match string.
- */
-
- while (fgets(szBuffer, cbBuffer, fp) != NULL) {
- LPSTR p, q;
-
- p = strstr(szBuffer, match);
- if (p != NULL) {
- /*
- * Skip to first digit.
- */
-
- while (*p && !isdigit(*p)) {
- ++p;
- }
-
- /*
- * Find ending whitespace.
- */
-
- q = p;
- while (*q && (isalnum(*q) || *q == '.')) {
- ++q;
- }
-
- memcpy(szBuffer, p, q - p);
- szBuffer[q-p] = 0;
- szResult = szBuffer;
- break;
- }
- }
- fclose(fp);
- }
- return szResult;
-}
-
-/*
- * List helpers for the SubstituteFile function
- */
-
-typedef struct list_item_t {
- struct list_item_t *nextPtr;
- char * key;
- char * value;
-} list_item_t;
-
-/* insert a list item into the list (list may be null) */
-static list_item_t *
-list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
-{
- list_item_t *itemPtr = malloc(sizeof(list_item_t));
- if (itemPtr) {
- itemPtr->key = strdup(key);
- itemPtr->value = strdup(value);
- itemPtr->nextPtr = NULL;
-
- while(*listPtrPtr) {
- listPtrPtr = &(*listPtrPtr)->nextPtr;
- }
- *listPtrPtr = itemPtr;
- }
- return itemPtr;
-}
-
-static void
-list_free(list_item_t **listPtrPtr)
-{
- list_item_t *tmpPtr, *listPtr = *listPtrPtr;
- while (listPtr) {
- tmpPtr = listPtr;
- listPtr = listPtr->nextPtr;
- free(tmpPtr->key);
- free(tmpPtr->value);
- free(tmpPtr);
- }
-}
-
-/*
- * SubstituteFile --
- * As windows doesn't provide anything useful like sed and it's unreliable
- * to use the tclsh you are building against (consider x-platform builds -
- * eg compiling AMD64 target from IX86) we provide a simple substitution
- * option here to handle autoconf style substitutions.
- * The substitution file is whitespace and line delimited. The file should
- * consist of lines matching the regular expression:
- * \s*\S+\s+\S*$
- *
- * Usage is something like:
- * nmakehlp -S << $** > $@
- * @PACKAGE_NAME@ $(PACKAGE_NAME)
- * @PACKAGE_VERSION@ $(PACKAGE_VERSION)
- * <<
- */
-
-int
-SubstituteFile(
- const char *substitutions,
- const char *filename)
-{
- size_t cbBuffer = 1024;
- static char szBuffer[1024], szCopy[1024];
- char *szResult = NULL;
- list_item_t *substPtr = NULL;
- FILE *fp, *sp;
-
- fp = fopen(filename, "rt");
- if (fp != NULL) {
-
- /*
- * Build a list of substutitions from the first filename
- */
-
- sp = fopen(substitutions, "rt");
- if (sp != NULL) {
- while (fgets(szBuffer, cbBuffer, sp) != NULL) {
- char *ks, *ke, *vs, *ve;
- ks = szBuffer;
- while (ks && *ks && isspace(*ks)) ++ks;
- ke = ks;
- while (ke && *ke && !isspace(*ke)) ++ke;
- vs = ke;
- while (vs && *vs && isspace(*vs)) ++vs;
- ve = vs;
- while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
- *ke = 0, *ve = 0;
- list_insert(&substPtr, ks, vs);
- }
- fclose(sp);
- }
-
- /* debug: dump the list */
-#ifdef _DEBUG
- {
- int n = 0;
- list_item_t *p = NULL;
- for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
- fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
- }
- }
-#endif
-
- /*
- * Run the substitutions over each line of the input
- */
-
- while (fgets(szBuffer, cbBuffer, fp) != NULL) {
- list_item_t *p = NULL;
- for (p = substPtr; p != NULL; p = p->nextPtr) {
- char *m = strstr(szBuffer, p->key);
- if (m) {
- char *cp, *op, *sp;
- cp = szCopy;
- op = szBuffer;
- while (op != m) *cp++ = *op++;
- sp = p->value;
- while (sp && *sp) *cp++ = *sp++;
- op += strlen(p->key);
- while (*op) *cp++ = *op++;
- *cp = 0;
- memcpy(szBuffer, szCopy, sizeof(szCopy));
- }
- }
- printf(szBuffer);
- }
-
- list_free(&substPtr);
- }
- fclose(fp);
- return 0;
-}
-
-/*
- * Local variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * indent-tabs-mode: t
- * tab-width: 8
- * End:
- */
diff --git a/win/rules.vc b/win/rules.vc
index e18dca9..0cc9ffb 100644
--- a/win/rules.vc
+++ b/win/rules.vc
@@ -6,9 +6,9 @@
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
+#
# Copyright (c) 2001-2003 David Gravereaux.
-# Copyright (c) 2003-2007 Patrick Thoyts
+# Copyright (c) 2003-2006 Patrick Thoyts
#------------------------------------------------------------------------------
!ifndef _RULES_VC
@@ -215,7 +215,6 @@ LINKERFLAGS =-ltcg
STATIC_BUILD = 0
TCL_THREADS = 0
DEBUG = 0
-SYMBOLS = 0
PROFILE = 0
MSVCRT = 0
LOIMPACT = 0
@@ -253,12 +252,6 @@ DEBUG = 1
!else
DEBUG = 0
!endif
-!if [nmakehlp -f $(OPTS) "pdbs"]
-!message *** Doing pdbs
-SYMBOLS = 1
-!else
-SYMBOLS = 0
-!endif
!if [nmakehlp -f $(OPTS) "profile"]
!message *** Doing profile
PROFILE = 1
@@ -314,8 +307,11 @@ SUFX = tsgx
!if $(DEBUG)
BUILDDIRTOP = Debug
+DBGX = g
!else
BUILDDIRTOP = Release
+DBGX =
+SUFX = $(SUFX:g=)
!endif
!if "$(MACHINE)" != "IX86"
@@ -325,10 +321,6 @@ BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
!endif
-!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
-SUFX = $(SUFX:g=)
-!endif
-
TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
!if !$(STATIC_BUILD)
@@ -387,14 +379,13 @@ TCL_COMPILE_DEBUG = 0
!endif
!endif
-
#----------------------------------------------------------
# Decode the checks requested.
#----------------------------------------------------------
!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
TCL_NO_DEPRECATED = 0
-WARNINGS = -W3
+FULLWARNINGS = 0
!else
!if [nmakehlp -f $(CHECKS) "nodep"]
!message *** Doing nodep check
@@ -404,16 +395,9 @@ TCL_NO_DEPRECATED = 0
!endif
!if [nmakehlp -f $(CHECKS) "fullwarn"]
!message *** Doing full warnings check
-WARNINGS = -W4
-!if [nmakehlp -l -warn:3]
-LINKERFLAGS = $(LINKERFLAGS) -warn:3
-!endif
+FULLWARNINGS = 1
!else
-WARNINGS = -W3
-!endif
-!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
-!message *** Doing 64bit portability warnings
-WARNINGS = $(WARNINGS) -Wp64
+FULLWARNINGS = 0
!endif
!endif
@@ -421,8 +405,7 @@ WARNINGS = $(WARNINGS) -Wp64
# Set our defines now armed with our options.
#----------------------------------------------------------
-OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
-
+OPTDEFINES =
!if $(TCL_MEM_DEBUG)
OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
!endif
@@ -438,9 +421,6 @@ OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
!if $(STATIC_BUILD)
OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
!endif
-!if $(TCL_NO_DEPRECATED)
-OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
-!endif
!if $(DEBUG)
OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DEBUG
@@ -456,26 +436,16 @@ OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
#----------------------------------------------------------
-# Locate the Tcl headers to build against
+# Get common info used when building extensions.
#----------------------------------------------------------
-!if "$(PROJECT)" == "tcl"
-
-_TCL_H = ..\generic\tcl.h
-
-!else
-
-# If INSTALLDIR set to tcl root dir then reset to the lib dir.
-!if exist("$(_INSTALLDIR)\include\tcl.h")
-_INSTALLDIR=$(_INSTALLDIR)\lib
-!endif
+!if "$(PROJECT)" != "tcl"
!if !defined(TCLDIR)
-!if exist("$(_INSTALLDIR)\..\include\tcl.h")
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+TCLH = "$(_INSTALLDIR)\include\tcl.h"
TCLINSTALL = 1
-_TCLDIR = $(_INSTALLDIR)\..
-_TCL_H = $(_INSTALLDIR)\..\include\tcl.h
-TCLDIR = $(_INSTALLDIR)\..
+_TCLDIR = $(_INSTALLDIR)
!else
MSG=^
Failed to find tcl.h. Set the TCLDIR macro.
@@ -484,181 +454,53 @@ Failed to find tcl.h. Set the TCLDIR macro.
!else
_TCLDIR = $(TCLDIR:/=\)
!if exist("$(_TCLDIR)\include\tcl.h")
+TCLH = "$(_TCLDIR)\include\tcl.h"
TCLINSTALL = 1
-_TCL_H = $(_TCLDIR)\include\tcl.h
!elseif exist("$(_TCLDIR)\generic\tcl.h")
+TCLH = "$(_TCLDIR)\generic\tcl.h"
TCLINSTALL = 0
-_TCL_H = $(_TCLDIR)\generic\tcl.h
!else
MSG =^
Failed to find tcl.h. The TCLDIR macro does not appear correct.
!error $(MSG)
!endif
!endif
-!endif
-
-#--------------------------------------------------------------
-# Extract various version numbers from tcl headers
-# The generated file is then included in the makefile.
-#--------------------------------------------------------------
-
-!if [echo REM = This file is generated from rules.vc > versions.vc]
-!endif
-!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
-!endif
-
-# If building the tcl core then we need additional package versions
-!if "$(PROJECT)" == "tcl"
-!if [echo PKG_HTTP_VER = \>> versions.vc] \
- && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc]
-!endif
-!if [echo PKG_TCLTEST_VER = \>> versions.vc] \
- && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc]
-!endif
-!if [echo PKG_MSGCAT_VER = \>> versions.vc] \
- && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc]
-!endif
-!if [echo PKG_PLATFORM_VER = \>> versions.vc] \
- && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc]
-!endif
-!if [echo PKG_SHELL_VER = \>> versions.vc] \
- && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc]
-!endif
-!if [echo PKG_DDE_VER = \>> versions.vc] \
- && [nmakehlp -V ..\library\dde\pkgIndex.tcl "dde " >> versions.vc]
-!endif
-!if [echo PKG_REG_VER =\>> versions.vc] \
- && [nmakehlp -V ..\library\reg\pkgIndex.tcl registry >> versions.vc]
-!endif
-!endif
-
-!include versions.vc
-#--------------------------------------------------------------
-# Setup tcl version dependent stuff headers
-#--------------------------------------------------------------
-
-!if "$(PROJECT)" != "tcl"
+### TODO: add a command to nmakehlp.c to grep for Tcl's version from tcl.h.
+### Because nmake can't return a string, we'll need to play games with return
+### codes. It might look something like this:
+#!if [nmakehlp -g $(TCL.H)] == 81
+#TCL_DOTVERSION = 8.1
+#!elseif [nmakehlp -g $(TCL.H)] == 82
+#TCL_DOTVERSION = 8.2
+#...
+#!endif
-TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
-
-!if $(TCL_VERSION) < 81
-TCL_DOES_STUBS = 0
-!else
-TCL_DOES_STUBS = 1
-!endif
+TCL_DOTVERSION = 8.4
+TCL_VERSION = $(TCL_DOTVERSION:.=)
!if $(TCLINSTALL)
-TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
-!endif
-TCLSTUBLIB = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
-TCLIMPLIB = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
-TCL_LIBRARY = $(_TCLDIR)\lib
-TCLREGLIB = "$(_TCLDIR)\lib\tclreg12$(SUFX:t=).lib"
-TCLDDELIB = "$(_TCLDIR)\lib\tcldde13$(SUFX:t=).lib"
+TCLSH = "$(_INSTALLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
+TCLSTUBLIB = "$(_INSTALLDIR)\lib\tclstub$(TCL_VERSION).lib"
+TCLIMPLIB = "$(_INSTALLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
+TCL_LIBRARY = $(_INSTALLDIR)\lib
+TCLREGLIB = "$(_INSTALLDIR)\lib\tclreg11$(SUFX:t=).lib"
+TCLDDELIB = "$(_INSTALLDIR)\lib\tcldde12$(SUFX:t=).lib"
COFFBASE = \must\have\tcl\sources\to\build\this\target
TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
-TCL_INCLUDES = -I"$(_TCLDIR)\include"
!else
TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
-!endif
TCLSTUBLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
TCLIMPLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
TCL_LIBRARY = $(_TCLDIR)\library
-TCLREGLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg12$(SUFX:t=).lib"
-TCLDDELIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde13$(SUFX:t=).lib"
+TCLREGLIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg11$(SUFX:t=).lib"
+TCLDDELIB = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde12$(SUFX:t=).lib"
COFFBASE = "$(_TCLDIR)\win\coffbase.txt"
TCLTOOLSDIR = $(_TCLDIR)\tools
-TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
-!endif
-
-!endif
-
-#-------------------------------------------------------------------------
-# Locate the Tk headers to build against
-#-------------------------------------------------------------------------
-
-!if "$(PROJECT)" == "tk"
-_TK_H = ..\generic\tk.h
-_INSTALLDIR = $(_INSTALLDIR)\..
-!endif
-
-!ifdef PROJECT_REQUIRES_TK
-!if !defined(TKDIR)
-!if exist("$(_INSTALLDIR)\..\include\tk.h")
-TKINSTALL = 1
-_TKDIR = $(_INSTALLDIR)\..
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
-!elseif exist("$(_TCLDIR)\include\tk.h")
-TKINSTALL = 1
-_TKDIR = $(_TCLDIR)
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
-!endif
-!else
-_TKDIR = $(TKDIR:/=\)
-!if exist("$(_TKDIR)\include\tk.h")
-TKINSTALL = 1
-_TK_H = $(_TKDIR)\include\tk.h
-!elseif exist("$(_TKDIR)\generic\tk.h")
-TKINSTALL = 0
-_TK_H = $(_TKDIR)\generic\tk.h
-!else
-MSG =^
-Failed to find tk.h. The TKDIR macro does not appear correct.
-!error $(MSG)
-!endif
!endif
-!endif
-
-#-------------------------------------------------------------------------
-# Extract Tk version numbers
-#-------------------------------------------------------------------------
-!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk"
-
-!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
-!endif
-
-!include versions.vc
-
-TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
-
-!if "$(PROJECT)" != "tk"
-!if $(TKINSTALL)
-WISH = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
-TKSTUBLIB = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
-TKIMPLIB = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
-TK_INCLUDES = -I"$(_TKDIR)\include"
-!else
-WISH = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
-TKSTUBLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
-TKIMPLIB = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
-TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
-!endif
!endif
-!endif
#----------------------------------------------------------
# Display stats being used.
@@ -669,8 +511,7 @@ TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
!message *** Suffix for binaries will be '$(SUFX)'
!message *** Optional defines are '$(OPTDEFINES)'
!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
-!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
+!message *** Compiler options '$(OPTIMIZATIONS) $(DEBUGFLAGS)'
!message *** Link options '$(LINKERFLAGS)'
!endif
diff --git a/win/stub16.c b/win/stub16.c
index 70fc051..aa42c58 100644
--- a/win/stub16.c
+++ b/win/stub16.c
@@ -1,13 +1,13 @@
-/*
- * stub16.c
+/*
+ * stub16.c
*
* A helper program used for running 16-bit DOS applications under
* Windows 95.
*
* Copyright (c) 1996 by Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#define STRICT
@@ -16,31 +16,32 @@
#include <stdio.h>
static HANDLE CreateTempFile(void);
-
+
/*
*---------------------------------------------------------------------------
*
* main
*
- * Entry point for the 32-bit console mode app used by Windows 95 to help
- * run the 16-bit program specified on the command line.
- *
- * 1. EOF on a pipe that connects a detached 16-bit process and a 32-bit
- * process is never seen. So, this process runs the 16-bit process
- * _attached_, and then it is run detached from the calling 32-bit
- * process.
+ * Entry point for the 32-bit console mode app used by Windows 95 to
+ * help run the 16-bit program specified on the command line.
*
- * 2. If a 16-bit process blocks reading from or writing to a pipe, it
- * never wakes up, and eventually brings the whole system down with it if
- * you try to kill the process. This app simulates pipes. If any of the
- * stdio handles is a pipe, this program accumulates information into
- * temp files and forwards it to or from the DOS application as
- * appropriate. This means that this program must receive EOF from a
- * stdin pipe before it will actually start the DOS app, and the DOS app
- * must finish generating stdout or stderr before the data will be sent
- * to the next stage of the pipe. If the stdio handles are not pipes, no
- * accumulation occurs and the data is passed straight through to and
- * from the DOS application.
+ * 1. EOF on a pipe that connects a detached 16-bit process and a
+ * 32-bit process is never seen. So, this process runs the 16-bit
+ * process _attached_, and then it is run detached from the calling
+ * 32-bit process.
+ *
+ * 2. If a 16-bit process blocks reading from or writing to a pipe,
+ * it never wakes up, and eventually brings the whole system down
+ * with it if you try to kill the process. This app simulates
+ * pipes. If any of the stdio handles is a pipe, this program
+ * accumulates information into temp files and forwards it to or
+ * from the DOS application as appropriate. This means that this
+ * program must receive EOF from a stdin pipe before it will actually
+ * start the DOS app, and the DOS app must finish generating stdout
+ * or stderr before the data will be sent to the next stage of the
+ * pipe. If the stdio handles are not pipes, no accumulation occurs
+ * and the data is passed straight through to and from the DOS
+ * application.
*
* Results:
* None.
@@ -53,7 +54,7 @@ static HANDLE CreateTempFile(void);
*/
int
-main(void)
+main()
{
DWORD dwRead, dwWrite;
char *cmdLine;
@@ -71,10 +72,10 @@ main(void)
/*
* Don't get command line from argc, argv, because the command line
- * tokenizer will have stripped off all the escape sequences needed for
- * quotes and backslashes, and then we'd have to put them all back in
- * again. Get the raw command line and parse off what we want ourselves.
- * The command line should be of the form:
+ * tokenizer will have stripped off all the escape sequences needed
+ * for quotes and backslashes, and then we'd have to put them all
+ * back in again. Get the raw command line and parse off what we
+ * want ourselves. The command line should be of the form:
*
* stub16.exe program arg1 arg2 ...
*/
@@ -122,7 +123,7 @@ main(void)
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
- if (CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si,
+ if (CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si,
&pi) == FALSE) {
goto cleanup;
}
@@ -156,7 +157,7 @@ main(void)
}
}
- cleanup:
+cleanup:
if (hFileInput != INVALID_HANDLE_VALUE) {
CloseHandle(hFileInput);
}
@@ -174,7 +175,7 @@ main(void)
}
static HANDLE
-CreateTempFile(void)
+CreateTempFile()
{
char name[MAX_PATH];
SECURITY_ATTRIBUTES sa;
@@ -189,7 +190,7 @@ CreateTempFile(void)
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
- return CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, &sa,
+ return CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, &sa,
CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
NULL);
}
diff --git a/win/tcl.dsp b/win/tcl.dsp
index b3de0ff..2d99988 100644
--- a/win/tcl.dsp
+++ b/win/tcl.dsp
@@ -36,16 +36,16 @@ CFG=tcl - Win32 Debug Static
# PROP BASE Intermediate_Dir "Release\tcl_Dynamic"
# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=none MSVCDIR=IDE"
# PROP BASE Rebuild_Opt "-a"
-# PROP BASE Target_File "Release\tclsh85.exe"
+# PROP BASE Target_File "Release\tclsh84.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release\tcl_Dynamic"
-# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=threads MSVCDIR=IDE"
-# PROP Rebuild_Opt "clean release"
-# PROP Target_File "Release\tclsh85t.exe"
+# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=none MSVCDIR=IDE"
+# PROP Rebuild_Opt "-a"
+# PROP Target_File "Release\tclsh84.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -57,16 +57,16 @@ CFG=tcl - Win32 Debug Static
# PROP BASE Intermediate_Dir "Debug\tcl_Dynamic"
# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols MSVCDIR=IDE"
# PROP BASE Rebuild_Opt "-a"
-# PROP BASE Target_File "Debug\tclsh85g.exe"
+# PROP BASE Target_File "Debug\tclsh84d.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug\tcl_Dynamic"
-# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=threads,symbols MSVCDIR=IDE"
-# PROP Rebuild_Opt "clean release"
-# PROP Target_File "Debug\tclsh85tg.exe"
+# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols MSVCDIR=IDE"
+# PROP Rebuild_Opt "-a"
+# PROP Target_File "Debug\tclsh84d.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -78,7 +78,7 @@ CFG=tcl - Win32 Debug Static
# PROP BASE Intermediate_Dir "Debug\tcl_Static"
# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols,static MSVCDIR=IDE"
# PROP BASE Rebuild_Opt "-a"
-# PROP BASE Target_File "Debug\tclsh85sg.exe"
+# PROP BASE Target_File "Debug\tclsh84d.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
@@ -87,7 +87,7 @@ CFG=tcl - Win32 Debug Static
# PROP Intermediate_Dir "Debug\tcl_Static"
# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols,static MSVCDIR=IDE"
# PROP Rebuild_Opt "-a"
-# PROP Target_File "Debug\tclsh85sg.exe"
+# PROP Target_File "Debug\tclsh84sd.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -99,7 +99,7 @@ CFG=tcl - Win32 Debug Static
# PROP BASE Intermediate_Dir "Release\tcl_Static"
# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=static MSVCDIR=IDE"
# PROP BASE Rebuild_Opt "-a"
-# PROP BASE Target_File "Release\tclsh85s.exe"
+# PROP BASE Target_File "Release\tclsh84.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
@@ -108,7 +108,7 @@ CFG=tcl - Win32 Debug Static
# PROP Intermediate_Dir "Release\tcl_Static"
# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=static MSVCDIR=IDE"
# PROP Rebuild_Opt "-a"
-# PROP Target_File "Release\tclsh85s.exe"
+# PROP Target_File "Release\tclsh84s.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -180,6 +180,10 @@ SOURCE=..\compat\stdlib.h
# End Source File
# Begin Source File
+SOURCE=..\compat\strftime.c
+# End Source File
+# Begin Source File
+
SOURCE=..\compat\string.h
# End Source File
# Begin Source File
@@ -208,6 +212,10 @@ SOURCE=..\compat\tclErrno.h
# End Source File
# Begin Source File
+SOURCE=..\compat\tmpnam.c
+# End Source File
+# Begin Source File
+
SOURCE=..\compat\unistd.h
# End Source File
# Begin Source File
@@ -644,6 +652,10 @@ SOURCE=..\doc\lsort.n
# End Source File
# Begin Source File
+SOURCE=..\doc\Macintosh.3
+# End Source File
+# Begin Source File
+
SOURCE=..\doc\man.macros
# End Source File
# Begin Source File
@@ -768,6 +780,10 @@ SOURCE=..\doc\rename.n
# End Source File
# Begin Source File
+SOURCE=..\doc\resource.n
+# End Source File
+# Begin Source File
+
SOURCE=..\doc\return.n
# End Source File
# Begin Source File
@@ -1152,6 +1168,10 @@ SOURCE=..\generic\tclIndexObj.c
# End Source File
# Begin Source File
+SOURCE=..\generic\tclInitScript.h
+# End Source File
+# Begin Source File
+
SOURCE=..\generic\tclInt.decls
# End Source File
# Begin Source File
@@ -1220,6 +1240,10 @@ SOURCE=..\generic\tclMain.c
# End Source File
# Begin Source File
+SOURCE=..\generic\tclMath.h
+# End Source File
+# Begin Source File
+
SOURCE=..\generic\tclNamesp.c
# End Source File
# Begin Source File
@@ -1240,6 +1264,10 @@ SOURCE=..\generic\tclParse.c
# End Source File
# Begin Source File
+SOURCE=..\generic\tclParseExpr.c
+# End Source File
+# Begin Source File
+
SOURCE=..\generic\tclPipe.c
# End Source File
# Begin Source File
@@ -1524,6 +1552,10 @@ SOURCE=.\tclWinLoad.c
# End Source File
# Begin Source File
+SOURCE=.\tclWinMtherr.c
+# End Source File
+# Begin Source File
+
SOURCE=.\tclWinNotify.c
# End Source File
# Begin Source File
diff --git a/win/tcl.hpj.in b/win/tcl.hpj.in
index 0d01f35..2a8c94a 100644
--- a/win/tcl.hpj.in
+++ b/win/tcl.hpj.in
@@ -5,9 +5,9 @@ HCW=0
LCID=0x409 0x0 0x0 ;English (United States)
REPORT=Yes
TITLE=Tcl/Tk Reference Manual
-CNT=tcl85.cnt
+CNT=tcl84.cnt
COPYRIGHT=Copyright © 2000 Ajuba Solutions
-HLP=tcl85.hlp
+HLP=tcl84.hlp
[FILES]
tcl.rtf
diff --git a/win/tcl.m4 b/win/tcl.m4
index 83a4ea3..b6241dc 100644
--- a/win/tcl.m4
+++ b/win/tcl.m4
@@ -20,15 +20,15 @@
AC_DEFUN([SC_PATH_TCLCONFIG], [
AC_MSG_CHECKING([the location of tclConfig.sh])
- if test -d ../../tcl8.5$1/win; then
- TCL_BIN_DIR_DEFAULT=../../tcl8.5$1/win
- elif test -d ../../tcl8.5/win; then
- TCL_BIN_DIR_DEFAULT=../../tcl8.5/win
+ if test -d ../../tcl8.4$1/win; then
+ TCL_BIN_DIR_DEFAULT=../../tcl8.4$1/win
+ elif test -d ../../tcl8.4/win; then
+ TCL_BIN_DIR_DEFAULT=../../tcl8.4/win
else
TCL_BIN_DIR_DEFAULT=../../tcl/win
fi
- AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.5 binaries from DIR],
+ AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.4 binaries from DIR],
TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DIR_DEFAULT; pwd`)
if test ! -d $TCL_BIN_DIR; then
AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist)
@@ -60,15 +60,15 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [
AC_DEFUN([SC_PATH_TKCONFIG], [
AC_MSG_CHECKING([the location of tkConfig.sh])
- if test -d ../../tk8.5$1/win; then
- TK_BIN_DIR_DEFAULT=../../tk8.5$1/win
- elif test -d ../../tk8.5/win; then
- TK_BIN_DIR_DEFAULT=../../tk8.5/win
+ if test -d ../../tk8.4$1/win; then
+ TK_BIN_DIR_DEFAULT=../../tk8.4$1/win
+ elif test -d ../../tk8.4/win; then
+ TK_BIN_DIR_DEFAULT=../../tk8.4/win
else
TK_BIN_DIR_DEFAULT=../../tk/win
fi
- AC_ARG_WITH(tk, [ --with-tk=DIR use Tk 8.5 binaries from DIR],
+ AC_ARG_WITH(tk, [ --with-tk=DIR use Tk 8.4 binaries from DIR],
TK_BIN_DIR=$withval, TK_BIN_DIR=`cd $TK_BIN_DIR_DEFAULT; pwd`)
if test ! -d $TK_BIN_DIR; then
AC_MSG_ERROR(Tk directory $TK_BIN_DIR does not exist)
@@ -301,8 +301,6 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
DBGX=""
AC_MSG_RESULT([no])
-
- AC_DEFINE(TCL_CFG_OPTIMIZED)
else
CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
@@ -313,7 +311,6 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
fi
AC_SUBST(CFLAGS_DEFAULT)
AC_SUBST(LDFLAGS_DEFAULT)
- AC_DEFINE(TCL_CFG_DEBUG)
if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
AC_DEFINE(TCL_MEM_DEBUG)
@@ -448,9 +445,8 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
if test "${GCC}" = "yes" ; then
SHLIB_LD=""
SHLIB_LD_LIBS=""
- LIBS="-lws2_32"
- # mingw needs to link ole32 and oleaut32 for [send], but MSVC doesn't
- LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32"
+ LIBS=""
+ LIBS_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32"
STLIB_LD='${AR} cr'
RC_OUT=-o
RC_TYPE=
@@ -523,7 +519,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
CFLAGS_DEBUG=-g
CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- CFLAGS_WARNING="-Wall"
+ CFLAGS_WARNING="-Wall -fno-strict-aliasing"
LDFLAGS_DEBUG=
LDFLAGS_OPTIMIZE=
@@ -628,17 +624,13 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
fi
fi
- LIBS="user32.lib advapi32.lib ws2_32.lib"
+ LIBS="user32.lib advapi32.lib"
if test "$do64bit" != "no" ; then
# The space-based-path will work for the Makefile, but will
# not work if AC_TRY_COMPILE is called. TEA has the
# TEA_PATH_NOSPACE to avoid this issue.
- # Check if _WIN64 is already recognized, and if so we don't
- # need to modify CC.
- AC_CHECK_DECL([_WIN64], [],
- [CC="\"${PATH64}/cl.exe\" -I\"${MSSDK}/Include\" \
- -I\"${MSSDK}/Include/crt\" \
- -I\"${MSSDK}/Include/crt/sys\""])
+ CC="\"${PATH64}/cl.exe\" -I\"${MSSDK}/Include\" \
+ -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
RC="\"${MSSDK}/bin/rc.exe\""
CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d"
# Do not use -O2 for Win64 - this has proved buggy in code gen.
@@ -749,7 +741,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
LIBS="$LIBS \"\${CELIB_DIR}/wince-${ARCH}-pocket-wce300-release/celib.lib\""
LIBS_GUI="commctrl.lib commdlg.lib"
else
- LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib"
+ LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib"
fi
SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
@@ -788,10 +780,6 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
fi
fi
- if test "$do64bit" != "no" ; then
- AC_DEFINE(TCL_CFG_DO64BIT)
- fi
-
# DL_LIBS is empty, but then we match the Unix version
AC_SUBST(DL_LIBS)
AC_SUBST(CFLAGS_DEBUG)
@@ -817,13 +805,13 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
#------------------------------------------------------------------------
AC_DEFUN([SC_WITH_TCL], [
- if test -d ../../tcl8.5$1/win; then
- TCL_BIN_DEFAULT=../../tcl8.5$1/win
+ if test -d ../../tcl8.4$1/win; then
+ TCL_BIN_DEFAULT=../../tcl8.4$1/win
else
- TCL_BIN_DEFAULT=../../tcl8.5/win
+ TCL_BIN_DEFAULT=../../tcl8.4/win
fi
- AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.5 binaries from DIR],
+ AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.4 binaries from DIR],
TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd $TCL_BIN_DEFAULT; pwd`)
if test ! -d $TCL_BIN_DIR; then
AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR does not exist)
@@ -910,34 +898,6 @@ AC_DEFUN([SC_BUILD_TCLSH], [
])
#--------------------------------------------------------------------
-# SC_TCL_CFG_ENCODING TIP #59
-#
-# Declare the encoding to use for embedded configuration information.
-#
-# Arguments:
-# None.
-#
-# Results:
-# Might append to the following vars:
-# DEFS (implicit)
-#
-# Will define the following vars:
-# TCL_CFGVAL_ENCODING
-#
-#--------------------------------------------------------------------
-
-AC_DEFUN([SC_TCL_CFG_ENCODING], [
- AC_ARG_WITH(encoding, [ --with-encoding encoding for configuration values], with_tcencoding=${withval})
-
- if test x"${with_tcencoding}" != x ; then
- AC_DEFINE_UNQUOTED(TCL_CFGVAL_ENCODING,"${with_tcencoding}")
- else
- # Default encoding on windows is not "iso8859-1"
- AC_DEFINE(TCL_CFGVAL_ENCODING,"cp1252")
- fi
-])
-
-#--------------------------------------------------------------------
# SC_EMBED_MANIFEST
#
# Figure out if we can embed the manifest where necessary
@@ -955,8 +915,7 @@ AC_DEFUN([SC_TCL_CFG_ENCODING], [
AC_DEFUN([SC_EMBED_MANIFEST], [
AC_MSG_CHECKING(whether to embed manifest)
AC_ARG_ENABLE(embedded-manifest,
- AC_HELP_STRING([--enable-embedded-manifest],
- [embed manifest if possible (default: yes)]),
+ [ --enable-embedded-manifest embed manifest if possible (default: yes)],
[embed_ok=$enableval], [embed_ok=yes])
VC_MANIFEST_EMBED_DLL=
@@ -973,11 +932,8 @@ print("manifest needed")
# Could do a CHECK_PROG for mt, but should always be with MSVC8+
# Could add 'if test -f' check, but manifest should be created
# in this compiler case
- # Add in a manifest argument that may be specified
- # XXX Needs improvement so that the test for existence accounts
- # XXX for a provided (known) manifest
- VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest $1 -outputresource:\[$]@\;2 ; fi"
- VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest $1 -outputresource:\[$]@\;1 ; fi"
+ VC_MANIFEST_EMBED_DLL="mt.exe -nologo -manifest \[$]@.manifest $1 -outputresource:\[$]@\;2"
+ VC_MANIFEST_EMBED_EXE="mt.exe -nologo -manifest \[$]@.manifest $1 -outputresource:\[$]@\;1"
result=yes
if test "x$1" != x ; then
result="yes ($1)"
diff --git a/win/tcl.rc b/win/tcl.rc
index d88ca0a..0cba28b 100644
--- a/win/tcl.rc
+++ b/win/tcl.rc
@@ -7,14 +7,14 @@
//
// build-up the name suffix that defines the type of build this is.
//
-#if TCL_THREADS
+#ifdef TCL_THREADS
#define SUFFIX_THREADS "t"
#else
#define SUFFIX_THREADS ""
#endif
-#if DEBUG && !UNCHECKED
-#define SUFFIX_DEBUG "g"
+#ifdef DEBUG
+#define SUFFIX_DEBUG "d"
#else
#define SUFFIX_DEBUG ""
#endif
@@ -42,7 +42,7 @@ BEGIN
BLOCK "040904b0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */
BEGIN
VALUE "FileDescription", "Tcl DLL\0"
- VALUE "OriginalFilename", "tcl" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) SUFFIX ".dll\0"
+ VALUE "OriginalFilename", "tcl" STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) SUFFIX ".dll\0"
VALUE "CompanyName", "ActiveState Corporation\0"
VALUE "FileVersion", TCL_PATCH_LEVEL
VALUE "LegalCopyright", "Copyright \251 2001 by ActiveState Corporation, et al\0"
diff --git a/win/tclAppInit.c b/win/tclAppInit.c
index 289a3c3..4578ea8 100644
--- a/win/tclAppInit.c
+++ b/win/tclAppInit.c
@@ -2,14 +2,14 @@
* tclAppInit.c --
*
* Provides a default version of the main program and Tcl_AppInit
- * function for Tcl applications (without Tk). Note that this program
- * must be built in Win32 console mode to work properly.
+ * procedure for Tcl applications (without Tk). Note that this
+ * program must be built in Win32 console mode to work properly.
*
* Copyright (c) 1996-1997 by Sun Microsystems, Inc.
* Copyright (c) 1998-1999 by Scriptics Corporation.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tcl.h"
@@ -17,15 +17,24 @@
#include <locale.h>
#ifdef TCL_TEST
-extern Tcl_PackageInitProc Procbodytest_Init;
-extern Tcl_PackageInitProc Procbodytest_SafeInit;
-extern Tcl_PackageInitProc Tcltest_Init;
-extern Tcl_PackageInitProc TclObjTest_Init;
+extern int Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+extern int Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
+extern int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+extern int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+#ifdef TCL_THREADS
+extern int TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp));
+#endif
#endif /* TCL_TEST */
-#if defined(__GNUC__)
-static void setargv(int *argcPtr, char ***argvPtr);
-#endif /* __GNUC__ */
+static void setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));
+static BOOL __stdcall sigHandler (DWORD fdwCtrlType);
+static Tcl_AsyncProc asyncExit;
+static void AppInitExitHandler(ClientData clientData);
+
+static char ** argvSave = NULL;
+static Tcl_AsyncHandler exitToken = NULL;
+static DWORD exitErrorCode = 0;
+
/*
*----------------------------------------------------------------------
@@ -35,8 +44,8 @@ static void setargv(int *argcPtr, char ***argvPtr);
* This is the main program for the application.
*
* Results:
- * None: Tcl_Main never returns here, so this function never returns
- * either.
+ * None: Tcl_Main never returns here, so this procedure never
+ * returns either.
*
* Side effects:
* Whatever the application does.
@@ -45,15 +54,15 @@ static void setargv(int *argcPtr, char ***argvPtr);
*/
int
-main(
- int argc,
- char *argv[])
+main(argc, argv)
+ int argc; /* Number of command-line arguments. */
+ char **argv; /* Values of command-line arguments. */
{
/*
- * The following #if block allows you to change the AppInit function by
- * using a #define of TCL_LOCAL_APPINIT instead of rewriting this entire
- * file. The #if checks for that #define and uses Tcl_AppInit if it
- * doesn't exist.
+ * The following #if block allows you to change the AppInit
+ * function by using a #define of TCL_LOCAL_APPINIT instead
+ * of rewriting this entire file. The #if checks for that
+ * #define and uses Tcl_AppInit if it doesn't exist.
*/
#ifndef TCL_LOCAL_APPINIT
@@ -71,23 +80,29 @@ main(
extern int TCL_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
#endif
+ char buffer[MAX_PATH +1];
char *p;
-
/*
- * Set up the default locale to be standard "C" locale so parsing is
- * performed correctly.
+ * Set up the default locale to be standard "C" locale so parsing
+ * is performed correctly.
*/
-#if defined(__GNUC__)
- setargv( &argc, &argv );
-#endif
setlocale(LC_ALL, "C");
+ setargv(&argc, &argv);
/*
- * Forward slashes substituted for backslashes.
+ * Save this for later, so we can free it.
*/
+ argvSave = argv;
- for (p = argv[0]; *p != '\0'; p++) {
+ /*
+ * Replace argv[0] with full pathname of executable, and forward
+ * slashes substituted for backslashes.
+ */
+
+ GetModuleFileName(NULL, buffer, sizeof(buffer));
+ argv[0] = buffer;
+ for (p = buffer; *p != '\0'; p++) {
if (*p == '\\') {
*p = '/';
}
@@ -101,19 +116,20 @@ main(
return 0; /* Needed only to prevent compiler warning. */
}
+
/*
*----------------------------------------------------------------------
*
* Tcl_AppInit --
*
- * This function performs application-specific initialization. Most
- * applications, especially those that incorporate additional packages,
- * will have their own version of this function.
+ * This procedure performs application-specific initialization.
+ * Most applications, especially those that incorporate additional
+ * packages, will have their own version of this procedure.
*
* Results:
- * Returns a standard Tcl completion code, and leaves an error message in
- * the interp's result if an error occurs.
+ * Returns a standard Tcl completion code, and leaves an error
+ * message in the interp's result if an error occurs.
*
* Side effects:
* Depends on the startup script.
@@ -122,33 +138,50 @@ main(
*/
int
-Tcl_AppInit(
- Tcl_Interp *interp) /* Interpreter for application. */
+Tcl_AppInit(interp)
+ Tcl_Interp *interp; /* Interpreter for application. */
{
if (Tcl_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
+ /*
+ * Install a signal handler to the win32 console tclsh is running in.
+ */
+ SetConsoleCtrlHandler(sigHandler, TRUE);
+ exitToken = Tcl_AsyncCreate(asyncExit, NULL);
+
+ /*
+ * This exit handler will be used to free the
+ * resources allocated in this file.
+ */
+ Tcl_CreateExitHandler(AppInitExitHandler, NULL);
+
#ifdef TCL_TEST
if (Tcltest_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
- Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, NULL);
+ Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
+ (Tcl_PackageInitProc *) NULL);
if (TclObjTest_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
+#ifdef TCL_THREADS
+ if (TclThread_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+#endif
if (Procbodytest_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init,
- Procbodytest_SafeInit);
+ Procbodytest_SafeInit);
#endif /* TCL_TEST */
-#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
+#if defined(STATIC_BUILD) && defined(TCL_USE_STATIC_PACKAGES)
{
extern Tcl_PackageInitProc Registry_Init;
extern Tcl_PackageInitProc Dde_Init;
- extern Tcl_PackageInitProc Dde_SafeInit;
if (Registry_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
@@ -158,13 +191,13 @@ Tcl_AppInit(
if (Dde_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
- Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit);
+ Tcl_StaticPackage(interp, "dde", Dde_Init, NULL);
}
#endif
/*
- * Call the init functions for included packages. Each call should look
- * like this:
+ * Call the init procedures for included packages. Each call should
+ * look like this:
*
* if (Mod_Init(interp) == TCL_ERROR) {
* return TCL_ERROR;
@@ -174,15 +207,15 @@ Tcl_AppInit(
*/
/*
- * Call Tcl_CreateCommand for application-specific commands, if they
- * weren't already created by the init functions called above.
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
*/
/*
- * Specify a user-specific startup file to invoke if the application is
- * run interactively. Typically the startup file is "~/.apprc" where "app"
- * is the name of the application. If this line is deleted then no
- * user-specific startup file will be run under any conditions.
+ * Specify a user-specific startup file to invoke if the application
+ * is run interactively. Typically the startup file is "~/.apprc"
+ * where "app" is the name of the application. If this line is deleted
+ * then no user-specific startup file will be run under any conditions.
*/
Tcl_SetVar(interp, "tcl_rcFileName", "~/tclshrc.tcl", TCL_GLOBAL_ONLY);
@@ -190,14 +223,50 @@ Tcl_AppInit(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * AppInitExitHandler --
+ *
+ * This function is called to cleanup the app init resources before
+ * Tcl is unloaded.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Frees the saved argv and deletes the async exit handler.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AppInitExitHandler(
+ ClientData clientData)
+{
+ if (argvSave != NULL) {
+ ckfree((char *)argvSave);
+ argvSave = NULL;
+ }
+
+ if (exitToken != NULL) {
+ /*
+ * This should be safe to do even if we
+ * are in an async exit right now.
+ */
+ Tcl_AsyncDelete(exitToken);
+ exitToken = NULL;
+ }
+}
+
+/*
*-------------------------------------------------------------------------
*
* setargv --
*
- * Parse the Windows command line string into argc/argv. Done here
- * because we don't trust the builtin argument parser in crt0. Windows
- * applications are responsible for breaking their command line into
- * arguments.
+ * Parse the Windows command line string into argc/argv. Done here
+ * because we don't trust the builtin argument parser in crt0.
+ * Windows applications are responsible for breaking their command
+ * line into arguments.
*
* 2N backslashes + quote -> N backslashes + begin quoted string
* 2N + 1 backslashes + quote -> literal
@@ -207,8 +276,8 @@ Tcl_AppInit(
* quote -> begin quoted string
*
* Results:
- * Fills argcPtr with the number of arguments and argvPtr with the array
- * of arguments.
+ * Fills argcPtr with the number of arguments and argvPtr with the
+ * array of arguments.
*
* Side effects:
* Memory allocated.
@@ -216,11 +285,10 @@ Tcl_AppInit(
*--------------------------------------------------------------------------
*/
-#if defined(__GNUC__)
static void
-setargv(
- int *argcPtr, /* Filled with number of argument strings. */
- char ***argvPtr) /* Filled with argument strings (malloc'd). */
+setargv(argcPtr, argvPtr)
+ int *argcPtr; /* Filled with number of argument strings. */
+ char ***argvPtr; /* Filled with argument strings (malloc'd). */
{
char *cmdLine, *p, *arg, *argSpace;
char **argv;
@@ -229,8 +297,8 @@ setargv(
cmdLine = GetCommandLine(); /* INTL: BUG */
/*
- * Precompute an overly pessimistic guess at the number of arguments in
- * the command line by counting non-space spans.
+ * Precompute an overly pessimistic guess at the number of arguments
+ * in the command line by counting non-space spans.
*/
size = 2;
@@ -278,18 +346,18 @@ setargv(
} else {
inquote = !inquote;
}
- }
- slashes >>= 1;
- }
+ }
+ slashes >>= 1;
+ }
- while (slashes) {
+ while (slashes) {
*arg = '\\';
arg++;
slashes--;
}
- if ((*p == '\0') || (!inquote &&
- ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
+ if ((*p == '\0')
+ || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
break;
}
if (copy != 0) {
@@ -297,7 +365,7 @@ setargv(
arg++;
}
p++;
- }
+ }
*arg = '\0';
argSpace = arg + 1;
}
@@ -306,12 +374,80 @@ setargv(
*argcPtr = argc;
*argvPtr = argv;
}
-#endif /* __GNUC__ */
/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
+ *----------------------------------------------------------------------
+ *
+ * asyncExit --
+ *
+ * The AsyncProc for the exitToken.
+ *
+ * Results:
+ * doesn't actually return.
+ *
+ * Side effects:
+ * tclsh cleanly exits.
+ *
+ *----------------------------------------------------------------------
*/
+
+int
+asyncExit (ClientData clientData, Tcl_Interp *interp, int code)
+{
+ Tcl_Exit((int)exitErrorCode);
+
+ /* NOTREACHED */
+ return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * sigHandler --
+ *
+ * Signal handler for the Win32 OS. Catches Ctrl+C, Ctrl+Break and
+ * other exits. This is needed so tclsh can do it's real clean-up
+ * and not an unclean crash terminate.
+ *
+ * Results:
+ * TRUE.
+ *
+ * Side effects:
+ * Effects the way the app exits from a signal. This is an
+ * operating system supplied thread and unsafe to call ANY
+ * Tcl commands except for Tcl_AsyncMark.
+ *
+ *----------------------------------------------------------------------
+ */
+
+BOOL __stdcall
+sigHandler(DWORD fdwCtrlType)
+{
+ HANDLE hStdIn;
+
+ if (!exitToken) {
+ /* Async token must have been destroyed, punt gracefully. */
+ return FALSE;
+ }
+
+ /*
+ * If Tcl is currently executing some bytecode or in the eventloop,
+ * this will cause Tcl to enter asyncExit at the next command
+ * boundry.
+ */
+ exitErrorCode = fdwCtrlType;
+ Tcl_AsyncMark(exitToken);
+
+ /*
+ * This will cause Tcl_Gets in Tcl_Main() to drop-out with an <EOF>
+ * should it be blocked on input and our Tcl_AsyncMark didn't grab
+ * the attention of the interpreter.
+ */
+ hStdIn = GetStdHandle(STD_INPUT_HANDLE);
+ if (hStdIn) {
+ CloseHandle(hStdIn);
+ }
+
+ /* indicate to the OS not to call the default terminator */
+ return TRUE;
+}
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c
index 6c863b9..ba3af7c 100644
--- a/win/tclWin32Dll.c
+++ b/win/tclWin32Dll.c
@@ -1,31 +1,20 @@
-/*
+/*
* tclWin32Dll.c --
*
- * This file contains the DLL entry point and other low-level bit bashing
- * code that needs inline assembly.
+ * This file contains the DLL entry point.
*
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 Scriptics Corporation.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclWinInt.h"
-#ifndef TCL_NO_STACK_CHECK
-/*
- * The following functions implement stack depth checking
- */
-typedef struct ThreadSpecificData {
- int *stackBound; /* The current stack boundary */
-} ThreadSpecificData;
-static Tcl_ThreadDataKey dataKey;
-#endif /* TCL_NO_STACK_CHECK */
-
/*
- * The following data structures are used when loading the thunking library
- * for execing child processes under Win32s.
+ * The following data structures are used when loading the thunking
+ * library for execing child processes under Win32s.
*/
typedef DWORD (WINAPI UT32PROC)(LPVOID lpBuff, DWORD dwUserDefined,
@@ -37,38 +26,41 @@ typedef BOOL (WINAPI UTREGISTER)(HANDLE hModule, LPCSTR SixteenBitDLL,
typedef VOID (WINAPI UTUNREGISTER)(HANDLE hModule);
-/*
- * The following variables keep track of information about this DLL on a
- * per-instance basis. Each time this DLL is loaded, it gets its own new data
- * segment with its own copy of all static and global information.
+/*
+ * The following variables keep track of information about this DLL
+ * on a per-instance basis. Each time this DLL is loaded, it gets its own
+ * new data segment with its own copy of all static and global information.
*/
static HINSTANCE hInstance; /* HINSTANCE of this DLL. */
static int platformId; /* Running under NT, or 95/98? */
#ifdef HAVE_NO_SEH
+
/*
- * Unlike Borland and Microsoft, we don't register exception handlers by
- * pushing registration records onto the runtime stack. Instead, we register
- * them by creating an EXCEPTION_REGISTRATION within the activation record.
+ * Unlike Borland and Microsoft, we don't register exception handlers
+ * by pushing registration records onto the runtime stack. Instead, we
+ * register them by creating an EXCEPTION_REGISTRATION within the activation
+ * record.
*/
typedef struct EXCEPTION_REGISTRATION {
- struct EXCEPTION_REGISTRATION *link;
- EXCEPTION_DISPOSITION (*handler)(
- struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
- void *ebp;
- void *esp;
+ struct EXCEPTION_REGISTRATION* link;
+ EXCEPTION_DISPOSITION (*handler)( struct _EXCEPTION_RECORD*, void*,
+ struct _CONTEXT*, void* );
+ void* ebp;
+ void* esp;
int status;
} EXCEPTION_REGISTRATION;
+
#endif
/*
- * VC++ 5.x has no 'cpuid' assembler instruction, so we must emulate it
+ * VC++ 5.x has no 'cpuid' assembler instruction, so we
+ * must emulate it
*/
-
-#if defined(_MSC_VER) && (_MSC_VER <= 1100)
-#define cpuid __asm __emit 0fh __asm __emit 0a2h
+#if defined(_MSC_VER) && ( _MSC_VER <= 1100 )
+#define cpuid __asm __emit 0fh __asm __emit 0a2h
#endif
/*
@@ -84,10 +76,10 @@ static TclWinProcs asciiProcs = {
(TCHAR *(WINAPI *)(TCHAR *)) CharLowerA,
(BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *, BOOL)) CopyFileA,
(BOOL (WINAPI *)(CONST TCHAR *, LPSECURITY_ATTRIBUTES)) CreateDirectoryA,
- (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *,
+ (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *,
DWORD, DWORD, HANDLE)) CreateFileA,
- (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES,
- LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *,
+ (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES,
+ LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *,
LPSTARTUPINFOA, LPPROCESS_INFORMATION)) CreateProcessA,
(BOOL (WINAPI *)(CONST TCHAR *)) DeleteFileA,
(HANDLE (WINAPI *)(CONST TCHAR *, WIN32_FIND_DATAT *)) FindFirstFileA,
@@ -95,35 +87,33 @@ static TclWinProcs asciiProcs = {
(BOOL (WINAPI *)(WCHAR *, LPDWORD)) GetComputerNameA,
(DWORD (WINAPI *)(DWORD, WCHAR *)) GetCurrentDirectoryA,
(DWORD (WINAPI *)(CONST TCHAR *)) GetFileAttributesA,
- (DWORD (WINAPI *)(CONST TCHAR *, DWORD nBufferLength, WCHAR *,
+ (DWORD (WINAPI *)(CONST TCHAR *, DWORD nBufferLength, WCHAR *,
TCHAR **)) GetFullPathNameA,
(DWORD (WINAPI *)(HMODULE, WCHAR *, int)) GetModuleFileNameA,
(DWORD (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD)) GetShortPathNameA,
- (UINT (WINAPI *)(CONST TCHAR *, CONST TCHAR *, UINT uUnique,
+ (UINT (WINAPI *)(CONST TCHAR *, CONST TCHAR *, UINT uUnique,
WCHAR *)) GetTempFileNameA,
(DWORD (WINAPI *)(DWORD, WCHAR *)) GetTempPathA,
(BOOL (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD, LPDWORD, LPDWORD, LPDWORD,
WCHAR *, DWORD)) GetVolumeInformationA,
- (HINSTANCE (WINAPI *)(CONST TCHAR *, HANDLE, DWORD)) LoadLibraryExA,
+ (HINSTANCE (WINAPI *)(const TCHAR *, HANDLE, DWORD)) LoadLibraryExA,
(TCHAR (WINAPI *)(WCHAR *, CONST TCHAR *)) lstrcpyA,
(BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *)) MoveFileA,
(BOOL (WINAPI *)(CONST TCHAR *)) RemoveDirectoryA,
- (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD,
+ (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD,
WCHAR *, TCHAR **)) SearchPathA,
(BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryA,
(BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesA,
-
- /*
+ /*
* The three NULL function pointers will only be set when
- * Tcl_FindExecutable is called. If you don't ever call that function, the
- * application will crash whenever WinTcl tries to call functions through
- * these null pointers. That is not a bug in Tcl - Tcl_FindExecutable is
- * mandatory in recent Tcl releases.
+ * Tcl_FindExecutable is called. If you don't ever call that
+ * function, the application will crash whenever WinTcl tries to call
+ * functions through these null pointers. That is not a bug in Tcl
+ * -- Tcl_FindExecutable is obligatory in recent Tcl releases.
*/
-
NULL,
NULL,
- /* deleted (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _utime, */
+ (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _utime,
NULL,
NULL,
/* getLongPathNameProc */
@@ -132,8 +122,7 @@ static TclWinProcs asciiProcs = {
NULL, NULL, NULL, NULL, NULL, NULL,
/* ReadConsole and WriteConsole */
(BOOL (WINAPI *)(HANDLE, LPVOID, DWORD, LPDWORD, LPVOID)) ReadConsoleA,
- (BOOL (WINAPI *)(HANDLE, const VOID*, DWORD, LPDWORD, LPVOID)) WriteConsoleA,
- (BOOL (WINAPI *)(LPTSTR, LPDWORD)) GetUserNameA
+ (BOOL (WINAPI *)(HANDLE, const VOID*, DWORD, LPDWORD, LPVOID)) WriteConsoleA
};
static TclWinProcs unicodeProcs = {
@@ -143,10 +132,10 @@ static TclWinProcs unicodeProcs = {
(TCHAR *(WINAPI *)(TCHAR *)) CharLowerW,
(BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *, BOOL)) CopyFileW,
(BOOL (WINAPI *)(CONST TCHAR *, LPSECURITY_ATTRIBUTES)) CreateDirectoryW,
- (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *,
+ (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *,
DWORD, DWORD, HANDLE)) CreateFileW,
- (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES,
- LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *,
+ (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES,
+ LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *,
LPSTARTUPINFOA, LPPROCESS_INFORMATION)) CreateProcessW,
(BOOL (WINAPI *)(CONST TCHAR *)) DeleteFileW,
(HANDLE (WINAPI *)(CONST TCHAR *, WIN32_FIND_DATAT *)) FindFirstFileW,
@@ -154,35 +143,33 @@ static TclWinProcs unicodeProcs = {
(BOOL (WINAPI *)(WCHAR *, LPDWORD)) GetComputerNameW,
(DWORD (WINAPI *)(DWORD, WCHAR *)) GetCurrentDirectoryW,
(DWORD (WINAPI *)(CONST TCHAR *)) GetFileAttributesW,
- (DWORD (WINAPI *)(CONST TCHAR *, DWORD nBufferLength, WCHAR *,
+ (DWORD (WINAPI *)(CONST TCHAR *, DWORD nBufferLength, WCHAR *,
TCHAR **)) GetFullPathNameW,
(DWORD (WINAPI *)(HMODULE, WCHAR *, int)) GetModuleFileNameW,
(DWORD (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD)) GetShortPathNameW,
- (UINT (WINAPI *)(CONST TCHAR *, CONST TCHAR *, UINT uUnique,
+ (UINT (WINAPI *)(CONST TCHAR *, CONST TCHAR *, UINT uUnique,
WCHAR *)) GetTempFileNameW,
(DWORD (WINAPI *)(DWORD, WCHAR *)) GetTempPathW,
- (BOOL (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD, LPDWORD, LPDWORD, LPDWORD,
+ (BOOL (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD, LPDWORD, LPDWORD, LPDWORD,
WCHAR *, DWORD)) GetVolumeInformationW,
- (HINSTANCE (WINAPI *)(CONST TCHAR *, HANDLE, DWORD)) LoadLibraryExW,
+ (HINSTANCE (WINAPI *)(const TCHAR *, HANDLE, DWORD)) LoadLibraryExW,
(TCHAR (WINAPI *)(WCHAR *, CONST TCHAR *)) lstrcpyW,
(BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *)) MoveFileW,
(BOOL (WINAPI *)(CONST TCHAR *)) RemoveDirectoryW,
- (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD,
+ (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD,
WCHAR *, TCHAR **)) SearchPathW,
(BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryW,
(BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesW,
-
- /*
+ /*
* The three NULL function pointers will only be set when
- * Tcl_FindExecutable is called. If you don't ever call that function, the
- * application will crash whenever WinTcl tries to call functions through
- * these null pointers. That is not a bug in Tcl - Tcl_FindExecutable is
- * mandatory in recent Tcl releases.
+ * Tcl_FindExecutable is called. If you don't ever call that
+ * function, the application will crash whenever WinTcl tries to call
+ * functions through these null pointers. That is not a bug in Tcl
+ * -- Tcl_FindExecutable is obligatory in recent Tcl releases.
*/
-
NULL,
NULL,
- /* deleted (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _wutime, */
+ (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _wutime,
NULL,
NULL,
/* getLongPathNameProc */
@@ -191,70 +178,70 @@ static TclWinProcs unicodeProcs = {
NULL, NULL, NULL, NULL, NULL, NULL,
/* ReadConsole and WriteConsole */
(BOOL (WINAPI *)(HANDLE, LPVOID, DWORD, LPDWORD, LPVOID)) ReadConsoleW,
- (BOOL (WINAPI *)(HANDLE, const VOID*, DWORD, LPDWORD, LPVOID)) WriteConsoleW,
- (BOOL (WINAPI *)(LPTSTR, LPDWORD)) GetUserNameW
+ (BOOL (WINAPI *)(HANDLE, const VOID*, DWORD, LPDWORD, LPVOID)) WriteConsoleW
};
TclWinProcs *tclWinProcs;
static Tcl_Encoding tclWinTCharEncoding;
+
#ifdef HAVE_NO_SEH
-/*
- * Need to add noinline flag to DllMain declaration so that gcc -O3 does not
- * inline asm code into DllEntryPoint and cause a compile time error because
- * of redefined local labels.
+
+/* Need to add noinline flag to DllMain declaration so that gcc -O3
+ * does not inline asm code into DllEntryPoint and cause a
+ * compile time error because of redefined local labels.
*/
-BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
- LPVOID reserved) __attribute__ ((noinline));
+BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
+ LPVOID reserved)
+ __attribute__ ((noinline));
+
#else
+
/*
* The following declaration is for the VC++ DLL entry point.
*/
-BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
- LPVOID reserved);
+BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
+ LPVOID reserved);
#endif /* HAVE_NO_SEH */
+
/*
* The following structure and linked list is to allow us to map between
- * volume mount points and drive letters on the fly (no Win API exists for
- * this).
+ * volume mount points and drive letters on the fly (no Win API exists
+ * for this).
*/
-
typedef struct MountPointMap {
- CONST WCHAR *volumeName; /* Native wide string volume name. */
- char driveLetter; /* Drive letter corresponding to the volume
- * name. */
- struct MountPointMap *nextPtr;
- /* Pointer to next structure in list, or
- * NULL. */
+ CONST WCHAR* volumeName; /* Native wide string volume name */
+ char driveLetter; /* Drive letter corresponding to
+ * the volume name. */
+ struct MountPointMap* nextPtr; /* Pointer to next structure in list,
+ * or NULL */
} MountPointMap;
-/*
- * This is the head of the linked list, which is protected by the mutex which
- * follows, for thread-enabled builds.
+/*
+ * This is the head of the linked list, which is protected by the
+ * mutex which follows, for thread-enabled builds.
*/
-
MountPointMap *driveLetterLookup = NULL;
TCL_DECLARE_MUTEX(mountPointMap)
-/*
- * We will need this below.
- */
-
+/* We will need this below */
extern Tcl_FSDupInternalRepProc TclNativeDupInternalRep;
#ifdef __WIN32__
#ifndef STATIC_BUILD
+
/*
*----------------------------------------------------------------------
*
* DllEntryPoint --
*
- * This wrapper function is used by Borland to invoke the initialization
- * code for Tcl. It simply calls the DllMain routine.
+ * This wrapper function is used by Borland to invoke the
+ * initialization code for Tcl. It simply calls the DllMain
+ * routine.
*
* Results:
* See DllMain.
@@ -266,10 +253,10 @@ extern Tcl_FSDupInternalRepProc TclNativeDupInternalRep;
*/
BOOL APIENTRY
-DllEntryPoint(
- HINSTANCE hInst, /* Library instance handle. */
- DWORD reason, /* Reason this function is being called. */
- LPVOID reserved) /* Not used. */
+DllEntryPoint(hInst, reason, reserved)
+ HINSTANCE hInst; /* Library instance handle. */
+ DWORD reason; /* Reason this function is being called. */
+ LPVOID reserved; /* Not used. */
{
return DllMain(hInst, reason, reserved);
}
@@ -279,27 +266,23 @@ DllEntryPoint(
*
* DllMain --
*
- * This routine is called by the VC++ C run time library init code, or
- * the DllEntryPoint routine. It is responsible for initializing various
- * dynamically loaded libraries.
+ * This routine is called by the VC++ C run time library init
+ * code, or the DllEntryPoint routine. It is responsible for
+ * initializing various dynamically loaded libraries.
*
* Results:
* TRUE on sucess, FALSE on failure.
*
* Side effects:
- * Establishes 32-to-16 bit thunk and initializes sockets library. This
- * might call some sycronization functions, but MSDN documentation
- * states: "Waiting on synchronization objects in DllMain can cause a
- * deadlock."
+ * Establishes 32-to-16 bit thunk and initializes sockets library.
*
*----------------------------------------------------------------------
*/
-
BOOL APIENTRY
-DllMain(
- HINSTANCE hInst, /* Library instance handle. */
- DWORD reason, /* Reason this function is being called. */
- LPVOID reserved) /* Not used. */
+DllMain(hInst, reason, reserved)
+ HINSTANCE hInst; /* Library instance handle. */
+ DWORD reason; /* Reason this function is being called. */
+ LPVOID reserved; /* Not used. */
{
#if defined(HAVE_NO_SEH) && !defined(_WIN64)
EXCEPTION_REGISTRATION registration;
@@ -424,7 +407,7 @@ DllMain(
*/
HINSTANCE
-TclWinGetTclInstance(void)
+TclWinGetTclInstance()
{
return hInstance;
}
@@ -446,8 +429,8 @@ TclWinGetTclInstance(void)
*/
void
-TclWinInit(
- HINSTANCE hInst) /* Library instance handle. */
+TclWinInit(hInst)
+ HINSTANCE hInst; /* Library instance handle. */
{
OSVERSIONINFO os;
@@ -457,12 +440,12 @@ TclWinInit(
platformId = os.dwPlatformId;
/*
- * We no longer support Win32s, so just in case someone manages to get a
- * runtime there, make sure they know that.
+ * We no longer support Win32s, so just in case someone manages to
+ * get a runtime there, make sure they know that.
*/
if (platformId == VER_PLATFORM_WIN32s) {
- Tcl_Panic("Win32s is not a supported platform");
+ panic("Win32s is not a supported platform");
}
tclWinProcs = &asciiProcs;
@@ -473,14 +456,14 @@ TclWinInit(
*
* TclWinGetPlatformId --
*
- * Determines whether running under NT, 95, or Win32s, to allow runtime
- * conditional code.
+ * Determines whether running under NT, 95, or Win32s, to allow
+ * runtime conditional code.
*
* Results:
* The return value is one of:
* VER_PLATFORM_WIN32s Win32s on Windows 3.1. (not supported)
- * VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95, 98, ME.
- * VER_PLATFORM_WIN32_NT Win32 on Windows NT, 2000, XP
+ * VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95.
+ * VER_PLATFORM_WIN32_NT Win32 on Windows NT
*
* Side effects:
* None.
@@ -488,8 +471,8 @@ TclWinInit(
*----------------------------------------------------------------------
*/
-int
-TclWinGetPlatformId(void)
+int
+TclWinGetPlatformId()
{
return platformId;
}
@@ -528,93 +511,168 @@ TclWinNoBackslash(
/*
*----------------------------------------------------------------------
*
- * TclpGetStackParams --
+ * TclpCheckStackSpace --
*
- * Determine the stack params for the current thread: in which
- * direction does the stack grow, and what is the stack lower (resp.
- * upper) bound for safe invocation of a new command? This is used to
- * cache the values needed for an efficient computation of
- * TclpCheckStackSpace() when the interp is known.
+ * Detect if we are about to blow the stack. Called before an
+ * evaluation can happen when nesting depth is checked.
*
* Results:
- * Returns 1 if the stack grows down, in which case a stack lower bound
- * is stored at stackBoundPtr. If the stack grows up, 0 is returned and
- * an upper bound is stored at stackBoundPtr. If a bound cannot be
- * determined NULL is stored at stackBoundPtr.
+ * 1 if there is enough stack space to continue; 0 if not.
+ *
+ * Side effects:
+ * None.
*
*----------------------------------------------------------------------
*/
-#ifndef TCL_NO_STACK_CHECK
int
-TclpGetCStackParams(
- int **stackBoundPtr)
+TclpCheckStackSpace()
{
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- SYSTEM_INFO si; /* The system information, used to
- * determine the page size */
- MEMORY_BASIC_INFORMATION mbi;
- /* The information about the memory
- * area in which the stack resides */
-
- if (!tsdPtr->stackBound
- || ((UINT_PTR)&tsdPtr < (UINT_PTR)tsdPtr->stackBound)) {
-
- /*
- * Either we haven't determined the stack bound in this thread,
- * or else we've overflowed the bound that we previously
- * determined. We need to find a new stack bound from
- * Windows.
- */
- GetSystemInfo(&si);
- if (VirtualQuery((LPCVOID) &tsdPtr, &mbi, sizeof(mbi)) == 0) {
+#if defined(HAVE_NO_SEH) && !defined(__WIN64__)
+ EXCEPTION_REGISTRATION registration;
+#endif
+ int retval = 0;
- /* For some reason, the system didn't let us query the
- * stack size. Nevertheless, we got here and haven't
- * blown up yet. Don't update the calculated stack bound.
- * If there is no calculated stack bound yet, set it to
- * the base of the current page of stack. */
+ /*
+ * We can recurse only if there is at least TCL_WIN_STACK_THRESHOLD
+ * bytes of stack space left. alloca() is cheap on windows; basically
+ * it just subtracts from the stack pointer causing the OS to throw an
+ * exception if the stack pointer is set below the bottom of the stack.
+ */
- if (!tsdPtr->stackBound) {
- tsdPtr->stackBound =
- (int*) ((UINT_PTR)(&tsdPtr)
- & ~ (UINT_PTR)(si.dwPageSize - 1));
- }
+#ifdef HAVE_NO_SEH
+# ifdef __WIN64__
- } else {
+ /* TODO: How to call allocal on Win64? */
+ retval = 1;
- /* The allocation base of the stack segment has to be advanced
- * by one page (to allow for the guard page maintained in the
- * C runtime) and then by TCL_WIN_STACK_THRESHOLD (to allow
- * for the amount of stack that Tcl needs).
- */
+# else
+ __asm__ __volatile__ (
+
+ /*
+ * Construct an EXCEPTION_REGISTRATION to protect the
+ * call to __alloca
+ */
+ "leal %[registration], %%edx" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
+ "leal 1f, %%eax" "\n\t"
+ "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
+ "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
+ "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
+ "movl %[error], 0x10(%%edx)" "\n\t" /* status */
+
+ /*
+ * Link the EXCEPTION_REGISTRATION on the chain
+ */
+ "movl %%edx, %%fs:0" "\n\t"
+
+ /*
+ * Attempt a call to __alloca, to determine whether there's
+ * sufficient memory to be had.
+ */
+
+ "movl %[size], %%eax" "\n\t"
+ "pushl %%eax" "\n\t"
+ "call __alloca" "\n\t"
+
+ /*
+ * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION
+ * and store a TCL_OK status
+ */
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl %[ok], %%eax" "\n\t"
+ "movl %%eax, 0x10(%%edx)" "\n\t"
+ "jmp 2f" "\n"
+
+ /*
+ * Come here on an exception. Get the EXCEPTION_REGISTRATION
+ * that we previously put on the chain.
+ */
+ "1:" "\t"
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl 0x8(%%edx), %%edx" "\n\t"
+
+ /*
+ * Come here however we exited. Restore context from the
+ * EXCEPTION_REGISTRATION in case the stack is unbalanced.
+ */
+
+ "2:" "\t"
+ "movl 0xc(%%edx), %%esp" "\n\t"
+ "movl 0x8(%%edx), %%ebp" "\n\t"
+ "movl 0x0(%%edx), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+
+ :
+ /* No outputs */
+ :
+ [registration] "m" (registration),
+ [ok] "i" (TCL_OK),
+ [error] "i" (TCL_ERROR),
+ [size] "i" (TCL_WIN_STACK_THRESHOLD)
+ :
+ "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"
+ );
+ retval = (registration.status == TCL_OK);
- tsdPtr->stackBound =
- (int*) ((UINT_PTR)(mbi.AllocationBase)
- + (UINT_PTR)(si.dwPageSize)
- + TCL_WIN_STACK_THRESHOLD);
- }
- }
- *stackBoundPtr = tsdPtr->stackBound;
- return 1;
+# endif
+#else /* !HAVE_NO_SEH */
+ __try {
+#ifdef HAVE_ALLOCA_GCC_INLINE
+ __asm__ __volatile__ (
+ "movl %0, %%eax" "\n\t"
+ "call __alloca" "\n\t"
+ :
+ : "i"(TCL_WIN_STACK_THRESHOLD)
+ : "%eax");
+#else
+ alloca(TCL_WIN_STACK_THRESHOLD);
+#endif /* HAVE_ALLOCA_GCC_INLINE */
+ retval = 1;
+ } __except (EXCEPTION_EXECUTE_HANDLER) {}
+#endif /* HAVE_NO_SEH */
+
+ return retval;
}
-#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclWinGetPlatform --
+ *
+ * This is a kludge that allows the test library to get access
+ * the internal tclPlatform variable.
+ *
+ * Results:
+ * Returns a pointer to the tclPlatform variable.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+TclPlatformType *
+TclWinGetPlatform()
+{
+ return &tclPlatform;
+}
/*
*---------------------------------------------------------------------------
*
* TclWinSetInterfaces --
*
- * A helper proc that allows the test library to change the tclWinProcs
- * structure to dispatch to either the wide-character or multi-byte
- * versions of the operating system calls, depending on whether Unicode
- * is the system encoding.
- *
- * As well as this, we can also try to load in some additional procs
- * which may/may not be present depending on the current Windows version
- * (e.g. Win95 will not have the procs below).
+ * A helper proc that allows the test library to change the
+ * tclWinProcs structure to dispatch to either the wide-character
+ * or multi-byte versions of the operating system calls, depending
+ * on whether Unicode is the system encoding.
+ *
+ * As well as this, we can also try to load in some additional
+ * procs which may/may not be present depending on the current
+ * Windows version (e.g. Win95 will not have the procs below).
*
* Results:
* None.
@@ -638,25 +696,21 @@ TclWinSetInterfaces(
if (tclWinProcs->getFileAttributesExProc == NULL) {
HINSTANCE hInstance = LoadLibraryA("kernel32");
if (hInstance != NULL) {
- tclWinProcs->getFileAttributesExProc =
- (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
- LPVOID)) GetProcAddress(hInstance,
- "GetFileAttributesExW");
- tclWinProcs->createHardLinkProc =
- (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
- LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
- "CreateHardLinkW");
- tclWinProcs->findFirstFileExProc =
- (HANDLE (WINAPI *)(CONST TCHAR*, UINT, LPVOID, UINT,
- LPVOID, DWORD)) GetProcAddress(hInstance,
- "FindFirstFileExW");
- tclWinProcs->getVolumeNameForVMPProc =
- (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
- DWORD)) GetProcAddress(hInstance,
- "GetVolumeNameForVolumeMountPointW");
- tclWinProcs->getLongPathNameProc =
- (DWORD (WINAPI *)(CONST TCHAR*, TCHAR*,
- DWORD)) GetProcAddress(hInstance, "GetLongPathNameW");
+ tclWinProcs->getFileAttributesExProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
+ LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExW");
+ tclWinProcs->createHardLinkProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
+ LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
+ "CreateHardLinkW");
+ tclWinProcs->findFirstFileExProc =
+ (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
+ LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
+ "FindFirstFileExW");
+ tclWinProcs->getVolumeNameForVMPProc =
+ (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
+ DWORD)) GetProcAddress(hInstance,
+ "GetVolumeNameForVolumeMountPointW");
FreeLibrary(hInstance);
}
hInstance = LoadLibraryA("advapi32");
@@ -696,31 +750,22 @@ TclWinSetInterfaces(
if (tclWinProcs->getFileAttributesExProc == NULL) {
HINSTANCE hInstance = LoadLibraryA("kernel32");
if (hInstance != NULL) {
- tclWinProcs->getFileAttributesExProc =
- (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
- LPVOID)) GetProcAddress(hInstance,
- "GetFileAttributesExA");
- tclWinProcs->createHardLinkProc =
- (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
- LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
- "CreateHardLinkA");
- tclWinProcs->findFirstFileExProc = NULL;
+ tclWinProcs->getFileAttributesExProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
+ LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExA");
+ tclWinProcs->createHardLinkProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
+ LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
+ "CreateHardLinkA");
+ tclWinProcs->findFirstFileExProc =
+ (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
+ LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
+ "FindFirstFileExA");
tclWinProcs->getLongPathNameProc = NULL;
- /*
- * The 'findFirstFileExProc' function exists on some of
- * 95/98/ME, but it seems not to work as anticipated.
- * Therefore we don't set this function pointer. The relevant
- * code will fall back on a slower approach using the normal
- * findFirstFileProc.
- *
- * (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
- * LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
- * "FindFirstFileExA");
- */
- tclWinProcs->getVolumeNameForVMPProc =
- (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
- DWORD)) GetProcAddress(hInstance,
- "GetVolumeNameForVolumeMountPointA");
+ tclWinProcs->getVolumeNameForVMPProc =
+ (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
+ DWORD)) GetProcAddress(hInstance,
+ "GetVolumeNameForVolumeMountPointA");
FreeLibrary(hInstance);
}
}
@@ -732,14 +777,15 @@ TclWinSetInterfaces(
*
* TclWinResetInterfaceEncodings --
*
- * Called during finalization to free up any encodings we use. The
- * tclWinProcs-> look up table is still ok to use after this call,
- * provided no encoding conversion is required.
- *
- * We also clean up any memory allocated in our mount point map which is
- * used to follow certain kinds of symlinks. That code should never be
- * used once encodings are taken down.
+ * Called during finalization to free up any encodings we use.
+ * The tclWinProcs-> look up table is still ok to use after
+ * this call, provided no encoding conversion is required.
*
+ * We also clean up any memory allocated in our mount point
+ * map which is used to follow certain kinds of symlinks.
+ * That code should never be used once encodings are taken
+ * down.
+ *
* Results:
* None.
*
@@ -748,22 +794,17 @@ TclWinSetInterfaces(
*
*---------------------------------------------------------------------------
*/
-
void
-TclWinResetInterfaceEncodings(void)
+TclWinResetInterfaceEncodings()
{
MountPointMap *dlIter, *dlIter2;
if (tclWinTCharEncoding != NULL) {
Tcl_FreeEncoding(tclWinTCharEncoding);
tclWinTCharEncoding = NULL;
}
-
- /*
- * Clean up the mount point map.
- */
-
+ /* Clean up the mount point map */
Tcl_MutexLock(&mountPointMap);
- dlIter = driveLetterLookup;
+ dlIter = driveLetterLookup;
while (dlIter != NULL) {
dlIter2 = dlIter->nextPtr;
ckfree((char*)dlIter->volumeName);
@@ -779,8 +820,8 @@ TclWinResetInterfaceEncodings(void)
* TclWinResetInterfaces --
*
* Called during finalization to reset us to a safe state for reuse.
- * After this call, it is best not to use the tclWinProcs-> look up table
- * since it is likely to be different to what is expected.
+ * After this call, it is best not to use the tclWinProcs-> look
+ * up table since it is likely to be different to what is expected.
*
* Results:
* None.
@@ -791,7 +832,7 @@ TclWinResetInterfaceEncodings(void)
*---------------------------------------------------------------------------
*/
void
-TclWinResetInterfaces(void)
+TclWinResetInterfaces()
{
tclWinProcs = &asciiProcs;
}
@@ -801,76 +842,64 @@ TclWinResetInterfaces(void)
*
* TclWinDriveLetterForVolMountPoint
*
- * Unfortunately, Windows provides no easy way at all to get hold of the
- * drive letter for a volume mount point, but we need that information to
- * understand paths correctly. So, we have to build an associated array
- * to find these correctly, and allow quick and easy lookup from volume
- * mount points to drive letters.
- *
- * We assume here that we are running on a system for which the wide
- * character interfaces are used, which is valid for Win 2000 and WinXP
- * which are the only systems on which this function will ever be called.
- *
- * Result:
- * The drive letter, or -1 if no drive letter corresponds to the given
- * mount point.
- *
+ * Unfortunately, Windows provides no easy way at all to get hold
+ * of the drive letter for a volume mount point, but we need that
+ * information to understand paths correctly. So, we have to
+ * build an associated array to find these correctly, and allow
+ * quick and easy lookup from volume mount points to drive letters.
+ *
+ * We assume here that we are running on a system for which the wide
+ * character interfaces are used, which is valid for Win 2000 and WinXP
+ * which are the only systems on which this function will ever be called.
+ *
+ * Result: the drive letter, or -1 if no drive letter corresponds to
+ * the given mount point.
+ *
*--------------------------------------------------------------------
*/
-
-char
-TclWinDriveLetterForVolMountPoint(
- CONST WCHAR *mountPoint)
+char
+TclWinDriveLetterForVolMountPoint(CONST WCHAR *mountPoint)
{
MountPointMap *dlIter, *dlPtr2;
- WCHAR Target[55]; /* Target of mount at mount point */
+ WCHAR Target[55]; /* Target of mount at mount point */
WCHAR drive[4] = { L'A', L':', L'\\', L'\0' };
-
- /*
- * Detect the volume mounted there. Unfortunately, there is no simple way
- * to map a unique volume name to a DOS drive letter. So, we have to build
- * an associative array.
+
+ /*
+ * Detect the volume mounted there. Unfortunately, there is no
+ * simple way to map a unique volume name to a DOS drive letter.
+ * So, we have to build an associative array.
*/
-
+
Tcl_MutexLock(&mountPointMap);
- dlIter = driveLetterLookup;
+ dlIter = driveLetterLookup;
while (dlIter != NULL) {
if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
- /*
- * We need to check whether this information is still valid, since
- * either the user or various programs could have adjusted the
- * mount points on the fly.
+ /*
+ * We need to check whether this information is
+ * still valid, since either the user or various
+ * programs could have adjusted the mount points on
+ * the fly.
*/
-
drive[0] = L'A' + (dlIter->driveLetter - 'A');
-
- /*
- * Try to read the volume mount point and see where it points.
- */
-
- if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
- (TCHAR*)Target, 55) != 0) {
+ /* Try to read the volume mount point and see where it points */
+ if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
+ (TCHAR*)Target, 55) != 0) {
if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
- /*
- * Nothing has changed.
- */
-
+ /* Nothing has changed */
Tcl_MutexUnlock(&mountPointMap);
return dlIter->driveLetter;
}
}
-
- /*
- * If we reach here, unfortunately, this mount point is no longer
- * valid at all.
+ /*
+ * If we reach here, unfortunately, this mount point is
+ * no longer valid at all
*/
-
if (driveLetterLookup == dlIter) {
dlPtr2 = dlIter;
driveLetterLookup = dlIter->nextPtr;
} else {
- for (dlPtr2 = driveLetterLookup;
- dlPtr2 != NULL; dlPtr2 = dlPtr2->nextPtr) {
+ for (dlPtr2 = driveLetterLookup;
+ dlPtr2 != NULL; dlPtr2 = dlPtr2->nextPtr) {
if (dlPtr2->nextPtr == dlIter) {
dlPtr2->nextPtr = dlIter->nextPtr;
dlPtr2 = dlIter;
@@ -878,48 +907,36 @@ TclWinDriveLetterForVolMountPoint(
}
}
}
-
- /*
- * Now dlPtr2 points to the structure to free.
- */
-
+ /* Now dlPtr2 points to the structure to free */
ckfree((char*)dlPtr2->volumeName);
ckfree((char*)dlPtr2);
-
- /*
- * Restart the loop - we could try to be clever and continue half
- * way through, but the logic is a bit messy, so it's cleanest
- * just to restart.
+ /*
+ * Restart the loop --- we could try to be clever
+ * and continue half way through, but the logic is a
+ * bit messy, so it's cleanest just to restart
*/
-
dlIter = driveLetterLookup;
continue;
}
dlIter = dlIter->nextPtr;
}
-
- /*
- * We couldn't find it, so we must iterate over the letters.
- */
-
+
+ /* We couldn't find it, so we must iterate over the letters */
+
for (drive[0] = L'A'; drive[0] <= L'Z'; drive[0]++) {
- /*
- * Try to read the volume mount point and see where it points.
- */
-
- if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
- (TCHAR*)Target, 55) != 0) {
+ /* Try to read the volume mount point and see where it points */
+ if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
+ (TCHAR*)Target, 55) != 0) {
int alreadyStored = 0;
-
- for (dlIter = driveLetterLookup; dlIter != NULL;
- dlIter = dlIter->nextPtr) {
+ for (dlIter = driveLetterLookup; dlIter != NULL;
+ dlIter = dlIter->nextPtr) {
if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
alreadyStored = 1;
break;
}
}
if (!alreadyStored) {
- dlPtr2 = (MountPointMap *) ckalloc(sizeof(MountPointMap));
+ dlPtr2 = (MountPointMap*) ckalloc(sizeof(MountPointMap));
dlPtr2->volumeName = TclNativeDupInternalRep(Target);
dlPtr2->driveLetter = 'A' + (drive[0] - L'A');
dlPtr2->nextPtr = driveLetterLookup;
@@ -927,24 +944,19 @@ TclWinDriveLetterForVolMountPoint(
}
}
}
-
- /*
- * Try again.
- */
-
- for (dlIter = driveLetterLookup; dlIter != NULL;
- dlIter = dlIter->nextPtr) {
+ /* Try again */
+ for (dlIter = driveLetterLookup; dlIter != NULL;
+ dlIter = dlIter->nextPtr) {
if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
Tcl_MutexUnlock(&mountPointMap);
return dlIter->driveLetter;
}
}
-
- /*
- * The volume doesn't appear to correspond to a drive letter - we remember
- * that fact and store '-1' so we don't have to look it up each time.
+ /*
+ * The volume doesn't appear to correspond to a drive letter -- we
+ * remember that fact and store '-1' so we don't have to look it
+ * up each time.
*/
-
dlPtr2 = (MountPointMap*) ckalloc(sizeof(MountPointMap));
dlPtr2->volumeName = TclNativeDupInternalRep((ClientData)mountPoint);
dlPtr2->driveLetter = -1;
@@ -959,24 +971,26 @@ TclWinDriveLetterForVolMountPoint(
*
* Tcl_WinUtfToTChar, Tcl_WinTCharToUtf --
*
- * Convert between UTF-8 and Unicode when running Windows NT or the
- * current ANSI code page when running Windows 95.
+ * Convert between UTF-8 and Unicode when running Windows NT or
+ * the current ANSI code page when running Windows 95.
*
- * On Mac, Unix, and Windows 95, all strings exchanged between Tcl and
- * the OS are "char" oriented. We need only one Tcl_Encoding to convert
- * between UTF-8 and the system's native encoding. We use NULL to
- * represent that encoding.
+ * On Mac, Unix, and Windows 95, all strings exchanged between Tcl
+ * and the OS are "char" oriented. We need only one Tcl_Encoding to
+ * convert between UTF-8 and the system's native encoding. We use
+ * NULL to represent that encoding.
*
* On NT, some strings exchanged between Tcl and the OS are "char"
- * oriented, while others are in Unicode. We need two Tcl_Encoding APIs
- * depending on whether we are targeting a "char" or Unicode interface.
- *
- * Calling Tcl_UtfToExternal() or Tcl_ExternalToUtf() with an encoding of
- * NULL should always used to convert between UTF-8 and the system's
- * "char" oriented encoding. The following two functions are used in
- * Windows-specific code to convert between UTF-8 and Unicode strings
- * (NT) or "char" strings(95). This saves you the trouble of writing the
- * following type of fragment over and over:
+ * oriented, while others are in Unicode. We need two Tcl_Encoding
+ * APIs depending on whether we are targeting a "char" or Unicode
+ * interface.
+ *
+ * Calling Tcl_UtfToExternal() or Tcl_ExternalToUtf() with an
+ * encoding of NULL should always used to convert between UTF-8
+ * and the system's "char" oriented encoding. The following two
+ * functions are used in Windows-specific code to convert between
+ * UTF-8 and Unicode strings (NT) or "char" strings(95). This saves
+ * you the trouble of writing the following type of fragment over and
+ * over:
*
* if (running NT) {
* encoding <- Tcl_GetEncoding("unicode");
@@ -986,17 +1000,19 @@ TclWinDriveLetterForVolMountPoint(
* nativeBuffer <- UtfToExternal(NULL, utfBuffer);
* }
*
- * By convention, in Windows a TCHAR is a character in the ANSI code page
- * on Windows 95, a Unicode character on Windows NT. If you plan on
- * targeting a Unicode interfaces when running on NT and a "char"
- * oriented interface while running on 95, these functions should be
- * used. If you plan on targetting the same "char" oriented function on
- * both 95 and NT, use Tcl_UtfToExternal() with an encoding of NULL.
+ * By convention, in Windows a TCHAR is a character in the ANSI code
+ * page on Windows 95, a Unicode character on Windows NT. If you
+ * plan on targeting a Unicode interfaces when running on NT and a
+ * "char" oriented interface while running on 95, these functions
+ * should be used. If you plan on targetting the same "char"
+ * oriented function on both 95 and NT, use Tcl_UtfToExternal()
+ * with an encoding of NULL.
*
* Results:
- * The result is a pointer to the string in the desired target encoding.
- * Storage for the result string is allocated in dsPtr; the caller must
- * call Tcl_DStringFree() when the result is no longer needed.
+ * The result is a pointer to the string in the desired target
+ * encoding. Storage for the result string is allocated in
+ * dsPtr; the caller must call Tcl_DStringFree() when the result
+ * is no longer needed.
*
* Side effects:
* None.
@@ -1005,27 +1021,27 @@ TclWinDriveLetterForVolMountPoint(
*/
TCHAR *
-Tcl_WinUtfToTChar(
- CONST char *string, /* Source string in UTF-8. */
- int len, /* Source string length in bytes, or < 0 for
+Tcl_WinUtfToTChar(string, len, dsPtr)
+ CONST char *string; /* Source string in UTF-8. */
+ int len; /* Source string length in bytes, or < 0 for
* strlen(). */
- Tcl_DString *dsPtr) /* Uninitialized or free DString in which the
- * converted string is stored. */
+ Tcl_DString *dsPtr; /* Uninitialized or free DString in which
+ * the converted string is stored. */
{
- return (TCHAR *) Tcl_UtfToExternalDString(tclWinTCharEncoding,
+ return (TCHAR *) Tcl_UtfToExternalDString(tclWinTCharEncoding,
string, len, dsPtr);
}
char *
-Tcl_WinTCharToUtf(
- CONST TCHAR *string, /* Source string in Unicode when running NT,
- * ANSI when running 95. */
- int len, /* Source string length in bytes, or < 0 for
+Tcl_WinTCharToUtf(string, len, dsPtr)
+ CONST TCHAR *string; /* Source string in Unicode when running
+ * NT, ANSI when running 95. */
+ int len; /* Source string length in bytes, or < 0 for
* platform-specific string length. */
- Tcl_DString *dsPtr) /* Uninitialized or free DString in which the
- * converted string is stored. */
+ Tcl_DString *dsPtr; /* Uninitialized or free DString in which
+ * the converted string is stored. */
{
- return Tcl_ExternalToUtfDString(tclWinTCharEncoding,
+ return Tcl_ExternalToUtfDString(tclWinTCharEncoding,
(CONST char *) string, len, dsPtr);
}
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index 0f17834..98de3b0 100644
--- a/win/tclWinChan.c
+++ b/win/tclWinChan.c
@@ -1,13 +1,13 @@
-/*
+/*
* tclWinChan.c
*
- * Channel drivers for Windows channels based on files, command pipes and
- * TCP sockets.
+ * Channel drivers for Windows channels based on files, command
+ * pipes and TCP sockets.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclWinInt.h"
@@ -39,8 +39,8 @@ typedef struct FileInfo {
int flags; /* State flags, see above for a list. */
HANDLE handle; /* Input/output file. */
struct FileInfo *nextPtr; /* Pointer to next registered file. */
- int dirty; /* Boolean flag. Set if the OS may have data
- * pending on the channel. */
+ int dirty; /* Boolean flag. Set if the OS may have data
+ * pending on the channel */
} FileInfo;
typedef struct ThreadSpecificData {
@@ -54,16 +54,16 @@ typedef struct ThreadSpecificData {
static Tcl_ThreadDataKey dataKey;
/*
- * The following structure is what is added to the Tcl event queue when file
- * events are generated.
+ * The following structure is what is added to the Tcl event queue when
+ * file events are generated.
*/
typedef struct FileEvent {
- Tcl_Event header; /* Information that is standard for all
- * events. */
- FileInfo *infoPtr; /* Pointer to file info structure. Note that
- * we still have to verify that the file
- * exists before dereferencing this
+ Tcl_Event header; /* Information that is standard for
+ * all events. */
+ FileInfo *infoPtr; /* Pointer to file info structure. Note
+ * that we still have to verify that the
+ * file exists before dereferencing this
* pointer. */
} FileEvent;
@@ -71,30 +71,34 @@ typedef struct FileEvent {
* Static routines for this file:
*/
-static int FileBlockProc(ClientData instanceData, int mode);
-static void FileChannelExitHandler(ClientData clientData);
-static void FileCheckProc(ClientData clientData, int flags);
-static int FileCloseProc(ClientData instanceData,
- Tcl_Interp *interp);
-static int FileEventProc(Tcl_Event *evPtr, int flags);
-static int FileGetHandleProc(ClientData instanceData,
- int direction, ClientData *handlePtr);
-static ThreadSpecificData *FileInit(void);
-static int FileInputProc(ClientData instanceData, char *buf,
- int toRead, int *errorCode);
-static int FileOutputProc(ClientData instanceData,
- CONST char *buf, int toWrite, int *errorCode);
-static int FileSeekProc(ClientData instanceData, long offset,
- int mode, int *errorCode);
-static Tcl_WideInt FileWideSeekProc(ClientData instanceData,
- Tcl_WideInt offset, int mode, int *errorCode);
-static void FileSetupProc(ClientData clientData, int flags);
-static void FileWatchProc(ClientData instanceData, int mask);
-static void FileThreadActionProc(ClientData instanceData,
- int action);
-static int FileTruncateProc(ClientData instanceData,
- Tcl_WideInt length);
-static DWORD FileGetType(HANDLE handle);
+static int FileBlockProc _ANSI_ARGS_((ClientData instanceData,
+ int mode));
+static void FileChannelExitHandler _ANSI_ARGS_((
+ ClientData clientData));
+static void FileCheckProc _ANSI_ARGS_((ClientData clientData,
+ int flags));
+static int FileCloseProc _ANSI_ARGS_((ClientData instanceData,
+ Tcl_Interp *interp));
+static int FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
+ int flags));
+static int FileGetHandleProc _ANSI_ARGS_((ClientData instanceData,
+ int direction, ClientData *handlePtr));
+static ThreadSpecificData *FileInit _ANSI_ARGS_((void));
+static int FileInputProc _ANSI_ARGS_((ClientData instanceData,
+ char *buf, int toRead, int *errorCode));
+static int FileOutputProc _ANSI_ARGS_((ClientData instanceData,
+ CONST char *buf, int toWrite, int *errorCode));
+static int FileSeekProc _ANSI_ARGS_((ClientData instanceData,
+ long offset, int mode, int *errorCode));
+static Tcl_WideInt FileWideSeekProc _ANSI_ARGS_((ClientData instanceData,
+ Tcl_WideInt offset, int mode, int *errorCode));
+static void FileSetupProc _ANSI_ARGS_((ClientData clientData,
+ int flags));
+static void FileWatchProc _ANSI_ARGS_((ClientData instanceData,
+ int mask));
+static void FileThreadActionProc _ANSI_ARGS_ ((
+ ClientData instanceData, int action));
+static DWORD FileGetType _ANSI_ARGS_((HANDLE handle));
/*
* This structure describes the channel type structure for file based IO.
@@ -102,7 +106,7 @@ static DWORD FileGetType(HANDLE handle);
static Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
+ TCL_CHANNEL_VERSION_4, /* v4 channel */
FileCloseProc, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
@@ -117,24 +121,26 @@ static Tcl_ChannelType fileChannelType = {
NULL, /* handler proc. */
FileWideSeekProc, /* Wide seek proc. */
FileThreadActionProc, /* Thread action proc. */
- FileTruncateProc, /* Truncate proc. */
};
#ifdef HAVE_NO_SEH
+
/*
- * Unlike Borland and Microsoft, we don't register exception handlers by
- * pushing registration records onto the runtime stack. Instead, we register
- * them by creating an EXCEPTION_REGISTRATION within the activation record.
+ * Unlike Borland and Microsoft, we don't register exception handlers
+ * by pushing registration records onto the runtime stack. Instead, we
+ * register them by creating an EXCEPTION_REGISTRATION within the activation
+ * record.
*/
typedef struct EXCEPTION_REGISTRATION {
struct EXCEPTION_REGISTRATION* link;
- EXCEPTION_DISPOSITION (*handler)(
- struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
+ EXCEPTION_DISPOSITION (*handler)( struct _EXCEPTION_RECORD*, void*,
+ struct _CONTEXT*, void* );
void* ebp;
void* esp;
int status;
} EXCEPTION_REGISTRATION;
+
#endif
/*
@@ -148,17 +154,16 @@ typedef struct EXCEPTION_REGISTRATION {
* None.
*
* Side effects:
- * Creates a new window and creates an exit handler.
+ * Creates a new window and creates an exit handler.
*
*----------------------------------------------------------------------
*/
static ThreadSpecificData *
-FileInit(void)
+FileInit()
{
ThreadSpecificData *tsdPtr =
- (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
-
+ (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (tsdPtr == NULL) {
tsdPtr = TCL_TSD_INIT(&dataKey);
tsdPtr->firstFilePtr = NULL;
@@ -173,8 +178,8 @@ FileInit(void)
*
* FileChannelExitHandler --
*
- * This function is called to cleanup the channel driver before Tcl is
- * unloaded.
+ * This function is called to cleanup the channel driver before
+ * Tcl is unloaded.
*
* Results:
* None.
@@ -186,8 +191,8 @@ FileInit(void)
*/
static void
-FileChannelExitHandler(
- ClientData clientData) /* Old window proc */
+FileChannelExitHandler(clientData)
+ ClientData clientData; /* Old window proc */
{
Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL);
}
@@ -197,8 +202,8 @@ FileChannelExitHandler(
*
* FileSetupProc --
*
- * This function is invoked before Tcl_DoOneEvent blocks waiting for an
- * event.
+ * This procedure is invoked before Tcl_DoOneEvent blocks waiting
+ * for an event.
*
* Results:
* None.
@@ -210,9 +215,9 @@ FileChannelExitHandler(
*/
void
-FileSetupProc(
- ClientData data, /* Not used. */
- int flags) /* Event flags as passed to Tcl_DoOneEvent. */
+FileSetupProc(data, flags)
+ ClientData data; /* Not used. */
+ int flags; /* Event flags as passed to Tcl_DoOneEvent. */
{
FileInfo *infoPtr;
Tcl_Time blockTime = { 0, 0 };
@@ -221,12 +226,12 @@ FileSetupProc(
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
-
+
/*
- * Check to see if there is a ready file. If so, poll.
+ * Check to see if there is a ready file. If so, poll.
*/
- for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
+ for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr->watchMask) {
Tcl_SetMaxBlockTime(&blockTime);
@@ -240,8 +245,8 @@ FileSetupProc(
*
* FileCheckProc --
*
- * This function is called by Tcl_DoOneEvent to check the file event
- * source for events.
+ * This procedure is called by Tcl_DoOneEvent to check the file
+ * event source for events.
*
* Results:
* None.
@@ -253,9 +258,9 @@ FileSetupProc(
*/
static void
-FileCheckProc(
- ClientData data, /* Not used. */
- int flags) /* Event flags as passed to Tcl_DoOneEvent. */
+FileCheckProc(data, flags)
+ ClientData data; /* Not used. */
+ int flags; /* Event flags as passed to Tcl_DoOneEvent. */
{
FileEvent *evPtr;
FileInfo *infoPtr;
@@ -264,13 +269,14 @@ FileCheckProc(
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
-
+
/*
- * Queue events for any ready files that don't already have events queued
- * (caused by persistent states that won't generate WinSock events).
+ * Queue events for any ready files that don't already have events
+ * queued (caused by persistent states that won't generate WinSock
+ * events).
*/
- for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
+ for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr->watchMask && !(infoPtr->flags & FILE_PENDING)) {
infoPtr->flags |= FILE_PENDING;
@@ -282,20 +288,19 @@ FileCheckProc(
}
}
-/*
- *----------------------------------------------------------------------
+/*----------------------------------------------------------------------
*
* FileEventProc --
*
- * This function is invoked by Tcl_ServiceEvent when a file event reaches
- * the front of the event queue. This function invokes Tcl_NotifyChannel
- * on the file.
+ * This function is invoked by Tcl_ServiceEvent when a file event
+ * reaches the front of the event queue. This procedure invokes
+ * Tcl_NotifyChannel on the file.
*
* Results:
- * Returns 1 if the event was handled, meaning it should be removed from
- * the queue. Returns 0 if the event was not handled, meaning it should
- * stay on the queue. The only time the event isn't handled is if the
- * TCL_FILE_EVENTS flag bit isn't set.
+ * Returns 1 if the event was handled, meaning it should be removed
+ * from the queue. Returns 0 if the event was not handled, meaning
+ * it should stay on the queue. The only time the event isn't
+ * handled is if the TCL_FILE_EVENTS flag bit isn't set.
*
* Side effects:
* Whatever the notifier callback does.
@@ -304,10 +309,10 @@ FileCheckProc(
*/
static int
-FileEventProc(
- Tcl_Event *evPtr, /* Event to service. */
- int flags) /* Flags that indicate what events to handle,
- * such as TCL_FILE_EVENTS. */
+FileEventProc(evPtr, flags)
+ Tcl_Event *evPtr; /* Event to service. */
+ int flags; /* Flags that indicate what events to
+ * handle, such as TCL_FILE_EVENTS. */
{
FileEvent *fileEvPtr = (FileEvent *)evPtr;
FileInfo *infoPtr;
@@ -319,9 +324,9 @@ FileEventProc(
/*
* Search through the list of watched files for the one whose handle
- * matches the event. We do this rather than simply dereferencing the
- * handle in the event so that files can be deleted while the event is in
- * the queue.
+ * matches the event. We do this rather than simply dereferencing
+ * the handle in the event so that files can be deleted while the
+ * event is in the queue.
*/
for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
@@ -352,13 +357,13 @@ FileEventProc(
*/
static int
-FileBlockProc(
- ClientData instanceData, /* Instance data for channel. */
- int mode) /* TCL_MODE_BLOCKING or
- * TCL_MODE_NONBLOCKING. */
+FileBlockProc(instanceData, mode)
+ ClientData instanceData; /* Instance data for channel. */
+ int mode; /* TCL_MODE_BLOCKING or
+ * TCL_MODE_NONBLOCKING. */
{
FileInfo *infoPtr = (FileInfo *) instanceData;
-
+
/*
* Files on Windows can not be switched between blocking and nonblocking,
* hence we have to emulate the behavior. This is done in the input
@@ -391,9 +396,9 @@ FileBlockProc(
*/
static int
-FileCloseProc(
- ClientData instanceData, /* Pointer to FileInfo structure. */
- Tcl_Interp *interp) /* Not used. */
+FileCloseProc(instanceData, interp)
+ ClientData instanceData; /* Pointer to FileInfo structure. */
+ Tcl_Interp *interp; /* Not used. */
{
FileInfo *fileInfoPtr = (FileInfo *) instanceData;
FileInfo *infoPtr;
@@ -407,15 +412,15 @@ FileCloseProc(
FileWatchProc(instanceData, 0);
/*
- * Don't close the Win32 handle if the handle is a standard channel during
- * the thread exit process. Otherwise, one thread may kill the stdio of
- * another.
+ * Don't close the Win32 handle if the handle is a standard channel
+ * during the thread exit process. Otherwise, one thread may kill
+ * the stdio of another.
*/
- if (!TclInThreadExit()
+ if (!TclInThreadExit()
|| ((GetStdHandle(STD_INPUT_HANDLE) != fileInfoPtr->handle)
- && (GetStdHandle(STD_OUTPUT_HANDLE) != fileInfoPtr->handle)
- && (GetStdHandle(STD_ERROR_HANDLE) != fileInfoPtr->handle))) {
+ && (GetStdHandle(STD_OUTPUT_HANDLE) != fileInfoPtr->handle)
+ && (GetStdHandle(STD_ERROR_HANDLE) != fileInfoPtr->handle))) {
if (CloseHandle(fileInfoPtr->handle) == FALSE) {
TclWinConvertError(GetLastError());
errorCode = errno;
@@ -425,21 +430,19 @@ FileCloseProc(
/*
* See if this FileInfo* is still on the thread local list.
*/
-
tsdPtr = TCL_TSD_INIT(&dataKey);
- for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
+ for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr == fileInfoPtr) {
- /*
- * This channel exists on the thread local list. It should have
- * been removed by an earlier Threadaction call, but do that now
- * since just deallocating fileInfoPtr would leave an deallocated
- * pointer on the thread local list.
- */
-
+ /*
+ * This channel exists on the thread local list. It should
+ * have been removed by an earlier Thread Action call,
+ * but do that now since just deallocating fileInfoPtr would
+ * leave an deallocated pointer on the thread local list.
+ */
FileThreadActionProc(fileInfoPtr,TCL_CHANNEL_THREAD_REMOVE);
- break;
- }
+ break;
+ }
}
ckfree((char *)fileInfoPtr);
return errorCode;
@@ -453,45 +456,44 @@ FileCloseProc(
* Seeks on a file-based channel. Returns the new position.
*
* Results:
- * -1 if failed, the new position if successful. If failed, it also sets
- * *errorCodePtr to the error code.
+ * -1 if failed, the new position if successful. If failed, it
+ * also sets *errorCodePtr to the error code.
*
* Side effects:
- * Moves the location at which the channel will be accessed in future
- * operations.
+ * Moves the location at which the channel will be accessed in
+ * future operations.
*
*----------------------------------------------------------------------
*/
static int
-FileSeekProc(
- ClientData instanceData, /* File state. */
- long offset, /* Offset to seek to. */
- int mode, /* Relative to where should we seek? */
- int *errorCodePtr) /* To store error code. */
+FileSeekProc(instanceData, offset, mode, errorCodePtr)
+ ClientData instanceData; /* File state. */
+ long offset; /* Offset to seek to. */
+ int mode; /* Relative to where should we seek? */
+ int *errorCodePtr; /* To store error code. */
{
FileInfo *infoPtr = (FileInfo *) instanceData;
- LONG newPos, newPosHigh, oldPos, oldPosHigh;
- DWORD moveMethod;
+ DWORD moveMethod, newPos, oldPos;
+ LONG newPosHigh, oldPosHigh;
*errorCodePtr = 0;
if (mode == SEEK_SET) {
- moveMethod = FILE_BEGIN;
+ moveMethod = FILE_BEGIN;
} else if (mode == SEEK_CUR) {
- moveMethod = FILE_CURRENT;
+ moveMethod = FILE_CURRENT;
} else {
- moveMethod = FILE_END;
+ moveMethod = FILE_END;
}
/*
* Save our current place in case we need to roll-back the seek.
*/
-
- oldPosHigh = 0;
- oldPos = SetFilePointer(infoPtr->handle, 0, &oldPosHigh, FILE_CURRENT);
- if (oldPos == (LONG)INVALID_SET_FILE_POINTER) {
+ oldPosHigh = (LONG)0;
+ oldPos = SetFilePointer(infoPtr->handle, (LONG)0, &oldPosHigh,
+ FILE_CURRENT);
+ if (oldPos == INVALID_SET_FILE_POINTER) {
DWORD winError = GetLastError();
-
if (winError != NO_ERROR) {
TclWinConvertError(winError);
*errorCodePtr = errno;
@@ -499,11 +501,11 @@ FileSeekProc(
}
}
- newPosHigh = (offset < 0 ? -1 : 0);
- newPos = SetFilePointer(infoPtr->handle, offset, &newPosHigh, moveMethod);
- if (newPos == (LONG)INVALID_SET_FILE_POINTER) {
+ newPosHigh = (LONG)(offset < 0 ? -1 : 0);
+ newPos = SetFilePointer(infoPtr->handle, (LONG) offset, &newPosHigh,
+ moveMethod);
+ if (newPos == INVALID_SET_FILE_POINTER) {
DWORD winError = GetLastError();
-
if (winError != NO_ERROR) {
TclWinConvertError(winError);
*errorCodePtr = errno;
@@ -514,10 +516,9 @@ FileSeekProc(
/*
* Check for expressability in our return type, and roll-back otherwise.
*/
-
if (newPosHigh != 0) {
*errorCodePtr = EOVERFLOW;
- SetFilePointer(infoPtr->handle, oldPos, &oldPosHigh, FILE_BEGIN);
+ SetFilePointer(infoPtr->handle, (LONG)oldPos, &oldPosHigh, FILE_BEGIN);
return -1;
}
return (int) newPos;
@@ -531,42 +532,41 @@ FileSeekProc(
* Seeks on a file-based channel. Returns the new position.
*
* Results:
- * -1 if failed, the new position if successful. If failed, it also sets
- * *errorCodePtr to the error code.
+ * -1 if failed, the new position if successful. If failed, it
+ * also sets *errorCodePtr to the error code.
*
* Side effects:
- * Moves the location at which the channel will be accessed in future
- * operations.
+ * Moves the location at which the channel will be accessed in
+ * future operations.
*
*----------------------------------------------------------------------
*/
static Tcl_WideInt
-FileWideSeekProc(
- ClientData instanceData, /* File state. */
- Tcl_WideInt offset, /* Offset to seek to. */
- int mode, /* Relative to where should we seek? */
- int *errorCodePtr) /* To store error code. */
+FileWideSeekProc(instanceData, offset, mode, errorCodePtr)
+ ClientData instanceData; /* File state. */
+ Tcl_WideInt offset; /* Offset to seek to. */
+ int mode; /* Relative to where should we seek? */
+ int *errorCodePtr; /* To store error code. */
{
FileInfo *infoPtr = (FileInfo *) instanceData;
- DWORD moveMethod;
- LONG newPos, newPosHigh;
+ DWORD moveMethod, newPos;
+ LONG newPosHigh;
*errorCodePtr = 0;
if (mode == SEEK_SET) {
- moveMethod = FILE_BEGIN;
+ moveMethod = FILE_BEGIN;
} else if (mode == SEEK_CUR) {
- moveMethod = FILE_CURRENT;
+ moveMethod = FILE_CURRENT;
} else {
- moveMethod = FILE_END;
+ moveMethod = FILE_END;
}
- newPosHigh = Tcl_WideAsLong(offset >> 32);
- newPos = SetFilePointer(infoPtr->handle, Tcl_WideAsLong(offset),
- &newPosHigh, moveMethod);
- if (newPos == (LONG)INVALID_SET_FILE_POINTER) {
+ newPosHigh = (DWORD)(offset >> 32);
+ newPos = SetFilePointer(infoPtr->handle, (LONG) offset, &newPosHigh,
+ moveMethod);
+ if (newPos == INVALID_SET_FILE_POINTER) {
DWORD winError = GetLastError();
-
if (winError != NO_ERROR) {
TclWinConvertError(winError);
*errorCodePtr = errno;
@@ -579,82 +579,10 @@ FileWideSeekProc(
/*
*----------------------------------------------------------------------
*
- * FileTruncateProc --
- *
- * Truncates a file-based channel. Returns the error code.
- *
- * Results:
- * 0 if successful, POSIX-y error code if it failed.
- *
- * Side effects:
- * Truncates the file, may move file pointers too.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-FileTruncateProc(
- ClientData instanceData, /* File state. */
- Tcl_WideInt length) /* Length to truncate at. */
-{
- FileInfo *infoPtr = (FileInfo *) instanceData;
- LONG newPos, newPosHigh, oldPos, oldPosHigh;
-
- /*
- * Save where we were...
- */
-
- oldPosHigh = 0;
- oldPos = SetFilePointer(infoPtr->handle, 0, &oldPosHigh, FILE_CURRENT);
- if (oldPos == (LONG)INVALID_SET_FILE_POINTER) {
- DWORD winError = GetLastError();
- if (winError != NO_ERROR) {
- TclWinConvertError(winError);
- return errno;
- }
- }
-
- /*
- * Move to where we want to truncate
- */
-
- newPosHigh = Tcl_WideAsLong(length >> 32);
- newPos = SetFilePointer(infoPtr->handle, Tcl_WideAsLong(length),
- &newPosHigh, FILE_BEGIN);
- if (newPos == (LONG)INVALID_SET_FILE_POINTER) {
- DWORD winError = GetLastError();
- if (winError != NO_ERROR) {
- TclWinConvertError(winError);
- return errno;
- }
- }
-
- /*
- * Perform the truncation (unlike POSIX ftruncate(), we needed to move to
- * the location to truncate at first).
- */
-
- if (!SetEndOfFile(infoPtr->handle)) {
- TclWinConvertError(GetLastError());
- return errno;
- }
-
- /*
- * Move back. If this last step fails, we don't care; it's just a "best
- * effort" attempt to restore our file pointer to where it was.
- */
-
- SetFilePointer(infoPtr->handle, oldPos, &oldPosHigh, FILE_BEGIN);
- return 0;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* FileInputProc --
*
- * Reads input from the IO channel into the buffer given. Returns count
- * of how many bytes were actually read, and an error indication.
+ * Reads input from the IO channel into the buffer given. Returns
+ * count of how many bytes were actually read, and an error indication.
*
* Results:
* A count of how many bytes were read is returned and an error
@@ -667,11 +595,12 @@ FileTruncateProc(
*/
static int
-FileInputProc(
- ClientData instanceData, /* File state. */
- char *buf, /* Where to store data read. */
- int bufSize, /* Num bytes available in buffer. */
- int *errorCode) /* Where to store error code. */
+FileInputProc(instanceData, buf, bufSize, errorCode)
+ ClientData instanceData; /* File state. */
+ char *buf; /* Where to store data read. */
+ int bufSize; /* How much space is available
+ * in the buffer? */
+ int *errorCode; /* Where to store error code. */
{
FileInfo *infoPtr;
DWORD bytesRead;
@@ -680,18 +609,18 @@ FileInputProc(
infoPtr = (FileInfo *) instanceData;
/*
- * Note that we will block on reads from a console buffer until a full
- * line has been entered. The only way I know of to get around this is to
- * write a console driver. We should probably do this at some point, but
- * for now, we just block. The same problem exists for files being read
- * over the network.
+ * Note that we will block on reads from a console buffer until a
+ * full line has been entered. The only way I know of to get
+ * around this is to write a console driver. We should probably
+ * do this at some point, but for now, we just block. The same
+ * problem exists for files being read over the network.
*/
if (ReadFile(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &bytesRead,
- (LPOVERLAPPED) NULL) != FALSE) {
+ (LPOVERLAPPED) NULL) != FALSE) {
return bytesRead;
}
-
+
TclWinConvertError(GetLastError());
*errorCode = errno;
if (errno == EPIPE) {
@@ -705,12 +634,12 @@ FileInputProc(
*
* FileOutputProc --
*
- * Writes the given output on the IO channel. Returns count of how many
- * characters were actually written, and an error indication.
+ * Writes the given output on the IO channel. Returns count of how
+ * many characters were actually written, and an error indication.
*
* Results:
- * A count of how many characters were written is returned and an error
- * indication is returned in an output argument.
+ * A count of how many characters were written is returned and an
+ * error indication is returned in an output argument.
*
* Side effects:
* Writes output on the actual channel.
@@ -719,15 +648,15 @@ FileInputProc(
*/
static int
-FileOutputProc(
- ClientData instanceData, /* File state. */
- CONST char *buf, /* The data buffer. */
- int toWrite, /* How many bytes to write? */
- int *errorCode) /* Where to store error code. */
+FileOutputProc(instanceData, buf, toWrite, errorCode)
+ ClientData instanceData; /* File state. */
+ CONST char *buf; /* The data buffer. */
+ int toWrite; /* How many bytes to write? */
+ int *errorCode; /* Where to store error code. */
{
FileInfo *infoPtr = (FileInfo *) instanceData;
DWORD bytesWritten;
-
+
*errorCode = 0;
/*
@@ -736,14 +665,14 @@ FileOutputProc(
*/
if (infoPtr->flags & FILE_APPEND) {
- SetFilePointer(infoPtr->handle, 0, NULL, FILE_END);
+ SetFilePointer(infoPtr->handle, 0, NULL, FILE_END);
}
- if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite,
- &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) {
- TclWinConvertError(GetLastError());
- *errorCode = errno;
- return -1;
+ if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite, &bytesWritten,
+ (LPOVERLAPPED) NULL) == FALSE) {
+ TclWinConvertError(GetLastError());
+ *errorCode = errno;
+ return -1;
}
infoPtr->dirty = 1;
return bytesWritten;
@@ -754,7 +683,8 @@ FileOutputProc(
*
* FileWatchProc --
*
- * Called by the notifier to set up to watch for events on this channel.
+ * Called by the notifier to set up to watch for events on this
+ * channel.
*
* Results:
* None.
@@ -766,18 +696,18 @@ FileOutputProc(
*/
static void
-FileWatchProc(
- ClientData instanceData, /* File state. */
- int mask) /* What events to watch for; OR-ed combination
- * of TCL_READABLE, TCL_WRITABLE and
- * TCL_EXCEPTION. */
+FileWatchProc(instanceData, mask)
+ ClientData instanceData; /* File state. */
+ int mask; /* What events to watch for; OR-ed
+ * combination of TCL_READABLE,
+ * TCL_WRITABLE and TCL_EXCEPTION. */
{
FileInfo *infoPtr = (FileInfo *) instanceData;
Tcl_Time blockTime = { 0, 0 };
/*
- * Since the file is always ready for events, we set the block time to
- * zero so we will poll.
+ * Since the file is always ready for events, we set the block time
+ * to zero so we will poll.
*/
infoPtr->watchMask = mask & infoPtr->validMask;
@@ -791,12 +721,12 @@ FileWatchProc(
*
* FileGetHandleProc --
*
- * Called from Tcl_GetChannelHandle to retrieve OS handles from a file
- * based channel.
+ * Called from Tcl_GetChannelHandle to retrieve OS handles from
+ * a file based channel.
*
* Results:
- * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if there is no
- * handle for the specified direction.
+ * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
+ * there is no handle for the specified direction.
*
* Side effects:
* None.
@@ -805,10 +735,10 @@ FileWatchProc(
*/
static int
-FileGetHandleProc(
- ClientData instanceData, /* The file state. */
- int direction, /* TCL_READABLE or TCL_WRITABLE */
- ClientData *handlePtr) /* Where to store the handle. */
+FileGetHandleProc(instanceData, direction, handlePtr)
+ ClientData instanceData; /* The file state. */
+ int direction; /* TCL_READABLE or TCL_WRITABLE */
+ ClientData *handlePtr; /* Where to store the handle. */
{
FileInfo *infoPtr = (FileInfo *) instanceData;
@@ -819,6 +749,7 @@ FileGetHandleProc(
return TCL_ERROR;
}
}
+
/*
*----------------------------------------------------------------------
@@ -828,24 +759,25 @@ FileGetHandleProc(
* Open an File based channel on Unix systems.
*
* Results:
- * The new channel or NULL. If NULL, the output argument errorCodePtr is
- * set to a POSIX error.
+ * The new channel or NULL. If NULL, the output argument
+ * errorCodePtr is set to a POSIX error.
*
* Side effects:
- * May open the channel and may cause creation of a file on the file
- * system.
+ * May open the channel and may cause creation of a file on the
+ * file system.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
-TclpOpenFileChannel(
- Tcl_Interp *interp, /* Interpreter for error reporting; can be
- * NULL. */
- Tcl_Obj *pathPtr, /* Name of file to open. */
- int mode, /* POSIX mode. */
- int permissions) /* If the open involves creating a file, with
- * what modes to create it? */
+TclpOpenFileChannel(interp, pathPtr, mode, permissions)
+ Tcl_Interp *interp; /* Interpreter for error reporting;
+ * can be NULL. */
+ Tcl_Obj *pathPtr; /* Name of file to open. */
+ int mode; /* POSIX mode. */
+ int permissions; /* If the open involves creating a
+ * file, with what modes to create
+ * it? */
{
Tcl_Channel channel = 0;
int channelPermissions = 0;
@@ -853,29 +785,30 @@ TclpOpenFileChannel(
CONST TCHAR *nativeName;
HANDLE handle;
char channelName[16 + TCL_INTEGER_SPACE];
- TclFile readFile = NULL, writeFile = NULL;
+ TclFile readFile = NULL;
+ TclFile writeFile = NULL;
nativeName = (TCHAR*) Tcl_FSGetNativePath(pathPtr);
if (nativeName == NULL) {
return NULL;
}
-
+
switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
- case O_RDONLY:
- accessMode = GENERIC_READ;
- channelPermissions = TCL_READABLE;
- break;
- case O_WRONLY:
- accessMode = GENERIC_WRITE;
- channelPermissions = TCL_WRITABLE;
- break;
- case O_RDWR:
- accessMode = (GENERIC_READ | GENERIC_WRITE);
- channelPermissions = (TCL_READABLE | TCL_WRITABLE);
- break;
- default:
- Tcl_Panic("TclpOpenFileChannel: invalid mode value");
- break;
+ case O_RDONLY:
+ accessMode = GENERIC_READ;
+ channelPermissions = TCL_READABLE;
+ break;
+ case O_WRONLY:
+ accessMode = GENERIC_WRITE;
+ channelPermissions = TCL_WRITABLE;
+ break;
+ case O_RDWR:
+ accessMode = (GENERIC_READ | GENERIC_WRITE);
+ channelPermissions = (TCL_READABLE | TCL_WRITABLE);
+ break;
+ default:
+ panic("TclpOpenFileChannel: invalid mode value");
+ break;
}
/*
@@ -883,23 +816,23 @@ TclpOpenFileChannel(
*/
switch (mode & (O_CREAT | O_EXCL | O_TRUNC)) {
- case (O_CREAT | O_EXCL):
- case (O_CREAT | O_EXCL | O_TRUNC):
- createMode = CREATE_NEW;
- break;
- case (O_CREAT | O_TRUNC):
- createMode = CREATE_ALWAYS;
- break;
- case O_CREAT:
- createMode = OPEN_ALWAYS;
- break;
- case O_TRUNC:
- case (O_TRUNC | O_EXCL):
- createMode = TRUNCATE_EXISTING;
- break;
- default:
- createMode = OPEN_EXISTING;
- break;
+ case (O_CREAT | O_EXCL):
+ case (O_CREAT | O_EXCL | O_TRUNC):
+ createMode = CREATE_NEW;
+ break;
+ case (O_CREAT | O_TRUNC):
+ createMode = CREATE_ALWAYS;
+ break;
+ case O_CREAT:
+ createMode = OPEN_ALWAYS;
+ break;
+ case O_TRUNC:
+ case (O_TRUNC | O_EXCL):
+ createMode = TRUNCATE_EXISTING;
+ break;
+ default:
+ createMode = OPEN_EXISTING;
+ break;
}
/*
@@ -908,14 +841,14 @@ TclpOpenFileChannel(
*/
if (mode & O_CREAT) {
- if (permissions & S_IWRITE) {
- flags = FILE_ATTRIBUTE_NORMAL;
- } else {
- flags = FILE_ATTRIBUTE_READONLY;
- }
+ if (permissions & S_IWRITE) {
+ flags = FILE_ATTRIBUTE_NORMAL;
+ } else {
+ flags = FILE_ATTRIBUTE_READONLY;
+ }
} else {
flags = (*tclWinProcs->getFileAttributesProc)(nativeName);
- if (flags == 0xFFFFFFFF) {
+ if (flags == 0xFFFFFFFF) {
flags = 0;
}
}
@@ -930,48 +863,48 @@ TclpOpenFileChannel(
* Now we get to create the file.
*/
- handle = (*tclWinProcs->createFileProc)(nativeName, accessMode,
+ handle = (*tclWinProcs->createFileProc)(nativeName, accessMode,
shareMode, NULL, createMode, flags, (HANDLE) NULL);
if (handle == INVALID_HANDLE_VALUE) {
- DWORD err = GetLastError();
-
+ DWORD err;
+ err = GetLastError();
if ((err & 0xffffL) == ERROR_OPEN_FAILED) {
err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND;
}
- TclWinConvertError(err);
+ TclWinConvertError(err);
if (interp != (Tcl_Interp *) NULL) {
- Tcl_AppendResult(interp, "couldn't open \"", TclGetString(pathPtr),
- "\": ", Tcl_PosixError(interp), NULL);
- }
- return NULL;
+ Tcl_AppendResult(interp, "couldn't open \"",
+ Tcl_GetString(pathPtr), "\": ",
+ Tcl_PosixError(interp), (char *) NULL);
+ }
+ return NULL;
}
-
+
channel = NULL;
- switch (FileGetType(handle)) {
+ switch ( FileGetType(handle) ) {
case FILE_TYPE_SERIAL:
/*
- * Reopen channel for OVERLAPPED operation. Normally this shouldn't
- * fail, because the channel exists.
+ * Reopen channel for OVERLAPPED operation
+ * Normally this shouldn't fail, because the channel exists
*/
-
handle = TclWinSerialReopen(handle, nativeName, accessMode);
if (handle == INVALID_HANDLE_VALUE) {
TclWinConvertError(GetLastError());
if (interp != (Tcl_Interp *) NULL) {
Tcl_AppendResult(interp, "couldn't reopen serial \"",
- TclGetString(pathPtr), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_GetString(pathPtr), "\": ",
+ Tcl_PosixError(interp), (char *) NULL);
}
return NULL;
}
channel = TclWinOpenSerialChannel(handle, channelName,
- channelPermissions);
+ channelPermissions);
break;
case FILE_TYPE_CONSOLE:
channel = TclWinOpenConsoleChannel(handle, channelName,
- channelPermissions);
+ channelPermissions);
break;
case FILE_TYPE_PIPE:
if (channelPermissions & TCL_READABLE) {
@@ -986,18 +919,20 @@ TclpOpenFileChannel(
case FILE_TYPE_DISK:
case FILE_TYPE_UNKNOWN:
channel = TclWinOpenFileChannel(handle, channelName,
- channelPermissions, (mode & O_APPEND) ? FILE_APPEND : 0);
+ channelPermissions,
+ (mode & O_APPEND) ? FILE_APPEND : 0);
break;
default:
/*
- * The handle is of an unknown type, probably /dev/nul equivalent or
- * possibly a closed handle.
+ * The handle is of an unknown type, probably /dev/nul equivalent
+ * or possibly a closed handle.
*/
-
+
channel = NULL;
- Tcl_AppendResult(interp, "couldn't open \"", TclGetString(pathPtr),
- "\": bad file type", NULL);
+ Tcl_AppendResult(interp, "couldn't open \"",
+ Tcl_GetString(pathPtr), "\": ",
+ "bad file type", (char *) NULL);
break;
}
@@ -1009,7 +944,8 @@ TclpOpenFileChannel(
*
* Tcl_MakeFileChannel --
*
- * Creates a Tcl_Channel from an existing platform specific file handle.
+ * Creates a Tcl_Channel from an existing platform specific file
+ * handle.
*
* Results:
* The Tcl_Channel created around the preexisting file.
@@ -1021,10 +957,10 @@ TclpOpenFileChannel(
*/
Tcl_Channel
-Tcl_MakeFileChannel(
- ClientData rawHandle, /* OS level handle */
- int mode) /* ORed combination of TCL_READABLE and
- * TCL_WRITABLE to indicate file mode. */
+Tcl_MakeFileChannel(rawHandle, mode)
+ ClientData rawHandle; /* OS level handle */
+ int mode; /* ORed combination of TCL_READABLE and
+ * TCL_WRITABLE to indicate file mode. */
{
#if defined(HAVE_NO_SEH) && !defined(_WIN64)
EXCEPTION_REGISTRATION registration;
@@ -1033,14 +969,16 @@ Tcl_MakeFileChannel(
Tcl_Channel channel = NULL;
HANDLE handle = (HANDLE) rawHandle;
HANDLE dupedHandle;
- TclFile readFile = NULL, writeFile = NULL;
+ TclFile readFile = NULL;
+ TclFile writeFile = NULL;
BOOL result;
if (mode == 0) {
return NULL;
}
- switch (FileGetType(handle)) {
+ switch (FileGetType(handle))
+ {
case FILE_TYPE_SERIAL:
channel = TclWinOpenSerialChannel(handle, channelName, mode);
break;
@@ -1048,10 +986,12 @@ Tcl_MakeFileChannel(
channel = TclWinOpenConsoleChannel(handle, channelName, mode);
break;
case FILE_TYPE_PIPE:
- if (mode & TCL_READABLE) {
+ if (mode & TCL_READABLE)
+ {
readFile = TclWinMakeFile(handle);
}
- if (mode & TCL_WRITABLE) {
+ if (mode & TCL_WRITABLE)
+ {
writeFile = TclWinMakeFile(handle);
}
channel = TclpCreateCommandChannel(readFile, writeFile, NULL, 0, NULL);
@@ -1061,14 +1001,14 @@ Tcl_MakeFileChannel(
case FILE_TYPE_CHAR:
channel = TclWinOpenFileChannel(handle, channelName, mode, 0);
break;
-
+
case FILE_TYPE_UNKNOWN:
default:
/*
- * The handle is of an unknown type. Test the validity of this OS
- * handle by duplicating it, then closing the dupe. The Win32 API
+ * The handle is of an unknown type. Test the validity of this OS
+ * handle by duplicating it, then closing the dupe. The Win32 API
* doesn't provide an IsValidHandle() function, so we have to emulate
- * it here. This test will not work on a console handle reliably,
+ * it here. This test will not work on a console handle reliably,
* which is why we can't test every handle that comes into this
* function in this way.
*/
@@ -1078,7 +1018,7 @@ Tcl_MakeFileChannel(
DUPLICATE_SAME_ACCESS);
if (result == 0) {
- /*
+ /*
* Unable to make a duplicate. It's definately invalid at this
* point.
*/
@@ -1094,11 +1034,12 @@ Tcl_MakeFileChannel(
result = 0;
#if defined(HAVE_NO_SEH) && !defined(_WIN64)
/*
- * Don't have SEH available, do things the hard way. Note that this
- * needs to be one block of asm, to avoid stack imbalance; also, it is
- * illegal for one asm block to contain a jump to another.
+ * Don't have SEH available, do things the hard way.
+ * Note that this needs to be one block of asm, to avoid stack
+ * imbalance; also, it is illegal for one asm block to contain
+ * a jump to another.
*/
-
+
__asm__ __volatile__ (
/*
@@ -1108,10 +1049,9 @@ Tcl_MakeFileChannel(
"movl %[dupedHandle], %%ebx" "\n\t"
/*
- * Construct an EXCEPTION_REGISTRATION to protect the call to
- * CloseHandle.
+ * Construct an EXCEPTION_REGISTRATION to protect the
+ * call to CloseHandle
*/
-
"leal %[registration], %%edx" "\n\t"
"movl %%fs:0, %%eax" "\n\t"
"movl %%eax, 0x0(%%edx)" "\n\t" /* link */
@@ -1120,49 +1060,45 @@ Tcl_MakeFileChannel(
"movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
"movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
"movl $0, 0x10(%%edx)" "\n\t" /* status */
-
- /*
- * Link the EXCEPTION_REGISTRATION on the chain.
- */
-
+
+ /* Link the EXCEPTION_REGISTRATION on the chain */
+
"movl %%edx, %%fs:0" "\n\t"
-
- /*
- * Call CloseHandle(dupedHandle).
- */
-
+
+ /* Call CloseHandle( dupedHandle ) */
+
"pushl %%ebx" "\n\t"
"call _CloseHandle@4" "\n\t"
-
- /*
- * Come here on normal exit. Recover the EXCEPTION_REGISTRATION
+
+ /*
+ * Come here on normal exit. Recover the EXCEPTION_REGISTRATION
* and put a TRUE status return into it.
*/
-
+
"movl %%fs:0, %%edx" "\n\t"
"movl $1, %%eax" "\n\t"
"movl %%eax, 0x10(%%edx)" "\n\t"
"jmp 2f" "\n"
-
+
/*
- * Come here on an exception. Recover the EXCEPTION_REGISTRATION
+ * Come here on an exception. Recover the EXCEPTION_REGISTRATION
*/
-
+
"1:" "\t"
"movl %%fs:0, %%edx" "\n\t"
"movl 0x8(%%edx), %%edx" "\n\t"
-
- /*
- * Come here however we exited. Restore context from the
+
+ /*
+ * Come here however we exited. Restore context from the
* EXCEPTION_REGISTRATION in case the stack is unbalanced.
*/
-
+
"2:" "\t"
"movl 0xc(%%edx), %%esp" "\n\t"
"movl 0x8(%%edx), %%ebp" "\n\t"
"movl 0x0(%%edx), %%eax" "\n\t"
"movl %%eax, %%fs:0" "\n\t"
-
+
:
/* No outputs */
:
@@ -1172,6 +1108,7 @@ Tcl_MakeFileChannel(
"%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"
);
result = registration.status;
+
#else
#ifndef HAVE_NO_SEH
__try {
@@ -1186,9 +1123,9 @@ Tcl_MakeFileChannel(
return NULL;
}
+ /* Fall through, the handle is valid. */
+
/*
- * Fall through, the handle is valid.
- *
* Create the undefined channel, anyways, because we know the handle
* is valid to something.
*/
@@ -1210,42 +1147,42 @@ Tcl_MakeFileChannel(
* Returns the specified default standard channel, or NULL.
*
* Side effects:
- * May cause the creation of a standard channel and the underlying file.
+ * May cause the creation of a standard channel and the underlying
+ * file.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
-TclpGetDefaultStdChannel(
- int type) /* One of TCL_STDIN, TCL_STDOUT, or
- * TCL_STDERR. */
+TclpGetDefaultStdChannel(type)
+ int type; /* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
Tcl_Channel channel;
HANDLE handle;
int mode = -1;
char *bufMode = NULL;
- DWORD handleId = (DWORD)-1;
+ DWORD handleId = (DWORD)INVALID_HANDLE_VALUE;
/* Standard handle to retrieve. */
switch (type) {
- case TCL_STDIN:
- handleId = STD_INPUT_HANDLE;
- mode = TCL_READABLE;
- bufMode = "line";
- break;
- case TCL_STDOUT:
- handleId = STD_OUTPUT_HANDLE;
- mode = TCL_WRITABLE;
- bufMode = "line";
- break;
- case TCL_STDERR:
- handleId = STD_ERROR_HANDLE;
- mode = TCL_WRITABLE;
- bufMode = "none";
- break;
- default:
- Tcl_Panic("TclGetDefaultStdChannel: Unexpected channel type");
- break;
+ case TCL_STDIN:
+ handleId = STD_INPUT_HANDLE;
+ mode = TCL_READABLE;
+ bufMode = "line";
+ break;
+ case TCL_STDOUT:
+ handleId = STD_OUTPUT_HANDLE;
+ mode = TCL_WRITABLE;
+ bufMode = "line";
+ break;
+ case TCL_STDERR:
+ handleId = STD_ERROR_HANDLE;
+ mode = TCL_WRITABLE;
+ bufMode = "none";
+ break;
+ default:
+ panic("TclGetDefaultStdChannel: Unexpected channel type");
+ break;
}
handle = GetStdHandle(handleId);
@@ -1270,121 +1207,126 @@ TclpGetDefaultStdChannel(
* Set up the normal channel options for stdio handles.
*/
- if (Tcl_SetChannelOption(NULL,channel,"-translation","auto")!=TCL_OK ||
- Tcl_SetChannelOption(NULL,channel,"-eofchar","\032 {}")!=TCL_OK ||
- Tcl_SetChannelOption(NULL,channel,"-buffering",bufMode)!=TCL_OK) {
- Tcl_Close(NULL, channel);
- return (Tcl_Channel) NULL;
+ if ((Tcl_SetChannelOption((Tcl_Interp *) NULL, channel, "-translation",
+ "auto") == TCL_ERROR)
+ || (Tcl_SetChannelOption((Tcl_Interp *) NULL, channel, "-eofchar",
+ "\032 {}") == TCL_ERROR)
+ || (Tcl_SetChannelOption((Tcl_Interp *) NULL, channel,
+ "-buffering", bufMode) == TCL_ERROR)) {
+ Tcl_Close((Tcl_Interp *) NULL, channel);
+ return (Tcl_Channel) NULL;
}
return channel;
}
+
+
/*
*----------------------------------------------------------------------
*
* TclWinOpenFileChannel --
*
- * Constructs a File channel for the specified standard OS handle. This
- * is a helper function to break up the construction of channels into
- * File, Console, or Serial.
+ * Constructs a File channel for the specified standard OS handle.
+ * This is a helper function to break up the construction of
+ * channels into File, Console, or Serial.
*
* Results:
* Returns the new channel, or NULL.
*
* Side effects:
- * May open the channel and may cause creation of a file on the file
- * system.
+ * May open the channel and may cause creation of a file on the
+ * file system.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
-TclWinOpenFileChannel(
- HANDLE handle, /* Win32 HANDLE to swallow */
- char *channelName, /* Buffer to receive channel name */
- int permissions, /* OR'ed combination of TCL_READABLE,
- * TCL_WRITABLE, or TCL_EXCEPTION, indicating
- * which operations are valid on the file. */
- int appendMode) /* OR'ed combination of bits indicating what
- * additional configuration of the channel is
- * present. */
+TclWinOpenFileChannel(handle, channelName, permissions, appendMode)
+ HANDLE handle;
+ char *channelName;
+ int permissions;
+ int appendMode;
{
FileInfo *infoPtr;
- ThreadSpecificData *tsdPtr = FileInit();
+ ThreadSpecificData *tsdPtr;
+
+ tsdPtr = FileInit();
/*
* See if a channel with this handle already exists.
*/
-
- for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
- infoPtr = infoPtr->nextPtr) {
+
+ for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
+ infoPtr = infoPtr->nextPtr) {
if (infoPtr->handle == (HANDLE) handle) {
- return (permissions==infoPtr->validMask) ? infoPtr->channel : NULL;
+ return (permissions == infoPtr->validMask) ? infoPtr->channel : NULL;
}
}
infoPtr = (FileInfo *) ckalloc((unsigned) sizeof(FileInfo));
-
- /*
- * TIP #218. Removed the code inserting the new structure into the global
- * list. This is now handled in the thread action callbacks, and only
- * there.
+ /* TIP #218. Removed the code inserting the new structure
+ * into the global list. This is now handled in the thread
+ * action callbacks, and only there.
*/
-
infoPtr->nextPtr = NULL;
infoPtr->validMask = permissions;
infoPtr->watchMask = 0;
infoPtr->flags = appendMode;
infoPtr->handle = handle;
infoPtr->dirty = 0;
- wsprintfA(channelName, "file%lx", PTR2INT(infoPtr));
-
+ wsprintfA(channelName, "file%lx", (int) infoPtr);
+
infoPtr->channel = Tcl_CreateChannel(&fileChannelType, channelName,
(ClientData) infoPtr, permissions);
-
+
/*
- * Files have default translation of AUTO and ^Z eof char, which means
- * that a ^Z will be accepted as EOF when reading.
+ * Files have default translation of AUTO and ^Z eof char, which
+ * means that a ^Z will be accepted as EOF when reading.
*/
-
+
Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
return infoPtr->channel;
}
-
+
+
/*
*----------------------------------------------------------------------
*
* TclWinFlushDirtyChannels --
*
- * Flush all dirty channels to disk, so that requesting the size of any
- * file returns the correct value.
+ * Flush all dirty channels to disk, so that requesting the
+ * size of any file returns the correct value.
*
* Results:
* None.
*
* Side effects:
- * Information is actually written to disk now, rather than later. Don't
- * call this too often, or there will be a performance hit (i.e. only
- * call when we need to ask for the size of a file).
+ * Information is actually written to disk now, rather than
+ * later. Don't call this too often, or there will be a
+ * performance hit (i.e. only call when we need to ask for
+ * the size of a file).
*
*----------------------------------------------------------------------
*/
void
-TclWinFlushDirtyChannels(void)
+TclWinFlushDirtyChannels ()
{
FileInfo *infoPtr;
- ThreadSpecificData *tsdPtr = FileInit();
+ ThreadSpecificData *tsdPtr;
+
+ tsdPtr = FileInit();
/*
- * Flush all channels which are dirty, i.e. may have data pending in the
- * OS.
+ * Flush all channels which are dirty, i.e. may have data pending
+ * in the OS
*/
-
- for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
- infoPtr = infoPtr->nextPtr) {
+
+ for (infoPtr = tsdPtr->firstFilePtr;
+ infoPtr != NULL;
+ infoPtr = infoPtr->nextPtr) {
if (infoPtr->dirty) {
FlushFileBuffers(infoPtr->handle);
infoPtr->dirty = 0;
@@ -1409,41 +1351,42 @@ TclWinFlushDirtyChannels(void)
*/
static void
-FileThreadActionProc(
- ClientData instanceData,
- int action)
+FileThreadActionProc (instanceData, action)
+ ClientData instanceData;
+ int action;
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
FileInfo *infoPtr = (FileInfo *) instanceData;
if (action == TCL_CHANNEL_THREAD_INSERT) {
- infoPtr->nextPtr = tsdPtr->firstFilePtr;
+ infoPtr->nextPtr = tsdPtr->firstFilePtr;
tsdPtr->firstFilePtr = infoPtr;
} else {
- FileInfo **nextPtrPtr;
+ FileInfo **nextPtrPtr;
int removed = 0;
for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
- nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
+ nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
if ((*nextPtrPtr) == infoPtr) {
- (*nextPtrPtr) = infoPtr->nextPtr;
+ (*nextPtrPtr) = infoPtr->nextPtr;
removed = 1;
break;
}
}
/*
- * This could happen if the channel was created in one thread and then
- * moved to another without updating the thread local data in each
- * thread.
+ * This could happen if the channel was created in one thread
+ * and then moved to another without updating the thread
+ * local data in each thread.
*/
if (!removed) {
- Tcl_Panic("file info ptr not on thread channel list");
+ panic("file info ptr not on thread channel list");
}
}
}
-
+
+
/*
*----------------------------------------------------------------------
*
@@ -1461,42 +1404,31 @@ FileThreadActionProc(
*/
DWORD
-FileGetType(
- HANDLE handle) /* Opened file handle */
-{
+FileGetType(handle)
+ HANDLE handle; /* Opened file handle */
+{
DWORD type;
+ DWORD consoleParams;
+ DCB dcb;
type = GetFileType(handle);
/*
- * If the file is a character device, we need to try to figure out whether
- * it is a serial port, a console, or something else. We test for the
- * console case first because this is more common.
+ * If the file is a character device, we need to try to figure out
+ * whether it is a serial port, a console, or something else. We
+ * test for the console case first because this is more common.
*/
-
- if ((type == FILE_TYPE_CHAR)
- || ((type == FILE_TYPE_UNKNOWN) && !GetLastError())) {
- DWORD consoleParams;
-
- if (GetConsoleMode(handle, &consoleParams)) {
- type = FILE_TYPE_CONSOLE;
- } else {
- DCB dcb;
-
- dcb.DCBlength = sizeof(DCB);
- if (GetCommState(handle, &dcb)) {
- type = FILE_TYPE_SERIAL;
- }
- }
+
+ if (type == FILE_TYPE_CHAR || (type == FILE_TYPE_UNKNOWN && !GetLastError())) {
+ if (GetConsoleMode(handle, &consoleParams)) {
+ type = FILE_TYPE_CONSOLE;
+ } else {
+ dcb.DCBlength = sizeof( DCB ) ;
+ if (GetCommState(handle, &dcb)) {
+ type = FILE_TYPE_SERIAL;
+ }
+ }
}
return type;
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c
index 8be8e09..d036bda 100644
--- a/win/tclWinConsole.c
+++ b/win/tclWinConsole.c
@@ -1,13 +1,13 @@
-/*
+/*
* tclWinConsole.c --
*
- * This file implements the Windows-specific console functions, and the
- * "console" channel driver.
+ * This file implements the Windows-specific console functions,
+ * and the "console" channel driver.
*
* Copyright (c) 1999 by Scriptics Corp.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclWinInt.h"
@@ -43,11 +43,10 @@ TCL_DECLARE_MUTEX(consoleMutex)
*/
#define CONSOLE_EOF (1<<2) /* Console has reached EOF. */
-#define CONSOLE_BUFFERED (1<<3) /* Data was read into a buffer by the reader
- * thread. */
+#define CONSOLE_BUFFERED (1<<3) /* data was read into a buffer by the reader
+ thread */
#define CONSOLE_BUFFER_SIZE (8*1024)
-
/*
* This structure describes per-instance data for a console based channel.
*/
@@ -70,47 +69,52 @@ typedef struct ConsoleInfo {
HANDLE writeThread; /* Handle to writer thread. */
HANDLE readThread; /* Handle to reader thread. */
HANDLE writable; /* Manual-reset event to signal when the
- * writer thread has finished waiting for the
- * current buffer to be written. */
+ * writer thread has finished waiting for
+ * the current buffer to be written. */
HANDLE readable; /* Manual-reset event to signal when the
* reader thread has finished waiting for
* input. */
HANDLE startWriter; /* Auto-reset event used by the main thread to
- * signal when the writer thread should
- * attempt to write to the console. */
+ * signal when the writer thread should attempt
+ * to write to the console. */
HANDLE stopWriter; /* Auto-reset event used by the main thread to
- * signal when the writer thread should exit */
+ * signal when the writer thread should exit.
+ */
HANDLE startReader; /* Auto-reset event used by the main thread to
- * signal when the reader thread should
- * attempt to read from the console. */
+ * signal when the reader thread should attempt
+ * to read from the console. */
HANDLE stopReader; /* Auto-reset event used by the main thread to
- * signal when the reader thread should exit */
+ * signal when the reader thread should exit.
+ */
DWORD writeError; /* An error caused by the last background
- * write. Set to 0 if no error has been
- * detected. This word is shared with the
+ * write. Set to 0 if no error has been
+ * detected. This word is shared with the
* writer thread so access must be
- * synchronized with the writable object. */
- char *writeBuf; /* Current background output buffer. Access is
- * synchronized with the writable object. */
- int writeBufLen; /* Size of write buffer. Access is
- * synchronized with the writable object. */
- int toWrite; /* Current amount to be written. Access is
+ * synchronized with the writable object.
+ */
+ char *writeBuf; /* Current background output buffer.
+ * Access is synchronized with the writable
+ * object. */
+ int writeBufLen; /* Size of write buffer. Access is
+ * synchronized with the writable
+ * object. */
+ int toWrite; /* Current amount to be written. Access is
* synchronized with the writable object. */
int readFlags; /* Flags that are shared with the reader
- * thread. Access is synchronized with the
- * readable object. */
- int bytesRead; /* number of bytes in the buffer */
- int offset; /* number of bytes read out of the buffer */
+ * thread. Access is synchronized with the
+ * readable object. */
+ int bytesRead; /* number of bytes in the buffer */
+ int offset; /* number of bytes read out of the buffer */
char buffer[CONSOLE_BUFFER_SIZE];
- /* Data consumed by reader thread. */
+ /* Data consumed by reader thread. */
} ConsoleInfo;
typedef struct ThreadSpecificData {
/*
- * The following pointer refers to the head of the list of consoles that
- * are being watched for file events.
+ * The following pointer refers to the head of the list of consoles
+ * that are being watched for file events.
*/
-
+
ConsoleInfo *firstConsolePtr;
} ThreadSpecificData;
@@ -122,9 +126,9 @@ static Tcl_ThreadDataKey dataKey;
*/
typedef struct ConsoleEvent {
- Tcl_Event header; /* Information that is standard for all
- * events. */
- ConsoleInfo *infoPtr; /* Pointer to console info structure. Note
+ Tcl_Event header; /* Information that is standard for
+ * all events. */
+ ConsoleInfo *infoPtr; /* Pointer to console info structure. Note
* that we still have to verify that the
* console exists before dereferencing this
* pointer. */
@@ -134,7 +138,7 @@ typedef struct ConsoleEvent {
* Declarations for functions used only in this file.
*/
-static int ConsoleBlockModeProc(ClientData instanceData,int mode);
+static int ConsoleBlockModeProc(ClientData instanceData, int mode);
static void ConsoleCheckProc(ClientData clientData, int flags);
static int ConsoleCloseProc(ClientData instanceData,
Tcl_Interp *interp);
@@ -142,7 +146,7 @@ static int ConsoleEventProc(Tcl_Event *evPtr, int flags);
static void ConsoleExitHandler(ClientData clientData);
static int ConsoleGetHandleProc(ClientData instanceData,
int direction, ClientData *handlePtr);
-static void ConsoleInit(void);
+static void ConsoleInit(void);
static int ConsoleInputProc(ClientData instanceData, char *buf,
int toRead, int *errorCode);
static int ConsoleOutputProc(ClientData instanceData,
@@ -153,8 +157,9 @@ static void ConsoleWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI ConsoleWriterThread(LPVOID arg);
static void ProcExitHandler(ClientData clientData);
static int WaitForRead(ConsoleInfo *infoPtr, int blocking);
-static void ConsoleThreadActionProc(ClientData instanceData,
- int action);
+
+static void ConsoleThreadActionProc _ANSI_ARGS_ ((
+ ClientData instanceData, int action));
/*
* This structure describes the channel type structure for command console
@@ -163,7 +168,7 @@ static void ConsoleThreadActionProc(ClientData instanceData,
static Tcl_ChannelType consoleChannelType = {
"console", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
+ TCL_CHANNEL_VERSION_4, /* v4 channel */
ConsoleCloseProc, /* Close proc. */
ConsoleInputProc, /* Input proc. */
ConsoleOutputProc, /* Output proc. */
@@ -176,57 +181,13 @@ static Tcl_ChannelType consoleChannelType = {
ConsoleBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
- NULL, /* wide seek proc */
+ NULL, /* wide seek proc */
ConsoleThreadActionProc, /* thread action proc */
- NULL, /* truncation */
};
/*
*----------------------------------------------------------------------
*
- * readConsoleBytes, writeConsoleBytes --
- * Wrapper for ReadConsole{A,W}, that takes and returns number of bytes
- * instead of number of TCHARS
- */
-static BOOL
-readConsoleBytes(
- HANDLE hConsole,
- LPVOID lpBuffer,
- DWORD nbytes,
- LPDWORD nbytesread)
-{
- DWORD ntchars;
- BOOL result;
- int tcharsize;
- tcharsize = tclWinProcs->useWide? 2 : 1;
- result = tclWinProcs->readConsoleProc(
- hConsole, lpBuffer, nbytes / tcharsize, &ntchars, NULL);
- if (nbytesread)
- *nbytesread = (ntchars*tcharsize);
- return result;
-}
-
-static BOOL
-writeConsoleBytes(
- HANDLE hConsole,
- const VOID *lpBuffer,
- DWORD nbytes,
- LPDWORD nbyteswritten)
-{
- DWORD ntchars;
- BOOL result;
- int tcharsize;
- tcharsize = tclWinProcs->useWide? 2 : 1;
- result = tclWinProcs->writeConsoleProc(
- hConsole, lpBuffer, nbytes / tcharsize, &ntchars, NULL);
- if (nbyteswritten)
- *nbyteswritten = (ntchars*tcharsize);
- return result;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* ConsoleInit --
*
* This function initializes the static variables for this file.
@@ -241,13 +202,13 @@ writeConsoleBytes(
*/
static void
-ConsoleInit(void)
+ConsoleInit()
{
ThreadSpecificData *tsdPtr;
/*
- * Check the initialized flag first, then check again in the mutex. This
- * is a speed enhancement.
+ * Check the initialized flag first, then check again in the mutex.
+ * This is a speed enhancement.
*/
if (!initialized) {
@@ -273,8 +234,8 @@ ConsoleInit(void)
*
* ConsoleExitHandler --
*
- * This function is called to cleanup the console module before Tcl is
- * unloaded.
+ * This function is called to cleanup the console module before
+ * Tcl is unloaded.
*
* Results:
* None.
@@ -297,8 +258,8 @@ ConsoleExitHandler(
*
* ProcExitHandler --
*
- * This function is called to cleanup the process list before Tcl is
- * unloaded.
+ * This function is called to cleanup the process list before
+ * Tcl is unloaded.
*
* Results:
* None.
@@ -323,8 +284,8 @@ ProcExitHandler(
*
* ConsoleSetupProc --
*
- * This procedure is invoked before Tcl_DoOneEvent blocks waiting for an
- * event.
+ * This procedure is invoked before Tcl_DoOneEvent blocks waiting
+ * for an event.
*
* Results:
* None.
@@ -348,12 +309,12 @@ ConsoleSetupProc(
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
-
+
/*
- * Look to see if any events are already pending. If they are, poll.
+ * Look to see if any events are already pending. If they are, poll.
*/
- for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
+ for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr->watchMask & TCL_WRITABLE) {
if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
@@ -376,8 +337,8 @@ ConsoleSetupProc(
*
* ConsoleCheckProc --
*
- * This procedure is called by Tcl_DoOneEvent to check the console event
- * source for events.
+ * This procedure is called by Tcl_DoOneEvent to check the console
+ * event source for events.
*
* Results:
* None.
@@ -401,18 +362,18 @@ ConsoleCheckProc(
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
-
+
/*
* Queue events for any ready consoles that don't already have events
* queued.
*/
- for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
+ for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr->flags & CONSOLE_PENDING) {
continue;
}
-
+
/*
* Queue an event if the console is signaled for reading or writing.
*/
@@ -423,7 +384,7 @@ ConsoleCheckProc(
needEvent = 1;
}
}
-
+
if (infoPtr->watchMask & TCL_READABLE) {
if (WaitForRead(infoPtr, 0) >= 0) {
needEvent = 1;
@@ -461,16 +422,15 @@ static int
ConsoleBlockModeProc(
ClientData instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
- * TCL_MODE_NONBLOCKING. */
+ * TCL_MODE_NONBLOCKING. */
{
ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
-
+
/*
- * Consoles on Windows can not be switched between blocking and
- * nonblocking, hence we have to emulate the behavior. This is done in the
- * input function by checking against a bit in the state. We set or unset
- * the bit here to cause the input function to emulate the correct
- * behavior.
+ * Consoles on Windows can not be switched between blocking and nonblocking,
+ * hence we have to emulate the behavior. This is done in the input
+ * function by checking against a bit in the state. We set or unset the
+ * bit here to cause the input function to emulate the correct behavior.
*/
if (mode == TCL_MODE_NONBLOCKING) {
@@ -509,25 +469,27 @@ ConsoleCloseProc(
DWORD exitCode;
errorCode = 0;
-
+
/*
- * Clean up the background thread if necessary. Note that this must be
- * done before we can close the file, since the thread may be blocking
- * trying to read from the console.
+ * Clean up the background thread if necessary. Note that this
+ * must be done before we can close the file, since the
+ * thread may be blocking trying to read from the console.
*/
-
+
if (consolePtr->readThread) {
+
/*
- * The thread may already have closed on it's own. Check it's exit
- * code.
+ * The thread may already have closed on it's own. Check it's
+ * exit code.
*/
GetExitCodeThread(consolePtr->readThread, &exitCode);
if (exitCode == STILL_ACTIVE) {
+
/*
- * Set the stop event so that if the reader thread is blocked in
- * ConsoleReaderThread on WaitForMultipleEvents, it will exit
+ * Set the stop event so that if the reader thread is blocked
+ * in ConsoleReaderThread on WaitForMultipleEvents, it will exit
* cleanly.
*/
@@ -540,10 +502,11 @@ ConsoleCloseProc(
if (WaitForSingleObject(consolePtr->readThread, 20)
== WAIT_TIMEOUT) {
/*
- * Forcibly terminate the background thread as a last resort.
- * Note that we need to guard against terminating the thread
- * while it is in the middle of Tcl_ThreadAlert because it
- * won't be able to release the notifier lock.
+ * Forcibly terminate the background thread as a last
+ * resort. Note that we need to guard against
+ * terminating the thread while it is in the middle of
+ * Tcl_ThreadAlert because it won't be able to release
+ * the notifier lock.
*/
Tcl_MutexLock(&consoleMutex);
@@ -563,33 +526,32 @@ ConsoleCloseProc(
consolePtr->validMask &= ~TCL_READABLE;
/*
- * Wait for the writer thread to finish the current buffer, then terminate
- * the thread and close the handles. If the channel is nonblocking, there
- * should be no pending write operations.
+ * Wait for the writer thread to finish the current buffer, then
+ * terminate the thread and close the handles. If the channel is
+ * nonblocking, there should be no pending write operations.
*/
-
+
if (consolePtr->writeThread) {
if (consolePtr->toWrite) {
/*
- * We only need to wait if there is something to write. This may
- * prevent infinite wait on exit. [python bug 216289]
+ * We only need to wait if there is something to write.
+ * This may prevent infinite wait on exit. [python bug 216289]
*/
-
WaitForSingleObject(consolePtr->writable, INFINITE);
}
/*
- * The thread may already have closed on it's own. Check it's exit
- * code.
+ * The thread may already have closed on it's own. Check it's
+ * exit code.
*/
GetExitCodeThread(consolePtr->writeThread, &exitCode);
if (exitCode == STILL_ACTIVE) {
/*
- * Set the stop event so that if the reader thread is blocked in
- * ConsoleWriterThread on WaitForMultipleEvents, it will exit
- * cleanly.
+ * Set the stop event so that if the reader thread is blocked
+ * in ConsoleWriterThread on WaitForMultipleEvents, it will
+ * exit cleanly.
*/
SetEvent(consolePtr->stopWriter);
@@ -601,10 +563,11 @@ ConsoleCloseProc(
if (WaitForSingleObject(consolePtr->writeThread, 20)
== WAIT_TIMEOUT) {
/*
- * Forcibly terminate the background thread as a last resort.
- * Note that we need to guard against terminating the thread
- * while it is in the middle of Tcl_ThreadAlert because it
- * won't be able to release the notifier lock.
+ * Forcibly terminate the background thread as a last
+ * resort. Note that we need to guard against
+ * terminating the thread while it is in the middle of
+ * Tcl_ThreadAlert because it won't be able to release
+ * the notifier lock.
*/
Tcl_MutexLock(&consoleMutex);
@@ -625,12 +588,12 @@ ConsoleCloseProc(
/*
- * Don't close the Win32 handle if the handle is a standard channel during
- * the thread exit process. Otherwise, one thread may kill the stdio of
- * another.
+ * Don't close the Win32 handle if the handle is a standard channel
+ * during the thread exit process. Otherwise, one thread may kill
+ * the stdio of another.
*/
- if (!TclInThreadExit()
+ if (!TclInThreadExit()
|| ((GetStdHandle(STD_INPUT_HANDLE) != consolePtr->handle)
&& (GetStdHandle(STD_OUTPUT_HANDLE) != consolePtr->handle)
&& (GetStdHandle(STD_ERROR_HANDLE) != consolePtr->handle))) {
@@ -639,7 +602,7 @@ ConsoleCloseProc(
errorCode = errno;
}
}
-
+
consolePtr->watchMask &= consolePtr->validMask;
/*
@@ -668,8 +631,8 @@ ConsoleCloseProc(
*
* ConsoleInputProc --
*
- * Reads input from the IO channel into the buffer given. Returns count
- * of how many bytes were actually read, and an error indication.
+ * Reads input from the IO channel into the buffer given. Returns
+ * count of how many bytes were actually read, and an error indication.
*
* Results:
* A count of how many bytes were read is returned and an error
@@ -683,11 +646,11 @@ ConsoleCloseProc(
static int
ConsoleInputProc(
- ClientData instanceData, /* Console state. */
- char *buf, /* Where to store data read. */
- int bufSize, /* How much space is available in the
- * buffer? */
- int *errorCode) /* Where to store error code. */
+ ClientData instanceData, /* Console state. */
+ char *buf, /* Where to store data read. */
+ int bufSize, /* How much space is available
+ * in the buffer? */
+ int *errorCode) /* Where to store error code. */
{
ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
DWORD count, bytesRead = 0;
@@ -698,13 +661,13 @@ ConsoleInputProc(
/*
* Synchronize with the reader thread.
*/
-
+
result = WaitForRead(infoPtr, (infoPtr->flags & CONSOLE_ASYNC) ? 0 : 1);
-
+
/*
* If an error occurred, return immediately.
*/
-
+
if (result == -1) {
*errorCode = errno;
return -1;
@@ -726,22 +689,22 @@ ConsoleInputProc(
/*
* Reset the buffer
*/
-
+
infoPtr->readFlags &= ~CONSOLE_BUFFERED;
infoPtr->offset = 0;
}
return bytesRead;
}
-
+
/*
- * Attempt to read bufSize bytes. The read will return immediately if
- * there is any data available. Otherwise it will block until at least one
- * byte is available or an EOF occurs.
+ * Attempt to read bufSize bytes. The read will return immediately
+ * if there is any data available. Otherwise it will block until
+ * at least one byte is available or an EOF occurs.
*/
- if (readConsoleBytes(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &count)
- == TRUE) {
+ if (ReadConsole(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &count,
+ NULL) == TRUE) {
buf[count] = '\0';
return count;
}
@@ -754,12 +717,12 @@ ConsoleInputProc(
*
* ConsoleOutputProc --
*
- * Writes the given output on the IO channel. Returns count of how many
- * characters were actually written, and an error indication.
+ * Writes the given output on the IO channel. Returns count of how
+ * many characters were actually written, and an error indication.
*
* Results:
- * A count of how many characters were written is returned and an error
- * indication is returned in an output argument.
+ * A count of how many characters were written is returned and an
+ * error indication is returned in an output argument.
*
* Side effects:
* Writes output on the actual channel.
@@ -769,26 +732,26 @@ ConsoleInputProc(
static int
ConsoleOutputProc(
- ClientData instanceData, /* Console state. */
- CONST char *buf, /* The data buffer. */
- int toWrite, /* How many bytes to write? */
- int *errorCode) /* Where to store error code. */
+ ClientData instanceData, /* Console state. */
+ CONST char *buf, /* The data buffer. */
+ int toWrite, /* How many bytes to write? */
+ int *errorCode) /* Where to store error code. */
{
ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
DWORD bytesWritten, timeout;
-
+
*errorCode = 0;
timeout = (infoPtr->flags & CONSOLE_ASYNC) ? 0 : INFINITE;
if (WaitForSingleObject(infoPtr->writable, timeout) == WAIT_TIMEOUT) {
/*
- * The writer thread is blocked waiting for a write to complete and
- * the channel is in non-blocking mode.
+ * The writer thread is blocked waiting for a write to complete
+ * and the channel is in non-blocking mode.
*/
errno = EAGAIN;
goto error;
}
-
+
/*
* Check for a background error on the last write.
*/
@@ -814,31 +777,31 @@ ConsoleOutputProc(
ckfree(infoPtr->writeBuf);
}
infoPtr->writeBufLen = toWrite;
- infoPtr->writeBuf = ckalloc((size_t)toWrite);
+ infoPtr->writeBuf = ckalloc((unsigned int) toWrite);
}
- memcpy(infoPtr->writeBuf, buf, (size_t)toWrite);
+ memcpy(infoPtr->writeBuf, buf, (size_t) toWrite);
infoPtr->toWrite = toWrite;
ResetEvent(infoPtr->writable);
SetEvent(infoPtr->startWriter);
bytesWritten = toWrite;
} else {
/*
- * In the blocking case, just try to write the buffer directly. This
- * avoids an unnecessary copy.
+ * In the blocking case, just try to write the buffer directly.
+ * This avoids an unnecessary copy.
*/
- if (writeConsoleBytes(infoPtr->handle, buf, (DWORD)toWrite,
- &bytesWritten)
- == FALSE) {
+ if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite,
+ &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) {
TclWinConvertError(GetLastError());
goto error;
}
}
return bytesWritten;
- error:
+ error:
*errorCode = errno;
return -1;
+
}
/*
@@ -846,15 +809,15 @@ ConsoleOutputProc(
*
* ConsoleEventProc --
*
- * This function is invoked by Tcl_ServiceEvent when a file event reaches
- * the front of the event queue. This procedure invokes Tcl_NotifyChannel
- * on the console.
+ * This function is invoked by Tcl_ServiceEvent when a file event
+ * reaches the front of the event queue. This procedure invokes
+ * Tcl_NotifyChannel on the console.
*
* Results:
- * Returns 1 if the event was handled, meaning it should be removed from
- * the queue. Returns 0 if the event was not handled, meaning it should
- * stay on the queue. The only time the event isn't handled is if the
- * TCL_FILE_EVENTS flag bit isn't set.
+ * Returns 1 if the event was handled, meaning it should be removed
+ * from the queue. Returns 0 if the event was not handled, meaning
+ * it should stay on the queue. The only time the event isn't
+ * handled is if the TCL_FILE_EVENTS flag bit isn't set.
*
* Side effects:
* Whatever the notifier callback does.
@@ -865,8 +828,8 @@ ConsoleOutputProc(
static int
ConsoleEventProc(
Tcl_Event *evPtr, /* Event to service. */
- int flags) /* Flags that indicate what events to handle,
- * such as TCL_FILE_EVENTS. */
+ int flags) /* Flags that indicate what events to
+ * handle, such as TCL_FILE_EVENTS. */
{
ConsoleEvent *consoleEvPtr = (ConsoleEvent *)evPtr;
ConsoleInfo *infoPtr;
@@ -879,9 +842,9 @@ ConsoleEventProc(
/*
* Search through the list of watched consoles for the one whose handle
- * matches the event. We do this rather than simply dereferencing the
- * handle in the event so that consoles can be deleted while the event is
- * in the queue.
+ * matches the event. We do this rather than simply dereferencing
+ * the handle in the event so that consoles can be deleted while the
+ * event is in the queue.
*/
for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
@@ -901,9 +864,9 @@ ConsoleEventProc(
}
/*
- * Check to see if the console is readable. Note that we can't tell if a
- * console is writable, so we always report it as being writable unless we
- * have detected EOF.
+ * Check to see if the console is readable. Note
+ * that we can't tell if a console is writable, so we always report it
+ * as being writable unless we have detected EOF.
*/
mask = 0;
@@ -920,7 +883,7 @@ ConsoleEventProc(
} else {
mask |= TCL_READABLE;
}
- }
+ }
}
/*
@@ -936,7 +899,8 @@ ConsoleEventProc(
*
* ConsoleWatchProc --
*
- * Called by the notifier to set up to watch for events on this channel.
+ * Called by the notifier to set up to watch for events on this
+ * channel.
*
* Results:
* None.
@@ -949,10 +913,10 @@ ConsoleEventProc(
static void
ConsoleWatchProc(
- ClientData instanceData, /* Console state. */
- int mask) /* What events to watch for, OR-ed combination
- * of TCL_READABLE, TCL_WRITABLE and
- * TCL_EXCEPTION. */
+ ClientData instanceData, /* Console state. */
+ int mask) /* What events to watch for, OR-ed
+ * combination of TCL_READABLE,
+ * TCL_WRITABLE and TCL_EXCEPTION. */
{
ConsoleInfo **nextPtrPtr, *ptr;
ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
@@ -960,8 +924,9 @@ ConsoleWatchProc(
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
- * Since most of the work is handled by the background threads, we just
- * need to update the watchMask and then force the notifier to poll once.
+ * Since most of the work is handled by the background threads,
+ * we just need to update the watchMask and then force the notifier
+ * to poll once.
*/
infoPtr->watchMask = mask & infoPtr->validMask;
@@ -972,17 +937,19 @@ ConsoleWatchProc(
tsdPtr->firstConsolePtr = infoPtr;
}
Tcl_SetMaxBlockTime(&blockTime);
- } else if (oldMask) {
- /*
- * Remove the console from the list of watched consoles.
- */
+ } else {
+ if (oldMask) {
+ /*
+ * Remove the console from the list of watched consoles.
+ */
- for (nextPtrPtr = &(tsdPtr->firstConsolePtr), ptr = *nextPtrPtr;
- ptr != NULL;
- nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
- if (infoPtr == ptr) {
- *nextPtrPtr = ptr->nextPtr;
- break;
+ for (nextPtrPtr = &(tsdPtr->firstConsolePtr), ptr = *nextPtrPtr;
+ ptr != NULL;
+ nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
+ if (infoPtr == ptr) {
+ *nextPtrPtr = ptr->nextPtr;
+ break;
+ }
}
}
}
@@ -993,12 +960,12 @@ ConsoleWatchProc(
*
* ConsoleGetHandleProc --
*
- * Called from Tcl_GetChannelHandle to retrieve OS handles from inside a
- * command consoleline based channel.
+ * Called from Tcl_GetChannelHandle to retrieve OS handles from
+ * inside a command consoleline based channel.
*
* Results:
- * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if there is no
- * handle for the specified direction.
+ * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
+ * there is no handle for the specified direction.
*
* Side effects:
* None.
@@ -1010,7 +977,7 @@ static int
ConsoleGetHandleProc(
ClientData instanceData, /* The console state. */
int direction, /* TCL_READABLE or TCL_WRITABLE */
- ClientData *handlePtr) /* Where to store the handle. */
+ ClientData *handlePtr) /* Where to store the handle. */
{
ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
@@ -1023,68 +990,69 @@ ConsoleGetHandleProc(
*
* WaitForRead --
*
- * Wait until some data is available, the console is at EOF or the reader
- * thread is blocked waiting for data (if the channel is in non-blocking
- * mode).
+ * Wait until some data is available, the console is at
+ * EOF or the reader thread is blocked waiting for data (if the
+ * channel is in non-blocking mode).
*
* Results:
- * Returns 1 if console is readable. Returns 0 if there is no data on the
- * console, but there is buffered data. Returns -1 if an error occurred.
- * If an error occurred, the threads may not be synchronized.
+ * Returns 1 if console is readable. Returns 0 if there is no data
+ * on the console, but there is buffered data. Returns -1 if an
+ * error occurred. If an error occurred, the threads may not
+ * be synchronized.
*
* Side effects:
- * Updates the shared state flags. If no error occurred, the reader
- * thread is blocked waiting for a signal from the main thread.
+ * Updates the shared state flags. If no error occurred,
+ * the reader thread is blocked waiting for a signal from the
+ * main thread.
*
*----------------------------------------------------------------------
*/
static int
WaitForRead(
- ConsoleInfo *infoPtr, /* Console state. */
- int blocking) /* Indicates whether call should be blocking
- * or not. */
+ ConsoleInfo *infoPtr, /* Console state. */
+ int blocking) /* Indicates whether call should be
+ * blocking or not. */
{
DWORD timeout, count;
HANDLE *handle = infoPtr->handle;
INPUT_RECORD input;
-
+
while (1) {
/*
* Synchronize with the reader thread.
*/
-
+
timeout = blocking ? INFINITE : 0;
if (WaitForSingleObject(infoPtr->readable, timeout) == WAIT_TIMEOUT) {
/*
* The reader thread is blocked waiting for data and the channel
* is in non-blocking mode.
*/
-
errno = EAGAIN;
return -1;
}
-
+
/*
- * At this point, the two threads are synchronized, so it is safe to
- * access shared state.
+ * At this point, the two threads are synchronized, so it is safe
+ * to access shared state.
*/
-
+
/*
* If the console has hit EOF, it is always readable.
*/
-
+
if (infoPtr->readFlags & CONSOLE_EOF) {
return 1;
}
-
+
if (PeekConsoleInput(handle, &input, 1, &count) == FALSE) {
- /*
+ /*
* Check to see if the peek failed because of EOF.
*/
-
+
TclWinConvertError(GetLastError());
-
+
if (errno == EOF) {
infoPtr->readFlags |= CONSOLE_EOF;
return 1;
@@ -1093,7 +1061,7 @@ WaitForRead(
/*
* Ignore errors if there is data in the buffer.
*/
-
+
if (infoPtr->readFlags & CONSOLE_BUFFERED) {
return 0;
} else {
@@ -1102,18 +1070,20 @@ WaitForRead(
}
/*
- * If there is data in the buffer, the console must be readable (since
- * it is a line-oriented device).
+ * If there is data in the buffer, the console must be
+ * readable (since it is a line-oriented device).
*/
if (infoPtr->readFlags & CONSOLE_BUFFERED) {
return 1;
}
+
/*
- * There wasn't any data available, so reset the thread and try again.
+ * There wasn't any data available, so reset the thread and
+ * try again.
*/
-
+
ResetEvent(infoPtr->readable);
SetEvent(infoPtr->startReader);
}
@@ -1124,23 +1094,22 @@ WaitForRead(
*
* ConsoleReaderThread --
*
- * This function runs in a separate thread and waits for input to become
- * available on a console.
+ * This function runs in a separate thread and waits for input
+ * to become available on a console.
*
* Results:
* None.
*
* Side effects:
- * Signals the main thread when input become available. May cause the
- * main thread to wake up by posting a message. May one line from the
- * console for each wait operation.
+ * Signals the main thread when input become available. May
+ * cause the main thread to wake up by posting a message. May
+ * one line from the console for each wait operation.
*
*----------------------------------------------------------------------
*/
static DWORD WINAPI
-ConsoleReaderThread(
- LPVOID arg)
+ConsoleReaderThread(LPVOID arg)
{
ConsoleInfo *infoPtr = (ConsoleInfo *)arg;
HANDLE *handle = infoPtr->handle;
@@ -1160,53 +1129,49 @@ ConsoleReaderThread(
if (waitResult != (WAIT_OBJECT_0 + 1)) {
/*
- * The start event was not signaled. It must be the stop event or
- * an error, so exit this thread.
+ * The start event was not signaled. It must be the stop event
+ * or an error, so exit this thread.
*/
break;
}
- /*
- * Look for data on the console, but first ignore any events that are
- * not KEY_EVENTs.
+ /*
+ * Look for data on the console, but first ignore any events
+ * that are not KEY_EVENTs
*/
-
- if (readConsoleBytes(handle, infoPtr->buffer, CONSOLE_BUFFER_SIZE,
- (LPDWORD) &infoPtr->bytesRead) != FALSE) {
+ if (ReadConsoleA(handle, infoPtr->buffer, CONSOLE_BUFFER_SIZE,
+ (LPDWORD) &infoPtr->bytesRead, NULL) != FALSE) {
/*
* Data was stored in the buffer.
*/
-
+
infoPtr->readFlags |= CONSOLE_BUFFERED;
} else {
DWORD err;
err = GetLastError();
-
+
if (err == (DWORD)EOF) {
infoPtr->readFlags = CONSOLE_EOF;
}
}
/*
- * Signal the main thread by signalling the readable event and then
- * waking up the notifier thread.
+ * Signal the main thread by signalling the readable event and
+ * then waking up the notifier thread.
*/
SetEvent(infoPtr->readable);
/*
- * Alert the foreground thread. Note that we need to treat this like a
- * critical section so the foreground thread does not terminate this
- * thread while we are holding a mutex in the notifier code.
+ * Alert the foreground thread. Note that we need to treat this like
+ * a critical section so the foreground thread does not terminate
+ * this thread while we are holding a mutex in the notifier code.
*/
Tcl_MutexLock(&consoleMutex);
if (infoPtr->threadId != NULL) {
- /*
- * TIP #218. When in flight ignore the event, no one will receive
- * it anyway.
- */
+ /* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
Tcl_MutexUnlock(&consoleMutex);
@@ -1220,23 +1185,21 @@ ConsoleReaderThread(
*
* ConsoleWriterThread --
*
- * This function runs in a separate thread and writes data onto a
- * console.
+ * This function runs in a separate thread and writes data
+ * onto a console.
*
* Results:
* Always returns 0.
*
* Side effects:
-
- * Signals the main thread when an output operation is completed. May
- * cause the main thread to wake up by posting a message.
+ * Signals the main thread when an output operation is completed.
+ * May cause the main thread to wake up by posting a message.
*
*----------------------------------------------------------------------
*/
static DWORD WINAPI
-ConsoleWriterThread(
- LPVOID arg)
+ConsoleWriterThread(LPVOID arg)
{
ConsoleInfo *infoPtr = (ConsoleInfo *)arg;
@@ -1258,8 +1221,8 @@ ConsoleWriterThread(
if (waitResult != (WAIT_OBJECT_0 + 1)) {
/*
- * The start event was not signaled. It must be the stop event or
- * an error, so exit this thread.
+ * The start event was not signaled. It must be the stop event
+ * or an error, so exit this thread.
*/
break;
@@ -1273,8 +1236,7 @@ ConsoleWriterThread(
*/
while (toWrite > 0) {
- if (writeConsoleBytes(handle, buf, (DWORD)toWrite,
- &count) == FALSE) {
+ if (WriteConsoleA(handle, buf, toWrite, &count, NULL) == FALSE) {
infoPtr->writeError = GetLastError();
break;
} else {
@@ -1284,25 +1246,21 @@ ConsoleWriterThread(
}
/*
- * Signal the main thread by signalling the writable event and then
- * waking up the notifier thread.
+ * Signal the main thread by signalling the writable event and
+ * then waking up the notifier thread.
*/
-
+
SetEvent(infoPtr->writable);
/*
- * Alert the foreground thread. Note that we need to treat this like a
- * critical section so the foreground thread does not terminate this
- * thread while we are holding a mutex in the notifier code.
+ * Alert the foreground thread. Note that we need to treat this like
+ * a critical section so the foreground thread does not terminate
+ * this thread while we are holding a mutex in the notifier code.
*/
Tcl_MutexLock(&consoleMutex);
if (infoPtr->threadId != NULL) {
- /*
- * TIP #218. When in flight ignore the event, no one will receive
- * it anyway.
- */
-
+ /* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
Tcl_MutexUnlock(&consoleMutex);
@@ -1310,6 +1268,8 @@ ConsoleWriterThread(
return 0;
}
+
+
/*
*----------------------------------------------------------------------
@@ -1317,8 +1277,8 @@ ConsoleWriterThread(
* TclWinOpenConsoleChannel --
*
* Constructs a Console channel for the specified standard OS handle.
- * This is a helper function to break up the construction of channels
- * into File, Console, or Serial.
+ * This is a helper function to break up the construction of
+ * channels into File, Console, or Serial.
*
* Results:
* Returns the new channel, or NULL.
@@ -1330,10 +1290,10 @@ ConsoleWriterThread(
*/
Tcl_Channel
-TclWinOpenConsoleChannel(
- HANDLE handle,
- char *channelName,
- int permissions)
+TclWinOpenConsoleChannel(handle, channelName, permissions)
+ HANDLE handle;
+ char *channelName;
+ int permissions;
{
char encoding[4 + TCL_INTEGER_SPACE];
ConsoleInfo *infoPtr;
@@ -1344,7 +1304,7 @@ TclWinOpenConsoleChannel(
/*
* See if a channel with this handle already exists.
*/
-
+
infoPtr = (ConsoleInfo *) ckalloc((unsigned) sizeof(ConsoleInfo));
memset(infoPtr, 0, sizeof(ConsoleInfo));
@@ -1357,23 +1317,23 @@ TclWinOpenConsoleChannel(
infoPtr->threadId = Tcl_GetCurrentThread();
/*
- * Use the pointer for the name of the result channel. This keeps the
- * channel names unique, since some may share handles (stdin/stdout/stderr
- * for instance).
+ * Use the pointer for the name of the result channel.
+ * This keeps the channel names unique, since some may share
+ * handles (stdin/stdout/stderr for instance).
*/
- wsprintfA(channelName, "file%lx", PTR2INT(infoPtr));
-
+ wsprintfA(channelName, "file%lx", (int) infoPtr);
+
infoPtr->channel = Tcl_CreateChannel(&consoleChannelType, channelName,
- (ClientData) infoPtr, permissions);
+ (ClientData) infoPtr, permissions);
if (permissions & TCL_READABLE) {
/*
* Make sure the console input buffer is ready for only character
- * input notifications and the buffer is set for line buffering. IOW,
- * we only want to catch when complete lines are ready for reading.
+ * input notifications and the buffer is set for line buffering.
+ * IOW, we only want to catch when complete lines are ready for
+ * reading.
*/
-
GetConsoleMode(infoPtr->handle, &modes);
modes &= ~(ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);
modes |= ENABLE_LINE_INPUT;
@@ -1383,7 +1343,7 @@ TclWinOpenConsoleChannel(
infoPtr->startReader = CreateEvent(NULL, FALSE, FALSE, NULL);
infoPtr->stopReader = CreateEvent(NULL, FALSE, FALSE, NULL);
infoPtr->readThread = CreateThread(NULL, 256, ConsoleReaderThread,
- infoPtr, 0, &id);
+ infoPtr, 0, &id);
SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST);
}
@@ -1392,21 +1352,18 @@ TclWinOpenConsoleChannel(
infoPtr->startWriter = CreateEvent(NULL, FALSE, FALSE, NULL);
infoPtr->stopWriter = CreateEvent(NULL, FALSE, FALSE, NULL);
infoPtr->writeThread = CreateThread(NULL, 256, ConsoleWriterThread,
- infoPtr, 0, &id);
+ infoPtr, 0, &id);
SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST);
}
/*
- * Files have default translation of AUTO and ^Z eof char, which means
- * that a ^Z will be accepted as EOF when reading.
+ * Files have default translation of AUTO and ^Z eof char, which
+ * means that a ^Z will be accepted as EOF when reading.
*/
-
+
Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
- if (tclWinProcs->useWide)
- Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", "unicode");
- else
- Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", encoding);
+ Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", encoding);
return infoPtr->channel;
}
@@ -1428,42 +1385,33 @@ TclWinOpenConsoleChannel(
*/
static void
-ConsoleThreadActionProc(
- ClientData instanceData,
- int action)
+ConsoleThreadActionProc (instanceData, action)
+ ClientData instanceData;
+ int action;
{
ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
- /* We do not access firstConsolePtr in the thread structures. This is not
- * for all serials managed by the thread, but only those we are watching.
- * Removal of the filevent handlers before transfer thus takes care of
- * this structure.
+ /* We do not access firstConsolePtr in the thread structures. This is
+ * not for all serials managed by the thread, but only those we are
+ * watching. Removal of the filevent handlers before transfer thus
+ * takes care of this structure.
*/
Tcl_MutexLock(&consoleMutex);
if (action == TCL_CHANNEL_THREAD_INSERT) {
- /*
- * We can't copy the thread information from the channel when the
- * channel is created. At this time the channel back pointer has not
- * been set yet. However in that case the threadId has already been
- * set by TclpCreateCommandChannel itself, so the structure is still
- * good.
+ /* We can't copy the thread information from the channel when
+ * the channel is created. At this time the channel back
+ * pointer has not been set yet. However in that case the
+ * threadId has already been set by TclpCreateCommandChannel
+ * itself, so the structure is still good.
*/
- ConsoleInit();
- if (infoPtr->channel != NULL) {
- infoPtr->threadId = Tcl_GetChannelThread(infoPtr->channel);
+ ConsoleInit ();
+ if (infoPtr->channel != NULL) {
+ infoPtr->threadId = Tcl_GetChannelThread (infoPtr->channel);
}
} else {
infoPtr->threadId = NULL;
}
Tcl_MutexUnlock(&consoleMutex);
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinDde.c b/win/tclWinDde.c
index 9f39b37..0d5f7d7 100644
--- a/win/tclWinDde.c
+++ b/win/tclWinDde.c
@@ -1,30 +1,31 @@
-/*
+/*
* tclWinDde.c --
*
- * This file provides functions that implement the "send" command,
- * allowing commands to be passed from interpreter to interpreter.
+ * This file provides procedures that implement the "send"
+ * command, allowing commands to be passed from interpreter
+ * to interpreter.
*
* Copyright (c) 1997 by Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tclInt.h"
+#include "tclPort.h"
#include <dde.h>
#include <ddeml.h>
+#include <tchar.h>
/*
- * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the Dde_Init
- * declaration is in the source file itself, which is only accessed when we
- * are building a library. DO NOT MOVE BEFORE ANY #include LINES. ONLY USE
- * EXTERN TO INDICATE EXPORTED FUNCTIONS FROM NOW ON.
+ * 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
-/*
+/*
* The following structure is used to keep track of the interpreters
* registered by this process.
*/
@@ -34,7 +35,6 @@ typedef struct RegisteredInterp {
/* The next interp this application knows
* about. */
char *name; /* Interpreter's name (malloc-ed). */
- Tcl_Obj *handlerPtr; /* The server handler command */
Tcl_Interp *interp; /* The interpreter attached to this name. */
} RegisteredInterp;
@@ -50,77 +50,64 @@ typedef struct Conversation {
Tcl_Obj *returnPackagePtr; /* The result package for this conversation. */
} Conversation;
-typedef struct DdeEnumServices {
- Tcl_Interp *interp;
- int result;
- ATOM service;
- ATOM topic;
- HWND hwnd;
-} DdeEnumServices;
-
typedef struct ThreadSpecificData {
Conversation *currentConversations;
- /* A list of conversations currently being
- * processed. */
+ /* A list of conversations currently
+ * being processed. */
RegisteredInterp *interpListPtr;
- /* List of all interpreters registered in the
- * current process. */
+ /* List of all interpreters registered
+ * in the current process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * The following variables cannot be placed in thread-local storage. The Mutex
- * ddeMutex guards access to the ddeInstance.
+ * The following variables cannot be placed in thread-local storage.
+ * The Mutex ddeMutex guards access to the ddeInstance.
*/
-
static HSZ ddeServiceGlobal = 0;
-static DWORD ddeInstance; /* The application instance handle given to us
- * by DdeInitialize. */
+static DWORD ddeInstance; /* The application instance handle given
+ * to us by DdeInitialize. */
static int ddeIsServer = 0;
-#define TCL_DDE_VERSION "1.3.2"
-#define TCL_DDE_PACKAGE_NAME "dde"
-#define TCL_DDE_SERVICE_NAME "TclEval"
-#define TCL_DDE_EXECUTE_RESULT "$TCLEVAL$EXECUTE$RESULT"
+#define TCL_DDE_VERSION "1.2.4"
+#define TCL_DDE_PACKAGE_NAME "dde"
+#define TCL_DDE_SERVICE_NAME "TclEval"
TCL_DECLARE_MUTEX(ddeMutex)
/*
- * Forward declarations for functions defined later in this file.
+ * Forward declarations for procedures defined later in this file.
*/
-static LRESULT CALLBACK DdeClientWindowProc(HWND hwnd, UINT uMsg,
- WPARAM wParam, LPARAM lParam);
-static int DdeCreateClient(struct DdeEnumServices *es);
-static BOOL CALLBACK DdeEnumWindowsCallback(HWND hwndTarget, LPARAM lParam);
-static void DdeExitProc(ClientData clientData);
-static int DdeGetServicesList(Tcl_Interp *interp,
- char *serviceName, char *topicName);
-static HDDEDATA CALLBACK DdeServerProc(UINT uType, UINT uFmt, HCONV hConv,
- HSZ ddeTopic, HSZ ddeItem, HDDEDATA hData,
- DWORD dwData1, DWORD dwData2);
-static LRESULT DdeServicesOnAck(HWND hwnd, WPARAM wParam,
- LPARAM lParam);
-static void DeleteProc(ClientData clientData);
-static Tcl_Obj * ExecuteRemoteObject(RegisteredInterp *riPtr,
- Tcl_Obj *ddeObjectPtr);
-static int MakeDdeConnection(Tcl_Interp *interp, char *name,
- HCONV *ddeConvPtr);
-static void SetDdeError(Tcl_Interp *interp);
-
-int Tcl_DdeObjCmd(ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]);
-
-EXTERN int Dde_Init(Tcl_Interp *interp);
-EXTERN int Dde_SafeInit(Tcl_Interp *interp);
+static void DdeExitProc _ANSI_ARGS_((ClientData clientData));
+static void DeleteProc _ANSI_ARGS_((ClientData clientData));
+static Tcl_Obj * ExecuteRemoteObject _ANSI_ARGS_((
+ RegisteredInterp *riPtr,
+ Tcl_Obj *ddeObjectPtr));
+static int MakeDdeConnection _ANSI_ARGS_((Tcl_Interp *interp,
+ char *name, HCONV *ddeConvPtr));
+static HDDEDATA CALLBACK DdeServerProc _ANSI_ARGS_((UINT uType,
+ UINT uFmt, HCONV hConv, HSZ ddeTopic,
+ HSZ ddeItem, HDDEDATA hData, DWORD dwData1,
+ DWORD dwData2));
+static void SetDdeError _ANSI_ARGS_((Tcl_Interp *interp));
+static int DdeGetServicesList _ANSI_ARGS_((
+ Tcl_Interp *interp,
+ char *serviceName,
+ char *topicName));
+int Tcl_DdeObjCmd(ClientData clientData, /* Used only for deletion */
+ Tcl_Interp *interp, /* The interp we are sending from */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[]); /* The arguments */
+
+EXTERN int Dde_Init(Tcl_Interp *interp);
/*
*----------------------------------------------------------------------
*
* Dde_Init --
*
- * This function initializes the dde command.
+ * This procedure initializes the dde command.
*
* Results:
* A standard Tcl result.
@@ -140,35 +127,10 @@ Dde_Init(
}
Tcl_CreateObjCommand(interp, "dde", Tcl_DdeObjCmd, NULL, NULL);
+
Tcl_CreateExitHandler(DdeExitProc, NULL);
- return Tcl_PkgProvide(interp, TCL_DDE_PACKAGE_NAME, TCL_DDE_VERSION);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Dde_SafeInit --
- *
- * This function initializes the dde command within a safe interp
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-int
-Dde_SafeInit(
- Tcl_Interp *interp)
-{
- int result = Dde_Init(interp);
- if (result == TCL_OK) {
- Tcl_HideCommand(interp, "dde", "dde");
- }
- return result;
+ return Tcl_PkgProvide(interp, TCL_DDE_PACKAGE_NAME, TCL_DDE_VERSION);
}
/*
@@ -192,11 +154,11 @@ Initialize(void)
{
int nameFound = 0;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
-
+
/*
- * See if the application is already registered; if so, remove its current
- * name from the registry. The deletion of the command will take care of
- * disposing of this entry.
+ * See if the application is already registered; if so, remove its
+ * current name from the registry. The deletion of the command
+ * will take care of disposing of this entry.
*/
if (tsdPtr->interpListPtr != NULL) {
@@ -204,16 +166,18 @@ Initialize(void)
}
/*
- * Make sure that the DDE server is there. This is done only once, add an
- * exit handler tear it down.
+ * Make sure that the DDE server is there. This is done only once,
+ * add an exit handler tear it down.
*/
if (ddeInstance == 0) {
Tcl_MutexLock(&ddeMutex);
if (ddeInstance == 0) {
if (DdeInitialize(&ddeInstance, (PFNCALLBACK) DdeServerProc,
- CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS
- | CBF_FAIL_POKES, 0) != DMLERR_NO_ERROR) {
+ CBF_SKIP_REGISTRATIONS
+ | CBF_SKIP_UNREGISTRATIONS
+ | CBF_FAIL_POKES, 0)
+ != DMLERR_NO_ERROR) {
ddeInstance = 0;
}
}
@@ -224,7 +188,7 @@ Initialize(void)
if ((ddeServiceGlobal == 0) && (nameFound != 0)) {
ddeIsServer = 1;
Tcl_CreateExitHandler(DdeExitProc, NULL);
- ddeServiceGlobal = DdeCreateStringHandle(ddeInstance,
+ ddeServiceGlobal = DdeCreateStringHandle(ddeInstance, \
TCL_DDE_SERVICE_NAME, 0);
DdeNameService(ddeInstance, ddeServiceGlobal, 0L, DNS_REGISTER);
} else {
@@ -232,58 +196,53 @@ Initialize(void)
}
Tcl_MutexUnlock(&ddeMutex);
}
-}
+}
/*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*
* DdeSetServerName --
*
- * This function is called to associate an ASCII name with a Dde server.
- * If the interpreter has already been named, the name replaces the old
- * one.
+ * This procedure is called to associate an ASCII name with a Dde
+ * server. If the interpreter has already been named, the
+ * name replaces the old one.
*
* Results:
- * The return value is the name actually given to the interp. This will
- * normally be the same as name, but if name was already in use for a Dde
- * Server then a name of the form "name #2" will be chosen, with a high
- * enough number to make the name unique.
+ * The return value is the name actually given to the interp.
+ * This will normally be the same as name, but if name was already
+ * in use for a Dde Server then a name of the form "name #2" will
+ * be chosen, with a high enough number to make the name unique.
*
* Side effects:
- * Registration info is saved, thereby allowing the "send" command to be
- * used later to invoke commands in the application. In addition, the
- * "send" command is created in the application's interpreter. The
- * registration will be removed automatically if the interpreter is
- * deleted or the "send" command is removed.
+ * Registration info is saved, thereby allowing the "send" command
+ * to be used later to invoke commands in the application. In
+ * addition, the "send" command is created in the application's
+ * interpreter. The registration will be removed automatically
+ * if the interpreter is deleted or the "send" command is removed.
*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*/
static char *
DdeSetServerName(
Tcl_Interp *interp,
- char *name, /* The name that will be used to refer to the
- * interpreter in later "send" commands. Must
- * be globally unique. */
- int exactName, /* Should we make a unique name? 0 = unique */
- Tcl_Obj *handlerPtr) /* Name of the optional proc/command to handle
- * incoming Dde eval's */
+ char *name /* The name that will be used to
+ * refer to the interpreter in later
+ * "send" commands. Must be globally
+ * unique. */
+ )
{
- int suffix, offset;
RegisteredInterp *riPtr, *prevPtr;
Tcl_DString dString;
- char *actualName;
- Tcl_Obj *srvListPtr = NULL, **srvPtrPtr = NULL;
- int n, srvCount = 0, lastSuffix, r = TCL_OK;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
- * See if the application is already registered; if so, remove its current
- * name from the registry. The deletion of the command will take care of
- * disposing of this entry.
+ * See if the application is already registered; if so, remove its
+ * current name from the registry. The deletion of the command
+ * will take care of disposing of this entry.
*/
- for (riPtr = tsdPtr->interpListPtr, prevPtr = NULL; riPtr != NULL;
+ for (riPtr = tsdPtr->interpListPtr, prevPtr = NULL; riPtr != NULL;
prevPtr = riPtr, riPtr = riPtr->nextPtr) {
if (riPtr->interp == interp) {
if (name != NULL) {
@@ -295,8 +254,8 @@ DdeSetServerName(
break;
} else {
/*
- * The name was NULL, so the caller is asking for the name of
- * the current interp.
+ * the name was NULL, so the caller is asking for
+ * the name of the current interp.
*/
return riPtr->name;
@@ -306,74 +265,22 @@ DdeSetServerName(
if (name == NULL) {
/*
- * The name was NULL, so the caller is asking for the name of the
- * current interp, but it doesn't have a name.
+ * the name was NULL, so the caller is asking for
+ * the name of the current interp, but it doesn't
+ * have a name.
*/
return "";
}
-
+
/*
- * Get the list of currently registered Tcl interpreters by calling the
- * internal implementation of the 'dde services' command.
+ * Pick a name to use for the application. Use "name" if it's not
+ * already in use. Otherwise add a suffix such as " #2", trying
+ * larger and larger numbers until we eventually find one that is
+ * unique.
*/
Tcl_DStringInit(&dString);
- actualName = name;
-
- if (!exactName) {
- r = DdeGetServicesList(interp, TCL_DDE_SERVICE_NAME, NULL);
- if (r == TCL_OK) {
- srvListPtr = Tcl_GetObjResult(interp);
- }
- if (r == TCL_OK) {
- r = Tcl_ListObjGetElements(interp, srvListPtr, &srvCount,
- &srvPtrPtr);
- }
- if (r != TCL_OK) {
- OutputDebugString(Tcl_GetStringResult(interp));
- return NULL;
- }
-
- /*
- * Pick a name to use for the application. Use "name" if it's not
- * already in use. Otherwise add a suffix such as " #2", trying larger
- * and larger numbers until we eventually find one that is unique.
- */
-
- offset = lastSuffix = 0;
- suffix = 1;
-
- while (suffix != lastSuffix) {
- lastSuffix = suffix;
- if (suffix > 1) {
- if (suffix == 2) {
- Tcl_DStringAppend(&dString, name, -1);
- Tcl_DStringAppend(&dString, " #", 2);
- offset = Tcl_DStringLength(&dString);
- Tcl_DStringSetLength(&dString, offset + TCL_INTEGER_SPACE);
- actualName = Tcl_DStringValue(&dString);
- }
- sprintf(Tcl_DStringValue(&dString) + offset, "%d", suffix);
- }
-
- /*
- * See if the name is already in use, if so increment suffix.
- */
-
- for (n = 0; n < srvCount; ++n) {
- Tcl_Obj* namePtr;
-
- Tcl_ListObjIndex(interp, srvPtrPtr[n], 1, &namePtr);
- if (strcmp(actualName, Tcl_GetString(namePtr)) == 0) {
- suffix++;
- break;
- }
- }
- }
- Tcl_DStringSetLength(&dString,
- offset + (int)strlen(Tcl_DStringValue(&dString)+offset));
- }
/*
* We have found a unique name. Now add it to the registry.
@@ -381,18 +288,10 @@ DdeSetServerName(
riPtr = (RegisteredInterp *) ckalloc(sizeof(RegisteredInterp));
riPtr->interp = interp;
- riPtr->name = ckalloc((unsigned int) strlen(actualName) + 1);
+ riPtr->name = ckalloc((unsigned int) strlen(name) + 1);
riPtr->nextPtr = tsdPtr->interpListPtr;
- riPtr->handlerPtr = handlerPtr;
- if (riPtr->handlerPtr != NULL) {
- Tcl_IncrRefCount(riPtr->handlerPtr);
- }
tsdPtr->interpListPtr = riPtr;
- strcpy(riPtr->name, actualName);
-
- if (Tcl_IsSafe(interp)) {
- Tcl_ExposeCommand(interp, "dde", "dde");
- }
+ strcpy(riPtr->name, name);
Tcl_CreateObjCommand(interp, "dde", Tcl_DdeObjCmd,
(ClientData) riPtr, DeleteProc);
@@ -402,52 +301,19 @@ DdeSetServerName(
Tcl_DStringFree(&dString);
/*
- * Re-initialize with the new name.
+ * re-initialize with the new name
*/
-
Initialize();
-
+
return riPtr->name;
}
/*
- *----------------------------------------------------------------------
- *
- * DdeGetRegistrationPtr
- *
- * Retrieve the registration info for an interpreter.
- *
- * Results:
- * Returns a pointer to the registration structure or NULL
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static RegisteredInterp *
-DdeGetRegistrationPtr(
- Tcl_Interp *interp)
-{
- RegisteredInterp *riPtr;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
-
- for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
- riPtr = riPtr->nextPtr) {
- if (riPtr->interp == interp) {
- break;
- }
- }
- return riPtr;
-}
-
-/*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*
* DeleteProc
*
- * This function is called when the command "dde" is destroyed.
+ * This procedure is called when the command "dde" is destroyed.
*
* Results:
* none
@@ -455,20 +321,20 @@ DdeGetRegistrationPtr(
* Side effects:
* The interpreter given by riPtr is unregistered.
*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*/
static void
-DeleteProc(
- ClientData clientData) /* The interp we are deleting passed as
- * ClientData. */
+DeleteProc(clientData)
+ ClientData clientData; /* The interp we are deleting passed
+ * as ClientData. */
{
RegisteredInterp *riPtr = (RegisteredInterp *) clientData;
RegisteredInterp *searchPtr, *prevPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
for (searchPtr = tsdPtr->interpListPtr, prevPtr = NULL;
- searchPtr != NULL && searchPtr != riPtr;
+ (searchPtr != NULL) && (searchPtr != riPtr);
prevPtr = searchPtr, searchPtr = searchPtr->nextPtr) {
/*
* Empty loop body.
@@ -483,33 +349,31 @@ DeleteProc(
}
}
ckfree(riPtr->name);
- if (riPtr->handlerPtr) {
- Tcl_DecrRefCount(riPtr->handlerPtr);
- }
Tcl_EventuallyFree(clientData, TCL_DYNAMIC);
}
/*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*
* ExecuteRemoteObject --
*
- * Takes the package delivered by DDE and executes it in the server's
- * interpreter.
+ * Takes the package delivered by DDE and executes it in
+ * the server's interpreter.
*
* Results:
- * A list Tcl_Obj * that describes what happened. The first element is
- * the numerical return code (TCL_ERROR, etc.). The second element is the
- * result of the script. If the return result was TCL_ERROR, then the
- * third element will be the value of the global "errorCode", and the
- * fourth will be the value of the global "errorInfo". The return result
- * will have a refCount of 0.
+ * A list Tcl_Obj * that describes what happened. The first
+ * element is the numerical return code (TCL_ERROR, etc.).
+ * The second element is the result of the script. If the
+ * return result was TCL_ERROR, then the third element
+ * will be the value of the global "errorCode", and the
+ * fourth will be the value of the global "errorInfo".
+ * The return result will have a refCount of 0.
*
* Side effects:
- * A Tcl script is run, which can cause all kinds of other things to
- * happen.
+ * A Tcl script is run, which can cause all kinds of other
+ * things to happen.
*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*/
static Tcl_Obj *
@@ -517,86 +381,63 @@ ExecuteRemoteObject(
RegisteredInterp *riPtr, /* Info about this server. */
Tcl_Obj *ddeObjectPtr) /* The object to execute. */
{
+ Tcl_Obj *errorObjPtr;
Tcl_Obj *returnPackagePtr;
- int result = TCL_OK;
-
- if (riPtr->handlerPtr == NULL && Tcl_IsSafe(riPtr->interp)) {
- Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj("permission denied: "
- "a handler procedure must be defined for use in a safe "
- "interp", -1));
- result = TCL_ERROR;
- }
-
- if (riPtr->handlerPtr != NULL) {
- /*
- * Add the dde request data to the handler proc list.
- */
-
- Tcl_Obj *cmdPtr = Tcl_DuplicateObj(riPtr->handlerPtr);
-
- result = Tcl_ListObjAppendElement(riPtr->interp, cmdPtr, ddeObjectPtr);
- if (result == TCL_OK) {
- ddeObjectPtr = cmdPtr;
- }
- }
-
- if (result == TCL_OK) {
- result = Tcl_EvalObjEx(riPtr->interp, ddeObjectPtr, TCL_EVAL_GLOBAL);
- }
-
- returnPackagePtr = Tcl_NewListObj(0, NULL);
+ int result;
- Tcl_ListObjAppendElement(NULL, returnPackagePtr, Tcl_NewIntObj(result));
+ result = Tcl_EvalObjEx(riPtr->interp, ddeObjectPtr, TCL_EVAL_GLOBAL);
+ returnPackagePtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+ Tcl_ListObjAppendElement(NULL, returnPackagePtr,
+ Tcl_NewIntObj(result));
Tcl_ListObjAppendElement(NULL, returnPackagePtr,
Tcl_GetObjResult(riPtr->interp));
-
if (result == TCL_ERROR) {
- Tcl_Obj *errorObjPtr = Tcl_GetVar2Ex(riPtr->interp, "errorCode", NULL,
+ errorObjPtr = Tcl_GetVar2Ex(riPtr->interp, "errorCode", NULL,
TCL_GLOBAL_ONLY);
- if (errorObjPtr) {
- Tcl_ListObjAppendElement(NULL, returnPackagePtr, errorObjPtr);
- }
+ Tcl_ListObjAppendElement(NULL, returnPackagePtr, errorObjPtr);
errorObjPtr = Tcl_GetVar2Ex(riPtr->interp, "errorInfo", NULL,
TCL_GLOBAL_ONLY);
- if (errorObjPtr) {
- Tcl_ListObjAppendElement(NULL, returnPackagePtr, errorObjPtr);
- }
+ Tcl_ListObjAppendElement(NULL, returnPackagePtr, errorObjPtr);
}
return returnPackagePtr;
}
/*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*
* DdeServerProc --
*
- * Handles all transactions for this server. Can handle execute, request,
- * and connect protocols. Dde will call this routine when a client
- * attempts to run a dde command using this server.
+ * Handles all transactions for this server. Can handle
+ * execute, request, and connect protocols. Dde will
+ * call this routine when a client attempts to run a dde
+ * command using this server.
*
* Results:
* A DDE Handle with the result of the dde command.
*
* Side effects:
- * Depending on which command is executed, arbitrary Tcl scripts can be
- * run.
+ * Depending on which command is executed, arbitrary
+ * Tcl scripts can be run.
*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*/
static HDDEDATA CALLBACK
-DdeServerProc(
- UINT uType, /* The type of DDE transaction we are
- * performing. */
- UINT uFmt, /* The format that data is sent or received. */
- HCONV hConv, /* The conversation associated with the
+DdeServerProc (
+ UINT uType, /* The type of DDE transaction we
+ * are performing. */
+ UINT uFmt, /* The format that data is sent or
+ * received. */
+ HCONV hConv, /* The conversation associated with the
* current transaction. */
- HSZ ddeTopic, HSZ ddeItem, /* String handles. Transaction-type
+ HSZ ddeTopic, /* A string handle. Transaction-type
+ * dependent. */
+ HSZ ddeItem, /* A string handle. Transaction-type
* dependent. */
HDDEDATA hData, /* DDE data. Transaction-type dependent. */
- DWORD dwData1, DWORD dwData2)
- /* Transaction-dependent data. */
+ DWORD dwData1, /* Transaction-dependent data. */
+ DWORD dwData2) /* Transaction-dependent data. */
{
Tcl_DString dString;
int len;
@@ -609,125 +450,129 @@ DdeServerProc(
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
switch(uType) {
- case XTYP_CONNECT:
- /*
- * Dde is trying to initialize a conversation with us. Check and make
- * sure we have a valid topic.
- */
+ case XTYP_CONNECT:
- len = DdeQueryString(ddeInstance, ddeTopic, NULL, 0, 0);
- Tcl_DStringInit(&dString);
- Tcl_DStringSetLength(&dString, len);
- utilString = Tcl_DStringValue(&dString);
- DdeQueryString(ddeInstance, ddeTopic, utilString, (DWORD) len + 1,
- CP_WINANSI);
+ /*
+ * Dde is trying to initialize a conversation with us. Check
+ * and make sure we have a valid topic.
+ */
- for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
- riPtr = riPtr->nextPtr) {
- if (stricmp(utilString, riPtr->name) == 0) {
- Tcl_DStringFree(&dString);
- return (HDDEDATA) TRUE;
+ len = DdeQueryString(ddeInstance, ddeTopic, NULL, 0, 0);
+ Tcl_DStringInit(&dString);
+ Tcl_DStringSetLength(&dString, len);
+ utilString = Tcl_DStringValue(&dString);
+ DdeQueryString(ddeInstance, ddeTopic, utilString, (DWORD) len + 1,
+ CP_WINANSI);
+
+ for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
+ riPtr = riPtr->nextPtr) {
+ if (stricmp(utilString, riPtr->name) == 0) {
+ Tcl_DStringFree(&dString);
+ return (HDDEDATA) TRUE;
+ }
}
- }
- Tcl_DStringFree(&dString);
- return (HDDEDATA) FALSE;
+ Tcl_DStringFree(&dString);
+ return (HDDEDATA) FALSE;
- case XTYP_CONNECT_CONFIRM:
- /*
- * Dde has decided that we can connect, so it gives us a conversation
- * handle. We need to keep track of it so we know which execution
- * result to return in an XTYP_REQUEST.
- */
+ case XTYP_CONNECT_CONFIRM:
- len = DdeQueryString(ddeInstance, ddeTopic, NULL, 0, 0);
- Tcl_DStringInit(&dString);
- Tcl_DStringSetLength(&dString, len);
- utilString = Tcl_DStringValue(&dString);
- DdeQueryString(ddeInstance, ddeTopic, utilString, (DWORD) len + 1,
- CP_WINANSI);
- for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
- riPtr = riPtr->nextPtr) {
- if (stricmp(riPtr->name, utilString) == 0) {
- convPtr = (Conversation *) ckalloc(sizeof(Conversation));
- convPtr->nextPtr = tsdPtr->currentConversations;
- convPtr->returnPackagePtr = NULL;
- convPtr->hConv = hConv;
- convPtr->riPtr = riPtr;
- tsdPtr->currentConversations = convPtr;
- break;
+ /*
+ * Dde has decided that we can connect, so it gives us a
+ * conversation handle. We need to keep track of it
+ * so we know which execution result to return in an
+ * XTYP_REQUEST.
+ */
+
+ len = DdeQueryString(ddeInstance, ddeTopic, NULL, 0, 0);
+ Tcl_DStringInit(&dString);
+ Tcl_DStringSetLength(&dString, len);
+ utilString = Tcl_DStringValue(&dString);
+ DdeQueryString(ddeInstance, ddeTopic, utilString, (DWORD) len + 1,
+ CP_WINANSI);
+ for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
+ riPtr = riPtr->nextPtr) {
+ if (stricmp(riPtr->name, utilString) == 0) {
+ convPtr = (Conversation *) ckalloc(sizeof(Conversation));
+ convPtr->nextPtr = tsdPtr->currentConversations;
+ convPtr->returnPackagePtr = NULL;
+ convPtr->hConv = hConv;
+ convPtr->riPtr = riPtr;
+ tsdPtr->currentConversations = convPtr;
+ break;
+ }
}
- }
- Tcl_DStringFree(&dString);
- return (HDDEDATA) TRUE;
+ Tcl_DStringFree(&dString);
+ return (HDDEDATA) TRUE;
- case XTYP_DISCONNECT:
- /*
- * The client has disconnected from our server. Forget this
- * conversation.
- */
+ case XTYP_DISCONNECT:
- for (convPtr = tsdPtr->currentConversations, prevConvPtr = NULL;
- convPtr != NULL;
- prevConvPtr = convPtr, convPtr = convPtr->nextPtr) {
- if (hConv == convPtr->hConv) {
- if (prevConvPtr == NULL) {
- tsdPtr->currentConversations = convPtr->nextPtr;
- } else {
- prevConvPtr->nextPtr = convPtr->nextPtr;
- }
- if (convPtr->returnPackagePtr != NULL) {
- Tcl_DecrRefCount(convPtr->returnPackagePtr);
+ /*
+ * The client has disconnected from our server. Forget this
+ * conversation.
+ */
+
+ for (convPtr = tsdPtr->currentConversations, prevConvPtr = NULL;
+ convPtr != NULL;
+ prevConvPtr = convPtr, convPtr = convPtr->nextPtr) {
+ if (hConv == convPtr->hConv) {
+ if (prevConvPtr == NULL) {
+ tsdPtr->currentConversations = convPtr->nextPtr;
+ } else {
+ prevConvPtr->nextPtr = convPtr->nextPtr;
+ }
+ if (convPtr->returnPackagePtr != NULL) {
+ Tcl_DecrRefCount(convPtr->returnPackagePtr);
+ }
+ ckfree((char *) convPtr);
+ break;
}
- ckfree((char *) convPtr);
- break;
}
- }
- return (HDDEDATA) TRUE;
+ return (HDDEDATA) TRUE;
- case XTYP_REQUEST:
- /*
- * This could be either a request for a value of a Tcl variable, or it
- * could be the send command requesting the results of the last
- * execute.
- */
-
- if (uFmt != CF_TEXT) {
- return (HDDEDATA) FALSE;
- }
+ case XTYP_REQUEST:
- ddeReturn = (HDDEDATA) FALSE;
- for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
- && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
/*
- * Empty loop body.
+ * This could be either a request for a value of a Tcl variable,
+ * or it could be the send command requesting the results of the
+ * last execute.
*/
- }
- if (convPtr != NULL) {
- BYTE *returnString;
+ if (uFmt != CF_TEXT) {
+ return (HDDEDATA) FALSE;
+ }
- len = DdeQueryString(ddeInstance, ddeItem, NULL, 0, CP_WINANSI);
- Tcl_DStringInit(&dString);
- Tcl_DStringSetLength(&dString, len);
- utilString = Tcl_DStringValue(&dString);
- DdeQueryString(ddeInstance, ddeItem, utilString, (DWORD) len + 1,
- CP_WINANSI);
- if (stricmp(utilString, TCL_DDE_EXECUTE_RESULT) == 0) {
- returnString = (BYTE *)
- Tcl_GetStringFromObj(convPtr->returnPackagePtr, &len);
- ddeReturn = DdeCreateDataHandle(ddeInstance, returnString,
- (DWORD) len+1, 0, ddeItem, CF_TEXT, 0);
- } else {
- if (Tcl_IsSafe(convPtr->riPtr->interp)) {
- ddeReturn = NULL;
+ ddeReturn = (HDDEDATA) FALSE;
+ for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
+ && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
+ /*
+ * Empty loop body.
+ */
+ }
+
+ if (convPtr != NULL) {
+ BYTE *returnString;
+
+ len = DdeQueryString(ddeInstance, ddeItem, NULL, 0,
+ CP_WINANSI);
+ Tcl_DStringInit(&dString);
+ Tcl_DStringSetLength(&dString, len);
+ utilString = Tcl_DStringValue(&dString);
+ DdeQueryString(ddeInstance, ddeItem, utilString,
+ (DWORD) len + 1, CP_WINANSI);
+ if (stricmp(utilString, "$TCLEVAL$EXECUTE$RESULT") == 0) {
+ returnString =
+ (BYTE *)Tcl_GetStringFromObj(convPtr->returnPackagePtr, &len);
+ ddeReturn = DdeCreateDataHandle(ddeInstance,
+ returnString, (DWORD) len+1, 0, ddeItem, CF_TEXT,
+ 0);
} else {
Tcl_Obj *variableObjPtr = Tcl_GetVar2Ex(
- convPtr->riPtr->interp, utilString, NULL,
+ convPtr->riPtr->interp, utilString, NULL,
TCL_GLOBAL_ONLY);
if (variableObjPtr != NULL) {
- returnString = (BYTE *) Tcl_GetStringFromObj(
- variableObjPtr, &len);
+ returnString = (BYTE *)Tcl_GetStringFromObj(variableObjPtr,
+ &len);
ddeReturn = DdeCreateDataHandle(ddeInstance,
returnString, (DWORD) len+1, 0, ddeItem,
CF_TEXT, 0);
@@ -735,101 +580,106 @@ DdeServerProc(
ddeReturn = NULL;
}
}
+ Tcl_DStringFree(&dString);
}
- Tcl_DStringFree(&dString);
- }
- return ddeReturn;
+ return ddeReturn;
- case XTYP_EXECUTE: {
- /*
- * Execute this script. The results will be saved into a list object
- * which will be retreived later. See ExecuteRemoteObject.
- */
+ case XTYP_EXECUTE: {
- Tcl_Obj *returnPackagePtr;
-
- for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
- && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
/*
- * Empty loop body.
+ * Execute this script. The results will be saved into
+ * a list object which will be retreived later. See
+ * ExecuteRemoteObject.
*/
- }
- if (convPtr == NULL) {
- return (HDDEDATA) DDE_FNOTPROCESSED;
- }
+ Tcl_Obj *returnPackagePtr;
+
+ for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
+ && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
+ /*
+ * Empty loop body.
+ */
+
+ }
+
+ if (convPtr == NULL) {
+ return (HDDEDATA) DDE_FNOTPROCESSED;
+ }
+
+ utilString = (char *) DdeAccessData(hData, &dlen);
+ len = dlen;
+ ddeObjectPtr = Tcl_NewStringObj(utilString, -1);
+ Tcl_IncrRefCount(ddeObjectPtr);
+ DdeUnaccessData(hData);
+ if (convPtr->returnPackagePtr != NULL) {
+ Tcl_DecrRefCount(convPtr->returnPackagePtr);
+ }
+ convPtr->returnPackagePtr = NULL;
+ returnPackagePtr =
+ ExecuteRemoteObject(convPtr->riPtr, ddeObjectPtr);
+ Tcl_IncrRefCount(returnPackagePtr);
+ for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
+ && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
+ /*
+ * Empty loop body.
+ */
- utilString = (char *) DdeAccessData(hData, &dlen);
- len = dlen;
- ddeObjectPtr = Tcl_NewStringObj(utilString, -1);
- Tcl_IncrRefCount(ddeObjectPtr);
- DdeUnaccessData(hData);
- if (convPtr->returnPackagePtr != NULL) {
- Tcl_DecrRefCount(convPtr->returnPackagePtr);
+ }
+ if (convPtr != NULL) {
+ convPtr->returnPackagePtr = returnPackagePtr;
+ } else {
+ Tcl_DecrRefCount(returnPackagePtr);
+ }
+ Tcl_DecrRefCount(ddeObjectPtr);
+ if (returnPackagePtr == NULL) {
+ return (HDDEDATA) DDE_FNOTPROCESSED;
+ } else {
+ return (HDDEDATA) DDE_FACK;
+ }
}
- convPtr->returnPackagePtr = NULL;
- returnPackagePtr = ExecuteRemoteObject(convPtr->riPtr, ddeObjectPtr);
- Tcl_IncrRefCount(returnPackagePtr);
- for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
- && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
+
+ case XTYP_WILDCONNECT: {
+
/*
- * Empty loop body.
+ * Dde wants a list of services and topics that we support.
*/
- }
- if (convPtr != NULL) {
- convPtr->returnPackagePtr = returnPackagePtr;
- } else {
- Tcl_DecrRefCount(returnPackagePtr);
- }
- Tcl_DecrRefCount(ddeObjectPtr);
- if (returnPackagePtr == NULL) {
- return (HDDEDATA) DDE_FNOTPROCESSED;
- } else {
- return (HDDEDATA) DDE_FACK;
- }
- }
- case XTYP_WILDCONNECT: {
- /*
- * Dde wants a list of services and topics that we support.
- */
+ HSZPAIR *returnPtr;
+ int i;
+ int numItems;
- HSZPAIR *returnPtr;
- int i;
- int numItems;
+ for (i = 0, riPtr = tsdPtr->interpListPtr; riPtr != NULL;
+ i++, riPtr = riPtr->nextPtr) {
+ /*
+ * Empty loop body.
+ */
- for (i = 0, riPtr = tsdPtr->interpListPtr; riPtr != NULL;
- i++, riPtr = riPtr->nextPtr) {
- /*
- * Empty loop body.
- */
- }
+ }
- numItems = i;
- ddeReturn = DdeCreateDataHandle(ddeInstance, NULL,
- (numItems + 1) * sizeof(HSZPAIR), 0, 0, 0, 0);
- returnPtr = (HSZPAIR *) DdeAccessData(ddeReturn, &dlen);
- len = dlen;
- for (i = 0, riPtr = tsdPtr->interpListPtr; i < numItems;
- i++, riPtr = riPtr->nextPtr) {
- returnPtr[i].hszSvc = DdeCreateStringHandle(ddeInstance,
- TCL_DDE_SERVICE_NAME, CP_WINANSI);
- returnPtr[i].hszTopic = DdeCreateStringHandle(ddeInstance,
- riPtr->name, CP_WINANSI);
+ numItems = i;
+ ddeReturn = DdeCreateDataHandle(ddeInstance, NULL,
+ (numItems + 1) * sizeof(HSZPAIR), 0, 0, 0, 0);
+ returnPtr = (HSZPAIR *) DdeAccessData(ddeReturn, &dlen);
+ len = dlen;
+ for (i = 0, riPtr = tsdPtr->interpListPtr; i < numItems;
+ i++, riPtr = riPtr->nextPtr) {
+ returnPtr[i].hszSvc = DdeCreateStringHandle(
+ ddeInstance, "TclEval", CP_WINANSI);
+ returnPtr[i].hszTopic = DdeCreateStringHandle(
+ ddeInstance, riPtr->name, CP_WINANSI);
+ }
+ returnPtr[i].hszSvc = NULL;
+ returnPtr[i].hszTopic = NULL;
+ DdeUnaccessData(ddeReturn);
+ return ddeReturn;
}
- returnPtr[i].hszSvc = NULL;
- returnPtr[i].hszTopic = NULL;
- DdeUnaccessData(ddeReturn);
- return ddeReturn;
- }
- default:
- return NULL;
}
+ return NULL;
}
/*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*
* DdeExitProc --
*
@@ -841,7 +691,7 @@ DdeServerProc(
* Side effects:
* The DDE server is deleted.
*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*/
static void
@@ -854,20 +704,21 @@ DdeExitProc(
}
/*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*
* MakeDdeConnection --
*
- * This function is a utility used to connect to a DDE server when given
- * a server name and a topic name.
+ * This procedure is a utility used to connect to a DDE
+ * server when given a server name and a topic name.
*
* Results:
* A standard Tcl result.
+ *
*
* Side effects:
* Passes back a conversation through ddeConvPtr
*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*/
static int
@@ -878,9 +729,9 @@ MakeDdeConnection(
{
HSZ ddeTopic, ddeService;
HCONV ddeConv;
-
- ddeService = DdeCreateStringHandle(ddeInstance, TCL_DDE_SERVICE_NAME, 0);
- ddeTopic = DdeCreateStringHandle(ddeInstance, (void *) name, 0);
+
+ ddeService = DdeCreateStringHandle(ddeInstance, "TclEval", 0);
+ ddeTopic = DdeCreateStringHandle(ddeInstance, name, 0);
ddeConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
DdeFreeStringHandle(ddeInstance, ddeService);
@@ -889,7 +740,7 @@ MakeDdeConnection(
if (ddeConv == (HCONV) NULL) {
if (interp != NULL) {
Tcl_AppendResult(interp, "no registered server named \"",
- name, "\"", NULL);
+ name, "\"", (char *) NULL);
}
return TCL_ERROR;
}
@@ -899,15 +750,14 @@ MakeDdeConnection(
}
/*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*
* DdeGetServicesList --
*
- * This function obtains the list of DDE services.
+ * This procedure obtains the list of DDE services.
*
- * The functions between here and this function are all involved with
- * handling the DDE callbacks for this. They are: DdeCreateClient,
- * DdeClientWindowProc, DdeServicesOnAck, and DdeEnumWindowsCallback
+ * The functions between here and this procedure are all
+ * involved with handling the DDE callbacks for this.
*
* Results:
* A standard Tcl result.
@@ -915,12 +765,24 @@ MakeDdeConnection(
* Side effects:
* Sets the services list into the interp result.
*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*/
+typedef struct ddeEnumServices {
+ Tcl_Interp *interp;
+ int result;
+ ATOM service;
+ ATOM topic;
+ HWND hwnd;
+} ddeEnumServices;
+
+LRESULT CALLBACK
+DdeClientWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static LRESULT
+DdeServicesOnAck(HWND hwnd, WPARAM wParam, LPARAM lParam);
+
static int
-DdeCreateClient(
- struct DdeEnumServices *es)
+DdeCreateClient(ddeEnumServices *es)
{
WNDCLASSEX wc;
static const char *szDdeClientClassName = "TclEval client class";
@@ -930,196 +792,176 @@ DdeCreateClient(
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = DdeClientWindowProc;
wc.lpszClassName = szDdeClientClassName;
- wc.cbWndExtra = sizeof(struct DdeEnumServices *);
-
- /*
- * Register and create the callback window.
- */
+ wc.cbWndExtra = sizeof(ddeEnumServices*);
+ /* register and create the callback window */
RegisterClassEx(&wc);
- es->hwnd = CreateWindowEx(0, szDdeClientClassName, szDdeClientWindowName,
- WS_POPUP, 0, 0, 0, 0, NULL, NULL, NULL, (LPVOID)es);
+ es->hwnd = CreateWindowEx(0, szDdeClientClassName,
+ szDdeClientWindowName,
+ WS_POPUP, 0, 0, 0, 0, NULL, NULL, NULL,
+ (LPVOID)es);
return TCL_OK;
}
-static LRESULT CALLBACK
-DdeClientWindowProc(
- HWND hwnd, /* What window is the message for */
- UINT uMsg, /* The type of message received */
- WPARAM wParam,
- LPARAM lParam) /* (Potentially) our local handle */
+LRESULT CALLBACK
+DdeClientWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
+ LRESULT lr = 0L;
switch (uMsg) {
- case WM_CREATE: {
- LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
- struct DdeEnumServices *es =
- (struct DdeEnumServices *) lpcs->lpCreateParams;
-
+ case WM_CREATE: {
+ LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
+ ddeEnumServices *es;
+ es = (ddeEnumServices*)lpcs->lpCreateParams;
#ifdef _WIN64
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) es);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (long)es);
#else
- SetWindowLong(hwnd, GWL_USERDATA, (long)es);
+ SetWindowLong(hwnd, GWL_USERDATA, (long)es);
#endif
- return (LRESULT) 0L;
- }
- case WM_DDE_ACK:
- return DdeServicesOnAck(hwnd, wParam, lParam);
- break;
- default:
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
+ break;
+ }
+ case WM_DDE_ACK:
+ lr = DdeServicesOnAck(hwnd, wParam, lParam);
+ break;
+ default:
+ lr = DefWindowProc(hwnd, uMsg, wParam, lParam);
}
+ return lr;
}
static LRESULT
-DdeServicesOnAck(
- HWND hwnd,
- WPARAM wParam,
- LPARAM lParam)
+DdeServicesOnAck(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
HWND hwndRemote = (HWND)wParam;
ATOM service = (ATOM)LOWORD(lParam);
ATOM topic = (ATOM)HIWORD(lParam);
- struct DdeEnumServices *es;
- char sz[255];
+ ddeEnumServices *es;
+ TCHAR sz[255];
#ifdef _WIN64
- es = (struct DdeEnumServices *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ es = (ddeEnumServices *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
#else
- es = (struct DdeEnumServices *) GetWindowLong(hwnd, GWL_USERDATA);
+ es = (ddeEnumServices *)GetWindowLong(hwnd, GWL_USERDATA);
#endif
if ((es->service == (ATOM)0 || es->service == service)
- && (es->topic == (ATOM)0 || es->topic == topic)) {
+ && (es->topic == (ATOM)0 || es->topic == topic)) {
Tcl_Obj *matchPtr = Tcl_NewListObj(0, NULL);
- Tcl_Obj *resultPtr = Tcl_GetObjResult(es->interp);
-
- GlobalGetAtomNameA(service, sz, 255);
- Tcl_ListObjAppendElement(NULL, matchPtr, Tcl_NewStringObj(sz, -1));
- GlobalGetAtomNameA(topic, sz, 255);
- Tcl_ListObjAppendElement(NULL, matchPtr, Tcl_NewStringObj(sz, -1));
- /*
- * Adding the hwnd as a third list element provides a unique
+ GlobalGetAtomName(service, sz, 255);
+ Tcl_ListObjAppendElement(es->interp, matchPtr,
+ Tcl_NewStringObj(sz, -1));
+ GlobalGetAtomName(topic, sz, 255);
+ Tcl_ListObjAppendElement(es->interp, matchPtr,
+ Tcl_NewStringObj(sz, -1));
+ /* Adding the hwnd as a third list element provides a unique
* identifier in the case of multiple servers with the name
* application and topic names.
*/
- /*
- * Needs a TIP though:
- * Tcl_ListObjAppendElement(NULL, matchPtr,
+ /* Needs a TIP though
+ * Tcl_ListObjAppendElement(es->interp, matchPtr,
* Tcl_NewLongObj((long)hwndRemote));
*/
-
- if (Tcl_IsShared(resultPtr)) {
- resultPtr = Tcl_DuplicateObj(resultPtr);
- }
- if (Tcl_ListObjAppendElement(es->interp, resultPtr,
- matchPtr) == TCL_OK) {
- Tcl_SetObjResult(es->interp, resultPtr);
- }
+ Tcl_ListObjAppendElement(es->interp,
+ Tcl_GetObjResult(es->interp), matchPtr);
}
- /*
- * Tell the server we are no longer interested.
- */
-
+ /* tell the server we are no longer interested */
PostMessage(hwndRemote, WM_DDE_TERMINATE, (WPARAM)hwnd, 0L);
return 0L;
}
-
+
static BOOL CALLBACK
-DdeEnumWindowsCallback(
- HWND hwndTarget,
- LPARAM lParam)
+DdeEnumWindowsCallback(HWND hwndTarget, LPARAM lParam)
{
DWORD_PTR dwResult = 0;
- struct DdeEnumServices *es = (struct DdeEnumServices *) lParam;
-
- SendMessageTimeout(hwndTarget, WM_DDE_INITIATE, (WPARAM)es->hwnd,
- MAKELONG(es->service, es->topic), SMTO_ABORTIFHUNG, 1000,
- &dwResult);
+ ddeEnumServices *es = (ddeEnumServices *)lParam;
+ SendMessageTimeout(hwndTarget, WM_DDE_INITIATE,
+ (WPARAM)es->hwnd,
+ MAKELONG(es->service, es->topic),
+ SMTO_ABORTIFHUNG, 1000, &dwResult);
return TRUE;
}
-
+
static int
-DdeGetServicesList(
- Tcl_Interp *interp,
- char *serviceName,
- char *topicName)
+DdeGetServicesList(Tcl_Interp *interp, char *serviceName, char *topicName)
{
- struct DdeEnumServices es;
-
+ ddeEnumServices es;
es.interp = interp;
es.result = TCL_OK;
es.service = (serviceName == NULL)
- ? (ATOM)0 : GlobalAddAtom(serviceName);
- es.topic = (topicName == NULL) ? (ATOM)0 : GlobalAddAtom(topicName);
-
+ ? (ATOM)0 : GlobalAddAtom(serviceName);
+ es.topic = (topicName == NULL)
+ ? (ATOM)0 : GlobalAddAtom(topicName);
+
Tcl_ResetResult(interp); /* our list is to be appended to result. */
DdeCreateClient(&es);
EnumWindows(DdeEnumWindowsCallback, (LPARAM)&es);
-
- if (IsWindow(es.hwnd)) {
- DestroyWindow(es.hwnd);
- }
- if (es.service != (ATOM)0) {
+
+ if (IsWindow(es.hwnd))
+ DestroyWindow(es.hwnd);
+ if (es.service != (ATOM)0)
GlobalDeleteAtom(es.service);
- }
- if (es.topic != (ATOM)0) {
+ if (es.topic != (ATOM)0)
GlobalDeleteAtom(es.topic);
- }
return es.result;
}
/*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*
* SetDdeError --
*
- * Sets the interp result to a cogent error message describing the last
- * DDE error.
+ * Sets the interp result to a cogent error message
+ * describing the last DDE error.
*
* Results:
* None.
+ *
*
* Side effects:
* The interp's result object is changed.
*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*/
static void
SetDdeError(
- Tcl_Interp *interp) /* The interp to put the message in. */
+ Tcl_Interp *interp) /* The interp to put the message in.*/
{
- char *errorMessage;
-
- switch (DdeGetLastError(ddeInstance)) {
- case DMLERR_DATAACKTIMEOUT:
- case DMLERR_EXECACKTIMEOUT:
- case DMLERR_POKEACKTIMEOUT:
- errorMessage = "remote interpreter did not respond";
- break;
- case DMLERR_BUSY:
- errorMessage = "remote server is busy";
- break;
- case DMLERR_NOTPROCESSED:
- errorMessage = "remote server cannot handle this command";
- break;
- default:
- errorMessage = "dde command failed";
- }
+ Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
+ int err;
+
+ err = DdeGetLastError(ddeInstance);
+ switch (err) {
+ case DMLERR_DATAACKTIMEOUT:
+ case DMLERR_EXECACKTIMEOUT:
+ case DMLERR_POKEACKTIMEOUT:
+ Tcl_SetStringObj(resultPtr,
+ "remote interpreter did not respond", -1);
+ break;
+
+ case DMLERR_BUSY:
+ Tcl_SetStringObj(resultPtr, "remote server is busy", -1);
+ break;
+
+ case DMLERR_NOTPROCESSED:
+ Tcl_SetStringObj(resultPtr,
+ "remote server cannot handle this command", -1);
+ break;
- Tcl_SetObjResult(interp, Tcl_NewStringObj(errorMessage, -1));
+ default:
+ Tcl_SetStringObj(resultPtr, "dde command failed", -1);
+ }
}
/*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*
* Tcl_DdeObjCmd --
*
- * This function is invoked to process the "dde" Tcl command. See the
- * user documentation for details on what it does.
+ * This procedure is invoked to process the "dde" Tcl command.
+ * See the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -1127,7 +969,7 @@ SetDdeError(
* Side effects:
* See the user documentation.
*
- *----------------------------------------------------------------------
+ *--------------------------------------------------------------
*/
int
@@ -1135,45 +977,49 @@ Tcl_DdeObjCmd(
ClientData clientData, /* Used only for deletion */
Tcl_Interp *interp, /* The interp we are sending from */
int objc, /* Number of arguments */
- Tcl_Obj *CONST * objv) /* The arguments */
+ Tcl_Obj *CONST *objv) /* The arguments */
{
- static CONST char *ddeCommands[] = {
- "servername", "execute", "poke", "request", "services", "eval",
- (char *) NULL
- };
- enum DdeSubcommands {
- DDE_SERVERNAME, DDE_EXECUTE, DDE_POKE, DDE_REQUEST, DDE_SERVICES,
+ enum {
+ DDE_SERVERNAME,
+ DDE_EXECUTE,
+ DDE_POKE,
+ DDE_REQUEST,
+ DDE_SERVICES,
DDE_EVAL
};
- static CONST char *ddeSrvOptions[] = {
- "-force", "-handler", "--", NULL
- };
- enum DdeSrvOptions {
- DDE_SERVERNAME_EXACT, DDE_SERVERNAME_HANDLER, DDE_SERVERNAME_LAST,
- };
- static CONST char *ddeExecOptions[] = {
- "-async", NULL
- };
- static CONST char *ddeReqOptions[] = {
- "-binary", NULL
- };
- int index, i, length;
- int async = 0, binary = 0, exact = 0;
- int result = TCL_OK, firstArg = 0;
- HSZ ddeService = NULL, ddeTopic = NULL, ddeItem = NULL, ddeCookie = NULL;
- HDDEDATA ddeData = NULL, ddeItemData = NULL, ddeReturn;
+ static CONST char *ddeCommands[] = {"servername", "execute", "poke",
+ "request", "services", "eval",
+ (char *) NULL};
+ static CONST char *ddeOptions[] = {"-async", (char *) NULL};
+ static CONST char *ddeReqOptions[] = {"-binary", (char *) NULL};
+ int index, argIndex;
+ int async = 0, binary = 0;
+ int result = TCL_OK;
+ HSZ ddeService = NULL;
+ HSZ ddeTopic = NULL;
+ HSZ ddeItem = NULL;
+ HDDEDATA ddeData = NULL;
+ HDDEDATA ddeItemData = NULL;
HCONV hConv = NULL;
- char *serviceName = NULL, *topicName = NULL, *string;
+ HSZ ddeCookie = 0;
+ char *serviceName, *topicName = NULL, *itemString;
+ char *string;
+ int firstArg = 0, length, dataLength;
DWORD ddeResult;
- Tcl_Obj *objPtr, *handlerPtr = NULL;
+ HDDEDATA ddeReturn;
+ RegisteredInterp *riPtr;
+ Tcl_Interp *sendInterp;
+ Tcl_Obj *objPtr;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
* Initialize DDE server/client
*/
-
+
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "command ?arg ...?");
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?-async? serviceName topicName value");
return TCL_ERROR;
}
@@ -1182,124 +1028,105 @@ Tcl_DdeObjCmd(
return TCL_ERROR;
}
- switch ((enum DdeSubcommands) index) {
- case DDE_SERVERNAME:
- for (i = 2; i < objc; i++) {
- int argIndex;
- if (Tcl_GetIndexFromObj(interp, objv[i], ddeSrvOptions,
- "option", 0, &argIndex) != TCL_OK) {
- /*
- * If it is the last argument, it might be a server name
- * instead of a bad argument.
- */
-
- if (i != objc-1) {
+ switch (index) {
+ case DDE_SERVERNAME:
+ if ((objc != 3) && (objc != 2)) {
+ Tcl_WrongNumArgs(interp, 1, objv, "servername ?serverName?");
+ return TCL_ERROR;
+ }
+ firstArg = (objc - 1);
+ break;
+ case DDE_EXECUTE:
+ if ((objc < 5) || (objc > 6)) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "execute ?-async? serviceName topicName value");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(NULL, objv[2], ddeOptions, "option", 0,
+ &argIndex) != TCL_OK) {
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "execute ?-async? serviceName topicName value");
return TCL_ERROR;
}
- Tcl_ResetResult(interp);
- break;
- }
- if (argIndex == DDE_SERVERNAME_EXACT) {
- exact = 1;
- } else if (argIndex == DDE_SERVERNAME_HANDLER) {
- if ((objc - i) == 1) { /* return current handler */
- RegisteredInterp *riPtr = DdeGetRegistrationPtr(interp);
-
- if (riPtr && riPtr->handlerPtr) {
- Tcl_SetObjResult(interp, riPtr->handlerPtr);
- } else {
- Tcl_ResetResult(interp);
- }
- return TCL_OK;
+ async = 0;
+ firstArg = 2;
+ } else {
+ if (objc != 6) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "execute ?-async? serviceName topicName value");
+ return TCL_ERROR;
}
- handlerPtr = objv[++i];
- } else if (argIndex == DDE_SERVERNAME_LAST) {
- i++;
- break;
- }
- }
-
- if ((objc - i) > 1) {
- Tcl_ResetResult(interp);
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-force? ?-handler proc? ?--? ?serverName?");
- return TCL_ERROR;
- }
-
- firstArg = (objc == i) ? 1 : i;
- break;
- case DDE_EXECUTE:
- if (objc == 5) {
- firstArg = 2;
- break;
- } else if (objc == 6) {
- int dummy;
- if (Tcl_GetIndexFromObj(NULL, objv[2], ddeExecOptions, "option", 0,
- &dummy) == TCL_OK) {
async = 1;
firstArg = 3;
- break;
}
- }
- /* otherwise... */
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-async? serviceName topicName value");
- return TCL_ERROR;
- case DDE_POKE:
- if (objc != 6) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "serviceName topicName item value");
- return TCL_ERROR;
- }
- firstArg = 2;
- break;
- case DDE_REQUEST:
- if (objc == 5) {
+ break;
+ case DDE_POKE:
+ if (objc != 6) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "poke serviceName topicName item value");
+ return TCL_ERROR;
+ }
firstArg = 2;
break;
- } else if (objc == 6) {
- int dummy;
+ case DDE_REQUEST:
+ if ((objc < 5) || (objc > 6)) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "request ?-binary? serviceName topicName value");
+ return TCL_ERROR;
+ }
if (Tcl_GetIndexFromObj(NULL, objv[2], ddeReqOptions, "option", 0,
- &dummy) == TCL_OK) {
+ &argIndex) != TCL_OK) {
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "request ?-binary? serviceName topicName value");
+ return TCL_ERROR;
+ }
+ binary = 0;
+ firstArg = 2;
+ } else {
+ if (objc != 6) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "request ?-binary? serviceName topicName value");
+ return TCL_ERROR;
+ }
binary = 1;
firstArg = 3;
- break;
}
- }
-
- /*
- * Otherwise ...
- */
-
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-binary? serviceName topicName value");
- return TCL_ERROR;
- case DDE_SERVICES:
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "serviceName topicName");
- return TCL_ERROR;
- }
- firstArg = 2;
- break;
- case DDE_EVAL:
- if (objc < 4) {
- wrongDdeEvalArgs:
- Tcl_WrongNumArgs(interp, 2, objv, "?-async? serviceName args");
- return TCL_ERROR;
- } else {
- int dummy;
-
+ break;
+ case DDE_SERVICES:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "services serviceName topicName");
+ return TCL_ERROR;
+ }
firstArg = 2;
- if (Tcl_GetIndexFromObj(NULL, objv[2], ddeExecOptions, "option", 0,
- &dummy) == TCL_OK) {
+ break;
+ case DDE_EVAL:
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "eval ?-async? serviceName args");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(NULL, objv[2], ddeOptions, "option", 0,
+ &argIndex) != TCL_OK) {
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "eval ?-async? serviceName args");
+ return TCL_ERROR;
+ }
+ async = 0;
+ firstArg = 2;
+ } else {
if (objc < 5) {
- goto wrongDdeEvalArgs;
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "eval ?-async? serviceName args");
+ return TCL_ERROR;
}
async = 1;
- firstArg++;
+ firstArg = 3;
}
break;
- }
}
Initialize();
@@ -1313,368 +1140,351 @@ Tcl_DdeObjCmd(
if (length == 0) {
serviceName = NULL;
} else if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) {
- ddeService = DdeCreateStringHandle(ddeInstance, (void *) serviceName,
+ ddeService = DdeCreateStringHandle(ddeInstance, serviceName,
CP_WINANSI);
}
- if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) {
+ if ((index != DDE_SERVERNAME) &&(index != DDE_EVAL)) {
topicName = Tcl_GetStringFromObj(objv[firstArg + 1], &length);
if (length == 0) {
topicName = NULL;
} else {
- ddeTopic = DdeCreateStringHandle(ddeInstance, (void *) topicName,
- CP_WINANSI);
+ ddeTopic = DdeCreateStringHandle(ddeInstance,
+ topicName, CP_WINANSI);
}
}
- switch ((enum DdeSubcommands) index) {
- case DDE_SERVERNAME:
- serviceName = DdeSetServerName(interp, serviceName, exact, handlerPtr);
- if (serviceName != NULL) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(serviceName, -1));
- } else {
- Tcl_ResetResult(interp);
- }
- break;
-
- case DDE_EXECUTE: {
- int dataLength;
- BYTE *dataString = (BYTE *) Tcl_GetStringFromObj(
- objv[firstArg + 2], &dataLength);
-
- if (dataLength == 0) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("cannot execute null data", -1));
- result = TCL_ERROR;
- break;
- }
- hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
- DdeFreeStringHandle(ddeInstance, ddeService);
- DdeFreeStringHandle(ddeInstance, ddeTopic);
-
- if (hConv == NULL) {
- SetDdeError(interp);
- result = TCL_ERROR;
- break;
- }
-
- ddeData = DdeCreateDataHandle(ddeInstance, dataString,
- (DWORD) dataLength+1, 0, 0, CF_TEXT, 0);
- if (ddeData != NULL) {
- if (async) {
- DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0,
- CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
- DdeAbandonTransaction(ddeInstance, hConv, ddeResult);
+ switch (index) {
+ case DDE_SERVERNAME: {
+ serviceName = DdeSetServerName(interp, serviceName);
+ if (serviceName != NULL) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp),
+ serviceName, -1);
} else {
- ddeReturn = DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF,
- hConv, 0, CF_TEXT, XTYP_EXECUTE, 30000, NULL);
- if (ddeReturn == 0) {
- SetDdeError(interp);
- result = TCL_ERROR;
- }
+ Tcl_ResetResult(interp);
}
- DdeFreeDataHandle(ddeData);
- } else {
- SetDdeError(interp);
- result = TCL_ERROR;
+ break;
}
- break;
- }
- case DDE_REQUEST: {
- char *itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length);
+ case DDE_EXECUTE: {
+ BYTE *dataString = (BYTE *) Tcl_GetStringFromObj(
+ objv[firstArg + 2], &dataLength);
+ if (dataLength == 0) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp),
+ "cannot execute null data", -1);
+ result = TCL_ERROR;
+ break;
+ }
+ hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
+ DdeFreeStringHandle(ddeInstance, ddeService);
+ DdeFreeStringHandle(ddeInstance, ddeTopic);
- if (length == 0) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("cannot request value of null data", -1));
- result = TCL_ERROR;
- goto cleanup;
- }
- hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
- DdeFreeStringHandle(ddeInstance, ddeService);
- DdeFreeStringHandle(ddeInstance, ddeTopic);
+ if (hConv == NULL) {
+ SetDdeError(interp);
+ result = TCL_ERROR;
+ break;
+ }
- if (hConv == NULL) {
- SetDdeError(interp);
- result = TCL_ERROR;
- } else {
- Tcl_Obj *returnObjPtr;
- ddeItem = DdeCreateStringHandle(ddeInstance, (void *)itemString,
- CP_WINANSI);
- if (ddeItem != NULL) {
- ddeData = DdeClientTransaction(NULL, 0, hConv, ddeItem,
- CF_TEXT, XTYP_REQUEST, 5000, NULL);
- if (ddeData == NULL) {
- SetDdeError(interp);
- result = TCL_ERROR;
+ ddeData = DdeCreateDataHandle(ddeInstance, dataString,
+ (DWORD) dataLength+1, 0, 0, CF_TEXT, 0);
+ if (ddeData != NULL) {
+ if (async) {
+ DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0,
+ CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
+ DdeAbandonTransaction(ddeInstance, hConv,
+ ddeResult);
} else {
- DWORD tmp;
- const BYTE *dataString = DdeAccessData(ddeData, &tmp);
-
- if (binary) {
- returnObjPtr = Tcl_NewByteArrayObj(dataString,
- (int) tmp);
- } else {
- returnObjPtr = Tcl_NewStringObj((const char *)dataString, -1);
+ ddeReturn = DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF,
+ hConv, 0, CF_TEXT, XTYP_EXECUTE, 30000, NULL);
+ if (ddeReturn == 0) {
+ SetDdeError(interp);
+ result = TCL_ERROR;
}
- DdeUnaccessData(ddeData);
- DdeFreeDataHandle(ddeData);
- Tcl_SetObjResult(interp, returnObjPtr);
}
+ DdeFreeDataHandle(ddeData);
} else {
SetDdeError(interp);
result = TCL_ERROR;
}
+ break;
}
+ case DDE_REQUEST: {
+ itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length);
+ if (length == 0) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp),
+ "cannot request value of null data", -1);
+ goto errorNoResult;
+ }
+ hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
+ DdeFreeStringHandle(ddeInstance, ddeService);
+ DdeFreeStringHandle(ddeInstance, ddeTopic);
+
+ if (hConv == NULL) {
+ SetDdeError(interp);
+ result = TCL_ERROR;
+ } else {
+ Tcl_Obj *returnObjPtr;
+ ddeItem = DdeCreateStringHandle(ddeInstance,
+ itemString, CP_WINANSI);
+ if (ddeItem != NULL) {
+ ddeData = DdeClientTransaction(NULL, 0, hConv, ddeItem,
+ CF_TEXT, XTYP_REQUEST, 5000, NULL);
+ if (ddeData == NULL) {
+ SetDdeError(interp);
+ result = TCL_ERROR;
+ } else {
+ DWORD tmp;
+ BYTE *dataString = (BYTE *) DdeAccessData(ddeData, &tmp);
+ dataLength = tmp;
+ if (binary) {
+ returnObjPtr = Tcl_NewByteArrayObj(dataString,
+ dataLength);
+ } else {
+ returnObjPtr = Tcl_NewStringObj((char *) dataString, -1);
+ }
+ DdeUnaccessData(ddeData);
+ DdeFreeDataHandle(ddeData);
+ Tcl_SetObjResult(interp, returnObjPtr);
+ }
+ } else {
+ SetDdeError(interp);
+ result = TCL_ERROR;
+ }
+ }
- break;
- }
- case DDE_POKE: {
- char *itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length);
- BYTE *dataString;
-
- if (length == 0) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("cannot have a null item", -1));
- result = TCL_ERROR;
- goto cleanup;
+ break;
}
- dataString = (BYTE *) Tcl_GetStringFromObj(objv[firstArg + 3],
- &length);
-
- hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
- DdeFreeStringHandle(ddeInstance, ddeService);
- DdeFreeStringHandle(ddeInstance, ddeTopic);
+ case DDE_POKE: {
+ BYTE *dataString;
+ itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length);
+ if (length == 0) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp),
+ "cannot have a null item", -1);
+ goto errorNoResult;
+ }
+ dataString = (BYTE *) Tcl_GetStringFromObj(objv[firstArg + 3], &length);
+
+ hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
+ DdeFreeStringHandle(ddeInstance, ddeService);
+ DdeFreeStringHandle(ddeInstance, ddeTopic);
- if (hConv == NULL) {
- SetDdeError(interp);
- result = TCL_ERROR;
- } else {
- ddeItem = DdeCreateStringHandle(ddeInstance, (void *) itemString,
- CP_WINANSI);
- if (ddeItem != NULL) {
- ddeData = DdeClientTransaction(dataString, (DWORD) length+1,
- hConv, ddeItem, CF_TEXT, XTYP_POKE, 5000, NULL);
- if (ddeData == NULL) {
+ if (hConv == NULL) {
+ SetDdeError(interp);
+ result = TCL_ERROR;
+ } else {
+ ddeItem = DdeCreateStringHandle(ddeInstance, itemString,
+ CP_WINANSI);
+ if (ddeItem != NULL) {
+ ddeData = DdeClientTransaction(dataString, (DWORD) length+1,
+ hConv, ddeItem, CF_TEXT, XTYP_POKE, 5000, NULL);
+ if (ddeData == NULL) {
+ SetDdeError(interp);
+ result = TCL_ERROR;
+ }
+ } else {
SetDdeError(interp);
result = TCL_ERROR;
}
- } else {
- SetDdeError(interp);
- result = TCL_ERROR;
}
+ break;
}
- break;
- }
-
- case DDE_SERVICES:
- result = DdeGetServicesList(interp, serviceName, topicName);
- break;
-
- case DDE_EVAL: {
- RegisteredInterp *riPtr;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- if (serviceName == NULL) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("invalid service name \"\"", -1));
- result = TCL_ERROR;
- goto cleanup;
+ case DDE_SERVICES: {
+ result = DdeGetServicesList(interp, serviceName, topicName);
+ break;
}
-
- objc -= (async + 3);
- objv += (async + 3);
-
- /*
- * See if the target interpreter is local. If so, execute the command
- * directly without going through the DDE server. Don't exchange
- * objects between interps. The target interp could compile an object,
- * producing a bytecode structure that refers to other objects owned
- * by the target interp. If the target interp is then deleted, the
- * bytecode structure would be referring to deallocated objects.
- */
-
- for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
- riPtr = riPtr->nextPtr) {
- if (stricmp(serviceName, riPtr->name) == 0) {
- break;
+ case DDE_EVAL: {
+ if (serviceName == NULL) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp),
+ "invalid service name \"\"", -1);
+ goto errorNoResult;
}
- }
-
- if (riPtr != NULL) {
- Tcl_Interp *sendInterp;
-
- /*
- * This command is to a local interp. No need to go through the
- * server.
- */
-
- Tcl_Preserve((ClientData) riPtr);
- sendInterp = riPtr->interp;
- Tcl_Preserve((ClientData) sendInterp);
- /*
- * Don't exchange objects between interps. The target interp would
- * compile an object, producing a bytecode structure that refers
- * to other objects owned by the target interp. If the target
- * interp is then deleted, the bytecode structure would be
- * referring to deallocated objects.
+ objc -= (async + 3);
+ objv += (async + 3);
+
+ /*
+ * See if the target interpreter is local. If so, execute
+ * the command directly without going through the DDE server.
+ * Don't exchange objects between interps. The target interp could
+ * compile an object, producing a bytecode structure that refers to
+ * other objects owned by the target interp. If the target interp
+ * is then deleted, the bytecode structure would be referring to
+ * deallocated objects.
*/
-
- if (Tcl_IsSafe(riPtr->interp) && riPtr->handlerPtr == NULL) {
- Tcl_SetResult(riPtr->interp, "permission denied: "
- "a handler procedure must be defined for use in "
- "a safe interp", TCL_STATIC);
- result = TCL_ERROR;
+
+ for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
+ riPtr = riPtr->nextPtr) {
+ if (stricmp(serviceName, riPtr->name) == 0) {
+ break;
+ }
}
- if (result == TCL_OK) {
- if (objc == 1)
- objPtr = objv[0];
- else {
+ if (riPtr != NULL) {
+ /*
+ * This command is to a local interp. No need to go through
+ * the server.
+ */
+
+ Tcl_Preserve((ClientData) riPtr);
+ sendInterp = riPtr->interp;
+ Tcl_Preserve((ClientData) sendInterp);
+
+ /*
+ * Don't exchange objects between interps. The target interp
+ * would compile an object, producing a bytecode structure that
+ * refers to other objects owned by the target interp. If the
+ * target interp is then deleted, the bytecode structure would
+ * be referring to deallocated objects.
+ */
+
+ if (objc == 1) {
+ result = Tcl_EvalObjEx(sendInterp, objv[0],
+ TCL_EVAL_GLOBAL);
+ } else {
objPtr = Tcl_ConcatObj(objc, objv);
+ Tcl_IncrRefCount(objPtr);
+ result = Tcl_EvalObjEx(sendInterp, objPtr,
+ TCL_EVAL_GLOBAL);
+ Tcl_DecrRefCount(objPtr);
}
- if (riPtr->handlerPtr != NULL) {
- /* add the dde request data to the handler proc list */
- /*
- *result = Tcl_ListObjReplace(sendInterp, objPtr, 0, 0, 1,
- * &(riPtr->handlerPtr));
- */
- Tcl_Obj *cmdPtr = Tcl_DuplicateObj(riPtr->handlerPtr);
- result = Tcl_ListObjAppendElement(sendInterp, cmdPtr,
- objPtr);
- if (result == TCL_OK) {
- objPtr = cmdPtr;
- }
- }
- }
- if (result == TCL_OK) {
- Tcl_IncrRefCount(objPtr);
- result = Tcl_EvalObjEx(sendInterp, objPtr, TCL_EVAL_GLOBAL);
- Tcl_DecrRefCount(objPtr);
- }
- if (interp != sendInterp) {
- if (result == TCL_ERROR) {
- /*
- * An error occurred, so transfer error information from
- * the destination interpreter back to our interpreter.
- */
-
- Tcl_ResetResult(interp);
- objPtr = Tcl_GetVar2Ex(sendInterp, "errorInfo", NULL,
- TCL_GLOBAL_ONLY);
- if (objPtr) {
+ if (interp != sendInterp) {
+ if (result == TCL_ERROR) {
+ /*
+ * An error occurred, so transfer error information
+ * from the destination interpreter back to our
+ * interpreter.
+ */
+
+ Tcl_ResetResult(interp);
+ objPtr = Tcl_GetVar2Ex(sendInterp, "errorInfo", NULL,
+ TCL_GLOBAL_ONLY);
string = Tcl_GetStringFromObj(objPtr, &length);
Tcl_AddObjErrorInfo(interp, string, length);
- }
-
- objPtr = Tcl_GetVar2Ex(sendInterp, "errorCode", NULL,
- TCL_GLOBAL_ONLY);
- if (objPtr) {
+
+ objPtr = Tcl_GetVar2Ex(sendInterp, "errorCode", NULL,
+ TCL_GLOBAL_ONLY);
Tcl_SetObjErrorCode(interp, objPtr);
}
+ Tcl_SetObjResult(interp, Tcl_GetObjResult(sendInterp));
}
- Tcl_SetObjResult(interp, Tcl_GetObjResult(sendInterp));
- }
- Tcl_Release((ClientData) riPtr);
- Tcl_Release((ClientData) sendInterp);
- } else {
- /*
- * This is a non-local request. Send the script to the server and
- * poll it for a result.
- */
-
- if (MakeDdeConnection(interp, serviceName, &hConv) != TCL_OK) {
- invalidServerResponse:
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("invalid data returned from server",
- -1));
- result = TCL_ERROR;
- goto cleanup;
- }
-
- objPtr = Tcl_ConcatObj(objc, objv);
- string = Tcl_GetStringFromObj(objPtr, &length);
- ddeItemData = DdeCreateDataHandle(ddeInstance,
- (BYTE *) string, (DWORD) length+1, 0, 0, CF_TEXT, 0);
-
- if (async) {
- ddeData = DdeClientTransaction((LPBYTE) ddeItemData,
- 0xFFFFFFFF, hConv, 0,
- CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
- DdeAbandonTransaction(ddeInstance, hConv, ddeResult);
+ Tcl_Release((ClientData) riPtr);
+ Tcl_Release((ClientData) sendInterp);
} else {
- ddeData = DdeClientTransaction((LPBYTE) ddeItemData,
- 0xFFFFFFFF, hConv, 0,
- CF_TEXT, XTYP_EXECUTE, 30000, NULL);
- if (ddeData != 0) {
- ddeCookie = DdeCreateStringHandle(ddeInstance,
- TCL_DDE_EXECUTE_RESULT, CP_WINANSI);
- ddeData = DdeClientTransaction(NULL, 0, hConv, ddeCookie,
- CF_TEXT, XTYP_REQUEST, 30000, NULL);
- }
- }
-
- Tcl_DecrRefCount(objPtr);
-
- if (ddeData == 0) {
- SetDdeError(interp);
- result = TCL_ERROR;
- }
-
- if (async == 0) {
- Tcl_Obj *resultPtr;
-
/*
- * The return handle has a two or four element list in it. The
- * first element is the return code (TCL_OK, TCL_ERROR, etc.).
- * The second is the result of the script. If the return code
- * is TCL_ERROR, then the third element is the value of the
- * variable "errorCode", and the fourth is the value of the
- * variable "errorInfo".
+ * This is a non-local request. Send the script to the server
+ * and poll it for a result.
*/
-
- resultPtr = Tcl_NewObj();
- length = DdeGetData(ddeData, NULL, 0, 0);
- Tcl_SetObjLength(resultPtr, length);
- string = Tcl_GetString(resultPtr);
- DdeGetData(ddeData, (BYTE *) string, (DWORD) length, 0);
- Tcl_SetObjLength(resultPtr, (int) strlen(string));
-
- if (Tcl_ListObjIndex(NULL, resultPtr, 0, &objPtr) != TCL_OK) {
- Tcl_DecrRefCount(resultPtr);
- goto invalidServerResponse;
+
+ if (MakeDdeConnection(interp, serviceName, &hConv) != TCL_OK) {
+ goto error;
}
- if (Tcl_GetIntFromObj(NULL, objPtr, &result) != TCL_OK) {
- Tcl_DecrRefCount(resultPtr);
- goto invalidServerResponse;
+
+ objPtr = Tcl_ConcatObj(objc, objv);
+ string = Tcl_GetStringFromObj(objPtr, &length);
+ ddeItemData = DdeCreateDataHandle(ddeInstance, (BYTE *) string,
+ (DWORD) length+1, 0, 0, CF_TEXT, 0);
+
+ if (async) {
+ ddeData = DdeClientTransaction((LPBYTE) ddeItemData,
+ 0xFFFFFFFF, hConv, 0,
+ CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
+ DdeAbandonTransaction(ddeInstance, hConv, ddeResult);
+ } else {
+ ddeData = DdeClientTransaction((LPBYTE) ddeItemData,
+ 0xFFFFFFFF, hConv, 0,
+ CF_TEXT, XTYP_EXECUTE, 30000, NULL);
+ if (ddeData != 0) {
+
+ ddeCookie = DdeCreateStringHandle(ddeInstance,
+ "$TCLEVAL$EXECUTE$RESULT", CP_WINANSI);
+ ddeData = DdeClientTransaction(NULL, 0, hConv,
+ ddeCookie, CF_TEXT, XTYP_REQUEST, 30000, NULL);
+ }
}
- if (result == TCL_ERROR) {
- Tcl_ResetResult(interp);
- if (Tcl_ListObjIndex(NULL, resultPtr, 3,
- &objPtr) != TCL_OK) {
+ Tcl_DecrRefCount(objPtr);
+
+ if (ddeData == 0) {
+ SetDdeError(interp);
+ goto errorNoResult;
+ }
+
+ if (async == 0) {
+ Tcl_Obj *resultPtr;
+
+ /*
+ * The return handle has a two or four element list in
+ * it. The first element is the return code (TCL_OK,
+ * TCL_ERROR, etc.). The second is the result of the
+ * script. If the return code is TCL_ERROR, then the third
+ * element is the value of the variable "errorCode", and
+ * the fourth is the value of the variable "errorInfo".
+ */
+
+ resultPtr = Tcl_NewObj();
+ length = DdeGetData(ddeData, NULL, 0, 0);
+ Tcl_SetObjLength(resultPtr, length);
+ string = Tcl_GetString(resultPtr);
+ DdeGetData(ddeData, (BYTE *) string, (DWORD) length, 0);
+ Tcl_SetObjLength(resultPtr, (int) strlen(string));
+
+ if (Tcl_ListObjIndex(NULL, resultPtr, 0, &objPtr)
+ != TCL_OK) {
Tcl_DecrRefCount(resultPtr);
- goto invalidServerResponse;
+ goto error;
}
- length = -1;
- string = Tcl_GetStringFromObj(objPtr, &length);
- Tcl_AddObjErrorInfo(interp, string, length);
+ if (Tcl_GetIntFromObj(NULL, objPtr, &result) != TCL_OK) {
+ Tcl_DecrRefCount(resultPtr);
+ goto error;
+ }
+ if (result == TCL_ERROR) {
+ Tcl_ResetResult(interp);
- Tcl_ListObjIndex(NULL, resultPtr, 2, &objPtr);
- Tcl_SetObjErrorCode(interp, objPtr);
- }
- if (Tcl_ListObjIndex(NULL, resultPtr, 1, &objPtr) != TCL_OK) {
+ if (Tcl_ListObjIndex(NULL, resultPtr, 3, &objPtr)
+ != TCL_OK) {
+ Tcl_DecrRefCount(resultPtr);
+ goto error;
+ }
+ length = -1;
+ string = Tcl_GetStringFromObj(objPtr, &length);
+ Tcl_AddObjErrorInfo(interp, string, length);
+
+ Tcl_ListObjIndex(NULL, resultPtr, 2, &objPtr);
+ Tcl_SetObjErrorCode(interp, objPtr);
+ }
+ if (Tcl_ListObjIndex(NULL, resultPtr, 1, &objPtr)
+ != TCL_OK) {
+ Tcl_DecrRefCount(resultPtr);
+ goto error;
+ }
+ Tcl_SetObjResult(interp, objPtr);
Tcl_DecrRefCount(resultPtr);
- goto invalidServerResponse;
}
- Tcl_SetObjResult(interp, objPtr);
- Tcl_DecrRefCount(resultPtr);
}
}
}
+ if (ddeCookie != NULL) {
+ DdeFreeStringHandle(ddeInstance, ddeCookie);
+ }
+ if (ddeItem != NULL) {
+ DdeFreeStringHandle(ddeInstance, ddeItem);
+ }
+ if (ddeItemData != NULL) {
+ DdeFreeDataHandle(ddeItemData);
+ }
+ if (ddeData != NULL) {
+ DdeFreeDataHandle(ddeData);
}
+ if (hConv != NULL) {
+ DdeDisconnect(hConv);
+ }
+ return result;
- cleanup:
+ error:
+ Tcl_SetStringObj(Tcl_GetObjResult(interp),
+ "invalid data returned from server", -1);
+
+ errorNoResult:
if (ddeCookie != NULL) {
DdeFreeStringHandle(ddeInstance, ddeCookie);
}
@@ -1690,15 +1500,5 @@ Tcl_DdeObjCmd(
if (hConv != NULL) {
DdeDisconnect(hConv);
}
- return result;
+ return TCL_ERROR;
}
-
-/*
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * tab-width: 8
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinError.c b/win/tclWinError.c
index ca1b0e8..da1e335 100644
--- a/win/tclWinError.c
+++ b/win/tclWinError.c
@@ -1,19 +1,20 @@
-/*
+/*
* tclWinError.c --
*
- * This file contains code for converting from Win32 errors to errno
- * errors.
+ * This file contains code for converting from Win32 errors to
+ * errno errors.
*
* Copyright (c) 1995-1996 by Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tclInt.h"
+#include "tclWinInt.h"
/*
- * The following table contains the mapping from Win32 errors to errno errors.
+ * The following table contains the mapping from Win32 errors to
+ * errno errors.
*/
static char errorTable[] = {
@@ -351,8 +352,8 @@ static int wsaErrorTable[] = {
*/
void
-TclWinConvertError(
- unsigned long errCode) /* Win32 error code. */
+TclWinConvertError(errCode)
+ DWORD errCode; /* Win32 error code. */
{
if (errCode >= tableLen) {
Tcl_SetErrno(EINVAL);
@@ -378,8 +379,8 @@ TclWinConvertError(
*/
void
-TclWinConvertWSAError(
- unsigned long errCode) /* Win32 error code. */
+TclWinConvertWSAError(errCode)
+ DWORD errCode; /* Win32 error code. */
{
if ((errCode >= WSAEWOULDBLOCK) && (errCode <= WSAEREMOTE)) {
Tcl_SetErrno(wsaErrorTable[errCode - WSAEWOULDBLOCK]);
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c
index a1338a7..231e4b7 100644
--- a/win/tclWinFCmd.c
+++ b/win/tclWinFCmd.c
@@ -1,13 +1,13 @@
/*
* tclWinFCmd.c
*
- * This file implements the Windows specific portion of file manipulation
- * subcommands of the "file" command.
+ * This file implements the Windows specific portion of file manipulation
+ * subcommands of the "file" command.
*
* Copyright (c) 1996-1998 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclWinInt.h"
@@ -17,25 +17,29 @@
* TraverseWinTree() calls the traverseProc()
*/
-#define DOTREE_PRED 1 /* pre-order directory */
-#define DOTREE_POSTD 2 /* post-order directory */
-#define DOTREE_F 3 /* regular file */
-#define DOTREE_LINK 4 /* symbolic link */
+#define DOTREE_PRED 1 /* pre-order directory */
+#define DOTREE_POSTD 2 /* post-order directory */
+#define DOTREE_F 3 /* regular file */
/*
* Callbacks for file attributes code.
*/
-static int GetWinFileAttributes(Tcl_Interp *interp, int objIndex,
- Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr);
-static int GetWinFileLongName(Tcl_Interp *interp, int objIndex,
- Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr);
-static int GetWinFileShortName(Tcl_Interp *interp, int objIndex,
- Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr);
-static int SetWinFileAttributes(Tcl_Interp *interp, int objIndex,
- Tcl_Obj *fileName, Tcl_Obj *attributePtr);
-static int CannotSetAttribute(Tcl_Interp *interp, int objIndex,
- Tcl_Obj *fileName, Tcl_Obj *attributePtr);
+static int GetWinFileAttributes _ANSI_ARGS_((Tcl_Interp *interp,
+ int objIndex, Tcl_Obj *fileName,
+ Tcl_Obj **attributePtrPtr));
+static int GetWinFileLongName _ANSI_ARGS_((Tcl_Interp *interp,
+ int objIndex, Tcl_Obj *fileName,
+ Tcl_Obj **attributePtrPtr));
+static int GetWinFileShortName _ANSI_ARGS_((Tcl_Interp *interp,
+ int objIndex, Tcl_Obj *fileName,
+ Tcl_Obj **attributePtrPtr));
+static int SetWinFileAttributes _ANSI_ARGS_((Tcl_Interp *interp,
+ int objIndex, Tcl_Obj *fileName,
+ Tcl_Obj *attributePtr));
+static int CannotSetAttribute _ANSI_ARGS_((Tcl_Interp *interp,
+ int objIndex, Tcl_Obj *fileName,
+ Tcl_Obj *attributePtr));
/*
* Constants and variables necessary for file attributes subcommand.
@@ -70,17 +74,18 @@ CONST TclFileAttrProcs tclpFileAttrProcs[] = {
#ifdef HAVE_NO_SEH
/*
- * Unlike Borland and Microsoft, we don't register exception handlers by
- * pushing registration records onto the runtime stack. Instead, we register
- * them by creating an EXCEPTION_REGISTRATION within the activation record.
+ * Unlike Borland and Microsoft, we don't register exception handlers
+ * by pushing registration records onto the runtime stack. Instead, we
+ * register them by creating an EXCEPTION_REGISTRATION within the activation
+ * record.
*/
typedef struct EXCEPTION_REGISTRATION {
- struct EXCEPTION_REGISTRATION *link;
- EXCEPTION_DISPOSITION (*handler)(
- struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
- void *ebp;
- void *esp;
+ struct EXCEPTION_REGISTRATION* link;
+ EXCEPTION_DISPOSITION (*handler)( struct _EXCEPTION_RECORD*, void*,
+ struct _CONTEXT*, void* );
+ void* ebp;
+ void* esp;
int status;
} EXCEPTION_REGISTRATION;
@@ -90,91 +95,91 @@ typedef struct EXCEPTION_REGISTRATION {
* Prototype for the TraverseWinTree callback function.
*/
-typedef int (TraversalProc)(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr,
+typedef int (TraversalProc)(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr,
int type, Tcl_DString *errorPtr);
/*
- * Declarations for local functions defined in this file:
+ * Declarations for local procedures defined in this file:
*/
static void StatError(Tcl_Interp *interp, Tcl_Obj *fileName);
-static int ConvertFileNameFormat(Tcl_Interp *interp,
+static int ConvertFileNameFormat(Tcl_Interp *interp,
int objIndex, Tcl_Obj *fileName, int longShort,
Tcl_Obj **attributePtrPtr);
static int DoCopyFile(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr);
static int DoCreateDirectory(CONST TCHAR *pathPtr);
-static int DoRemoveJustDirectory(CONST TCHAR *nativeSrc,
+static int DoRemoveJustDirectory(CONST TCHAR *nativeSrc,
int ignoreError, Tcl_DString *errorPtr);
-static int DoRemoveDirectory(Tcl_DString *pathPtr, int recursive,
+static int DoRemoveDirectory(Tcl_DString *pathPtr, int recursive,
Tcl_DString *errorPtr);
-static int DoRenameFile(CONST TCHAR *nativeSrc,
- CONST TCHAR *dstPtr);
-static int TraversalCopy(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr,
+static int DoRenameFile(CONST TCHAR *nativeSrc, CONST TCHAR *dstPtr);
+static int TraversalCopy(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr,
+ int type, Tcl_DString *errorPtr);
+static int TraversalDelete(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr,
int type, Tcl_DString *errorPtr);
-static int TraversalDelete(CONST TCHAR *srcPtr,
- CONST TCHAR *dstPtr, int type,
- Tcl_DString *errorPtr);
static int TraverseWinTree(TraversalProc *traverseProc,
- Tcl_DString *sourcePtr, Tcl_DString *dstPtr,
+ Tcl_DString *sourcePtr, Tcl_DString *dstPtr,
Tcl_DString *errorPtr);
+
/*
*---------------------------------------------------------------------------
*
* TclpObjRenameFile, DoRenameFile --
*
- * Changes the name of an existing file or directory, from src to dst.
- * If src and dst refer to the same file or directory, does nothing and
- * returns success. Otherwise if dst already exists, it will be deleted
- * and replaced by src subject to the following conditions:
+ * Changes the name of an existing file or directory, from src to dst.
+ * If src and dst refer to the same file or directory, does nothing
+ * and returns success. Otherwise if dst already exists, it will be
+ * deleted and replaced by src subject to the following conditions:
* If src is a directory, dst may be an empty directory.
* If src is a file, dst may be a file.
- * In any other situation where dst already exists, the rename will fail.
+ * In any other situation where dst already exists, the rename will
+ * fail.
*
* Results:
* If the file or directory was successfully renamed, returns TCL_OK.
- * Otherwise the return value is TCL_ERROR and errno is set to indicate
- * the error. Some possible values for errno are:
+ * Otherwise the return value is TCL_ERROR and errno is set to
+ * indicate the error. Some possible values for errno are:
*
* ENAMETOOLONG: src or dst names are too long.
- * EACCES: src or dst parent directory can't be read and/or written.
+ * EACCES: src or dst parent directory can't be read and/or written.
* EEXIST: dst is a non-empty directory.
* EINVAL: src is a root directory or dst is a subdirectory of src.
* EISDIR: dst is a directory, but src is not.
- * ENOENT: src doesn't exist. src or dst is "".
- * ENOTDIR: src is a directory, but dst is not.
+ * ENOENT: src doesn't exist. src or dst is "".
+ * ENOTDIR: src is a directory, but dst is not.
* EXDEV: src and dst are on different filesystems.
*
- * EACCES: exists an open file already referring to src or dst.
- * EACCES: src or dst specify the current working directory (NT).
- * EACCES: src specifies a char device (nul:, com1:, etc.)
+ * EACCES: exists an open file already referring to src or dst.
+ * EACCES: src or dst specify the current working directory (NT).
+ * EACCES: src specifies a char device (nul:, com1:, etc.)
* EEXIST: dst specifies a char device (nul:, com1:, etc.) (NT)
* EACCES: dst specifies a char device (nul:, com1:, etc.) (95)
- *
+ *
* Side effects:
- * The implementation supports cross-filesystem renames of files, but the
- * caller should be prepared to emulate cross-filesystem renames of
- * directories if errno is EXDEV.
+ * The implementation supports cross-filesystem renames of files,
+ * but the caller should be prepared to emulate cross-filesystem
+ * renames of directories if errno is EXDEV.
*
*---------------------------------------------------------------------------
*/
-int
-TclpObjRenameFile(
- Tcl_Obj *srcPathPtr,
- Tcl_Obj *destPathPtr)
+int
+TclpObjRenameFile(srcPathPtr, destPathPtr)
+ Tcl_Obj *srcPathPtr;
+ Tcl_Obj *destPathPtr;
{
- return DoRenameFile(Tcl_FSGetNativePath(srcPathPtr),
- Tcl_FSGetNativePath(destPathPtr));
+ return DoRenameFile(Tcl_FSGetNativePath(srcPathPtr),
+ Tcl_FSGetNativePath(destPathPtr));
}
static int
DoRenameFile(
CONST TCHAR *nativeSrc, /* Pathname of file or dir to be renamed
- * (native). */
+ * (native). */
CONST TCHAR *nativeDst) /* New pathname for file or directory
* (native). */
-{
+{
#if defined(HAVE_NO_SEH) && !defined(_WIN64)
EXCEPTION_REGISTRATION registration;
#endif
@@ -182,103 +187,99 @@ DoRenameFile(
int retval = -1;
/*
- * The MoveFile API acts differently under Win95/98 and NT WRT NULL and
- * "". Avoid passing these values.
+ * The MoveFile API acts differently under Win95/98 and NT
+ * WRT NULL and "". Avoid passing these values.
*/
if (nativeSrc == NULL || nativeSrc[0] == '\0' ||
- nativeDst == NULL || nativeDst[0] == '\0') {
+ nativeDst == NULL || nativeDst[0] == '\0') {
Tcl_SetErrno(ENOENT);
return TCL_ERROR;
}
/*
- * The MoveFile API would throw an exception under NT if one of the
- * arguments is a char block device.
+ * The MoveFile API would throw an exception under NT
+ * if one of the arguments is a char block device.
*/
#if defined(HAVE_NO_SEH) && !defined(_WIN64)
+
/*
- * Don't have SEH available, do things the hard way. Note that this needs
- * to be one block of asm, to avoid stack imbalance; also, it is illegal
- * for one asm block to contain a jump to another.
+ * Don't have SEH available, do things the hard way.
+ * Note that this needs to be one block of asm, to avoid stack
+ * imbalance; also, it is illegal for one asm block to contain
+ * a jump to another.
*/
__asm__ __volatile__ (
/*
- * Pick up params before messing with the stack.
- */
+ * Pick up params before messing with the stack */
"movl %[nativeDst], %%ebx" "\n\t"
- "movl %[nativeSrc], %%ecx" "\n\t"
+ "movl %[nativeSrc], %%ecx" "\n\t"
/*
- * Construct an EXCEPTION_REGISTRATION to protect the call to
- * MoveFile.
+ * Construct an EXCEPTION_REGISTRATION to protect the
+ * call to MoveFile
*/
-
- "leal %[registration], %%edx" "\n\t"
- "movl %%fs:0, %%eax" "\n\t"
- "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
- "leal 1f, %%eax" "\n\t"
- "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
- "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
- "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
- "movl $0, 0x10(%%edx)" "\n\t" /* status */
-
- /*
- * Link the EXCEPTION_REGISTRATION on the chain.
- */
-
- "movl %%edx, %%fs:0" "\n\t"
-
- /*
- * Call MoveFile(nativeSrc, nativeDst)
- */
-
+ "leal %[registration], %%edx" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
+ "leal 1f, %%eax" "\n\t"
+ "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
+ "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
+ "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
+ "movl $0, 0x10(%%edx)" "\n\t" /* status */
+
+ /* Link the EXCEPTION_REGISTRATION on the chain */
+
+ "movl %%edx, %%fs:0" "\n\t"
+
+ /* Call MoveFile( nativeSrc, nativeDst ) */
+
"pushl %%ebx" "\n\t"
"pushl %%ecx" "\n\t"
"movl %[moveFile], %%eax" "\n\t"
"call *%%eax" "\n\t"
-
- /*
- * Come here on normal exit. Recover the EXCEPTION_REGISTRATION and
- * put the status return from MoveFile into it.
+
+ /*
+ * Come here on normal exit. Recover the EXCEPTION_REGISTRATION
+ * and put the status return from MoveFile into it.
*/
-
+
"movl %%fs:0, %%edx" "\n\t"
"movl %%eax, 0x10(%%edx)" "\n\t"
"jmp 2f" "\n"
-
+
/*
- * Come here on an exception. Recover the EXCEPTION_REGISTRATION
+ * Come here on an exception. Recover the EXCEPTION_REGISTRATION
*/
-
+
"1:" "\t"
- "movl %%fs:0, %%edx" "\n\t"
- "movl 0x8(%%edx), %%edx" "\n\t"
-
- /*
- * Come here however we exited. Restore context from the
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl 0x8(%%edx), %%edx" "\n\t"
+
+ /*
+ * Come here however we exited. Restore context from the
* EXCEPTION_REGISTRATION in case the stack is unbalanced.
*/
-
- "2:" "\t"
- "movl 0xc(%%edx), %%esp" "\n\t"
- "movl 0x8(%%edx), %%ebp" "\n\t"
- "movl 0x0(%%edx), %%eax" "\n\t"
- "movl %%eax, %%fs:0" "\n\t"
-
+
+ "2:" "\t"
+ "movl 0xc(%%edx), %%esp" "\n\t"
+ "movl 0x8(%%edx), %%ebp" "\n\t"
+ "movl 0x0(%%edx), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+
:
/* No outputs */
- :
- [registration] "m" (registration),
- [nativeDst] "m" (nativeDst),
- [nativeSrc] "m" (nativeSrc),
- [moveFile] "r" (tclWinProcs->moveFileProc)
- :
+ :
+ [registration] "m" (registration),
+ [nativeDst] "m" (nativeDst),
+ [nativeSrc] "m" (nativeSrc),
+ [moveFile] "r" (tclWinProcs->moveFileProc)
+ :
"%eax", "%ebx", "%ecx", "%edx", "memory"
- );
+ );
if (registration.status != FALSE) {
retval = TCL_OK;
}
@@ -294,25 +295,22 @@ DoRenameFile(
#endif
#endif
- if (retval != -1) {
- return retval;
- }
+ if (retval != -1)
+ return retval;
TclWinConvertError(GetLastError());
srcAttr = (*tclWinProcs->getFileAttributesProc)(nativeSrc);
dstAttr = (*tclWinProcs->getFileAttributesProc)(nativeDst);
if (srcAttr == 0xffffffff) {
- if ((*tclWinProcs->getFullPathNameProc)(nativeSrc, 0, NULL,
- NULL) >= MAX_PATH) {
+ if ((*tclWinProcs->getFullPathNameProc)(nativeSrc, 0, NULL, NULL) >= MAX_PATH) {
errno = ENAMETOOLONG;
return TCL_ERROR;
}
srcAttr = 0;
}
if (dstAttr == 0xffffffff) {
- if ((*tclWinProcs->getFullPathNameProc)(nativeDst, 0, NULL,
- NULL) >= MAX_PATH) {
+ if ((*tclWinProcs->getFullPathNameProc)(nativeDst, 0, NULL, NULL) >= MAX_PATH) {
errno = ENAMETOOLONG;
return TCL_ERROR;
}
@@ -324,7 +322,7 @@ DoRenameFile(
return TCL_ERROR;
}
if (errno == EACCES) {
- decode:
+ decode:
if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {
TCHAR *nativeSrcRest, *nativeDstRest;
CONST char **srcArgv, **dstArgv;
@@ -334,12 +332,12 @@ DoRenameFile(
Tcl_DString srcString, dstString;
CONST char *src, *dst;
- size = (*tclWinProcs->getFullPathNameProc)(nativeSrc, MAX_PATH,
+ size = (*tclWinProcs->getFullPathNameProc)(nativeSrc, MAX_PATH,
nativeSrcPath, &nativeSrcRest);
if ((size == 0) || (size > MAX_PATH)) {
return TCL_ERROR;
}
- size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH,
+ size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH,
nativeDstPath, &nativeDstRest);
if ((size == 0) || (size > MAX_PATH)) {
return TCL_ERROR;
@@ -349,17 +347,7 @@ DoRenameFile(
src = Tcl_WinTCharToUtf((TCHAR *) nativeSrcPath, -1, &srcString);
dst = Tcl_WinTCharToUtf((TCHAR *) nativeDstPath, -1, &dstString);
-
- /*
- * Check whether the destination path is actually inside the
- * source path. This is true if the prefix matches, and the next
- * character is either end-of-string or a directory separator
- */
-
- if ((strncmp(src, dst, (size_t) Tcl_DStringLength(&srcString))==0)
- && (dst[Tcl_DStringLength(&srcString)] == '\\'
- || dst[Tcl_DStringLength(&srcString)] == '/'
- || dst[Tcl_DStringLength(&srcString)] == '\0')) {
+ if (strncmp(src, dst, (size_t) Tcl_DStringLength(&srcString)) == 0) {
/*
* Trying to move a directory into itself.
*/
@@ -376,20 +364,22 @@ DoRenameFile(
if (srcArgc == 1) {
/*
- * They are trying to move a root directory. Whether or not it
- * is across filesystems, this cannot be done.
+ * They are trying to move a root directory. Whether
+ * or not it is across filesystems, this cannot be
+ * done.
*/
Tcl_SetErrno(EINVAL);
} else if ((srcArgc > 0) && (dstArgc > 0) &&
(strcmp(srcArgv[0], dstArgv[0]) != 0)) {
/*
- * If src is a directory and dst filesystem != src filesystem,
- * errno should be EXDEV. It is very important to get this
- * behavior, so that the caller can respond to a cross
- * filesystem rename by simulating it with copy and delete.
- * The MoveFile system call already handles the case of moving
- * a file between filesystems.
+ * If src is a directory and dst filesystem != src
+ * filesystem, errno should be EXDEV. It is very
+ * important to get this behavior, so that the caller
+ * can respond to a cross filesystem rename by
+ * simulating it with copy and delete. The MoveFile
+ * system call already handles the case of moving a
+ * file between filesystems.
*/
Tcl_SetErrno(EXDEV);
@@ -401,40 +391,39 @@ DoRenameFile(
/*
* Other types of access failure is that dst is a read-only
- * filesystem, that an open file referred to src or dest, or that src
- * or dest specified the current working directory on the current
- * filesystem. EACCES is returned for those cases.
+ * filesystem, that an open file referred to src or dest, or that
+ * src or dest specified the current working directory on the
+ * current filesystem. EACCES is returned for those cases.
*/
} else if (Tcl_GetErrno() == EEXIST) {
/*
- * Reports EEXIST any time the target already exists. If it makes
+ * Reports EEXIST any time the target already exists. If it makes
* sense, remove the old file and try renaming again.
*/
if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {
if (dstAttr & FILE_ATTRIBUTE_DIRECTORY) {
/*
- * Overwrite empty dst directory with src directory. The
- * following call will remove an empty directory. If it fails,
- * it's because it wasn't empty.
+ * Overwrite empty dst directory with src directory. The
+ * following call will remove an empty directory. If it
+ * fails, it's because it wasn't empty.
*/
if (DoRemoveJustDirectory(nativeDst, 0, NULL) == TCL_OK) {
/*
* Now that that empty directory is gone, we can try
- * renaming again. If that fails, we'll put this empty
+ * renaming again. If that fails, we'll put this empty
* directory back, for completeness.
*/
- if ((*tclWinProcs->moveFileProc)(nativeSrc,
- nativeDst) != FALSE) {
+ if ((*tclWinProcs->moveFileProc)(nativeSrc, nativeDst) != FALSE) {
return TCL_OK;
}
/*
- * Some new error has occurred. Don't know what it could
- * be, but report this one.
+ * Some new error has occurred. Don't know what it
+ * could be, but report this one.
*/
TclWinConvertError(GetLastError());
@@ -457,18 +446,18 @@ DoRenameFile(
} else {
/*
* Overwrite existing file by:
- *
+ *
* 1. Rename existing file to temp name.
* 2. Rename old file to new name.
- * 3. If success, delete temp file. If failure, put temp file
- * back to old name.
+ * 3. If success, delete temp file. If failure,
+ * put temp file back to old name.
*/
TCHAR *nativeRest, *nativeTmp, *nativePrefix;
int result, size;
WCHAR tempBuf[MAX_PATH];
-
- size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH,
+
+ size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH,
tempBuf, &nativeRest);
if ((size == 0) || (size > MAX_PATH) || (nativeRest == NULL)) {
return TCL_ERROR;
@@ -478,9 +467,9 @@ DoRenameFile(
((char *) nativeRest)[1] = '\0'; /* In case it's Unicode. */
result = TCL_ERROR;
- nativePrefix = (tclWinProcs->useWide)
+ nativePrefix = (tclWinProcs->useWide)
? (TCHAR *) L"tclr" : (TCHAR *) "tclr";
- if ((*tclWinProcs->getTempFileNameProc)(nativeTmp,
+ if ((*tclWinProcs->getTempFileNameProc)(nativeTmp,
nativePrefix, 0, tempBuf) != 0) {
/*
* Strictly speaking, need the following DeleteFile and
@@ -488,14 +477,12 @@ DoRenameFile(
* other app comes along in the meantime and creates the
* same temp file.
*/
-
+
nativeTmp = (TCHAR *) tempBuf;
(*tclWinProcs->deleteFileProc)(nativeTmp);
- if ((*tclWinProcs->moveFileProc)(nativeDst,
- nativeTmp) != FALSE) {
- if ((*tclWinProcs->moveFileProc)(nativeSrc,
- nativeDst) != FALSE) {
- (*tclWinProcs->setFileAttributesProc)(nativeTmp,
+ if ((*tclWinProcs->moveFileProc)(nativeDst, nativeTmp) != FALSE) {
+ if ((*tclWinProcs->moveFileProc)(nativeSrc, nativeDst) != FALSE) {
+ (*tclWinProcs->setFileAttributesProc)(nativeTmp,
FILE_ATTRIBUTE_NORMAL);
(*tclWinProcs->deleteFileProc)(nativeTmp);
return TCL_OK;
@@ -503,11 +490,11 @@ DoRenameFile(
(*tclWinProcs->deleteFileProc)(nativeDst);
(*tclWinProcs->moveFileProc)(nativeTmp, nativeDst);
}
- }
+ }
/*
- * Can't backup dst file or move src file. Return that
- * error. Could happen if an open file refers to dst.
+ * Can't backup dst file or move src file. Return that
+ * error. Could happen if an open file refers to dst.
*/
TclWinConvertError(GetLastError());
@@ -531,19 +518,19 @@ DoRenameFile(
*
* TclpObjCopyFile, DoCopyFile --
*
- * Copy a single file (not a directory). If dst already exists and is not
- * a directory, it is removed.
+ * Copy a single file (not a directory). If dst already exists and
+ * is not a directory, it is removed.
*
* Results:
- * If the file was successfully copied, returns TCL_OK. Otherwise the
- * return value is TCL_ERROR and errno is set to indicate the error.
- * Some possible values for errno are:
+ * If the file was successfully copied, returns TCL_OK. Otherwise
+ * the return value is TCL_ERROR and errno is set to indicate the
+ * error. Some possible values for errno are:
*
- * EACCES: src or dst parent directory can't be read and/or written.
+ * EACCES: src or dst parent directory can't be read and/or written.
* EISDIR: src or dst is a directory.
- * ENOENT: src doesn't exist. src or dst is "".
+ * ENOENT: src doesn't exist. src or dst is "".
*
- * EACCES: exists an open file already referring to dst (95).
+ * EACCES: exists an open file already referring to dst (95).
* EACCES: src specifies a char device (nul:, com1:, etc.) (NT)
* ENOENT: src specifies a char device (nul:, com1:, etc.) (95)
*
@@ -553,19 +540,19 @@ DoRenameFile(
*---------------------------------------------------------------------------
*/
-int
-TclpObjCopyFile(
- Tcl_Obj *srcPathPtr,
- Tcl_Obj *destPathPtr)
+int
+TclpObjCopyFile(srcPathPtr, destPathPtr)
+ Tcl_Obj *srcPathPtr;
+ Tcl_Obj *destPathPtr;
{
return DoCopyFile(Tcl_FSGetNativePath(srcPathPtr),
- Tcl_FSGetNativePath(destPathPtr));
+ Tcl_FSGetNativePath(destPathPtr));
}
static int
DoCopyFile(
- CONST TCHAR *nativeSrc, /* Pathname of file to be copied (native). */
- CONST TCHAR *nativeDst) /* Pathname of file to copy to (native). */
+ CONST TCHAR *nativeSrc, /* Pathname of file to be copied (native). */
+ CONST TCHAR *nativeDst) /* Pathname of file to copy to (native). */
{
#if defined(HAVE_NO_SEH) && !defined(_WIN64)
EXCEPTION_REGISTRATION registration;
@@ -573,26 +560,28 @@ DoCopyFile(
int retval = -1;
/*
- * The CopyFile API acts differently under Win95/98 and NT WRT NULL and
- * "". Avoid passing these values.
+ * The CopyFile API acts differently under Win95/98 and NT
+ * WRT NULL and "". Avoid passing these values.
*/
if (nativeSrc == NULL || nativeSrc[0] == '\0' ||
- nativeDst == NULL || nativeDst[0] == '\0') {
+ nativeDst == NULL || nativeDst[0] == '\0') {
Tcl_SetErrno(ENOENT);
return TCL_ERROR;
}
-
+
/*
- * The CopyFile API would throw an exception under NT if one of the
- * arguments is a char block device.
+ * The CopyFile API would throw an exception under NT if one
+ * of the arguments is a char block device.
*/
#if defined(HAVE_NO_SEH) && !defined(_WIN64)
+
/*
- * Don't have SEH available, do things the hard way. Note that this needs
- * to be one block of asm, to avoid stack imbalance; also, it is illegal
- * for one asm block to contain a jump to another.
+ * Don't have SEH available, do things the hard way.
+ * Note that this needs to be one block of asm, to avoid stack
+ * imbalance; also, it is illegal for one asm block to contain
+ * a jump to another.
*/
__asm__ __volatile__ (
@@ -601,77 +590,71 @@ DoCopyFile(
* Pick up parameters before messing with the stack
*/
- "movl %[nativeDst], %%ebx" "\n\t"
- "movl %[nativeSrc], %%ecx" "\n\t"
-
- /*
- * Construct an EXCEPTION_REGISTRATION to protect the call to
- * CopyFile.
- */
-
- "leal %[registration], %%edx" "\n\t"
- "movl %%fs:0, %%eax" "\n\t"
- "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
- "leal 1f, %%eax" "\n\t"
- "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
- "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
- "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
- "movl $0, 0x10(%%edx)" "\n\t" /* status */
-
+ "movl %[nativeDst], %%ebx" "\n\t"
+ "movl %[nativeSrc], %%ecx" "\n\t"
/*
- * Link the EXCEPTION_REGISTRATION on the chain.
+ * Construct an EXCEPTION_REGISTRATION to protect the
+ * call to CopyFile
*/
-
- "movl %%edx, %%fs:0" "\n\t"
-
- /*
- * Call CopyFile(nativeSrc, nativeDst, 0)
- */
-
+ "leal %[registration], %%edx" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
+ "leal 1f, %%eax" "\n\t"
+ "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
+ "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
+ "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
+ "movl $0, 0x10(%%edx)" "\n\t" /* status */
+
+ /* Link the EXCEPTION_REGISTRATION on the chain */
+
+ "movl %%edx, %%fs:0" "\n\t"
+
+ /* Call CopyFile( nativeSrc, nativeDst, 0 ) */
+
"movl %[copyFile], %%eax" "\n\t"
- "pushl $0" "\n\t"
+ "pushl $0" "\n\t"
"pushl %%ebx" "\n\t"
"pushl %%ecx" "\n\t"
"call *%%eax" "\n\t"
-
- /*
- * Come here on normal exit. Recover the EXCEPTION_REGISTRATION and
- * put the status return from CopyFile into it.
+
+ /*
+ * Come here on normal exit. Recover the EXCEPTION_REGISTRATION
+ * and put the status return from CopyFile into it.
*/
-
+
"movl %%fs:0, %%edx" "\n\t"
"movl %%eax, 0x10(%%edx)" "\n\t"
"jmp 2f" "\n"
-
+
/*
- * Come here on an exception. Recover the EXCEPTION_REGISTRATION
+ * Come here on an exception. Recover the EXCEPTION_REGISTRATION
*/
-
+
"1:" "\t"
- "movl %%fs:0, %%edx" "\n\t"
- "movl 0x8(%%edx), %%edx" "\n\t"
-
- /*
- * Come here however we exited. Restore context from the
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl 0x8(%%edx), %%edx" "\n\t"
+
+ /*
+ * Come here however we exited. Restore context from the
* EXCEPTION_REGISTRATION in case the stack is unbalanced.
*/
-
- "2:" "\t"
- "movl 0xc(%%edx), %%esp" "\n\t"
- "movl 0x8(%%edx), %%ebp" "\n\t"
- "movl 0x0(%%edx), %%eax" "\n\t"
- "movl %%eax, %%fs:0" "\n\t"
-
+
+ "2:" "\t"
+ "movl 0xc(%%edx), %%esp" "\n\t"
+ "movl 0x8(%%edx), %%ebp" "\n\t"
+ "movl 0x0(%%edx), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+
:
/* No outputs */
- :
- [registration] "m" (registration),
- [nativeDst] "m" (nativeDst),
- [nativeSrc] "m" (nativeSrc),
- [copyFile] "r" (tclWinProcs->copyFileProc)
- :
+ :
+ [registration] "m" (registration),
+ [nativeDst] "m" (nativeDst),
+ [nativeSrc] "m" (nativeSrc),
+ [copyFile] "r" (tclWinProcs->copyFileProc)
+ :
"%eax", "%ebx", "%ecx", "%edx", "memory"
- );
+ );
if (registration.status != FALSE) {
retval = TCL_OK;
}
@@ -687,9 +670,8 @@ DoCopyFile(
#endif
#endif
- if (retval != -1) {
- return retval;
- }
+ if (retval != -1)
+ return retval;
TclWinConvertError(GetLastError());
if (Tcl_GetErrno() == EBADF) {
@@ -709,23 +691,21 @@ DoCopyFile(
(dstAttr & FILE_ATTRIBUTE_DIRECTORY)) {
if (srcAttr & FILE_ATTRIBUTE_REPARSE_POINT) {
/* Source is a symbolic link -- copy it */
- if (TclWinSymLinkCopyDirectory(nativeSrc, nativeDst)==0) {
- return TCL_OK;
+ if (TclWinSymLinkCopyDirectory(nativeSrc, nativeDst) == 0) {
+ return TCL_OK;
}
}
Tcl_SetErrno(EISDIR);
}
if (dstAttr & FILE_ATTRIBUTE_READONLY) {
- (*tclWinProcs->setFileAttributesProc)(nativeDst,
+ (*tclWinProcs->setFileAttributesProc)(nativeDst,
dstAttr & ~((DWORD)FILE_ATTRIBUTE_READONLY));
- if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst,
- 0) != FALSE) {
+ if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst, 0) != FALSE) {
return TCL_OK;
}
-
/*
- * Still can't copy onto dst. Return that error, and restore
- * attributes of dst.
+ * Still can't copy onto dst. Return that error, and
+ * restore attributes of dst.
*/
TclWinConvertError(GetLastError());
@@ -741,29 +721,29 @@ DoCopyFile(
*
* TclpObjDeleteFile, TclpDeleteFile --
*
- * Removes a single file (not a directory).
+ * Removes a single file (not a directory).
*
* Results:
- * If the file was successfully deleted, returns TCL_OK. Otherwise the
- * return value is TCL_ERROR and errno is set to indicate the error.
- * Some possible values for errno are:
+ * If the file was successfully deleted, returns TCL_OK. Otherwise
+ * the return value is TCL_ERROR and errno is set to indicate the
+ * error. Some possible values for errno are:
*
- * EACCES: a parent directory can't be read and/or written.
+ * EACCES: a parent directory can't be read and/or written.
* EISDIR: path is a directory.
* ENOENT: path doesn't exist or is "".
*
- * EACCES: exists an open file already referring to path.
+ * EACCES: exists an open file already referring to path.
* EACCES: path is a char device (nul:, com1:, etc.)
*
* Side effects:
- * The file is deleted, even if it is read-only.
+ * The file is deleted, even if it is read-only.
*
*---------------------------------------------------------------------------
*/
-int
-TclpObjDeleteFile(
- Tcl_Obj *pathPtr)
+int
+TclpObjDeleteFile(pathPtr)
+ Tcl_Obj *pathPtr;
{
return TclpDeleteFile(Tcl_FSGetNativePath(pathPtr));
}
@@ -775,8 +755,8 @@ TclpDeleteFile(
DWORD attr;
/*
- * The DeleteFile API acts differently under Win95/98 and NT WRT NULL and
- * "". Avoid passing these values.
+ * The DeleteFile API acts differently under Win95/98 and NT
+ * WRT NULL and "". Avoid passing these values.
*/
if (nativePath == NULL || nativePath[0] == '\0') {
@@ -790,30 +770,27 @@ TclpDeleteFile(
TclWinConvertError(GetLastError());
if (Tcl_GetErrno() == EACCES) {
- attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
+ attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr != 0xffffffff) {
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
- /*
- * It is a symbolic link - remove it.
- */
+ /* It is a symbolic link -- remove it */
if (TclWinSymLinkDelete(nativePath, 0) == 0) {
- return TCL_OK;
+ return TCL_OK;
}
}
-
- /*
+
+ /*
* If we fall through here, it is a directory.
- *
+ *
* Windows NT reports removing a directory as EACCES instead
* of EISDIR.
*/
Tcl_SetErrno(EISDIR);
} else if (attr & FILE_ATTRIBUTE_READONLY) {
- int res = (*tclWinProcs->setFileAttributesProc)(nativePath,
+ int res = (*tclWinProcs->setFileAttributesProc)(nativePath,
attr & ~((DWORD)FILE_ATTRIBUTE_READONLY));
-
if ((res != 0) && ((*tclWinProcs->deleteFileProc)(nativePath)
!= FALSE)) {
return TCL_OK;
@@ -825,12 +802,12 @@ TclpDeleteFile(
}
}
} else if (Tcl_GetErrno() == ENOENT) {
- attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
+ attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr != 0xffffffff) {
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
- /*
- * Windows 95 reports removing a directory as ENOENT instead
- * of EISDIR.
+ /*
+ * Windows 95 reports removing a directory as ENOENT instead
+ * of EISDIR.
*/
Tcl_SetErrno(EISDIR);
@@ -853,29 +830,29 @@ TclpDeleteFile(
*
* TclpObjCreateDirectory --
*
- * Creates the specified directory. All parent directories of the
- * specified directory must already exist. The directory is automatically
- * created with permissions so that user can access the new directory and
- * create new files or subdirectories in it.
+ * Creates the specified directory. All parent directories of the
+ * specified directory must already exist. The directory is
+ * automatically created with permissions so that user can access
+ * the new directory and create new files or subdirectories in it.
*
* Results:
- * If the directory was successfully created, returns TCL_OK. Otherwise
- * the return value is TCL_ERROR and errno is set to indicate the error.
- * Some possible values for errno are:
+ * If the directory was successfully created, returns TCL_OK.
+ * Otherwise the return value is TCL_ERROR and errno is set to
+ * indicate the error. Some possible values for errno are:
*
- * EACCES: a parent directory can't be read and/or written.
+ * EACCES: a parent directory can't be read and/or written.
* EEXIST: path already exists.
* ENOENT: a parent directory doesn't exist.
*
* Side effects:
- * A directory is created.
+ * A directory is created.
*
*---------------------------------------------------------------------------
*/
-int
-TclpObjCreateDirectory(
- Tcl_Obj *pathPtr)
+int
+TclpObjCreateDirectory(pathPtr)
+ Tcl_Obj *pathPtr;
{
return DoCreateDirectory(Tcl_FSGetNativePath(pathPtr));
}
@@ -889,7 +866,7 @@ DoCreateDirectory(
error = GetLastError();
TclWinConvertError(error);
return TCL_ERROR;
- }
+ }
return TCL_OK;
}
@@ -898,30 +875,32 @@ DoCreateDirectory(
*
* TclpObjCopyDirectory --
*
- * Recursively copies a directory. The target directory dst must not
- * already exist. Note that this function does not merge two directory
- * hierarchies, even if the target directory is an an empty directory.
+ * Recursively copies a directory. The target directory dst must
+ * not already exist. Note that this function does not merge two
+ * directory hierarchies, even if the target directory is an an
+ * empty directory.
*
* Results:
- * If the directory was successfully copied, returns TCL_OK. Otherwise
- * the return value is TCL_ERROR, errno is set to indicate the error, and
- * the pathname of the file that caused the error is stored in errorPtr.
- * See TclpCreateDirectory and TclpCopyFile for a description of possible
- * values for errno.
+ * If the directory was successfully copied, returns TCL_OK.
+ * Otherwise the return value is TCL_ERROR, errno is set to indicate
+ * the error, and the pathname of the file that caused the error
+ * is stored in errorPtr. See TclpCreateDirectory and TclpCopyFile
+ * for a description of possible values for errno.
*
* Side effects:
- * An exact copy of the directory hierarchy src will be created with the
- * name dst. If an error occurs, the error will be returned immediately,
- * and remaining files will not be processed.
+ * An exact copy of the directory hierarchy src will be created
+ * with the name dst. If an error occurs, the error will
+ * be returned immediately, and remaining files will not be
+ * processed.
*
*---------------------------------------------------------------------------
*/
-int
-TclpObjCopyDirectory(
- Tcl_Obj *srcPathPtr,
- Tcl_Obj *destPathPtr,
- Tcl_Obj **errorPtr)
+int
+TclpObjCopyDirectory(srcPathPtr, destPathPtr, errorPtr)
+ Tcl_Obj *srcPathPtr;
+ Tcl_Obj *destPathPtr;
+ Tcl_Obj **errorPtr;
{
Tcl_DString ds;
Tcl_DString srcString, dstString;
@@ -929,12 +908,14 @@ TclpObjCopyDirectory(
int ret;
normSrcPtr = Tcl_FSGetNormalizedPath(NULL,srcPathPtr);
- normDestPtr = Tcl_FSGetNormalizedPath(NULL,destPathPtr);
- if ((normSrcPtr == NULL) || (normDestPtr == NULL)) {
+ if (normSrcPtr == NULL) {
return TCL_ERROR;
}
-
Tcl_WinUtfToTChar(Tcl_GetString(normSrcPtr), -1, &srcString);
+ normDestPtr = Tcl_FSGetNormalizedPath(NULL,destPathPtr);
+ if (normDestPtr == NULL) {
+ return TCL_ERROR;
+ }
Tcl_WinUtfToTChar(Tcl_GetString(normDestPtr), -1, &dstString);
ret = TraverseWinTree(TraversalCopy, &srcString, &dstString, &ds);
@@ -943,9 +924,9 @@ TclpObjCopyDirectory(
Tcl_DStringFree(&dstString);
if (ret != TCL_OK) {
- if (!strcmp(Tcl_DStringValue(&ds), TclGetString(normSrcPtr))) {
+ if (!strcmp(Tcl_DStringValue(&ds), Tcl_GetString(normSrcPtr))) {
*errorPtr = srcPathPtr;
- } else if (!strcmp(Tcl_DStringValue(&ds), TclGetString(normDestPtr))) {
+ } else if (!strcmp(Tcl_DStringValue(&ds), Tcl_GetString(normDestPtr))) {
*errorPtr = destPathPtr;
} else {
*errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
@@ -959,49 +940,47 @@ TclpObjCopyDirectory(
/*
*----------------------------------------------------------------------
*
- * TclpObjRemoveDirectory, DoRemoveDirectory --
+ * TclpObjRemoveDirectory, DoRemoveDirectory --
*
* Removes directory (and its contents, if the recursive flag is set).
*
* Results:
- * If the directory was successfully removed, returns TCL_OK. Otherwise
- * the return value is TCL_ERROR, errno is set to indicate the error, and
- * the pathname of the file that caused the error is stored in errorPtr.
- * Some possible values for errno are:
+ * If the directory was successfully removed, returns TCL_OK.
+ * Otherwise the return value is TCL_ERROR, errno is set to indicate
+ * the error, and the pathname of the file that caused the error
+ * is stored in errorPtr. Some possible values for errno are:
*
- * EACCES: path directory can't be read and/or written.
+ * EACCES: path directory can't be read and/or written.
* EEXIST: path is a non-empty directory.
* EINVAL: path is root directory or current directory.
* ENOENT: path doesn't exist or is "".
- * ENOTDIR: path is not a directory.
+ * ENOTDIR: path is not a directory.
*
* EACCES: path is a char device (nul:, com1:, etc.) (95)
* EINVAL: path is a char device (nul:, com1:, etc.) (NT)
*
* Side effects:
- * Directory removed. If an error occurs, the error will be returned
+ * Directory removed. If an error occurs, the error will be returned
* immediately, and remaining files will not be deleted.
*
*----------------------------------------------------------------------
*/
-int
-TclpObjRemoveDirectory(
- Tcl_Obj *pathPtr,
- int recursive,
- Tcl_Obj **errorPtr)
+int
+TclpObjRemoveDirectory(pathPtr, recursive, errorPtr)
+ Tcl_Obj *pathPtr;
+ int recursive;
+ Tcl_Obj **errorPtr;
{
Tcl_DString ds;
Tcl_Obj *normPtr = NULL;
int ret;
-
if (recursive) {
- /*
+ /*
* In the recursive case, the string rep is used to construct a
- * Tcl_DString which may be used extensively, so we can't optimize
- * this case easily.
+ * Tcl_DString which may be used extensively, so we can't
+ * optimize this case easily.
*/
-
Tcl_DString native;
normPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr);
if (normPtr == NULL) {
@@ -1011,14 +990,14 @@ TclpObjRemoveDirectory(
ret = DoRemoveDirectory(&native, recursive, &ds);
Tcl_DStringFree(&native);
} else {
- ret = DoRemoveJustDirectory(Tcl_FSGetNativePath(pathPtr), 0, &ds);
+ ret = DoRemoveJustDirectory(Tcl_FSGetNativePath(pathPtr),
+ 0, &ds);
}
-
if (ret != TCL_OK) {
int len = Tcl_DStringLength(&ds);
if (len > 0) {
- if (normPtr != NULL &&
- !strcmp(Tcl_DStringValue(&ds), TclGetString(normPtr))) {
+ if (normPtr != NULL
+ && !strcmp(Tcl_DStringValue(&ds), Tcl_GetString(normPtr))) {
*errorPtr = pathPtr;
} else {
*errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
@@ -1027,7 +1006,6 @@ TclpObjRemoveDirectory(
}
Tcl_DStringFree(&ds);
}
-
return ret;
}
@@ -1035,17 +1013,16 @@ static int
DoRemoveJustDirectory(
CONST TCHAR *nativePath, /* Pathname of directory to be removed
* (native). */
- int ignoreError, /* If non-zero, don't initialize the errorPtr
- * under some circumstances on return. */
- Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free DString
- * filled with UTF-8 name of file causing
- * error. */
+ int ignoreError, /* If non-zero, don't initialize the
+ * errorPtr under some circumstances
+ * on return. */
+ Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free
+ * DString filled with UTF-8 name of file
+ * causing error. */
{
- DWORD attr;
-
/*
- * The RemoveDirectory API acts differently under Win95/98 and NT WRT NULL
- * and "". Avoid passing these values.
+ * The RemoveDirectory API acts differently under Win95/98 and NT
+ * WRT NULL and "". Avoid passing these values.
*/
if (nativePath == NULL || nativePath[0] == '\0') {
@@ -1053,68 +1030,48 @@ DoRemoveJustDirectory(
goto end;
}
- attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
-
- if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
- /*
- * It is a symbolic link - remove it.
- */
- if (TclWinSymLinkDelete(nativePath, 0) == 0) {
- return TCL_OK;
- }
- } else {
- /*
- * Ordinary directory.
- */
-
- if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) {
- return TCL_OK;
- }
+ if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) {
+ return TCL_OK;
}
-
TclWinConvertError(GetLastError());
if (Tcl_GetErrno() == EACCES) {
- attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
+ DWORD attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr != 0xffffffff) {
if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
- /*
- * Windows 95 reports calling RemoveDirectory on a file as an
+ /*
+ * Windows 95 reports calling RemoveDirectory on a file as an
* EACCES, not an ENOTDIR.
*/
-
+
Tcl_SetErrno(ENOTDIR);
goto end;
}
if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
- /*
- * It is a symbolic link - remove it.
- */
-
+ /* It is a symbolic link -- remove it */
if (TclWinSymLinkDelete(nativePath, 1) != 0) {
goto end;
}
}
-
+
if (attr & FILE_ATTRIBUTE_READONLY) {
attr &= ~FILE_ATTRIBUTE_READONLY;
- if ((*tclWinProcs->setFileAttributesProc)(nativePath,
- attr) == FALSE) {
+ if ((*tclWinProcs->setFileAttributesProc)(nativePath, attr) == FALSE) {
goto end;
}
if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) {
return TCL_OK;
}
TclWinConvertError(GetLastError());
- (*tclWinProcs->setFileAttributesProc)(nativePath,
+ (*tclWinProcs->setFileAttributesProc)(nativePath,
attr | FILE_ATTRIBUTE_READONLY);
}
- /*
- * Windows 95 and Win32s report removing a non-empty directory as
- * EACCES, not EEXIST. If the directory is not empty, change errno
- * so caller knows what's going on.
+ /*
+ * Windows 95 and Win32s report removing a non-empty directory
+ * as EACCES, not EEXIST. If the directory is not empty,
+ * change errno so caller knows what's going on.
*/
if (TclWinGetPlatformId() != VER_PLATFORM_WIN32_NT) {
@@ -1155,25 +1112,24 @@ DoRemoveJustDirectory(
}
}
}
-
if (Tcl_GetErrno() == ENOTEMPTY) {
- /*
- * The caller depends on EEXIST to signify that the directory is not
- * empty, not ENOTEMPTY.
+ /*
+ * The caller depends on EEXIST to signify that the directory is
+ * not empty, not ENOTEMPTY.
*/
Tcl_SetErrno(EEXIST);
}
-
if ((ignoreError != 0) && (Tcl_GetErrno() == EEXIST)) {
- /*
- * If we're being recursive, this error may actually be ok, so we
- * don't want to initialise the errorPtr yet.
+ /*
+ * If we're being recursive, this error may actually
+ * be ok, so we don't want to initialise the errorPtr
+ * yet.
*/
return TCL_ERROR;
}
- end:
+ end:
if (errorPtr != NULL) {
Tcl_WinTCharToUtf(nativePath, -1, errorPtr);
}
@@ -1185,22 +1141,21 @@ static int
DoRemoveDirectory(
Tcl_DString *pathPtr, /* Pathname of directory to be removed
* (native). */
- int recursive, /* If non-zero, removes directories that are
- * nonempty. Otherwise, will only remove empty
- * directories. */
- Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free DString
- * filled with UTF-8 name of file causing
- * error. */
+ int recursive, /* If non-zero, removes directories that
+ * are nonempty. Otherwise, will only remove
+ * empty directories. */
+ Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free
+ * DString filled with UTF-8 name of file
+ * causing error. */
{
- int res = DoRemoveJustDirectory(Tcl_DStringValue(pathPtr), recursive,
- errorPtr);
-
+ int res = DoRemoveJustDirectory(Tcl_DStringValue(pathPtr), recursive,
+ errorPtr);
+
if ((res == TCL_ERROR) && (recursive != 0) && (Tcl_GetErrno() == EEXIST)) {
/*
* The directory is nonempty, but the recursive flag has been
* specified, so we recursively remove all the files in the directory.
*/
-
return TraverseWinTree(TraversalDelete, pathPtr, NULL, errorPtr);
} else {
return res;
@@ -1212,24 +1167,24 @@ DoRemoveDirectory(
*
* TraverseWinTree --
*
- * Traverse directory tree specified by sourcePtr, calling the function
- * traverseProc for each file and directory encountered. If destPtr is
- * non-null, each of name in the sourcePtr directory is appended to the
- * directory specified by destPtr and passed as the second argument to
- * traverseProc().
+ * Traverse directory tree specified by sourcePtr, calling the function
+ * traverseProc for each file and directory encountered. If destPtr
+ * is non-null, each of name in the sourcePtr directory is appended to
+ * the directory specified by destPtr and passed as the second argument
+ * to traverseProc() .
*
* Results:
- * Standard Tcl result.
+ * Standard Tcl result.
*
* Side effects:
- * None caused by TraverseWinTree, however the user specified
- * traverseProc() may change state. If an error occurs, the error will be
- * returned immediately, and remaining files will not be processed.
+ * None caused by TraverseWinTree, however the user specified
+ * traverseProc() may change state. If an error occurs, the error will
+ * be returned immediately, and remaining files will not be processed.
*
*---------------------------------------------------------------------------
*/
-static int
+static int
TraverseWinTree(
TraversalProc *traverseProc,/* Function to call for every file and
* directory in source hierarchy. */
@@ -1238,9 +1193,9 @@ TraverseWinTree(
Tcl_DString *targetPtr, /* Pathname of directory to traverse in
* parallel with source directory (native),
* may be NULL. */
- Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free DString
- * filled with UTF-8 name of file causing
- * error. */
+ Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free
+ * DString filled with UTF-8 name of file
+ * causing error. */
{
DWORD sourceAttr;
TCHAR *nativeSource, *nativeTarget, *nativeErrfile;
@@ -1253,25 +1208,15 @@ TraverseWinTree(
oldTargetLen = 0; /* lint. */
nativeSource = (TCHAR *) Tcl_DStringValue(sourcePtr);
- nativeTarget = (TCHAR *)
- (targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr));
-
+ nativeTarget = (TCHAR *) (targetPtr == NULL
+ ? NULL : Tcl_DStringValue(targetPtr));
+
oldSourceLen = Tcl_DStringLength(sourcePtr);
sourceAttr = (*tclWinProcs->getFileAttributesProc)(nativeSource);
if (sourceAttr == 0xffffffff) {
nativeErrfile = nativeSource;
goto end;
}
-
- if (sourceAttr & FILE_ATTRIBUTE_REPARSE_POINT) {
- /*
- * Process the symbolic link
- */
-
- return (*traverseProc)(nativeSource, nativeTarget, DOTREE_LINK,
- errorPtr);
- }
-
if ((sourceAttr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
/*
* Process the regular file
@@ -1286,12 +1231,11 @@ TraverseWinTree(
} else {
Tcl_DStringAppend(sourcePtr, "\\*.*", 4);
}
-
nativeSource = (TCHAR *) Tcl_DStringValue(sourcePtr);
handle = (*tclWinProcs->findFirstFileProc)(nativeSource, &data);
- if (handle == INVALID_HANDLE_VALUE) {
- /*
- * Can't read directory.
+ if (handle == INVALID_HANDLE_VALUE) {
+ /*
+ * Can't read directory
*/
TclWinConvertError(GetLastError());
@@ -1301,8 +1245,7 @@ TraverseWinTree(
nativeSource[oldSourceLen + 1] = '\0';
Tcl_DStringSetLength(sourcePtr, oldSourceLen);
- result = (*traverseProc)(nativeSource, nativeTarget, DOTREE_PRED,
- errorPtr);
+ result = (*traverseProc)(nativeSource, nativeTarget, DOTREE_PRED, errorPtr);
if (result != TCL_OK) {
FindClose(handle);
return result;
@@ -1333,7 +1276,7 @@ TraverseWinTree(
}
found = 1;
- for (; found; found = (*tclWinProcs->findNextFileProc)(handle, &data)) {
+ for ( ; found; found = (*tclWinProcs->findNextFileProc)(handle, &data)) {
TCHAR *nativeName;
int len;
@@ -1353,7 +1296,7 @@ TraverseWinTree(
nativeName = (TCHAR *) data.w.cFileName;
len = wcslen(data.w.cFileName) * sizeof(WCHAR);
} else {
- if ((strcmp(data.a.cFileName, ".") == 0)
+ if ((strcmp(data.a.cFileName, ".") == 0)
|| (strcmp(data.a.cFileName, "..") == 0)) {
continue;
}
@@ -1361,8 +1304,8 @@ TraverseWinTree(
len = strlen(data.a.cFileName);
}
- /*
- * Append name after slash, and recurse on the file.
+ /*
+ * Append name after slash, and recurse on the file.
*/
Tcl_DStringAppend(sourcePtr, (char *) nativeName, len + 1);
@@ -1371,7 +1314,7 @@ TraverseWinTree(
Tcl_DStringAppend(targetPtr, (char *) nativeName, len + 1);
Tcl_DStringSetLength(targetPtr, Tcl_DStringLength(targetPtr) - 1);
}
- result = TraverseWinTree(traverseProc, sourcePtr, targetPtr,
+ result = TraverseWinTree(traverseProc, sourcePtr, targetPtr,
errorPtr);
if (result != TCL_OK) {
break;
@@ -1389,7 +1332,7 @@ TraverseWinTree(
FindClose(handle);
/*
- * Strip off the trailing slash we added.
+ * Strip off the trailing slash we added
*/
Tcl_DStringSetLength(sourcePtr, oldSourceLen + 1);
@@ -1404,12 +1347,11 @@ TraverseWinTree(
* files in that directory.
*/
- result = (*traverseProc)(Tcl_DStringValue(sourcePtr),
- (targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr)),
- DOTREE_POSTD, errorPtr);
+ result = (*traverseProc)(Tcl_DStringValue(sourcePtr),
+ (targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr)),
+ DOTREE_POSTD, errorPtr);
}
-
- end:
+ end:
if (nativeErrfile != NULL) {
TclWinConvertError(GetLastError());
if (errorPtr != NULL) {
@@ -1426,19 +1368,19 @@ TraverseWinTree(
*
* TraversalCopy
*
- * Called from TraverseUnixTree in order to execute a recursive copy of a
- * directory.
+ * Called from TraverseUnixTree in order to execute a recursive
+ * copy of a directory.
*
* Results:
- * Standard Tcl result.
+ * Standard Tcl result.
*
* Side effects:
- * Depending on the value of type, src may be copied to dst.
- *
+ * Depending on the value of type, src may be copied to dst.
+ *
*----------------------------------------------------------------------
*/
-static int
+static int
TraversalCopy(
CONST TCHAR *nativeSrc, /* Source pathname to copy. */
CONST TCHAR *nativeDst, /* Destination pathname of copy. */
@@ -1447,34 +1389,30 @@ TraversalCopy(
* with UTF-8 name of file causing error. */
{
switch (type) {
- case DOTREE_F:
- if (DoCopyFile(nativeSrc, nativeDst) == TCL_OK) {
- return TCL_OK;
- }
- break;
- case DOTREE_LINK:
- if (TclWinSymLinkCopyDirectory(nativeSrc, nativeDst) == TCL_OK) {
- return TCL_OK;
- }
- break;
- case DOTREE_PRED:
- if (DoCreateDirectory(nativeDst) == TCL_OK) {
- DWORD attr = (tclWinProcs->getFileAttributesProc)(nativeSrc);
-
- if ((tclWinProcs->setFileAttributesProc)(nativeDst,
- attr) != FALSE) {
+ case DOTREE_F: {
+ if (DoCopyFile(nativeSrc, nativeDst) == TCL_OK) {
return TCL_OK;
}
- TclWinConvertError(GetLastError());
+ break;
+ }
+ case DOTREE_PRED: {
+ if (DoCreateDirectory(nativeDst) == TCL_OK) {
+ DWORD attr = (*tclWinProcs->getFileAttributesProc)(nativeSrc);
+ if ((*tclWinProcs->setFileAttributesProc)(nativeDst, attr) != FALSE) {
+ return TCL_OK;
+ }
+ TclWinConvertError(GetLastError());
+ }
+ break;
+ }
+ case DOTREE_POSTD: {
+ return TCL_OK;
}
- break;
- case DOTREE_POSTD:
- return TCL_OK;
}
/*
- * There shouldn't be a problem with src, because we already checked it to
- * get here.
+ * There shouldn't be a problem with src, because we already
+ * checked it to get here.
*/
if (errorPtr != NULL) {
@@ -1488,24 +1426,24 @@ TraversalCopy(
*
* TraversalDelete --
*
- * Called by function TraverseWinTree for every file and directory that
- * it encounters in a directory hierarchy. This function unlinks files,
- * and removes directories after all the containing files have been
- * processed.
+ * Called by procedure TraverseWinTree for every file and
+ * directory that it encounters in a directory hierarchy. This
+ * procedure unlinks files, and removes directories after all the
+ * containing files have been processed.
*
* Results:
- * Standard Tcl result.
+ * Standard Tcl result.
*
* Side effects:
- * Files or directory specified by src will be deleted. If an error
- * occurs, the windows error is converted to a Posix error and errno is
- * set accordingly.
+ * Files or directory specified by src will be deleted. If an
+ * error occurs, the windows error is converted to a Posix error
+ * and errno is set accordingly.
*
*----------------------------------------------------------------------
*/
static int
-TraversalDelete(
+TraversalDelete(
CONST TCHAR *nativeSrc, /* Source pathname to delete. */
CONST TCHAR *dstPtr, /* Not used. */
int type, /* Reason for call - see TraverseWinTree() */
@@ -1513,23 +1451,21 @@ TraversalDelete(
* with UTF-8 name of file causing error. */
{
switch (type) {
- case DOTREE_F:
- if (TclpDeleteFile(nativeSrc) == TCL_OK) {
- return TCL_OK;
+ case DOTREE_F: {
+ if (TclpDeleteFile(nativeSrc) == TCL_OK) {
+ return TCL_OK;
+ }
+ break;
}
- break;
- case DOTREE_LINK:
- if (DoRemoveJustDirectory(nativeSrc, 0, NULL) == TCL_OK) {
+ case DOTREE_PRED: {
return TCL_OK;
}
- break;
- case DOTREE_PRED:
- return TCL_OK;
- case DOTREE_POSTD:
- if (DoRemoveJustDirectory(nativeSrc, 0, NULL) == TCL_OK) {
- return TCL_OK;
+ case DOTREE_POSTD: {
+ if (DoRemoveJustDirectory(nativeSrc, 0, NULL) == TCL_OK) {
+ return TCL_OK;
+ }
+ break;
}
- break;
}
if (errorPtr != NULL) {
@@ -1546,11 +1482,11 @@ TraversalDelete(
* Sets the object result with the appropriate error.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * The interp's object result is set with an error message based on the
- * objIndex, fileName and errno.
+ * The interp's object result is set with an error message
+ * based on the objIndex, fileName and errno.
*
*----------------------------------------------------------------------
*/
@@ -1558,12 +1494,14 @@ TraversalDelete(
static void
StatError(
Tcl_Interp *interp, /* The interp that has the error */
- Tcl_Obj *fileName) /* The name of the file which caused the
+ Tcl_Obj *fileName) /* The name of the file which caused the
* error. */
{
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "could not read \"", TclGetString(fileName),
- "\": ", Tcl_PosixError(interp), (char *) NULL);
+ Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+ "could not read \"", Tcl_GetString(fileName),
+ "\": ", Tcl_PosixError(interp),
+ (char *) NULL);
}
/*
@@ -1571,16 +1509,16 @@ StatError(
*
* GetWinFileAttributes --
*
- * Returns a Tcl_Obj containing the value of a file attribute. This
- * routine gets the -hidden, -readonly or -system attribute.
+ * Returns a Tcl_Obj containing the value of a file attribute.
+ * This routine gets the -hidden, -readonly or -system attribute.
*
* Results:
- * Standard Tcl result and a Tcl_Obj in attributePtrPtr. The object will
- * have ref count 0. If the return value is not TCL_OK, attributePtrPtr
- * is not touched.
+ * Standard Tcl result and a Tcl_Obj in attributePtrPtr. The object
+ * will have ref count 0. If the return value is not TCL_OK,
+ * attributePtrPtr is not touched.
*
* Side effects:
- * A new object is allocated if the file is valid.
+ * A new object is allocated if the file is valid.
*
*----------------------------------------------------------------------
*/
@@ -1589,13 +1527,13 @@ static int
GetWinFileAttributes(
Tcl_Interp *interp, /* The interp we are using for errors. */
int objIndex, /* The index of the attribute. */
- Tcl_Obj *fileName, /* The name of the file. */
+ Tcl_Obj *fileName, /* The name of the file. */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
DWORD result;
CONST TCHAR *nativeName;
int attr;
-
+
nativeName = Tcl_FSGetNativePath(fileName);
result = (*tclWinProcs->getFileAttributesProc)(nativeName);
@@ -1606,39 +1544,31 @@ GetWinFileAttributes(
attr = (int)(result & attributeArray[objIndex]);
if ((objIndex == WIN_HIDDEN_ATTRIBUTE) && (attr != 0)) {
- /*
- * It is hidden. However there is a bug on some Windows OSes in which
- * root volumes (drives) formatted as NTFS are declared hidden when
- * they are not (and cannot be).
- *
+ /*
+ * It is hidden. However there is a bug on some Windows
+ * OSes in which root volumes (drives) formatted as NTFS
+ * are declared hidden when they are not (and cannot be).
+ *
* We test for, and fix that case, here.
*/
-
int len;
char *str = Tcl_GetStringFromObj(fileName,&len);
-
if (len < 4) {
if (len == 0) {
- /*
- * Not sure if this is possible, but we pass it on anyway.
+ /*
+ * Not sure if this is possible, but we pass it on
+ * anyway
*/
} else if (len == 1 && (str[0] == '/' || str[0] == '\\')) {
- /*
- * Path is pointing to the root volume.
- */
-
+ /* Path is pointing to the root volume */
attr = 0;
- } else if ((str[1] == ':')
- && (len == 2 || (str[2] == '/' || str[2] == '\\'))) {
- /*
- * Path is of the form 'x:' or 'x:/' or 'x:\'
- */
-
+ } else if ((str[1] == ':')
+ && (len == 2 || (str[2] == '/' || str[2] == '\\'))) {
+ /* Path is of the form 'x:' or 'x:/' or 'x:\' */
attr = 0;
}
}
}
-
*attributePtrPtr = Tcl_NewBooleanObj(attr);
return TCL_OK;
}
@@ -1648,20 +1578,21 @@ GetWinFileAttributes(
*
* ConvertFileNameFormat --
*
- * Returns a Tcl_Obj containing either the long or short version of the
+ * Returns a Tcl_Obj containing either the long or short version of the
* file name.
*
* Results:
- * Standard Tcl result and a Tcl_Obj in attributePtrPtr. The object will
- * have ref count 0. If the return value is not TCL_OK, attributePtrPtr
- * is not touched.
- *
- * Warning: if you pass this function a drive name like 'c:' it will
- * actually return the current working directory on that drive. To avoid
- * this, make sure the drive name ends in a slash, like this 'c:/'.
+ * Standard Tcl result and a Tcl_Obj in attributePtrPtr. The object
+ * will have ref count 0. If the return value is not TCL_OK,
+ * attributePtrPtr is not touched.
+ *
+ * Warning: if you pass this function a drive name like 'c:' it
+ * will actually return the current working directory on that
+ * drive. To avoid this, make sure the drive name ends in a
+ * slash, like this 'c:/'.
*
* Side effects:
- * A new object is allocated if the file is valid.
+ * A new object is allocated if the file is valid.
*
*----------------------------------------------------------------------
*/
@@ -1670,55 +1601,48 @@ static int
ConvertFileNameFormat(
Tcl_Interp *interp, /* The interp we are using for errors. */
int objIndex, /* The index of the attribute. */
- Tcl_Obj *fileName, /* The name of the file. */
+ Tcl_Obj *fileName, /* The name of the file. */
int longShort, /* 0 to short name, 1 to long name. */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
int pathc, i;
Tcl_Obj *splitPath;
+ int result = TCL_OK;
splitPath = Tcl_FSSplitPath(fileName, &pathc);
if (splitPath == NULL || pathc == 0) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "could not read \"",
- Tcl_GetString(fileName), "\": no such file or directory",
- (char *) NULL);
+ Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+ "could not read \"", Tcl_GetString(fileName),
+ "\": no such file or directory",
+ (char *) NULL);
}
+ result = TCL_ERROR;
goto cleanup;
}
-
- /*
- * We will decrement this again at the end. It is safer to do this in
- * case any of the calls below retain a reference to splitPath.
- */
-
- Tcl_IncrRefCount(splitPath);
-
+
for (i = 0; i < pathc; i++) {
Tcl_Obj *elt;
char *pathv;
int pathLen;
-
Tcl_ListObjIndex(NULL, splitPath, i, &elt);
-
+
pathv = Tcl_GetStringFromObj(elt, &pathLen);
- if ((pathv[0] == '/') || ((pathLen == 3) && (pathv[1] == ':'))
- || (strcmp(pathv, ".") == 0) || (strcmp(pathv, "..") == 0)) {
+ if ((pathv[0] == '/')
+ || ((pathLen == 3) && (pathv[1] == ':'))
+ || (strcmp(pathv, ".") == 0)
+ || (strcmp(pathv, "..") == 0)) {
/*
* Handle "/", "//machine/export", "c:/", "." or ".." by just
- * copying the string literally. Uppercase the drive letter, just
- * because it looks better under Windows to do so.
- */
-
- simple:
- /*
- * Here we are modifying the string representation in place.
- *
- * I believe this is legal, since this won't affect any file
- * representation this thing may have.
+ * copying the string literally. Uppercase the drive letter,
+ * just because it looks better under Windows to do so.
*/
+ simple:
+ /* Here we are modifying the string representation in place */
+ /* I believe this is legal, since this won't affect any
+ * file representation this thing may have. */
pathv[0] = (char) Tcl_UniCharToUpper(UCHAR(pathv[0]));
} else {
Tcl_Obj *tempPath;
@@ -1733,12 +1657,10 @@ ConvertFileNameFormat(
tempPath = Tcl_FSJoinPath(splitPath, i+1);
Tcl_IncrRefCount(tempPath);
-
- /*
- * We'd like to call Tcl_FSGetNativePath(tempPath) but that is
- * likely to lead to infinite loops.
+ /*
+ * We'd like to call Tcl_FSGetNativePath(tempPath)
+ * but that is likely to lead to infinite loops
*/
-
Tcl_DStringInit(&ds);
tempString = Tcl_GetStringFromObj(tempPath,&tempLen);
nativeName = Tcl_WinUtfToTChar(tempString, tempLen, &ds);
@@ -1746,14 +1668,14 @@ ConvertFileNameFormat(
handle = (*tclWinProcs->findFirstFileProc)(nativeName, &data);
if (handle == INVALID_HANDLE_VALUE) {
/*
- * FindFirstFile() doesn't like root directories. We would
- * only get a root directory here if the caller specified "c:"
- * or "c:." and the current directory on the drive was the
- * root directory
+ * FindFirstFile() doesn't like root directories. We
+ * would only get a root directory here if the caller
+ * specified "c:" or "c:." and the current directory on the
+ * drive was the root directory
*/
attr = (*tclWinProcs->getFileAttributesProc)(nativeName);
- if ((attr!=0xFFFFFFFF) && (attr & FILE_ATTRIBUTE_DIRECTORY)) {
+ if ((attr != 0xFFFFFFFF) && (attr & FILE_ATTRIBUTE_DIRECTORY)) {
Tcl_DStringFree(&ds);
goto simple;
}
@@ -1764,6 +1686,7 @@ ConvertFileNameFormat(
if (interp != NULL) {
StatError(interp, fileName);
}
+ result = TCL_ERROR;
goto cleanup;
}
if (tclWinProcs->useWide) {
@@ -1771,7 +1694,7 @@ ConvertFileNameFormat(
if (longShort) {
if (data.w.cFileName[0] != '\0') {
nativeName = (TCHAR *) data.w.cFileName;
- }
+ }
} else {
if (data.w.cAlternateFileName[0] == '\0') {
nativeName = (TCHAR *) data.w.cFileName;
@@ -1782,7 +1705,7 @@ ConvertFileNameFormat(
if (longShort) {
if (data.a.cFileName[0] != '\0') {
nativeName = (TCHAR *) data.a.cFileName;
- }
+ }
} else {
if (data.a.cAlternateFileName[0] == '\0') {
nativeName = (TCHAR *) data.a.cFileName;
@@ -1791,12 +1714,12 @@ ConvertFileNameFormat(
}
/*
- * Purify reports a extraneous UMR in Tcl_WinTCharToUtf() trying
- * to dereference nativeName as a Unicode string. I have proven to
- * myself that purify is wrong by running the following example
- * when nativeName == data.w.cAlternateFileName and noting that
- * purify doesn't complain about the first line, but does complain
- * about the second.
+ * Purify reports a extraneous UMR in Tcl_WinTCharToUtf() trying
+ * to dereference nativeName as a Unicode string. I have proven
+ * to myself that purify is wrong by running the following
+ * example when nativeName == data.w.cAlternateFileName and
+ * noting that purify doesn't complain about the first line,
+ * but does complain about the second.
*
* fprintf(stderr, "%d\n", data.w.cAlternateFileName[0]);
* fprintf(stderr, "%d\n", ((WCHAR *) nativeName)[0]);
@@ -1804,18 +1727,14 @@ ConvertFileNameFormat(
Tcl_DStringInit(&dsTemp);
Tcl_WinTCharToUtf(nativeName, -1, &dsTemp);
-
- /*
- * Deal with issues of tildes being absolute.
- */
-
+ /* Deal with issues of tildes being absolute */
if (Tcl_DStringValue(&dsTemp)[0] == '~') {
tempPath = Tcl_NewStringObj("./",2);
- Tcl_AppendToObj(tempPath, Tcl_DStringValue(&dsTemp),
- Tcl_DStringLength(&dsTemp));
+ Tcl_AppendToObj(tempPath, Tcl_DStringValue(&dsTemp),
+ Tcl_DStringLength(&dsTemp));
} else {
- tempPath = Tcl_NewStringObj(Tcl_DStringValue(&dsTemp),
- Tcl_DStringLength(&dsTemp));
+ tempPath = Tcl_NewStringObj(Tcl_DStringValue(&dsTemp),
+ Tcl_DStringLength(&dsTemp));
}
Tcl_ListObjReplace(NULL, splitPath, i, 1, 1, &tempPath);
Tcl_DStringFree(&ds);
@@ -1826,27 +1745,12 @@ ConvertFileNameFormat(
*attributePtrPtr = Tcl_FSJoinPath(splitPath, -1);
- if (splitPath != NULL) {
- /*
- * Unfortunately, the object we will return may have its only refCount
- * as part of the list splitPath. This means if we free splitPath, the
- * object will disappear. So, we have to be very careful here.
- * Unfortunately this means we must manipulate the object's refCount
- * directly.
- */
-
- Tcl_IncrRefCount(*attributePtrPtr);
- Tcl_DecrRefCount(splitPath);
- --(*attributePtrPtr)->refCount;
- }
- return TCL_OK;
-
- cleanup:
+cleanup:
if (splitPath != NULL) {
Tcl_DecrRefCount(splitPath);
}
-
- return TCL_ERROR;
+
+ return result;
}
/*
@@ -1854,15 +1758,16 @@ ConvertFileNameFormat(
*
* GetWinFileLongName --
*
- * Returns a Tcl_Obj containing the long version of the file name.
+ * Returns a Tcl_Obj containing the long version of the file
+ * name.
*
* Results:
- * Standard Tcl result and a Tcl_Obj in attributePtrPtr. The object will
- * have ref count 0. If the return value is not TCL_OK, attributePtrPtr
- * is not touched.
+ * Standard Tcl result and a Tcl_Obj in attributePtrPtr. The object
+ * will have ref count 0. If the return value is not TCL_OK,
+ * attributePtrPtr is not touched.
*
* Side effects:
- * A new object is allocated if the file is valid.
+ * A new object is allocated if the file is valid.
*
*----------------------------------------------------------------------
*/
@@ -1871,11 +1776,10 @@ static int
GetWinFileLongName(
Tcl_Interp *interp, /* The interp we are using for errors. */
int objIndex, /* The index of the attribute. */
- Tcl_Obj *fileName, /* The name of the file. */
+ Tcl_Obj *fileName, /* The name of the file. */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
- return ConvertFileNameFormat(interp, objIndex, fileName, 1,
- attributePtrPtr);
+ return ConvertFileNameFormat(interp, objIndex, fileName, 1, attributePtrPtr);
}
/*
@@ -1883,15 +1787,16 @@ GetWinFileLongName(
*
* GetWinFileShortName --
*
- * Returns a Tcl_Obj containing the short version of the file name.
+ * Returns a Tcl_Obj containing the short version of the file
+ * name.
*
* Results:
- * Standard Tcl result and a Tcl_Obj in attributePtrPtr. The object will
- * have ref count 0. If the return value is not TCL_OK, attributePtrPtr
- * is not touched.
+ * Standard Tcl result and a Tcl_Obj in attributePtrPtr. The object
+ * will have ref count 0. If the return value is not TCL_OK,
+ * attributePtrPtr is not touched.
*
* Side effects:
- * A new object is allocated if the file is valid.
+ * A new object is allocated if the file is valid.
*
*----------------------------------------------------------------------
*/
@@ -1900,11 +1805,10 @@ static int
GetWinFileShortName(
Tcl_Interp *interp, /* The interp we are using for errors. */
int objIndex, /* The index of the attribute. */
- Tcl_Obj *fileName, /* The name of the file. */
+ Tcl_Obj *fileName, /* The name of the file. */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
- return ConvertFileNameFormat(interp, objIndex, fileName, 0,
- attributePtrPtr);
+ return ConvertFileNameFormat(interp, objIndex, fileName, 0, attributePtrPtr);
}
/*
@@ -1912,14 +1816,14 @@ GetWinFileShortName(
*
* SetWinFileAttributes --
*
- * Set the file attributes to the value given by attributePtr. This
- * routine sets the -hidden, -readonly, or -system attributes.
+ * Set the file attributes to the value given by attributePtr.
+ * This routine sets the -hidden, -readonly, or -system attributes.
*
* Results:
- * Standard TCL error.
+ * Standard TCL error.
*
* Side effects:
- * The file's attribute is set.
+ * The file's attribute is set.
*
*----------------------------------------------------------------------
*/
@@ -1928,7 +1832,7 @@ static int
SetWinFileAttributes(
Tcl_Interp *interp, /* The interp we are using for errors. */
int objIndex, /* The index of the attribute. */
- Tcl_Obj *fileName, /* The name of the file. */
+ Tcl_Obj *fileName, /* The name of the file. */
Tcl_Obj *attributePtr) /* The new value of the attribute. */
{
DWORD fileAttributes;
@@ -1968,13 +1872,14 @@ SetWinFileAttributes(
*
* SetWinFileLongName --
*
- * The attribute in question is a readonly attribute and cannot be set.
+ * The attribute in question is a readonly attribute and cannot
+ * be set.
*
* Results:
- * TCL_ERROR
+ * TCL_ERROR
*
* Side effects:
- * The object result is set to a pertinent error message.
+ * The object result is set to a pertinent error message.
*
*----------------------------------------------------------------------
*/
@@ -1983,12 +1888,13 @@ static int
CannotSetAttribute(
Tcl_Interp *interp, /* The interp we are using for errors. */
int objIndex, /* The index of the attribute. */
- Tcl_Obj *fileName, /* The name of the file. */
+ Tcl_Obj *fileName, /* The name of the file. */
Tcl_Obj *attributePtr) /* The new value of the attribute. */
{
- Tcl_AppendResult(interp, "cannot set attribute \"",
- tclpFileAttrStrings[objIndex], "\" for file \"",
- Tcl_GetString(fileName), "\": attribute is readonly",
+ Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+ "cannot set attribute \"", tclpFileAttrStrings[objIndex],
+ "\" for file \"", Tcl_GetString(fileName),
+ "\": attribute is readonly",
(char *) NULL);
return TCL_ERROR;
}
@@ -2029,11 +1935,11 @@ TclpObjListVolumes(void)
if (GetLogicalDriveStringsA(sizeof(buf), buf) == 0) {
/*
* GetVolumeInformation() will detects all drives, but causes
- * chattering on empty floppy drives. We only do this if
- * GetLogicalDriveStrings() didn't work. It has also been reported
- * that on some laptops it takes a while for GetVolumeInformation() to
- * return when pinging an empty floppy drive, another reason to try to
- * avoid calling it.
+ * chattering on empty floppy drives. We only do this if
+ * GetLogicalDriveStrings() didn't work. It has also been reported
+ * that on some laptops it takes a while for GetVolumeInformation()
+ * to return when pinging an empty floppy drive, another reason to
+ * try to avoid calling it.
*/
buf[1] = ':';
@@ -2042,7 +1948,7 @@ TclpObjListVolumes(void)
for (i = 0; i < 26; i++) {
buf[0] = (char) ('a' + i);
- if (GetVolumeInformationA(buf, NULL, 0, NULL, NULL, NULL, NULL, 0)
+ if (GetVolumeInformationA(buf, NULL, 0, NULL, NULL, NULL, NULL, 0)
|| (GetLastError() == ERROR_NOT_READY)) {
elemPtr = Tcl_NewStringObj(buf, -1);
Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
@@ -2055,15 +1961,7 @@ TclpObjListVolumes(void)
Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
}
}
-
+
Tcl_IncrRefCount(resultPtr);
return resultPtr;
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinFile.c b/win/tclWinFile.c
index 08413d6..f145e23 100644
--- a/win/tclWinFile.c
+++ b/win/tclWinFile.c
@@ -1,21 +1,24 @@
-/*
+/*
* tclWinFile.c --
*
- * This file contains temporary wrappers around UNIX file handling
- * functions. These wrappers map the UNIX functions to Win32 HANDLE-style
- * files, which can be manipulated through the Win32 console redirection
- * interfaces.
+ * This file contains temporary wrappers around UNIX file handling
+ * functions. These wrappers map the UNIX functions to Win32 HANDLE-style
+ * files, which can be manipulated through the Win32 console redirection
+ * interfaces.
*
* Copyright (c) 1995-1998 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#ifndef _WIN64
+/* See [Bug 2935503]: file mtime sets wrong time */
+# define _USE_32BIT_TIME_T
+#endif
+#include <sys/stat.h>
#include "tclWinInt.h"
-#include "tclFileSystem.h"
#include <winioctl.h>
-#include <sys/stat.h>
#include <shlobj.h>
#include <lmaccess.h> /* For TclpGetUserHome(). */
@@ -24,280 +27,234 @@
* on the proleptic Gregorian calendar) and the Posix epoch (1970-01-01).
*/
-#define POSIX_EPOCH_AS_FILETIME \
- ((Tcl_WideInt) 116444736 * (Tcl_WideInt) 1000000000)
+#define POSIX_EPOCH_AS_FILETIME 116444736000000000
/*
- * Declarations for 'link' related information. This information should come
- * with VC++ 6.0, but is not in some older SDKs. In any case it is not well
- * documented.
+ * Declarations for 'link' related information. This information
+ * should come with VC++ 6.0, but is not in some older SDKs.
+ * In any case it is not well documented.
*/
-
#ifndef IO_REPARSE_TAG_RESERVED_ONE
-# define IO_REPARSE_TAG_RESERVED_ONE 0x000000001
+# define IO_REPARSE_TAG_RESERVED_ONE 0x000000001
#endif
#ifndef IO_REPARSE_TAG_RESERVED_RANGE
-# define IO_REPARSE_TAG_RESERVED_RANGE 0x000000001
+# define IO_REPARSE_TAG_RESERVED_RANGE 0x000000001
#endif
#ifndef IO_REPARSE_TAG_VALID_VALUES
-# define IO_REPARSE_TAG_VALID_VALUES 0x0E000FFFF
+# define IO_REPARSE_TAG_VALID_VALUES 0x0E000FFFF
#endif
#ifndef IO_REPARSE_TAG_HSM
-# define IO_REPARSE_TAG_HSM 0x0C0000004
+# define IO_REPARSE_TAG_HSM 0x0C0000004
#endif
#ifndef IO_REPARSE_TAG_NSS
-# define IO_REPARSE_TAG_NSS 0x080000005
+# define IO_REPARSE_TAG_NSS 0x080000005
#endif
#ifndef IO_REPARSE_TAG_NSSRECOVER
-# define IO_REPARSE_TAG_NSSRECOVER 0x080000006
+# define IO_REPARSE_TAG_NSSRECOVER 0x080000006
#endif
#ifndef IO_REPARSE_TAG_SIS
-# define IO_REPARSE_TAG_SIS 0x080000007
+# define IO_REPARSE_TAG_SIS 0x080000007
#endif
#ifndef IO_REPARSE_TAG_DFS
-# define IO_REPARSE_TAG_DFS 0x080000008
+# define IO_REPARSE_TAG_DFS 0x080000008
#endif
#ifndef IO_REPARSE_TAG_RESERVED_ZERO
-# define IO_REPARSE_TAG_RESERVED_ZERO 0x00000000
+# define IO_REPARSE_TAG_RESERVED_ZERO 0x00000000
#endif
#ifndef FILE_FLAG_OPEN_REPARSE_POINT
-# define FILE_FLAG_OPEN_REPARSE_POINT 0x00200000
+# define FILE_FLAG_OPEN_REPARSE_POINT 0x00200000
#endif
#ifndef IO_REPARSE_TAG_MOUNT_POINT
-# define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
+# define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
#endif
#ifndef IsReparseTagValid
-# define IsReparseTagValid(x) \
- (!((x)&~IO_REPARSE_TAG_VALID_VALUES)&&((x)>IO_REPARSE_TAG_RESERVED_RANGE))
+# define IsReparseTagValid(x) (!((x)&~IO_REPARSE_TAG_VALID_VALUES)&&((x)>IO_REPARSE_TAG_RESERVED_RANGE))
#endif
#ifndef IO_REPARSE_TAG_SYMBOLIC_LINK
-# define IO_REPARSE_TAG_SYMBOLIC_LINK IO_REPARSE_TAG_RESERVED_ZERO
+# define IO_REPARSE_TAG_SYMBOLIC_LINK IO_REPARSE_TAG_RESERVED_ZERO
#endif
#ifndef FILE_SPECIAL_ACCESS
-# define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
+# define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
#endif
#ifndef FSCTL_SET_REPARSE_POINT
-# define FSCTL_SET_REPARSE_POINT \
- CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
-# define FSCTL_GET_REPARSE_POINT \
- CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
-# define FSCTL_DELETE_REPARSE_POINT \
- CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
+# define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
+# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
+# define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#endif
#ifndef INVALID_FILE_ATTRIBUTES
-#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
-/*
- * Maximum reparse buffer info size. The max user defined reparse data is
- * 16KB, plus there's a header.
+/*
+ * Maximum reparse buffer info size. The max user defined reparse
+ * data is 16KB, plus there's a header.
*/
-#define MAX_REPARSE_SIZE 17000
+#define MAX_REPARSE_SIZE 17000
/*
- * Undocumented REPARSE_MOUNTPOINT_HEADER_SIZE structure definition. This is
- * found in winnt.h.
- *
- * IMPORTANT: caution when using this structure, since the actual structures
- * used will want to store a full path in the 'PathBuffer' field, but there
- * isn't room (there's only a single WCHAR!). Therefore one must artificially
- * create a larger space of memory and then cast it to this type. We use the
- * 'DUMMY_REPARSE_BUFFER' struct just below to deal with this problem.
+ * Undocumented REPARSE_MOUNTPOINT_HEADER_SIZE structure definition.
+ * This is found in winnt.h.
+ *
+ * IMPORTANT: caution when using this structure, since the actual
+ * structures used will want to store a full path in the 'PathBuffer'
+ * field, but there isn't room (there's only a single WCHAR!). Therefore
+ * one must artificially create a larger space of memory and then cast it
+ * to this type. We use the 'DUMMY_REPARSE_BUFFER' struct just below to
+ * deal with this problem.
*/
-#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
+#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
#ifndef REPARSE_DATA_BUFFER_HEADER_SIZE
typedef struct _REPARSE_DATA_BUFFER {
- DWORD ReparseTag;
- WORD ReparseDataLength;
- WORD Reserved;
+ DWORD ReparseTag;
+ WORD ReparseDataLength;
+ WORD Reserved;
union {
- struct {
- WORD SubstituteNameOffset;
- WORD SubstituteNameLength;
- WORD PrintNameOffset;
- WORD PrintNameLength;
- ULONG Flags;
- WCHAR PathBuffer[1];
- } SymbolicLinkReparseBuffer;
- struct {
- WORD SubstituteNameOffset;
- WORD SubstituteNameLength;
- WORD PrintNameOffset;
- WORD PrintNameLength;
- WCHAR PathBuffer[1];
- } MountPointReparseBuffer;
- struct {
- BYTE DataBuffer[1];
- } GenericReparseBuffer;
+ struct {
+ WORD SubstituteNameOffset;
+ WORD SubstituteNameLength;
+ WORD PrintNameOffset;
+ WORD PrintNameLength;
+ WCHAR PathBuffer[1];
+ } SymbolicLinkReparseBuffer;
+ struct {
+ WORD SubstituteNameOffset;
+ WORD SubstituteNameLength;
+ WORD PrintNameOffset;
+ WORD PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct {
+ BYTE DataBuffer[1];
+ } GenericReparseBuffer;
};
} REPARSE_DATA_BUFFER;
#endif
typedef struct {
REPARSE_DATA_BUFFER dummy;
- WCHAR dummyBuf[MAX_PATH * 3];
+ WCHAR dummyBuf[MAX_PATH*3];
} DUMMY_REPARSE_BUFFER;
-#if defined(_MSC_VER) && (_MSC_VER <= 1100)
-#undef HAVE_NO_FINDEX_ENUMS
+#if defined(_MSC_VER) && ( _MSC_VER <= 1100 )
#define HAVE_NO_FINDEX_ENUMS
#elif !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0400)
-#undef HAVE_NO_FINDEX_ENUMS
#define HAVE_NO_FINDEX_ENUMS
#endif
#ifdef HAVE_NO_FINDEX_ENUMS
/* These two aren't in VC++ 5.2 headers */
typedef enum _FINDEX_INFO_LEVELS {
- FindExInfoStandard,
- FindExInfoMaxInfoLevel
+ FindExInfoStandard,
+ FindExInfoMaxInfoLevel
} FINDEX_INFO_LEVELS;
typedef enum _FINDEX_SEARCH_OPS {
- FindExSearchNameMatch,
- FindExSearchLimitToDirectories,
- FindExSearchLimitToDevices,
- FindExSearchMaxSearchOp
+ FindExSearchNameMatch,
+ FindExSearchLimitToDirectories,
+ FindExSearchLimitToDevices,
+ FindExSearchMaxSearchOp
} FINDEX_SEARCH_OPS;
#endif /* HAVE_NO_FINDEX_ENUMS */
-/*
- * Other typedefs required by this code.
- */
+/* Other typedefs required by this code */
static time_t ToCTime(FILETIME fileTime);
static void FromCTime(time_t posixTime, FILETIME *fileTime);
-typedef NET_API_STATUS NET_API_FUNCTION NETUSERGETINFOPROC(
- LPWSTR servername, LPWSTR username, DWORD level, LPBYTE *bufptr);
+typedef NET_API_STATUS NET_API_FUNCTION NETUSERGETINFOPROC
+ (LPWSTR servername, LPWSTR username, DWORD level, LPBYTE *bufptr);
-typedef NET_API_STATUS NET_API_FUNCTION NETAPIBUFFERFREEPROC(LPVOID Buffer);
+typedef NET_API_STATUS NET_API_FUNCTION NETAPIBUFFERFREEPROC
+ (LPVOID Buffer);
-typedef NET_API_STATUS NET_API_FUNCTION NETGETDCNAMEPROC(
- LPWSTR servername, LPWSTR domainname, LPBYTE *bufptr);
+typedef NET_API_STATUS NET_API_FUNCTION NETGETDCNAMEPROC
+ (LPWSTR servername, LPWSTR domainname, LPBYTE *bufptr);
/*
- * Declarations for local functions defined in this file:
+ * Declarations for local procedures defined in this file:
*/
-static int NativeAccess(const TCHAR *path, int mode);
-static int NativeDev(const TCHAR *path);
-static int NativeStat(const TCHAR *path, Tcl_StatBuf *statPtr,
- int checkLinks);
-static unsigned short NativeStatMode(DWORD attr, int checkLinks,
- int isExec);
-static int NativeIsExec(const TCHAR *path);
-static int NativeReadReparse(const TCHAR *LinkDirectory,
- REPARSE_DATA_BUFFER *buffer);
-static int NativeWriteReparse(const TCHAR *LinkDirectory,
- REPARSE_DATA_BUFFER *buffer);
-static int NativeMatchType(int isDrive, DWORD attr,
- const TCHAR *nativeName, Tcl_GlobTypeData *types);
-static int WinIsDrive(const char *name, int nameLen);
-static int WinIsReserved(const char *path);
-static Tcl_Obj * WinReadLink(const TCHAR *LinkSource);
-static Tcl_Obj * WinReadLinkDirectory(const TCHAR *LinkDirectory);
-static int WinLink(const TCHAR *LinkSource,
- const TCHAR *LinkTarget, int linkAction);
-static int WinSymLinkDirectory(const TCHAR *LinkDirectory,
- const TCHAR *LinkTarget);
+static int NativeAccess(CONST TCHAR *path, int mode);
+static int NativeStat(CONST TCHAR *path, Tcl_StatBuf *statPtr, int checkLinks);
+static unsigned short NativeStatMode(DWORD attr, int checkLinks, int isExec);
+static int NativeIsExec(CONST TCHAR *path);
+static int NativeReadReparse(CONST TCHAR* LinkDirectory,
+ REPARSE_DATA_BUFFER* buffer);
+static int NativeWriteReparse(CONST TCHAR* LinkDirectory,
+ REPARSE_DATA_BUFFER* buffer);
+static int NativeMatchType(int isDrive, DWORD attr, CONST TCHAR* nativeName,
+ Tcl_GlobTypeData *types);
+static int WinIsDrive(CONST char *name, int nameLen);
+static int WinIsReserved(CONST char *path);
+static Tcl_Obj* WinReadLink(CONST TCHAR* LinkSource);
+static Tcl_Obj* WinReadLinkDirectory(CONST TCHAR* LinkDirectory);
+static int WinLink(CONST TCHAR* LinkSource, CONST TCHAR* LinkTarget,
+ int linkAction);
+static int WinSymLinkDirectory(CONST TCHAR* LinkDirectory,
+ CONST TCHAR* LinkTarget);
/*
*--------------------------------------------------------------------
*
- * WinLink --
- *
- * Make a link from source to target.
+ * WinLink
*
+ * Make a link from source to target.
*--------------------------------------------------------------------
*/
-
-static int
-WinLink(
- const TCHAR *linkSourcePath,
- const TCHAR *linkTargetPath,
- int linkAction)
+static int
+WinLink(LinkSource, LinkTarget, linkAction)
+ CONST TCHAR* LinkSource;
+ CONST TCHAR* LinkTarget;
+ int linkAction;
{
- WCHAR tempFileName[MAX_PATH];
- TCHAR *tempFilePart;
- DWORD attr;
-
- /*
- * Get the full path referenced by the target.
- */
-
- if (!(*tclWinProcs->getFullPathNameProc)(linkTargetPath, MAX_PATH,
- tempFileName, &tempFilePart)) {
- /*
- * Invalid file.
- */
-
+ WCHAR tempFileName[MAX_PATH];
+ TCHAR* tempFilePart;
+ int attr;
+
+ /* Get the full path referenced by the target */
+ if (!(*tclWinProcs->getFullPathNameProc)(LinkTarget,
+ MAX_PATH, tempFileName, &tempFilePart)) {
+ /* Invalid file */
TclWinConvertError(GetLastError());
return -1;
}
- /*
- * Make sure source file doesn't exist.
- */
-
- attr = (*tclWinProcs->getFileAttributesProc)(linkSourcePath);
- if (attr != INVALID_FILE_ATTRIBUTES) {
+ /* Make sure source file doesn't exist */
+ attr = (*tclWinProcs->getFileAttributesProc)(LinkSource);
+ if (attr != 0xffffffff) {
Tcl_SetErrno(EEXIST);
return -1;
}
- /*
- * Get the full path referenced by the source file/directory.
- */
-
- if (!(*tclWinProcs->getFullPathNameProc)(linkSourcePath, MAX_PATH,
- tempFileName, &tempFilePart)) {
- /*
- * Invalid file.
- */
-
+ /* Get the full path referenced by the directory */
+ if (!(*tclWinProcs->getFullPathNameProc)(LinkSource,
+ MAX_PATH, tempFileName, &tempFilePart)) {
+ /* Invalid file */
TclWinConvertError(GetLastError());
return -1;
}
-
- /*
- * Check the target.
- */
-
- attr = (*tclWinProcs->getFileAttributesProc)(linkTargetPath);
- if (attr == INVALID_FILE_ATTRIBUTES) {
- /*
- * The target doesn't exist.
- */
-
+ /* Check the target */
+ attr = (*tclWinProcs->getFileAttributesProc)(LinkTarget);
+ if (attr == 0xffffffff) {
+ /* The target doesn't exist */
TclWinConvertError(GetLastError());
return -1;
-
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
- /*
- * It is a file.
- */
-
+ /* It is a file */
if (tclWinProcs->createHardLinkProc == NULL) {
Tcl_SetErrno(ENOTDIR);
return -1;
}
-
if (linkAction & TCL_CREATE_HARD_LINK) {
- if (!(*tclWinProcs->createHardLinkProc)(linkSourcePath,
- linkTargetPath, NULL)) {
+ if (!(*tclWinProcs->createHardLinkProc)(LinkSource, LinkTarget, NULL)) {
TclWinConvertError(GetLastError());
return -1;
}
return 0;
-
} else if (linkAction & TCL_CREATE_SYMBOLIC_LINK) {
- /*
- * Can't symlink files.
- */
-
+ /* Can't symlink files */
Tcl_SetErrno(ENOTDIR);
return -1;
} else {
@@ -305,19 +262,10 @@ WinLink(
return -1;
}
} else {
- /*
- * We've got a directory. Now check whether what we're trying to do is
- * reasonable.
- */
-
if (linkAction & TCL_CREATE_SYMBOLIC_LINK) {
- return WinSymLinkDirectory(linkSourcePath, linkTargetPath);
-
+ return WinSymLinkDirectory(LinkSource, LinkTarget);
} else if (linkAction & TCL_CREATE_HARD_LINK) {
- /*
- * Can't hard link directories.
- */
-
+ /* Can't hard link directories */
Tcl_SetErrno(EISDIR);
return -1;
} else {
@@ -330,213 +278,169 @@ WinLink(
/*
*--------------------------------------------------------------------
*
- * WinReadLink --
- *
- * What does 'LinkSource' point to?
+ * WinReadLink
*
+ * What does 'LinkSource' point to?
*--------------------------------------------------------------------
*/
-
-static Tcl_Obj *
-WinReadLink(
- const TCHAR *linkSourcePath)
+static Tcl_Obj*
+WinReadLink(LinkSource)
+ CONST TCHAR* LinkSource;
{
- WCHAR tempFileName[MAX_PATH];
- TCHAR *tempFilePart;
- DWORD attr;
-
- /*
- * Get the full path referenced by the target.
- */
-
- if (!(*tclWinProcs->getFullPathNameProc)(linkSourcePath, MAX_PATH,
- tempFileName, &tempFilePart)) {
- /*
- * Invalid file.
- */
-
+ WCHAR tempFileName[MAX_PATH];
+ TCHAR* tempFilePart;
+ int attr;
+
+ /* Get the full path referenced by the target */
+ if (!(*tclWinProcs->getFullPathNameProc)(LinkSource,
+ MAX_PATH, tempFileName, &tempFilePart)) {
+ /* Invalid file */
TclWinConvertError(GetLastError());
return NULL;
}
- /*
- * Make sure source file does exist.
- */
-
- attr = (*tclWinProcs->getFileAttributesProc)(linkSourcePath);
- if (attr == INVALID_FILE_ATTRIBUTES) {
- /*
- * The source doesn't exist.
- */
-
+ /* Make sure source file does exist */
+ attr = (*tclWinProcs->getFileAttributesProc)(LinkSource);
+ if (attr == 0xffffffff) {
+ /* The source doesn't exist */
TclWinConvertError(GetLastError());
return NULL;
-
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
- /*
- * It is a file - this is not yet supported.
- */
-
+ /* It is a file - this is not yet supported */
Tcl_SetErrno(ENOTDIR);
return NULL;
} else {
- return WinReadLinkDirectory(linkSourcePath);
+ return WinReadLinkDirectory(LinkSource);
}
}
/*
*--------------------------------------------------------------------
*
- * WinSymLinkDirectory --
- *
- * This routine creates a NTFS junction, using the undocumented
- * FSCTL_SET_REPARSE_POINT structure Win2K uses for mount points and
- * junctions.
+ * WinSymLinkDirectory
*
- * Assumption that linkTargetPath is a valid, existing directory.
- *
- * Returns:
- * Zero on success.
+ * This routine creates a NTFS junction, using the undocumented
+ * FSCTL_SET_REPARSE_POINT structure Win2K uses for mount points
+ * and junctions.
*
+ * Assumption that LinkTarget is a valid, existing directory.
+ *
+ * Returns zero on success.
*--------------------------------------------------------------------
*/
-
-static int
-WinSymLinkDirectory(
- const TCHAR *linkDirPath,
- const TCHAR *linkTargetPath)
+static int
+WinSymLinkDirectory(LinkDirectory, LinkTarget)
+ CONST TCHAR* LinkDirectory;
+ CONST TCHAR* LinkTarget;
{
DUMMY_REPARSE_BUFFER dummy;
- REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER *) &dummy;
- int len;
- WCHAR nativeTarget[MAX_PATH];
- WCHAR *loop;
-
- /*
- * Make the native target name.
- */
-
- memcpy(nativeTarget, L"\\??\\", 4 * sizeof(WCHAR));
- memcpy(nativeTarget + 4, linkTargetPath,
- sizeof(WCHAR) * (1+wcslen((WCHAR *) linkTargetPath)));
+ REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER*)&dummy;
+ int len;
+ WCHAR nativeTarget[MAX_PATH];
+ WCHAR *loop;
+
+ /* Make the native target name */
+ memcpy((VOID*)nativeTarget, (VOID*)L"\\??\\", 4*sizeof(WCHAR));
+ memcpy((VOID*)(nativeTarget + 4), (VOID*)LinkTarget,
+ sizeof(WCHAR)*(1+wcslen((WCHAR*)LinkTarget)));
len = wcslen(nativeTarget);
-
- /*
- * We must have backslashes only. This is VERY IMPORTANT. If we have any
- * forward slashes everything appears to work, but the resulting symlink
- * is useless!
+ /*
+ * We must have backslashes only. This is VERY IMPORTANT.
+ * If we have any forward slashes everything appears to work,
+ * but the resulting symlink is useless!
*/
-
for (loop = nativeTarget; *loop != 0; loop++) {
- if (*loop == L'/') {
- *loop = L'\\';
- }
+ if (*loop == L'/') *loop = L'\\';
}
if ((nativeTarget[len-1] == L'\\') && (nativeTarget[len-2] != L':')) {
nativeTarget[len-1] = 0;
}
-
- /*
- * Build the reparse info.
- */
-
+
+ /* Build the reparse info */
memset(reparseBuffer, 0, sizeof(DUMMY_REPARSE_BUFFER));
reparseBuffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
- reparseBuffer->MountPointReparseBuffer.SubstituteNameLength =
- wcslen(nativeTarget) * sizeof(WCHAR);
+ reparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength =
+ wcslen(nativeTarget) * sizeof(WCHAR);
reparseBuffer->Reserved = 0;
- reparseBuffer->MountPointReparseBuffer.PrintNameLength = 0;
- reparseBuffer->MountPointReparseBuffer.PrintNameOffset =
- reparseBuffer->MountPointReparseBuffer.SubstituteNameLength
- + sizeof(WCHAR);
- memcpy(reparseBuffer->MountPointReparseBuffer.PathBuffer, nativeTarget,
- sizeof(WCHAR)
- + reparseBuffer->MountPointReparseBuffer.SubstituteNameLength);
- reparseBuffer->ReparseDataLength =
- reparseBuffer->MountPointReparseBuffer.SubstituteNameLength+12;
-
- return NativeWriteReparse(linkDirPath, reparseBuffer);
+ reparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength = 0;
+ reparseBuffer->SymbolicLinkReparseBuffer.PrintNameOffset =
+ reparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength
+ + sizeof(WCHAR);
+ memcpy(reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer, nativeTarget,
+ sizeof(WCHAR)
+ + reparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength);
+ reparseBuffer->ReparseDataLength =
+ reparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength + 12;
+
+ return NativeWriteReparse(LinkDirectory, reparseBuffer);
}
/*
*--------------------------------------------------------------------
*
- * TclWinSymLinkCopyDirectory --
- *
- * Copy a Windows NTFS junction. This function assumes that LinkOriginal
- * exists and is a valid junction point, and that LinkCopy does not
- * exist.
- *
- * Returns:
- * Zero on success.
+ * TclWinSymLinkCopyDirectory
*
+ * Copy a Windows NTFS junction. This function assumes that
+ * LinkOriginal exists and is a valid junction point, and that
+ * LinkCopy does not exist.
+ *
+ * Returns zero on success.
*--------------------------------------------------------------------
*/
-
-int
-TclWinSymLinkCopyDirectory(
- const TCHAR *linkOrigPath, /* Existing junction - reparse point */
- const TCHAR *linkCopyPath) /* Will become a duplicate junction */
+int
+TclWinSymLinkCopyDirectory(LinkOriginal, LinkCopy)
+ CONST TCHAR* LinkOriginal; /* Existing junction - reparse point */
+ CONST TCHAR* LinkCopy; /* Will become a duplicate junction */
{
DUMMY_REPARSE_BUFFER dummy;
- REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER *) &dummy;
-
- if (NativeReadReparse(linkOrigPath, reparseBuffer)) {
+ REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER*)&dummy;
+
+ if (NativeReadReparse(LinkOriginal, reparseBuffer)) {
return -1;
}
- return NativeWriteReparse(linkCopyPath, reparseBuffer);
+ return NativeWriteReparse(LinkCopy, reparseBuffer);
}
/*
*--------------------------------------------------------------------
*
- * TclWinSymLinkDelete --
- *
- * Delete a Windows NTFS junction. Once the junction information is
- * deleted, the filesystem object becomes an ordinary directory. Unless
- * 'linkOnly' is given, that directory is also removed.
- *
- * Assumption that LinkOriginal is a valid, existing junction.
- *
- * Returns:
- * Zero on success.
+ * TclWinSymLinkDelete
*
+ * Delete a Windows NTFS junction. Once the junction information
+ * is deleted, the filesystem object becomes an ordinary directory.
+ * Unless 'linkOnly' is given, that directory is also removed.
+ *
+ * Assumption that LinkOriginal is a valid, existing junction.
+ *
+ * Returns zero on success.
*--------------------------------------------------------------------
*/
-
-int
-TclWinSymLinkDelete(
- const TCHAR *linkOrigPath,
- int linkOnly)
+int
+TclWinSymLinkDelete(LinkOriginal, linkOnly)
+ CONST TCHAR* LinkOriginal;
+ int linkOnly;
{
- /*
- * It is a symbolic link - remove it.
- */
-
+ /* It is a symbolic link -- remove it */
DUMMY_REPARSE_BUFFER dummy;
- REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER *) &dummy;
+ REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER*)&dummy;
HANDLE hFile;
DWORD returnedLength;
-
memset(reparseBuffer, 0, sizeof(DUMMY_REPARSE_BUFFER));
reparseBuffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
- hFile = (*tclWinProcs->createFileProc)(linkOrigPath, GENERIC_WRITE, 0,
- NULL, OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
-
+ hFile = (*tclWinProcs->createFileProc)(LinkOriginal, GENERIC_WRITE, 0,
+ NULL, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
- if (!DeviceIoControl(hFile, FSCTL_DELETE_REPARSE_POINT, reparseBuffer,
- REPARSE_MOUNTPOINT_HEADER_SIZE,NULL,0,&returnedLength,NULL)) {
- /*
- * Error setting junction.
- */
-
+ if (!DeviceIoControl(hFile, FSCTL_DELETE_REPARSE_POINT, reparseBuffer,
+ REPARSE_MOUNTPOINT_HEADER_SIZE,
+ NULL, 0, &returnedLength, NULL)) {
+ /* Error setting junction */
TclWinConvertError(GetLastError());
CloseHandle(hFile);
} else {
CloseHandle(hFile);
if (!linkOnly) {
- (*tclWinProcs->removeDirectoryProc)(linkOrigPath);
+ (*tclWinProcs->removeDirectoryProc)(LinkOriginal);
}
return 0;
}
@@ -547,136 +451,123 @@ TclWinSymLinkDelete(
/*
*--------------------------------------------------------------------
*
- * WinReadLinkDirectory --
- *
- * This routine reads a NTFS junction, using the undocumented
- * FSCTL_GET_REPARSE_POINT structure Win2K uses for mount points and
- * junctions.
- *
- * Assumption that LinkDirectory is a valid, existing directory.
- *
- * Returns:
- * A Tcl_Obj with refCount of 1 (i.e. owned by the caller), or NULL if
- * anything went wrong.
+ * WinReadLinkDirectory
*
- * In the future we should enhance this to return a path object rather
- * than a string.
+ * This routine reads a NTFS junction, using the undocumented
+ * FSCTL_GET_REPARSE_POINT structure Win2K uses for mount points
+ * and junctions.
*
+ * Assumption that LinkDirectory is a valid, existing directory.
+ *
+ * Returns a Tcl_Obj with refCount of 1 (i.e. owned by the caller),
+ * or NULL if anything went wrong.
+ *
+ * In the future we should enhance this to return a path object
+ * rather than a string.
*--------------------------------------------------------------------
*/
-
-static Tcl_Obj *
-WinReadLinkDirectory(
- const TCHAR *linkDirPath)
+static Tcl_Obj*
+WinReadLinkDirectory(LinkDirectory)
+ CONST TCHAR* LinkDirectory;
{
- int attr, len, offset;
+ int attr;
DUMMY_REPARSE_BUFFER dummy;
- REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER *) &dummy;
- Tcl_Obj *retVal;
- Tcl_DString ds;
- const char *copy;
-
- attr = (*tclWinProcs->getFileAttributesProc)(linkDirPath);
+ REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER*)&dummy;
+
+ attr = (*tclWinProcs->getFileAttributesProc)(LinkDirectory);
if (!(attr & FILE_ATTRIBUTE_REPARSE_POINT)) {
- goto invalidError;
- }
- if (NativeReadReparse(linkDirPath, reparseBuffer)) {
+ Tcl_SetErrno(EINVAL);
return NULL;
}
-
+ if (NativeReadReparse(LinkDirectory, reparseBuffer)) {
+ return NULL;
+ }
+
switch (reparseBuffer->ReparseTag) {
- case 0x80000000|IO_REPARSE_TAG_SYMBOLIC_LINK:
- case IO_REPARSE_TAG_SYMBOLIC_LINK:
- case IO_REPARSE_TAG_MOUNT_POINT:
- /*
- * Certain native path representations on Windows have a special
- * prefix to indicate that they are to be treated specially. For
- * example extremely long paths, or symlinks, or volumes mounted
- * inside directories.
- *
- * There is an assumption in this code that 'wide' interfaces are
- * being used (see tclWin32Dll.c), which is true for the only systems
- * which support reparse tags at present. If that changes in the
- * future, this code will have to be generalised.
- */
-
- offset = 0;
- if (reparseBuffer->MountPointReparseBuffer.PathBuffer[0] == L'\\') {
- /*
- * Check whether this is a mounted volume.
+ case 0x80000000|IO_REPARSE_TAG_SYMBOLIC_LINK:
+ case IO_REPARSE_TAG_SYMBOLIC_LINK:
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ Tcl_Obj *retVal;
+ Tcl_DString ds;
+ CONST char *copy;
+ int len;
+ int offset = 0;
+
+ /*
+ * Certain native path representations on Windows have a
+ * special prefix to indicate that they are to be treated
+ * specially. For example extremely long paths, or symlinks,
+ * or volumes mounted inside directories.
+ *
+ * There is an assumption in this code that 'wide' interfaces
+ * are being used (see tclWin32Dll.c), which is true for the
+ * only systems which support reparse tags at present. If
+ * that changes in the future, this code will have to be
+ * generalised.
*/
-
- if (wcsncmp(reparseBuffer->MountPointReparseBuffer.PathBuffer,
- L"\\??\\Volume{",11) == 0) {
- char drive;
-
- /*
- * There is some confusion between \??\ and \\?\ which we have
- * to fix here. It doesn't seem very well documented.
- */
-
- reparseBuffer->MountPointReparseBuffer.PathBuffer[1]=L'\\';
-
- /*
- * Check if a corresponding drive letter exists, and use that
- * if it is found
- */
-
- drive = TclWinDriveLetterForVolMountPoint(
- reparseBuffer->MountPointReparseBuffer.PathBuffer);
- if (drive != -1) {
- char driveSpec[3] = {
- '\0', ':', '\0'
- };
-
- driveSpec[0] = drive;
- retVal = Tcl_NewStringObj(driveSpec,2);
- Tcl_IncrRefCount(retVal);
- return retVal;
+ if (reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer[0]
+ == L'\\') {
+ /* Check whether this is a mounted volume */
+ if (wcsncmp(reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer,
+ L"\\??\\Volume{",11) == 0) {
+ char drive;
+ /*
+ * There is some confusion between \??\ and \\?\ which
+ * we have to fix here. It doesn't seem very well
+ * documented.
+ */
+ reparseBuffer->SymbolicLinkReparseBuffer
+ .PathBuffer[1] = L'\\';
+ /*
+ * Check if a corresponding drive letter exists, and
+ * use that if it is found
+ */
+ drive = TclWinDriveLetterForVolMountPoint(reparseBuffer
+ ->SymbolicLinkReparseBuffer.PathBuffer);
+ if (drive != -1) {
+ char driveSpec[3] = {
+ drive, ':', '\0'
+ };
+ retVal = Tcl_NewStringObj(driveSpec,2);
+ Tcl_IncrRefCount(retVal);
+ return retVal;
+ }
+ /*
+ * This is actually a mounted drive, which doesn't
+ * exists as a DOS drive letter. This means the path
+ * isn't actually a link, although we partially treat
+ * it like one ('file type' will return 'link'), but
+ * then the link will actually just be treated like
+ * an ordinary directory. I don't believe any
+ * serious inconsistency will arise from this, but it
+ * is something to be aware of.
+ */
+ Tcl_SetErrno(EINVAL);
+ return NULL;
+ } else if (wcsncmp(reparseBuffer->SymbolicLinkReparseBuffer
+ .PathBuffer, L"\\\\?\\",4) == 0) {
+ /* Strip off the prefix */
+ offset = 4;
+ } else if (wcsncmp(reparseBuffer->SymbolicLinkReparseBuffer
+ .PathBuffer, L"\\??\\",4) == 0) {
+ /* Strip off the prefix */
+ offset = 4;
}
-
- /*
- * This is actually a mounted drive, which doesn't exists as a
- * DOS drive letter. This means the path isn't actually a
- * link, although we partially treat it like one ('file type'
- * will return 'link'), but then the link will actually just
- * be treated like an ordinary directory. I don't believe any
- * serious inconsistency will arise from this, but it is
- * something to be aware of.
- */
-
- goto invalidError;
- } else if (wcsncmp(reparseBuffer->MountPointReparseBuffer
- .PathBuffer, L"\\\\?\\",4) == 0) {
- /*
- * Strip off the prefix.
- */
-
- offset = 4;
- } else if (wcsncmp(reparseBuffer->MountPointReparseBuffer
- .PathBuffer, L"\\??\\",4) == 0) {
- /*
- * Strip off the prefix.
- */
-
- offset = 4;
}
- }
-
- Tcl_WinTCharToUtf((const char *)
- reparseBuffer->MountPointReparseBuffer.PathBuffer,
- (int) reparseBuffer->MountPointReparseBuffer
+
+ Tcl_WinTCharToUtf(
+ (CONST char*)reparseBuffer->SymbolicLinkReparseBuffer.PathBuffer,
+ (int)reparseBuffer->SymbolicLinkReparseBuffer
.SubstituteNameLength, &ds);
-
- copy = Tcl_DStringValue(&ds)+offset;
- len = Tcl_DStringLength(&ds)-offset;
- retVal = Tcl_NewStringObj(copy,len);
- Tcl_IncrRefCount(retVal);
- Tcl_DStringFree(&ds);
- return retVal;
+
+ copy = Tcl_DStringValue(&ds)+offset;
+ len = Tcl_DStringLength(&ds)-offset;
+ retVal = Tcl_NewStringObj(copy,len);
+ Tcl_IncrRefCount(retVal);
+ Tcl_DStringFree(&ds);
+ return retVal;
+ }
}
-
- invalidError:
Tcl_SetErrno(EINVAL);
return NULL;
}
@@ -684,55 +575,42 @@ WinReadLinkDirectory(
/*
*--------------------------------------------------------------------
*
- * NativeReadReparse --
+ * NativeReadReparse
*
- * Read the junction/reparse information from a given NTFS directory.
- *
- * Assumption that linkDirPath is a valid, existing directory.
- *
- * Returns:
- * Zero on success.
+ * Read the junction/reparse information from a given NTFS directory.
*
+ * Assumption that LinkDirectory is a valid, existing directory.
+ *
+ * Returns zero on success.
*--------------------------------------------------------------------
*/
-
-static int
-NativeReadReparse(
- const TCHAR *linkDirPath, /* The junction to read */
- REPARSE_DATA_BUFFER *buffer)/* Pointer to buffer. Cannot be NULL */
+static int
+NativeReadReparse(LinkDirectory, buffer)
+ CONST TCHAR* LinkDirectory; /* The junction to read */
+ REPARSE_DATA_BUFFER* buffer; /* Pointer to buffer. Cannot be NULL */
{
HANDLE hFile;
DWORD returnedLength;
-
- hFile = (*tclWinProcs->createFileProc)(linkDirPath, GENERIC_READ, 0,
- NULL, OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
-
+
+ hFile = (*tclWinProcs->createFileProc)(LinkDirectory, GENERIC_READ, 0,
+ NULL, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
- /*
- * Error creating directory.
- */
-
+ /* Error creating directory */
TclWinConvertError(GetLastError());
return -1;
}
-
- /*
- * Get the link.
- */
-
- if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer,
- sizeof(DUMMY_REPARSE_BUFFER), &returnedLength, NULL)) {
- /*
- * Error setting junction.
- */
-
+ /* Get the link */
+ if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL,
+ 0, buffer, sizeof(DUMMY_REPARSE_BUFFER),
+ &returnedLength, NULL)) {
+ /* Error setting junction */
TclWinConvertError(GetLastError());
CloseHandle(hFile);
return -1;
}
CloseHandle(hFile);
-
+
if (!IsReparseTagValid(buffer->ReparseTag)) {
Tcl_SetErrno(EINVAL);
return -1;
@@ -743,69 +621,48 @@ NativeReadReparse(
/*
*--------------------------------------------------------------------
*
- * NativeWriteReparse --
- *
- * Write the reparse information for a given directory.
- *
- * Assumption that LinkDirectory does not exist.
+ * NativeWriteReparse
*
+ * Write the reparse information for a given directory.
+ *
+ * Assumption that LinkDirectory does not exist.
*--------------------------------------------------------------------
*/
-
-static int
-NativeWriteReparse(
- const TCHAR *linkDirPath,
- REPARSE_DATA_BUFFER *buffer)
+static int
+NativeWriteReparse(LinkDirectory, buffer)
+ CONST TCHAR* LinkDirectory;
+ REPARSE_DATA_BUFFER* buffer;
{
HANDLE hFile;
DWORD returnedLength;
-
- /*
- * Create the directory - it must not already exist.
- */
-
- if ((*tclWinProcs->createDirectoryProc)(linkDirPath, NULL) == 0) {
- /*
- * Error creating directory.
- */
-
+
+ /* Create the directory - it must not already exist */
+ if ((*tclWinProcs->createDirectoryProc)(LinkDirectory, NULL) == 0) {
+ /* Error creating directory */
TclWinConvertError(GetLastError());
return -1;
}
- hFile = (*tclWinProcs->createFileProc)(linkDirPath, GENERIC_WRITE, 0,
- NULL, OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ hFile = (*tclWinProcs->createFileProc)(LinkDirectory, GENERIC_WRITE, 0,
+ NULL, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
- /*
- * Error creating directory.
- */
-
+ /* Error creating directory */
TclWinConvertError(GetLastError());
return -1;
}
-
- /*
- * Set the link.
- */
-
- if (!DeviceIoControl(hFile, FSCTL_SET_REPARSE_POINT, buffer,
- (DWORD) buffer->ReparseDataLength + REPARSE_MOUNTPOINT_HEADER_SIZE,
- NULL, 0, &returnedLength, NULL)) {
- /*
- * Error setting junction.
- */
-
+ /* Set the link */
+ if (!DeviceIoControl(hFile, FSCTL_SET_REPARSE_POINT, buffer,
+ (DWORD) buffer->ReparseDataLength
+ + REPARSE_MOUNTPOINT_HEADER_SIZE,
+ NULL, 0, &returnedLength, NULL)) {
+ /* Error setting junction */
TclWinConvertError(GetLastError());
CloseHandle(hFile);
- (*tclWinProcs->removeDirectoryProc)(linkDirPath);
+ (*tclWinProcs->removeDirectoryProc)(LinkDirectory);
return -1;
}
CloseHandle(hFile);
-
- /*
- * We succeeded.
- */
-
+ /* We succeeded */
return 0;
}
@@ -814,26 +671,39 @@ NativeWriteReparse(
*
* TclpFindExecutable --
*
- * This function computes the absolute path name of the current
- * application.
+ * This procedure computes the absolute path name of the current
+ * application, given its argv[0] value.
*
* Results:
- * None.
+ * A clean UTF string that is the path to the executable. At this
+ * point we may not know the system encoding, but we convert the
+ * string value to UTF-8 using core Windows functions. The path name
+ * contains ASCII string and '/' chars do not conflict with other UTF
+ * chars.
*
* Side effects:
- * The computed path is stored.
+ * The variable tclNativeExecutableName gets filled in with the file
+ * name for the application, if we figured it out. If we couldn't
+ * figure it out, tclNativeExecutableName is set to NULL.
*
*---------------------------------------------------------------------------
*/
-void
-TclpFindExecutable(
- const char *argv0) /* The value of the application's argv[0]
+char *
+TclpFindExecutable(argv0)
+ CONST char *argv0; /* The value of the application's argv[0]
* (native). */
{
WCHAR wName[MAX_PATH];
char name[MAX_PATH * TCL_UTF_MAX];
+ if (argv0 == NULL) {
+ return NULL;
+ }
+ if (tclNativeExecutableName != NULL) {
+ return tclNativeExecutableName;
+ }
+
/*
* Under Windows we ignore argv0, and return the path for the file used to
* create this process.
@@ -841,17 +711,16 @@ TclpFindExecutable(
if (GetModuleFileNameW(NULL, wName, MAX_PATH) == 0) {
GetModuleFileNameA(NULL, name, sizeof(name));
-
- /*
- * Convert to WCHAR to get out of ANSI codepage
- */
-
- MultiByteToWideChar(CP_ACP, 0, name, -1, wName, MAX_PATH);
+ } else {
+ WideCharToMultiByte(CP_UTF8, 0, wName, -1,
+ name, sizeof(name), NULL, NULL);
}
- WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, sizeof(name), NULL,NULL);
- TclWinNoBackslash(name);
- TclSetObjNameOfExecutable(Tcl_NewStringObj(name, -1), NULL);
+ tclNativeExecutableName = ckalloc((unsigned) (strlen(name) + 1));
+ strcpy(tclNativeExecutableName, name);
+
+ TclWinNoBackslash(tclNativeExecutableName);
+ return tclNativeExecutableName;
}
/*
@@ -859,53 +728,42 @@ TclpFindExecutable(
*
* TclpMatchInDirectory --
*
- * This routine is used by the globbing code to search a directory for
- * all files which match a given pattern.
+ * This routine is used by the globbing code to search a
+ * directory for all files which match a given pattern.
*
- * Results:
- * The return value is a standard Tcl result indicating whether an error
- * occurred in globbing. Errors are left in interp, good results are
- * lappended to resultPtr (which must be a valid object).
+ * Results:
+ *
+ * The return value is a standard Tcl result indicating whether an
+ * error occurred in globbing. Errors are left in interp, good
+ * results are lappended to resultPtr (which must be a valid object)
*
* Side effects:
* None.
*
- *----------------------------------------------------------------------
- */
+ *---------------------------------------------------------------------- */
int
-TclpMatchInDirectory(
- Tcl_Interp *interp, /* Interpreter to receive errors. */
- Tcl_Obj *resultPtr, /* List object to lappend results. */
- Tcl_Obj *pathPtr, /* Contains path to directory to search. */
- const char *pattern, /* Pattern to match against. */
- Tcl_GlobTypeData *types) /* Object containing list of acceptable types.
+TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
+ Tcl_Interp *interp; /* Interpreter to receive errors. */
+ Tcl_Obj *resultPtr; /* List object to lappend results. */
+ Tcl_Obj *pathPtr; /* Contains path to directory to search. */
+ CONST char *pattern; /* Pattern to match against. */
+ Tcl_GlobTypeData *types; /* Object containing list of acceptable types.
* May be NULL. In particular the directory
* flag is very important. */
{
- const TCHAR *native;
-
- if (types != NULL && types->type == TCL_GLOB_TYPE_MOUNT) {
- /*
- * The native filesystem never adds mounts.
- */
-
- return TCL_OK;
- }
+ CONST TCHAR *native;
if (pattern == NULL || (*pattern == '\0')) {
Tcl_Obj *norm = Tcl_FSGetNormalizedPath(NULL, pathPtr);
if (norm != NULL) {
- /*
- * Match a single file directly.
- */
-
+ /* Match a single file directly */
int len;
DWORD attr;
- const char *str = Tcl_GetStringFromObj(norm,&len);
-
- native = (const TCHAR *) Tcl_FSGetNativePath(pathPtr);
+ CONST char *str = Tcl_GetStringFromObj(norm,&len);
+ native = (CONST TCHAR*) Tcl_FSGetNativePath(pathPtr);
+
if (tclWinProcs->getFileAttributesExProc == NULL) {
attr = (*tclWinProcs->getFileAttributesProc)(native);
if (attr == 0xffffffff) {
@@ -919,8 +777,8 @@ TclpMatchInDirectory(
}
attr = data.dwFileAttributes;
}
-
- if (NativeMatchType(WinIsDrive(str,len), attr, native, types)) {
+ if (NativeMatchType(WinIsDrive(str,len), attr,
+ native, types)) {
Tcl_ListObjAppendElement(interp, resultPtr, pathPtr);
}
}
@@ -929,127 +787,94 @@ TclpMatchInDirectory(
DWORD attr;
HANDLE handle;
WIN32_FIND_DATAT data;
- const char *dirName; /* UTF-8 dir name, later with pattern
- * appended. */
+ CONST char *dirName;
int dirLength;
int matchSpecialDots;
- Tcl_DString ds; /* Native encoding of dir, also used
- * temporarily for other things. */
- Tcl_DString dsOrig; /* UTF-8 encoding of dir. */
+ Tcl_DString ds; /* native encoding of dir */
+ Tcl_DString dsOrig; /* utf-8 encoding of dir */
+ Tcl_DString dirString; /* utf-8 encoding of dir with \'s */
Tcl_Obj *fileNamePtr;
- char lastChar;
/*
- * Get the normalized path representation (the main thing is we dont
- * want any '~' sequences).
+ * Convert the path to normalized form since some interfaces only
+ * accept backslashes. Also, ensure that the directory ends with a
+ * separator character.
*/
- fileNamePtr = Tcl_FSGetNormalizedPath(interp, pathPtr);
+ fileNamePtr = Tcl_FSGetTranslatedPath(interp, pathPtr);
if (fileNamePtr == NULL) {
return TCL_ERROR;
}
+ Tcl_DStringInit(&dsOrig);
+ dirName = Tcl_GetStringFromObj(fileNamePtr, &dirLength);
+ Tcl_DStringAppend(&dsOrig, dirName, dirLength);
+
+ Tcl_DStringInit(&dirString);
+ if (dirLength == 0) {
+ Tcl_DStringAppend(&dirString, ".\\", 2);
+ } else {
+ char *p;
+ Tcl_DStringAppend(&dirString, dirName, dirLength);
+ for (p = Tcl_DStringValue(&dirString); *p != '\0'; p++) {
+ if (*p == '/') {
+ *p = '\\';
+ }
+ }
+ p--;
+ /* Make sure we have a trailing directory delimiter */
+ if ((*p != '\\') && (*p != ':')) {
+ Tcl_DStringAppend(&dirString, "\\", 1);
+ Tcl_DStringAppend(&dsOrig, "/", 1);
+ dirLength++;
+ }
+ }
+ dirName = Tcl_DStringValue(&dirString);
+ Tcl_DecrRefCount(fileNamePtr);
+
/*
- * Verify that the specified path exists and is actually a directory.
+ * First verify that the specified path is actually a directory.
*/
- native = Tcl_FSGetNativePath(pathPtr);
- if (native == NULL) {
- return TCL_OK;
- }
+ native = Tcl_WinUtfToTChar(dirName, Tcl_DStringLength(&dirString),
+ &ds);
attr = (*tclWinProcs->getFileAttributesProc)(native);
+ Tcl_DStringFree(&ds);
if ((attr == 0xffffffff) || ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
+ Tcl_DStringFree(&dirString);
return TCL_OK;
}
/*
- * Build up the directory name for searching, including a trailing
- * directory separator.
+ * We need to check all files in the directory, so append a *.*
+ * to the path.
*/
- Tcl_DStringInit(&dsOrig);
- dirName = Tcl_GetStringFromObj(fileNamePtr, &dirLength);
- Tcl_DStringAppend(&dsOrig, dirName, dirLength);
-
- lastChar = dirName[dirLength -1];
- if ((lastChar != '\\') && (lastChar != '/') && (lastChar != ':')) {
- Tcl_DStringAppend(&dsOrig, "/", 1);
- dirLength++;
- }
- dirName = Tcl_DStringValue(&dsOrig);
-
- /*
- * We need to check all files in the directory, so we append '*.*' to
- * the path, unless the pattern we've been given is rather simple,
- * when we can use that instead.
- */
-
- if (strpbrk(pattern, "[]\\") == NULL) {
- /*
- * The pattern is a simple one containing just '*' and/or '?'.
- * This means we can get the OS to help us, by passing it the
- * pattern.
- */
-
- dirName = Tcl_DStringAppend(&dsOrig, pattern, -1);
- } else {
- dirName = Tcl_DStringAppend(&dsOrig, "*.*", 3);
- }
-
+ dirName = Tcl_DStringAppend(&dirString, "*.*", 3);
native = Tcl_WinUtfToTChar(dirName, -1, &ds);
- if (tclWinProcs->findFirstFileExProc == NULL || (types == NULL)
- || (types->type != TCL_GLOB_TYPE_DIR)) {
- handle = (*tclWinProcs->findFirstFileProc)(native, &data);
- } else {
- /*
- * We can be more efficient, for pure directory requests.
- */
-
- handle = (*tclWinProcs->findFirstFileExProc)(native,
- FindExInfoStandard, &data,
- FindExSearchLimitToDirectories, NULL, 0);
- }
+ handle = (*tclWinProcs->findFirstFileProc)(native, &data);
if (handle == INVALID_HANDLE_VALUE) {
- DWORD err = GetLastError();
+ TclWinConvertError(GetLastError());
Tcl_DStringFree(&ds);
- if (err == ERROR_FILE_NOT_FOUND) {
- /*
- * We used our 'pattern' above, and matched nothing. This
- * means we just return TCL_OK, indicating no results found.
- */
-
- Tcl_DStringFree(&dsOrig);
- return TCL_OK;
- }
-
- TclWinConvertError(err);
- if (interp != NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "couldn't read directory \"",
- Tcl_DStringValue(&dsOrig), "\": ",
- Tcl_PosixError(interp), NULL);
- }
+ Tcl_DStringFree(&dirString);
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "couldn't read directory \"",
+ Tcl_DStringValue(&dsOrig), "\": ",
+ Tcl_PosixError(interp), (char *) NULL);
Tcl_DStringFree(&dsOrig);
return TCL_ERROR;
}
Tcl_DStringFree(&ds);
/*
- * We may use this later, so we must restore it to its length
- * including the directory delimiter.
- */
-
- Tcl_DStringSetLength(&dsOrig, dirLength);
-
- /*
- * Check to see if the pattern should match the special . and
- * .. names, referring to the current directory, or the directory
- * above. We need a special check for this because paths beginning
- * with a dot are not considered hidden on Windows, and so otherwise a
- * relative glob like 'glob -join * *' will actually return
- * './. ../..' etc.
+ * Check to see if the pattern should match the special
+ * . and .. names, referring to the current directory,
+ * or the directory above. We need a special check for
+ * this because paths beginning with a dot are not considered
+ * hidden on Windows, and so otherwise a relative glob like
+ * 'glob -join * *' will actually return './. ../..' etc.
*/
if ((pattern[0] == '.')
@@ -1060,53 +885,51 @@ TclpMatchInDirectory(
}
/*
- * Now iterate over all of the files in the directory, starting with
- * the first one we found.
+ * Now iterate over all of the files in the directory, starting
+ * with the first one we found.
*/
do {
- const char *utfname;
- int checkDrive = 0, isDrive;
+ CONST char *utfname;
+ int checkDrive = 0;
+ int isDrive;
DWORD attr;
-
+
if (tclWinProcs->useWide) {
- native = (const TCHAR *) data.w.cFileName;
+ native = (CONST TCHAR *) data.w.cFileName;
attr = data.w.dwFileAttributes;
} else {
- native = (const TCHAR *) data.a.cFileName;
+ native = (CONST TCHAR *) data.a.cFileName;
attr = data.a.dwFileAttributes;
}
-
+
utfname = Tcl_WinTCharToUtf(native, -1, &ds);
if (!matchSpecialDots) {
- /*
- * If it is exactly '.' or '..' then we ignore it.
- */
-
- if ((utfname[0] == '.') && (utfname[1] == '\0'
+ /* If it is exactly '.' or '..' then we ignore it */
+ if ((utfname[0] == '.') && (utfname[1] == '\0'
|| (utfname[1] == '.' && utfname[2] == '\0'))) {
Tcl_DStringFree(&ds);
continue;
}
} else if (utfname[0] == '.' && utfname[1] == '.'
&& utfname[2] == '\0') {
- /*
- * Have to check if this is a drive below, so we can correctly
- * match 'hidden' and not hidden files.
+ /*
+ * Have to check if this is a drive below, so we can
+ * correctly match 'hidden' and not hidden files.
*/
-
checkDrive = 1;
}
-
+
/*
- * Check to see if the file matches the pattern. Note that we are
- * ignoring the case sensitivity flag because Windows doesn't
- * honor case even if the volume is case sensitive. If the volume
- * also doesn't preserve case, then we previously returned the
- * lower case form of the name. This didn't seem quite right since
- * there are non-case-preserving volumes that actually return
- * mixed case. So now we are returning exactly what we get from
+ * Check to see if the file matches the pattern. Note that
+ * we are ignoring the case sensitivity flag because Windows
+ * doesn't honor case even if the volume is case sensitive.
+ * If the volume also doesn't preserve case, then we
+ * previously returned the lower case form of the name. This
+ * didn't seem quite right since there are
+ * non-case-preserving volumes that actually return mixed
+ * case. So now we are returning exactly what we get from
* the system.
*/
@@ -1117,7 +940,7 @@ TclpMatchInDirectory(
*/
if (checkDrive) {
- const char *fullname = Tcl_DStringAppend(&dsOrig, utfname,
+ CONST char *fullname = Tcl_DStringAppend(&dsOrig, utfname,
Tcl_DStringLength(&ds));
isDrive = WinIsDrive(fullname, Tcl_DStringLength(&dsOrig));
Tcl_DStringSetLength(&dsOrig, dirLength);
@@ -1125,7 +948,7 @@ TclpMatchInDirectory(
isDrive = 0;
}
if (NativeMatchType(isDrive, attr, native, types)) {
- Tcl_ListObjAppendElement(interp, resultPtr,
+ Tcl_ListObjAppendElement(interp, resultPtr,
TclNewFSPathObj(pathPtr, utfname,
Tcl_DStringLength(&ds)));
}
@@ -1134,38 +957,33 @@ TclpMatchInDirectory(
/*
* Free ds here to ensure that native is valid above.
*/
-
Tcl_DStringFree(&ds);
} while ((*tclWinProcs->findNextFileProc)(handle, &data) == TRUE);
FindClose(handle);
+ Tcl_DStringFree(&dirString);
Tcl_DStringFree(&dsOrig);
return TCL_OK;
}
}
-/*
- * Does the given path represent a root volume? We need this special case
- * because for NTFS root volumes, the getFileAttributesProc returns a 'hidden'
- * attribute when it should not.
+/*
+ * Does the given path represent a root volume? We need this special
+ * case because for NTFS root volumes, the getFileAttributesProc returns
+ * a 'hidden' attribute when it should not.
*/
-
static int
WinIsDrive(
- const char *name, /* Name (UTF-8) */
- int len) /* Length of name */
+ CONST char *name, /* Name (UTF-8) */
+ int len) /* Length of name */
{
int remove = 0;
-
while (len > 4) {
- if ((name[len-1] != '.' || name[len-2] != '.')
- || (name[len-3] != '/' && name[len-3] != '\\')) {
- /*
- * We don't have '/..' at the end.
- */
-
+ if ((name[len-1] != '.' || name[len-2] != '.')
+ || (name[len-3] != '/' && name[len-3] != '\\')) {
+ /* We don't have '/..' at the end */
if (remove == 0) {
- break;
+ break;
}
remove--;
while (len > 0) {
@@ -1175,95 +993,74 @@ WinIsDrive(
}
}
if (len < 4) {
- len++;
+ len++;
break;
}
- } else {
- /*
- * We do have '/..'
- */
-
+ } else {
+ /* We do have '/..' */
len -= 3;
remove++;
- }
+ }
}
-
if (len < 4) {
if (len == 0) {
- /*
- * Not sure if this is possible, but we pass it on anyway.
+ /*
+ * Not sure if this is possible, but we pass it on
+ * anyway
*/
} else if (len == 1 && (name[0] == '/' || name[0] == '\\')) {
- /*
- * Path is pointing to the root volume.
- */
-
+ /* Path is pointing to the root volume */
return 1;
- } else if ((name[1] == ':')
+ } else if ((name[1] == ':')
&& (len == 2 || (name[2] == '/' || name[2] == '\\'))) {
- /*
- * Path is of the form 'x:' or 'x:/' or 'x:\'
- */
-
+ /* Path is of the form 'x:' or 'x:/' or 'x:\' */
return 1;
}
}
-
return 0;
}
-/*
- * Does the given path represent a reserved window path name? If not return 0,
- * if true, return the number of characters of the path that we actually want
- * (not any trailing :).
+/*
+ * Does the given path represent a reserved window path name? If not
+ * return 0, if true, return the number of characters of the path that
+ * we actually want (not any trailing :).
*/
-
-static int
-WinIsReserved(
- const char *path) /* Path in UTF-8 */
+static int WinIsReserved(
+ CONST char *path) /* Path in UTF-8 */
{
- if ((path[0] == 'c' || path[0] == 'C')
- && (path[1] == 'o' || path[1] == 'O')) {
+ if ((path[0] == 'c' || path[0] == 'C')
+ && (path[1] == 'o' || path[1] == 'O')) {
if ((path[2] == 'm' || path[2] == 'M')
- && path[3] >= '1' && path[3] <= '4') {
- /*
- * May have match for 'com[1-4]:?', which is a serial port.
- */
-
+ && path[3] >= '1' && path[3] <= '4') {
+ /* May have match for 'com[1-4]:?', which is a serial port */
if (path[4] == '\0') {
return 4;
} else if (path [4] == ':' && path[5] == '\0') {
return 4;
}
} else if ((path[2] == 'n' || path[2] == 'N') && path[3] == '\0') {
- /*
- * Have match for 'con'
- */
-
+ /* Have match for 'con' */
return 3;
}
-
} else if ((path[0] == 'l' || path[0] == 'L')
- && (path[1] == 'p' || path[1] == 'P')
- && (path[2] == 't' || path[2] == 'T')) {
+ && (path[1] == 'p' || path[1] == 'P')
+ && (path[2] == 't' || path[2] == 'T')) {
if (path[3] >= '1' && path[3] <= '3') {
- /*
- * May have match for 'lpt[1-3]:?'
- */
-
+ /* May have match for 'lpt[1-3]:?' */
if (path[4] == '\0') {
return 4;
} else if (path [4] == ':' && path[5] == '\0') {
return 4;
}
}
-
- } else if (!strcasecmp(path, "prn") || !strcasecmp(path, "nul")
- || !strcasecmp(path, "aux")) {
- /*
- * Have match for 'prn', 'nul' or 'aux'.
- */
-
+ } else if (stricmp(path, "prn") == 0) {
+ /* Have match for 'prn' */
+ return 3;
+ } else if (stricmp(path, "nul") == 0) {
+ /* Have match for 'nul' */
+ return 3;
+ } else if (stricmp(path, "aux") == 0) {
+ /* Have match for 'aux' */
return 3;
}
return 0;
@@ -1271,108 +1068,102 @@ WinIsReserved(
/*
*----------------------------------------------------------------------
- *
+ *
* NativeMatchType --
- *
- * This function needs a special case for a path which is a root volume,
- * because for NTFS root volumes, the getFileAttributesProc returns a
- * 'hidden' attribute when it should not.
- *
- * We never make any calls to a 'get attributes' routine here, since we
- * have arranged things so that our caller already knows such
- * information.
- *
+ *
+ * This function needs a special case for a path which is a root
+ * volume, because for NTFS root volumes, the getFileAttributesProc
+ * returns a 'hidden' attribute when it should not.
+ *
+ * We never make any calls to a 'get attributes' routine here,
+ * since we have arranged things so that our caller already knows
+ * such information.
+ *
* Results:
- * 0 = file doesn't match
- * 1 = file matches
- *
+ * 0 = file doesn't match
+ * 1 = file matches
+ *
*----------------------------------------------------------------------
*/
-
-static int
+static int
NativeMatchType(
- int isDrive, /* Is this a drive. */
- DWORD attr, /* We already know the attributes for the
- * file. */
- const TCHAR *nativeName, /* Native path to check. */
- Tcl_GlobTypeData *types) /* Type description to match against. */
+ int isDrive, /* Is this a drive */
+ DWORD attr, /* We already know the attributes
+ * for the file */
+ CONST TCHAR* nativeName, /* Native path to check */
+ Tcl_GlobTypeData *types) /* Type description to match against */
{
/*
- * 'attr' represents the attributes of the file, but we only want to
- * retrieve this info if it is absolutely necessary because it is an
- * expensive call. Unfortunately, to deal with hidden files properly, we
- * must always retrieve it.
+ * 'attr' represents the attributes of the file, but we only
+ * want to retrieve this info if it is absolutely necessary
+ * because it is an expensive call. Unfortunately, to deal
+ * with hidden files properly, we must always retrieve it.
*/
if (types == NULL) {
- /*
- * If invisible, don't return the file.
- */
-
+ /* If invisible, don't return the file */
if (attr & FILE_ATTRIBUTE_HIDDEN && !isDrive) {
return 0;
}
} else {
if (attr & FILE_ATTRIBUTE_HIDDEN && !isDrive) {
- /*
- * If invisible.
- */
-
- if ((types->perm == 0) || !(types->perm & TCL_GLOB_PERM_HIDDEN)) {
+ /* If invisible */
+ if ((types->perm == 0) ||
+ !(types->perm & TCL_GLOB_PERM_HIDDEN)) {
return 0;
}
} else {
- /*
- * Visible.
- */
-
+ /* Visible */
if (types->perm & TCL_GLOB_PERM_HIDDEN) {
return 0;
}
}
-
+
if (types->perm != 0) {
- if (((types->perm & TCL_GLOB_PERM_RONLY) &&
+ if (
+ ((types->perm & TCL_GLOB_PERM_RONLY) &&
!(attr & FILE_ATTRIBUTE_READONLY)) ||
- ((types->perm & TCL_GLOB_PERM_R) &&
+ ((types->perm & TCL_GLOB_PERM_R) &&
(0 /* File exists => R_OK on Windows */)) ||
- ((types->perm & TCL_GLOB_PERM_W) &&
+ ((types->perm & TCL_GLOB_PERM_W) &&
(attr & FILE_ATTRIBUTE_READONLY)) ||
- ((types->perm & TCL_GLOB_PERM_X) &&
+ ((types->perm & TCL_GLOB_PERM_X) &&
(!(attr & FILE_ATTRIBUTE_DIRECTORY)
- && !NativeIsExec(nativeName)))) {
+ && !NativeIsExec(nativeName)))
+ ) {
return 0;
}
}
- if ((types->type & TCL_GLOB_TYPE_DIR)
- && (attr & FILE_ATTRIBUTE_DIRECTORY)) {
- /*
- * Quicker test for directory, which is a common case.
- */
-
+ if ((types->type & TCL_GLOB_TYPE_DIR)
+ && (attr & FILE_ATTRIBUTE_DIRECTORY)) {
+ /* Quicker test for directory, which is a common case */
return 1;
-
} else if (types->type != 0) {
unsigned short st_mode;
int isExec = NativeIsExec(nativeName);
-
+
st_mode = NativeStatMode(attr, 0, isExec);
/*
* In order bcdpfls as in 'find -t'
*/
-
- if (((types->type&TCL_GLOB_TYPE_BLOCK) && S_ISBLK(st_mode)) ||
- ((types->type&TCL_GLOB_TYPE_CHAR) && S_ISCHR(st_mode)) ||
- ((types->type&TCL_GLOB_TYPE_DIR) && S_ISDIR(st_mode)) ||
- ((types->type&TCL_GLOB_TYPE_PIPE) && S_ISFIFO(st_mode)) ||
+ if (
+ ((types->type & TCL_GLOB_TYPE_BLOCK) &&
+ S_ISBLK(st_mode)) ||
+ ((types->type & TCL_GLOB_TYPE_CHAR) &&
+ S_ISCHR(st_mode)) ||
+ ((types->type & TCL_GLOB_TYPE_DIR) &&
+ S_ISDIR(st_mode)) ||
+ ((types->type & TCL_GLOB_TYPE_PIPE) &&
+ S_ISFIFO(st_mode)) ||
+ ((types->type & TCL_GLOB_TYPE_FILE) &&
+ S_ISREG(st_mode))
#ifdef S_ISSOCK
- ((types->type&TCL_GLOB_TYPE_SOCK) && S_ISSOCK(st_mode)) ||
+ || ((types->type & TCL_GLOB_TYPE_SOCK) &&
+ S_ISSOCK(st_mode))
#endif
- ((types->type&TCL_GLOB_TYPE_FILE) && S_ISREG(st_mode))) {
- /*
- * Do nothing - this file is ok.
- */
+ ) {
+ /* Do nothing -- this file is ok */
} else {
#ifdef S_ISLNK
if (types->type & TCL_GLOB_TYPE_LINK) {
@@ -1384,8 +1175,8 @@ NativeMatchType(
#endif
return 0;
}
- }
- }
+ }
+ }
return 1;
}
@@ -1400,9 +1191,9 @@ NativeMatchType(
* Results:
* The result is a pointer to a string specifying the user's home
* directory, or NULL if the user's home directory could not be
- * determined. Storage for the result string is allocated in bufferPtr;
- * the caller must call Tcl_DStringFree() when the result is no longer
- * needed.
+ * determined. Storage for the result string is allocated in
+ * bufferPtr; the caller must call Tcl_DStringFree() when the result
+ * is no longer needed.
*
* Side effects:
* None.
@@ -1411,15 +1202,16 @@ NativeMatchType(
*/
char *
-TclpGetUserHome(
- const char *name, /* User name for desired home directory. */
- Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with
- * name of user's home directory. */
+TclpGetUserHome(name, bufferPtr)
+ CONST char *name; /* User name for desired home directory. */
+ Tcl_DString *bufferPtr; /* Uninitialized or free DString filled
+ * with name of user's home directory. */
{
char *result;
HINSTANCE netapiInst;
result = NULL;
+
Tcl_DStringInit(bufferPtr);
netapiInst = LoadLibraryA("netapi32.dll");
@@ -1430,17 +1222,17 @@ TclpGetUserHome(
netApiBufferFreeProc = (NETAPIBUFFERFREEPROC *)
GetProcAddress(netapiInst, "NetApiBufferFree");
- netGetDCNameProc = (NETGETDCNAMEPROC *)
+ netGetDCNameProc = (NETGETDCNAMEPROC *)
GetProcAddress(netapiInst, "NetGetDCName");
- netUserGetInfoProc = (NETUSERGETINFOPROC *)
+ netUserGetInfoProc = (NETUSERGETINFOPROC *)
GetProcAddress(netapiInst, "NetUserGetInfo");
if ((netUserGetInfoProc != NULL) && (netGetDCNameProc != NULL)
&& (netApiBufferFreeProc != NULL)) {
- USER_INFO_1 *uiPtr, **uiPtrPtr = &uiPtr;
+ USER_INFO_1 *uiPtr;
Tcl_DString ds;
int nameLen, badDomain;
char *domain;
- WCHAR *wName, *wHomeDir, *wDomain, **wDomainPtr = &wDomain;
+ WCHAR *wName, *wHomeDir, *wDomain;
WCHAR buf[MAX_PATH];
badDomain = 0;
@@ -1450,23 +1242,23 @@ TclpGetUserHome(
if (domain != NULL) {
Tcl_DStringInit(&ds);
wName = Tcl_UtfToUniCharDString(domain + 1, -1, &ds);
- badDomain = (netGetDCNameProc)(NULL, wName,
- (LPBYTE *) wDomainPtr);
+ badDomain = (*netGetDCNameProc)(NULL, wName,
+ (LPBYTE *) &wDomain);
Tcl_DStringFree(&ds);
nameLen = domain - name;
}
if (badDomain == 0) {
Tcl_DStringInit(&ds);
wName = Tcl_UtfToUniCharDString(name, nameLen, &ds);
- if ((netUserGetInfoProc)(wDomain, wName, 1,
- (LPBYTE *) uiPtrPtr) == 0) {
+ if ((*netUserGetInfoProc)(wDomain, wName, 1,
+ (LPBYTE *) &uiPtr) == 0) {
wHomeDir = uiPtr->usri1_home_dir;
if ((wHomeDir != NULL) && (wHomeDir[0] != L'\0')) {
Tcl_UniCharToUtfDString(wHomeDir, lstrlenW(wHomeDir),
bufferPtr);
} else {
- /*
- * User exists but has no home dir. Return
+ /*
+ * User exists but has no home dir. Return
* "{Windows Drive}:/users/default".
*/
@@ -1487,20 +1279,20 @@ TclpGetUserHome(
}
if (result == NULL) {
/*
- * Look in the "Password Lists" section of system.ini for the local
- * user. There are also entries in that section that begin with a "*"
- * character that are used by Windows for other purposes; ignore user
- * names beginning with a "*".
+ * Look in the "Password Lists" section of system.ini for the
+ * local user. There are also entries in that section that begin
+ * with a "*" character that are used by Windows for other
+ * purposes; ignore user names beginning with a "*".
*/
char buf[MAX_PATH];
if (name[0] != '*') {
- if (GetPrivateProfileStringA("Password Lists", name, "", buf,
+ if (GetPrivateProfileStringA("Password Lists", name, "", buf,
MAX_PATH, "system.ini") > 0) {
- /*
- * User exists, but there is no such thing as a home directory
- * in system.ini. Return "{Windows drive}:/".
+ /*
+ * User exists, but there is no such thing as a home
+ * directory in system.ini. Return "{Windows drive}:/".
*/
GetWindowsDirectoryA(buf, MAX_PATH);
@@ -1520,7 +1312,7 @@ TclpGetUserHome(
*
* This function replaces the library version of access(), fixing the
* following bugs:
- *
+ *
* 1. access() returns that all files have execute permission.
*
* Results:
@@ -1534,7 +1326,7 @@ TclpGetUserHome(
static int
NativeAccess(
- const TCHAR *nativePath, /* Path of file to access, native encoding. */
+ CONST TCHAR *nativePath, /* Path of file to access (UTF-8). */
int mode) /* Permission setting. */
{
DWORD attr;
@@ -1602,7 +1394,8 @@ NativeAccess(
SID_IDENTIFIER_AUTHORITY samba_unmapped = { 0, 0, 0, 0, 0, 22 };
GENERIC_MAPPING genMap;
HANDLE hToken = NULL;
- DWORD desiredAccess = 0, grantedAccess = 0;
+ DWORD desiredAccess = 0;
+ DWORD grantedAccess = 0;
BOOL accessYesNo = FALSE;
PRIVILEGE_SET privSet;
DWORD privSetSize = sizeof(PRIVILEGE_SET);
@@ -1629,12 +1422,12 @@ NativeAccess(
* to EACCES - just what we want!
*/
- TclWinConvertError((DWORD) error);
+ TclWinConvertError((DWORD)error);
return -1;
}
/*
- * Now size contains the size of buffer needed.
+ * Now size contains the size of buffer needed
*/
sdPtr = (SECURITY_DESCRIPTOR *) HeapAlloc(GetProcessHeap(), 0, size);
@@ -1644,7 +1437,7 @@ NativeAccess(
}
/*
- * Call GetFileSecurity() for real.
+ * Call GetFileSecurity() for real
*/
if (!(*tclWinProcs->getFileSecurityProc)(nativePath,
@@ -1679,28 +1472,28 @@ NativeAccess(
}
/*
- * Perform security impersonation of the user and open the resulting
- * thread token.
+ * Perform security impersonation of the user and open the
+ * resulting thread token.
*/
if (!(*tclWinProcs->impersonateSelfProc)(SecurityImpersonation)) {
/*
* Unable to perform security impersonation.
*/
-
+
goto accessError;
}
- if (!(*tclWinProcs->openThreadTokenProc)(GetCurrentThread(),
+ if (!(*tclWinProcs->openThreadTokenProc)(GetCurrentThread (),
TOKEN_DUPLICATE | TOKEN_QUERY, FALSE, &hToken)) {
/*
* Unable to get current thread's token.
*/
-
+
goto accessError;
}
-
+
(*tclWinProcs->revertToSelfProc)();
-
+
/*
* Setup desiredAccess according to the access priveleges we are
* checking.
@@ -1716,12 +1509,12 @@ NativeAccess(
desiredAccess |= FILE_GENERIC_EXECUTE;
}
- memset(&genMap, 0x0, sizeof(GENERIC_MAPPING));
+ memset (&genMap, 0x0, sizeof (GENERIC_MAPPING));
genMap.GenericRead = FILE_GENERIC_READ;
genMap.GenericWrite = FILE_GENERIC_WRITE;
genMap.GenericExecute = FILE_GENERIC_EXECUTE;
genMap.GenericAll = FILE_ALL_ACCESS;
-
+
/*
* Perform access check using the token.
*/
@@ -1748,13 +1541,12 @@ NativeAccess(
* Clean up.
*/
- HeapFree(GetProcessHeap(), 0, sdPtr);
+ HeapFree(GetProcessHeap (), 0, sdPtr);
CloseHandle(hToken);
if (!accessYesNo) {
Tcl_SetErrno(EACCES);
return -1;
}
-
}
return 0;
}
@@ -1764,22 +1556,25 @@ NativeAccess(
*
* NativeIsExec --
*
- * Determines if a path is executable. On windows this is simply defined
- * by whether the path ends in any of ".exe", ".com", or ".bat"
+ * Determines if a path is executable. On windows this is
+ * simply defined by whether the path ends in any of ".exe",
+ * ".com", or ".bat"
*
* Results:
* 1 = executable, 0 = not.
*
*----------------------------------------------------------------------
*/
-
static int
-NativeIsExec(
- const TCHAR *nativePath)
+NativeIsExec(nativePath)
+ CONST TCHAR *nativePath;
{
if (tclWinProcs->useWide) {
- const WCHAR *path = (const WCHAR *) nativePath;
- int len = wcslen(path);
+ CONST WCHAR *path;
+ int len;
+
+ path = (CONST WCHAR*)nativePath;
+ len = wcslen(path);
if (len < 5) {
return 0;
@@ -1792,31 +1587,26 @@ NativeIsExec(
/*
* Use wide-char case-insensitive comparison
*/
-
- if ((_wcsicmp(path+len-3, L"exe") == 0)
- || (_wcsicmp(path+len-3, L"com") == 0)
- || (_wcsicmp(path+len-3, L"bat") == 0)) {
+ if ((_wcsicmp(path+len-3,L"exe") == 0)
+ || (_wcsicmp(path+len-3,L"com") == 0)
+ || (_wcsicmp(path+len-3,L"bat") == 0)) {
return 1;
}
} else {
- const char *p;
+ CONST char *p;
- /*
- * We are only looking for pure ascii.
- */
+ /* We are only looking for pure ascii */
- p = strrchr((const char *) nativePath, '.');
+ p = strrchr((CONST char*)nativePath, '.');
if (p != NULL) {
p++;
-
- /*
+ /*
* Note: in the old code, stat considered '.pif' files as
* executable, whereas access did not.
*/
-
- if ((strcasecmp(p, "exe") == 0)
- || (strcasecmp(p, "com") == 0)
- || (strcasecmp(p, "bat") == 0)) {
+ if ((stricmp(p, "exe") == 0)
+ || (stricmp(p, "com") == 0)
+ || (stricmp(p, "bat") == 0)) {
/*
* File that ends with .exe, .com, or .bat is executable.
*/
@@ -1839,31 +1629,28 @@ NativeIsExec(
* See chdir() documentation.
*
* Side effects:
- * See chdir() documentation.
+ * See chdir() documentation.
*
*----------------------------------------------------------------------
*/
-int
-TclpObjChdir(
- Tcl_Obj *pathPtr) /* Path to new working directory. */
+int
+TclpObjChdir(pathPtr)
+ Tcl_Obj *pathPtr; /* Path to new working directory. */
{
int result;
- const TCHAR *nativePath;
+ CONST TCHAR *nativePath;
#ifdef __CYGWIN__
- extern int cygwin_conv_to_posix_path(const char *, char *);
+ extern int cygwin_conv_to_posix_path
+ _ANSI_ARGS_((CONST char *, char *));
char posixPath[MAX_PATH+1];
- const char *path;
+ CONST char *path;
Tcl_DString ds;
#endif /* __CYGWIN__ */
- nativePath = (const TCHAR *) Tcl_FSGetNativePath(pathPtr);
-
+ nativePath = (CONST TCHAR *) Tcl_FSGetNativePath(pathPtr);
#ifdef __CYGWIN__
- /*
- * Cygwin chdir only groks POSIX path.
- */
-
+ /* Cygwin chdir only groks POSIX path. */
path = Tcl_WinTCharToUtf(nativePath, -1, &ds);
cygwin_conv_to_posix_path(path, posixPath);
result = (chdir(posixPath) == 0 ? 1 : 0);
@@ -1885,26 +1672,26 @@ TclpObjChdir(
*
* TclpReadlink --
*
- * This function replaces the library version of readlink().
+ * This function replaces the library version of readlink().
*
* Results:
- * The result is a pointer to a string specifying the contents of the
- * symbolic link given by 'path', or NULL if the symbolic link could not
- * be read. Storage for the result string is allocated in bufferPtr; the
- * caller must call Tcl_DStringFree() when the result is no longer
- * needed.
+ * The result is a pointer to a string specifying the contents
+ * of the symbolic link given by 'path', or NULL if the symbolic
+ * link could not be read. Storage for the result string is
+ * allocated in bufferPtr; the caller must call Tcl_DStringFree()
+ * when the result is no longer needed.
*
* Side effects:
- * See readlink() documentation.
+ * See readlink() documentation.
*
*---------------------------------------------------------------------------
*/
char *
-TclpReadlink(
- const char *path, /* Path of file to readlink (UTF-8). */
- Tcl_DString *linkPtr) /* Uninitialized or free DString filled with
- * contents of link (UTF-8). */
+TclpReadlink(path, linkPtr)
+ CONST char *path; /* Path of file to readlink (UTF-8). */
+ Tcl_DString *linkPtr; /* Uninitialized or free DString filled
+ * with contents of link (UTF-8). */
{
char link[MAXPATHLEN];
int length;
@@ -1912,9 +1699,9 @@ TclpReadlink(
Tcl_DString ds;
native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
- length = readlink(native, link, sizeof(link)); /* INTL: Native. */
+ length = readlink(native, link, sizeof(link)); /* INTL: Native. */
Tcl_DStringFree(&ds);
-
+
if (length < 0) {
return NULL;
}
@@ -1929,16 +1716,15 @@ TclpReadlink(
*
* TclpGetCwd --
*
- * This function replaces the library version of getcwd(). (Obsolete
- * function, only retained for old extensions which may call it
- * directly).
+ * This function replaces the library version of getcwd().
*
* Results:
- * The result is a pointer to a string specifying the current directory,
- * or NULL if the current directory could not be determined. If NULL is
- * returned, an error message is left in the interp's result. Storage for
- * the result string is allocated in bufferPtr; the caller must call
- * Tcl_DStringFree() when the result is no longer needed.
+ * The result is a pointer to a string specifying the current
+ * directory, or NULL if the current directory could not be
+ * determined. If NULL is returned, an error message is left in the
+ * interp's result. Storage for the result string is allocated in
+ * bufferPtr; the caller must call Tcl_DStringFree() when the result
+ * is no longer needed.
*
* Side effects:
* None.
@@ -1946,11 +1732,11 @@ TclpReadlink(
*----------------------------------------------------------------------
*/
-const char *
-TclpGetCwd(
- Tcl_Interp *interp, /* If non-NULL, used for error reporting. */
- Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with
- * name of current directory. */
+CONST char *
+TclpGetCwd(interp, bufferPtr)
+ Tcl_Interp *interp; /* If non-NULL, used for error reporting. */
+ Tcl_DString *bufferPtr; /* Uninitialized or free DString filled
+ * with name of current directory. */
{
WCHAR buffer[MAX_PATH];
char *p;
@@ -1958,8 +1744,9 @@ TclpGetCwd(
if ((*tclWinProcs->getCurrentDirectoryProc)(MAX_PATH, buffer) == 0) {
TclWinConvertError(GetLastError());
if (interp != NULL) {
- Tcl_AppendResult(interp, "error getting working directory name: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_AppendResult(interp,
+ "error getting working directory name: ",
+ Tcl_PosixError(interp), (char *) NULL);
}
return NULL;
}
@@ -1972,7 +1759,7 @@ TclpGetCwd(
WCHAR *native;
native = (WCHAR *) buffer;
- if ((native[0] != '\0') && (native[1] == ':')
+ if ((native[0] != '\0') && (native[1] == ':')
&& (native[2] == '\\') && (native[3] == '\\')) {
native += 2;
}
@@ -1981,7 +1768,7 @@ TclpGetCwd(
char *native;
native = (char *) buffer;
- if ((native[0] != '\0') && (native[1] == ':')
+ if ((native[0] != '\0') && (native[1] == ':')
&& (native[2] == '\\') && (native[3] == '\\')) {
native += 2;
}
@@ -1991,7 +1778,7 @@ TclpGetCwd(
/*
* Convert to forward slashes for easier use in scripts.
*/
-
+
for (p = Tcl_DStringValue(bufferPtr); *p != '\0'; p++) {
if (*p == '\\') {
*p = '/';
@@ -2000,21 +1787,38 @@ TclpGetCwd(
return Tcl_DStringValue(bufferPtr);
}
-int
-TclpObjStat(
- Tcl_Obj *pathPtr, /* Path of file to stat. */
- Tcl_StatBuf *statPtr) /* Filled with results of stat call. */
+int
+TclpObjStat(pathPtr, statPtr)
+ Tcl_Obj *pathPtr; /* Path of file to stat */
+ Tcl_StatBuf *statPtr; /* Filled with results of stat call. */
{
+#ifdef OLD_API
+ Tcl_Obj *transPtr;
/*
- * Ensure correct file sizes by forcing the OS to write any pending data
- * to disk. This is done only for channels which are dirty, i.e. have been
- * written to since the last flush here.
+ * Eliminate file names containing wildcard characters, or subsequent
+ * call to FindFirstFile() will expand them, matching some other file.
*/
- TclWinFlushDirtyChannels();
+ transPtr = Tcl_FSGetTranslatedPath(NULL, pathPtr);
+ if (transPtr == NULL || (strpbrk(Tcl_GetString(transPtr), "?*") != NULL)) {
+ if (transPtr != NULL) {
+ Tcl_DecrRefCount(transPtr);
+ }
+ Tcl_SetErrno(ENOENT);
+ return -1;
+ }
+ Tcl_DecrRefCount(transPtr);
+#endif
+
+ /*
+ * Ensure correct file sizes by forcing the OS to write any
+ * pending data to disk. This is done only for channels which are
+ * dirty, i.e. have been written to since the last flush here.
+ */
- return NativeStat((const TCHAR *) Tcl_FSGetNativePath(pathPtr),
- statPtr, 0);
+ TclWinFlushDirtyChannels ();
+
+ return NativeStat((CONST TCHAR*) Tcl_FSGetNativePath(pathPtr), statPtr, 0);
}
/*
@@ -2022,8 +1826,8 @@ TclpObjStat(
*
* NativeStat --
*
- * This function replaces the library version of stat(), fixing the
- * following bugs:
+ * This function replaces the library version of stat(), fixing
+ * the following bugs:
*
* 1. stat("c:") returns an error.
* 2. Borland stat() return time in GMT instead of localtime.
@@ -2040,97 +1844,31 @@ TclpObjStat(
*----------------------------------------------------------------------
*/
-static int
-NativeStat(
- const TCHAR *nativePath, /* Path of file to stat */
- Tcl_StatBuf *statPtr, /* Filled with results of stat call. */
- int checkLinks) /* If non-zero, behave like 'lstat' */
+static int
+NativeStat(nativePath, statPtr, checkLinks)
+ CONST TCHAR *nativePath; /* Path of file to stat */
+ Tcl_StatBuf *statPtr; /* Filled with results of stat call. */
+ int checkLinks; /* If non-zero, behave like 'lstat' */
{
+ Tcl_DString ds;
DWORD attr;
- int dev, nlink = 1;
+ WCHAR nativeFullPath[MAX_PATH];
+ TCHAR *nativePart;
+ CONST char *fullPath;
+ int dev;
unsigned short mode;
- unsigned int inode = 0;
- HANDLE fileHandle;
-
- /*
- * If we can use 'createFile' on this, then we can use the resulting
- * fileHandle to read more information (nlink, ino) than we can get from
- * other attributes reading APIs. If not, then we try to fall back on the
- * 'getFileAttributesExProc', and if that isn't available, then on even
- * simpler routines.
- */
-
- fileHandle = (tclWinProcs->createFileProc)(nativePath, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
-
- if (fileHandle != INVALID_HANDLE_VALUE) {
- BY_HANDLE_FILE_INFORMATION data;
-
- if (GetFileInformationByHandle(fileHandle,&data) != TRUE) {
- CloseHandle(fileHandle);
- Tcl_SetErrno(ENOENT);
- return -1;
- }
- CloseHandle(fileHandle);
-
- attr = data.dwFileAttributes;
-
- statPtr->st_size = ((Tcl_WideInt) data.nFileSizeLow) |
- (((Tcl_WideInt) data.nFileSizeHigh) << 32);
- statPtr->st_atime = ToCTime(data.ftLastAccessTime);
- statPtr->st_mtime = ToCTime(data.ftLastWriteTime);
- statPtr->st_ctime = ToCTime(data.ftCreationTime);
-
- /*
- * On Unix, for directories, nlink apparently depends on the number of
- * files in the directory. We could calculate that, but it would be a
- * bit of a performance penalty, I think. Hence we just use what
- * Windows gives us, which is the same as Unix for files, at least.
- */
-
- nlink = data.nNumberOfLinks;
-
- /*
- * Unfortunately our stat definition's inode field (unsigned short)
- * will throw away most of the precision we have here, which means we
- * can't rely on inode as a unique identifier of a file. We'd really
- * like to do something like how we handle 'st_size'.
- */
-
- inode = data.nFileIndexHigh | data.nFileIndexLow;
- } else if (tclWinProcs->getFileAttributesExProc != NULL) {
- /*
- * Fall back on the less capable routines. This means no nlink or ino.
- */
-
- WIN32_FILE_ATTRIBUTE_DATA data;
-
- if ((*tclWinProcs->getFileAttributesExProc)(nativePath,
- GetFileExInfoStandard, &data) != TRUE) {
- Tcl_SetErrno(ENOENT);
- return -1;
- }
-
- attr = data.dwFileAttributes;
-
- statPtr->st_size = ((Tcl_WideInt) data.nFileSizeLow) |
- (((Tcl_WideInt) data.nFileSizeHigh) << 32);
- statPtr->st_atime = ToCTime(data.ftLastAccessTime);
- statPtr->st_mtime = ToCTime(data.ftLastWriteTime);
- statPtr->st_ctime = ToCTime(data.ftCreationTime);
- } else {
- /*
- * We don't have the faster attributes proc, so we're probably running
- * on Win95.
- */
-
+
+ if (tclWinProcs->getFileAttributesExProc == NULL) {
+ /*
+ * We don't have the faster attributes proc, so we're
+ * probably running on Win95
+ */
WIN32_FIND_DATAT data;
HANDLE handle;
handle = (*tclWinProcs->findFirstFileProc)(nativePath, &data);
if (handle == INVALID_HANDLE_VALUE) {
- /*
+ /*
* FindFirstFile() doesn't work on root directories, so call
* GetFileAttributes() to see if the specified file exists.
*/
@@ -2141,9 +1879,9 @@ NativeStat(
return -1;
}
- /*
- * Make up some fake information for this file. It has the correct
- * file attributes and a time of 0.
+ /*
+ * Make up some fake information for this file. It has the
+ * correct file attributes and a time of 0.
*/
memset(&data, 0, sizeof(data));
@@ -2152,95 +1890,131 @@ NativeStat(
FindClose(handle);
}
+
+ (*tclWinProcs->getFullPathNameProc)(nativePath, MAX_PATH, nativeFullPath,
+ &nativePart);
+
+ fullPath = Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds);
+
+ dev = -1;
+ if ((fullPath[0] == '\\') && (fullPath[1] == '\\')) {
+ CONST char *p;
+ DWORD dw;
+ CONST TCHAR *nativeVol;
+ Tcl_DString volString;
+
+ p = strchr(fullPath + 2, '\\');
+ p = strchr(p + 1, '\\');
+ if (p == NULL) {
+ /*
+ * Add terminating backslash to fullpath or
+ * GetVolumeInformation() won't work.
+ */
+
+ fullPath = Tcl_DStringAppend(&ds, "\\", 1);
+ p = fullPath + Tcl_DStringLength(&ds);
+ } else {
+ p++;
+ }
+ nativeVol = Tcl_WinUtfToTChar(fullPath, p - fullPath, &volString);
+ dw = (DWORD) -1;
+ (*tclWinProcs->getVolumeInformationProc)(nativeVol, NULL, 0, &dw,
+ NULL, NULL, NULL, 0);
+ /*
+ * GetFullPathName() turns special devices like "NUL" into
+ * "\\.\NUL", but GetVolumeInformation() returns failure for
+ * "\\.\NUL". This will cause "NUL" to get a drive number of
+ * -1, which makes about as much sense as anything since the
+ * special devices don't live on any drive.
+ */
+
+ dev = dw;
+ Tcl_DStringFree(&volString);
+ } else if ((fullPath[0] != '\0') && (fullPath[1] == ':')) {
+ dev = Tcl_UniCharToLower(fullPath[0]) - 'a';
+ }
+ Tcl_DStringFree(&ds);
+
attr = data.a.dwFileAttributes;
- statPtr->st_size = ((Tcl_WideInt) data.a.nFileSizeLow) |
- (((Tcl_WideInt) data.a.nFileSizeHigh) << 32);
+ statPtr->st_size = ((Tcl_WideInt)data.a.nFileSizeLow) |
+ (((Tcl_WideInt)data.a.nFileSizeHigh) << 32);
statPtr->st_atime = ToCTime(data.a.ftLastAccessTime);
statPtr->st_mtime = ToCTime(data.a.ftLastWriteTime);
statPtr->st_ctime = ToCTime(data.a.ftCreationTime);
- }
-
- dev = NativeDev(nativePath);
- mode = NativeStatMode(attr, checkLinks, NativeIsExec(nativePath));
-
- statPtr->st_dev = (dev_t) dev;
- statPtr->st_ino = inode;
- statPtr->st_mode = mode;
- statPtr->st_nlink = nlink;
- statPtr->st_uid = 0;
- statPtr->st_gid = 0;
- statPtr->st_rdev = (dev_t) dev;
- return 0;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * NativeDev --
- *
- * Calculate just the 'st_dev' field of a 'stat' structure.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-NativeDev(
- const TCHAR *nativePath) /* Full path of file to stat */
-{
- int dev;
- Tcl_DString ds;
- WCHAR nativeFullPath[MAX_PATH];
- TCHAR *nativePart;
- const char *fullPath;
+ } else {
+ WIN32_FILE_ATTRIBUTE_DATA data;
+ if((*tclWinProcs->getFileAttributesExProc)(nativePath,
+ GetFileExInfoStandard,
+ &data) != TRUE) {
+ Tcl_SetErrno(ENOENT);
+ return -1;
+ }
- (*tclWinProcs->getFullPathNameProc)(nativePath, MAX_PATH,
- nativeFullPath, &nativePart);
+
+ (*tclWinProcs->getFullPathNameProc)(nativePath, MAX_PATH,
+ nativeFullPath, &nativePart);
- fullPath = Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds);
+ fullPath = Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds);
- if ((fullPath[0] == '\\') && (fullPath[1] == '\\')) {
- const char *p;
- DWORD dw;
- const TCHAR *nativeVol;
- Tcl_DString volString;
+ dev = -1;
+ if ((fullPath[0] == '\\') && (fullPath[1] == '\\')) {
+ CONST char *p;
+ DWORD dw;
+ CONST TCHAR *nativeVol;
+ Tcl_DString volString;
+
+ p = strchr(fullPath + 2, '\\');
+ p = strchr(p + 1, '\\');
+ if (p == NULL) {
+ /*
+ * Add terminating backslash to fullpath or
+ * GetVolumeInformation() won't work.
+ */
- p = strchr(fullPath + 2, '\\');
- p = strchr(p + 1, '\\');
- if (p == NULL) {
+ fullPath = Tcl_DStringAppend(&ds, "\\", 1);
+ p = fullPath + Tcl_DStringLength(&ds);
+ } else {
+ p++;
+ }
+ nativeVol = Tcl_WinUtfToTChar(fullPath, p - fullPath, &volString);
+ dw = (DWORD) -1;
+ (*tclWinProcs->getVolumeInformationProc)(nativeVol, NULL, 0, &dw,
+ NULL, NULL, NULL, 0);
/*
- * Add terminating backslash to fullpath or GetVolumeInformation()
- * won't work.
+ * GetFullPathName() turns special devices like "NUL" into
+ * "\\.\NUL", but GetVolumeInformation() returns failure for
+ * "\\.\NUL". This will cause "NUL" to get a drive number of
+ * -1, which makes about as much sense as anything since the
+ * special devices don't live on any drive.
*/
- fullPath = Tcl_DStringAppend(&ds, "\\", 1);
- p = fullPath + Tcl_DStringLength(&ds);
- } else {
- p++;
+ dev = dw;
+ Tcl_DStringFree(&volString);
+ } else if ((fullPath[0] != '\0') && (fullPath[1] == ':')) {
+ dev = Tcl_UniCharToLower(fullPath[0]) - 'a';
}
- nativeVol = Tcl_WinUtfToTChar(fullPath, p - fullPath, &volString);
- dw = (DWORD) -1;
- (*tclWinProcs->getVolumeInformationProc)(nativeVol, NULL, 0, &dw,
- NULL, NULL, NULL, 0);
-
- /*
- * GetFullPathName() turns special devices like "NUL" into "\\.\NUL",
- * but GetVolumeInformation() returns failure for "\\.\NUL". This will
- * cause "NUL" to get a drive number of -1, which makes about as much
- * sense as anything since the special devices don't live on any
- * drive.
- */
-
- dev = dw;
- Tcl_DStringFree(&volString);
- } else if ((fullPath[0] != '\0') && (fullPath[1] == ':')) {
- dev = Tcl_UniCharToLower(fullPath[0]) - 'a';
- } else {
- dev = -1;
+ Tcl_DStringFree(&ds);
+
+ attr = data.dwFileAttributes;
+
+ statPtr->st_size = ((Tcl_WideInt)data.nFileSizeLow) |
+ (((Tcl_WideInt)data.nFileSizeHigh) << 32);
+ statPtr->st_atime = ToCTime(data.ftLastAccessTime);
+ statPtr->st_mtime = ToCTime(data.ftLastWriteTime);
+ statPtr->st_ctime = ToCTime(data.ftCreationTime);
}
- Tcl_DStringFree(&ds);
- return dev;
+ mode = NativeStatMode(attr, checkLinks, NativeIsExec(nativePath));
+
+ statPtr->st_dev = (dev_t) dev;
+ statPtr->st_ino = 0;
+ statPtr->st_mode = mode;
+ statPtr->st_nlink = 1;
+ statPtr->st_uid = 0;
+ statPtr->st_gid = 0;
+ statPtr->st_rdev = (dev_t) dev;
+ return 0;
}
/*
@@ -2250,42 +2024,31 @@ NativeDev(
*
* Calculate just the 'st_mode' field of a 'stat' structure.
*
- * In many places we don't need the full stat structure, and it's much
- * faster just to calculate these pieces, if that's all we need.
- *
*----------------------------------------------------------------------
*/
-
static unsigned short
-NativeStatMode(
- DWORD attr,
- int checkLinks,
- int isExec)
+NativeStatMode(DWORD attr, int checkLinks, int isExec)
{
int mode;
-
if (checkLinks && (attr & FILE_ATTRIBUTE_REPARSE_POINT)) {
- /*
- * It is a link.
- */
-
+ /* It is a link */
mode = S_IFLNK;
} else {
- mode = (attr & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR|S_IEXEC : S_IFREG;
+ mode = (attr & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR | S_IEXEC : S_IFREG;
}
- mode |= (attr & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD|S_IWRITE;
+ mode |= (attr & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE;
if (isExec) {
mode |= S_IEXEC;
}
-
+
/*
- * Propagate the S_IREAD, S_IWRITE, S_IEXEC bits to the group and other
- * positions.
+ * Propagate the S_IREAD, S_IWRITE, S_IEXEC bits to the group and
+ * other positions.
*/
mode |= (mode & (S_IREAD|S_IWRITE|S_IEXEC)) >> 3;
mode |= (mode & (S_IREAD|S_IWRITE|S_IEXEC)) >> 6;
- return (unsigned short) mode;
+ return (unsigned short)mode;
}
/*
@@ -2310,8 +2073,8 @@ ToCTime(
convertedTime.LowPart = fileTime.dwLowDateTime;
convertedTime.HighPart = (LONG) fileTime.dwHighDateTime;
- return (time_t) ((convertedTime.QuadPart -
- (Tcl_WideInt) POSIX_EPOCH_AS_FILETIME) / (Tcl_WideInt) 10000000);
+ return (time_t) ((convertedTime.QuadPart
+ - (Tcl_WideInt) POSIX_EPOCH_AS_FILETIME) / (Tcl_WideInt) 10000000);
}
/*
@@ -2330,7 +2093,7 @@ ToCTime(
static void
FromCTime(
time_t posixTime,
- FILETIME *fileTime) /* UTC Time */
+ FILETIME* fileTime) /* UTC Time */
{
LARGE_INTEGER convertedTime;
convertedTime.QuadPart = ((LONGLONG) posixTime) * 10000000
@@ -2339,105 +2102,136 @@ FromCTime(
fileTime->dwHighDateTime = convertedTime.HighPart;
}
+#if 0
/*
- *---------------------------------------------------------------------------
+ *-------------------------------------------------------------------------
*
- * TclpGetNativeCwd --
+ * TclWinResolveShortcut --
*
- * This function replaces the library version of getcwd().
+ * Resolve a potential Windows shortcut to get the actual file or
+ * directory in question.
*
* Results:
- * The input and output are filesystem paths in native form. The result
- * is either the given clientData, if the working directory hasn't
- * changed, or a new clientData (owned by our caller), giving the new
- * native path, or NULL if the current directory could not be determined.
- * If NULL is returned, the caller can examine the standard posix error
- * codes to determine the cause of the problem.
+ * Returns 1 if the shortcut could be resolved, or 0 if there was
+ * an error or if the filename was not a shortcut.
+ * If bufferPtr did hold the name of a shortcut, it is modified to
+ * hold the resolved target of the shortcut instead.
*
* Side effects:
- * None.
+ * Loads and unloads OLE package to determine if filename refers to
+ * a shortcut.
*
- *----------------------------------------------------------------------
+ *-------------------------------------------------------------------------
*/
-ClientData
-TclpGetNativeCwd(
- ClientData clientData)
+int
+TclWinResolveShortcut(bufferPtr)
+ Tcl_DString *bufferPtr; /* Holds name of file to resolve. On
+ * return, holds resolved file name. */
{
- WCHAR buffer[MAX_PATH];
-
- if ((*tclWinProcs->getCurrentDirectoryProc)(MAX_PATH, buffer) == 0) {
- TclWinConvertError(GetLastError());
- return NULL;
- }
-
- if (clientData != NULL) {
- if (tclWinProcs->useWide) {
- /*
- * Unicode representation when running on NT/2K/XP.
- */
+ HRESULT hres;
+ IShellLink *psl;
+ IPersistFile *ppf;
+ WIN32_FIND_DATA wfd;
+ WCHAR wpath[MAX_PATH];
+ char *path, *ext;
+ char realFileName[MAX_PATH];
- if (wcscmp((const WCHAR*)clientData, (const WCHAR*)buffer) == 0) {
- return clientData;
- }
- } else {
- /*
- * ANSI representation when running on 95/98/ME.
- */
+ /*
+ * Windows system calls do not automatically resolve
+ * shortcuts like UNIX automatically will with symbolic links.
+ */
- if (strcmp((const char*) clientData, (const char*) buffer) == 0) {
- return clientData;
- }
- }
+ path = Tcl_DStringValue(bufferPtr);
+ ext = strrchr(path, '.');
+ if ((ext == NULL) || (stricmp(ext, ".lnk") != 0)) {
+ return 0;
}
- return TclNativeDupInternalRep((ClientData) buffer);
+ CoInitialize(NULL);
+ path = Tcl_DStringValue(bufferPtr);
+ realFileName[0] = '\0';
+ hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IShellLink, &psl);
+ if (SUCCEEDED(hres)) {
+ hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, &ppf);
+ if (SUCCEEDED(hres)) {
+ MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, sizeof(wpath));
+ hres = ppf->lpVtbl->Load(ppf, wpath, STGM_READ);
+ if (SUCCEEDED(hres)) {
+ hres = psl->lpVtbl->Resolve(psl, NULL,
+ SLR_ANY_MATCH | SLR_NO_UI);
+ if (SUCCEEDED(hres)) {
+ hres = psl->lpVtbl->GetPath(psl, realFileName, MAX_PATH,
+ &wfd, 0);
+ }
+ }
+ ppf->lpVtbl->Release(ppf);
+ }
+ psl->lpVtbl->Release(psl);
+ }
+ CoUninitialize();
+
+ if (realFileName[0] != '\0') {
+ Tcl_DStringSetLength(bufferPtr, 0);
+ Tcl_DStringAppend(bufferPtr, realFileName, -1);
+ return 1;
+ }
+ return 0;
}
+#endif
-int
-TclpObjAccess(
- Tcl_Obj *pathPtr,
- int mode)
+Tcl_Obj*
+TclpObjGetCwd(interp)
+ Tcl_Interp *interp;
{
- return NativeAccess((const TCHAR *) Tcl_FSGetNativePath(pathPtr), mode);
+ Tcl_DString ds;
+ if (TclpGetCwd(interp, &ds) != NULL) {
+ Tcl_Obj *cwdPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
+ Tcl_IncrRefCount(cwdPtr);
+ Tcl_DStringFree(&ds);
+ return cwdPtr;
+ } else {
+ return NULL;
+ }
}
-
-int
-TclpObjLstat(
- Tcl_Obj *pathPtr,
- Tcl_StatBuf *statPtr)
+
+int
+TclpObjAccess(pathPtr, mode)
+ Tcl_Obj *pathPtr;
+ int mode;
+{
+ return NativeAccess((CONST TCHAR*) Tcl_FSGetNativePath(pathPtr), mode);
+}
+
+int
+TclpObjLstat(pathPtr, statPtr)
+ Tcl_Obj *pathPtr;
+ Tcl_StatBuf *statPtr;
{
/*
- * Ensure correct file sizes by forcing the OS to write any pending data
- * to disk. This is done only for channels which are dirty, i.e. have been
- * written to since the last flush here.
+ * Ensure correct file sizes by forcing the OS to write any
+ * pending data to disk. This is done only for channels which are
+ * dirty, i.e. have been written to since the last flush here.
*/
- TclWinFlushDirtyChannels();
+ TclWinFlushDirtyChannels ();
- return NativeStat((const TCHAR *) Tcl_FSGetNativePath(pathPtr),
- statPtr, 1);
+ return NativeStat((CONST TCHAR*) Tcl_FSGetNativePath(pathPtr), statPtr, 1);
}
-
+
#ifdef S_IFLNK
-Tcl_Obj *
-TclpObjLink(
- Tcl_Obj *pathPtr,
- Tcl_Obj *toPtr,
- int linkAction)
+
+Tcl_Obj*
+TclpObjLink(pathPtr, toPtr, linkAction)
+ Tcl_Obj *pathPtr;
+ Tcl_Obj *toPtr;
+ int linkAction;
{
if (toPtr != NULL) {
int res;
- TCHAR *LinkTarget;
- TCHAR *LinkSource = (TCHAR *) Tcl_FSGetNativePath(pathPtr);
- Tcl_Obj *normalizedToPtr = Tcl_FSGetNormalizedPath(NULL, toPtr);
-
- if (normalizedToPtr == NULL) {
- return NULL;
- }
-
- LinkTarget = (TCHAR *) Tcl_FSGetNativePath(normalizedToPtr);
-
+ TCHAR* LinkTarget = (TCHAR*)Tcl_FSGetNativePath(toPtr);
+ TCHAR* LinkSource = (TCHAR*)Tcl_FSGetNativePath(pathPtr);
if (LinkSource == NULL || LinkTarget == NULL) {
return NULL;
}
@@ -2448,65 +2242,60 @@ TclpObjLink(
return NULL;
}
} else {
- TCHAR *LinkSource = (TCHAR *) Tcl_FSGetNativePath(pathPtr);
-
+ TCHAR* LinkSource = (TCHAR*)Tcl_FSGetNativePath(pathPtr);
if (LinkSource == NULL) {
return NULL;
}
return WinReadLink(LinkSource);
}
}
+
#endif
+
/*
*---------------------------------------------------------------------------
*
* TclpFilesystemPathType --
*
- * This function is part of the native filesystem support, and returns
- * the path type of the given path. Returns NTFS or FAT or whatever is
- * returned by the 'volume information' proc.
+ * This function is part of the native filesystem support, and
+ * returns the path type of the given path. Returns NTFS or FAT
+ * or whatever is returned by the 'volume information' proc.
*
* Results:
- * NULL at present.
+ * NULL at present.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
-
-Tcl_Obj *
-TclpFilesystemPathType(
- Tcl_Obj *pathPtr)
+Tcl_Obj*
+TclpFilesystemPathType(pathObjPtr)
+ Tcl_Obj* pathObjPtr;
{
#define VOL_BUF_SIZE 32
int found;
WCHAR volType[VOL_BUF_SIZE];
- char *firstSeparator;
- const char *path;
- Tcl_Obj *normPath = Tcl_FSGetNormalizedPath(NULL, pathPtr);
-
- if (normPath == NULL) {
- return NULL;
- }
+ char* firstSeparator;
+ CONST char *path;
+
+ Tcl_Obj *normPath = Tcl_FSGetNormalizedPath(NULL, pathObjPtr);
+ if (normPath == NULL) return NULL;
path = Tcl_GetString(normPath);
- if (path == NULL) {
- return NULL;
- }
-
+ if (path == NULL) return NULL;
+
firstSeparator = strchr(path, '/');
if (firstSeparator == NULL) {
found = tclWinProcs->getVolumeInformationProc(
- Tcl_FSGetNativePath(pathPtr), NULL, 0, NULL, NULL, NULL,
- (WCHAR *) volType, VOL_BUF_SIZE);
+ Tcl_FSGetNativePath(pathObjPtr), NULL, 0, NULL, NULL,
+ NULL, (WCHAR *)volType, VOL_BUF_SIZE);
} else {
Tcl_Obj *driveName = Tcl_NewStringObj(path, firstSeparator - path+1);
-
Tcl_IncrRefCount(driveName);
found = tclWinProcs->getVolumeInformationProc(
- Tcl_FSGetNativePath(driveName), NULL, 0, NULL, NULL, NULL,
- (WCHAR *) volType, VOL_BUF_SIZE);
+ Tcl_FSGetNativePath(driveName), NULL, 0, NULL, NULL,
+ NULL, (WCHAR *)volType, VOL_BUF_SIZE);
Tcl_DecrRefCount(driveName);
}
@@ -2515,118 +2304,91 @@ TclpFilesystemPathType(
} else {
Tcl_DString ds;
Tcl_Obj *objPtr;
-
- Tcl_WinTCharToUtf((const char *) volType, -1, &ds);
- objPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds),
- Tcl_DStringLength(&ds));
+
+ Tcl_WinTCharToUtf((CONST char *)volType, -1, &ds);
+ objPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));
Tcl_DStringFree(&ds);
return objPtr;
}
#undef VOL_BUF_SIZE
}
-
-/*
- * This define can be turned on to experiment with a different way of
- * normalizing paths (using a different Windows API). Unfortunately the new
- * path seems to take almost exactly the same amount of time as the old path!
- * The primary time taken by normalization is in
- * GetFileAttributesEx/FindFirstFile or GetFileAttributesEx/GetLongPathName.
- * Conversion to/from native is not a significant factor at all.
- *
- * Also, since we have to check for symbolic links (reparse points) then we
- * have to call GetFileAttributes on each path segment anyway, so there's no
- * benefit to doing anything clever there.
- */
-/* #define TclNORM_LONG_PATH */
/*
*---------------------------------------------------------------------------
*
* TclpObjNormalizePath --
*
- * This function scans through a path specification and replaces it, in
- * place, with a normalized version. This means using the 'longname', and
- * expanding any symbolic links contained within the path.
+ * This function scans through a path specification and replaces it,
+ * in place, with a normalized version. This means using the
+ * 'longname', and expanding any symbolic links contained within the
+ * path.
*
* Results:
- * The new 'nextCheckpoint' value, giving as far as we could understand
- * in the path.
+ * The new 'nextCheckpoint' value, giving as far as we could
+ * understand in the path.
*
* Side effects:
- * The pathPtr string, which must contain a valid path, is possibly
- * modified in place.
+ * The pathPtr string, which must contain a valid path, is
+ * possibly modified in place.
*
*---------------------------------------------------------------------------
*/
int
-TclpObjNormalizePath(
- Tcl_Interp *interp,
- Tcl_Obj *pathPtr,
- int nextCheckpoint)
+TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)
+ Tcl_Interp *interp;
+ Tcl_Obj *pathPtr;
+ int nextCheckpoint;
{
char *lastValidPathEnd = NULL;
- Tcl_DString dsNorm; /* This will hold the normalized string. */
- char *path, *currentPathEndPosition;
+ /* This will hold the normalized string */
+ Tcl_DString dsNorm;
+ char *path;
+ char *currentPathEndPosition;
Tcl_Obj *temp = NULL;
Tcl_DStringInit(&dsNorm);
path = Tcl_GetString(pathPtr);
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_WINDOWS) {
- /*
- * We're on Win95, 98 or ME. There are two assumptions in this block
- * of code. First that the native (NULL) encoding is basically ascii,
- * and second that symbolic links are not possible. Both of these
- * assumptions appear to be true of these operating systems.
+ /*
+ * We're on Win95, 98 or ME. There are two assumptions
+ * in this block of code. First that the native (NULL)
+ * encoding is basically ascii, and second that symbolic
+ * links are not possible. Both of these assumptions
+ * appear to be true of these operating systems.
*/
-
int isDrive = 1;
Tcl_DString ds;
currentPathEndPosition = path + nextCheckpoint;
- if (*currentPathEndPosition == '/') {
+ if (*currentPathEndPosition == '/') {
currentPathEndPosition++;
- }
-
+ }
while (1) {
char cur = *currentPathEndPosition;
+ if ((cur == '/' || cur == 0) && (path != currentPathEndPosition)) {
+ /* Reached directory separator, or end of string */
+ CONST char *nativePath = Tcl_UtfToExternalDString(NULL, path,
+ currentPathEndPosition - path, &ds);
- if ((cur=='/' || cur==0) && (path != currentPathEndPosition)) {
/*
- * Reached directory separator, or end of string.
+ * Now we convert the tail of the current path to its
+ * 'long form', and append it to 'dsNorm' which holds
+ * the current normalized path, if the file exists.
*/
-
- const char *nativePath = Tcl_UtfToExternalDString(NULL, path,
- currentPathEndPosition - path, &ds);
-
- /*
- * Now we convert the tail of the current path to its 'long
- * form', and append it to 'dsNorm' which holds the current
- * normalized path, if the file exists.
- */
-
if (isDrive) {
- if (GetFileAttributesA(nativePath)
- == INVALID_FILE_ATTRIBUTES) {
- /*
- * File doesn't exist.
- */
-
+ if (GetFileAttributesA(nativePath) == INVALID_FILE_ATTRIBUTES) {
+ /* File doesn't exist */
if (isDrive) {
int len = WinIsReserved(path);
-
if (len > 0) {
- /*
- * Actually it does exist - COM1, etc.
- */
-
+ /* Actually it does exist - COM1, etc */
int i;
-
- for (i=0 ; i<len ; i++) {
+ for (i=0;i<len;i++) {
if (nativePath[i] >= 'a') {
- ((char *) nativePath)[i] -= ('a'-'A');
+ ((char*)nativePath)[i] -= ('a' - 'A');
}
}
Tcl_DStringAppend(&dsNorm, nativePath, len);
@@ -2637,74 +2399,33 @@ TclpObjNormalizePath(
break;
}
if (nativePath[0] >= 'a') {
- ((char *) nativePath)[0] -= ('a' - 'A');
+ ((char*)nativePath)[0] -= ('a' - 'A');
}
- Tcl_DStringAppend(&dsNorm, nativePath,
- Tcl_DStringLength(&ds));
+ Tcl_DStringAppend(&dsNorm,nativePath,Tcl_DStringLength(&ds));
} else {
- char *checkDots = NULL;
-
- if (lastValidPathEnd[1] == '.') {
- checkDots = lastValidPathEnd + 1;
- while (checkDots < currentPathEndPosition) {
- if (*checkDots != '.') {
- checkDots = NULL;
- break;
- }
- checkDots++;
+ WIN32_FIND_DATA fData;
+ HANDLE handle;
+
+ handle = FindFirstFileA(nativePath, &fData);
+ if (handle == INVALID_HANDLE_VALUE) {
+ if (GetFileAttributesA(nativePath)
+ == INVALID_FILE_ATTRIBUTES) {
+ /* File doesn't exist */
+ Tcl_DStringFree(&ds);
+ break;
}
- }
- if (checkDots != NULL) {
- int dotLen = currentPathEndPosition-lastValidPathEnd;
-
- /*
- * Path is just dots. We shouldn't really ever see a
- * path like that. However, to be nice we at least
- * don't mangle the path - we just add the dots as a
- * path segment and continue
- */
-
- Tcl_DStringAppend(&dsNorm, (TCHAR *)
- (nativePath + Tcl_DStringLength(&ds)-dotLen),
- dotLen);
+ /* This is usually the '/' in 'c:/' at end of string */
+ Tcl_DStringAppend(&dsNorm,"/", 1);
} else {
- /*
- * Normal path.
- */
-
- WIN32_FIND_DATA fData;
- HANDLE handle;
-
- handle = FindFirstFileA(nativePath, &fData);
- if (handle == INVALID_HANDLE_VALUE) {
- if (GetFileAttributesA(nativePath)
- == INVALID_FILE_ATTRIBUTES) {
- /*
- * File doesn't exist.
- */
-
- Tcl_DStringFree(&ds);
- break;
- }
-
- /*
- * This is usually the '/' in 'c:/' at end of
- * string.
- */
-
- Tcl_DStringAppend(&dsNorm,"/", 1);
+ char *nativeName;
+ if (fData.cFileName[0] != '\0') {
+ nativeName = fData.cFileName;
} else {
- char *nativeName;
-
- if (fData.cFileName[0] != '\0') {
- nativeName = fData.cFileName;
- } else {
- nativeName = fData.cAlternateFileName;
- }
- FindClose(handle);
- Tcl_DStringAppend(&dsNorm,"/", 1);
- Tcl_DStringAppend(&dsNorm,nativeName,-1);
+ nativeName = fData.cAlternateFileName;
}
+ FindClose(handle);
+ Tcl_DStringAppend(&dsNorm,"/", 1);
+ Tcl_DStringAppend(&dsNorm,nativeName,-1);
}
}
Tcl_DStringFree(&ds);
@@ -2712,21 +2433,16 @@ TclpObjNormalizePath(
if (cur == 0) {
break;
}
-
- /*
- * If we get here, we've got past one directory delimiter, so
- * we know it is no longer a drive.
+ /*
+ * If we get here, we've got past one directory
+ * delimiter, so we know it is no longer a drive
*/
-
isDrive = 0;
}
currentPathEndPosition++;
}
} else {
- /*
- * We're on WinNT (or 2000 or XP; something with an NT core).
- */
-
+ /* We're on WinNT or 2000 or XP */
int isDrive = 1;
Tcl_DString ds;
@@ -2736,42 +2452,28 @@ TclpObjNormalizePath(
}
while (1) {
char cur = *currentPathEndPosition;
-
- if ((cur=='/' || cur==0) && (path != currentPathEndPosition)) {
- /*
- * Reached directory separator, or end of string.
- */
-
+ if ((cur == '/' || cur == 0) && (path != currentPathEndPosition)) {
+ /* Reached directory separator, or end of string */
WIN32_FILE_ATTRIBUTE_DATA data;
- const char *nativePath = Tcl_WinUtfToTChar(path,
- currentPathEndPosition - path, &ds);
-
+ CONST char *nativePath = Tcl_WinUtfToTChar(path,
+ currentPathEndPosition - path, &ds);
if ((*tclWinProcs->getFileAttributesExProc)(nativePath,
- GetFileExInfoStandard, &data) != TRUE) {
- /*
- * File doesn't exist.
- */
-
+ GetFileExInfoStandard, &data) != TRUE) {
+ /* File doesn't exist */
if (isDrive) {
int len = WinIsReserved(path);
-
if (len > 0) {
- /*
- * Actually it does exist - COM1, etc.
- */
-
+ /* Actually it does exist - COM1, etc */
int i;
-
- for (i=0 ; i<len ; i++) {
- WCHAR wc = ((WCHAR *) nativePath)[i];
-
+ for (i=0;i<len;i++) {
+ WCHAR wc = ((WCHAR*)nativePath)[i];
if (wc >= L'a') {
wc -= (L'a' - L'A');
- ((WCHAR *) nativePath)[i] = wc;
+ ((WCHAR*)nativePath)[i] = wc;
}
}
Tcl_DStringAppend(&dsNorm, nativePath,
- (int)(sizeof(WCHAR) * len));
+ sizeof(WCHAR)*len);
lastValidPathEnd = currentPathEndPosition;
}
}
@@ -2779,46 +2481,31 @@ TclpObjNormalizePath(
break;
}
- /*
- * File 'nativePath' does exist if we get here. We now want to
- * check if it is a symlink and otherwise continue with the
- * rest of the path.
+ /*
+ * File 'nativePath' does exist if we get here. We
+ * now want to check if it is a symlink and otherwise
+ * continue with the rest of the path.
*/
-
- /*
- * Check for symlinks, except at last component of path (we
- * don't follow final symlinks). Also a drive (C:/) for
- * example, may sometimes have the reparse flag set for some
- * reason I don't understand. We therefore don't perform this
+
+ /*
+ * Check for symlinks, except at last component
+ * of path (we don't follow final symlinks). Also
+ * a drive (C:/) for example, may sometimes have
+ * the reparse flag set for some reason I don't
+ * understand. We therefore don't perform this
* check for drives.
*/
-
- if (cur != 0 && !isDrive &&
- data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT){
+ if (cur != 0 && !isDrive && (data.dwFileAttributes
+ & FILE_ATTRIBUTE_REPARSE_POINT)) {
Tcl_Obj *to = WinReadLinkDirectory(nativePath);
-
if (to != NULL) {
- /*
- * Read the reparse point ok. Now, reparse points need
- * not be normalized, otherwise we could use:
- *
- * Tcl_GetStringFromObj(to, &pathLen);
- * nextCheckpoint = pathLen
- *
- * So, instead we have to start from the beginning.
- */
-
- nextCheckpoint = 0;
+ /* Read the reparse point ok */
+ /* Tcl_GetStringFromObj(to, &pathLen); */
+ nextCheckpoint = 0; /* pathLen */
Tcl_AppendToObj(to, currentPathEndPosition, -1);
-
- /*
- * Convert link to forward slashes.
- */
-
+ /* Convert link to forward slashes */
for (path = Tcl_GetString(to); *path != 0; path++) {
- if (*path == '\\') {
- *path = '/';
- }
+ if (*path == '\\') *path = '/';
}
path = Tcl_GetString(to);
currentPathEndPosition = path + nextCheckpoint;
@@ -2826,11 +2513,7 @@ TclpObjNormalizePath(
Tcl_DecrRefCount(temp);
}
temp = to;
-
- /*
- * Reset variables so we can restart normalization.
- */
-
+ /* Reset variables so we can restart normalization */
isDrive = 1;
Tcl_DStringFree(&dsNorm);
Tcl_DStringInit(&dsNorm);
@@ -2838,25 +2521,21 @@ TclpObjNormalizePath(
continue;
}
}
-
-#ifndef TclNORM_LONG_PATH
/*
- * Now we convert the tail of the current path to its 'long
- * form', and append it to 'dsNorm' which holds the current
- * normalized path
+ * Now we convert the tail of the current path to its
+ * 'long form', and append it to 'dsNorm' which holds
+ * the current normalized path
*/
-
if (isDrive) {
- WCHAR drive = ((WCHAR *) nativePath)[0];
+ WCHAR drive = ((WCHAR*)nativePath)[0];
if (drive >= L'a') {
- drive -= (L'a' - L'A');
- ((WCHAR *) nativePath)[0] = drive;
+ drive -= (L'a' - L'A');
+ ((WCHAR*)nativePath)[0] = drive;
}
- Tcl_DStringAppend(&dsNorm, nativePath,
- Tcl_DStringLength(&ds));
+ Tcl_DStringAppend(&dsNorm,nativePath,Tcl_DStringLength(&ds));
} else {
char *checkDots = NULL;
-
+
if (lastValidPathEnd[1] == '.') {
checkDots = lastValidPathEnd + 1;
while (checkDots < currentPathEndPosition) {
@@ -2868,132 +2547,86 @@ TclpObjNormalizePath(
}
}
if (checkDots != NULL) {
- int dotLen = currentPathEndPosition-lastValidPathEnd;
-
- /*
- * Path is just dots. We shouldn't really ever see a
- * path like that. However, to be nice we at least
- * don't mangle the path - we just add the dots as a
- * path segment and continue.
+ int dotLen = currentPathEndPosition - lastValidPathEnd;
+ /*
+ * Path is just dots. We shouldn't really
+ * ever see a path like that. However, to be
+ * nice we at least don't mangle the path --
+ * we just add the dots as a path segment and
+ * continue
*/
-
- Tcl_DStringAppend(&dsNorm, (TCHAR *)
- ((WCHAR*)(nativePath + Tcl_DStringLength(&ds))
- - dotLen), (int)(dotLen * sizeof(WCHAR)));
+ Tcl_DStringAppend(&dsNorm,
+ (TCHAR*)((WCHAR*)(nativePath
+ + Tcl_DStringLength(&ds))
+ - dotLen),
+ (int)(dotLen * sizeof(WCHAR)));
} else {
- /*
- * Normal path.
- */
-
+ /* Normal path */
WIN32_FIND_DATAW fData;
HANDLE handle;
-
- handle = FindFirstFileW((WCHAR *) nativePath, &fData);
+
+ handle = FindFirstFileW((WCHAR*)nativePath, &fData);
if (handle == INVALID_HANDLE_VALUE) {
- /*
- * This is usually the '/' in 'c:/' at end of
- * string.
- */
-
- Tcl_DStringAppend(&dsNorm, (const char *) L"/",
- sizeof(WCHAR));
+ /* This is usually the '/' in 'c:/' at end of string */
+ Tcl_DStringAppend(&dsNorm,(CONST char*)L"/",
+ sizeof(WCHAR));
} else {
WCHAR *nativeName;
-
if (fData.cFileName[0] != '\0') {
nativeName = fData.cFileName;
} else {
nativeName = fData.cAlternateFileName;
}
FindClose(handle);
- Tcl_DStringAppend(&dsNorm, (const char *) L"/",
- sizeof(WCHAR));
- Tcl_DStringAppend(&dsNorm, (TCHAR *) nativeName,
- (int) (wcslen(nativeName)*sizeof(WCHAR)));
+ Tcl_DStringAppend(&dsNorm,(CONST char*)L"/",
+ sizeof(WCHAR));
+ Tcl_DStringAppend(&dsNorm,(TCHAR*)nativeName,
+ (int) (wcslen(nativeName)*sizeof(WCHAR)));
}
}
}
-#endif
Tcl_DStringFree(&ds);
lastValidPathEnd = currentPathEndPosition;
if (cur == 0) {
break;
}
-
- /*
- * If we get here, we've got past one directory delimiter, so
- * we know it is no longer a drive.
+ /*
+ * If we get here, we've got past one directory
+ * delimiter, so we know it is no longer a drive
*/
-
isDrive = 0;
}
currentPathEndPosition++;
}
-
-#ifdef TclNORM_LONG_PATH
- /*
- * Convert the entire known path to long form.
- */
-
- if (1) {
- WCHAR wpath[MAX_PATH];
- const char *nativePath =
- Tcl_WinUtfToTChar(path, lastValidPathEnd - path, &ds);
- DWORD wpathlen = (*tclWinProcs->getLongPathNameProc)(
- nativePath, (TCHAR *) wpath, MAX_PATH);
-
- /*
- * We have to make the drive letter uppercase.
- */
-
- if (wpath[0] >= L'a') {
- wpath[0] -= (L'a' - L'A');
- }
- Tcl_DStringAppend(&dsNorm, (TCHAR*)wpath, wpathlen*sizeof(WCHAR));
- Tcl_DStringFree(&ds);
- }
-#endif
}
-
- /*
- * Common code path for all Windows platforms.
- */
-
+ /* Common code path for all Windows platforms */
nextCheckpoint = currentPathEndPosition - path;
if (lastValidPathEnd != NULL) {
- /*
- * Concatenate the normalized string in dsNorm with the tail of the
- * path which we didn't recognise. The string in dsNorm is in the
- * native encoding, so we have to convert it to Utf.
+ /*
+ * Concatenate the normalized string in dsNorm with the
+ * tail of the path which we didn't recognise. The
+ * string in dsNorm is in the native encoding, so we
+ * have to convert it to Utf.
*/
-
Tcl_DString dsTemp;
-
- Tcl_WinTCharToUtf(Tcl_DStringValue(&dsNorm),
- Tcl_DStringLength(&dsNorm), &dsTemp);
+ Tcl_WinTCharToUtf(Tcl_DStringValue(&dsNorm),
+ Tcl_DStringLength(&dsNorm), &dsTemp);
nextCheckpoint = Tcl_DStringLength(&dsTemp);
if (*lastValidPathEnd != 0) {
- /*
- * Not the end of the string.
- */
-
+ /* Not the end of the string */
int len;
char *path;
Tcl_Obj *tmpPathPtr;
-
- tmpPathPtr = Tcl_NewStringObj(Tcl_DStringValue(&dsTemp),
- nextCheckpoint);
+ tmpPathPtr = Tcl_NewStringObj(Tcl_DStringValue(&dsTemp),
+ nextCheckpoint);
Tcl_AppendToObj(tmpPathPtr, lastValidPathEnd, -1);
path = Tcl_GetStringFromObj(tmpPathPtr, &len);
Tcl_SetStringObj(pathPtr, path, len);
Tcl_DecrRefCount(tmpPathPtr);
} else {
- /*
- * End of string was reached above.
- */
-
+ /* End of string was reached above */
Tcl_SetStringObj(pathPtr, Tcl_DStringValue(&dsTemp),
- nextCheckpoint);
+ nextCheckpoint);
}
Tcl_DStringFree(&dsTemp);
}
@@ -3007,298 +2640,8 @@ TclpObjNormalizePath(
if (temp != NULL) {
Tcl_DecrRefCount(temp);
}
- return nextCheckpoint;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TclWinVolumeRelativeNormalize --
- *
- * Only Windows has volume-relative paths. These paths are rather rare,
- * but it is nice if Tcl can handle them. It is much better if we can
- * handle them here, rather than in the native fs code, because we really
- * need to have a real absolute path just below.
- *
- * We do not let this block compile on non-Windows platforms because the
- * test suite's manual forcing of tclPlatform can otherwise cause this
- * code path to be executed, causing various errors because
- * volume-relative paths really do not exist.
- *
- * Results:
- * A valid normalized path.
- *
- * Side effects:
- * None.
- *
- *---------------------------------------------------------------------------
- */
-
-Tcl_Obj *
-TclWinVolumeRelativeNormalize(
- Tcl_Interp *interp,
- const char *path,
- Tcl_Obj **useThisCwdPtr)
-{
- Tcl_Obj *absolutePath, *useThisCwd;
-
- useThisCwd = Tcl_FSGetCwd(interp);
- if (useThisCwd == NULL) {
- return NULL;
- }
-
- if (path[0] == '/') {
- /*
- * Path of form /foo/bar which is a path in the root directory of the
- * current volume.
- */
-
- const char *drive = Tcl_GetString(useThisCwd);
-
- absolutePath = Tcl_NewStringObj(drive,2);
- Tcl_AppendToObj(absolutePath, path, -1);
- Tcl_IncrRefCount(absolutePath);
- /*
- * We have a refCount on the cwd.
- */
- } else {
- /*
- * Path of form C:foo/bar, but this only makes sense if the cwd is
- * also on drive C.
- */
-
- int cwdLen;
- const char *drive =
- Tcl_GetStringFromObj(useThisCwd, &cwdLen);
- char drive_cur = path[0];
-
- if (drive_cur >= 'a') {
- drive_cur -= ('a' - 'A');
- }
- if (drive[0] == drive_cur) {
- absolutePath = Tcl_DuplicateObj(useThisCwd);
-
- /*
- * We have a refCount on the cwd, which we will release later.
- */
-
- if (drive[cwdLen-1] != '/' && (path[2] != '\0')) {
- /*
- * Only add a trailing '/' if needed, which is if there isn't
- * one already, and if we are going to be adding some more
- * characters.
- */
-
- Tcl_AppendToObj(absolutePath, "/", 1);
- }
- } else {
- Tcl_DecrRefCount(useThisCwd);
- useThisCwd = NULL;
-
- /*
- * The path is not in the current drive, but is volume-relative.
- * The way Tcl 8.3 handles this is that it treats such a path as
- * relative to the root of the drive. We therefore behave the same
- * here. This behaviour is, however, different to that of the
- * windows command-line. If we want to fix this at some point in
- * the future (at the expense of a behaviour change to Tcl), we
- * could use the '_dgetdcwd' Win32 API to get the drive's cwd.
- */
-
- absolutePath = Tcl_NewStringObj(path, 2);
- Tcl_AppendToObj(absolutePath, "/", 1);
- }
- Tcl_IncrRefCount(absolutePath);
- Tcl_AppendToObj(absolutePath, path+2, -1);
- }
- *useThisCwdPtr = useThisCwd;
- return absolutePath;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TclpNativeToNormalized --
- *
- * Convert native format to a normalized path object, with refCount of
- * zero.
- *
- * Currently assumes all native paths are actually normalized already, so
- * if the path given is not normalized this will actually just convert to
- * a valid string path, but not necessarily a normalized one.
- *
- * Results:
- * A valid normalized path.
- *
- * Side effects:
- * None.
- *
- *---------------------------------------------------------------------------
- */
-
-Tcl_Obj *
-TclpNativeToNormalized(
- ClientData clientData)
-{
- Tcl_DString ds;
- Tcl_Obj *objPtr;
- int len;
- char *copy, *p;
-
- Tcl_WinTCharToUtf((const char *) clientData, -1, &ds);
- copy = Tcl_DStringValue(&ds);
- len = Tcl_DStringLength(&ds);
-
- /*
- * Certain native path representations on Windows have this special prefix
- * to indicate that they are to be treated specially. For example
- * extremely long paths, or symlinks.
- */
-
- if (*copy == '\\') {
- if (0 == strncmp(copy,"\\??\\",4)) {
- copy += 4;
- len -= 4;
- } else if (0 == strncmp(copy,"\\\\?\\",4)) {
- copy += 4;
- len -= 4;
- }
- }
-
- /*
- * Ensure we are using forward slashes only.
- */
-
- for (p = copy; *p != '\0'; p++) {
- if (*p == '\\') {
- *p = '/';
- }
- }
-
- objPtr = Tcl_NewStringObj(copy,len);
- Tcl_DStringFree(&ds);
-
- return objPtr;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TclNativeCreateNativeRep --
- *
- * Create a native representation for the given path.
- *
- * Results:
- * The nativePath representation.
- *
- * Side effects:
- * Memory will be allocated. The path may need to be normalized.
- *
- *---------------------------------------------------------------------------
- */
-
-ClientData
-TclNativeCreateNativeRep(
- Tcl_Obj *pathPtr)
-{
- char *nativePathPtr, *str;
- Tcl_DString ds;
- Tcl_Obj *validPathPtr;
- int len;
-
- if (TclFSCwdIsNative()) {
- /*
- * The cwd is native, which means we can use the translated path
- * without worrying about normalization (this will also usually be
- * shorter so the utf-to-external conversion will be somewhat faster).
- */
-
- validPathPtr = Tcl_FSGetTranslatedPath(NULL, pathPtr);
- if (validPathPtr == NULL) {
- return NULL;
- }
- } else {
- /*
- * Make sure the normalized path is set.
- */
-
- validPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr);
- if (validPathPtr == NULL) {
- return NULL;
- }
- Tcl_IncrRefCount(validPathPtr);
- }
-
- str = Tcl_GetStringFromObj(validPathPtr, &len);
- if (str[0] == '/' && str[1] == '/' && str[2] == '?' && str[3] == '/') {
- char *p;
-
- for (p = str; p && *p; ++p) {
- if (*p == '/') {
- *p = '\\';
- }
- }
- }
- Tcl_WinUtfToTChar(str, len, &ds);
- if (tclWinProcs->useWide) {
- len = Tcl_DStringLength(&ds) + sizeof(WCHAR);
- } else {
- len = Tcl_DStringLength(&ds) + sizeof(char);
- }
- Tcl_DecrRefCount(validPathPtr);
- nativePathPtr = ckalloc((unsigned) len);
- memcpy(nativePathPtr, Tcl_DStringValue(&ds), (size_t) len);
-
- Tcl_DStringFree(&ds);
- return (ClientData) nativePathPtr;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TclNativeDupInternalRep --
- *
- * Duplicate the native representation.
- *
- * Results:
- * The copied native representation, or NULL if it is not possible to
- * copy the representation.
- *
- * Side effects:
- * Memory allocation for the copy.
- *
- *---------------------------------------------------------------------------
- */
-
-ClientData
-TclNativeDupInternalRep(
- ClientData clientData)
-{
- char *copy;
- size_t len;
-
- if (clientData == NULL) {
- return NULL;
- }
-
- if (tclWinProcs->useWide) {
- /*
- * Unicode representation when running on NT/2K/XP.
- */
-
- len = sizeof(WCHAR) * (wcslen((const WCHAR *) clientData) + 1);
- } else {
- /*
- * ANSI representation when running on 95/98/ME.
- */
-
- len = sizeof(char) * (strlen((const char *) clientData) + 1);
- }
-
- copy = (char *) ckalloc(len);
- memcpy(copy, clientData, len);
- return (ClientData) copy;
+ return nextCheckpoint;
}
/*
@@ -3325,7 +2668,7 @@ TclpUtime(
{
int res = 0;
HANDLE fileHandle;
- const TCHAR *native;
+ CONST TCHAR *native;
DWORD attr = 0;
DWORD flags = FILE_ATTRIBUTE_NORMAL;
FILETIME lastAccessTime, lastModTime;
@@ -3333,7 +2676,7 @@ TclpUtime(
FromCTime(tval->actime, &lastAccessTime);
FromCTime(tval->modtime, &lastModTime);
- native = (const TCHAR *) Tcl_FSGetNativePath(pathPtr);
+ native = (CONST TCHAR *)Tcl_FSGetNativePath(pathPtr);
attr = (*tclWinProcs->getFileAttributesProc)(native);
@@ -3346,8 +2689,9 @@ TclpUtime(
* savings complications that utime gets wrong.
*/
- fileHandle = (tclWinProcs->createFileProc)(native, FILE_WRITE_ATTRIBUTES,
- 0, NULL, OPEN_EXISTING, flags, NULL);
+ fileHandle = (tclWinProcs->createFileProc) (
+ native, FILE_WRITE_ATTRIBUTES, 0, NULL,
+ OPEN_EXISTING, flags, NULL);
if (fileHandle == INVALID_HANDLE_VALUE ||
!SetFileTime(fileHandle, NULL, &lastAccessTime, &lastModTime)) {
@@ -3359,11 +2703,3 @@ TclpUtime(
}
return res;
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinInit.c b/win/tclWinInit.c
index a1087c9..acaf705 100644
--- a/win/tclWinInit.c
+++ b/win/tclWinInit.c
@@ -1,4 +1,4 @@
-/*
+/*
* tclWinInit.c --
*
* Contains the Windows-specific interpreter initialization functions.
@@ -6,9 +6,6 @@
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 1998-1999 by Scriptics Corporation.
* All rights reserved.
- *
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclWinInt.h"
@@ -17,17 +14,10 @@
#include <lmcons.h>
/*
- * GetUserName() is found in advapi32.dll
- */
-#ifdef _MSC_VER
-# pragma comment(lib, "advapi32.lib")
-#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 can
- * access the interesting slots in a uniform way.
+ * layout is the same. So we overlay our own structure on top of it so we
+ * can access the interesting slots in a uniform way.
*/
typedef struct {
@@ -40,40 +30,40 @@ typedef struct {
*/
#ifndef PROCESSOR_ARCHITECTURE_INTEL
-#define PROCESSOR_ARCHITECTURE_INTEL 0
+#define PROCESSOR_ARCHITECTURE_INTEL 0
#endif
#ifndef PROCESSOR_ARCHITECTURE_MIPS
-#define PROCESSOR_ARCHITECTURE_MIPS 1
+#define PROCESSOR_ARCHITECTURE_MIPS 1
#endif
#ifndef PROCESSOR_ARCHITECTURE_ALPHA
-#define PROCESSOR_ARCHITECTURE_ALPHA 2
+#define PROCESSOR_ARCHITECTURE_ALPHA 2
#endif
#ifndef PROCESSOR_ARCHITECTURE_PPC
-#define PROCESSOR_ARCHITECTURE_PPC 3
+#define PROCESSOR_ARCHITECTURE_PPC 3
#endif
-#ifndef PROCESSOR_ARCHITECTURE_SHX
-#define PROCESSOR_ARCHITECTURE_SHX 4
+#ifndef PROCESSOR_ARCHITECTURE_SHX
+#define PROCESSOR_ARCHITECTURE_SHX 4
#endif
#ifndef PROCESSOR_ARCHITECTURE_ARM
-#define PROCESSOR_ARCHITECTURE_ARM 5
+#define PROCESSOR_ARCHITECTURE_ARM 5
#endif
#ifndef PROCESSOR_ARCHITECTURE_IA64
-#define PROCESSOR_ARCHITECTURE_IA64 6
+#define PROCESSOR_ARCHITECTURE_IA64 6
#endif
#ifndef PROCESSOR_ARCHITECTURE_ALPHA64
-#define PROCESSOR_ARCHITECTURE_ALPHA64 7
+#define PROCESSOR_ARCHITECTURE_ALPHA64 7
#endif
#ifndef PROCESSOR_ARCHITECTURE_MSIL
-#define PROCESSOR_ARCHITECTURE_MSIL 8
+#define PROCESSOR_ARCHITECTURE_MSIL 8
#endif
#ifndef PROCESSOR_ARCHITECTURE_AMD64
-#define PROCESSOR_ARCHITECTURE_AMD64 9
+#define PROCESSOR_ARCHITECTURE_AMD64 9
#endif
#ifndef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
-#define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
+#define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
#endif
#ifndef PROCESSOR_ARCHITECTURE_UNKNOWN
-#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF
+#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF
#endif
/*
@@ -93,15 +83,21 @@ static char* processors[NUMPROCESSORS] = {
"amd64", "ia32_on_win64"
};
+/* Used to store the encoding used for binary files */
+static Tcl_Encoding binaryEncoding = NULL;
+/* Has the basic library path encoding issue been fixed */
+static int libraryPathEncodingFixed = 0;
+
/*
- * The default directory in which the init.tcl file is expected to be found.
+ * The Init script (common to Windows and Unix platforms) is
+ * defined in tkInitScript.h
*/
-static TclInitProcessGlobalValueProc InitializeDefaultLibraryDir;
-static ProcessGlobalValue defaultLibraryDir =
- {0, 0, NULL, NULL, InitializeDefaultLibraryDir, NULL, NULL};
+#include "tclInitScript.h"
static void AppendEnvironment(Tcl_Obj *listPtr, CONST char *lib);
+static void AppendDllPath(Tcl_Obj *listPtr, HMODULE hModule,
+ CONST char *lib);
static int ToUtf(CONST WCHAR *wSrc, char *dst);
/*
@@ -124,18 +120,19 @@ static int ToUtf(CONST WCHAR *wSrc, char *dst);
*/
void
-TclpInitPlatform(void)
+TclpInitPlatform()
{
tclPlatform = TCL_PLATFORM_WINDOWS;
/*
- * The following code stops Windows 3.X and Windows NT 3.51 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.
+ * The following code stops Windows 3.X and Windows NT 3.51 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 4.0, this is a NOOP because the system doesn't
+ * Under 95 and NT 4.0, this is a NOOP because the system doesn't
* automatically put up dialogs when the above operations fail.
*/
@@ -143,9 +140,9 @@ TclpInitPlatform(void)
#ifdef STATIC_BUILD
/*
- * If we are in a statically linked executable, then we need to explicitly
- * initialize the Windows function tables here since DllMain() will not be
- * invoked.
+ * If we are in a statically linked executable, then we need to
+ * explicitly initialize the Windows function tables here since
+ * DllMain() will not be invoked.
*/
TclWinInit(GetModuleHandle(NULL));
@@ -153,64 +150,186 @@ TclpInitPlatform(void)
}
/*
- *-------------------------------------------------------------------------
+ *---------------------------------------------------------------------------
*
* TclpInitLibraryPath --
*
- * This is the fallback routine that sets the library path if the
- * application has not set one by the first time it is needed.
+ * Initialize the library path at startup.
+ *
+ * This call sets the library path to strings in UTF-8. Any
+ * pre-existing library path information is assumed to have been
+ * in the native multibyte encoding.
+ *
+ * Called at process initialization time.
*
* Results:
- * None.
+ * Return 0, indicating that the UTF is clean.
*
* Side effects:
- * Sets the library path to an initial value.
+ * None.
*
- *-------------------------------------------------------------------------
+ *---------------------------------------------------------------------------
*/
-void
-TclpInitLibraryPath(
- char **valuePtr,
- int *lengthPtr,
- Tcl_Encoding *encodingPtr)
+int
+TclpInitLibraryPath(path)
+ CONST char *path; /* Potentially dirty UTF string that is */
+ /* the path to the executable name. */
{
#define LIBRARY_SIZE 32
- Tcl_Obj *pathPtr;
- char installLib[LIBRARY_SIZE];
- char *bytes;
+ Tcl_Obj *pathPtr, *objPtr;
+ CONST char *str;
+ Tcl_DString ds;
+ int pathc;
+ CONST char **pathv;
+ char installLib[LIBRARY_SIZE], developLib[LIBRARY_SIZE];
+ Tcl_DStringInit(&ds);
pathPtr = Tcl_NewObj();
/*
- * Initialize the substring used when locating the script library. The
- * installLib variable computes the script library path relative to the
- * installed DLL.
+ * Initialize the substrings used when locating an executable. The
+ * installLib variable computes the path as though the executable
+ * is installed. The developLib computes the path as though the
+ * executable is run from a develpment directory.
*/
sprintf(installLib, "lib/tcl%s", TCL_VERSION);
+ sprintf(developLib, "tcl%s/library", TCL_PATCH_LEVEL);
+
+ /*
+ * Look for the library relative to default encoding dir.
+ */
+
+ str = Tcl_GetDefaultEncodingDir();
+ if ((str != NULL) && (str[0] != '\0')) {
+ objPtr = Tcl_NewStringObj(str, -1);
+ Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+ }
/*
- * Look for the library relative to the TCL_LIBRARY env variable. If the
- * last dirname in the TCL_LIBRARY path does not match the last dirname in
- * the installLib variable, use the last dir name of installLib in
- * addition to the orginal TCL_LIBRARY path.
+ * Look for the library relative to the TCL_LIBRARY env variable.
+ * If the last dirname in the TCL_LIBRARY path does not match the
+ * last dirname in the installLib variable, use the last dir name
+ * of installLib in addition to the orginal TCL_LIBRARY path.
*/
AppendEnvironment(pathPtr, installLib);
/*
- * Look for the library in its default location.
+ * Look for the library relative to the DLL. Only use the installLib
+ * because in practice, the DLL is always installed.
*/
- Tcl_ListObjAppendElement(NULL, pathPtr,
- TclGetProcessGlobalValue(&defaultLibraryDir));
+ AppendDllPath(pathPtr, TclWinGetTclInstance(), installLib);
+
- *encodingPtr = NULL;
- bytes = Tcl_GetStringFromObj(pathPtr, lengthPtr);
- *valuePtr = ckalloc((unsigned int)(*lengthPtr)+1);
- memcpy(*valuePtr, bytes, (size_t)(*lengthPtr)+1);
- Tcl_DecrRefCount(pathPtr);
+ /*
+ * Look for the library relative to the executable. This algorithm
+ * should be the same as the one in the tcl_findLibrary procedure.
+ *
+ * This code looks in the following directories:
+ *
+ * <bindir>/../<installLib>
+ * (e.g. /usr/local/bin/../lib/tcl8.4)
+ * <bindir>/../../<installLib>
+ * (e.g. /usr/local/TclPro/solaris-sparc/bin/../../lib/tcl8.4)
+ * <bindir>/../library
+ * (e.g. /usr/src/tcl8.4.0/unix/../library)
+ * <bindir>/../../library
+ * (e.g. /usr/src/tcl8.4.0/unix/solaris-sparc/../../library)
+ * <bindir>/../../<developLib>
+ * (e.g. /usr/src/tcl8.4.0/unix/../../tcl8.4.0/library)
+ * <bindir>/../../../<developLib>
+ * (e.g. /usr/src/tcl8.4.0/unix/solaris-sparc/../../../tcl8.4.0/library)
+ */
+
+ /*
+ * The variable path holds an absolute path. Take care not to
+ * overwrite pathv[0] since that might produce a relative path.
+ */
+
+ if (path != NULL) {
+ int i, origc;
+ CONST char **origv;
+
+ Tcl_SplitPath(path, &origc, &origv);
+ pathc = 0;
+ pathv = (CONST char **) ckalloc((unsigned int)(origc * sizeof(char *)));
+ for (i=0; i< origc; i++) {
+ if (origv[i][0] == '.') {
+ if (strcmp(origv[i], ".") == 0) {
+ /* do nothing */
+ } else if (strcmp(origv[i], "..") == 0) {
+ pathc--;
+ } else {
+ pathv[pathc++] = origv[i];
+ }
+ } else {
+ pathv[pathc++] = origv[i];
+ }
+ }
+ if (pathc > 2) {
+ str = pathv[pathc - 2];
+ pathv[pathc - 2] = installLib;
+ path = Tcl_JoinPath(pathc - 1, pathv, &ds);
+ pathv[pathc - 2] = str;
+ objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
+ Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+ Tcl_DStringFree(&ds);
+ }
+ if (pathc > 3) {
+ str = pathv[pathc - 3];
+ pathv[pathc - 3] = installLib;
+ path = Tcl_JoinPath(pathc - 2, pathv, &ds);
+ pathv[pathc - 3] = str;
+ objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
+ Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+ Tcl_DStringFree(&ds);
+ }
+ if (pathc > 2) {
+ str = pathv[pathc - 2];
+ pathv[pathc - 2] = "library";
+ path = Tcl_JoinPath(pathc - 1, pathv, &ds);
+ pathv[pathc - 2] = str;
+ objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
+ Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+ Tcl_DStringFree(&ds);
+ }
+ if (pathc > 3) {
+ str = pathv[pathc - 3];
+ pathv[pathc - 3] = "library";
+ path = Tcl_JoinPath(pathc - 2, pathv, &ds);
+ pathv[pathc - 3] = str;
+ objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
+ Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+ Tcl_DStringFree(&ds);
+ }
+ if (pathc > 3) {
+ str = pathv[pathc - 3];
+ pathv[pathc - 3] = developLib;
+ path = Tcl_JoinPath(pathc - 2, pathv, &ds);
+ pathv[pathc - 3] = str;
+ objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
+ Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+ Tcl_DStringFree(&ds);
+ }
+ if (pathc > 4) {
+ str = pathv[pathc - 4];
+ pathv[pathc - 4] = developLib;
+ path = Tcl_JoinPath(pathc - 3, pathv, &ds);
+ pathv[pathc - 4] = str;
+ objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
+ Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
+ Tcl_DStringFree(&ds);
+ }
+ ckfree((char *) origv);
+ ckfree((char *) pathv);
+ }
+
+ TclSetLibraryPath(pathPtr);
+
+ return 0; /* 0 indicates that pathPtr is clean (true) utf */
}
/*
@@ -218,9 +337,9 @@ TclpInitLibraryPath(
*
* AppendEnvironment --
*
- * Append the value of the TCL_LIBRARY environment variable onto the path
- * pointer. If the env variable points to another version of tcl (e.g.
- * "tcl7.6") also append the path to this version (e.g.,
+ * Append the value of the TCL_LIBRARY environment variable onto the
+ * path pointer. If the env variable points to another version of
+ * tcl (e.g. "tcl7.6") also append the path to this version (e.g.,
* "tcl7.6/../tcl8.2")
*
* Results:
@@ -246,30 +365,30 @@ AppendEnvironment(
char *shortlib;
/*
- * The shortlib value needs to be the tail component of the lib path. For
- * example, "lib/tcl8.4" -> "tcl8.4" while "usr/share/tcl8.5" -> "tcl8.5".
+ * The shortlib value needs to be the tail component of the
+ * lib path. For example, "lib/tcl8.4" -> "tcl8.4" while
+ * "usr/share/tcl8.5" -> "tcl8.5".
*/
-
- for (shortlib = (char *) &lib[strlen(lib)-1]; shortlib>lib ; shortlib--) {
- if (*shortlib == '/') {
- if ((unsigned)(shortlib - lib) == strlen(lib) - 1) {
- Tcl_Panic("last character in lib cannot be '/'");
- }
- shortlib++;
- break;
- }
+ for (shortlib = (char *) (lib + strlen(lib) - 1); shortlib > lib ; shortlib--) {
+ if (*shortlib == '/') {
+ if (shortlib == (lib + strlen(lib) - 1)) {
+ Tcl_Panic("last character in lib cannot be '/'");
+ }
+ shortlib++;
+ break;
+ }
}
if (shortlib == lib) {
- Tcl_Panic("no '/' character found in lib");
+ Tcl_Panic("no '/' character found in lib");
}
/*
- * The "L" preceeding the TCL_LIBRARY string is used to tell VC++ that
- * this is a unicode string.
+ * The "L" preceeding the TCL_LIBRARY string is used to tell VC++
+ * that this is a unicode string.
*/
-
+
if (GetEnvironmentVariableW(L"TCL_LIBRARY", wBuf, MAX_PATH) == 0) {
- buf[0] = '\0';
+ buf[0] = '\0';
GetEnvironmentVariableA("TCL_LIBRARY", buf, MAX_PATH);
} else {
ToUtf(wBuf, buf);
@@ -282,21 +401,21 @@ AppendEnvironment(
TclWinNoBackslash(buf);
Tcl_SplitPath(buf, &pathc, &pathv);
- /*
- * The lstrcmpi() will work even if pathv[pathc-1] is random UTF-8
- * chars because I know shortlib is ascii.
+ /*
+ * The lstrcmpi() will work even if pathv[pathc - 1] is random
+ * UTF-8 chars because I know shortlib is ascii.
*/
if ((pathc > 0) && (lstrcmpiA(shortlib, pathv[pathc - 1]) != 0)) {
CONST char *str;
-
/*
- * TCL_LIBRARY is set but refers to a different tcl installation
- * than the current version. Try fiddling with the specified
- * directory to make it refer to this installation by removing the
- * old "tclX.Y" and substituting the current version string.
+ * TCL_LIBRARY is set but refers to a different tcl
+ * installation than the current version. Try fiddling with the
+ * specified directory to make it refer to this installation by
+ * removing the old "tclX.Y" and substituting the current
+ * version string.
*/
-
+
pathv[pathc - 1] = shortlib;
Tcl_DStringInit(&ds);
str = Tcl_JoinPath(pathc, pathv, &ds);
@@ -313,10 +432,10 @@ AppendEnvironment(
/*
*---------------------------------------------------------------------------
*
- * InitializeDefaultLibraryDir --
+ * AppendDllPath --
*
- * Locate the Tcl script library default location relative to the
- * location of the Tcl DLL.
+ * Append a path onto the path pointer that tries to locate the Tcl
+ * library relative to the location of the Tcl DLL.
*
* Results:
* None.
@@ -327,37 +446,34 @@ AppendEnvironment(
*---------------------------------------------------------------------------
*/
-static void
-InitializeDefaultLibraryDir(
- char **valuePtr,
- int *lengthPtr,
- Tcl_Encoding *encodingPtr)
+static void
+AppendDllPath(
+ Tcl_Obj *pathPtr,
+ HMODULE hModule,
+ CONST char *lib)
{
- HMODULE hModule = TclWinGetTclInstance();
WCHAR wName[MAX_PATH + LIBRARY_SIZE];
char name[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX];
- char *end, *p;
if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) {
GetModuleFileNameA(hModule, name, MAX_PATH);
} else {
ToUtf(wName, name);
}
-
- end = strrchr(name, '\\');
- *end = '\0';
- p = strrchr(name, '\\');
- if (p != NULL) {
- end = p;
+ if (lib != NULL) {
+ char *end, *p;
+
+ end = strrchr(name, '\\');
+ *end = '\0';
+ p = strrchr(name, '\\');
+ if (p != NULL) {
+ end = p;
+ }
+ *end = '\\';
+ strcpy(end + 1, lib);
}
- *end = '\\';
-
TclWinNoBackslash(name);
- sprintf(end + 1, "lib/tcl%s", TCL_VERSION);
- *lengthPtr = strlen(name);
- *valuePtr = ckalloc((unsigned int) *lengthPtr + 1);
- *encodingPtr = NULL;
- memcpy(*valuePtr, name, (size_t) *lengthPtr + 1);
+ Tcl_ListObjAppendElement(NULL, pathPtr, Tcl_NewStringObj(name, -1));
}
/*
@@ -365,7 +481,7 @@ InitializeDefaultLibraryDir(
*
* ToUtf --
*
- * Convert a char string to a UTF string.
+ * Convert a char string to a UTF string.
*
* Results:
* None.
@@ -397,10 +513,10 @@ ToUtf(
*
* TclWinEncodingsCleanup --
*
- * Reset information to its original state in finalization to allow for
- * reinitialization to be possible. This must not be called until after
- * the filesystem has been finalised, or exit crashes may occur when
- * using virtual filesystems.
+ * Reset information to its original state in finalization to
+ * allow for reinitialization to be possible. This must not
+ * be called until after the filesystem has been finalised, or
+ * exit crashes may occur when using virtual filesystems.
*
* Results:
* None.
@@ -412,9 +528,14 @@ ToUtf(
*/
void
-TclWinEncodingsCleanup(void)
+TclWinEncodingsCleanup()
{
TclWinResetInterfaceEncodings();
+ libraryPathEncodingFixed = 0;
+ if (binaryEncoding != NULL) {
+ Tcl_FreeEncoding(binaryEncoding);
+ binaryEncoding = NULL;
+ }
}
/*
@@ -422,56 +543,79 @@ TclWinEncodingsCleanup(void)
*
* TclpSetInitialEncodings --
*
- * Based on the locale, determine the encoding of the operating system
- * and the default encoding for newly opened files.
+ * Based on the locale, determine the encoding of the operating
+ * system and the default encoding for newly opened files.
*
- * Called at process initialization time, and part way through startup,
- * we verify that the initial encodings were correctly setup. Depending
- * on Tcl's environment, there may not have been enough information first
- * time through (above).
+ * Called at process initialization time, and part way through
+ * startup, we verify that the initial encodings were correctly
+ * setup. Depending on Tcl's environment, there may not have been
+ * enough information first time through (above).
*
* Results:
* None.
*
* Side effects:
- * The Tcl library path is converted from native encoding to UTF-8, on
- * the first call, and the encodings may be changed on first or second
- * call.
+ * The Tcl library path is converted from native encoding to UTF-8,
+ * on the first call, and the encodings may be changed on first or
+ * second call.
*
*---------------------------------------------------------------------------
*/
void
-TclpSetInitialEncodings(void)
+TclpSetInitialEncodings()
{
- Tcl_DString encodingName;
-
- TclpSetInterfaces();
- Tcl_SetSystemEncoding(NULL,
- Tcl_GetEncodingNameFromEnvironment(&encodingName));
- Tcl_DStringFree(&encodingName);
-}
-
-void
-TclpSetInterfaces(void)
-{
- int platformId, useWide;
-
- platformId = TclWinGetPlatformId();
- useWide = ((platformId == VER_PLATFORM_WIN32_NT)
- || (platformId == VER_PLATFORM_WIN32_CE));
- TclWinSetInterfaces(useWide);
-}
+ CONST char *encoding;
+ char buf[4 + TCL_INTEGER_SPACE];
+
+ if (libraryPathEncodingFixed == 0) {
+ int platformId, useWide;
+
+ platformId = TclWinGetPlatformId();
+ useWide = ((platformId == VER_PLATFORM_WIN32_NT)
+ || (platformId == VER_PLATFORM_WIN32_CE));
+ TclWinSetInterfaces(useWide);
+
+ wsprintfA(buf, "cp%d", GetACP());
+ Tcl_SetSystemEncoding(NULL, buf);
+
+ if (!useWide) {
+ Tcl_Obj *pathPtr = TclGetLibraryPath();
+ if (pathPtr != NULL) {
+ int i, objc;
+ Tcl_Obj **objv;
+
+ objc = 0;
+ Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);
+ for (i = 0; i < objc; i++) {
+ int length;
+ char *string;
+ Tcl_DString ds;
+
+ string = Tcl_GetStringFromObj(objv[i], &length);
+ Tcl_ExternalToUtfDString(NULL, string, length, &ds);
+ Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds));
+ Tcl_DStringFree(&ds);
+ }
+ }
+ }
+
+ libraryPathEncodingFixed = 1;
+ } else {
+ wsprintfA(buf, "cp%d", GetACP());
+ Tcl_SetSystemEncoding(NULL, buf);
+ }
-CONST char *
-Tcl_GetEncodingNameFromEnvironment(
- Tcl_DString *bufPtr)
-{
- Tcl_DStringInit(bufPtr);
- Tcl_DStringSetLength(bufPtr, 2+TCL_INTEGER_SPACE);
- wsprintfA(Tcl_DStringValue(bufPtr), "cp%d", GetACP());
- Tcl_DStringSetLength(bufPtr, strlen(Tcl_DStringValue(bufPtr)));
- return Tcl_DStringValue(bufPtr);
+ /* This is only ever called from the startup thread */
+ if (binaryEncoding == NULL) {
+ /*
+ * Keep this encoding preloaded. The IO package uses it for
+ * gets on a binary channel.
+ */
+ encoding = "iso8859-1";
+ binaryEncoding = Tcl_GetEncoding(NULL, encoding);
+ }
}
/*
@@ -479,8 +623,9 @@ Tcl_GetEncodingNameFromEnvironment(
*
* TclpSetVariables --
*
- * Performs platform-specific interpreter initialization related to the
- * tcl_platform and env variables, and other platform-specific things.
+ * Performs platform-specific interpreter initialization related to
+ * the tcl_platform and env variables, and other platform-specific
+ * things.
*
* Results:
* None.
@@ -492,27 +637,23 @@ Tcl_GetEncodingNameFromEnvironment(
*/
void
-TclpSetVariables(
- Tcl_Interp *interp) /* Interp to initialize. */
-{
+TclpSetVariables(interp)
+ Tcl_Interp *interp; /* Interp to initialize. */
+{
CONST char *ptr;
char buffer[TCL_INTEGER_SPACE * 2];
- union {
- SYSTEM_INFO info;
- OemId oemId;
- } sys;
+ SYSTEM_INFO sysInfo;
+ OemId *oemId;
OSVERSIONINFOA osInfo;
Tcl_DString ds;
- WCHAR szUserName[UNLEN+1];
- DWORD cchUserNameLen = UNLEN;
-
- Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL,
- TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY);
+ TCHAR szUserName[ UNLEN+1 ];
+ DWORD dwUserNameLen = sizeof(szUserName);
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
GetVersionExA(&osInfo);
- GetSystemInfo(&sys.info);
+ oemId = (OemId *) &sysInfo;
+ GetSystemInfo(&sysInfo);
/*
* Define the tcl_platform array.
@@ -526,19 +667,18 @@ TclpSetVariables(
}
wsprintfA(buffer, "%d.%d", osInfo.dwMajorVersion, osInfo.dwMinorVersion);
Tcl_SetVar2(interp, "tcl_platform", "osVersion", buffer, TCL_GLOBAL_ONLY);
- if (sys.oemId.wProcessorArchitecture < NUMPROCESSORS) {
+ if (oemId->wProcessorArchitecture < NUMPROCESSORS) {
Tcl_SetVar2(interp, "tcl_platform", "machine",
- processors[sys.oemId.wProcessorArchitecture],
+ processors[oemId->wProcessorArchitecture],
TCL_GLOBAL_ONLY);
}
#ifdef _DEBUG
/*
- * The existence of the "debug" element of the tcl_platform array
- * indicates that this particular Tcl shell has been compiled with debug
- * information. Using "info exists tcl_platform(debug)" a Tcl script can
- * direct the interpreter to load debug versions of DLLs with the load
- * command.
+ * The existence of the "debug" element of the tcl_platform array indicates
+ * that this particular Tcl shell has been compiled with debug information.
+ * Using "info exists tcl_platform(debug)" a Tcl script can direct the
+ * interpreter to load debug versions of DLLs with the load command.
*/
Tcl_SetVar2(interp, "tcl_platform", "debug", "1",
@@ -572,16 +712,14 @@ TclpSetVariables(
/*
* Initialize the user name from the environment first, since this is much
* faster than asking the system.
- * Note: cchUserNameLen is number of characters including nul terminator.
*/
- Tcl_DStringInit(&ds);
+ Tcl_DStringInit( &ds );
if (TclGetEnv("USERNAME", &ds) == NULL) {
- if (tclWinProcs->getUserName((LPTSTR)szUserName, &cchUserNameLen) != 0) {
- int cbUserNameLen = cchUserNameLen - 1;
- if (tclWinProcs->useWide) cbUserNameLen *= sizeof(WCHAR);
- Tcl_WinTCharToUtf((LPTSTR)szUserName, cbUserNameLen, &ds);
- }
+
+ if ( GetUserName( szUserName, &dwUserNameLen ) != 0 ) {
+ Tcl_WinTCharToUtf( szUserName, dwUserNameLen, &ds );
+ }
}
Tcl_SetVar2(interp, "tcl_platform", "user", Tcl_DStringValue(&ds),
TCL_GLOBAL_ONLY);
@@ -593,14 +731,15 @@ TclpSetVariables(
*
* TclpFindVariable --
*
- * Locate the entry in environ for a given name. On Unix this routine is
- * case sensitive, on Windows this matches mioxed case.
+ * Locate the entry in environ for a given name. On Unix this
+ * routine is case sensetive, on Windows this matches mioxed case.
*
* Results:
- * The return value is the index in environ of an entry with the name
- * "name", or -1 if there is no such entry. The integer at *lengthPtr is
- * filled in with the length of name (if a matching entry is found) or
- * the length of the environ array (if no matching entry is found).
+ * The return value is the index in environ of an entry with the
+ * name "name", or -1 if there is no such entry. The integer at
+ * *lengthPtr is filled in with the length of name (if a matching
+ * entry is found) or the length of the environ array (if no matching
+ * entry is found).
*
* Side effects:
* None.
@@ -609,10 +748,10 @@ TclpSetVariables(
*/
int
-TclpFindVariable(
- CONST char *name, /* Name of desired environment variable
+TclpFindVariable(name, lengthPtr)
+ CONST char *name; /* Name of desired environment variable
* (UTF-8). */
- int *lengthPtr) /* Used to return length of name (for
+ int *lengthPtr; /* Used to return length of name (for
* successful searches) or number of non-NULL
* entries in environ (for unsuccessful
* searches). */
@@ -623,22 +762,23 @@ TclpFindVariable(
Tcl_DString envString;
/*
- * Convert the name to all upper case for the case insensitive comparison.
+ * Convert the name to all upper case for the case insensitive
+ * comparison.
*/
length = strlen(name);
nameUpper = (char *) ckalloc((unsigned) length+1);
- memcpy(nameUpper, name, (size_t) length+1);
+ memcpy((VOID *) nameUpper, (VOID *) name, (size_t) length+1);
Tcl_UtfToUpper(nameUpper);
-
+
Tcl_DStringInit(&envString);
for (i = 0, env = environ[i]; env != NULL; i++, env = environ[i]) {
/*
- * Chop the env string off after the equal sign, then Convert the name
- * to all upper case, so we do not have to convert all the characters
- * after the equal sign.
+ * Chop the env string off after the equal sign, then Convert
+ * the name to all upper case, so we do not have to convert
+ * all the characters after the equal sign.
*/
-
+
envUpper = Tcl_ExternalToUtfDString(NULL, env, -1, &envString);
p1 = strchr(envUpper, '=');
if (p1 == NULL) {
@@ -658,22 +798,117 @@ TclpFindVariable(
result = i;
goto done;
}
-
+
Tcl_DStringFree(&envString);
}
-
+
*lengthPtr = i;
- done:
+ done:
Tcl_DStringFree(&envString);
ckfree(nameUpper);
return result;
}
/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Init --
+ *
+ * This procedure is typically invoked by Tcl_AppInit procedures
+ * to perform additional initialization for a Tcl interpreter,
+ * such as sourcing the "init.tcl" script.
+ *
+ * Results:
+ * Returns a standard Tcl completion code and sets the interp's
+ * result if there is an error.
+ *
+ * Side effects:
+ * Depends on what's in the init.tcl script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Init(interp)
+ Tcl_Interp *interp; /* Interpreter to initialize. */
+{
+ Tcl_Obj *pathPtr;
+
+ if (tclPreInitScript != NULL) {
+ if (Tcl_Eval(interp, tclPreInitScript) == TCL_ERROR) {
+ return (TCL_ERROR);
+ };
+ }
+
+ pathPtr = TclGetLibraryPath();
+ if (pathPtr == NULL) {
+ pathPtr = Tcl_NewObj();
+ }
+ Tcl_IncrRefCount(pathPtr);
+ Tcl_SetVar2Ex(interp, "tcl_libPath", NULL, pathPtr, TCL_GLOBAL_ONLY);
+ Tcl_DecrRefCount(pathPtr);
+ return Tcl_Eval(interp, initScript);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SourceRCFile --
+ *
+ * This procedure is typically invoked by Tcl_Main of Tk_Main
+ * procedure to source an application specific rc file into the
+ * interpreter at startup time.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Depends on what's in the rc script.
+ *
+ *----------------------------------------------------------------------
*/
+
+void
+Tcl_SourceRCFile(interp)
+ Tcl_Interp *interp; /* Interpreter to source rc file into. */
+{
+ Tcl_DString temp;
+ CONST char *fileName;
+ Tcl_Channel errChannel;
+
+ fileName = Tcl_GetVar(interp, "tcl_rcFileName", TCL_GLOBAL_ONLY);
+
+ if (fileName != NULL) {
+ Tcl_Channel c;
+ CONST char *fullName;
+
+ Tcl_DStringInit(&temp);
+ fullName = Tcl_TranslateFileName(interp, fileName, &temp);
+ if (fullName == NULL) {
+ /*
+ * Couldn't translate the file name (e.g. it referred to a
+ * bogus user or there was no HOME environment variable).
+ * Just do nothing.
+ */
+ } else {
+
+ /*
+ * Test for the existence of the rc file before trying to read it.
+ */
+
+ c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
+ if (c != (Tcl_Channel) NULL) {
+ Tcl_Close(NULL, c);
+ if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
+ errChannel = Tcl_GetStdChannel(TCL_STDERR);
+ if (errChannel) {
+ Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
+ Tcl_WriteChars(errChannel, "\n", 1);
+ }
+ }
+ }
+ }
+ Tcl_DStringFree(&temp);
+ }
+}
diff --git a/win/tclWinInt.h b/win/tclWinInt.h
index a76865d..2e80afa 100644
--- a/win/tclWinInt.h
+++ b/win/tclWinInt.h
@@ -12,7 +12,12 @@
#ifndef _TCLWININT
#define _TCLWININT
+#ifndef _TCLINT
#include "tclInt.h"
+#endif
+#ifndef _TCLPORT
+#include "tclPort.h"
+#endif
/*
* The following specifies how much stack space TclpCheckStackSpace()
@@ -22,6 +27,11 @@
#define TCL_WIN_STACK_THRESHOLD 0x8000
+#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.
@@ -73,7 +83,7 @@ typedef struct TclWinProcs {
DWORD (WINAPI *getTempPathProc)(DWORD, WCHAR *);
BOOL (WINAPI *getVolumeInformationProc)(CONST TCHAR *, WCHAR *, DWORD,
LPDWORD, LPDWORD, LPDWORD, WCHAR *, DWORD);
- HINSTANCE (WINAPI *loadLibraryExProc)(CONST TCHAR *, HANDLE, DWORD);
+ HINSTANCE (WINAPI *loadLibraryExProc)(const TCHAR *, HANDLE, DWORD);
TCHAR (WINAPI *lstrcpyProc)(WCHAR *, CONST TCHAR *);
BOOL (WINAPI *moveFileProc)(CONST TCHAR *, CONST TCHAR *);
BOOL (WINAPI *removeDirectoryProc)(CONST TCHAR *);
@@ -93,12 +103,13 @@ typedef struct TclWinProcs {
BOOL (WINAPI *createHardLinkProc)(CONST TCHAR*, CONST TCHAR*,
LPSECURITY_ATTRIBUTES);
- /* deleted INT (__cdecl *utimeProc)(CONST TCHAR*, struct _utimbuf *); */
+ INT (__cdecl *utimeProc)(CONST TCHAR*, struct _utimbuf *);
/* These two are also NULL at start; see comment above */
HANDLE (WINAPI *findFirstFileExProc)(CONST TCHAR*, UINT,
LPVOID, UINT,
LPVOID, DWORD);
BOOL (WINAPI *getVolumeNameForVMPProc)(CONST TCHAR*, TCHAR*, DWORD);
+
DWORD (WINAPI *getLongPathNameProc)(CONST TCHAR*, TCHAR*, DWORD);
/*
* These six are for the security sdk to get correct file
@@ -125,57 +136,42 @@ typedef struct TclWinProcs {
LPDWORD PrivilegeSetLength,
LPDWORD GrantedAccess,
LPBOOL AccessStatus);
- /*
- * Unicode console support. WriteConsole and ReadConsole
- */
- BOOL (WINAPI *readConsoleProc)(
- HANDLE hConsoleInput,
- LPVOID lpBuffer,
- DWORD nNumberOfCharsToRead,
- LPDWORD lpNumberOfCharsRead,
- LPVOID lpReserved
- );
- BOOL (WINAPI *writeConsoleProc)(
- HANDLE hConsoleOutput,
- const VOID* lpBuffer,
- DWORD nNumberOfCharsToWrite,
- LPDWORD lpNumberOfCharsWritten,
- LPVOID lpReserved
- );
- BOOL (WINAPI *getUserName)(LPTSTR lpBuffer, LPDWORD lpnSize);
+ /*
+ * Unicode console support. WriteConsole and ReadConsole
+ */
+ BOOL (WINAPI *readConsoleProc)(HANDLE hConsoleInput,
+ LPVOID lpBuffer,
+ DWORD nNumberOfCharsToRead,
+ LPDWORD lpNumberOfCharsRead,
+ LPVOID lpReserved);
+ BOOL (WINAPI *writeConsoleProc)(HANDLE hConsoleOutput,
+ const VOID* lpBuffer,
+ DWORD nNumberOfCharsToWrite,
+ LPDWORD lpNumberOfCharsWritten,
+ LPVOID lpReserved);
} TclWinProcs;
-MODULE_SCOPE TclWinProcs *tclWinProcs;
+EXTERN TclWinProcs *tclWinProcs;
/*
* Declarations of functions that are not accessible by way of the
* stubs table.
*/
-MODULE_SCOPE char TclWinDriveLetterForVolMountPoint(
- CONST WCHAR *mountPoint);
-MODULE_SCOPE void TclWinEncodingsCleanup();
-MODULE_SCOPE void TclWinInit(HINSTANCE hInst);
-MODULE_SCOPE TclFile TclWinMakeFile(HANDLE handle);
-MODULE_SCOPE Tcl_Channel TclWinOpenConsoleChannel(HANDLE handle,
- char *channelName, int permissions);
-MODULE_SCOPE Tcl_Channel TclWinOpenFileChannel(HANDLE handle, char *channelName,
- int permissions, int appendMode);
-MODULE_SCOPE Tcl_Channel TclWinOpenSerialChannel(HANDLE handle,
- char *channelName, int permissions);
-MODULE_SCOPE void TclWinResetInterfaceEncodings();
-MODULE_SCOPE HANDLE TclWinSerialReopen(HANDLE handle, CONST TCHAR *name,
- DWORD access);
-MODULE_SCOPE int TclWinSymLinkCopyDirectory(CONST TCHAR* LinkOriginal,
- CONST TCHAR* LinkCopy);
-MODULE_SCOPE int TclWinSymLinkDelete(CONST TCHAR* LinkOriginal,
- int linkOnly);
+EXTERN void TclWinEncodingsCleanup();
+EXTERN void TclWinResetInterfaceEncodings();
+EXTERN void TclWinInit(HINSTANCE hInst);
+EXTERN int TclWinSymLinkCopyDirectory(CONST TCHAR* LinkOriginal,
+ CONST TCHAR* LinkCopy);
+EXTERN int TclWinSymLinkDelete(CONST TCHAR* LinkOriginal,
+ int linkOnly);
+EXTERN char TclWinDriveLetterForVolMountPoint(CONST WCHAR *mountPoint);
#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
-MODULE_SCOPE void TclWinFreeAllocCache(void);
-MODULE_SCOPE void TclFreeAllocCache(void *);
-MODULE_SCOPE Tcl_Mutex *TclpNewAllocMutex(void);
-MODULE_SCOPE void * TclpGetAllocCache(void);
-MODULE_SCOPE void TclpSetAllocCache(void *);
+EXTERN void TclWinFreeAllocCache(void);
+EXTERN void TclFreeAllocCache(void *);
+EXTERN Tcl_Mutex *TclpNewAllocMutex(void);
+EXTERN void *TclpGetAllocCache(void);
+EXTERN void TclpSetAllocCache(void *);
#endif /* TCL_THREADS */
/* Needed by tclWinFile.c and tclWinFCmd.c */
@@ -183,4 +179,9 @@ MODULE_SCOPE void TclpSetAllocCache(void *);
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
#endif
+#include "tclIntPlatDecls.h"
+
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLIMPORT
+
#endif /* _TCLWININT */
diff --git a/win/tclWinLoad.c b/win/tclWinLoad.c
index c4d08e8..09ade9b 100644
--- a/win/tclWinLoad.c
+++ b/win/tclWinLoad.c
@@ -1,14 +1,14 @@
-/*
+/*
* tclWinLoad.c --
*
- * This function provides a version of the TclLoadFile that works with
- * the Windows "LoadLibrary" and "GetProcAddress" API for dynamic
- * loading.
+ * This procedure provides a version of the TclLoadFile that
+ * works with the Windows "LoadLibrary" and "GetProcAddress"
+ * API for dynamic loading.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclWinInt.h"
@@ -19,12 +19,12 @@
*
* TclpDlopen --
*
- * Dynamically loads a binary code file into memory and returns a handle
- * to the new code.
+ * Dynamically loads a binary code file into memory and returns
+ * a handle to the new code.
*
* Results:
- * A standard Tcl completion code. If an error occurs, an error message
- * is left in the interp's result.
+ * A standard Tcl completion code. If an error occurs, an error
+ * message is left in the interp's result.
*
* Side effects:
* New code suddenly appears in memory.
@@ -33,100 +33,92 @@
*/
int
-TclpDlopen(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Obj *pathPtr, /* Name of the file containing the desired
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
+ Tcl_Interp *interp; /* Used for error reporting. */
+ Tcl_Obj *pathPtr; /* Name of the file containing the desired
* code (UTF-8). */
- Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded
- * file which will be passed back to
+ Tcl_LoadHandle *loadHandle; /* Filled with token for dynamically loaded
+ * file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
- Tcl_FSUnloadFileProc **unloadProcPtr)
+ Tcl_FSUnloadFileProc **unloadProcPtr;
/* Filled with address of Tcl_FSUnloadFileProc
- * function which should be used for this
- * file. */
+ * function which should be used for
+ * this file. */
{
HINSTANCE handle;
CONST TCHAR *nativeName;
- /*
- * First try the full path the user gave us. This is particularly
- * important if the cwd is inside a vfs, and we are trying to load using a
- * relative path.
+ /*
+ * First try the full path the user gave us. This is particularly
+ * important if the cwd is inside a vfs, and we are trying to load
+ * using a relative path.
*/
-
nativeName = Tcl_FSGetNativePath(pathPtr);
handle = (*tclWinProcs->loadLibraryExProc)(nativeName, NULL,
- LOAD_WITH_ALTERED_SEARCH_PATH);
+ LOAD_WITH_ALTERED_SEARCH_PATH);
if (handle == NULL) {
- /*
- * Let the OS loader examine the binary search path for whatever
- * string the user gave us which hopefully refers to a file on the
- * binary path.
+ /*
+ * Let the OS loader examine the binary search path for
+ * whatever string the user gave us which hopefully refers
+ * to a file on the binary path
*/
-
Tcl_DString ds;
- char *fileName = Tcl_GetString(pathPtr);
-
+ char *fileName = Tcl_GetString(pathPtr);
nativeName = Tcl_WinUtfToTChar(fileName, -1, &ds);
handle = (*tclWinProcs->loadLibraryExProc)(nativeName, NULL,
- LOAD_WITH_ALTERED_SEARCH_PATH);
+ LOAD_WITH_ALTERED_SEARCH_PATH);
Tcl_DStringFree(&ds);
}
*loadHandle = (Tcl_LoadHandle) handle;
-
+
if (handle == NULL) {
DWORD lastError = GetLastError();
-
#if 0
/*
- * It would be ideal if the FormatMessage stuff worked better, but
- * unfortunately it doesn't seem to want to...
+ * It would be ideal if the FormatMessage stuff worked better,
+ * but unfortunately it doesn't seem to want to...
*/
-
LPTSTR lpMsgBuf;
char *buf;
int size;
-
size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastError, 0,
(LPTSTR) &lpMsgBuf, 0, NULL);
buf = (char *) ckalloc((unsigned) TCL_INTEGER_SPACE + size + 1);
sprintf(buf, "%d %s", lastError, (char *)lpMsgBuf);
#endif
-
Tcl_AppendResult(interp, "couldn't load library \"",
- Tcl_GetString(pathPtr), "\": ", NULL);
-
+ Tcl_GetString(pathPtr), "\": ", (char *) NULL);
/*
- * Check for possible DLL errors. This doesn't work quite right,
- * because Windows seems to only return ERROR_MOD_NOT_FOUND for just
- * about any problem, but it's better than nothing. It'd be even
- * better if there was a way to get what DLLs
+ * Check for possible DLL errors. This doesn't work quite right,
+ * because Windows seems to only return ERROR_MOD_NOT_FOUND for
+ * just about any problem, but it's better than nothing. It'd be
+ * even better if there was a way to get what DLLs
*/
-
switch (lastError) {
- case ERROR_MOD_NOT_FOUND:
- case ERROR_DLL_NOT_FOUND:
- Tcl_AppendResult(interp, "this library or a dependent library"
- " could not be found in library path", NULL);
- break;
- case ERROR_PROC_NOT_FOUND:
- Tcl_AppendResult(interp, "A function specified in the import"
- " table could not be resolved by the system. Windows"
- " is not telling which one, I'm sorry.", NULL);
- break;
- case ERROR_INVALID_DLL:
- Tcl_AppendResult(interp, "this library or a dependent library"
- " is damaged", NULL);
- break;
- case ERROR_DLL_INIT_FAILED:
- Tcl_AppendResult(interp, "the library initialization"
- " routine failed", NULL);
- break;
- default:
- TclWinConvertError(lastError);
- Tcl_AppendResult(interp, Tcl_PosixError(interp), NULL);
+ case ERROR_MOD_NOT_FOUND:
+ case ERROR_DLL_NOT_FOUND:
+ Tcl_AppendResult(interp, "this library or a dependent library",
+ " could not be found in library path",
+ (char *) NULL);
+ break;
+ case ERROR_PROC_NOT_FOUND:
+ Tcl_AppendResult(interp, "could not find specified procedure",
+ (char *) NULL);
+ break;
+ case ERROR_INVALID_DLL:
+ Tcl_AppendResult(interp, "this library or a dependent library",
+ " is damaged", (char *) NULL);
+ break;
+ case ERROR_DLL_INIT_FAILED:
+ Tcl_AppendResult(interp, "the library initialization",
+ " routine failed", (char *) NULL);
+ break;
+ default:
+ TclWinConvertError(lastError);
+ Tcl_AppendResult(interp, Tcl_PosixError(interp),
+ (char *) NULL);
}
return TCL_ERROR;
} else {
@@ -140,22 +132,21 @@ TclpDlopen(
*
* TclpFindSymbol --
*
- * Looks up a symbol, by name, through a handle associated with a
- * previously loaded piece of code (shared library).
+ * Looks up a symbol, by name, through a handle associated with
+ * a previously loaded piece of code (shared library).
*
* Results:
- * Returns a pointer to the function associated with 'symbol' if it is
- * found. Otherwise returns NULL and may leave an error message in the
- * interp's result.
+ * Returns a pointer to the function associated with 'symbol' if
+ * it is found. Otherwise returns NULL and may leave an error
+ * message in the interp's result.
*
*----------------------------------------------------------------------
*/
-
-Tcl_PackageInitProc *
-TclpFindSymbol(
- Tcl_Interp *interp,
- Tcl_LoadHandle loadHandle,
- CONST char *symbol)
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ Tcl_LoadHandle loadHandle;
+ CONST char *symbol;
{
Tcl_PackageInitProc *proc = NULL;
HINSTANCE handle = (HINSTANCE)loadHandle;
@@ -168,7 +159,6 @@ TclpFindSymbol(
proc = (Tcl_PackageInitProc *) GetProcAddress(handle, symbol);
if (proc == NULL) {
Tcl_DString ds;
-
Tcl_DStringInit(&ds);
Tcl_DStringAppend(&ds, "_", 1);
symbol = Tcl_DStringAppend(&ds, symbol, -1);
@@ -183,9 +173,9 @@ TclpFindSymbol(
*
* TclpUnloadFile --
*
- * Unloads a dynamically loaded binary code file from memory. Code
- * pointers in the formerly loaded file are no longer valid after calling
- * this function.
+ * Unloads a dynamically loaded binary code file from memory.
+ * Code pointers in the formerly loaded file are no longer valid
+ * after calling this function.
*
* Results:
* None.
@@ -197,10 +187,11 @@ TclpFindSymbol(
*/
void
-TclpUnloadFile(
- Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to
- * TclpDlopen(). The loadHandle is a token
- * that represents the loaded file. */
+TclpUnloadFile(loadHandle)
+ Tcl_LoadHandle loadHandle; /* loadHandle returned by a previous call
+ * to TclpDlopen(). The loadHandle is
+ * a token that represents the loaded
+ * file. */
{
HINSTANCE handle;
@@ -213,14 +204,14 @@ TclpUnloadFile(
*
* TclGuessPackageName --
*
- * If the "load" command is invoked without providing a package name,
- * this function is invoked to try to figure it out.
+ * If the "load" command is invoked without providing a package
+ * name, this procedure is invoked to try to figure it out.
*
* Results:
- * Always returns 0 to indicate that we couldn't figure out a package
- * name; generic code will then try to guess the package from the file
- * name. A return value of 1 would have meant that we figured out the
- * package name and put it in bufPtr.
+ * Always returns 0 to indicate that we couldn't figure out a
+ * package name; generic code will then try to guess the package
+ * from the file name. A return value of 1 would have meant that
+ * we figured out the package name and put it in bufPtr.
*
* Side effects:
* None.
@@ -229,19 +220,11 @@ TclpUnloadFile(
*/
int
-TclGuessPackageName(
- CONST char *fileName, /* Name of file containing package (already
+TclGuessPackageName(fileName, bufPtr)
+ CONST char *fileName; /* Name of file containing package (already
* translated to local form if needed). */
- Tcl_DString *bufPtr) /* Initialized empty dstring. Append package
- * name to this if possible. */
+ Tcl_DString *bufPtr; /* Initialized empty dstring. Append
+ * package name to this if possible. */
{
return 0;
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinMtherr.c b/win/tclWinMtherr.c
new file mode 100644
index 0000000..269a363
--- /dev/null
+++ b/win/tclWinMtherr.c
@@ -0,0 +1,55 @@
+/*
+ * tclWinMtherr.c --
+ *
+ * This function provides a default implementation of the
+ * _matherr function for Borland C++.
+ *
+ * Copyright (c) 1995 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclWinInt.h"
+#include <math.h>
+
+
+#ifndef __MINGW32__
+/*
+ *----------------------------------------------------------------------
+ *
+ * _matherr --
+ *
+ * This procedure is invoked by Borland C++ when certain
+ * errors occur in mathematical functions. This procedure
+ * replaces the default implementation which generates pop-up
+ * warnings.
+ *
+ * Results:
+ * Returns 1 to indicate that we've handled the error
+ * locally.
+ *
+ * Side effects:
+ * Sets errno based on what's in xPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+_matherr(xPtr)
+ struct exception *xPtr; /* Describes error that occurred. */
+{
+ if ((xPtr->type == DOMAIN)
+#ifdef __BORLANDC__
+ || (xPtr->type == TLOSS)
+#endif
+ || (xPtr->type == SING)) {
+ errno = EDOM;
+ } else {
+ errno = ERANGE;
+ }
+ return 1;
+}
+
+#endif /* !__MINGW__ */
+
diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c
index 1cd5823..3ac1c6c 100644
--- a/win/tclWinNotify.c
+++ b/win/tclWinNotify.c
@@ -1,30 +1,30 @@
-/*
+/*
* tclWinNotify.c --
*
- * This file contains Windows-specific procedures for the notifier, which
- * is the lowest-level part of the Tcl event loop. This file works
- * together with ../generic/tclNotify.c.
+ * This file contains Windows-specific procedures for the notifier,
+ * which is the lowest-level part of the Tcl event loop. This file
+ * works together with ../generic/tclNotify.c.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tclInt.h"
+#include "tclWinInt.h"
/*
* The follwing static indicates whether this module has been initialized.
*/
-#define INTERVAL_TIMER 1 /* Handle of interval timer. */
+#define INTERVAL_TIMER 1 /* Handle of interval timer. */
-#define WM_WAKEUP WM_USER /* Message that is send by
+#define WM_WAKEUP WM_USER /* Message that is send by
* Tcl_AlertNotifier. */
/*
* The following static structure contains the state information for the
- * Windows implementation of the Tcl notifier. One of these structures is
- * created for each thread that is using the notifier.
+ * Windows implementation of the Tcl notifier. One of these structures
+ * is created for each thread that is using the notifier.
*/
typedef struct ThreadSpecificData {
@@ -33,8 +33,8 @@ typedef struct ThreadSpecificData {
* notifier. */
HANDLE event; /* Event object used to wake up the notifier
* thread. */
- int pending; /* Alert message pending, this field is locked
- * by the notifierMutex. */
+ int pending; /* Alert message pending, this field is
+ * locked by the notifierMutex. */
HWND hwnd; /* Messaging window. */
int timeout; /* Current timeout value. */
int timerActive; /* 1 if interval timer is running. */
@@ -46,8 +46,9 @@ extern TclStubs tclStubs;
extern Tcl_NotifierProcs tclOriginalNotifier;
/*
- * The following static indicates the number of threads that have initialized
- * notifiers. It controls the lifetime of the TclNotifier window class.
+ * The following static indicates the number of threads that have
+ * initialized notifiers. It controls the lifetime of the TclNotifier
+ * window class.
*
* You must hold the notifierMutex lock before accessing this variable.
*/
@@ -59,8 +60,9 @@ TCL_DECLARE_MUTEX(notifierMutex)
* Static routines defined in this file.
*/
-static LRESULT CALLBACK NotifierProc(HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam);
+static LRESULT CALLBACK NotifierProc(HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+
/*
*----------------------------------------------------------------------
@@ -79,14 +81,14 @@ static LRESULT CALLBACK NotifierProc(HWND hwnd, UINT message,
*/
ClientData
-Tcl_InitNotifier(void)
+Tcl_InitNotifier()
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
WNDCLASS class;
/*
- * Register Notifier window class if this is the first thread to use this
- * module.
+ * Register Notifier window class if this is the first thread to
+ * use this module.
*/
Tcl_MutexLock(&notifierMutex);
@@ -103,7 +105,7 @@ Tcl_InitNotifier(void)
class.hCursor = NULL;
if (!RegisterClassA(&class)) {
- Tcl_Panic("Unable to register TclNotifier window class");
+ panic("Unable to register TclNotifier window class");
}
}
notifierCount++;
@@ -127,8 +129,8 @@ Tcl_InitNotifier(void)
*
* Tcl_FinalizeNotifier --
*
- * This function is called to cleanup the notifier state before a thread
- * is terminated.
+ * This function is called to cleanup the notifier state before
+ * a thread is terminated.
*
* Results:
* None.
@@ -140,22 +142,21 @@ Tcl_InitNotifier(void)
*/
void
-Tcl_FinalizeNotifier(
- ClientData clientData) /* Pointer to notifier data. */
+Tcl_FinalizeNotifier(clientData)
+ ClientData clientData; /* Pointer to notifier data. */
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
/*
- * Only finalize the notifier if a notifier was installed in the current
- * thread; there is a route in which this is not guaranteed to be true
- * (when tclWin32Dll.c:DllMain() is called with the flag
- * DLL_PROCESS_DETACH by the OS, which could be doing so from a thread
- * that's never previously been involved with Tcl, e.g. the task manager)
- * so this check is important.
+ * Only finalize the notifier if a notifier was installed in the
+ * current thread; there is a route in which this is not
+ * guaranteed to be true (when tclWin32Dll.c:DllMain() is called
+ * with the flag DLL_PROCESS_DETACH by the OS, which could be
+ * doing so from a thread that's never previously been involved
+ * with Tcl, e.g. the task manager) so this check is important.
*
* Fixes Bug #217982 reported by Hugh Vu and Gene Leache.
*/
-
if (tsdPtr == NULL) {
return;
}
@@ -173,8 +174,8 @@ Tcl_FinalizeNotifier(
}
/*
- * If this is the last thread to use the notifier, unregister the notifier
- * window class.
+ * If this is the last thread to use the notifier, unregister
+ * the notifier window class.
*/
Tcl_MutexLock(&notifierMutex);
@@ -190,33 +191,34 @@ Tcl_FinalizeNotifier(
*
* Tcl_AlertNotifier --
*
- * Wake up the specified notifier from any thread. This routine is called
- * by the platform independent notifier code whenever the Tcl_ThreadAlert
- * routine is called. This routine is guaranteed not to be called on a
- * given notifier after Tcl_FinalizeNotifier is called for that notifier.
- * This routine is typically called from a thread other than the
- * notifier's thread.
+ * Wake up the specified notifier from any thread. This routine
+ * is called by the platform independent notifier code whenever
+ * the Tcl_ThreadAlert routine is called. This routine is
+ * guaranteed not to be called on a given notifier after
+ * Tcl_FinalizeNotifier is called for that notifier. This routine
+ * is typically called from a thread other than the notifier's
+ * thread.
*
* Results:
* None.
*
* Side effects:
- * Sends a message to the messaging window for the notifier if there
- * isn't already one pending.
+ * Sends a message to the messaging window for the notifier
+ * if there isn't already one pending.
*
*----------------------------------------------------------------------
*/
void
-Tcl_AlertNotifier(
- ClientData clientData) /* Pointer to thread data. */
+Tcl_AlertNotifier(clientData)
+ ClientData clientData; /* Pointer to thread data. */
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
/*
- * Note that we do not need to lock around access to the hwnd because the
- * race condition has no effect since any race condition implies that the
- * notifier thread is already awake.
+ * Note that we do not need to lock around access to the hwnd
+ * because the race condition has no effect since any race condition
+ * implies that the notifier thread is already awake.
*/
if (tsdPtr->hwnd) {
@@ -240,9 +242,9 @@ Tcl_AlertNotifier(
*
* Tcl_SetTimer --
*
- * This procedure sets the current notifier timer value. The notifier
- * will ensure that Tcl_ServiceAll() is called after the specified
- * interval, even if no events have occurred.
+ * This procedure sets the current notifier timer value. The
+ * notifier will ensure that Tcl_ServiceAll() is called after
+ * the specified interval, even if no events have occurred.
*
* Results:
* None.
@@ -261,8 +263,8 @@ Tcl_SetTimer(
UINT timeout;
/*
- * Allow the notifier to be hooked. This may not make sense on Windows,
- * but mirrors the UNIX hook.
+ * Allow the notifier to be hooked. This may not make sense
+ * on Windows, but mirrors the UNIX hook.
*/
if (tclStubs.tcl_SetTimer != tclOriginalNotifier.setTimerProc) {
@@ -271,9 +273,10 @@ Tcl_SetTimer(
}
/*
- * We only need to set up an interval timer if we're being called from an
- * external event loop. If we don't have a window handle then we just
- * return immediately and let Tcl_WaitForEvent handle timeouts.
+ * We only need to set up an interval timer if we're being called
+ * from an external event loop. If we don't have a window handle
+ * then we just return immediately and let Tcl_WaitForEvent handle
+ * timeouts.
*/
if (!tsdPtr->hwnd) {
@@ -296,8 +299,8 @@ Tcl_SetTimer(
tsdPtr->timeout = timeout;
if (timeout != 0) {
tsdPtr->timerActive = 1;
- SetTimer(tsdPtr->hwnd, INTERVAL_TIMER, (unsigned long) tsdPtr->timeout,
- NULL);
+ SetTimer(tsdPtr->hwnd, INTERVAL_TIMER,
+ (unsigned long) tsdPtr->timeout, NULL);
} else {
tsdPtr->timerActive = 0;
KillTimer(tsdPtr->hwnd, INTERVAL_TIMER);
@@ -315,37 +318,37 @@ Tcl_SetTimer(
* None.
*
* Side effects:
- * If this is the first time the notifier is set into TCL_SERVICE_ALL,
- * then the communication window is created.
+ * If this is the first time the notifier is set into
+ * TCL_SERVICE_ALL, then the communication window is created.
*
*----------------------------------------------------------------------
*/
void
-Tcl_ServiceModeHook(
- int mode) /* Either TCL_SERVICE_ALL, or
+Tcl_ServiceModeHook(mode)
+ int mode; /* Either TCL_SERVICE_ALL, or
* TCL_SERVICE_NONE. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
- * If this is the first time that the notifier has been used from a modal
- * loop, then create a communication window. Note that after this point,
- * the application needs to service events in a timely fashion or Windows
- * will hang waiting for the window to respond to synchronous system
- * messages. At some point, we may want to consider destroying the window
- * if we leave the modal loop, but for now we'll leave it around.
+ * If this is the first time that the notifier has been used from a
+ * modal loop, then create a communication window. Note that after
+ * this point, the application needs to service events in a timely
+ * fashion or Windows will hang waiting for the window to respond
+ * to synchronous system messages. At some point, we may want to
+ * consider destroying the window if we leave the modal loop, but
+ * for now we'll leave it around.
*/
if (mode == TCL_SERVICE_ALL && !tsdPtr->hwnd) {
tsdPtr->hwnd = CreateWindowA("TclNotifier", "TclNotifier", WS_TILED,
0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL);
-
/*
* Send an initial message to the window to ensure that we wake up the
- * notifier once we get into the modal loop. This will force the
- * notifier to recompute the timeout value and schedule a timer if one
- * is needed.
+ * notifier once we get into the modal loop. This will force the
+ * notifier to recompute the timeout value and schedule a timer
+ * if one is needed.
*/
Tcl_AlertNotifier((ClientData)tsdPtr);
@@ -357,9 +360,10 @@ Tcl_ServiceModeHook(
*
* NotifierProc --
*
- * This procedure is invoked by Windows to process events on the notifier
- * window. Messages will be sent to this window in response to external
- * timer events or calls to TclpAlertTsdPtr->
+ * This procedure is invoked by Windows to process events on
+ * the notifier window. Messages will be sent to this window
+ * in response to external timer events or calls to
+ * TclpAlertTsdPtr->
*
* Results:
* A standard windows result.
@@ -372,10 +376,10 @@ Tcl_ServiceModeHook(
static LRESULT CALLBACK
NotifierProc(
- HWND hwnd, /* Passed on... */
- UINT message, /* What messsage is this? */
- WPARAM wParam, /* Passed on... */
- LPARAM lParam) /* Passed on... */
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -386,7 +390,7 @@ NotifierProc(
} else if (message != WM_TIMER) {
return DefWindowProc(hwnd, message, wParam, lParam);
}
-
+
/*
* Process all of the runnable events.
*/
@@ -400,16 +404,17 @@ NotifierProc(
*
* Tcl_WaitForEvent --
*
- * This function is called by Tcl_DoOneEvent to wait for new events on
- * the message queue. If the block time is 0, then Tcl_WaitForEvent just
- * polls the event queue without blocking.
+ * This function is called by Tcl_DoOneEvent to wait for new
+ * events on the message queue. If the block time is 0, then
+ * Tcl_WaitForEvent just polls the event queue without blocking.
*
* Results:
- * Returns -1 if a WM_QUIT message is detected, returns 1 if a message
- * was dispatched, otherwise returns 0.
+ * Returns -1 if a WM_QUIT message is detected, returns 1 if
+ * a message was dispatched, otherwise returns 0.
*
* Side effects:
- * Dispatches a message to a window procedure, which could do anything.
+ * Dispatches a message to a window procedure, which could do
+ * anything.
*
*----------------------------------------------------------------------
*/
@@ -424,8 +429,8 @@ Tcl_WaitForEvent(
int status;
/*
- * Allow the notifier to be hooked. This may not make sense on windows,
- * but mirrors the UNIX hook.
+ * Allow the notifier to be hooked. This may not make
+ * sense on windows, but mirrors the UNIX hook.
*/
if (tclStubs.tcl_WaitForEvent != tclOriginalNotifier.waitForEventProc) {
@@ -437,21 +442,7 @@ Tcl_WaitForEvent(
*/
if (timePtr) {
- /*
- * TIP #233 (Virtualized Time). Convert virtual domain delay to
- * real-time.
- */
-
- Tcl_Time myTime;
-
- myTime.sec = timePtr->sec;
- myTime.usec = timePtr->usec;
-
- if (myTime.sec != 0 || myTime.usec != 0) {
- (*tclScaleTimeProcPtr) (&myTime, tclTimeClientData);
- }
-
- timeout = myTime.sec * 1000 + myTime.usec / 1000;
+ timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
} else {
timeout = INFINITE;
}
@@ -465,19 +456,11 @@ Tcl_WaitForEvent(
if (!PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
/*
* Wait for something to happen (a signal from another thread, a
- * message, or timeout) or loop servicing asynchronous procedure calls
- * queued to this thread.
+ * message, or timeout).
*/
- again:
- result = MsgWaitForMultipleObjectsEx(1, &tsdPtr->event, timeout,
- QS_ALLINPUT, MWMO_ALERTABLE);
- if (result == WAIT_IO_COMPLETION) {
- goto again;
- } else if (result == WAIT_FAILED) {
- status = -1;
- goto end;
- }
+ result = MsgWaitForMultipleObjects(1, &tsdPtr->event, FALSE, timeout,
+ QS_ALLINPUT);
}
/*
@@ -500,7 +483,7 @@ Tcl_WaitForEvent(
status = -1;
} else if (result == (DWORD)-1) {
/*
- * We got an error from the system. I have no idea why this would
+ * We got an error from the system. I have no idea why this would
* happen, so we'll just unwind.
*/
@@ -514,7 +497,6 @@ Tcl_WaitForEvent(
status = 0;
}
- end:
ResetEvent(tsdPtr->event);
return status;
}
@@ -536,64 +518,42 @@ Tcl_WaitForEvent(
*/
void
-Tcl_Sleep(
- int ms) /* Number of milliseconds to sleep. */
+Tcl_Sleep(ms)
+ int ms; /* Number of milliseconds to sleep. */
{
/*
- * Simply calling 'Sleep' for the requisite number of milliseconds can
- * make the process appear to wake up early because it isn't synchronized
- * with the CPU performance counter that is used in tclWinTime.c. This
- * behavior is probably benign, but messes up some of the corner cases in
- * the test suite. We get around this problem by repeating the 'Sleep'
- * call as many times as necessary to make the clock advance by the
- * requisite amount.
+ * Simply calling 'Sleep' for the requisite number of milliseconds
+ * can make the process appear to wake up early because it isn't
+ * synchronized with the CPU performance counter that is used in
+ * tclWinTime.c. This behavior is probably benign, but messes
+ * up some of the corner cases in the test suite. We get around
+ * this problem by repeating the 'Sleep' call as many times
+ * as necessary to make the clock advance by the requisite amount.
*/
- Tcl_Time now; /* Current wall clock time. */
- Tcl_Time desired; /* Desired wakeup time. */
- Tcl_Time vdelay; /* Time to sleep, for scaling virtual ->
- * real. */
- DWORD sleepTime; /* Time to sleep, real-time */
-
- vdelay.sec = ms / 1000;
- vdelay.usec = (ms % 1000) * 1000;
+ Tcl_Time now; /* Current wall clock time */
+ Tcl_Time desired; /* Desired wakeup time */
+ DWORD sleepTime = ms; /* Time to sleep */
- Tcl_GetTime(&now);
- desired.sec = now.sec + vdelay.sec;
- desired.usec = now.usec + vdelay.usec;
- if (desired.usec > 1000000) {
+ Tcl_GetTime( &now );
+ desired.sec = now.sec + ( ms / 1000 );
+ desired.usec = now.usec + 1000 * ( ms % 1000 );
+ if ( desired.usec > 1000000 ) {
++desired.sec;
desired.usec -= 1000000;
}
-
- /*
- * TIP #233: Scale delay from virtual to real-time.
- */
-
- (*tclScaleTimeProcPtr) (&vdelay, tclTimeClientData);
- sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000;
-
- for (;;) {
- Sleep(sleepTime);
- Tcl_GetTime(&now);
- if (now.sec > desired.sec) {
+
+ for ( ; ; ) {
+ Sleep( sleepTime );
+ Tcl_GetTime( &now );
+ if ( now.sec > desired.sec ) {
break;
- } else if ((now.sec == desired.sec) && (now.usec >= desired.usec)) {
+ } else if ( ( now.sec == desired.sec )
+ && ( now.usec >= desired.usec ) ) {
break;
}
-
- vdelay.sec = desired.sec - now.sec;
- vdelay.usec = desired.usec - now.usec;
-
- (*tclScaleTimeProcPtr) (&vdelay, tclTimeClientData);
- sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000;
+ sleepTime = ( ( 1000 * ( desired.sec - now.sec ) )
+ + ( ( desired.usec - now.usec ) / 1000 ) );
}
+
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c
index b29dde4..f15daa5 100644
--- a/win/tclWinPipe.c
+++ b/win/tclWinPipe.c
@@ -1,17 +1,19 @@
-/*
+/*
* tclWinPipe.c --
*
- * This file implements the Windows-specific exec pipeline functions, the
- * "pipe" channel driver, and the "pid" Tcl command.
+ * This file implements the Windows-specific exec pipeline functions,
+ * the "pipe" channel driver, and the "pid" Tcl command.
*
* Copyright (c) 1996-1997 by Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclWinInt.h"
+#include <fcntl.h>
+#include <io.h>
#include <sys/stat.h>
/*
@@ -22,16 +24,16 @@
static int initialized = 0;
/*
- * The pipeMutex locks around access to the initialized and procList
- * variables, and it is used to protect background threads from being
- * terminated while they are using APIs that hold locks.
+ * The pipeMutex locks around access to the initialized and procList variables,
+ * and it is used to protect background threads from being terminated while
+ * they are using APIs that hold locks.
*/
TCL_DECLARE_MUTEX(pipeMutex)
/*
- * The following defines identify the various types of applications that run
- * under windows. There is special case code for the various types.
+ * The following defines identify the various types of applications that
+ * run under windows. There is special case code for the various types.
*/
#define APPL_NONE 0
@@ -40,16 +42,16 @@ TCL_DECLARE_MUTEX(pipeMutex)
#define APPL_WIN32 3
/*
- * The following constants and structures are used to encapsulate the state of
- * various types of files used in a pipeline. This used to have a 1 && 2 that
- * supported Win32s.
+ * The following constants and structures are used to encapsulate the state
+ * of various types of files used in a pipeline.
+ * This used to have a 1 && 2 that supported Win32s.
*/
-#define WIN_FILE 3 /* Basic Win32 file. */
+#define WIN_FILE 3 /* Basic Win32 file. */
/*
- * This structure encapsulates the common state associated with all file types
- * used in a pipeline.
+ * This structure encapsulates the common state associated with all file
+ * types used in a pipeline.
*/
typedef struct WinFile {
@@ -108,64 +110,66 @@ typedef struct PipeInfo {
HANDLE writeThread; /* Handle to writer thread. */
HANDLE readThread; /* Handle to reader thread. */
HANDLE writable; /* Manual-reset event to signal when the
- * writer thread has finished waiting for the
- * current buffer to be written. */
+ * writer thread has finished waiting for
+ * the current buffer to be written. */
HANDLE readable; /* Manual-reset event to signal when the
* reader thread has finished waiting for
* input. */
HANDLE startWriter; /* Auto-reset event used by the main thread to
- * signal when the writer thread should
- * attempt to write to the pipe. */
+ * signal when the writer thread should attempt
+ * to write to the pipe. */
HANDLE stopWriter; /* Manual-reset event used to alert the reader
* thread to fall-out and exit */
HANDLE startReader; /* Auto-reset event used by the main thread to
- * signal when the reader thread should
- * attempt to read from the pipe. */
+ * signal when the reader thread should attempt
+ * to read from the pipe. */
HANDLE stopReader; /* Manual-reset event used to alert the reader
* thread to fall-out and exit */
DWORD writeError; /* An error caused by the last background
- * write. Set to 0 if no error has been
- * detected. This word is shared with the
+ * write. Set to 0 if no error has been
+ * detected. This word is shared with the
* writer thread so access must be
* synchronized with the writable object.
*/
- char *writeBuf; /* Current background output buffer. Access is
- * synchronized with the writable object. */
- int writeBufLen; /* Size of write buffer. Access is
- * synchronized with the writable object. */
- int toWrite; /* Current amount to be written. Access is
+ char *writeBuf; /* Current background output buffer.
+ * Access is synchronized with the writable
+ * object. */
+ int writeBufLen; /* Size of write buffer. Access is
+ * synchronized with the writable
+ * object. */
+ int toWrite; /* Current amount to be written. Access is
* synchronized with the writable object. */
int readFlags; /* Flags that are shared with the reader
- * thread. Access is synchronized with the
+ * thread. Access is synchronized with the
* readable object. */
char extraByte; /* Buffer for extra character consumed by
- * reader thread. This byte is shared with the
- * reader thread so access must be
+ * reader thread. This byte is shared with
+ * the reader thread so access must be
* synchronized with the readable object. */
} PipeInfo;
typedef struct ThreadSpecificData {
/*
- * The following pointer refers to the head of the list of pipes that are
- * being watched for file events.
+ * The following pointer refers to the head of the list of pipes
+ * that are being watched for file events.
*/
-
+
PipeInfo *firstPipePtr;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * The following structure is what is added to the Tcl event queue when pipe
- * events are generated.
+ * The following structure is what is added to the Tcl event queue when
+ * pipe events are generated.
*/
typedef struct PipeEvent {
- Tcl_Event header; /* Information that is standard for all
- * events. */
- PipeInfo *infoPtr; /* Pointer to pipe info structure. Note that
- * we still have to verify that the pipe
- * exists before dereferencing this
+ Tcl_Event header; /* Information that is standard for
+ * all events. */
+ PipeInfo *infoPtr; /* Pointer to pipe info structure. Note
+ * that we still have to verify that the
+ * pipe exists before dereferencing this
* pointer. */
} PipeEvent;
@@ -175,8 +179,8 @@ typedef struct PipeEvent {
static int ApplicationType(Tcl_Interp *interp,
const char *fileName, char *fullName);
-static void BuildCommandLine(const char *executable, int argc,
- const char **argv, Tcl_DString *linePtr);
+static void BuildCommandLine(const char *executable, int argc,
+ CONST char **argv, Tcl_DString *linePtr);
static BOOL HasConsole(void);
static int PipeBlockModeProc(ClientData instanceData, int mode);
static void PipeCheckProc(ClientData clientData, int flags);
@@ -189,24 +193,25 @@ static void PipeInit(void);
static int PipeInputProc(ClientData instanceData, char *buf,
int toRead, int *errorCode);
static int PipeOutputProc(ClientData instanceData,
- const char *buf, int toWrite, int *errorCode);
+ CONST char *buf, int toWrite, int *errorCode);
static DWORD WINAPI PipeReaderThread(LPVOID arg);
static void PipeSetupProc(ClientData clientData, int flags);
static void PipeWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI PipeWriterThread(LPVOID arg);
static int TempFileName(WCHAR name[MAX_PATH]);
static int WaitForRead(PipeInfo *infoPtr, int blocking);
-static void PipeThreadActionProc(ClientData instanceData,
- int action);
+
+static void PipeThreadActionProc _ANSI_ARGS_ ((
+ ClientData instanceData, int action));
/*
- * This structure describes the channel type structure for command pipe based
- * I/O.
+ * This structure describes the channel type structure for command pipe
+ * based IO.
*/
static Tcl_ChannelType pipeChannelType = {
"pipe", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
+ TCL_CHANNEL_VERSION_4, /* v4 channel */
TCL_CLOSE2PROC, /* Close proc. */
PipeInputProc, /* Input proc. */
PipeOutputProc, /* Output proc. */
@@ -219,9 +224,8 @@ static Tcl_ChannelType pipeChannelType = {
PipeBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
- NULL, /* wide seek proc */
- PipeThreadActionProc, /* thread action proc */
- NULL, /* truncate */
+ NULL, /* wide seek proc */
+ PipeThreadActionProc, /* thread action proc */
};
/*
@@ -241,13 +245,13 @@ static Tcl_ChannelType pipeChannelType = {
*/
static void
-PipeInit(void)
+PipeInit()
{
ThreadSpecificData *tsdPtr;
/*
- * Check the initialized flag first, then check again in the mutex. This
- * is a speed enhancement.
+ * Check the initialized flag first, then check again in the mutex.
+ * This is a speed enhancement.
*/
if (!initialized) {
@@ -272,7 +276,7 @@ PipeInit(void)
*
* TclpFinalizePipes --
*
- * This function is called from Tcl_FinalizeThread to finalize the
+ * This function is called from Tcl_FinalizeThread to finalize the
* platform specific pipe subsystem.
*
* Results:
@@ -285,8 +289,8 @@ PipeInit(void)
*/
void
-TclpFinalizePipes(void)
-{
+TclpFinalizePipes()
+{
ThreadSpecificData *tsdPtr;
tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
@@ -300,8 +304,8 @@ TclpFinalizePipes(void)
*
* PipeSetupProc --
*
- * This function is invoked before Tcl_DoOneEvent blocks waiting for an
- * event.
+ * This procedure is invoked before Tcl_DoOneEvent blocks waiting
+ * for an event.
*
* Results:
* None.
@@ -325,12 +329,12 @@ PipeSetupProc(
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
-
+
/*
* Look to see if any events are already pending. If they are, poll.
*/
- for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL;
+ for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr->watchMask & TCL_WRITABLE) {
if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
@@ -353,8 +357,8 @@ PipeSetupProc(
*
* PipeCheckProc --
*
- * This function is called by Tcl_DoOneEvent to check the pipe event
- * source for events.
+ * This procedure is called by Tcl_DoOneEvent to check the pipe
+ * event source for events.
*
* Results:
* None.
@@ -378,17 +382,18 @@ PipeCheckProc(
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
-
+
/*
- * Queue events for any ready pipes that don't already have events queued.
+ * Queue events for any ready pipes that don't already have events
+ * queued.
*/
- for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL;
+ for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr->flags & PIPE_PENDING) {
continue;
}
-
+
/*
* Queue an event if the pipe is signaled for reading or writing.
*/
@@ -398,7 +403,7 @@ PipeCheckProc(
(WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT)) {
needEvent = 1;
}
-
+
if ((infoPtr->watchMask & TCL_READABLE) &&
(WaitForRead(infoPtr, 0) >= 0)) {
needEvent = 1;
@@ -419,8 +424,8 @@ PipeCheckProc(
*
* TclWinMakeFile --
*
- * This function constructs a new TclFile from a given data and type
- * value.
+ * This function constructs a new TclFile from a given data and
+ * type value.
*
* Results:
* Returns a newly allocated WinFile as a TclFile.
@@ -449,14 +454,15 @@ TclWinMakeFile(
*
* TempFileName --
*
- * Gets a temporary file name and deals with the fact that the temporary
- * file path provided by Windows may not actually exist if the TMP or
- * TEMP environment variables refer to a non-existent directory.
+ * Gets a temporary file name and deals with the fact that the
+ * temporary file path provided by Windows may not actually exist
+ * if the TMP or TEMP environment variables refer to a
+ * non-existent directory.
*
- * Results:
- * 0 if error, non-zero otherwise. If non-zero is returned, the name
- * buffer will be filled with a name that can be used to construct a
- * temporary file.
+ * Results:
+ * 0 if error, non-zero otherwise. If non-zero is returned, the
+ * name buffer will be filled with a name that can be used to
+ * construct a temporary file.
*
* Side effects:
* None.
@@ -465,15 +471,15 @@ TclWinMakeFile(
*/
static int
-TempFileName(
- WCHAR name[MAX_PATH]) /* Buffer in which name for temporary file
- * gets stored. */
+TempFileName(name)
+ WCHAR name[MAX_PATH]; /* Buffer in which name for temporary
+ * file gets stored. */
{
TCHAR *prefix;
prefix = (tclWinProcs->useWide) ? (TCHAR *) L"TCL" : (TCHAR *) "TCL";
if ((*tclWinProcs->getTempPathProc)(MAX_PATH, name) != 0) {
- if ((*tclWinProcs->getTempFileNameProc)((TCHAR *) name, prefix, 0,
+ if ((*tclWinProcs->getTempFileNameProc)((TCHAR *) name, prefix, 0,
name) != 0) {
return 1;
}
@@ -485,7 +491,7 @@ TempFileName(
((char *) name)[0] = '.';
((char *) name)[1] = '\0';
}
- return (*tclWinProcs->getTempFileNameProc)((TCHAR *) name, prefix, 0,
+ return (*tclWinProcs->getTempFileNameProc)((TCHAR *) name, prefix, 0,
name);
}
@@ -506,13 +512,13 @@ TempFileName(
*/
TclFile
-TclpMakeFile(
- Tcl_Channel channel, /* Channel to get file from. */
- int direction) /* Either TCL_READABLE or TCL_WRITABLE. */
+TclpMakeFile(channel, direction)
+ Tcl_Channel channel; /* Channel to get file from. */
+ int direction; /* Either TCL_READABLE or TCL_WRITABLE. */
{
HANDLE handle;
- if (Tcl_GetChannelHandle(channel, direction,
+ if (Tcl_GetChannelHandle(channel, direction,
(ClientData *) &handle) == TCL_OK) {
return TclWinMakeFile(handle);
} else {
@@ -528,8 +534,8 @@ TclpMakeFile(
* This function opens files for use in a pipeline.
*
* Results:
- * Returns a newly allocated TclFile structure containing the file
- * handle.
+ * Returns a newly allocated TclFile structure containing the
+ * file handle.
*
* Side effects:
* None.
@@ -538,32 +544,32 @@ TclpMakeFile(
*/
TclFile
-TclpOpenFile(
- const char *path, /* The name of the file to open. */
- int mode) /* In what mode to open the file? */
+TclpOpenFile(path, mode)
+ CONST char *path; /* The name of the file to open. */
+ int mode; /* In what mode to open the file? */
{
HANDLE handle;
DWORD accessMode, createMode, shareMode, flags;
Tcl_DString ds;
- const TCHAR *nativePath;
-
+ CONST TCHAR *nativePath;
+
/*
* Map the access bits to the NT access mode.
*/
switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
- case O_RDONLY:
- accessMode = GENERIC_READ;
- break;
- case O_WRONLY:
- accessMode = GENERIC_WRITE;
- break;
- case O_RDWR:
- accessMode = (GENERIC_READ | GENERIC_WRITE);
- break;
- default:
- TclWinConvertError(ERROR_INVALID_FUNCTION);
- return NULL;
+ case O_RDONLY:
+ accessMode = GENERIC_READ;
+ break;
+ case O_WRONLY:
+ accessMode = GENERIC_WRITE;
+ break;
+ case O_RDWR:
+ accessMode = (GENERIC_READ | GENERIC_WRITE);
+ break;
+ default:
+ TclWinConvertError(ERROR_INVALID_FUNCTION);
+ return NULL;
}
/*
@@ -571,23 +577,23 @@ TclpOpenFile(
*/
switch (mode & (O_CREAT | O_EXCL | O_TRUNC)) {
- case (O_CREAT | O_EXCL):
- case (O_CREAT | O_EXCL | O_TRUNC):
- createMode = CREATE_NEW;
- break;
- case (O_CREAT | O_TRUNC):
- createMode = CREATE_ALWAYS;
- break;
- case O_CREAT:
- createMode = OPEN_ALWAYS;
- break;
- case O_TRUNC:
- case (O_TRUNC | O_EXCL):
- createMode = TRUNCATE_EXISTING;
- break;
- default:
- createMode = OPEN_EXISTING;
- break;
+ case (O_CREAT | O_EXCL):
+ case (O_CREAT | O_EXCL | O_TRUNC):
+ createMode = CREATE_NEW;
+ break;
+ case (O_CREAT | O_TRUNC):
+ createMode = CREATE_ALWAYS;
+ break;
+ case O_CREAT:
+ createMode = OPEN_ALWAYS;
+ break;
+ case O_TRUNC:
+ case (O_TRUNC | O_EXCL):
+ createMode = TRUNCATE_EXISTING;
+ break;
+ default:
+ createMode = OPEN_EXISTING;
+ break;
}
nativePath = Tcl_WinUtfToTChar(path, -1, &ds);
@@ -614,19 +620,19 @@ TclpOpenFile(
* Now we get to create the file.
*/
- handle = (*tclWinProcs->createFileProc)(nativePath, accessMode,
+ handle = (*tclWinProcs->createFileProc)(nativePath, accessMode,
shareMode, NULL, createMode, flags, NULL);
Tcl_DStringFree(&ds);
if (handle == INVALID_HANDLE_VALUE) {
DWORD err;
-
+
err = GetLastError();
if ((err & 0xffffL) == ERROR_OPEN_FAILED) {
err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND;
}
- TclWinConvertError(err);
- return NULL;
+ TclWinConvertError(err);
+ return NULL;
}
/*
@@ -645,9 +651,9 @@ TclpOpenFile(
*
* TclpCreateTempFile --
*
- * This function opens a unique file with the property that it will be
- * deleted when its file handle is closed. The temporary file is created
- * in the system temporary directory.
+ * This function opens a unique file with the property that it
+ * will be deleted when its file handle is closed. The temporary
+ * file is created in the system temporary directory.
*
* Results:
* Returns a valid TclFile, or NULL on failure.
@@ -659,11 +665,11 @@ TclpOpenFile(
*/
TclFile
-TclpCreateTempFile(
- const char *contents) /* String to write into temp file, or NULL. */
+TclpCreateTempFile(contents)
+ CONST char *contents; /* String to write into temp file, or NULL. */
{
WCHAR name[MAX_PATH];
- const char *native;
+ CONST char *native;
Tcl_DString dstring;
HANDLE handle;
@@ -671,8 +677,8 @@ TclpCreateTempFile(
return NULL;
}
- handle = (*tclWinProcs->createFileProc)((TCHAR *) name,
- GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+ handle = (*tclWinProcs->createFileProc)((TCHAR *) name,
+ GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, NULL);
if (handle == INVALID_HANDLE_VALUE) {
goto error;
@@ -684,14 +690,13 @@ TclpCreateTempFile(
if (contents != NULL) {
DWORD result, length;
- const char *p;
+ CONST char *p;
/*
* Convert the contents from UTF to native encoding
*/
-
native = Tcl_UtfToExternalDString(NULL, contents, -1, &dstring);
-
+
for (p = native; *p != '\0'; p++) {
if (*p == '\n') {
length = p - native;
@@ -721,10 +726,7 @@ TclpCreateTempFile(
return TclWinMakeFile(handle);
error:
- /*
- * Free the native representation of the contents if necessary.
- */
-
+ /* Free the native representation of the contents if necessary */
if (contents != NULL) {
Tcl_DStringFree(&dstring);
}
@@ -751,8 +753,8 @@ TclpCreateTempFile(
*----------------------------------------------------------------------
*/
-Tcl_Obj *
-TclpTempFileName(void)
+Tcl_Obj*
+TclpTempFileName()
{
WCHAR fileName[MAX_PATH];
@@ -768,23 +770,23 @@ TclpTempFileName(void)
*
* TclpCreatePipe --
*
- * Creates an anonymous pipe.
+ * Creates an anonymous pipe.
*
* Results:
- * Returns 1 on success, 0 on failure.
+ * Returns 1 on success, 0 on failure.
*
* Side effects:
- * Creates a pipe.
+ * Creates a pipe.
*
*----------------------------------------------------------------------
*/
int
TclpCreatePipe(
- TclFile *readPipe, /* Location to store file handle for read side
- * of pipe. */
- TclFile *writePipe) /* Location to store file handle for write
- * side of pipe. */
+ TclFile *readPipe, /* Location to store file handle for
+ * read side of pipe. */
+ TclFile *writePipe) /* Location to store file handle for
+ * write side of pipe. */
{
HANDLE readHandle, writeHandle;
@@ -803,7 +805,7 @@ TclpCreatePipe(
*
* TclpCloseFile --
*
- * Closes a pipeline file handle. These handles are created by
+ * Closes a pipeline file handle. These handles are created by
* TclpOpenFile, TclpCreatePipe, or TclpMakeFile.
*
* Results:
@@ -817,33 +819,33 @@ TclpCreatePipe(
int
TclpCloseFile(
- TclFile file) /* The file to close. */
+ TclFile file) /* The file to close. */
{
WinFile *filePtr = (WinFile *) file;
switch (filePtr->type) {
- case WIN_FILE:
- /*
- * Don't close the Win32 handle if the handle is a standard channel
- * during the thread exit process. Otherwise, one thread may kill the
- * stdio of another.
- */
+ case WIN_FILE:
+ /*
+ * Don't close the Win32 handle if the handle is a standard channel
+ * during the thread exit process. Otherwise, one thread may kill
+ * the stdio of another.
+ */
- if (!TclInThreadExit()
- || ((GetStdHandle(STD_INPUT_HANDLE) != filePtr->handle)
- && (GetStdHandle(STD_OUTPUT_HANDLE) != filePtr->handle)
- && (GetStdHandle(STD_ERROR_HANDLE) != filePtr->handle))) {
- if (filePtr->handle != NULL &&
- CloseHandle(filePtr->handle) == FALSE) {
- TclWinConvertError(GetLastError());
- ckfree((char *) filePtr);
- return -1;
+ if (!TclInThreadExit()
+ || ((GetStdHandle(STD_INPUT_HANDLE) != filePtr->handle)
+ && (GetStdHandle(STD_OUTPUT_HANDLE) != filePtr->handle)
+ && (GetStdHandle(STD_ERROR_HANDLE) != filePtr->handle))) {
+ if (filePtr->handle != NULL &&
+ CloseHandle(filePtr->handle) == FALSE) {
+ TclWinConvertError(GetLastError());
+ ckfree((char *) filePtr);
+ return -1;
+ }
}
- }
- break;
+ break;
- default:
- Tcl_Panic("TclpCloseFile: unexpected file type");
+ default:
+ panic("TclpCloseFile: unexpected file type");
}
ckfree((char *) filePtr);
@@ -859,9 +861,9 @@ TclpCloseFile(
* child process.
*
* Results:
- * Returns the process id for the child process. If the pid was not known
- * by Tcl, either because the pid was not created by Tcl or the child
- * process has already been reaped, -1 is returned.
+ * Returns the process id for the child process. If the pid was not
+ * known by Tcl, either because the pid was not created by Tcl or the
+ * child process has already been reaped, -1 is returned.
*
* Side effects:
* None.
@@ -893,25 +895,25 @@ TclpGetPid(
*
* TclpCreateProcess --
*
- * Create a child process that has the specified files as its standard
- * input, output, and error. The child process runs asynchronously under
- * Windows NT and Windows 9x, and runs with the same environment
- * variables as the creating process.
+ * Create a child process that has the specified files as its
+ * standard input, output, and error. The child process runs
+ * asynchronously under Windows NT and Windows 9x, and runs
+ * with the same environment variables as the creating process.
*
- * The complete Windows search path is searched to find the specified
- * executable. If an executable by the given name is not found,
- * automatically tries appending ".com", ".exe", and ".bat" to the
+ * The complete Windows search path is searched to find the specified
+ * executable. If an executable by the given name is not found,
+ * automatically tries appending ".com", ".exe", and ".bat" to the
* executable name.
*
* Results:
- * The return value is TCL_ERROR and an error message is left in the
- * interp's result if there was a problem creating the child process.
- * Otherwise, the return value is TCL_OK and *pidPtr is filled with the
- * process id of the child process.
- *
+ * The return value is TCL_ERROR and an error message is left in
+ * the interp's result if there was a problem creating the child
+ * process. Otherwise, the return value is TCL_OK and *pidPtr is
+ * filled with the process id of the child process.
+ *
* Side effects:
* A process is created.
- *
+ *
*----------------------------------------------------------------------
*/
@@ -922,27 +924,27 @@ TclpCreateProcess(
* Error messages from the child process
* itself are sent to errorFile. */
int argc, /* Number of arguments in following array. */
- const char **argv, /* Array of argument strings. argv[0] contains
- * the name of the executable converted to
- * native format (using the
- * Tcl_TranslateFileName call). Additional
+ CONST char **argv, /* Array of argument strings. argv[0]
+ * contains the name of the executable
+ * converted to native format (using the
+ * Tcl_TranslateFileName call). Additional
* arguments have not been converted. */
- TclFile inputFile, /* If non-NULL, gives the file to use as input
- * for the child process. If inputFile file is
- * not readable or is NULL, the child will
- * receive no standard input. */
- TclFile outputFile, /* If non-NULL, gives the file that receives
- * output from the child process. If
+ TclFile inputFile, /* If non-NULL, gives the file to use as
+ * input for the child process. If inputFile
+ * file is not readable or is NULL, the child
+ * will receive no standard input. */
+ TclFile outputFile, /* If non-NULL, gives the file that
+ * receives output from the child process. If
* outputFile file is not writeable or is
* NULL, output from the child will be
* discarded. */
- TclFile errorFile, /* If non-NULL, gives the file that receives
- * errors from the child process. If errorFile
- * file is not writeable or is NULL, errors
- * from the child will be discarded. errorFile
- * may be the same as outputFile. */
- Tcl_Pid *pidPtr) /* If this function is successful, pidPtr is
- * filled with the process id of the child
+ TclFile errorFile, /* If non-NULL, gives the file that
+ * receives errors from the child process. If
+ * errorFile file is not writeable or is NULL,
+ * errors from the child will be discarded.
+ * errorFile may be the same as outputFile. */
+ Tcl_Pid *pidPtr) /* If this procedure is successful, pidPtr
+ * is filled with the process id of the child
* process. */
{
int result, applType, createFlags;
@@ -967,13 +969,13 @@ TclpCreateProcess(
/*
* STARTF_USESTDHANDLES must be used to pass handles to child process.
- * Using SetStdHandle() and/or dup2() only works when a console mode
+ * Using SetStdHandle() and/or dup2() only works when a console mode
* parent process is spawning an attached console mode child process.
*/
ZeroMemory(&startInfo, sizeof(startInfo));
startInfo.cb = sizeof(startInfo);
- startInfo.dwFlags = STARTF_USESTDHANDLES;
+ startInfo.dwFlags = STARTF_USESTDHANDLES;
startInfo.hStdInput = INVALID_HANDLE_VALUE;
startInfo.hStdOutput= INVALID_HANDLE_VALUE;
startInfo.hStdError = INVALID_HANDLE_VALUE;
@@ -983,8 +985,8 @@ TclpCreateProcess(
secAtts.bInheritHandle = TRUE;
/*
- * We have to check the type of each file, since we cannot duplicate some
- * file types.
+ * We have to check the type of each file, since we cannot duplicate
+ * some file types.
*/
inputHandle = INVALID_HANDLE_VALUE;
@@ -1010,22 +1012,23 @@ TclpCreateProcess(
}
/*
- * Duplicate all the handles which will be passed off as stdin, stdout and
- * stderr of the child process. The duplicate handles are set to be
- * inheritable, so the child process can use them.
+ * Duplicate all the handles which will be passed off as stdin, stdout
+ * and stderr of the child process. The duplicate handles are set to
+ * be inheritable, so the child process can use them.
*/
if (inputHandle == INVALID_HANDLE_VALUE) {
- /*
- * If handle was not set, stdin should return immediate EOF. Under
- * Windows95, some applications (both 16 and 32 bit!) cannot read from
- * the NUL device; they read from console instead. When running tk,
- * this is fatal because the child process would hang forever waiting
- * for EOF from the unmapped console window used by the helper
- * application.
+ /*
+ * If handle was not set, stdin should return immediate EOF.
+ * Under Windows95, some applications (both 16 and 32 bit!)
+ * cannot read from the NUL device; they read from console
+ * instead. When running tk, this is fatal because the child
+ * process would hang forever waiting for EOF from the unmapped
+ * console window used by the helper application.
*
- * Fortunately, the helper application detects a closed pipe as an
- * immediate EOF and can pass that information to the child process.
+ * Fortunately, the helper application detects a closed pipe
+ * as an immediate EOF and can pass that information to the
+ * child process.
*/
if (CreatePipe(&startInfo.hStdInput, &h, &secAtts, 0) != FALSE) {
@@ -1044,20 +1047,21 @@ TclpCreateProcess(
if (outputHandle == INVALID_HANDLE_VALUE) {
/*
- * If handle was not set, output should be sent to an infinitely deep
- * sink. Under Windows 95, some 16 bit applications cannot have stdout
- * redirected to NUL; they send their output to the console instead.
- * Some applications, like "more" or "dir /p", when outputting
- * multiple pages to the console, also then try and read from the
- * console to go the next page. When running tk, this is fatal because
- * the child process would hang forever waiting for input from the
- * unmapped console window used by the helper application.
+ * If handle was not set, output should be sent to an infinitely
+ * deep sink. Under Windows 95, some 16 bit applications cannot
+ * have stdout redirected to NUL; they send their output to
+ * the console instead. Some applications, like "more" or "dir /p",
+ * when outputting multiple pages to the console, also then try and
+ * read from the console to go the next page. When running tk, this
+ * is fatal because the child process would hang forever waiting
+ * for input from the unmapped console window used by the helper
+ * application.
*
- * Fortunately, the helper application will detect a closed pipe as a
- * sink.
+ * Fortunately, the helper application will detect a closed pipe
+ * as a sink.
*/
- if ((TclWinGetPlatformId() == VER_PLATFORM_WIN32_WINDOWS)
+ if ((TclWinGetPlatformId() == VER_PLATFORM_WIN32_WINDOWS)
&& (applType == APPL_DOS)) {
if (CreatePipe(&h, &startInfo.hStdOutput, &secAtts, 0) != FALSE) {
CloseHandle(h);
@@ -1067,8 +1071,8 @@ TclpCreateProcess(
&secAtts, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
}
} else {
- DuplicateHandle(hProcess, outputHandle, hProcess,
- &startInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
+ DuplicateHandle(hProcess, outputHandle, hProcess, &startInfo.hStdOutput,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
}
if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) {
TclWinConvertError(GetLastError());
@@ -1079,34 +1083,35 @@ TclpCreateProcess(
if (errorHandle == INVALID_HANDLE_VALUE) {
/*
- * If handle was not set, errors should be sent to an infinitely deep
- * sink.
+ * If handle was not set, errors should be sent to an infinitely
+ * deep sink.
*/
startInfo.hStdError = CreateFileA("NUL:", GENERIC_WRITE, 0,
&secAtts, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
} else {
- DuplicateHandle(hProcess, errorHandle, hProcess, &startInfo.hStdError,
+ DuplicateHandle(hProcess, errorHandle, hProcess, &startInfo.hStdError,
0, TRUE, DUPLICATE_SAME_ACCESS);
- }
+ }
if (startInfo.hStdError == INVALID_HANDLE_VALUE) {
TclWinConvertError(GetLastError());
Tcl_AppendResult(interp, "couldn't duplicate error handle: ",
Tcl_PosixError(interp), (char *) NULL);
goto end;
}
-
- /*
- * If we do not have a console window, then we must run DOS and WIN32
- * console mode applications as detached processes. This tells the loader
- * that the child application should not inherit the console, and that it
- * should not create a new console window for the child application. The
- * child application should get its stdio from the redirection handles
- * provided by this application, and run in the background.
+ /*
+ * If we do not have a console window, then we must run DOS and
+ * WIN32 console mode applications as detached processes. This tells
+ * the loader that the child application should not inherit the
+ * console, and that it should not create a new console window for
+ * the child application. The child application should get its stdio
+ * from the redirection handles provided by this application, and run
+ * in the background.
*
- * If we are starting a GUI process, they don't automatically get a
+ * If we are starting a GUI process, they don't automatically get a
* console, so it doesn't matter if they are started as foreground or
- * detached processes. The GUI window will still pop up to the foreground.
+ * detached processes. The GUI window will still pop up to the
+ * foreground.
*/
if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
@@ -1114,11 +1119,11 @@ TclpCreateProcess(
createFlags = 0;
} else if (applType == APPL_DOS) {
/*
- * Under NT, 16-bit DOS applications will not run unless they can
- * be attached to a console. If we are running without a console,
- * run the 16-bit program as an normal process inside of a hidden
- * console application, and then run that hidden console as a
- * detached process.
+ * Under NT, 16-bit DOS applications will not run unless they
+ * can be attached to a console. If we are running without a
+ * console, run the 16-bit program as an normal process inside
+ * of a hidden console application, and then run that hidden
+ * console as a detached process.
*/
startInfo.wShowWindow = SW_HIDE;
@@ -1127,46 +1132,42 @@ TclpCreateProcess(
Tcl_DStringAppend(&cmdLine, "cmd.exe /c", -1);
} else {
createFlags = DETACHED_PROCESS;
- }
+ }
} else {
if (HasConsole()) {
createFlags = 0;
} else {
createFlags = DETACHED_PROCESS;
}
-
+
if (applType == APPL_DOS) {
/*
- * Under Windows 95, 16-bit DOS applications do not work well with
- * pipes:
+ * Under Windows 95, 16-bit DOS applications do not work well
+ * with pipes:
*
- * 1. EOF on a pipe between a detached 16-bit DOS application and
- * another application is not seen at the other end of the pipe,
- * so the listening process blocks forever on reads. This inablity
- * to detect EOF happens when either a 16-bit app or the 32-bit
- * app is the listener.
+ * 1. EOF on a pipe between a detached 16-bit DOS application
+ * and another application is not seen at the other
+ * end of the pipe, so the listening process blocks forever on
+ * reads. This inablity to detect EOF happens when either a
+ * 16-bit app or the 32-bit app is the listener.
*
- * 2. If a 16-bit DOS application (detached or not) blocks when
+ * 2. If a 16-bit DOS application (detached or not) blocks when
* writing to a pipe, it will never wake up again, and it
* eventually brings the whole system down around it.
*
- * The 16-bit application is run as a normal process inside of a
- * hidden helper console app, and this helper may be run as a
- * detached process. If any of the stdio handles is a pipe, the
- * helper application accumulates information into temp files and
- * forwards it to or from the DOS application as appropriate.
- * This means that DOS apps must receive EOF from a stdin pipe
- * before they will actually begin, and must finish generating
- * stdout or stderr before the data will be sent to the next stage
- * of the pipe.
+ * The 16-bit application is run as a normal process inside
+ * of a hidden helper console app, and this helper may be run
+ * as a detached process. If any of the stdio handles is
+ * a pipe, the helper application accumulates information
+ * into temp files and forwards it to or from the DOS
+ * application as appropriate. This means that DOS apps
+ * must receive EOF from a stdin pipe before they will actually
+ * begin, and must finish generating stdout or stderr before
+ * the data will be sent to the next stage of the pipe.
*
- * The helper app should be located in the same directory as the
- * tcl dll.
+ * The helper app should be located in the same directory as
+ * the tcl dll.
*/
- Tcl_Obj *tclExePtr, *pipeDllPtr;
- char *start, *end;
- int i, fileExists;
- Tcl_DString pipeDll;
if (createFlags != 0) {
startInfo.wShowWindow = SW_HIDE;
@@ -1174,69 +1175,63 @@ TclpCreateProcess(
createFlags = CREATE_NEW_CONSOLE;
}
- Tcl_DStringInit(&pipeDll);
- Tcl_DStringAppend(&pipeDll, TCL_PIPE_DLL, -1);
- tclExePtr = TclGetObjNameOfExecutable();
- Tcl_IncrRefCount(tclExePtr);
- start = Tcl_GetStringFromObj(tclExePtr, &i);
- for (end = start + (i-1); end > start; end--) {
- if (*end == '/') {
- break;
+ {
+ Tcl_Obj *tclExePtr, *pipeDllPtr;
+ int i, fileExists;
+ char *start,*end;
+ Tcl_DString pipeDll;
+ Tcl_DStringInit(&pipeDll);
+ Tcl_DStringAppend(&pipeDll, TCL_PIPE_DLL, -1);
+ tclExePtr = Tcl_NewStringObj(TclpFindExecutable(""), -1);
+ start = Tcl_GetStringFromObj(tclExePtr, &i);
+ for (end = start + (i-1); end > start; end--) {
+ if (*end == '/')
+ break;
}
- }
- if (*end != '/') {
- Tcl_AppendResult(interp, "no / in executable path name \"",
- start, "\"", (char *) NULL);
- Tcl_DecrRefCount(tclExePtr);
- Tcl_DStringFree(&pipeDll);
- goto end;
- }
- i = (end - start) + 1;
- pipeDllPtr = Tcl_NewStringObj(start, i);
- Tcl_AppendToObj(pipeDllPtr, Tcl_DStringValue(&pipeDll), -1);
- Tcl_IncrRefCount(pipeDllPtr);
- if (Tcl_FSConvertToPathType(interp, pipeDllPtr) != TCL_OK) {
- Tcl_Panic("Tcl_FSConvertToPathType failed");
- }
- fileExists = (Tcl_FSAccess(pipeDllPtr, F_OK) == 0);
- if (!fileExists) {
- Tcl_AppendResult(interp, "Tcl pipe dll \"",
- Tcl_DStringValue(&pipeDll), "\" not found",
- (char *) NULL);
+ if (*end != '/')
+ panic("no / in executable path name");
+ i = (end - start) + 1;
+ pipeDllPtr = Tcl_NewStringObj(start, i);
+ Tcl_AppendToObj(pipeDllPtr, Tcl_DStringValue(&pipeDll), -1);
+ Tcl_IncrRefCount(pipeDllPtr);
+ if (Tcl_FSConvertToPathType(interp, pipeDllPtr) != TCL_OK)
+ panic("Tcl_FSConvertToPathType failed");
+ fileExists = (Tcl_FSAccess(pipeDllPtr, F_OK) == 0);
+ if (!fileExists) {
+ panic("Tcl pipe dll \"%s\" not found",
+ Tcl_DStringValue(&pipeDll));
+ }
+ Tcl_DStringAppend(&cmdLine, Tcl_DStringValue(&pipeDll), -1);
Tcl_DecrRefCount(tclExePtr);
Tcl_DecrRefCount(pipeDllPtr);
Tcl_DStringFree(&pipeDll);
- goto end;
}
- Tcl_DStringAppend(&cmdLine, Tcl_DStringValue(&pipeDll), -1);
- Tcl_DecrRefCount(tclExePtr);
- Tcl_DecrRefCount(pipeDllPtr);
- Tcl_DStringFree(&pipeDll);
}
}
-
+
/*
* cmdLine gets the full command line used to invoke the executable,
- * including the name of the executable itself. The command line arguments
- * in argv[] are stored in cmdLine separated by spaces. Special characters
- * in individual arguments from argv[] must be quoted when being stored in
- * cmdLine.
+ * including the name of the executable itself. The command line
+ * arguments in argv[] are stored in cmdLine separated by spaces.
+ * Special characters in individual arguments from argv[] must be
+ * quoted when being stored in cmdLine.
*
- * When calling any application, bear in mind that arguments that specify
- * a path name are not converted. If an argument contains forward slashes
- * as path separators, it may or may not be recognized as a path name,
- * depending on the program. In general, most applications accept forward
- * slashes only as option delimiters and backslashes only as paths.
+ * When calling any application, bear in mind that arguments that
+ * specify a path name are not converted. If an argument contains
+ * forward slashes as path separators, it may or may not be
+ * recognized as a path name, depending on the program. In general,
+ * most applications accept forward slashes only as option
+ * delimiters and backslashes only as paths.
*
- * Additionally, when calling a 16-bit dos or windows application, all
- * path names must use the short, cryptic, path format (e.g., using
- * ab~1.def instead of "a b.default").
+ * Additionally, when calling a 16-bit dos or windows application,
+ * all path names must use the short, cryptic, path format (e.g.,
+ * using ab~1.def instead of "a b.default").
*/
BuildCommandLine(execPath, argc, argv, &cmdLine);
- if ((*tclWinProcs->createProcessProc)(NULL,
- (TCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE,
+ if ((*tclWinProcs->createProcessProc)(NULL,
+ (TCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE,
(DWORD) createFlags, NULL, NULL, &startInfo, &procInfo) == 0) {
TclWinConvertError(GetLastError());
Tcl_AppendResult(interp, "couldn't execute \"", argv[0],
@@ -1245,20 +1240,21 @@ TclpCreateProcess(
}
/*
- * This wait is used to force the OS to give some time to the DOS process.
+ * This wait is used to force the OS to give some time to the DOS
+ * process.
*/
if (applType == APPL_DOS) {
WaitForSingleObject(procInfo.hProcess, 50);
}
- /*
- * "When an application spawns a process repeatedly, a new thread instance
- * will be created for each process but the previous instances may not be
- * cleaned up. This results in a significant virtual memory loss each time
- * the process is spawned. If there is a WaitForInputIdle() call between
- * CreateProcess() and CloseHandle(), the problem does not occur." PSS ID
- * Number: Q124121
+ /*
+ * "When an application spawns a process repeatedly, a new thread
+ * instance will be created for each process but the previous
+ * instances may not be cleaned up. This results in a significant
+ * virtual memory loss each time the process is spawned. If there
+ * is a WaitForInputIdle() call between CreateProcess() and
+ * CloseHandle(), the problem does not occur." PSS ID Number: Q124121
*/
WaitForInputIdle(procInfo.hProcess, 5000);
@@ -1270,13 +1266,13 @@ TclpCreateProcess(
}
result = TCL_OK;
- end:
+ end:
Tcl_DStringFree(&cmdLine);
if (startInfo.hStdInput != INVALID_HANDLE_VALUE) {
- CloseHandle(startInfo.hStdInput);
+ CloseHandle(startInfo.hStdInput);
}
if (startInfo.hStdOutput != INVALID_HANDLE_VALUE) {
- CloseHandle(startInfo.hStdOutput);
+ CloseHandle(startInfo.hStdOutput);
}
if (startInfo.hStdError != INVALID_HANDLE_VALUE) {
CloseHandle(startInfo.hStdError);
@@ -1290,7 +1286,8 @@ TclpCreateProcess(
*
* HasConsole --
*
- * Determines whether the current application is attached to a console.
+ * Determines whether the current application is attached to a
+ * console.
*
* Results:
* Returns TRUE if this application has a console, else FALSE.
@@ -1302,18 +1299,18 @@ TclpCreateProcess(
*/
static BOOL
-HasConsole(void)
+HasConsole()
{
HANDLE handle;
-
+
handle = CreateFileA("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle != INVALID_HANDLE_VALUE) {
- CloseHandle(handle);
+ CloseHandle(handle);
return TRUE;
} else {
- return FALSE;
+ return FALSE;
}
}
@@ -1323,28 +1320,29 @@ HasConsole(void)
* ApplicationType --
*
* Search for the specified program and identify if it refers to a DOS,
- * Windows 3.X, or Win32 program. Used to determine how to invoke a
- * program, or if it can even be invoked.
- *
- * It is possible to almost positively identify DOS and Windows
- * applications that contain the appropriate magic numbers. However, DOS
- * .com files do not seem to contain a magic number; if the program name
- * ends with .com and could not be identified as a Windows .com file, it
- * will be assumed to be a DOS application, even if it was just random
- * data. If the program name does not end with .com, no such assumption
- * is made.
- *
- * The Win32 function GetBinaryType incorrectly identifies any junk file
- * that ends with .exe as a dos executable and some executables that
- * don't end with .exe as not executable. Plus it doesn't exist under
- * win95, so I won't feel bad about reimplementing functionality.
+ * Windows 3.X, or Win32 program. Used to determine how to invoke
+ * a program, or if it can even be invoked.
+ *
+ * It is possible to almost positively identify DOS and Windows
+ * applications that contain the appropriate magic numbers. However,
+ * DOS .com files do not seem to contain a magic number; if the program
+ * name ends with .com and could not be identified as a Windows .com
+ * file, it will be assumed to be a DOS application, even if it was
+ * just random data. If the program name does not end with .com, no
+ * such assumption is made.
+ *
+ * The Win32 procedure GetBinaryType incorrectly identifies any
+ * junk file that ends with .exe as a dos executable and some
+ * executables that don't end with .exe as not executable. Plus it
+ * doesn't exist under win95, so I won't feel bad about reimplementing
+ * functionality.
*
* Results:
- * The return value is one of APPL_DOS, APPL_WIN3X, or APPL_WIN32 if the
- * filename referred to the corresponding application type. If the file
- * name could not be found or did not refer to any known application
- * type, APPL_NONE is returned and an error message is left in interp.
- * .bat files are identified as APPL_DOS.
+ * The return value is one of APPL_DOS, APPL_WIN3X, or APPL_WIN32
+ * if the filename referred to the corresponding application type.
+ * If the file name could not be found or did not refer to any known
+ * application type, APPL_NONE is returned and an error message is
+ * left in interp. .bat files are identified as APPL_DOS.
*
* Side effects:
* None.
@@ -1353,10 +1351,10 @@ HasConsole(void)
*/
static int
-ApplicationType(
- Tcl_Interp *interp, /* Interp, for error message. */
- const char *originalName, /* Name of the application to find. */
- char fullName[]) /* Filled with complete path to
+ApplicationType(interp, originalName, fullName)
+ Tcl_Interp *interp; /* Interp, for error message. */
+ const char *originalName; /* Name of the application to find. */
+ char fullName[]; /* Filled with complete path to
* application. */
{
int applType, i, nameLen, found;
@@ -1367,21 +1365,21 @@ ApplicationType(
DWORD attr, read;
IMAGE_DOS_HEADER header;
Tcl_DString nameBuf, ds;
- const TCHAR *nativeName;
+ CONST TCHAR *nativeName;
WCHAR nativeFullPath[MAX_PATH];
static char extensions[][5] = {"", ".com", ".exe", ".bat"};
- /*
- * Look for the program as an external program. First try the name as it
- * is, then try adding .com, .exe, and .bat, in that order, to the name,
- * looking for an executable.
+ /* Look for the program as an external program. First try the name
+ * as it is, then try adding .com, .exe, and .bat, in that order, to
+ * the name, looking for an executable.
*
- * Using the raw SearchPath() function doesn't do quite what is necessary.
- * If the name of the executable already contains a '.' character, it will
- * not try appending the specified extension when searching (in other
- * words, SearchPath will not find the program "a.b.exe" if the arguments
- * specified "a.b" and ".exe"). So, first look for the file as it is
- * named. Then manually append the extensions, looking for a match.
+ * Using the raw SearchPath() procedure doesn't do quite what is
+ * necessary. If the name of the executable already contains a '.'
+ * character, it will not try appending the specified extension when
+ * searching (in other words, SearchPath will not find the program
+ * "a.b.exe" if the arguments specified "a.b" and ".exe").
+ * So, first look for the file as it is named. Then manually append
+ * the extensions, looking for a match.
*/
applType = APPL_NONE;
@@ -1392,9 +1390,9 @@ ApplicationType(
for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) {
Tcl_DStringSetLength(&nameBuf, nameLen);
Tcl_DStringAppend(&nameBuf, extensions[i], -1);
- nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(&nameBuf),
+ nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(&nameBuf),
Tcl_DStringLength(&nameBuf), &ds);
- found = (*tclWinProcs->searchPathProc)(NULL, nativeName, NULL,
+ found = (*tclWinProcs->searchPathProc)(NULL, nativeName, NULL,
MAX_PATH, nativeFullPath, &rest);
Tcl_DStringFree(&ds);
if (found == 0) {
@@ -1402,8 +1400,8 @@ ApplicationType(
}
/*
- * Ignore matches on directories or data files, return if identified a
- * known type.
+ * Ignore matches on directories or data files, return if identified
+ * a known type.
*/
attr = (*tclWinProcs->getFileAttributesProc)((TCHAR *) nativeFullPath);
@@ -1414,13 +1412,13 @@ ApplicationType(
Tcl_DStringFree(&ds);
ext = strrchr(fullName, '.');
- if ((ext != NULL) && (strcasecmp(ext, ".bat") == 0)) {
+ if ((ext != NULL) && (stricmp(ext, ".bat") == 0)) {
applType = APPL_DOS;
break;
}
-
- hFile = (*tclWinProcs->createFileProc)((TCHAR *) nativeFullPath,
- GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+
+ hFile = (*tclWinProcs->createFileProc)((TCHAR *) nativeFullPath,
+ GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
continue;
@@ -1429,25 +1427,25 @@ ApplicationType(
header.e_magic = 0;
ReadFile(hFile, (void *) &header, sizeof(header), &read, NULL);
if (header.e_magic != IMAGE_DOS_SIGNATURE) {
- /*
- * Doesn't have the magic number for relocatable executables. If
+ /*
+ * Doesn't have the magic number for relocatable executables. If
* filename ends with .com, assume it's a DOS application anyhow.
* Note that we didn't make this assumption at first, because some
* supposed .com files are really 32-bit executables with all the
- * magic numbers and everything.
+ * magic numbers and everything.
*/
CloseHandle(hFile);
- if ((ext != NULL) && (strcasecmp(ext, ".com") == 0)) {
+ if ((ext != NULL) && (stricmp(ext, ".com") == 0)) {
applType = APPL_DOS;
break;
}
continue;
}
if (header.e_lfarlc != sizeof(header)) {
- /*
+ /*
* All Windows 3.X and Win32 and some DOS programs have this value
- * set here. If it doesn't, assume that since it already had the
+ * set here. If it doesn't, assume that since it already had the
* other magic number it was a DOS application.
*/
@@ -1456,7 +1454,7 @@ ApplicationType(
break;
}
- /*
+ /*
* The DWORD at header.e_lfanew points to yet another magic number.
*/
@@ -1471,11 +1469,11 @@ ApplicationType(
applType = APPL_WIN32;
} else {
/*
- * Strictly speaking, there should be a test that there is an 'L'
- * and 'E' at buf[0..1], to identify the type as DOS, but of
- * course we ran into a DOS executable that _doesn't_ have the
- * magic number - specifically, one compiled using the Lahey
- * Fortran90 compiler.
+ * Strictly speaking, there should be a test that there
+ * is an 'L' and 'E' at buf[0..1], to identify the type as
+ * DOS, but of course we ran into a DOS executable that
+ * _doesn't_ have the magic number -- specifically, one
+ * compiled using the Lahey Fortran90 compiler.
*/
applType = APPL_DOS;
@@ -1492,14 +1490,14 @@ ApplicationType(
}
if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) {
- /*
- * Replace long path name of executable with short path name for
- * 16-bit applications. Otherwise the application may not be able to
- * correctly parse its own command line to separate off the
+ /*
+ * Replace long path name of executable with short path name for
+ * 16-bit applications. Otherwise the application may not be able
+ * to correctly parse its own command line to separate off the
* application name from the arguments.
*/
- (*tclWinProcs->getShortPathNameProc)((TCHAR *) nativeFullPath,
+ (*tclWinProcs->getShortPathNameProc)((TCHAR *) nativeFullPath,
nativeFullPath, MAX_PATH);
strcpy(fullName, Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds));
Tcl_DStringFree(&ds);
@@ -1507,15 +1505,15 @@ ApplicationType(
return applType;
}
-/*
+/*
*----------------------------------------------------------------------
*
* BuildCommandLine --
*
- * The command line arguments are stored in linePtr separated by spaces,
- * in a form that CreateProcess() understands. Special characters in
- * individual arguments from argv[] must be quoted when being stored in
- * cmdLine.
+ * The command line arguments are stored in linePtr separated
+ * by spaces, in a form that CreateProcess() understands. Special
+ * characters in individual arguments from argv[] must be quoted
+ * when being stored in cmdLine.
*
* Results:
* None.
@@ -1528,27 +1526,26 @@ ApplicationType(
static void
BuildCommandLine(
- const char *executable, /* Full path of executable (including
- * extension). Replacement for argv[0]. */
+ CONST char *executable, /* Full path of executable (including
+ * extension). Replacement for argv[0]. */
int argc, /* Number of arguments. */
- const char **argv, /* Argument strings in UTF. */
+ CONST char **argv, /* Argument strings in UTF. */
Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the
* command line (TCHAR). */
{
- const char *arg, *start, *special;
+ CONST char *arg, *start, *special;
int quote, i;
Tcl_DString ds;
Tcl_DStringInit(&ds);
/*
- * Prime the path. Add a space separator if we were primed with something.
+ * Prime the path. Add a space separator if we were primed with
+ * something.
*/
Tcl_DStringAppend(&ds, Tcl_DStringValue(linePtr), -1);
- if (Tcl_DStringLength(linePtr) > 0) {
- Tcl_DStringAppend(&ds, " ", 1);
- }
+ if (Tcl_DStringLength(&ds) > 0) Tcl_DStringAppend(&ds, " ", 1);
for (i = 0; i < argc; i++) {
if (i == 0) {
@@ -1565,8 +1562,8 @@ BuildCommandLine(
int count;
Tcl_UniChar ch;
for (start = arg; *start != '\0'; start += count) {
- count = Tcl_UtfToUniChar(start, &ch);
- if (Tcl_UniCharIsSpace(ch)) { /* INTL: ISO space. */
+ count = Tcl_UtfToUniChar(start, &ch);
+ if (Tcl_UniCharIsSpace(ch)) { /* INTL: ISO space. */
quote = 1;
break;
}
@@ -1575,18 +1572,18 @@ BuildCommandLine(
if (quote) {
Tcl_DStringAppend(&ds, "\"", 1);
}
- start = arg;
+ start = arg;
for (special = arg; ; ) {
- if ((*special == '\\') && (special[1] == '\\' ||
- special[1] == '"' || (quote && special[1] == '\0'))) {
+ if ((*special == '\\') &&
+ (special[1] == '\\' || special[1] == '"' || (quote && special[1] == '\0'))) {
Tcl_DStringAppend(&ds, start, (int) (special - start));
start = special;
while (1) {
special++;
if (*special == '"' || (quote && *special == '\0')) {
- /*
- * N backslashes followed a quote -> insert N * 2 + 1
- * backslashes then a quote.
+ /*
+ * N backslashes followed a quote -> insert
+ * N * 2 + 1 backslashes then a quote.
*/
Tcl_DStringAppend(&ds, start,
@@ -1625,8 +1622,9 @@ BuildCommandLine(
*
* TclpCreateCommandChannel --
*
- * This function is called by Tcl_OpenCommandChannel to perform the
- * platform specific channel initialization for a command channel.
+ * This function is called by Tcl_OpenCommandChannel to perform
+ * the platform specific channel initialization for a command
+ * channel.
*
* Results:
* Returns a new channel or NULL on failure.
@@ -1679,8 +1677,8 @@ TclpCreateCommandChannel(
infoPtr->stopReader = CreateEvent(NULL, TRUE, FALSE, NULL);
infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread,
infoPtr, 0, &id);
- SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST);
- infoPtr->validMask |= TCL_READABLE;
+ SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST);
+ infoPtr->validMask |= TCL_READABLE;
} else {
infoPtr->readThread = 0;
}
@@ -1694,25 +1692,26 @@ TclpCreateCommandChannel(
infoPtr->stopWriter = CreateEvent(NULL, TRUE, FALSE, NULL);
infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread,
infoPtr, 0, &id);
- SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST);
- infoPtr->validMask |= TCL_WRITABLE;
+ SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST);
+ infoPtr->validMask |= TCL_WRITABLE;
}
/*
- * For backward compatibility with previous versions of Tcl, we use
- * "file%d" as the base name for pipes even though it would be more
- * natural to use "pipe%d". Use the pointer to keep the channel names
- * unique, in case channels share handles (stdin/stdout).
+ * For backward compatibility with previous versions of Tcl, we
+ * use "file%d" as the base name for pipes even though it would
+ * be more natural to use "pipe%d".
+ * Use the pointer to keep the channel names unique, in case
+ * channels share handles (stdin/stdout).
*/
wsprintfA(channelName, "file%lx", infoPtr);
infoPtr->channel = Tcl_CreateChannel(&pipeChannelType, channelName,
- (ClientData) infoPtr, infoPtr->validMask);
+ (ClientData) infoPtr, infoPtr->validMask);
/*
* Pipes have AUTO translation mode on Windows and ^Z eof char, which
- * means that a ^Z will be appended to them at close. This is needed for
- * Windows programs that expect a ^Z at EOF.
+ * means that a ^Z will be appended to them at close. This is needed
+ * for Windows programs that expect a ^Z at EOF.
*/
Tcl_SetChannelOption((Tcl_Interp *) NULL, infoPtr->channel,
@@ -1727,8 +1726,8 @@ TclpCreateCommandChannel(
*
* TclGetAndDetachPids --
*
- * Stores a list of the command PIDs for a command channel in the
- * interp's result.
+ * Stores a list of the command PIDs for a command channel in
+ * the interp's result.
*
* Results:
* None.
@@ -1745,7 +1744,7 @@ TclGetAndDetachPids(
Tcl_Channel chan)
{
PipeInfo *pipePtr;
- const Tcl_ChannelType *chanTypePtr;
+ Tcl_ChannelType *chanTypePtr;
int i;
char buf[TCL_INTEGER_SPACE];
@@ -1755,18 +1754,18 @@ TclGetAndDetachPids(
chanTypePtr = Tcl_GetChannelType(chan);
if (chanTypePtr != &pipeChannelType) {
- return;
+ return;
}
pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan);
for (i = 0; i < pipePtr->numPids; i++) {
- wsprintfA(buf, "%lu", TclpGetPid(pipePtr->pidPtr[i]));
- Tcl_AppendElement(interp, buf);
- Tcl_DetachPids(1, &(pipePtr->pidPtr[i]));
+ wsprintfA(buf, "%lu", TclpGetPid(pipePtr->pidPtr[i]));
+ Tcl_AppendElement(interp, buf);
+ Tcl_DetachPids(1, &(pipePtr->pidPtr[i]));
}
if (pipePtr->numPids > 0) {
- ckfree((char *) pipePtr->pidPtr);
- pipePtr->numPids = 0;
+ ckfree((char *) pipePtr->pidPtr);
+ pipePtr->numPids = 0;
}
}
@@ -1790,10 +1789,10 @@ static int
PipeBlockModeProc(
ClientData instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
- * TCL_MODE_NONBLOCKING. */
+ * TCL_MODE_NONBLOCKING. */
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
-
+
/*
* Pipes on Windows can not be switched between blocking and nonblocking,
* hence we have to emulate the behavior. This is done in the input
@@ -1839,19 +1838,18 @@ PipeClose2Proc(
DWORD exitCode;
errorCode = 0;
- result = 0;
-
- if ((!flags || flags == TCL_CLOSE_READ) && (pipePtr->readFile != NULL)) {
+ if ((!flags || (flags == TCL_CLOSE_READ))
+ && (pipePtr->readFile != NULL)) {
/*
- * Clean up the background thread if necessary. Note that this must be
- * done before we can close the file, since the thread may be blocking
- * trying to read from the pipe.
+ * Clean up the background thread if necessary. Note that this
+ * must be done before we can close the file, since the
+ * thread may be blocking trying to read from the pipe.
*/
if (pipePtr->readThread) {
/*
- * The thread may already have closed on its own. Check its exit
- * code.
+ * The thread may already have closed on it's own. Check it's
+ * exit code.
*/
GetExitCodeThread(pipePtr->readThread, &exitCode);
@@ -1866,20 +1864,19 @@ PipeClose2Proc(
SetEvent(pipePtr->stopReader);
/*
- * Wait at most 20 milliseconds for the reader thread to
- * close.
+ * Wait at most 20 milliseconds for the reader thread to close.
*/
- if (WaitForSingleObject(pipePtr->readThread,
- 20) == WAIT_TIMEOUT) {
+ if (WaitForSingleObject(pipePtr->readThread, 20)
+ == WAIT_TIMEOUT) {
/*
* The thread must be blocked waiting for the pipe to
- * become readable in ReadFile(). There isn't a clean way
- * to exit the thread from this condition. We should
+ * become readable in ReadFile(). There isn't a clean way
+ * to exit the thread from this condition. We should
* terminate the child process instead to get the reader
- * thread to fall out of ReadFile with a FALSE. (below) is
- * not the correct way to do this, but will stay here
- * until a better solution is found.
+ * thread to fall out of ReadFile with a FALSE. (below) is
+ * not the correct way to do this, but will stay here until
+ * a better solution is found.
*
* Note that we need to guard against terminating the
* thread while it is in the middle of Tcl_ThreadAlert
@@ -1906,20 +1903,22 @@ PipeClose2Proc(
pipePtr->validMask &= ~TCL_READABLE;
pipePtr->readFile = NULL;
}
- if ((!flags || flags & TCL_CLOSE_WRITE)
- && (pipePtr->writeFile != NULL)) {
+ if ((!flags || (flags & TCL_CLOSE_WRITE))
+ && (pipePtr->writeFile != NULL)) {
+
if (pipePtr->writeThread) {
/*
- * Wait for the writer thread to finish the current buffer, then
- * terminate the thread and close the handles. If the channel is
- * nonblocking, there should be no pending write operations.
+ * Wait for the writer thread to finish the current buffer,
+ * then terminate the thread and close the handles. If the
+ * channel is nonblocking, there should be no pending write
+ * operations.
*/
WaitForSingleObject(pipePtr->writable, INFINITE);
/*
- * The thread may already have closed on it's own. Check its exit
- * code.
+ * The thread may already have closed on it's own. Check it's
+ * exit code.
*/
GetExitCodeThread(pipePtr->writeThread, &exitCode);
@@ -1934,20 +1933,19 @@ PipeClose2Proc(
SetEvent(pipePtr->stopWriter);
/*
- * Wait at most 20 milliseconds for the reader thread to
- * close.
+ * Wait at most 20 milliseconds for the reader thread to close.
*/
- if (WaitForSingleObject(pipePtr->writeThread,
- 20) == WAIT_TIMEOUT) {
+ if (WaitForSingleObject(pipePtr->writeThread, 20)
+ == WAIT_TIMEOUT) {
/*
* The thread must be blocked waiting for the pipe to
- * consume input in WriteFile(). There isn't a clean way
- * to exit the thread from this condition. We should
+ * consume input in WriteFile(). There isn't a clean way
+ * to exit the thread from this condition. We should
* terminate the child process instead to get the writer
- * thread to fall out of WriteFile with a FALSE. (below)
- * is not the correct way to do this, but will stay here
- * until a better solution is found.
+ * thread to fall out of WriteFile with a FALSE. (below) is
+ * not the correct way to do this, but will stay here until
+ * a better solution is found.
*
* Note that we need to guard against terminating the
* thread while it is in the middle of Tcl_ThreadAlert
@@ -1992,8 +1990,8 @@ PipeClose2Proc(
*/
for (nextPtrPtr = &(tsdPtr->firstPipePtr), infoPtr = *nextPtrPtr;
- infoPtr != NULL;
- nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) {
+ infoPtr != NULL;
+ nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) {
if (infoPtr == (PipeInfo *)pipePtr) {
*nextPtrPtr = infoPtr->nextPtr;
break;
@@ -2002,9 +2000,9 @@ PipeClose2Proc(
if ((pipePtr->flags & PIPE_ASYNC) || TclInExit()) {
/*
- * If the channel is non-blocking or Tcl is being cleaned up, just
- * detach the children PIDs, reap them (important if we are in a
- * dynamic load module), and discard the errorFile.
+ * If the channel is non-blocking or Tcl is being cleaned up,
+ * just detach the children PIDs, reap them (important if we are
+ * in a dynamic load module), and discard the errorFile.
*/
Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr);
@@ -2012,7 +2010,7 @@ PipeClose2Proc(
if (pipePtr->errorFile) {
if (TclpCloseFile(pipePtr->errorFile) != 0) {
- if (errorCode == 0) {
+ if ( errorCode == 0 ) {
errorCode = errno;
}
}
@@ -2029,18 +2027,18 @@ PipeClose2Proc(
filePtr = (WinFile*)pipePtr->errorFile;
errChan = Tcl_MakeFileChannel((ClientData) filePtr->handle,
- TCL_READABLE);
+ TCL_READABLE);
ckfree((char *) filePtr);
} else {
errChan = NULL;
}
result = TclCleanupChildren(interp, pipePtr->numPids,
- pipePtr->pidPtr, errChan);
+ pipePtr->pidPtr, errChan);
}
if (pipePtr->numPids > 0) {
- ckfree((char *) pipePtr->pidPtr);
+ ckfree((char *) pipePtr->pidPtr);
}
if (pipePtr->writeBuf != NULL) {
@@ -2050,7 +2048,7 @@ PipeClose2Proc(
ckfree((char*) pipePtr);
if (errorCode == 0) {
- return result;
+ return result;
}
return errorCode;
}
@@ -2060,8 +2058,8 @@ PipeClose2Proc(
*
* PipeInputProc --
*
- * Reads input from the IO channel into the buffer given. Returns count
- * of how many bytes were actually read, and an error indication.
+ * Reads input from the IO channel into the buffer given. Returns
+ * count of how many bytes were actually read, and an error indication.
*
* Results:
* A count of how many bytes were read is returned and an error
@@ -2075,11 +2073,11 @@ PipeClose2Proc(
static int
PipeInputProc(
- ClientData instanceData, /* Pipe state. */
- char *buf, /* Where to store data read. */
- int bufSize, /* How much space is available in the
- * buffer? */
- int *errorCode) /* Where to store error code. */
+ ClientData instanceData, /* Pipe state. */
+ char *buf, /* Where to store data read. */
+ int bufSize, /* How much space is available
+ * in the buffer? */
+ int *errorCode) /* Where to store error code. */
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
WinFile *filePtr = (WinFile*) infoPtr->readFile;
@@ -2104,8 +2102,8 @@ PipeInputProc(
if (infoPtr->readFlags & PIPE_EXTRABYTE) {
/*
- * The reader thread consumed 1 byte as a side effect of waiting so we
- * need to move it into the buffer.
+ * The reader thread consumed 1 byte as a side effect of
+ * waiting so we need to move it into the buffer.
*/
*buf = infoPtr->extraByte;
@@ -2124,9 +2122,9 @@ PipeInputProc(
}
/*
- * Attempt to read bufSize bytes. The read will return immediately if
- * there is any data available. Otherwise it will block until at least one
- * byte is available or an EOF occurs.
+ * Attempt to read bufSize bytes. The read will return immediately
+ * if there is any data available. Otherwise it will block until
+ * at least one byte is available or an EOF occurs.
*/
if (ReadFile(filePtr->handle, (LPVOID) buf, (DWORD) bufSize, &count,
@@ -2154,12 +2152,12 @@ PipeInputProc(
*
* PipeOutputProc --
*
- * Writes the given output on the IO channel. Returns count of how many
- * characters were actually written, and an error indication.
+ * Writes the given output on the IO channel. Returns count of how
+ * many characters were actually written, and an error indication.
*
* Results:
- * A count of how many characters were written is returned and an error
- * indication is returned in an output argument.
+ * A count of how many characters were written is returned and an
+ * error indication is returned in an output argument.
*
* Side effects:
* Writes output on the actual channel.
@@ -2169,27 +2167,27 @@ PipeInputProc(
static int
PipeOutputProc(
- ClientData instanceData, /* Pipe state. */
- const char *buf, /* The data buffer. */
- int toWrite, /* How many bytes to write? */
- int *errorCode) /* Where to store error code. */
+ ClientData instanceData, /* Pipe state. */
+ CONST char *buf, /* The data buffer. */
+ int toWrite, /* How many bytes to write? */
+ int *errorCode) /* Where to store error code. */
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
WinFile *filePtr = (WinFile*) infoPtr->writeFile;
DWORD bytesWritten, timeout;
-
+
*errorCode = 0;
timeout = (infoPtr->flags & PIPE_ASYNC) ? 0 : INFINITE;
if (WaitForSingleObject(infoPtr->writable, timeout) == WAIT_TIMEOUT) {
/*
- * The writer thread is blocked waiting for a write to complete and
- * the channel is in non-blocking mode.
+ * The writer thread is blocked waiting for a write to complete
+ * and the channel is in non-blocking mode.
*/
errno = EAGAIN;
goto error;
}
-
+
/*
* Check for a background error on the last write.
*/
@@ -2202,8 +2200,8 @@ PipeOutputProc(
if (infoPtr->flags & PIPE_ASYNC) {
/*
- * The pipe is non-blocking, so copy the data into the output buffer
- * and restart the writer thread.
+ * The pipe is non-blocking, so copy the data into the output
+ * buffer and restart the writer thread.
*/
if (toWrite > infoPtr->writeBufLen) {
@@ -2224,8 +2222,8 @@ PipeOutputProc(
bytesWritten = toWrite;
} else {
/*
- * In the blocking case, just try to write the buffer directly. This
- * avoids an unnecessary copy.
+ * In the blocking case, just try to write the buffer directly.
+ * This avoids an unnecessary copy.
*/
if (WriteFile(filePtr->handle, (LPVOID) buf, (DWORD) toWrite,
@@ -2236,7 +2234,7 @@ PipeOutputProc(
}
return bytesWritten;
- error:
+ error:
*errorCode = errno;
return -1;
@@ -2247,15 +2245,15 @@ PipeOutputProc(
*
* PipeEventProc --
*
- * This function is invoked by Tcl_ServiceEvent when a file event reaches
- * the front of the event queue. This function invokes Tcl_NotifyChannel
- * on the pipe.
+ * This function is invoked by Tcl_ServiceEvent when a file event
+ * reaches the front of the event queue. This procedure invokes
+ * Tcl_NotifyChannel on the pipe.
*
* Results:
- * Returns 1 if the event was handled, meaning it should be removed from
- * the queue. Returns 0 if the event was not handled, meaning it should
- * stay on the queue. The only time the event isn't handled is if the
- * TCL_FILE_EVENTS flag bit isn't set.
+ * Returns 1 if the event was handled, meaning it should be removed
+ * from the queue. Returns 0 if the event was not handled, meaning
+ * it should stay on the queue. The only time the event isn't
+ * handled is if the TCL_FILE_EVENTS flag bit isn't set.
*
* Side effects:
* Whatever the notifier callback does.
@@ -2280,9 +2278,9 @@ PipeEventProc(
/*
* Search through the list of watched pipes for the one whose handle
- * matches the event. We do this rather than simply dereferencing the
- * handle in the event so that pipes can be deleted while the event is in
- * the queue.
+ * matches the event. We do this rather than simply dereferencing
+ * the handle in the event so that pipes can be deleted while the
+ * event is in the queue.
*/
for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL;
@@ -2302,9 +2300,9 @@ PipeEventProc(
}
/*
- * Check to see if the pipe is readable. Note that we can't tell if a pipe
- * is writable, so we always report it as being writable unless we have
- * detected EOF.
+ * Check to see if the pipe is readable. Note
+ * that we can't tell if a pipe is writable, so we always report it
+ * as being writable unless we have detected EOF.
*/
mask = 0;
@@ -2313,7 +2311,8 @@ PipeEventProc(
mask = TCL_WRITABLE;
}
- if ((infoPtr->watchMask & TCL_READABLE) && (WaitForRead(infoPtr,0) >= 0)) {
+ if ((infoPtr->watchMask & TCL_READABLE) &&
+ (WaitForRead(infoPtr, 0) >= 0)) {
if (infoPtr->readFlags & PIPE_EOF) {
mask = TCL_READABLE;
} else {
@@ -2334,7 +2333,8 @@ PipeEventProc(
*
* PipeWatchProc --
*
- * Called by the notifier to set up to watch for events on this channel.
+ * Called by the notifier to set up to watch for events on this
+ * channel.
*
* Results:
* None.
@@ -2347,10 +2347,10 @@ PipeEventProc(
static void
PipeWatchProc(
- ClientData instanceData, /* Pipe state. */
- int mask) /* What events to watch for, OR-ed combination
- * of TCL_READABLE, TCL_WRITABLE and
- * TCL_EXCEPTION. */
+ ClientData instanceData, /* Pipe state. */
+ int mask) /* What events to watch for, OR-ed
+ * combination of TCL_READABLE,
+ * TCL_WRITABLE and TCL_EXCEPTION. */
{
PipeInfo **nextPtrPtr, *ptr;
PipeInfo *infoPtr = (PipeInfo *) instanceData;
@@ -2358,8 +2358,9 @@ PipeWatchProc(
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
- * Since most of the work is handled by the background threads, we just
- * need to update the watchMask and then force the notifier to poll once.
+ * Since most of the work is handled by the background threads,
+ * we just need to update the watchMask and then force the notifier
+ * to poll once.
*/
infoPtr->watchMask = mask & infoPtr->validMask;
@@ -2377,8 +2378,8 @@ PipeWatchProc(
*/
for (nextPtrPtr = &(tsdPtr->firstPipePtr), ptr = *nextPtrPtr;
- ptr != NULL;
- nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
+ ptr != NULL;
+ nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
if (infoPtr == ptr) {
*nextPtrPtr = ptr->nextPtr;
break;
@@ -2393,12 +2394,12 @@ PipeWatchProc(
*
* PipeGetHandleProc --
*
- * Called from Tcl_GetChannelHandle to retrieve OS handles from inside a
- * command pipeline based channel.
+ * Called from Tcl_GetChannelHandle to retrieve OS handles from
+ * inside a command pipeline based channel.
*
* Results:
- * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if there is no
- * handle for the specified direction.
+ * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
+ * there is no handle for the specified direction.
*
* Side effects:
* None.
@@ -2413,7 +2414,7 @@ PipeGetHandleProc(
ClientData *handlePtr) /* Where to store the handle. */
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
- WinFile *filePtr;
+ WinFile *filePtr;
if (direction == TCL_READABLE && infoPtr->readFile) {
filePtr = (WinFile*) infoPtr->readFile;
@@ -2436,12 +2437,13 @@ PipeGetHandleProc(
* Emulates the waitpid system call.
*
* Results:
- * Returns 0 if the process is still alive, -1 on an error, or the pid on
- * a clean close.
+ * Returns 0 if the process is still alive, -1 on an error, or
+ * the pid on a clean close.
*
* Side effects:
- * Unless WNOHANG is set and the wait times out, the process information
- * record will be deleted and the process handle will be closed.
+ * Unless WNOHANG is set and the wait times out, the process
+ * information record will be deleted and the process handle
+ * will be closed.
*
*----------------------------------------------------------------------
*/
@@ -2462,7 +2464,7 @@ Tcl_WaitPid(
/*
* If no pid is specified, do nothing.
*/
-
+
if (pid == 0) {
*statPtr = 0;
return 0;
@@ -2470,6 +2472,12 @@ Tcl_WaitPid(
/*
* Find the process and cut it from the process list.
+ * SF Tcl Bug 859820, Backport of its fix.
+ * SF Tcl Bug 1381436, asking for the backport.
+ *
+ * [x] Cutting the infoPtr after the closehandle allows the
+ * pointer to become stale. We do it here, and compensate if the
+ * process was not done yet.
*/
Tcl_MutexLock(&pipeMutex);
@@ -2487,17 +2495,17 @@ Tcl_WaitPid(
* If the pid is not one of the processes we know about (we started it)
* then do nothing.
*/
-
+
if (infoPtr == NULL) {
- *statPtr = 0;
+ *statPtr = 0;
return 0;
}
/*
- * Officially "wait" for it to finish. We either poll (WNOHANG) or wait
- * for an infinite amount of time.
+ * Officially "wait" for it to finish. We either poll (WNOHANG) or
+ * wait for an infinite amount of time.
*/
-
+
if (options & WNOHANG) {
flags = 0;
} else {
@@ -2508,9 +2516,9 @@ Tcl_WaitPid(
*statPtr = 0;
if (options & WNOHANG) {
/*
- * Re-insert this infoPtr back on the list.
+ * Re-insert the cut infoPtr back on the list.
+ * See [x] for explanation.
*/
-
Tcl_MutexLock(&pipeMutex);
infoPtr->nextPtr = procList;
procList = infoPtr;
@@ -2521,71 +2529,54 @@ Tcl_WaitPid(
}
} else if (ret == WAIT_OBJECT_0) {
GetExitCodeProcess(infoPtr->hProcess, &exitCode);
+ if (exitCode & 0xC0000000) {
+ /*
+ * A fatal exception occured.
+ */
+ switch (exitCode) {
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ case EXCEPTION_FLT_INEXACT_RESULT:
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ case EXCEPTION_FLT_OVERFLOW:
+ case EXCEPTION_FLT_STACK_CHECK:
+ case EXCEPTION_FLT_UNDERFLOW:
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ case EXCEPTION_INT_OVERFLOW:
+ *statPtr = 0xC0000000 | SIGFPE;
+ break;
- /*
- * Does the exit code look like one of the exception codes?
- */
-
- switch (exitCode) {
- case EXCEPTION_FLT_DENORMAL_OPERAND:
- case EXCEPTION_FLT_DIVIDE_BY_ZERO:
- case EXCEPTION_FLT_INEXACT_RESULT:
- case EXCEPTION_FLT_INVALID_OPERATION:
- case EXCEPTION_FLT_OVERFLOW:
- case EXCEPTION_FLT_STACK_CHECK:
- case EXCEPTION_FLT_UNDERFLOW:
- case EXCEPTION_INT_DIVIDE_BY_ZERO:
- case EXCEPTION_INT_OVERFLOW:
- *statPtr = 0xC0000000 | SIGFPE;
- break;
-
- case EXCEPTION_PRIV_INSTRUCTION:
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- *statPtr = 0xC0000000 | SIGILL;
- break;
-
- case EXCEPTION_ACCESS_VIOLATION:
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- case EXCEPTION_STACK_OVERFLOW:
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- case EXCEPTION_INVALID_DISPOSITION:
- case EXCEPTION_GUARD_PAGE:
- case EXCEPTION_INVALID_HANDLE:
- *statPtr = 0xC0000000 | SIGSEGV;
- break;
-
- case EXCEPTION_DATATYPE_MISALIGNMENT:
- *statPtr = 0xC0000000 | SIGBUS;
- break;
-
- case EXCEPTION_BREAKPOINT:
- case EXCEPTION_SINGLE_STEP:
- *statPtr = 0xC0000000 | SIGTRAP;
- break;
+ case EXCEPTION_PRIV_INSTRUCTION:
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ *statPtr = 0xC0000000 | SIGILL;
+ break;
- case CONTROL_C_EXIT:
- *statPtr = 0xC0000000 | SIGINT;
- break;
+ case EXCEPTION_ACCESS_VIOLATION:
+ case EXCEPTION_DATATYPE_MISALIGNMENT:
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ case EXCEPTION_STACK_OVERFLOW:
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+ case EXCEPTION_INVALID_DISPOSITION:
+ case EXCEPTION_GUARD_PAGE:
+ case EXCEPTION_INVALID_HANDLE:
+ *statPtr = 0xC0000000 | SIGSEGV;
+ break;
- default:
- /*
- * Non-exceptional, normal, exit code. Note that the exit code is
- * truncated to a signed short range [-32768,32768) whether it
- * fits into this range or not.
- *
- * BUG: Even though the exit code is a DWORD, it is understood by
- * convention to be a signed integer, yet there isn't enough room
- * to fit this into the POSIX style waitstatus mask without
- * truncating it.
- */
+ case CONTROL_C_EXIT:
+ *statPtr = 0xC0000000 | SIGINT;
+ break;
+ default:
+ *statPtr = 0xC0000000 | SIGABRT;
+ break;
+ }
+ } else {
*statPtr = exitCode;
- break;
}
result = pid;
} else {
errno = ECHILD;
- *statPtr = 0xC0000000 | ECHILD;
+ *statPtr = 0xC0000000 | ECHILD;
result = (Tcl_Pid) -1;
}
@@ -2604,28 +2595,28 @@ Tcl_WaitPid(
*
* TclWinAddProcess --
*
- * Add a process to the process list so that we can use Tcl_WaitPid on
- * the process.
+ * Add a process to the process list so that we can use
+ * Tcl_WaitPid on the process.
*
* Results:
- * None
+ * None
*
* Side effects:
- * Adds the specified process handle to the process list so Tcl_WaitPid
- * knows about it.
+ * Adds the specified process handle to the process list so
+ * Tcl_WaitPid knows about it.
*
*----------------------------------------------------------------------
*/
void
-TclWinAddProcess(
- void *hProcess, /* Handle to process */
- unsigned long id) /* Global process identifier */
+TclWinAddProcess(hProcess, id)
+ HANDLE hProcess; /* Handle to process */
+ DWORD id; /* Global process identifier */
{
ProcInfo *procPtr = (ProcInfo *) ckalloc(sizeof(ProcInfo));
PipeInit();
-
+
procPtr->hProcess = hProcess;
procPtr->dwProcessId = id;
Tcl_MutexLock(&pipeMutex);
@@ -2639,8 +2630,8 @@ TclWinAddProcess(
*
* Tcl_PidObjCmd --
*
- * This function is invoked to process the "pid" Tcl command. See the
- * user documentation for details on what it does.
+ * This procedure is invoked to process the "pid" Tcl command.
+ * See the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -2657,10 +2648,10 @@ Tcl_PidObjCmd(
ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *const *objv) /* Argument strings. */
+ Tcl_Obj *CONST *objv) /* Argument strings. */
{
Tcl_Channel chan;
- const Tcl_ChannelType *chanTypePtr;
+ Tcl_ChannelType *chanTypePtr;
PipeInfo *pipePtr;
int i;
Tcl_Obj *resultPtr;
@@ -2671,12 +2662,13 @@ Tcl_PidObjCmd(
return TCL_ERROR;
}
if (objc == 1) {
+ resultPtr = Tcl_GetObjResult(interp);
wsprintfA(buf, "%lu", (unsigned long) getpid());
- Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
+ Tcl_SetStringObj(resultPtr, buf, -1);
} else {
- chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL),
+ chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL),
NULL);
- if (chan == (Tcl_Channel) NULL) {
+ if (chan == (Tcl_Channel) NULL) {
return TCL_ERROR;
}
chanTypePtr = Tcl_GetChannelType(chan);
@@ -2684,14 +2676,13 @@ Tcl_PidObjCmd(
return TCL_OK;
}
- pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan);
- resultPtr = Tcl_NewObj();
- for (i = 0; i < pipePtr->numPids; i++) {
+ pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan);
+ resultPtr = Tcl_GetObjResult(interp);
+ for (i = 0; i < pipePtr->numPids; i++) {
wsprintfA(buf, "%lu", TclpGetPid(pipePtr->pidPtr[i]));
Tcl_ListObjAppendElement(/*interp*/ NULL, resultPtr,
Tcl_NewStringObj(buf, -1));
}
- Tcl_SetObjResult(interp, resultPtr);
}
return TCL_OK;
}
@@ -2701,19 +2692,20 @@ Tcl_PidObjCmd(
*
* WaitForRead --
*
- * Wait until some data is available, the pipe is at EOF or the reader
- * thread is blocked waiting for data (if the channel is in non-blocking
- * mode).
+ * Wait until some data is available, the pipe is at
+ * EOF or the reader thread is blocked waiting for data (if the
+ * channel is in non-blocking mode).
*
* Results:
- * Returns 1 if pipe is readable. Returns 0 if there is no data on the
- * pipe, but there is buffered data. Returns -1 if an error occurred. If
- * an error occurred, the threads may not be synchronized.
+ * Returns 1 if pipe is readable. Returns 0 if there is no data
+ * on the pipe, but there is buffered data. Returns -1 if an
+ * error occurred. If an error occurred, the threads may not
+ * be synchronized.
*
* Side effects:
- * Updates the shared state flags and may consume 1 byte of data from the
- * pipe. If no error occurred, the reader thread is blocked waiting for a
- * signal from the main thread.
+ * Updates the shared state flags and may consume 1 byte of data
+ * from the pipe. If no error occurred, the reader thread is
+ * blocked waiting for a signal from the main thread.
*
*----------------------------------------------------------------------
*/
@@ -2721,8 +2713,8 @@ Tcl_PidObjCmd(
static int
WaitForRead(
PipeInfo *infoPtr, /* Pipe state. */
- int blocking) /* Indicates whether call should be blocking
- * or not. */
+ int blocking) /* Indicates whether call should be
+ * blocking or not. */
{
DWORD timeout, count;
HANDLE *handle = ((WinFile *) infoPtr->readFile)->handle;
@@ -2731,7 +2723,7 @@ WaitForRead(
/*
* Synchronize with the reader thread.
*/
-
+
timeout = blocking ? INFINITE : 0;
if (WaitForSingleObject(infoPtr->readable, timeout) == WAIT_TIMEOUT) {
/*
@@ -2744,10 +2736,11 @@ WaitForRead(
}
/*
- * At this point, the two threads are synchronized, so it is safe to
- * access shared state.
+ * At this point, the two threads are synchronized, so it is safe
+ * to access shared state.
*/
+
/*
* If the pipe has hit EOF, it is always readable.
*/
@@ -2755,7 +2748,7 @@ WaitForRead(
if (infoPtr->readFlags & PIPE_EOF) {
return 1;
}
-
+
/*
* Check to see if there is any data sitting in the pipe.
*/
@@ -2763,7 +2756,6 @@ WaitForRead(
if (PeekNamedPipe(handle, (LPVOID) NULL, (DWORD) 0,
(LPDWORD) NULL, &count, (LPDWORD) NULL) != TRUE) {
TclWinConvertError(GetLastError());
-
/*
* Check to see if the peek failed because of EOF.
*/
@@ -2793,8 +2785,8 @@ WaitForRead(
}
/*
- * The pipe isn't readable, but there is some data sitting in the
- * buffer, so return immediately.
+ * The pipe isn't readable, but there is some data sitting
+ * in the buffer, so return immediately.
*/
if (infoPtr->readFlags & PIPE_EXTRABYTE) {
@@ -2802,9 +2794,10 @@ WaitForRead(
}
/*
- * There wasn't any data available, so reset the thread and try again.
+ * There wasn't any data available, so reset the thread and
+ * try again.
*/
-
+
ResetEvent(infoPtr->readable);
SetEvent(infoPtr->startReader);
}
@@ -2815,24 +2808,24 @@ WaitForRead(
*
* PipeReaderThread --
*
- * This function runs in a separate thread and waits for input to become
- * available on a pipe.
+ * This function runs in a separate thread and waits for input
+ * to become available on a pipe.
*
* Results:
* None.
*
* Side effects:
- * Signals the main thread when input become available. May cause the
- * main thread to wake up by posting a message. May consume one byte from
- * the pipe for each wait operation. Will cause a memory leak of ~4k, if
- * forcefully terminated with TerminateThread().
+ * Signals the main thread when input become available. May
+ * cause the main thread to wake up by posting a message. May
+ * consume one byte from the pipe for each wait operation. Will
+ * cause a memory leak of ~4k, if forcefully terminated with
+ * TerminateThread().
*
*----------------------------------------------------------------------
*/
static DWORD WINAPI
-PipeReaderThread(
- LPVOID arg)
+PipeReaderThread(LPVOID arg)
{
PipeInfo *infoPtr = (PipeInfo *)arg;
HANDLE *handle = ((WinFile *) infoPtr->readFile)->handle;
@@ -2846,33 +2839,34 @@ PipeReaderThread(
while (!done) {
/*
- * Wait for the main thread to signal before attempting to wait on the
- * pipe becoming readable.
+ * Wait for the main thread to signal before attempting to wait
+ * on the pipe becoming readable.
*/
waitResult = WaitForMultipleObjects(2, wEvents, FALSE, INFINITE);
if (waitResult != (WAIT_OBJECT_0 + 1)) {
/*
- * The start event was not signaled. It might be the stop event or
- * an error, so exit.
+ * The start event was not signaled. It might be the stop event
+ * or an error, so exit.
*/
break;
}
/*
- * Try waiting for 0 bytes. This will block until some data is
- * available on NT, but will return immediately on Win 95. So, if no
- * data is available after the first read, we block until we can read
- * a single byte off of the pipe.
+ * Try waiting for 0 bytes. This will block until some data is
+ * available on NT, but will return immediately on Win 95. So,
+ * if no data is available after the first read, we block until
+ * we can read a single byte off of the pipe.
*/
- if (ReadFile(handle, NULL, 0, &count, NULL) == FALSE ||
- PeekNamedPipe(handle, NULL, 0, NULL, &count, NULL) == FALSE) {
+ if ((ReadFile(handle, NULL, 0, &count, NULL) == FALSE)
+ || (PeekNamedPipe(handle, NULL, 0, NULL, &count,
+ NULL) == FALSE)) {
/*
- * The error is a result of an EOF condition, so set the EOF bit
- * before signalling the main thread.
+ * The error is a result of an EOF condition, so set the
+ * EOF bit before signalling the main thread.
*/
err = GetLastError();
@@ -2886,8 +2880,8 @@ PipeReaderThread(
if (ReadFile(handle, &(infoPtr->extraByte), 1, &count, NULL)
!= FALSE) {
/*
- * One byte was consumed as a side effect of waiting for the
- * pipe to become readable.
+ * One byte was consumed as a side effect of waiting
+ * for the pipe to become readable.
*/
infoPtr->readFlags |= PIPE_EXTRABYTE;
@@ -2907,27 +2901,23 @@ PipeReaderThread(
}
}
-
+
/*
- * Signal the main thread by signalling the readable event and then
- * waking up the notifier thread.
+ * Signal the main thread by signalling the readable event and
+ * then waking up the notifier thread.
*/
SetEvent(infoPtr->readable);
-
+
/*
- * Alert the foreground thread. Note that we need to treat this like a
- * critical section so the foreground thread does not terminate this
- * thread while we are holding a mutex in the notifier code.
+ * Alert the foreground thread. Note that we need to treat this like
+ * a critical section so the foreground thread does not terminate
+ * this thread while we are holding a mutex in the notifier code.
*/
Tcl_MutexLock(&pipeMutex);
if (infoPtr->threadId != NULL) {
- /*
- * TIP #218. When in flight ignore the event, no one will receive
- * it anyway.
- */
-
+ /* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
Tcl_MutexUnlock(&pipeMutex);
@@ -2941,22 +2931,23 @@ PipeReaderThread(
*
* PipeWriterThread --
*
- * This function runs in a separate thread and writes data onto a pipe.
+ * This function runs in a separate thread and writes data
+ * onto a pipe.
*
* Results:
* Always returns 0.
*
* Side effects:
- * Signals the main thread when an output operation is completed. May
- * cause the main thread to wake up by posting a message.
+ * Signals the main thread when an output operation is completed.
+ * May cause the main thread to wake up by posting a message.
*
*----------------------------------------------------------------------
*/
static DWORD WINAPI
-PipeWriterThread(
- LPVOID arg)
+PipeWriterThread(LPVOID arg)
{
+
PipeInfo *infoPtr = (PipeInfo *)arg;
HANDLE *handle = ((WinFile *) infoPtr->writeFile)->handle;
DWORD count, toWrite;
@@ -2977,8 +2968,8 @@ PipeWriterThread(
if (waitResult != (WAIT_OBJECT_0 + 1)) {
/*
- * The start event was not signaled. It might be the stop event or
- * an error, so exit.
+ * The start event was not signaled. It might be the stop event
+ * or an error, so exit.
*/
break;
@@ -2994,34 +2985,30 @@ PipeWriterThread(
while (toWrite > 0) {
if (WriteFile(handle, buf, toWrite, &count, NULL) == FALSE) {
infoPtr->writeError = GetLastError();
- done = 1;
+ done = 1;
break;
} else {
toWrite -= count;
buf += count;
}
}
-
+
/*
- * Signal the main thread by signalling the writable event and then
- * waking up the notifier thread.
+ * Signal the main thread by signalling the writable event and
+ * then waking up the notifier thread.
*/
SetEvent(infoPtr->writable);
/*
- * Alert the foreground thread. Note that we need to treat this like a
- * critical section so the foreground thread does not terminate this
- * thread while we are holding a mutex in the notifier code.
+ * Alert the foreground thread. Note that we need to treat this like
+ * a critical section so the foreground thread does not terminate
+ * this thread while we are holding a mutex in the notifier code.
*/
Tcl_MutexLock(&pipeMutex);
if (infoPtr->threadId != NULL) {
- /*
- * TIP #218. When in flight ignore the event, no one will receive
- * it anyway.
- */
-
+ /* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
Tcl_MutexUnlock(&pipeMutex);
@@ -3029,7 +3016,7 @@ PipeWriterThread(
return 0;
}
-
+
/*
*----------------------------------------------------------------------
*
@@ -3047,43 +3034,33 @@ PipeWriterThread(
*/
static void
-PipeThreadActionProc(
- ClientData instanceData,
- int action)
+PipeThreadActionProc (instanceData, action)
+ ClientData instanceData;
+ int action;
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
- /*
- * We do not access firstPipePtr in the thread structures. This is not for
- * all pipes managed by the thread, but only those we are watching.
- * Removal of the filevent handlers before transfer thus takes care of
- * this structure.
+ /* We do not access firstPipePtr in the thread structures. This is
+ * not for all pipes managed by the thread, but only those we are
+ * watching. Removal of the filevent handlers before transfer thus
+ * takes care of this structure.
*/
Tcl_MutexLock(&pipeMutex);
if (action == TCL_CHANNEL_THREAD_INSERT) {
- /*
- * We can't copy the thread information from the channel when the
- * channel is created. At this time the channel back pointer has not
- * been set yet. However in that case the threadId has already been
- * set by TclpCreateCommandChannel itself, so the structure is still
- * good.
+ /* We can't copy the thread information from the channel when
+ * the channel is created. At this time the channel back
+ * pointer has not been set yet. However in that case the
+ * threadId has already been set by TclpCreateCommandChannel
+ * itself, so the structure is still good.
*/
- PipeInit();
- if (infoPtr->channel != NULL) {
- infoPtr->threadId = Tcl_GetChannelThread(infoPtr->channel);
+ PipeInit ();
+ if (infoPtr->channel != NULL) {
+ infoPtr->threadId = Tcl_GetChannelThread (infoPtr->channel);
}
} else {
infoPtr->threadId = NULL;
}
Tcl_MutexUnlock(&pipeMutex);
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinPort.h b/win/tclWinPort.h
index c5a726a..377aea3 100644
--- a/win/tclWinPort.h
+++ b/win/tclWinPort.h
@@ -14,21 +14,10 @@
#ifndef _TCLWINPORT
#define _TCLWINPORT
-#ifndef _WIN64
-/* See [Bug 2935503]: file mtime sets wrong time */
-# define _USE_32BIT_TIME_T
+#ifndef _TCLINT
+# include "tclInt.h"
#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-
-/*
- * Ask for the winsock function typedefs, also.
- */
-#define INCL_WINSOCK_API_TYPEDEFS 1
-#include <winsock2.h>
-
#ifdef CHECK_UNICODE_CALLS
# define _UNICODE
# define UNICODE
@@ -45,36 +34,17 @@
*---------------------------------------------------------------------------
*/
-#ifdef __CYGWIN__
-# include <unistd.h>
-# include <wchar.h>
-#else
-# include <io.h>
-#endif
#include <stdio.h>
#include <stdlib.h>
+
#include <errno.h>
#include <fcntl.h>
#include <float.h>
+#include <io.h>
#include <malloc.h>
#include <process.h>
#include <signal.h>
#include <string.h>
-#include <limits.h>
-
-#ifdef __CYGWIN__
-# include <unistd.h>
-# ifndef _wcsicmp
-# define _wcsicmp wcscasecmp
-# endif
-#else
-# ifndef strncasecmp
-# define strncasecmp strnicmp
-# endif
-# ifndef strcasecmp
-# define strcasecmp stricmp
-# endif
-#endif
/*
* Need to block out these includes for building extensions with MetroWerks
@@ -93,6 +63,21 @@
#include <time.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+/*
+ * Ask for the winsock function typedefs, also.
+ */
+#define INCL_WINSOCK_API_TYPEDEFS 1
+#include <winsock2.h>
+
+#ifdef BUILD_tcl
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLEXPORT
+#endif /* BUILD_tcl */
+
/*
* Define EINPROGRESS in terms of WSAEINPROGRESS.
*/
@@ -217,18 +202,6 @@
#define EOVERFLOW EFBIG /* The object couldn't fit in the datatype */
/*
- * Signals not known to the standard ANSI signal.h. These are used
- * by Tcl_WaitPid() and generic/tclPosixStr.c
- */
-
-#ifndef SIGTRAP
-# define SIGTRAP 5
-#endif
-#ifndef SIGBUS
-# define SIGBUS 10
-#endif
-
-/*
* Supply definitions for macros to query wait status, if not already
* defined in header files above.
*/
@@ -298,7 +271,7 @@
*/
#ifndef S_IFLNK
-# define S_IFLNK 0120000 /* Symbolic Link */
+#define S_IFLNK 0120000 /* Symbolic Link */
#endif
#ifndef S_ISREG
@@ -350,11 +323,11 @@
*/
#ifndef MAXPATH
-# define MAXPATH MAX_PATH
+#define MAXPATH MAX_PATH
#endif /* MAXPATH */
#ifndef MAXPATHLEN
-# define MAXPATHLEN MAXPATH
+#define MAXPATHLEN MAXPATH
#endif /* MAXPATHLEN */
/*
@@ -375,15 +348,15 @@
*/
#if defined(_MSC_VER) || defined(__MINGW32__)
-# define environ _environ
+# define environ _environ
# if defined(_MSC_VER) && (_MSC_VER < 1600)
# define hypot _hypot
# endif
-# define exception _exception
-# undef EDEADLOCK
-# if defined(__MINGW32__) && !defined(__MSVCRT__)
+# define exception _exception
+# undef EDEADLOCK
+# if defined(__MINGW32__) && !defined(__MSVCRT__)
# define timezone _timezone
-# endif
+# endif
#endif /* _MSC_VER || __MINGW32__ */
/*
@@ -395,27 +368,13 @@
# define environ _environ
#endif /* __BORLANDC__ */
-#ifdef __WATCOMC__
- /*
- * OpenWatcom uses a wine derived winsock2.h that is missing the
- * LPFN_* typedefs.
- */
-# define HAVE_NO_LPFN_DECLS
-# if !defined(__CHAR_SIGNED__)
-# error "You must use the -j switch to ensure char is signed."
-# endif
-#endif
-
-
-/*
- * MSVC 8.0 started to mark many standard C library functions depreciated
- * including the *printf family and others. Tell it to shut up.
- * (_MSC_VER is 1200 for VC6, 1300 or 1310 for vc7.net, 1400 for 8.0)
- */
-#if _MSC_VER >= 1400
-#pragma warning(disable:4996)
-#endif
-
+#ifdef __CYGWIN__
+/* On Cygwin, the environment is imported from the Cygwin DLL. */
+ DLLIMPORT extern char **__cygwin_environ;
+# define environ __cygwin_environ
+# define putenv TclCygwinPutenv
+# define timezone _timezone
+#endif /* __CYGWIN__ */
/*
* There is no platform-specific panic routine for Windows in the Tcl internals.
@@ -425,8 +384,8 @@
/*
*---------------------------------------------------------------------------
- * The following macros and declarations represent the interface between
- * generic and windows-specific parts of Tcl. Some of the macros may
+ * The following macros and declarations represent the interface between
+ * generic and windows-specific parts of Tcl. Some of the macros may
* override functions declared in tclInt.h.
*---------------------------------------------------------------------------
*/
@@ -461,13 +420,6 @@
#endif
/*
- * Older version of Mingw are known to lack a MWMO_ALERTABLE define.
- */
-#if defined(HAVE_NO_MWMO_ALERTABLE)
-# define MWMO_ALERTABLE 2
-#endif
-
-/*
* The following defines wrap the system memory allocation routines for
* use by tclAlloc.c.
*/
@@ -500,21 +452,71 @@
/*
- * The following macros have trivial definitions, allowing generic code to
+ * The following macros have trivial definitions, allowing generic code to
* address platform-specific issues.
*/
#define TclpReleaseFile(file) ckfree((char *) file)
/*
- * The following macros and declarations wrap the C runtime library
+ * The following macros and declarations wrap the C runtime library
* functions.
*/
#define TclpExit exit
+/*
+ * Declarations for Windows-only functions.
+ */
+
+EXTERN HANDLE TclWinSerialReopen _ANSI_ARGS_(( HANDLE handle,
+ CONST TCHAR *name, DWORD access));
+
+EXTERN Tcl_Channel TclWinOpenSerialChannel _ANSI_ARGS_((HANDLE handle,
+ char *channelName, int permissions));
+
+EXTERN Tcl_Channel TclWinOpenConsoleChannel _ANSI_ARGS_((HANDLE handle,
+ char *channelName, int permissions));
+
+EXTERN Tcl_Channel TclWinOpenFileChannel _ANSI_ARGS_((HANDLE handle,
+ char *channelName, int permissions, int appendMode));
+
+EXTERN TclFile TclWinMakeFile _ANSI_ARGS_((HANDLE handle));
+
+/*
+ * Platform specific mutex definition used by memory allocators.
+ * These mutexes are statically allocated and explicitly initialized.
+ * Most modules do not use this, but instead use Tcl_Mutex types and
+ * Tcl_MutexLock and Tcl_MutexUnlock that are self-initializing.
+ */
+
+#ifdef TCL_THREADS
+typedef CRITICAL_SECTION TclpMutex;
+EXTERN void TclpMutexInit _ANSI_ARGS_((TclpMutex *mPtr));
+EXTERN void TclpMutexLock _ANSI_ARGS_((TclpMutex *mPtr));
+EXTERN void TclpMutexUnlock _ANSI_ARGS_((TclpMutex *mPtr));
+#else /* !TCL_THREADS */
+typedef int TclpMutex;
+#define TclpMutexInit(a)
+#define TclpMutexLock(a)
+#define TclpMutexUnlock(a)
+#endif /* TCL_THREADS */
+
+#ifdef TCL_WIDE_INT_TYPE
+EXTERN Tcl_WideInt strtoll _ANSI_ARGS_((CONST char *string,
+ char **endPtr, int base));
+EXTERN Tcl_WideUInt strtoull _ANSI_ARGS_((CONST char *string,
+ char **endPtr, int base));
+#endif /* TCL_WIDE_INT_TYPE */
+
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
#endif /* INVALID_SET_FILE_POINTER */
+#include "tclPlatDecls.h"
+#include "tclIntPlatDecls.h"
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+
#endif /* _TCLWINPORT */
diff --git a/win/tclWinReg.c b/win/tclWinReg.c
index 8eaf2a7..d4c7292 100644
--- a/win/tclWinReg.c
+++ b/win/tclWinReg.c
@@ -1,21 +1,18 @@
/*
* tclWinReg.c --
*
- * This file contains the implementation of the "registry" Tcl built-in
- * command. This command is built as a dynamically loadable extension in
- * a separate DLL.
+ * This file contains the implementation of the "registry" Tcl
+ * built-in command. This command is built as a dynamically
+ * loadable extension in a separate DLL.
*
* Copyright (c) 1997 by Sun Microsystems, Inc.
* Copyright (c) 1998-1999 by Scriptics Corporation.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tclInt.h"
-#ifdef _MSC_VER
-# pragma comment (lib, "advapi32.lib")
-#endif
+#include <tclPort.h>
#include <stdlib.h>
/*
@@ -35,15 +32,15 @@
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
/*
- * The following flag is used in OpenKeys to indicate that the specified key
- * should be created if it doesn't currently exist.
+ * The following flag is used in OpenKeys to indicate that the specified
+ * key should be created if it doesn't currently exist.
*/
#define REG_CREATE 1
/*
- * The following tables contain the mapping from registry root names to the
- * system predefined keys.
+ * The following tables contain the mapping from registry root names
+ * to the system predefined keys.
*/
static CONST char *rootKeyNames[] = {
@@ -57,12 +54,11 @@ static HKEY rootKeys[] = {
HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, HKEY_DYN_DATA
};
-static CONST char REGISTRY_ASSOC_KEY[] = "registry::command";
-
/*
- * The following table maps from registry types to strings. Note that the
- * indices for this array are the same as the constants for the known registry
- * types so we don't need a separate table to hold the mapping.
+ * The following table maps from registry types to strings. Note that
+ * the indices for this array are the same as the constants for the
+ * known registry types so we don't need a separate table to hold the
+ * mapping.
*/
static CONST char *typeNames[] = {
@@ -74,9 +70,9 @@ static DWORD lastType = REG_RESOURCE_LIST;
/*
* The following structures allow us to select between the Unicode and ASCII
- * interfaces at run time based on whether Unicode APIs are available. The
- * Unicode APIs are preferable because they will handle characters outside of
- * the current code page.
+ * interfaces at run time based on whether Unicode APIs are available. The
+ * Unicode APIs are preferable because they will handle characters outside
+ * of the current code page.
*/
typedef struct RegWinProcs {
@@ -84,7 +80,7 @@ typedef struct RegWinProcs {
LONG (WINAPI *regConnectRegistryProc)(CONST TCHAR *, HKEY, PHKEY);
LONG (WINAPI *regCreateKeyExProc)(HKEY, CONST TCHAR *, DWORD, TCHAR *,
- DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *, DWORD *);
+ DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *, DWORD *);
LONG (WINAPI *regDeleteKeyProc)(HKEY, CONST TCHAR *);
LONG (WINAPI *regDeleteValueProc)(HKEY, CONST TCHAR *);
LONG (WINAPI *regEnumKeyProc)(HKEY, DWORD, TCHAR *, DWORD);
@@ -111,7 +107,7 @@ static RegWinProcs asciiProcs = {
(LONG (WINAPI *)(CONST TCHAR *, HKEY, PHKEY)) RegConnectRegistryA,
(LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, TCHAR *,
DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *,
- DWORD *)) RegCreateKeyExA,
+ DWORD *)) RegCreateKeyExA,
(LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteKeyA,
(LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteValueA,
(LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD)) RegEnumKeyA,
@@ -136,7 +132,7 @@ static RegWinProcs unicodeProcs = {
(LONG (WINAPI *)(CONST TCHAR *, HKEY, PHKEY)) RegConnectRegistryW,
(LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, TCHAR *,
DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *,
- DWORD *)) RegCreateKeyExW,
+ DWORD *)) RegCreateKeyExW,
(LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteKeyW,
(LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteValueW,
(LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD)) RegEnumKeyW,
@@ -164,7 +160,6 @@ static void AppendSystemError(Tcl_Interp *interp, DWORD error);
static int BroadcastValue(Tcl_Interp *interp, int objc,
Tcl_Obj * CONST objv[]);
static DWORD ConvertDWORD(DWORD type, DWORD value);
-static void DeleteCmd(ClientData clientData);
static int DeleteKey(Tcl_Interp *interp, Tcl_Obj *keyNameObj);
static int DeleteValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,
Tcl_Obj *valueNameObj);
@@ -193,15 +188,14 @@ static int SetValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,
Tcl_Obj *valueNameObj, Tcl_Obj *dataObj,
Tcl_Obj *typeObj);
-EXTERN int Registry_Init(Tcl_Interp *interp);
-EXTERN int Registry_Unload(Tcl_Interp *interp, int flags);
+EXTERN int Registry_Init(Tcl_Interp *interp);
/*
*----------------------------------------------------------------------
*
* Registry_Init --
*
- * This function initializes the registry command.
+ * This procedure initializes the registry command.
*
* Results:
* A standard Tcl result.
@@ -216,9 +210,7 @@ int
Registry_Init(
Tcl_Interp *interp)
{
- Tcl_Command cmd;
-
- if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
+ if (!Tcl_InitStubs(interp, "8.0", 0)) {
return TCL_ERROR;
}
@@ -233,80 +225,8 @@ Registry_Init(
regWinProcs = &asciiProcs;
}
- cmd = Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd,
- (ClientData)interp, DeleteCmd);
- Tcl_SetAssocData(interp, REGISTRY_ASSOC_KEY, NULL, (ClientData)cmd);
- return Tcl_PkgProvide(interp, "registry", "1.2.1");
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Registry_Unload --
- *
- * This function removes the registry command.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * The registry command is deleted and the dll may be unloaded.
- *
- *----------------------------------------------------------------------
- */
-
-int
-Registry_Unload(
- Tcl_Interp *interp, /* Interpreter for unloading */
- int flags) /* Flags passed by the unload system */
-{
- Tcl_Command cmd;
- Tcl_Obj *objv[3];
-
- /*
- * Unregister the registry package. There is no Tcl_PkgForget()
- */
-
- objv[0] = Tcl_NewStringObj("package", -1);
- objv[1] = Tcl_NewStringObj("forget", -1);
- objv[2] = Tcl_NewStringObj("registry", -1);
- Tcl_EvalObjv(interp, 3, objv, TCL_EVAL_GLOBAL);
-
- /*
- * Delete the originally registered command.
- */
-
- cmd = (Tcl_Command)Tcl_GetAssocData(interp, REGISTRY_ASSOC_KEY, NULL);
- if (cmd != NULL) {
- Tcl_DeleteCommandFromToken(interp, cmd);
- }
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * DeleteCmd --
- *
- * Cleanup the interp command token so that unloading doesn't try to
- * re-delete the command (which will crash).
- *
- * Results:
- * None.
- *
- * Side effects:
- * The unload command will not attempt to delete this command.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-DeleteCmd(
- ClientData clientData)
-{
- Tcl_Interp *interp = clientData;
- Tcl_SetAssocData(interp, REGISTRY_ASSOC_KEY, NULL, (ClientData)NULL);
+ Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd, NULL, NULL);
+ return Tcl_PkgProvide(interp, "registry", "1.1.5");
}
/*
@@ -336,7 +256,8 @@ RegistryObjCmd(
char *errString = NULL;
static CONST char *subcommands[] = {
- "broadcast", "delete", "get", "keys", "set", "type", "values", NULL
+ "broadcast", "delete", "get", "keys", "set", "type", "values",
+ (char *) NULL
};
enum SubCmdIdx {
BroadcastIdx, DeleteIdx, GetIdx, KeysIdx, SetIdx, TypeIdx, ValuesIdx
@@ -353,64 +274,65 @@ RegistryObjCmd(
}
switch (index) {
- case BroadcastIdx: /* broadcast */
- return BroadcastValue(interp, objc, objv);
- break;
- case DeleteIdx: /* delete */
- if (objc == 3) {
- return DeleteKey(interp, objv[2]);
- } else if (objc == 4) {
- return DeleteValue(interp, objv[2], objv[3]);
- }
- errString = "keyName ?valueName?";
- break;
- case GetIdx: /* get */
- if (objc == 4) {
- return GetValue(interp, objv[2], objv[3]);
- }
- errString = "keyName valueName";
- break;
- case KeysIdx: /* keys */
- if (objc == 3) {
- return GetKeyNames(interp, objv[2], NULL);
- } else if (objc == 4) {
- return GetKeyNames(interp, objv[2], objv[3]);
- }
- errString = "keyName ?pattern?";
- break;
- case SetIdx: /* set */
- if (objc == 3) {
- HKEY key;
+ case BroadcastIdx: /* broadcast */
+ return BroadcastValue(interp, objc, objv);
+ break;
+ case DeleteIdx: /* delete */
+ if (objc == 3) {
+ return DeleteKey(interp, objv[2]);
+ } else if (objc == 4) {
+ return DeleteValue(interp, objv[2], objv[3]);
+ }
+ errString = "keyName ?valueName?";
+ break;
+ case GetIdx: /* get */
+ if (objc == 4) {
+ return GetValue(interp, objv[2], objv[3]);
+ }
+ errString = "keyName valueName";
+ break;
+ case KeysIdx: /* keys */
+ if (objc == 3) {
+ return GetKeyNames(interp, objv[2], NULL);
+ } else if (objc == 4) {
+ return GetKeyNames(interp, objv[2], objv[3]);
+ }
+ errString = "keyName ?pattern?";
+ break;
+ case SetIdx: /* set */
+ if (objc == 3) {
+ HKEY key;
- /*
- * Create the key and then close it immediately.
- */
+ /*
+ * Create the key and then close it immediately.
+ */
- if (OpenKey(interp, objv[2], KEY_ALL_ACCESS, 1, &key) != TCL_OK) {
- return TCL_ERROR;
+ if (OpenKey(interp, objv[2], KEY_ALL_ACCESS, 1, &key)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ RegCloseKey(key);
+ return TCL_OK;
+ } else if (objc == 5 || objc == 6) {
+ Tcl_Obj *typeObj = (objc == 5) ? NULL : objv[5];
+ return SetValue(interp, objv[2], objv[3], objv[4], typeObj);
}
- RegCloseKey(key);
- return TCL_OK;
- } else if (objc == 5 || objc == 6) {
- Tcl_Obj *typeObj = (objc == 5) ? NULL : objv[5];
- return SetValue(interp, objv[2], objv[3], objv[4], typeObj);
- }
- errString = "keyName ?valueName data ?type??";
- break;
- case TypeIdx: /* type */
- if (objc == 4) {
- return GetType(interp, objv[2], objv[3]);
- }
- errString = "keyName valueName";
- break;
- case ValuesIdx: /* values */
- if (objc == 3) {
- return GetValueNames(interp, objv[2], NULL);
- } else if (objc == 4) {
- return GetValueNames(interp, objv[2], objv[3]);
- }
- errString = "keyName ?pattern?";
- break;
+ errString = "keyName ?valueName data ?type??";
+ break;
+ case TypeIdx: /* type */
+ if (objc == 4) {
+ return GetType(interp, objv[2], objv[3]);
+ }
+ errString = "keyName valueName";
+ break;
+ case ValuesIdx: /* values */
+ if (objc == 3) {
+ return GetValueNames(interp, objv[2], NULL);
+ } else if (objc == 4) {
+ return GetValueNames(interp, objv[2], objv[3]);
+ }
+ errString = "keyName ?pattern?";
+ break;
}
Tcl_WrongNumArgs(interp, 2, objv, errString);
return TCL_ERROR;
@@ -442,6 +364,7 @@ DeleteKey(
HKEY rootKey, subkey;
DWORD result;
int length;
+ Tcl_Obj *resultPtr;
Tcl_DString buf;
/*
@@ -452,15 +375,15 @@ DeleteKey(
buffer = ckalloc((unsigned int) length + 1);
strcpy(buffer, keyName);
- if (ParseKeyName(interp, buffer, &hostName, &rootKey,
- &keyName) != TCL_OK) {
+ if (ParseKeyName(interp, buffer, &hostName, &rootKey, &keyName)
+ != TCL_OK) {
ckfree(buffer);
return TCL_ERROR;
}
+ resultPtr = Tcl_GetObjResult(interp);
if (*keyName == '\0') {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "bad key: cannot delete root keys", -1));
+ Tcl_AppendToObj(resultPtr, "bad key: cannot delete root keys", -1);
ckfree(buffer);
return TCL_ERROR;
}
@@ -479,11 +402,11 @@ DeleteKey(
ckfree(buffer);
if (result == ERROR_FILE_NOT_FOUND) {
return TCL_OK;
+ } else {
+ Tcl_AppendToObj(resultPtr, "unable to delete key: ", -1);
+ AppendSystemError(interp, result);
+ return TCL_ERROR;
}
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "unable to delete key: ", -1));
- AppendSystemError(interp, result);
- return TCL_ERROR;
}
/*
@@ -495,8 +418,7 @@ DeleteKey(
Tcl_DStringFree(&buf);
if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("unable to delete key: ", -1));
+ Tcl_AppendToObj(resultPtr, "unable to delete key: ", -1);
AppendSystemError(interp, result);
result = TCL_ERROR;
} else {
@@ -534,6 +456,7 @@ DeleteValue(
char *valueName;
int length;
DWORD result;
+ Tcl_Obj *resultPtr;
Tcl_DString ds;
/*
@@ -545,12 +468,13 @@ DeleteValue(
return TCL_ERROR;
}
+ resultPtr = Tcl_GetObjResult(interp);
valueName = Tcl_GetStringFromObj(valueNameObj, &length);
Tcl_WinUtfToTChar(valueName, length, &ds);
result = (*regWinProcs->regDeleteValueProc)(key, Tcl_DStringValue(&ds));
Tcl_DStringFree(&ds);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to delete value \"",
+ Tcl_AppendStringsToObj(resultPtr, "unable to delete value \"",
Tcl_GetString(valueNameObj), "\" from key \"",
Tcl_GetString(keyNameObj), "\": ", NULL);
AppendSystemError(interp, result);
@@ -567,13 +491,13 @@ DeleteValue(
*
* GetKeyNames --
*
- * This function enumerates the subkeys of a given key. If the optional
- * pattern is supplied, then only keys that match the pattern will be
- * returned.
+ * This function enumerates the subkeys of a given key. If the
+ * optional pattern is supplied, then only keys that match the
+ * pattern will be returned.
*
* Results:
- * Returns the list of subkeys in the result object of the interpreter,
- * or an error message on failure.
+ * Returns the list of subkeys in the result object of the
+ * interpreter, or an error message on failure.
*
* Side effects:
* None.
@@ -613,17 +537,17 @@ GetKeyNames(
return TCL_ERROR;
}
- /*
+ /*
* Determine how big a buffer is needed for enumerating subkeys, and
* how many subkeys there are
*/
result = (*regWinProcs->regQueryInfoKeyProc)
- (key, NULL, NULL, NULL, &subKeyCount, &maxSubKeyLen, NULL, NULL,
+ (key, NULL, NULL, NULL, &subKeyCount, &maxSubKeyLen, NULL, NULL,
NULL, NULL, NULL, NULL);
if (result != ERROR_SUCCESS) {
Tcl_SetObjResult(interp, Tcl_NewObj());
- Tcl_AppendResult(interp, "unable to query key \"",
+ Tcl_AppendResult(interp, "unable to query key \"",
Tcl_GetString(keyNameObj), "\": ", NULL);
AppendSystemError(interp, result);
RegCloseKey(key);
@@ -683,8 +607,8 @@ GetKeyNames(
*
* GetType --
*
- * This function gets the type of a given registry value and places it in
- * the interpreter result.
+ * This function gets the type of a given registry value and
+ * places it in the interpreter result.
*
* Results:
* Returns a normal Tcl result.
@@ -702,6 +626,7 @@ GetType(
Tcl_Obj *valueNameObj) /* Name of value to get. */
{
HKEY key;
+ Tcl_Obj *resultPtr;
DWORD result;
DWORD type;
Tcl_DString ds;
@@ -722,6 +647,8 @@ GetType(
* Get the type of the value.
*/
+ resultPtr = Tcl_GetObjResult(interp);
+
valueName = Tcl_GetStringFromObj(valueNameObj, &length);
nativeValue = Tcl_WinUtfToTChar(valueName, length, &ds);
result = (*regWinProcs->regQueryValueExProc)(key, nativeValue, NULL, &type,
@@ -730,7 +657,7 @@ GetType(
RegCloseKey(key);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to get type of value \"",
+ Tcl_AppendStringsToObj(resultPtr, "unable to get type of value \"",
Tcl_GetString(valueNameObj), "\" from key \"",
Tcl_GetString(keyNameObj), "\": ", NULL);
AppendSystemError(interp, result);
@@ -738,14 +665,14 @@ GetType(
}
/*
- * Set the type into the result. Watch out for unknown types. If we don't
- * know about the type, just use the numeric value.
+ * Set the type into the result. Watch out for unknown types.
+ * If we don't know about the type, just use the numeric value.
*/
if (type > lastType) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj((int) type));
+ Tcl_SetIntObj(resultPtr, (int) type);
} else {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(typeNames[type], -1));
+ Tcl_SetStringObj(resultPtr, typeNames[type], -1);
}
return TCL_OK;
}
@@ -755,8 +682,9 @@ GetType(
*
* GetValue --
*
- * This function gets the contents of a registry value and places a list
- * containing the data and the type in the interpreter result.
+ * This function gets the contents of a registry value and places
+ * a list containing the data and the type in the interpreter
+ * result.
*
* Results:
* Returns a normal Tcl result.
@@ -777,6 +705,7 @@ GetValue(
char *valueName;
CONST char *nativeValue;
DWORD result, length, type;
+ Tcl_Obj *resultPtr;
Tcl_DString data, buf;
int nameLen;
@@ -784,15 +713,16 @@ GetValue(
* Attempt to open the key for reading.
*/
- if (OpenKey(interp, keyNameObj, KEY_QUERY_VALUE, 0, &key) != TCL_OK) {
+ if (OpenKey(interp, keyNameObj, KEY_QUERY_VALUE, 0, &key)
+ != TCL_OK) {
return TCL_ERROR;
}
/*
- * 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 of Dstrings changes.
+ * 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 of 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.
@@ -802,6 +732,8 @@ GetValue(
length = TCL_DSTRING_STATIC_SIZE - 1;
Tcl_DStringSetLength(&data, (int) length);
+ resultPtr = Tcl_GetObjResult(interp);
+
valueName = Tcl_GetStringFromObj(valueNameObj, &nameLen);
nativeValue = Tcl_WinUtfToTChar(valueName, nameLen, &buf);
@@ -809,20 +741,19 @@ GetValue(
(BYTE *) Tcl_DStringValue(&data), &length);
while (result == ERROR_MORE_DATA) {
/*
- * The Windows docs say that in this error case, we just need to
- * expand our buffer and request more data. Required for
- * HKEY_PERFORMANCE_DATA
+ * The Windows docs say that in this error case, we just need
+ * to expand our buffer and request more data.
+ * Required for HKEY_PERFORMANCE_DATA
*/
-
length *= 2;
- Tcl_DStringSetLength(&data, (int) length);
- result = (*regWinProcs->regQueryValueExProc)(key, (char *) nativeValue,
+ Tcl_DStringSetLength(&data, (int) length);
+ result = (*regWinProcs->regQueryValueExProc)(key, (char *) nativeValue,
NULL, &type, (BYTE *) Tcl_DStringValue(&data), &length);
}
Tcl_DStringFree(&buf);
RegCloseKey(key);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to get value \"",
+ Tcl_AppendStringsToObj(resultPtr, "unable to get value \"",
Tcl_GetString(valueNameObj), "\" from key \"",
Tcl_GetString(keyNameObj), "\": ", NULL);
AppendSystemError(interp, result);
@@ -831,27 +762,26 @@ GetValue(
}
/*
- * If the data is a 32-bit quantity, store it as an integer object. If it
- * is a multi-string, store it as a list of strings. For null-terminated
- * strings, append up the to first null. Otherwise, store it as a binary
+ * If the data is a 32-bit quantity, store it as an integer object. If it
+ * is a multi-string, store it as a list of strings. For null-terminated
+ * strings, append up the to first null. Otherwise, store it as a binary
* string.
*/
if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj((int) ConvertDWORD(type,
- *((DWORD*) Tcl_DStringValue(&data)))));
+ Tcl_SetIntObj(resultPtr, (int) ConvertDWORD(type,
+ *((DWORD*) Tcl_DStringValue(&data))));
} else if (type == REG_MULTI_SZ) {
char *p = Tcl_DStringValue(&data);
char *end = Tcl_DStringValue(&data) + length;
- Tcl_Obj *resultPtr = Tcl_NewObj();
/*
* Multistrings are stored as an array of null-terminated strings,
- * terminated by two null characters. Also do a bounds check in case
- * we get bogus data.
+ * terminated by two null characters. Also do a bounds check in
+ * case we get bogus data.
*/
-
- while (p < end && ((regWinProcs->useWide)
+
+ while (p < end && ((regWinProcs->useWide)
? *((Tcl_UniChar *)p) : *p) != 0) {
Tcl_WinTCharToUtf((TCHAR *) p, -1, &buf);
Tcl_ListObjAppendElement(interp, resultPtr,
@@ -866,17 +796,17 @@ GetValue(
}
Tcl_DStringFree(&buf);
}
- Tcl_SetObjResult(interp, resultPtr);
} else if ((type == REG_SZ) || (type == REG_EXPAND_SZ)) {
Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&data), -1, &buf);
- Tcl_DStringResult(interp, &buf);
+ Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&buf),
+ Tcl_DStringLength(&buf));
+ Tcl_DStringFree(&buf);
} else {
/*
* Save binary data as a byte array.
*/
- Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(
- (BYTE *) Tcl_DStringValue(&data), (int) length));
+ Tcl_SetByteArrayObj(resultPtr, (BYTE *) Tcl_DStringValue(&data), (int) length);
}
Tcl_DStringFree(&data);
return result;
@@ -887,9 +817,9 @@ GetValue(
*
* GetValueNames --
*
- * This function enumerates the values of the a given key. If the
- * optional pattern is supplied, then only value names that match the
- * pattern will be returned.
+ * This function enumerates the values of the a given key. If
+ * the optional pattern is supplied, then only value names that
+ * match the pattern will be returned.
*
* Results:
* Returns the list of value names in the result object of the
@@ -922,6 +852,8 @@ GetValueNames(
return TCL_ERROR;
}
+ resultPtr = Tcl_GetObjResult(interp);
+
/*
* Query the key to determine the appropriate buffer size to hold the
* largest value name plus the terminating null.
@@ -930,7 +862,7 @@ GetValueNames(
result = (*regWinProcs->regQueryInfoKeyProc)(key, NULL, NULL, NULL, NULL,
NULL, NULL, &index, &maxSize, NULL, NULL, NULL);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to query key \"",
+ Tcl_AppendStringsToObj(resultPtr, "unable to query key \"",
Tcl_GetString(keyNameObj), "\": ", NULL);
AppendSystemError(interp, result);
RegCloseKey(key);
@@ -939,7 +871,7 @@ GetValueNames(
}
maxSize++;
- resultPtr = Tcl_NewObj();
+
Tcl_DStringInit(&buffer);
Tcl_DStringSetLength(&buffer,
(int) ((regWinProcs->useWide) ? maxSize*2 : maxSize));
@@ -954,8 +886,8 @@ GetValueNames(
/*
* Enumerate the values under the given subkey until we get an error,
- * indicating the end of the list. Note that we need to reset size after
- * each iteration because RegEnumValue smashes the old value.
+ * indicating the end of the list. Note that we need to reset size
+ * after each iteration because RegEnumValue smashes the old value.
*/
size = maxSize;
@@ -967,8 +899,7 @@ GetValueNames(
size *= 2;
}
- Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&buffer), (int) size,
- &ds);
+ Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&buffer), (int) size, &ds);
name = Tcl_DStringValue(&ds);
if (!pattern || Tcl_StringMatch(name, pattern)) {
result = Tcl_ListObjAppendElement(interp, resultPtr,
@@ -983,10 +914,9 @@ GetValueNames(
index++;
size = maxSize;
}
- Tcl_SetObjResult(interp, resultPtr);
Tcl_DStringFree(&buffer);
- done:
+ done:
RegCloseKey(key);
return result;
}
@@ -996,11 +926,12 @@ GetValueNames(
*
* OpenKey --
*
- * This function opens the specified key. This function is a simple
- * wrapper around ParseKeyName and OpenSubKey.
+ * This function opens the specified key. This function is a
+ * simple wrapper around ParseKeyName and OpenSubKey.
*
* Results:
- * Returns the opened key in the keyPtr argument and a Tcl result code.
+ * Returns the opened key in the keyPtr argument and a Tcl
+ * result code.
*
* Side effects:
* None.
@@ -1029,8 +960,8 @@ OpenKey(
if (result == TCL_OK) {
result = OpenSubKey(hostName, rootKey, keyName, mode, flags, keyPtr);
if (result != ERROR_SUCCESS) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("unable to open key: ", -1));
+ Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
+ Tcl_AppendToObj(resultPtr, "unable to open key: ", -1);
AppendSystemError(interp, result);
result = TCL_ERROR;
} else {
@@ -1047,12 +978,12 @@ OpenKey(
*
* OpenSubKey --
*
- * This function opens a given subkey of a root key on the specified
- * host.
+ * This function opens a given subkey of a root key on the
+ * specified host.
*
* Results:
- * Returns the opened key in the keyPtr and a Windows error code as the
- * return value.
+ * Returns the opened key in the keyPtr and a Windows error code
+ * as the return value.
*
* Side effects:
* None.
@@ -1087,8 +1018,8 @@ OpenSubKey(
}
/*
- * Now open the specified key with the requested permissions. Note that
- * this key must be closed by the caller.
+ * Now open the specified key with the requested permissions. Note
+ * that this key must be closed by the caller.
*/
keyName = (char *) Tcl_WinUtfToTChar(keyName, -1, &buf);
@@ -1096,16 +1027,19 @@ OpenSubKey(
DWORD create;
result = (*regWinProcs->regCreateKeyExProc)(rootKey, keyName, 0, NULL,
REG_OPTION_NON_VOLATILE, mode, NULL, keyPtr, &create);
- } else if (rootKey == HKEY_PERFORMANCE_DATA) {
- /*
- * Here we fudge it for this special root key. See MSDN for more info
- * on HKEY_PERFORMANCE_DATA and the peculiarities surrounding it.
- */
- *keyPtr = HKEY_PERFORMANCE_DATA;
- result = ERROR_SUCCESS;
} else {
- result = (*regWinProcs->regOpenKeyExProc)(rootKey, keyName, 0, mode,
- keyPtr);
+ if (rootKey == HKEY_PERFORMANCE_DATA) {
+ /*
+ * Here we fudge it for this special root key.
+ * See MSDN for more info on HKEY_PERFORMANCE_DATA and
+ * the peculiarities surrounding it
+ */
+ *keyPtr = HKEY_PERFORMANCE_DATA;
+ result = ERROR_SUCCESS;
+ } else {
+ result = (*regWinProcs->regOpenKeyExProc)(rootKey, keyName, 0,
+ mode, keyPtr);
+ }
}
Tcl_DStringFree(&buf);
@@ -1124,12 +1058,15 @@ OpenSubKey(
*
* ParseKeyName --
*
- * This function parses a key name into the host, root, and subkey parts.
+ * This function parses a key name into the host, root, and subkey
+ * parts.
*
* Results:
- * The pointers to the start of the host and subkey names are returned in
- * the hostNamePtr and keyNamePtr variables. The specified root HKEY is
- * returned in rootKeyPtr. Returns a standard Tcl result.
+ * The pointers to the start of the host and subkey names are
+ * returned in the hostNamePtr and keyNamePtr variables. The
+ * specified root HKEY is returned in rootKeyPtr. Returns
+ * a standard Tcl result.
+ *
*
* Side effects:
* Modifies the name string by inserting nulls.
@@ -1147,7 +1084,7 @@ ParseKeyName(
{
char *rootName;
int result, index;
- Tcl_Obj *rootObj;
+ Tcl_Obj *rootObj, *resultPtr = Tcl_GetObjResult(interp);
/*
* Split the key into host and root portions.
@@ -1168,7 +1105,7 @@ ParseKeyName(
rootName = name;
}
if (!rootName) {
- Tcl_AppendResult(interp, "bad key \"", name,
+ Tcl_AppendStringsToObj(resultPtr, "bad key \"", name,
"\": must start with a valid root", NULL);
return TCL_ERROR;
}
@@ -1205,9 +1142,9 @@ ParseKeyName(
*
* RecursiveDeleteKey --
*
- * This function recursively deletes all the keys below a starting key.
- * Although Windows 95 does this automatically, we still need to do this
- * for Windows NT.
+ * This function recursively deletes all the keys below a starting
+ * key. Although Windows 95 does this automatically, we still need
+ * to do this for Windows NT.
*
* Results:
* Returns a Windows error code.
@@ -1277,9 +1214,9 @@ RecursiveDeleteKey(
*
* SetValue --
*
- * This function sets the contents of a registry value. If the key or
- * value does not exist, it will be created. If it does exist, then the
- * data and type will be replaced.
+ * This function sets the contents of a registry value. If
+ * the key or value does not exist, it will be created. If it
+ * does exist, then the data and type will be replaced.
*
* Results:
* Returns a normal Tcl result.
@@ -1298,11 +1235,11 @@ SetValue(
Tcl_Obj *dataObj, /* Data to be written. */
Tcl_Obj *typeObj) /* Type of data to be written. */
{
- int type;
- DWORD result;
+ DWORD type, result;
HKEY key;
int length;
char *valueName;
+ Tcl_Obj *resultPtr;
Tcl_DString nameBuf;
if (typeObj == NULL) {
@@ -1320,19 +1257,19 @@ SetValue(
valueName = Tcl_GetStringFromObj(valueNameObj, &length);
valueName = (char *) Tcl_WinUtfToTChar(valueName, length, &nameBuf);
+ resultPtr = Tcl_GetObjResult(interp);
if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
- int value;
-
- if (Tcl_GetIntFromObj(interp, dataObj, &value) != TCL_OK) {
+ DWORD value;
+ if (Tcl_GetIntFromObj(interp, dataObj, (int*) &value) != TCL_OK) {
RegCloseKey(key);
Tcl_DStringFree(&nameBuf);
return TCL_ERROR;
}
- value = ConvertDWORD((DWORD)type, (DWORD)value);
- result = (*regWinProcs->regSetValueExProc)(key, valueName, 0,
- (DWORD) type, (BYTE *) &value, sizeof(DWORD));
+ value = ConvertDWORD(type, value);
+ result = (*regWinProcs->regSetValueExProc)(key, valueName, 0, type,
+ (BYTE*) &value, sizeof(DWORD));
} else if (type == REG_MULTI_SZ) {
Tcl_DString data, buf;
int objc, i;
@@ -1345,9 +1282,9 @@ SetValue(
}
/*
- * Append the elements as null terminated strings. Note that we must
- * not assume the length of the string in case there are embedded
- * nulls, which aren't allowed in REG_MULTI_SZ values.
+ * Append the elements as null terminated strings. Note that
+ * we must not assume the length of the string in case there are
+ * embedded nulls, which aren't allowed in REG_MULTI_SZ values.
*/
Tcl_DStringInit(&data);
@@ -1355,8 +1292,8 @@ SetValue(
Tcl_DStringAppend(&data, Tcl_GetString(objv[i]), -1);
/*
- * Add a null character to separate this value from the next. We
- * accomplish this by growing the string by one byte. Since the
+ * Add a null character to separate this value from the next.
+ * We accomplish this by growing the string by one byte. Since the
* DString always tacks on an extra null byte, the new byte will
* already be set to null.
*/
@@ -1366,16 +1303,16 @@ SetValue(
Tcl_WinUtfToTChar(Tcl_DStringValue(&data), Tcl_DStringLength(&data)+1,
&buf);
- result = (*regWinProcs->regSetValueExProc)(key, valueName, 0,
- (DWORD) type, (BYTE *) Tcl_DStringValue(&buf),
+ result = (*regWinProcs->regSetValueExProc)(key, valueName, 0, type,
+ (BYTE *) Tcl_DStringValue(&buf),
(DWORD) Tcl_DStringLength(&buf));
Tcl_DStringFree(&data);
Tcl_DStringFree(&buf);
} else if (type == REG_SZ || type == REG_EXPAND_SZ) {
Tcl_DString buf;
- CONST char *data = Tcl_GetStringFromObj(dataObj, &length);
+ char *data = Tcl_GetStringFromObj(dataObj, &length);
- data = Tcl_WinUtfToTChar(data, length, &buf);
+ data = (char *) Tcl_WinUtfToTChar(data, length, &buf);
/*
* Include the null in the length, padding if needed for Unicode.
@@ -1386,8 +1323,8 @@ SetValue(
}
length = Tcl_DStringLength(&buf) + 1;
- result = (*regWinProcs->regSetValueExProc)(key, valueName, 0,
- (DWORD) type, (BYTE *) data, (DWORD) length);
+ result = (*regWinProcs->regSetValueExProc)(key, valueName, 0, type,
+ (BYTE*)data, (DWORD) length);
Tcl_DStringFree(&buf);
} else {
BYTE *data;
@@ -1396,17 +1333,14 @@ SetValue(
* Store binary data in the registry.
*/
- data = (BYTE *) Tcl_GetByteArrayFromObj(dataObj, &length);
- result = (*regWinProcs->regSetValueExProc)(key, valueName, 0,
- (DWORD) type, data, (DWORD) length);
+ data = Tcl_GetByteArrayFromObj(dataObj, &length);
+ result = (*regWinProcs->regSetValueExProc)(key, valueName, 0, type,
+ data, (DWORD) length);
}
-
Tcl_DStringFree(&nameBuf);
RegCloseKey(key);
-
if (result != ERROR_SUCCESS) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("unable to set value: ", -1));
+ Tcl_AppendToObj(resultPtr, "unable to set value: ", -1);
AppendSystemError(interp, result);
return TCL_ERROR;
}
@@ -1418,8 +1352,9 @@ SetValue(
*
* BroadcastValue --
*
- * This function broadcasts a WM_SETTINGCHANGE message to indicate to
- * other programs that we have changed the contents of a registry value.
+ * This function broadcasts a WM_SETTINGCHANGE message to indicate
+ * to other programs that we have changed the contents of a registry
+ * value.
*
* Results:
* Returns a normal Tcl result.
@@ -1434,13 +1369,13 @@ static int
BroadcastValue(
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *CONST objv[]) /* Argument values. */
+ Tcl_Obj * CONST objv[]) /* Argument values. */
{
LRESULT result;
DWORD_PTR sendResult;
UINT timeout = 3000;
int len;
- CONST char *str;
+ char *str;
Tcl_Obj *objPtr;
if ((objc != 3) && (objc != 5)) {
@@ -1450,8 +1385,7 @@ BroadcastValue(
if (objc > 3) {
str = Tcl_GetStringFromObj(objv[3], &len);
- if ((len < 2) || (*str != '-')
- || strncmp(str, "-timeout", (size_t) len)) {
+ if ((len < 2) || (*str != '-') || strncmp(str, "-timeout", (size_t) len)) {
Tcl_WrongNumArgs(interp, 2, objv, "keyName ?-timeout millisecs?");
return TCL_ERROR;
}
@@ -1468,7 +1402,6 @@ BroadcastValue(
/*
* Use the ignore the result.
*/
-
result = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE,
(WPARAM) 0, (LPARAM) str, SMTO_ABORTIFHUNG, timeout, &sendResult);
@@ -1485,8 +1418,8 @@ BroadcastValue(
*
* AppendSystemError --
*
- * This routine formats a Windows system error message and places it into
- * the interpreter result.
+ * This routine formats a Windows system error message and places
+ * it into the interpreter result.
*
* Results:
* None.
@@ -1503,18 +1436,15 @@ AppendSystemError(
DWORD error) /* Result code from error. */
{
int length;
- WCHAR *wMsgPtr, **wMsgPtrPtr = &wMsgPtr;
+ WCHAR *wMsgPtr;
char *msg;
char id[TCL_INTEGER_SPACE], msgBuf[24 + TCL_INTEGER_SPACE];
Tcl_DString ds;
Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
- if (Tcl_IsShared(resultPtr)) {
- resultPtr = Tcl_DuplicateObj(resultPtr);
- }
length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) wMsgPtrPtr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) &wMsgPtr,
0, NULL);
if (length == 0) {
char *msgPtr;
@@ -1551,7 +1481,6 @@ AppendSystemError(
/*
* Trim the trailing CR/LF from the system message.
*/
-
if (msg[length-1] == '\n') {
msg[--length] = 0;
}
@@ -1561,9 +1490,8 @@ AppendSystemError(
}
sprintf(id, "%ld", error);
- Tcl_SetErrorCode(interp, "WINDOWS", id, msg, NULL);
+ Tcl_SetErrorCode(interp, "WINDOWS", id, msg, (char *) NULL);
Tcl_AppendToObj(resultPtr, msg, length);
- Tcl_SetObjResult(interp, resultPtr);
if (length != 0) {
Tcl_DStringFree(&ds);
@@ -1575,8 +1503,8 @@ AppendSystemError(
*
* ConvertDWORD --
*
- * This function determines whether a DWORD needs to be byte swapped, and
- * returns the appropriately swapped value.
+ * This function determines whether a DWORD needs to be byte
+ * swapped, and returns the appropriately swapped value.
*
* Results:
* Returns a converted DWORD.
@@ -1599,14 +1527,6 @@ ConvertDWORD(
* Check to see if the low bit is in the first byte.
*/
- localType = (*((char*) &order) == 1) ? REG_DWORD : REG_DWORD_BIG_ENDIAN;
- return (type != localType) ? (DWORD) SWAPLONG(value) : value;
+ localType = (*((char*)(&order)) == 1) ? REG_DWORD : REG_DWORD_BIG_ENDIAN;
+ return (type != localType) ? (DWORD)SWAPLONG(value) : value;
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c
index fb092ff..24c6a67 100644
--- a/win/tclWinSerial.c
+++ b/win/tclWinSerial.c
@@ -1,19 +1,21 @@
/*
* tclWinSerial.c --
*
- * This file implements the Windows-specific serial port functions, and
- * the "serial" channel driver.
+ * This file implements the Windows-specific serial port functions,
+ * and the "serial" channel driver.
*
* Copyright (c) 1999 by Scriptics Corp.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Serial functionality implemented by Rolf.Schroedter@dlr.de
*/
#include "tclWinInt.h"
+#include <fcntl.h>
+#include <io.h>
#include <sys/stat.h>
/*
@@ -35,30 +37,27 @@ TCL_DECLARE_MUTEX(serialMutex)
* Bit masks used in the flags field of the SerialInfo structure below.
*/
-#define SERIAL_PENDING (1<<0) /* Message is pending in the queue. */
-#define SERIAL_ASYNC (1<<1) /* Channel is non-blocking. */
+#define SERIAL_PENDING (1<<0) /* Message is pending in the queue. */
+#define SERIAL_ASYNC (1<<1) /* Channel is non-blocking. */
/*
* Bit masks used in the sharedFlags field of the SerialInfo structure below.
*/
-#define SERIAL_EOF (1<<2) /* Serial has reached EOF. */
-#define SERIAL_ERROR (1<<4)
+#define SERIAL_EOF (1<<2) /* Serial has reached EOF. */
+#define SERIAL_ERROR (1<<4)
/*
* Default time to block between checking status on the serial port.
*/
-
-#define SERIAL_DEFAULT_BLOCKTIME 10 /* 10 msec */
+#define SERIAL_DEFAULT_BLOCKTIME 10 /* 10 msec */
/*
* Define Win32 read/write error masks returned by ClearCommError()
*/
-
-#define SERIAL_READ_ERRORS \
- (CE_RXOVER | CE_OVERRUN | CE_RXPARITY | CE_FRAME | CE_BREAK)
-#define SERIAL_WRITE_ERRORS \
- (CE_TXFULL | CE_PTO)
+#define SERIAL_READ_ERRORS ( CE_RXOVER | CE_OVERRUN | CE_RXPARITY \
+ | CE_FRAME | CE_BREAK )
+#define SERIAL_WRITE_ERRORS ( CE_TXFULL | CE_PTO )
/*
* This structure describes per-instance data for a serial based channel.
@@ -66,66 +65,68 @@ TCL_DECLARE_MUTEX(serialMutex)
typedef struct SerialInfo {
HANDLE handle;
- struct SerialInfo *nextPtr; /* Pointer to next registered serial. */
- Tcl_Channel channel; /* Pointer to channel structure. */
- int validMask; /* OR'ed combination of TCL_READABLE,
- * TCL_WRITABLE, or TCL_EXCEPTION: indicates
- * which operations are valid on the file. */
- int watchMask; /* OR'ed combination of TCL_READABLE,
- * TCL_WRITABLE, or TCL_EXCEPTION: indicates
- * which events should be reported. */
- int flags; /* State flags, see above for a list. */
- int readable; /* Flag that the channel is readable. */
- int writable; /* Flag that the channel is writable. */
- int blockTime; /* Maximum blocktime in msec. */
- unsigned int lastEventTime; /* Time in milliseconds since last readable
- * event. */
+ struct SerialInfo *nextPtr; /* Pointer to next registered serial. */
+ Tcl_Channel channel; /* Pointer to channel structure. */
+ int validMask; /* OR'ed combination of TCL_READABLE,
+ * TCL_WRITABLE, or TCL_EXCEPTION: indicates
+ * which operations are valid on the file. */
+ int watchMask; /* OR'ed combination of TCL_READABLE,
+ * TCL_WRITABLE, or TCL_EXCEPTION: indicates
+ * which events should be reported. */
+ int flags; /* State flags, see above for a list. */
+ int readable; /* flag that the channel is readable */
+ int writable; /* flag that the channel is writable */
+ int blockTime; /* max. blocktime in msec */
+ unsigned int lastEventTime; /* Time in milliseconds since last readable event */
/* Next readable event only after blockTime */
- DWORD error; /* pending error code returned by
- * ClearCommError() */
- DWORD lastError; /* last error code, can be fetched with
- * fconfigure chan -lasterror */
- DWORD sysBufRead; /* Win32 system buffer size for read ops,
- * default=4096 */
- DWORD sysBufWrite; /* Win32 system buffer size for write ops,
- * default=4096 */
-
- Tcl_ThreadId threadId; /* Thread to which events should be reported.
- * This value is used by the reader/writer
- * threads. */
- OVERLAPPED osRead; /* OVERLAPPED structure for read operations. */
- OVERLAPPED osWrite; /* OVERLAPPED structure for write operations */
- HANDLE writeThread; /* Handle to writer thread. */
- CRITICAL_SECTION csWrite; /* Writer thread synchronisation. */
- HANDLE evWritable; /* Manual-reset event to signal when the
- * writer thread has finished waiting for the
- * current buffer to be written. */
- HANDLE evStartWriter; /* Auto-reset event used by the main thread to
- * signal when the writer thread should
- * attempt to write to the serial. */
+ DWORD error; /* pending error code returned by
+ * ClearCommError() */
+ DWORD lastError; /* last error code, can be fetched with
+ * fconfigure chan -lasterror */
+ DWORD sysBufRead; /* Win32 system buffer size for read ops,
+ * default=4096 */
+ DWORD sysBufWrite; /* Win32 system buffer size for write ops,
+ * default=4096 */
+
+ Tcl_ThreadId threadId; /* Thread to which events should be reported.
+ * This value is used by the reader/writer
+ * threads. */
+ OVERLAPPED osRead; /* OVERLAPPED structure for read operations */
+ OVERLAPPED osWrite; /* OVERLAPPED structure for write operations */
+ HANDLE writeThread; /* Handle to writer thread. */
+ CRITICAL_SECTION csWrite; /* Writer thread synchronisation */
+ HANDLE evWritable; /* Manual-reset event to signal when the
+ * writer thread has finished waiting for
+ * the current buffer to be written. */
+ HANDLE evStartWriter; /* Auto-reset event used by the main thread to
+ * signal when the writer thread should attempt
+ * to write to the serial. */
HANDLE evStopWriter; /* Auto-reset event used by the main thread to
- * signal when the writer thread should close.
+ * signal when the writer thread should close.
*/
- DWORD writeError; /* An error caused by the last background
- * write. Set to 0 if no error has been
- * detected. This word is shared with the
- * writer thread so access must be
- * synchronized with the evWritable object. */
- char *writeBuf; /* Current background output buffer. Access is
- * synchronized with the evWritable object. */
- int writeBufLen; /* Size of write buffer. Access is
- * synchronized with the evWritable object. */
- int toWrite; /* Current amount to be written. Access is
- * synchronized with the evWritable object. */
- int writeQueue; /* Number of bytes pending in output queue.
- * Offset to DCB.cbInQue. Used to query
- * [fconfigure -queue] */
+ DWORD writeError; /* An error caused by the last background
+ * write. Set to 0 if no error has been
+ * detected. This word is shared with the
+ * writer thread so access must be
+ * synchronized with the evWritable object.
+ */
+ char *writeBuf; /* Current background output buffer.
+ * Access is synchronized with the evWritable
+ * object. */
+ int writeBufLen; /* Size of write buffer. Access is
+ * synchronized with the evWritable
+ * object. */
+ int toWrite; /* Current amount to be written. Access is
+ * synchronized with the evWritable object. */
+ int writeQueue; /* Number of bytes pending in output queue.
+ * Offset to DCB.cbInQue.
+ * Used to query [fconfigure -queue] */
} SerialInfo;
typedef struct ThreadSpecificData {
/*
- * The following pointer refers to the head of the list of serials that
- * are being watched for file events.
+ * The following pointer refers to the head of the list of serials
+ * that are being watched for file events.
*/
SerialInfo *firstSerialPtr;
@@ -134,17 +135,17 @@ typedef struct ThreadSpecificData {
static Tcl_ThreadDataKey dataKey;
/*
- * The following structure is what is added to the Tcl event queue when serial
- * events are generated.
+ * The following structure is what is added to the Tcl event queue when
+ * serial events are generated.
*/
typedef struct SerialEvent {
- Tcl_Event header; /* Information that is standard for all
- * events. */
- SerialInfo *infoPtr; /* Pointer to serial info structure. Note that
- * we still have to verify that the serial
- * exists before dereferencing this
- * pointer. */
+ Tcl_Event header; /* Information that is standard for
+ * all events. */
+ SerialInfo *infoPtr; /* Pointer to serial info structure. Note
+ * that we still have to verify that the
+ * serial exists before dereferencing this
+ * pointer. */
} SerialEvent;
/*
@@ -152,47 +153,43 @@ typedef struct SerialEvent {
*/
static COMMTIMEOUTS no_timeout = {
- 0, /* ReadIntervalTimeout */
- 0, /* ReadTotalTimeoutMultiplier */
- 0, /* ReadTotalTimeoutConstant */
- 0, /* WriteTotalTimeoutMultiplier */
- 0, /* WriteTotalTimeoutConstant */
+ 0, /* ReadIntervalTimeout */
+ 0, /* ReadTotalTimeoutMultiplier */
+ 0, /* ReadTotalTimeoutConstant */
+ 0, /* WriteTotalTimeoutMultiplier */
+ 0, /* WriteTotalTimeoutConstant */
};
/*
* Declarations for functions used only in this file.
*/
-static int SerialBlockProc(ClientData instanceData, int mode);
-static void SerialCheckProc(ClientData clientData, int flags);
-static int SerialCloseProc(ClientData instanceData,
- Tcl_Interp *interp);
-static int SerialEventProc(Tcl_Event *evPtr, int flags);
-static void SerialExitHandler(ClientData clientData);
-static int SerialGetHandleProc(ClientData instanceData,
- int direction, ClientData *handlePtr);
+static int SerialBlockProc(ClientData instanceData, int mode);
+static void SerialCheckProc(ClientData clientData, int flags);
+static int SerialCloseProc(ClientData instanceData,
+ Tcl_Interp *interp);
+static int SerialEventProc(Tcl_Event *evPtr, int flags);
+static void SerialExitHandler(ClientData clientData);
+static int SerialGetHandleProc(ClientData instanceData,
+ int direction, ClientData *handlePtr);
static ThreadSpecificData *SerialInit(void);
-static int SerialInputProc(ClientData instanceData, char *buf,
- int toRead, int *errorCode);
-static int SerialOutputProc(ClientData instanceData,
- CONST char *buf, int toWrite, int *errorCode);
-static void SerialSetupProc(ClientData clientData, int flags);
-static void SerialWatchProc(ClientData instanceData, int mask);
-static void ProcExitHandler(ClientData clientData);
-static int SerialGetOptionProc(ClientData instanceData,
- Tcl_Interp *interp, CONST char *optionName,
- Tcl_DString *dsPtr);
-static int SerialSetOptionProc(ClientData instanceData,
- Tcl_Interp *interp, CONST char *optionName,
- CONST char *value);
-static DWORD WINAPI SerialWriterThread(LPVOID arg);
-static void SerialThreadActionProc(ClientData instanceData,
- int action);
-static int SerialBlockingRead(SerialInfo *infoPtr, LPVOID buf,
- DWORD bufSize, LPDWORD lpRead, LPOVERLAPPED osPtr);
-static int SerialBlockingWrite(SerialInfo *infoPtr, LPVOID buf,
- DWORD bufSize, LPDWORD lpWritten,
- LPOVERLAPPED osPtr);
+static int SerialInputProc(ClientData instanceData, char *buf,
+ int toRead, int *errorCode);
+static int SerialOutputProc(ClientData instanceData, CONST char *buf,
+ int toWrite, int *errorCode);
+static void SerialSetupProc(ClientData clientData, int flags);
+static void SerialWatchProc(ClientData instanceData, int mask);
+static void ProcExitHandler(ClientData clientData);
+static int SerialGetOptionProc _ANSI_ARGS_((ClientData instanceData,
+ Tcl_Interp *interp, CONST char *optionName,
+ Tcl_DString *dsPtr));
+static int SerialSetOptionProc _ANSI_ARGS_((ClientData instanceData,
+ Tcl_Interp *interp, CONST char *optionName,
+ CONST char *value));
+static DWORD WINAPI SerialWriterThread(LPVOID arg);
+
+static void SerialThreadActionProc _ANSI_ARGS_ ((
+ ClientData instanceData, int action));
/*
* This structure describes the channel type structure for command serial
@@ -200,43 +197,42 @@ static int SerialBlockingWrite(SerialInfo *infoPtr, LPVOID buf,
*/
static Tcl_ChannelType serialChannelType = {
- "serial", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
- SerialCloseProc, /* Close proc. */
- SerialInputProc, /* Input proc. */
- SerialOutputProc, /* Output proc. */
- NULL, /* Seek proc. */
- SerialSetOptionProc, /* Set option proc. */
- SerialGetOptionProc, /* Get option proc. */
- SerialWatchProc, /* Set up notifier to watch the channel. */
- SerialGetHandleProc, /* Get an OS handle from channel. */
- NULL, /* close2proc. */
- SerialBlockProc, /* Set blocking or non-blocking mode.*/
- NULL, /* flush proc. */
- NULL, /* handler proc. */
- NULL, /* wide seek proc */
- SerialThreadActionProc, /* thread action proc */
- NULL, /* truncate */
+ "serial", /* Type name. */
+ TCL_CHANNEL_VERSION_4, /* v4 channel */
+ SerialCloseProc, /* Close proc. */
+ SerialInputProc, /* Input proc. */
+ SerialOutputProc, /* Output proc. */
+ NULL, /* Seek proc. */
+ SerialSetOptionProc, /* Set option proc. */
+ SerialGetOptionProc, /* Get option proc. */
+ SerialWatchProc, /* Set up notifier to watch the channel. */
+ SerialGetHandleProc, /* Get an OS handle from channel. */
+ NULL, /* close2proc. */
+ SerialBlockProc, /* Set blocking or non-blocking mode.*/
+ NULL, /* flush proc. */
+ NULL, /* handler proc. */
+ NULL, /* wide seek proc */
+ SerialThreadActionProc, /* thread action proc */
};
-
+
/*
*----------------------------------------------------------------------
*
* SerialInit --
*
- * This function initializes the static variables for this file.
+ * This function initializes the static variables for this file.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Creates a new event source.
+ * Creates a new event source.
*
*----------------------------------------------------------------------
*/
static ThreadSpecificData *
-SerialInit(void)
+SerialInit()
{
ThreadSpecificData *tsdPtr;
@@ -246,107 +242,104 @@ SerialInit(void)
*/
if (!initialized) {
- Tcl_MutexLock(&serialMutex);
- if (!initialized) {
- initialized = 1;
- Tcl_CreateExitHandler(ProcExitHandler, NULL);
- }
- Tcl_MutexUnlock(&serialMutex);
+ Tcl_MutexLock(&serialMutex);
+ if (!initialized) {
+ initialized = 1;
+ Tcl_CreateExitHandler(ProcExitHandler, NULL);
+ }
+ Tcl_MutexUnlock(&serialMutex);
}
- tsdPtr = (ThreadSpecificData *) TclThreadDataKeyGet(&dataKey);
+ tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (tsdPtr == NULL) {
- tsdPtr = TCL_TSD_INIT(&dataKey);
- tsdPtr->firstSerialPtr = NULL;
- Tcl_CreateEventSource(SerialSetupProc, SerialCheckProc, NULL);
- Tcl_CreateThreadExitHandler(SerialExitHandler, NULL);
+ tsdPtr = TCL_TSD_INIT(&dataKey);
+ tsdPtr->firstSerialPtr = NULL;
+ Tcl_CreateEventSource(SerialSetupProc, SerialCheckProc, NULL);
+ Tcl_CreateThreadExitHandler(SerialExitHandler, NULL);
}
return tsdPtr;
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialExitHandler --
*
- * This function is called to cleanup the serial module before Tcl is
- * unloaded.
+ * This function is called to cleanup the serial module before
+ * Tcl is unloaded.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Removes the serial event source.
+ * Removes the serial event source.
*
*----------------------------------------------------------------------
*/
static void
SerialExitHandler(
- ClientData clientData) /* Old window proc */
+ ClientData clientData) /* Old window proc */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
SerialInfo *infoPtr;
/*
- * Clear all eventually pending output. Otherwise Tcl's exit could totally
- * block, because it performs a blocking flush on all open channels. Note
- * that serial write operations may be blocked due to handshake.
+ * Clear all eventually pending output.
+ * Otherwise Tcl's exit could totally block,
+ * because it performs a blocking flush on all open channels.
+ * Note that serial write operations may be blocked due to handshake.
*/
-
for (infoPtr = tsdPtr->firstSerialPtr; infoPtr != NULL;
- infoPtr = infoPtr->nextPtr) {
- PurgeComm(infoPtr->handle,
- PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+ infoPtr = infoPtr->nextPtr) {
+ PurgeComm(infoPtr->handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR
+ | PURGE_RXCLEAR);
+
}
Tcl_DeleteEventSource(SerialSetupProc, SerialCheckProc, NULL);
}
-
+
/*
*----------------------------------------------------------------------
*
* ProcExitHandler --
*
- * This function is called to cleanup the process list before Tcl is
- * unloaded.
+ * This function is called to cleanup the process list before
+ * Tcl is unloaded.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Resets the process list.
+ * Resets the process list.
*
*----------------------------------------------------------------------
*/
static void
ProcExitHandler(
- ClientData clientData) /* Old window proc */
+ ClientData clientData) /* Old window proc */
{
Tcl_MutexLock(&serialMutex);
initialized = 0;
Tcl_MutexUnlock(&serialMutex);
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialBlockTime --
*
- * Wrapper to set Tcl's block time in msec
+ * Wrapper to set Tcl's block time in msec
*
* Results:
- * None.
- *
- * Side effects:
- * Updates the maximum blocking time.
- *
+ * None.
*----------------------------------------------------------------------
*/
static void
SerialBlockTime(
- int msec) /* milli-seconds */
+ int msec) /* milli-seconds */
{
Tcl_Time blockTime;
@@ -354,25 +347,22 @@ SerialBlockTime(
blockTime.usec = (msec % 1000) * 1000;
Tcl_SetMaxBlockTime(&blockTime);
}
-
/*
*----------------------------------------------------------------------
*
* SerialGetMilliseconds --
*
- * Get current time in milliseconds,ignoring integer overruns.
+ * Get current time in milliseconds,
+ * Don't care about integer overruns
*
* Results:
- * The current time.
- *
- * Side effects:
- * None.
- *
+ * None.
*----------------------------------------------------------------------
*/
static unsigned int
-SerialGetMilliseconds(void)
+SerialGetMilliseconds(
+ void)
{
Tcl_Time time;
@@ -380,83 +370,82 @@ SerialGetMilliseconds(void)
return (time.sec * 1000 + time.usec / 1000);
}
-
/*
*----------------------------------------------------------------------
*
* SerialSetupProc --
*
- * This procedure is invoked before Tcl_DoOneEvent blocks waiting for an
- * event.
+ * This procedure is invoked before Tcl_DoOneEvent blocks waiting
+ * for an event.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Adjusts the block time if needed.
+ * Adjusts the block time if needed.
*
*----------------------------------------------------------------------
*/
void
SerialSetupProc(
- ClientData data, /* Not used. */
- int flags) /* Event flags as passed to Tcl_DoOneEvent. */
+ ClientData data, /* Not used. */
+ int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
SerialInfo *infoPtr;
int block = 1;
- int msec = INT_MAX; /* min. found block time */
+ int msec = INT_MAX; /* min. found block time */
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
- return;
+ return;
}
/*
- * Look to see if any events handlers installed. If they are, do not
- * block.
+ * Look to see if any events handlers installed. If they are, do not block.
*/
- for (infoPtr=tsdPtr->firstSerialPtr ; infoPtr!=NULL ;
- infoPtr=infoPtr->nextPtr) {
- if (infoPtr->watchMask & TCL_WRITABLE) {
- if (WaitForSingleObject(infoPtr->evWritable, 0) != WAIT_TIMEOUT) {
- block = 0;
- msec = min(msec, infoPtr->blockTime);
- }
- }
- if (infoPtr->watchMask & TCL_READABLE) {
- block = 0;
- msec = min(msec, infoPtr->blockTime);
- }
+ for (infoPtr = tsdPtr->firstSerialPtr; infoPtr != NULL;
+ infoPtr = infoPtr->nextPtr) {
+
+ if (infoPtr->watchMask & TCL_WRITABLE) {
+ if (WaitForSingleObject(infoPtr->evWritable, 0) != WAIT_TIMEOUT) {
+ block = 0;
+ msec = min( msec, infoPtr->blockTime );
+ }
+ }
+ if( infoPtr->watchMask & TCL_READABLE ) {
+ block = 0;
+ msec = min( msec, infoPtr->blockTime );
+ }
}
if (!block) {
- SerialBlockTime(msec);
+ SerialBlockTime(msec);
}
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialCheckProc --
*
- * This procedure is called by Tcl_DoOneEvent to check the serial event
- * source for events.
+ * This procedure is called by Tcl_DoOneEvent to check the serial
+ * event source for events.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * May queue an event.
+ * May queue an event.
*
*----------------------------------------------------------------------
*/
static void
SerialCheckProc(
- ClientData data, /* Not used. */
- int flags) /* Event flags as passed to Tcl_DoOneEvent. */
+ ClientData data, /* Not used. */
+ int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
SerialInfo *infoPtr;
SerialEvent *evPtr;
@@ -466,7 +455,7 @@ SerialCheckProc(
unsigned int time;
if (!(flags & TCL_FILE_EVENTS)) {
- return;
+ return;
}
/*
@@ -474,81 +463,81 @@ SerialCheckProc(
* queued.
*/
- for (infoPtr=tsdPtr->firstSerialPtr ; infoPtr!=NULL ;
- infoPtr=infoPtr->nextPtr) {
- if (infoPtr->flags & SERIAL_PENDING) {
- continue;
- }
-
- needEvent = 0;
-
- /*
- * If WRITABLE watch mask is set look for infoPtr->evWritable object.
- */
-
- if (infoPtr->watchMask & TCL_WRITABLE &&
- WaitForSingleObject(infoPtr->evWritable, 0) != WAIT_TIMEOUT) {
- infoPtr->writable = 1;
- needEvent = 1;
- }
-
- /*
- * If READABLE watch mask is set call ClearCommError to poll cbInQue.
- * Window errors are ignored here.
- */
-
- if (infoPtr->watchMask & TCL_READABLE) {
- if (ClearCommError(infoPtr->handle, &infoPtr->error, &cStat)) {
- /*
- * Look for characters already pending in windows queue. If
- * they are, poll.
- */
-
- if (infoPtr->watchMask & TCL_READABLE) {
- /*
- * Force fileevent after serial read error.
- */
-
- if ((cStat.cbInQue > 0) ||
- (infoPtr->error & SERIAL_READ_ERRORS)) {
- infoPtr->readable = 1;
+ for (infoPtr = tsdPtr->firstSerialPtr; infoPtr != NULL;
+ infoPtr = infoPtr->nextPtr) {
+ if (infoPtr->flags & SERIAL_PENDING) {
+ continue;
+ }
+
+ needEvent = 0;
+
+ /*
+ * If WRITABLE watch mask is set
+ * look for infoPtr->evWritable object
+ */
+ if (infoPtr->watchMask & TCL_WRITABLE) {
+ if (WaitForSingleObject(infoPtr->evWritable, 0) != WAIT_TIMEOUT) {
+ infoPtr->writable = 1;
+ needEvent = 1;
+ }
+ }
+
+ /*
+ * If READABLE watch mask is set
+ * call ClearCommError to poll cbInQue
+ * Window errors are ignored here
+ */
+
+ if( infoPtr->watchMask & TCL_READABLE ) {
+ if( ClearCommError( infoPtr->handle, &infoPtr->error, &cStat ) ) {
+ /*
+ * Look for characters already pending in windows queue.
+ * If they are, poll.
+ */
+
+ if( infoPtr->watchMask & TCL_READABLE ) {
+ /*
+ * force fileevent after serial read error
+ */
+ if( (cStat.cbInQue > 0) ||
+ (infoPtr->error & SERIAL_READ_ERRORS) ) {
+ infoPtr->readable = 1;
time = SerialGetMilliseconds();
if ((unsigned int) (time - infoPtr->lastEventTime)
>= (unsigned int) infoPtr->blockTime) {
needEvent = 1;
infoPtr->lastEventTime = time;
}
- }
- }
- }
- }
-
- /*
- * Queue an event if the serial is signaled for reading or writing.
- */
-
- if (needEvent) {
- infoPtr->flags |= SERIAL_PENDING;
- evPtr = (SerialEvent *) ckalloc(sizeof(SerialEvent));
- evPtr->header.proc = SerialEventProc;
- evPtr->infoPtr = infoPtr;
- Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
- }
+ }
+ }
+ }
+ }
+
+ /*
+ * Queue an event if the serial is signaled for reading or writing.
+ */
+ if (needEvent) {
+ infoPtr->flags |= SERIAL_PENDING;
+ evPtr = (SerialEvent *) ckalloc(sizeof(SerialEvent));
+ evPtr->header.proc = SerialEventProc;
+ evPtr->infoPtr = infoPtr;
+ Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
+ }
}
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialBlockProc --
*
- * Set blocking or non-blocking mode on channel.
+ * Set blocking or non-blocking mode on channel.
*
* Results:
- * 0 if successful, errno when failed.
+ * 0 if successful, errno when failed.
*
* Side effects:
- * Sets the device into blocking or non-blocking mode.
+ * Sets the device into blocking or non-blocking mode.
*
*----------------------------------------------------------------------
*/
@@ -556,38 +545,39 @@ SerialCheckProc(
static int
SerialBlockProc(
ClientData instanceData, /* Instance data for channel. */
- int mode) /* TCL_MODE_BLOCKING or
- * TCL_MODE_NONBLOCKING. */
+ int mode) /* TCL_MODE_BLOCKING or
+ * TCL_MODE_NONBLOCKING. */
{
int errorCode = 0;
+
SerialInfo *infoPtr = (SerialInfo *) instanceData;
/*
- * Only serial READ can be switched between blocking & nonblocking using
- * COMMTIMEOUTS. Serial write emulates blocking & nonblocking by the
- * SerialWriterThread.
+ * Only serial READ can be switched between blocking & nonblocking
+ * using COMMTIMEOUTS.
+ * Serial write emulates blocking & nonblocking by the SerialWriterThread.
*/
if (mode == TCL_MODE_NONBLOCKING) {
- infoPtr->flags |= SERIAL_ASYNC;
+ infoPtr->flags |= SERIAL_ASYNC;
} else {
- infoPtr->flags &= ~(SERIAL_ASYNC);
+ infoPtr->flags &= ~(SERIAL_ASYNC);
}
return errorCode;
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialCloseProc --
*
- * Closes a serial based IO channel.
+ * Closes a serial based IO channel.
*
* Results:
- * 0 on success, errno otherwise.
+ * 0 on success, errno otherwise.
*
* Side effects:
- * Closes the physical channel.
+ * Closes the physical channel.
*
*----------------------------------------------------------------------
*/
@@ -595,7 +585,7 @@ SerialBlockProc(
static int
SerialCloseProc(
ClientData instanceData, /* Pointer to SerialInfo structure. */
- Tcl_Interp *interp) /* For error reporting. */
+ Tcl_Interp *interp) /* For error reporting. */
{
SerialInfo *serialPtr = (SerialInfo *) instanceData;
int errorCode, result = 0;
@@ -606,45 +596,48 @@ SerialCloseProc(
errorCode = 0;
if (serialPtr->validMask & TCL_READABLE) {
- PurgeComm(serialPtr->handle, PURGE_RXABORT | PURGE_RXCLEAR);
- CloseHandle(serialPtr->osRead.hEvent);
+ PurgeComm(serialPtr->handle, PURGE_RXABORT | PURGE_RXCLEAR);
+ CloseHandle(serialPtr->osRead.hEvent);
}
serialPtr->validMask &= ~TCL_READABLE;
-
+
if (serialPtr->validMask & TCL_WRITABLE) {
- /*
- * Generally we cannot wait for a pending write operation because it
- * may hang due to handshake
- * WaitForSingleObject(serialPtr->evWritable, INFINITE);
- */
+
+ /*
+ * Generally we cannot wait for a pending write operation
+ * because it may hang due to handshake
+ * WaitForSingleObject(serialPtr->evWritable, INFINITE);
+ */
/*
- * The thread may have already closed on it's own. Check it's exit
- * code.
+ * The thread may have already closed on it's own. Check it's
+ * exit code.
*/
GetExitCodeThread(serialPtr->writeThread, &exitCode);
if (exitCode == STILL_ACTIVE) {
/*
- * Set the stop event so that if the writer thread is blocked in
- * SerialWriterThread on WaitForMultipleEvents, it will exit
- * cleanly.
+ * Set the stop event so that if the writer thread is
+ * blocked in SerialWriterThread on WaitForMultipleEvents, it
+ * will exit cleanly.
*/
SetEvent(serialPtr->evStopWriter);
/*
- * Wait at most 20 milliseconds for the writer thread to close.
+ * Wait at most 20 milliseconds for the writer thread to
+ * close.
*/
- if (WaitForSingleObject(serialPtr->writeThread,
- 20) == WAIT_TIMEOUT) {
+ if (WaitForSingleObject(serialPtr->writeThread, 20)
+ == WAIT_TIMEOUT) {
/*
- * Forcibly terminate the background thread as a last resort.
- * Note that we need to guard against terminating the thread
- * while it is in the middle of Tcl_ThreadAlert because it
- * won't be able to release the notifier lock.
+ * Forcibly terminate the background thread as a last
+ * resort. Note that we need to guard against
+ * terminating the thread while it is in the middle of
+ * Tcl_ThreadAlert because it won't be able to release
+ * the notifier lock.
*/
Tcl_MutexLock(&serialMutex);
@@ -656,33 +649,33 @@ SerialCloseProc(
}
}
- CloseHandle(serialPtr->writeThread);
+ CloseHandle(serialPtr->writeThread);
CloseHandle(serialPtr->osWrite.hEvent);
- CloseHandle(serialPtr->evWritable);
- CloseHandle(serialPtr->evStartWriter);
- CloseHandle(serialPtr->evStopWriter);
- serialPtr->writeThread = NULL;
+ CloseHandle(serialPtr->evWritable);
+ CloseHandle(serialPtr->evStartWriter);
+ CloseHandle(serialPtr->evStopWriter);
+ serialPtr->writeThread = NULL;
- PurgeComm(serialPtr->handle, PURGE_TXABORT | PURGE_TXCLEAR);
+ PurgeComm(serialPtr->handle, PURGE_TXABORT | PURGE_TXCLEAR);
}
serialPtr->validMask &= ~TCL_WRITABLE;
DeleteCriticalSection(&serialPtr->csWrite);
/*
- * Don't close the Win32 handle if the handle is a standard channel during
- * the thread exit process. Otherwise, one thread may kill the stdio of
- * another.
+ * Don't close the Win32 handle if the handle is a standard channel
+ * during the thread exit process. Otherwise, one thread may kill
+ * the stdio of another.
*/
if (!TclInThreadExit()
- || ((GetStdHandle(STD_INPUT_HANDLE) != serialPtr->handle)
- && (GetStdHandle(STD_OUTPUT_HANDLE) != serialPtr->handle)
- && (GetStdHandle(STD_ERROR_HANDLE) != serialPtr->handle))) {
- if (CloseHandle(serialPtr->handle) == FALSE) {
- TclWinConvertError(GetLastError());
- errorCode = errno;
- }
+ || ((GetStdHandle(STD_INPUT_HANDLE) != serialPtr->handle)
+ && (GetStdHandle(STD_OUTPUT_HANDLE) != serialPtr->handle)
+ && (GetStdHandle(STD_ERROR_HANDLE) != serialPtr->handle))) {
+ if (CloseHandle(serialPtr->handle) == FALSE) {
+ TclWinConvertError(GetLastError());
+ errorCode = errno;
+ }
}
serialPtr->watchMask &= serialPtr->validMask;
@@ -691,176 +684,148 @@ SerialCloseProc(
* Remove the file from the list of watched files.
*/
- for (nextPtrPtr=&(tsdPtr->firstSerialPtr), infoPtr=*nextPtrPtr;
- infoPtr!=NULL;
- nextPtrPtr=&infoPtr->nextPtr, infoPtr=*nextPtrPtr) {
- if (infoPtr == (SerialInfo *)serialPtr) {
- *nextPtrPtr = infoPtr->nextPtr;
- break;
- }
+ for (nextPtrPtr = &(tsdPtr->firstSerialPtr), infoPtr = *nextPtrPtr;
+ infoPtr != NULL;
+ nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) {
+ if (infoPtr == (SerialInfo *)serialPtr) {
+ *nextPtrPtr = infoPtr->nextPtr;
+ break;
+ }
}
/*
- * Wrap the error file into a channel and give it to the cleanup routine.
+ * Wrap the error file into a channel and give it to the cleanup
+ * routine.
*/
-
if (serialPtr->writeBuf != NULL) {
- ckfree(serialPtr->writeBuf);
- serialPtr->writeBuf = NULL;
+ ckfree(serialPtr->writeBuf);
+ serialPtr->writeBuf = NULL;
}
ckfree((char*) serialPtr);
if (errorCode == 0) {
- return result;
+ return result;
}
return errorCode;
}
-
+
/*
*----------------------------------------------------------------------
*
- * SerialBlockingRead --
+ * blockingRead --
*
- * Perform a blocking read into the buffer given. Returns count of how
- * many bytes were actually read, and an error indication.
+ * Perform a blocking read into the buffer given. Returns
+ * count of how many bytes were actually read, and an error indication.
*
* Results:
- * A count of how many bytes were read is returned and an error
- * indication is returned.
+ * A count of how many bytes were read is returned and an error
+ * indication is returned.
*
* Side effects:
- * Reads input from the actual channel.
+ * Reads input from the actual channel.
*
*----------------------------------------------------------------------
*/
-
static int
-SerialBlockingRead(
- SerialInfo *infoPtr, /* Serial info structure */
- LPVOID buf, /* The input buffer pointer */
- DWORD bufSize, /* The number of bytes to read */
- LPDWORD lpRead, /* Returns number of bytes read */
- LPOVERLAPPED osPtr) /* OVERLAPPED structure */
+blockingRead(
+ SerialInfo *infoPtr, /* Serial info structure */
+ LPVOID buf, /* The input buffer pointer */
+ DWORD bufSize, /* The number of bytes to read */
+ LPDWORD lpRead, /* Returns number of bytes read */
+ LPOVERLAPPED osPtr ) /* OVERLAPPED structure */
{
/*
- * Perform overlapped blocking read.
+ * Perform overlapped blocking read.
* 1. Reset the overlapped event
* 2. Start overlapped read operation
* 3. Wait for completion
*/
- /*
+ /*
* Set Offset to ZERO, otherwise NT4.0 may report an error.
*/
-
osPtr->Offset = osPtr->OffsetHigh = 0;
ResetEvent(osPtr->hEvent);
- if (!ReadFile(infoPtr->handle, buf, bufSize, lpRead, osPtr)) {
- if (GetLastError() != ERROR_IO_PENDING) {
- /*
- * ReadFile failed, but it isn't delayed. Report error.
- */
-
- return FALSE;
- } else {
- /*
- * Read is pending, wait for completion, timeout?
- */
-
- if (!GetOverlappedResult(infoPtr->handle, osPtr, lpRead, TRUE)) {
- return FALSE;
- }
- }
+ if (! ReadFile(infoPtr->handle, buf, bufSize, lpRead, osPtr) ) {
+ if (GetLastError() != ERROR_IO_PENDING) {
+ /* ReadFile failed, but it isn't delayed. Report error. */
+ return FALSE;
+ } else {
+ /* Read is pending, wait for completion, timeout ? */
+ if (! GetOverlappedResult(infoPtr->handle, osPtr, lpRead, TRUE) ) {
+ return FALSE;
+ }
+ }
} else {
- /*
- * ReadFile completed immediately.
- */
+ /* ReadFile completed immediately. */
}
return TRUE;
}
-
+
/*
*----------------------------------------------------------------------
*
- * SerialBlockingWrite --
+ * blockingWrite --
*
- * Perform a blocking write from the buffer given. Returns count of how
- * many bytes were actually written, and an error indication.
+ * Perform a blocking write from the buffer given. Returns
+ * count of how many bytes were actually written, and an error indication.
*
* Results:
- * A count of how many bytes were written is returned and an error
- * indication is returned.
+ * A count of how many bytes were written is returned and an error
+ * indication is returned.
*
* Side effects:
- * Writes output to the actual channel.
+ * Writes output to the actual channel.
*
*----------------------------------------------------------------------
*/
-
static int
-SerialBlockingWrite(
- SerialInfo *infoPtr, /* Serial info structure */
- LPVOID buf, /* The output buffer pointer */
- DWORD bufSize, /* The number of bytes to write */
- LPDWORD lpWritten, /* Returns number of bytes written */
- LPOVERLAPPED osPtr) /* OVERLAPPED structure */
+blockingWrite(
+ SerialInfo *infoPtr, /* Serial info structure */
+ LPVOID buf, /* The output buffer pointer */
+ DWORD bufSize, /* The number of bytes to write */
+ LPDWORD lpWritten, /* Returns number of bytes written */
+ LPOVERLAPPED osPtr ) /* OVERLAPPED structure */
{
int result;
-
/*
- * Perform overlapped blocking write.
- * 1. Reset the overlapped event
- * 2. Remove these bytes from the output queue counter
- * 3. Start overlapped write operation
- * 3. Remove these bytes from the output queue counter
- * 4. Wait for completion
- * 5. Adjust the output queue counter
- */
-
+ * Perform overlapped blocking write.
+ * 1. Reset the overlapped event
+ * 2. Remove these bytes from the output queue counter
+ * 3. Start overlapped write operation
+ * 3. Remove these bytes from the output queue counter
+ * 4. Wait for completion
+ * 5. Adjust the output queue counter
+ */
ResetEvent(osPtr->hEvent);
EnterCriticalSection(&infoPtr->csWrite);
infoPtr->writeQueue -= bufSize;
-
- /*
- * Set Offset to ZERO, otherwise NT4.0 may report an error
- */
-
- osPtr->Offset = osPtr->OffsetHigh = 0;
+ /*
+ * Set Offset to ZERO, otherwise NT4.0 may report an error
+ */
+ osPtr->Offset = osPtr->OffsetHigh = 0;
result = WriteFile(infoPtr->handle, buf, bufSize, lpWritten, osPtr);
LeaveCriticalSection(&infoPtr->csWrite);
- if (result == FALSE) {
- int err = GetLastError();
-
- switch (err) {
- case ERROR_IO_PENDING:
- /*
- * Write is pending, wait for completion.
- */
-
- if (!GetOverlappedResult(infoPtr->handle, osPtr, lpWritten,
- TRUE)) {
- return FALSE;
- }
- break;
- case ERROR_COUNTER_TIMEOUT:
- /*
- * Write timeout handled in SerialOutputProc.
- */
-
- break;
- default:
- /*
- * WriteFile failed, but it isn't delayed. Report error.
- */
-
- return FALSE;
- }
+ if (result == FALSE ) {
+ int err = GetLastError();
+ switch (err) {
+ case ERROR_IO_PENDING:
+ /* Write is pending, wait for completion */
+ if (! GetOverlappedResult(infoPtr->handle, osPtr, lpWritten, TRUE) ) {
+ return FALSE;
+ }
+ break;
+ case ERROR_COUNTER_TIMEOUT:
+ /* Write timeout handled in SerialOutputProc */
+ break;
+ default:
+ /* WriteFile failed, but it isn't delayed. Report error */
+ return FALSE;
+ }
} else {
- /*
- * WriteFile completed immediately.
- */
+ /* WriteFile completed immediately. */
}
EnterCriticalSection(&infoPtr->csWrite);
@@ -869,32 +834,31 @@ SerialBlockingWrite(
return TRUE;
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialInputProc --
*
- * Reads input from the IO channel into the buffer given. Returns count
- * of how many bytes were actually read, and an error indication.
+ * Reads input from the IO channel into the buffer given. Returns
+ * count of how many bytes were actually read, and an error indication.
*
* Results:
- * A count of how many bytes were read is returned and an error
- * indication is returned in an output argument.
+ * A count of how many bytes were read is returned and an error
+ * indication is returned in an output argument.
*
* Side effects:
- * Reads input from the actual channel.
+ * Reads input from the actual channel.
*
*----------------------------------------------------------------------
*/
-
static int
SerialInputProc(
- ClientData instanceData, /* Serial state. */
- char *buf, /* Where to store data read. */
- int bufSize, /* How much space is available in the
- * buffer? */
- int *errorCode) /* Where to store error code. */
+ ClientData instanceData, /* Serial state. */
+ char *buf, /* Where to store data read. */
+ int bufSize, /* How much space is available
+ * in the buffer? */
+ int *errorCode) /* Where to store error code. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
DWORD bytesRead = 0;
@@ -905,102 +869,104 @@ SerialInputProc(
/*
* Check if there is a CommError pending from SerialCheckProc
*/
-
- if (infoPtr->error & SERIAL_READ_ERRORS) {
- goto commError;
+ if( infoPtr->error & SERIAL_READ_ERRORS ){
+ goto commError;
}
/*
- * Look for characters already pending in windows queue. This is the
- * mainly restored good old code from Tcl8.0
+ * Look for characters already pending in windows queue.
+ * This is the mainly restored good old code from Tcl8.0
*/
- if (ClearCommError(infoPtr->handle, &infoPtr->error, &cStat)) {
- /*
- * Check for errors here, but not in the evSetup/Check procedures.
- */
-
- if (infoPtr->error & SERIAL_READ_ERRORS) {
- goto commError;
- }
- if (infoPtr->flags & SERIAL_ASYNC) {
- /*
- * NON_BLOCKING mode: Avoid blocking by reading more bytes than
- * available in input buffer.
- */
-
- if (cStat.cbInQue > 0) {
- if ((DWORD) bufSize > cStat.cbInQue) {
- bufSize = cStat.cbInQue;
- }
- } else {
- errno = *errorCode = EAGAIN;
- return -1;
- }
- } else {
- /*
- * BLOCKING mode: Tcl trys to read a full buffer of 4 kBytes here.
- */
-
- if (cStat.cbInQue > 0) {
- if ((DWORD) bufSize > cStat.cbInQue) {
- bufSize = cStat.cbInQue;
- }
- } else {
- bufSize = 1;
- }
- }
- }
-
- if (bufSize == 0) {
- return bytesRead = 0;
+ if( ClearCommError( infoPtr->handle, &infoPtr->error, &cStat ) ) {
+ /*
+ * Check for errors here, but not in the evSetup/Check procedures
+ */
+
+ if( infoPtr->error & SERIAL_READ_ERRORS ) {
+ goto commError;
+ }
+ if( infoPtr->flags & SERIAL_ASYNC ) {
+ /*
+ * NON_BLOCKING mode:
+ * Avoid blocking by reading more bytes than available
+ * in input buffer
+ */
+
+ if( cStat.cbInQue > 0 ) {
+ if( (DWORD) bufSize > cStat.cbInQue ) {
+ bufSize = cStat.cbInQue;
+ }
+ } else {
+ errno = *errorCode = EAGAIN;
+ return -1;
+ }
+ } else {
+ /*
+ * BLOCKING mode:
+ * Tcl trys to read a full buffer of 4 kBytes here
+ */
+
+ if( cStat.cbInQue > 0 ) {
+ if( (DWORD) bufSize > cStat.cbInQue ) {
+ bufSize = cStat.cbInQue;
+ }
+ } else {
+ bufSize = 1;
+ }
+ }
+ }
+
+ if( bufSize == 0 ) {
+ return bytesRead = 0;
}
/*
- * Perform blocking read. Doesn't block in non-blocking mode, because we
- * checked the number of available bytes.
- */
-
- if (SerialBlockingRead(infoPtr, (LPVOID) buf, (DWORD) bufSize, &bytesRead,
- &infoPtr->osRead) == FALSE) {
- TclWinConvertError(GetLastError());
- *errorCode = errno;
- return -1;
+ * Perform blocking read. Doesn't block in non-blocking mode,
+ * because we checked the number of available bytes.
+ */
+ if (blockingRead(infoPtr, (LPVOID) buf, (DWORD) bufSize, &bytesRead,
+ &infoPtr->osRead) == FALSE) {
+ goto error;
}
return bytesRead;
- commError:
- infoPtr->lastError = infoPtr->error;
- /* save last error code */
- infoPtr->error = 0; /* reset error code */
- *errorCode = EIO; /* to return read-error only once */
+error:
+ TclWinConvertError(GetLastError());
+ *errorCode = errno;
+ return -1;
+
+commError:
+ infoPtr->lastError = infoPtr->error; /* save last error code */
+ infoPtr->error = 0; /* reset error code */
+ *errorCode = EIO; /* to return read-error only once */
return -1;
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialOutputProc --
*
- * Writes the given output on the IO channel. Returns count of how many
- * characters were actually written, and an error indication.
+ * Writes the given output on the IO channel. Returns count of how
+ * many characters were actually written, and an error indication.
*
* Results:
- * A count of how many characters were written is returned and an error
- * indication is returned in an output argument.
+ * A count of how many characters were written is returned and an
+ * error indication is returned in an output argument.
*
* Side effects:
- * Writes output on the actual channel.
+ * Writes output on the actual channel.
*
*----------------------------------------------------------------------
*/
static int
SerialOutputProc(
- ClientData instanceData, /* Serial state. */
- CONST char *buf, /* The data buffer. */
- int toWrite, /* How many bytes to write? */
- int *errorCode) /* Where to store error code. */
+ ClientData instanceData, /* Serial state. */
+ CONST char *buf, /* The data buffer. */
+ int toWrite, /* How many bytes to write? */
+ int *errorCode) /* Where to store error code. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
DWORD bytesWritten, timeout;
@@ -1008,145 +974,136 @@ SerialOutputProc(
*errorCode = 0;
/*
- * At EXIT Tcl trys to flush all open channels in blocking mode. We avoid
- * blocking output after ExitProc or CloseHandler(chan) has been called by
- * checking the corrresponding variables.
+ * At EXIT Tcl trys to flush all open channels in blocking mode.
+ * We avoid blocking output after ExitProc or CloseHandler(chan)
+ * has been called by checking the corrresponding variables.
*/
-
- if (!initialized || TclInExit()) {
- return toWrite;
+ if( ! initialized || TclInExit() ) {
+ return toWrite;
}
/*
* Check if there is a CommError pending from SerialCheckProc
*/
-
- if (infoPtr->error & SERIAL_WRITE_ERRORS) {
- infoPtr->lastError = infoPtr->error;
- /* save last error code */
- infoPtr->error = 0; /* reset error code */
- errno = EIO;
- goto error;
+ if( infoPtr->error & SERIAL_WRITE_ERRORS ){
+ infoPtr->lastError = infoPtr->error; /* save last error code */
+ infoPtr->error = 0; /* reset error code */
+ errno = EIO;
+ goto error;
}
timeout = (infoPtr->flags & SERIAL_ASYNC) ? 0 : INFINITE;
if (WaitForSingleObject(infoPtr->evWritable, timeout) == WAIT_TIMEOUT) {
- /*
- * The writer thread is blocked waiting for a write to complete and
- * the channel is in non-blocking mode.
- */
+ /*
+ * The writer thread is blocked waiting for a write to complete
+ * and the channel is in non-blocking mode.
+ */
- errno = EWOULDBLOCK;
- goto error1;
+ errno = EWOULDBLOCK;
+ goto error1;
}
-
/*
* Check for a background error on the last write.
*/
if (infoPtr->writeError) {
- TclWinConvertError(infoPtr->writeError);
- infoPtr->writeError = 0;
- goto error1;
+ TclWinConvertError(infoPtr->writeError);
+ infoPtr->writeError = 0;
+ goto error1;
}
/*
* Remember the number of bytes in output queue
*/
-
EnterCriticalSection(&infoPtr->csWrite);
infoPtr->writeQueue += toWrite;
LeaveCriticalSection(&infoPtr->csWrite);
if (infoPtr->flags & SERIAL_ASYNC) {
- /*
- * The serial is non-blocking, so copy the data into the output buffer
- * and restart the writer thread.
- */
-
- if (toWrite > infoPtr->writeBufLen) {
- /*
- * Reallocate the buffer to be large enough to hold the data.
- */
-
- if (infoPtr->writeBuf) {
- ckfree(infoPtr->writeBuf);
- }
- infoPtr->writeBufLen = toWrite;
- infoPtr->writeBuf = ckalloc((unsigned int) toWrite);
- }
- memcpy(infoPtr->writeBuf, buf, (size_t) toWrite);
- infoPtr->toWrite = toWrite;
- ResetEvent(infoPtr->evWritable);
- SetEvent(infoPtr->evStartWriter);
- bytesWritten = (DWORD) toWrite;
+ /*
+ * The serial is non-blocking, so copy the data into the output
+ * buffer and restart the writer thread.
+ */
+
+ if (toWrite > infoPtr->writeBufLen) {
+ /*
+ * Reallocate the buffer to be large enough to hold the data.
+ */
+
+ if (infoPtr->writeBuf) {
+ ckfree(infoPtr->writeBuf);
+ }
+ infoPtr->writeBufLen = toWrite;
+ infoPtr->writeBuf = ckalloc((unsigned int) toWrite);
+ }
+ memcpy(infoPtr->writeBuf, buf, (size_t) toWrite);
+ infoPtr->toWrite = toWrite;
+ ResetEvent(infoPtr->evWritable);
+ SetEvent(infoPtr->evStartWriter);
+ bytesWritten = (DWORD) toWrite;
} else {
- /*
- * In the blocking case, just try to write the buffer directly. This
- * avoids an unnecessary copy.
- */
-
- if (!SerialBlockingWrite(infoPtr, (LPVOID) buf, (DWORD) toWrite,
- &bytesWritten, &infoPtr->osWrite)) {
- goto writeError;
- }
- if (bytesWritten != (DWORD) toWrite) {
- /*
- * Write timeout.
- */
- infoPtr->lastError |= CE_PTO;
- errno = EIO;
- goto error;
- }
+ /*
+ * In the blocking case, just try to write the buffer directly.
+ * This avoids an unnecessary copy.
+ */
+ if (! blockingWrite(infoPtr, (LPVOID) buf, (DWORD) toWrite,
+ &bytesWritten, &infoPtr->osWrite) ) {
+ goto writeError;
+ }
+ if (bytesWritten != (DWORD) toWrite) {
+ /* Write timeout */
+ infoPtr->lastError |= CE_PTO;
+ errno = EIO;
+ goto error;
+ }
}
return (int) bytesWritten;
- writeError:
+writeError:
TclWinConvertError(GetLastError());
- error:
- /*
- * Reset the output queue counter on error during blocking output
- */
-
- /*
- * EnterCriticalSection(&infoPtr->csWrite);
- * infoPtr->writeQueue = 0;
- * LeaveCriticalSection(&infoPtr->csWrite);
+error:
+ /*
+ * Reset the output queue counter on error during blocking output
*/
- error1:
+/*
+ EnterCriticalSection(&infoPtr->csWrite);
+ infoPtr->writeQueue = 0;
+ LeaveCriticalSection(&infoPtr->csWrite);
+*/
+ error1:
*errorCode = errno;
return -1;
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialEventProc --
*
- * This function is invoked by Tcl_ServiceEvent when a file event reaches
- * the front of the event queue. This procedure invokes Tcl_NotifyChannel
- * on the serial.
+ * This function is invoked by Tcl_ServiceEvent when a file event
+ * reaches the front of the event queue. This procedure invokes
+ * Tcl_NotifyChannel on the serial.
*
* Results:
- * Returns 1 if the event was handled, meaning it should be removed from
- * the queue. Returns 0 if the event was not handled, meaning it should
- * stay on the queue. The only time the event isn't handled is if the
- * TCL_FILE_EVENTS flag bit isn't set.
+ * Returns 1 if the event was handled, meaning it should be removed
+ * from the queue. Returns 0 if the event was not handled, meaning
+ * it should stay on the queue. The only time the event isn't
+ * handled is if the TCL_FILE_EVENTS flag bit isn't set.
*
* Side effects:
- * Whatever the notifier callback does.
+ * Whatever the notifier callback does.
*
*----------------------------------------------------------------------
*/
static int
SerialEventProc(
- Tcl_Event *evPtr, /* Event to service. */
- int flags) /* Flags that indicate what events to handle,
- * such as TCL_FILE_EVENTS. */
+ Tcl_Event *evPtr, /* Event to service. */
+ int flags) /* Flags that indicate what events to
+ * handle, such as TCL_FILE_EVENTS. */
{
SerialEvent *serialEvPtr = (SerialEvent *)evPtr;
SerialInfo *infoPtr;
@@ -1154,22 +1111,22 @@ SerialEventProc(
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
- return 0;
+ return 0;
}
/*
* Search through the list of watched serials for the one whose handle
- * matches the event. We do this rather than simply dereferencing the
- * handle in the event so that serials can be deleted while the event is
- * in the queue.
+ * matches the event. We do this rather than simply dereferencing
+ * the handle in the event so that serials can be deleted while the
+ * event is in the queue.
*/
for (infoPtr = tsdPtr->firstSerialPtr; infoPtr != NULL;
- infoPtr = infoPtr->nextPtr) {
- if (serialEvPtr->infoPtr == infoPtr) {
- infoPtr->flags &= ~(SERIAL_PENDING);
- break;
- }
+ infoPtr = infoPtr->nextPtr) {
+ if (serialEvPtr->infoPtr == infoPtr) {
+ infoPtr->flags &= ~(SERIAL_PENDING);
+ break;
+ }
}
/*
@@ -1177,28 +1134,28 @@ SerialEventProc(
*/
if (!infoPtr) {
- return 1;
+ return 1;
}
/*
- * Check to see if the serial is readable. Note that we can't tell if a
- * serial is writable, so we always report it as being writable unless we
- * have detected EOF.
+ * Check to see if the serial is readable. Note
+ * that we can't tell if a serial is writable, so we always report it
+ * as being writable unless we have detected EOF.
*/
mask = 0;
- if (infoPtr->watchMask & TCL_WRITABLE) {
- if (infoPtr->writable) {
- mask |= TCL_WRITABLE;
- infoPtr->writable = 0;
- }
+ if( infoPtr->watchMask & TCL_WRITABLE ) {
+ if( infoPtr->writable ) {
+ mask |= TCL_WRITABLE;
+ infoPtr->writable = 0;
+ }
}
- if (infoPtr->watchMask & TCL_READABLE) {
- if (infoPtr->readable) {
- mask |= TCL_READABLE;
- infoPtr->readable = 0;
- }
+ if( infoPtr->watchMask & TCL_READABLE ) {
+ if( infoPtr->readable ) {
+ mask |= TCL_READABLE;
+ infoPtr->readable = 0;
+ }
}
/*
@@ -1208,29 +1165,30 @@ SerialEventProc(
Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask & mask);
return 1;
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialWatchProc --
*
- * Called by the notifier to set up to watch for events on this channel.
+ * Called by the notifier to set up to watch for events on this
+ * channel.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
static void
SerialWatchProc(
- ClientData instanceData, /* Serial state. */
- int mask) /* What events to watch for, OR-ed combination
- * of TCL_READABLE, TCL_WRITABLE and
- * TCL_EXCEPTION. */
+ ClientData instanceData, /* Serial state. */
+ int mask) /* What events to watch for, OR-ed
+ * combination of TCL_READABLE,
+ * TCL_WRITABLE and TCL_EXCEPTION. */
{
SerialInfo **nextPtrPtr, *ptr;
SerialInfo *infoPtr = (SerialInfo *) instanceData;
@@ -1238,240 +1196,232 @@ SerialWatchProc(
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
- * Since the file is always ready for events, we set the block time so we
- * will poll.
+ * Since the file is always ready for events, we set the block time
+ * so we will poll.
*/
infoPtr->watchMask = mask & infoPtr->validMask;
if (infoPtr->watchMask) {
- if (!oldMask) {
- infoPtr->nextPtr = tsdPtr->firstSerialPtr;
- tsdPtr->firstSerialPtr = infoPtr;
- }
- SerialBlockTime(infoPtr->blockTime);
- } else if (oldMask) {
- /*
- * Remove the serial port from the list of watched serial ports.
- */
-
- for (nextPtrPtr=&(tsdPtr->firstSerialPtr), ptr=*nextPtrPtr; ptr!=NULL;
- nextPtrPtr=&ptr->nextPtr, ptr=*nextPtrPtr) {
- if (infoPtr == ptr) {
- *nextPtrPtr = ptr->nextPtr;
- break;
- }
- }
+ if (!oldMask) {
+ infoPtr->nextPtr = tsdPtr->firstSerialPtr;
+ tsdPtr->firstSerialPtr = infoPtr;
+ }
+ SerialBlockTime(infoPtr->blockTime);
+ } else {
+ if (oldMask) {
+ /*
+ * Remove the serial port from the list of watched serial ports.
+ */
+
+ for (nextPtrPtr = &(tsdPtr->firstSerialPtr), ptr = *nextPtrPtr;
+ ptr != NULL;
+ nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
+ if (infoPtr == ptr) {
+ *nextPtrPtr = ptr->nextPtr;
+ break;
+ }
+ }
+ }
}
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialGetHandleProc --
*
- * Called from Tcl_GetChannelHandle to retrieve OS handles from inside a
- * command serial port based channel.
+ * Called from Tcl_GetChannelHandle to retrieve OS handles from
+ * inside a command serial port based channel.
*
* Results:
- * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if there is no
- * handle for the specified direction.
+ * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
+ * there is no handle for the specified direction.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
static int
SerialGetHandleProc(
- ClientData instanceData, /* The serial state. */
- int direction, /* TCL_READABLE or TCL_WRITABLE */
- ClientData *handlePtr) /* Where to store the handle. */
+ ClientData instanceData, /* The serial state. */
+ int direction, /* TCL_READABLE or TCL_WRITABLE */
+ ClientData *handlePtr) /* Where to store the handle. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
*handlePtr = (ClientData) infoPtr->handle;
return TCL_OK;
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialWriterThread --
*
- * This function runs in a separate thread and writes data onto a serial.
+ * This function runs in a separate thread and writes data
+ * onto a serial.
*
* Results:
- * Always returns 0.
+ * Always returns 0.
*
* Side effects:
- * Signals the main thread when an output operation is completed. May
- * cause the main thread to wake up by posting a message.
+ * Signals the main thread when an output operation is completed.
+ * May cause the main thread to wake up by posting a message.
*
*----------------------------------------------------------------------
*/
static DWORD WINAPI
-SerialWriterThread(
- LPVOID arg)
+SerialWriterThread(LPVOID arg)
{
+
SerialInfo *infoPtr = (SerialInfo *)arg;
DWORD bytesWritten, toWrite, waitResult;
char *buf;
- OVERLAPPED myWrite; /* Have an own OVERLAPPED in this thread. */
+ OVERLAPPED myWrite; /* have an own OVERLAPPED in this thread */
HANDLE wEvents[2];
/*
* The stop event takes precedence by being first in the list.
*/
-
wEvents[0] = infoPtr->evStopWriter;
wEvents[1] = infoPtr->evStartWriter;
for (;;) {
- /*
- * Wait for the main thread to signal before attempting to write.
- */
+ /*
+ * Wait for the main thread to signal before attempting to write.
+ */
waitResult = WaitForMultipleObjects(2, wEvents, FALSE, INFINITE);
if (waitResult != (WAIT_OBJECT_0 + 1)) {
/*
- * The start event was not signaled. It might be the stop event or
- * an error, so exit.
+ * The start event was not signaled. It might be the stop event
+ * or an error, so exit.
*/
break;
}
- buf = infoPtr->writeBuf;
- toWrite = infoPtr->toWrite;
-
- myWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
- /*
- * Loop until all of the bytes are written or an error occurs.
- */
-
- while (toWrite > 0) {
- /*
- * Check for pending writeError. Ignore all write operations until
- * the user has been notified.
- */
-
- if (infoPtr->writeError) {
- break;
- }
- if (SerialBlockingWrite(infoPtr, (LPVOID) buf, (DWORD) toWrite,
- &bytesWritten, &myWrite) == FALSE) {
- infoPtr->writeError = GetLastError();
- break;
- }
- if (bytesWritten != toWrite) {
- /*
- * Write timeout.
- */
-
- infoPtr->writeError = ERROR_WRITE_FAULT;
- break;
- }
- toWrite -= bytesWritten;
- buf += bytesWritten;
- }
-
- CloseHandle(myWrite.hEvent);
-
- /*
- * Signal the main thread by signalling the evWritable event and then
- * waking up the notifier thread.
- */
-
- SetEvent(infoPtr->evWritable);
-
- /*
- * Alert the foreground thread. Note that we need to treat this like a
- * critical section so the foreground thread does not terminate this
- * thread while we are holding a mutex in the notifier code.
- */
-
- Tcl_MutexLock(&serialMutex);
+ buf = infoPtr->writeBuf;
+ toWrite = infoPtr->toWrite;
+
+ myWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ /*
+ * Loop until all of the bytes are written or an error occurs.
+ */
+
+ while (toWrite > 0) {
+ /*
+ * Check for pending writeError
+ * Ignore all write operations until the user has been notified
+ */
+ if (infoPtr->writeError) {
+ break;
+ }
+ if (blockingWrite(infoPtr, (LPVOID) buf, (DWORD) toWrite,
+ &bytesWritten, &myWrite) == FALSE) {
+ infoPtr->writeError = GetLastError();
+ break;
+ }
+ if (bytesWritten != toWrite) {
+ /* Write timeout */
+ infoPtr->writeError = ERROR_WRITE_FAULT;
+ break;
+ }
+ toWrite -= bytesWritten;
+ buf += bytesWritten;
+ }
+
+ CloseHandle(myWrite.hEvent);
+ /*
+ * Signal the main thread by signalling the evWritable event and
+ * then waking up the notifier thread.
+ */
+ SetEvent(infoPtr->evWritable);
+
+ /*
+ * Alert the foreground thread. Note that we need to treat this like
+ * a critical section so the foreground thread does not terminate
+ * this thread while we are holding a mutex in the notifier code.
+ */
+
+ Tcl_MutexLock(&serialMutex);
if (infoPtr->threadId != NULL) {
- /*
- * TIP #218: When in flight ignore the event, no one will receive
- * it anyway.
- */
-
+ /* TIP #218. When in flight ignore the event, no one will receive it anyway */
Tcl_ThreadAlert(infoPtr->threadId);
}
- Tcl_MutexUnlock(&serialMutex);
+ Tcl_MutexUnlock(&serialMutex);
}
return 0;
}
-
+
+
/*
*----------------------------------------------------------------------
*
* TclWinSerialReopen --
*
- * Reopens the serial port with the OVERLAPPED FLAG set
+ * Reopens the serial port with the OVERLAPPED FLAG set
*
* Results:
- * Returns the new handle, or INVALID_HANDLE_VALUE. Normally there
- * shouldn't be any error, because the same channel has previously been
- * succeesfully opened.
+ * Returns the new handle, or INVALID_HANDLE_VALUE
+ * Normally there shouldn't be any error,
+ * because the same channel has previously been succeesfully opened.
*
* Side effects:
- * May close the original handle
+ * May close the original handle
*
*----------------------------------------------------------------------
*/
HANDLE
-TclWinSerialReopen(
- HANDLE handle,
- CONST TCHAR *name,
- DWORD access)
+TclWinSerialReopen(handle, name, access)
+ HANDLE handle;
+ CONST TCHAR *name;
+ DWORD access;
{
SerialInit();
- /*
- * Multithreaded I/O needs the overlapped flag set otherwise
- * ClearCommError blocks under Windows NT/2000 until serial output is
- * finished
- */
-
+ /*
+ * Multithreaded I/O needs the overlapped flag set
+ * otherwise ClearCommError blocks under Windows NT/2000 until serial
+ * output is finished
+ */
if (CloseHandle(handle) == FALSE) {
- return INVALID_HANDLE_VALUE;
+ return INVALID_HANDLE_VALUE;
}
- handle = (*tclWinProcs->createFileProc)(name, access, 0, 0,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+ handle = (*tclWinProcs->createFileProc)(name, access,
+ 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
return handle;
}
-
/*
*----------------------------------------------------------------------
*
* TclWinOpenSerialChannel --
*
- * Constructs a Serial port channel for the specified standard OS handle.
- * This is a helper function to break up the construction of channels
- * into File, Console, or Serial.
+ * Constructs a Serial port channel for the specified standard OS handle.
+ * This is a helper function to break up the construction of
+ * channels into File, Console, or Serial.
*
* Results:
- * Returns the new channel, or NULL.
+ * Returns the new channel, or NULL.
*
* Side effects:
- * May open the channel
+ * May open the channel
*
*----------------------------------------------------------------------
*/
Tcl_Channel
-TclWinOpenSerialChannel(
- HANDLE handle,
- char *channelName,
- int permissions)
+TclWinOpenSerialChannel(handle, channelName, permissions)
+ HANDLE handle;
+ char *channelName;
+ int permissions;
{
SerialInfo *infoPtr;
DWORD id;
@@ -1481,60 +1431,60 @@ TclWinOpenSerialChannel(
infoPtr = (SerialInfo *) ckalloc((unsigned) sizeof(SerialInfo));
memset(infoPtr, 0, sizeof(SerialInfo));
- infoPtr->validMask = permissions;
- infoPtr->handle = handle;
- infoPtr->channel = (Tcl_Channel) NULL;
- infoPtr->readable = 0;
- infoPtr->writable = 1;
- infoPtr->toWrite = infoPtr->writeQueue = 0;
- infoPtr->blockTime = SERIAL_DEFAULT_BLOCKTIME;
+ infoPtr->validMask = permissions;
+ infoPtr->handle = handle;
+ infoPtr->channel = (Tcl_Channel) NULL;
+ infoPtr->readable = 0;
+ infoPtr->writable = 1;
+ infoPtr->toWrite = infoPtr->writeQueue = 0;
+ infoPtr->blockTime = SERIAL_DEFAULT_BLOCKTIME;
infoPtr->lastEventTime = 0;
- infoPtr->lastError = infoPtr->error = 0;
- infoPtr->threadId = Tcl_GetCurrentThread();
- infoPtr->sysBufRead = 4096;
- infoPtr->sysBufWrite = 4096;
+ infoPtr->lastError = infoPtr->error = 0;
+ infoPtr->threadId = Tcl_GetCurrentThread();
+ infoPtr->sysBufRead = 4096;
+ infoPtr->sysBufWrite = 4096;
/*
- * Use the pointer to keep the channel names unique, in case the handles
- * are shared between multiple channels (stdin/stdout).
+ * Use the pointer to keep the channel names unique, in case
+ * the handles are shared between multiple channels (stdin/stdout).
*/
- wsprintfA(channelName, "file%lx", PTR2INT(infoPtr));
+ wsprintfA(channelName, "file%lx", (int) infoPtr);
infoPtr->channel = Tcl_CreateChannel(&serialChannelType, channelName,
- (ClientData) infoPtr, permissions);
+ (ClientData) infoPtr, permissions);
SetupComm(handle, infoPtr->sysBufRead, infoPtr->sysBufWrite);
- PurgeComm(handle,
- PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+ PurgeComm(handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR
+ | PURGE_RXCLEAR);
/*
- * Default is blocking.
+ * default is blocking
*/
-
SetCommTimeouts(handle, &no_timeout);
InitializeCriticalSection(&infoPtr->csWrite);
+
if (permissions & TCL_READABLE) {
- infoPtr->osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ infoPtr->osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
if (permissions & TCL_WRITABLE) {
- /*
- * Initially the channel is writable and the writeThread is idle.
- */
-
- infoPtr->osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- infoPtr->evWritable = CreateEvent(NULL, TRUE, TRUE, NULL);
- infoPtr->evStartWriter = CreateEvent(NULL, FALSE, FALSE, NULL);
+ /*
+ * Initially the channel is writable
+ * and the writeThread is idle.
+ */
+ infoPtr->osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ infoPtr->evWritable = CreateEvent(NULL, TRUE, TRUE, NULL);
+ infoPtr->evStartWriter = CreateEvent(NULL, FALSE, FALSE, NULL);
infoPtr->evStopWriter = CreateEvent(NULL, FALSE, FALSE, NULL);
- infoPtr->writeThread = CreateThread(NULL, 256, SerialWriterThread,
- infoPtr, 0, &id);
+ infoPtr->writeThread = CreateThread(NULL, 256, SerialWriterThread,
+ infoPtr, 0, &id);
}
/*
- * Files have default translation of AUTO and ^Z eof char, which means
- * that a ^Z will be accepted as EOF when reading.
+ * Files have default translation of AUTO and ^Z eof char, which
+ * means that a ^Z will be accepted as EOF when reading.
*/
Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
@@ -1542,77 +1492,61 @@ TclWinOpenSerialChannel(
return infoPtr->channel;
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialErrorStr --
*
- * Converts a Win32 serial error code to a list of readable errors.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Generates readable errors in the supplied DString.
+ * Converts a Win32 serial error code to a list of readable errors
*
*----------------------------------------------------------------------
*/
-
static void
-SerialErrorStr(
- DWORD error, /* Win32 serial error code. */
- Tcl_DString *dsPtr) /* Where to store string. */
+SerialErrorStr(error, dsPtr)
+ DWORD error; /* Win32 serial error code */
+ Tcl_DString *dsPtr; /* Where to store string */
{
- if (error & CE_RXOVER) {
- Tcl_DStringAppendElement(dsPtr, "RXOVER");
+ if( (error & CE_RXOVER) != 0) {
+ Tcl_DStringAppendElement(dsPtr, "RXOVER");
}
- if (error & CE_OVERRUN) {
- Tcl_DStringAppendElement(dsPtr, "OVERRUN");
+ if( (error & CE_OVERRUN) != 0) {
+ Tcl_DStringAppendElement(dsPtr, "OVERRUN");
}
- if (error & CE_RXPARITY) {
- Tcl_DStringAppendElement(dsPtr, "RXPARITY");
+ if( (error & CE_RXPARITY) != 0) {
+ Tcl_DStringAppendElement(dsPtr, "RXPARITY");
}
- if (error & CE_FRAME) {
- Tcl_DStringAppendElement(dsPtr, "FRAME");
+ if( (error & CE_FRAME) != 0) {
+ Tcl_DStringAppendElement(dsPtr, "FRAME");
}
- if (error & CE_BREAK) {
- Tcl_DStringAppendElement(dsPtr, "BREAK");
+ if( (error & CE_BREAK) != 0) {
+ Tcl_DStringAppendElement(dsPtr, "BREAK");
}
- if (error & CE_TXFULL) {
- Tcl_DStringAppendElement(dsPtr, "TXFULL");
+ if( (error & CE_TXFULL) != 0) {
+ Tcl_DStringAppendElement(dsPtr, "TXFULL");
}
- if (error & CE_PTO) { /* PTO used to signal WRITE-TIMEOUT */
- Tcl_DStringAppendElement(dsPtr, "TIMEOUT");
+ if( (error & CE_PTO) != 0) { /* PTO used to signal WRITE-TIMEOUT */
+ Tcl_DStringAppendElement(dsPtr, "TIMEOUT");
}
- if (error & ~((DWORD) (SERIAL_READ_ERRORS | SERIAL_WRITE_ERRORS))) {
- char buf[TCL_INTEGER_SPACE + 1];
-
- wsprintfA(buf, "%d", error);
- Tcl_DStringAppendElement(dsPtr, buf);
+ if( (error & ~((DWORD) (SERIAL_READ_ERRORS | SERIAL_WRITE_ERRORS))) != 0) {
+ char buf[TCL_INTEGER_SPACE + 1];
+ wsprintfA(buf, "%d", error);
+ Tcl_DStringAppendElement(dsPtr, buf);
}
}
-
/*
*----------------------------------------------------------------------
*
* SerialModemStatusStr --
*
- * Converts a Win32 modem status list of readable flags
- *
- * Result:
- * None.
- *
- * Side effects:
- * Appends modem status flag strings to the given DString.
+ * Converts a Win32 modem status list of readable flags
*
*----------------------------------------------------------------------
*/
-
static void
-SerialModemStatusStr(
- DWORD status, /* Win32 modem status. */
- Tcl_DString *dsPtr) /* Where to store string. */
+SerialModemStatusStr(status, dsPtr)
+ DWORD status; /* Win32 modem status */
+ Tcl_DString *dsPtr; /* Where to store string */
{
Tcl_DStringAppendElement(dsPtr, "CTS");
Tcl_DStringAppendElement(dsPtr, (status & MS_CTS_ON) ? "1" : "0");
@@ -1623,30 +1557,29 @@ SerialModemStatusStr(
Tcl_DStringAppendElement(dsPtr, "DCD");
Tcl_DStringAppendElement(dsPtr, (status & MS_RLSD_ON) ? "1" : "0");
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialSetOptionProc --
*
- * Sets an option on a channel.
+ * Sets an option on a channel.
*
* Results:
- * A standard Tcl result. Also sets the interp's result on error if
- * interp is not NULL.
+ * A standard Tcl result. Also sets the interp's result on error if
+ * interp is not NULL.
*
* Side effects:
- * May modify an option on a device.
+ * May modify an option on a device.
*
*----------------------------------------------------------------------
*/
-
static int
-SerialSetOptionProc(
- ClientData instanceData, /* File state. */
- Tcl_Interp *interp, /* For error reporting - can be NULL. */
- CONST char *optionName, /* Which option to set? */
- CONST char *value) /* New value for option. */
+SerialSetOptionProc(instanceData, interp, optionName, value)
+ ClientData instanceData; /* File state. */
+ Tcl_Interp *interp; /* For error reporting - can be NULL. */
+ CONST char *optionName; /* Which option to set? */
+ CONST char *value; /* New value for option. */
{
SerialInfo *infoPtr;
DCB dcb;
@@ -1660,21 +1593,19 @@ SerialSetOptionProc(
infoPtr = (SerialInfo *) instanceData;
/*
- * Parse options. This would be far easier if we had Tcl_Objs to work with
- * as that would let us use Tcl_GetIndexFromObj()...
+ * Parse options
*/
-
len = strlen(optionName);
vlen = strlen(value);
/*
* Option -mode baud,parity,databits,stopbits
*/
-
if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) {
- if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't get comm state", NULL);
+ if (! GetCommState(infoPtr->handle, &dcb)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't get comm state", (char *) NULL);
}
return TCL_ERROR;
}
@@ -1683,25 +1614,24 @@ SerialSetOptionProc(
Tcl_DStringFree(&ds);
if (result == FALSE) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value \"", value,
- "\" for -mode: should be baud,parity,data,stop", NULL);
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "bad value for -mode: should be baud,parity,data,stop",
+ (char *) NULL);
}
return TCL_ERROR;
}
- /*
- * Default settings for serial communications.
- */
-
+ /* Default settings for serial communications */
dcb.fBinary = TRUE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fAbortOnError = FALSE;
- if (!SetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't set comm state", NULL);
+ if (! SetCommState(infoPtr->handle, &dcb) ) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't set comm state", (char *) NULL);
}
return TCL_ERROR;
}
@@ -1711,19 +1641,18 @@ SerialSetOptionProc(
/*
* Option -handshake none|xonxoff|rtscts|dtrdsr
*/
-
if ((len > 1) && (strncmp(optionName, "-handshake", len) == 0)) {
- if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't get comm state", NULL);
+ if (! GetCommState(infoPtr->handle, &dcb)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't get comm state", (char *) NULL);
}
return TCL_ERROR;
}
-
/*
- * Reset all handshake options. DTR and RTS are ON by default.
+ * Reset all handshake options
+ * DTR and RTS are ON by default
*/
-
dcb.fOutX = dcb.fInX = FALSE;
dcb.fOutxCtsFlow = dcb.fOutxDsrFlow = dcb.fDsrSensitivity = FALSE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
@@ -1731,37 +1660,35 @@ SerialSetOptionProc(
dcb.fTXContinueOnXoff = FALSE;
/*
- * Adjust the handshake limits. Yes, the XonXoff limits seem to
- * influence even hardware handshake.
+ * Adjust the handshake limits.
+ * Yes, the XonXoff limits seem to influence even hardware handshake
*/
-
dcb.XonLim = (WORD) (infoPtr->sysBufRead*1/2);
dcb.XoffLim = (WORD) (infoPtr->sysBufRead*1/4);
- if (strncasecmp(value, "NONE", vlen) == 0) {
- /*
- * Leave all handshake options disabled.
- */
- } else if (strncasecmp(value, "XONXOFF", vlen) == 0) {
+ if (strnicmp(value, "NONE", vlen) == 0) {
+ /* leave all handshake options disabled */
+ } else if (strnicmp(value, "XONXOFF", vlen) == 0) {
dcb.fOutX = dcb.fInX = TRUE;
- } else if (strncasecmp(value, "RTSCTS", vlen) == 0) {
+ } else if (strnicmp(value, "RTSCTS", vlen) == 0) {
dcb.fOutxCtsFlow = TRUE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
- } else if (strncasecmp(value, "DTRDSR", vlen) == 0) {
+ } else if (strnicmp(value, "DTRDSR", vlen) == 0) {
dcb.fOutxDsrFlow = TRUE;
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
} else {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value \"", value,
- "\" for -handshake: must be one of xonxoff, rtscts, "
- "dtrdsr or none", NULL);
+ if (interp) {
+ Tcl_AppendResult(interp, "bad value for -handshake: ",
+ "must be one of xonxoff, rtscts, dtrdsr or none",
+ (char *) NULL);
+ return TCL_ERROR;
}
- return TCL_ERROR;
}
- if (!SetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't set comm state", NULL);
+ if (! SetCommState(infoPtr->handle, &dcb)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't set comm state", (char *) NULL);
}
return TCL_ERROR;
}
@@ -1771,11 +1698,11 @@ SerialSetOptionProc(
/*
* Option -xchar {\x11 \x13}
*/
-
if ((len > 1) && (strncmp(optionName, "-xchar", len) == 0)) {
- if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't get comm state", NULL);
+ if (! GetCommState(infoPtr->handle, &dcb)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't get comm state", (char *) NULL);
}
return TCL_ERROR;
}
@@ -1783,49 +1710,24 @@ SerialSetOptionProc(
if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {
return TCL_ERROR;
}
- if (argc != 2) {
- badXchar:
- if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value for -xchar: should be "
- "a list of two elements with each a single character",
- NULL);
+ if (argc == 2) {
+ dcb.XonChar = argv[0][0];
+ dcb.XoffChar = argv[1][0];
+ ckfree((char *) argv);
+ } else {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "bad value for -xchar: should be a list of two elements",
+ (char *) NULL);
}
ckfree((char *) argv);
return TCL_ERROR;
}
- /*
- * These dereferences are safe, even in the zero-length string cases,
- * because that just makes the xon/xoff character into NUL. When the
- * character looks like it is UTF-8 encoded, decode it before casting
- * into the format required for the Win guts. Note that this does not
- * convert character sets; it is expected that when people set the
- * control characters to something large and custom, they'll know the
- * hex/octal value rather than the printable form.
- */
-
- dcb.XonChar = argv[0][0];
- dcb.XoffChar = argv[1][0];
- if (argv[0][0] & 0x80 || argv[1][0] & 0x80) {
- Tcl_UniChar character;
- int charLen;
-
- charLen = Tcl_UtfToUniChar(argv[0], &character);
- if (argv[0][charLen]) {
- goto badXchar;
- }
- dcb.XonChar = (char) character;
- charLen = Tcl_UtfToUniChar(argv[1], &character);
- if (argv[1][charLen]) {
- goto badXchar;
- }
- dcb.XoffChar = (char) character;
- }
- ckfree((char *) argv);
-
- if (!SetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't set comm state", NULL);
+ if (! SetCommState(infoPtr->handle, &dcb)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't set comm state", (char *) NULL);
}
return TCL_ERROR;
}
@@ -1835,7 +1737,6 @@ SerialSetOptionProc(
/*
* Option -ttycontrol {DTR 1 RTS 0 BREAK 0}
*/
-
if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) {
int i, result = TCL_OK;
@@ -1843,52 +1744,53 @@ SerialSetOptionProc(
return TCL_ERROR;
}
if ((argc % 2) == 1) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value \"", value,
- "\" for -ttycontrol: should be a list of "
- "signal,value pairs", NULL);
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "bad value for -ttycontrol: should be a list of signal,value pairs",
+ (char *) NULL);
}
ckfree((char *) argv);
return TCL_ERROR;
}
-
for (i = 0; i < argc - 1; i += 2) {
if (Tcl_GetBoolean(interp, argv[i+1], &flag) == TCL_ERROR) {
result = TCL_ERROR;
break;
}
- if (strncasecmp(argv[i], "DTR", strlen(argv[i])) == 0) {
- if (!EscapeCommFunction(infoPtr->handle,
- (DWORD) (flag ? SETDTR : CLRDTR))) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't set DTR signal", NULL);
+ if (strnicmp(argv[i], "DTR", strlen(argv[i])) == 0) {
+ if (!EscapeCommFunction(infoPtr->handle, flag ?
+ (DWORD) SETDTR : (DWORD) CLRDTR)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't set DTR signal", (char *) NULL);
}
result = TCL_ERROR;
break;
}
- } else if (strncasecmp(argv[i], "RTS", strlen(argv[i])) == 0) {
- if (!EscapeCommFunction(infoPtr->handle,
- (DWORD) (flag ? SETRTS : CLRRTS))) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't set RTS signal", NULL);
+ } else if (strnicmp(argv[i], "RTS", strlen(argv[i])) == 0) {
+ if (!EscapeCommFunction(infoPtr->handle, flag ?
+ (DWORD) SETRTS : (DWORD) CLRRTS)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't set RTS signal", (char *) NULL);
}
result = TCL_ERROR;
break;
}
- } else if (strncasecmp(argv[i], "BREAK", strlen(argv[i])) == 0) {
- if (!EscapeCommFunction(infoPtr->handle,
- (DWORD) (flag ? SETBREAK : CLRBREAK))) {
- if (interp != NULL) {
- Tcl_AppendResult(interp,"can't set BREAK signal",NULL);
+ } else if (strnicmp(argv[i], "BREAK", strlen(argv[i])) == 0) {
+ if (!EscapeCommFunction(infoPtr->handle, flag ?
+ (DWORD) SETBREAK : (DWORD) CLRBREAK)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't set BREAK signal", (char *) NULL);
}
result = TCL_ERROR;
break;
}
} else {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "bad signal name \"", argv[i],
- "\" for -ttycontrol: must be DTR, RTS or BREAK",
- NULL);
+ if (interp) {
+ Tcl_AppendResult(interp, "bad signal for -ttycontrol: ",
+ "must be DTR, RTS or BREAK", (char *) NULL);
}
result = TCL_ERROR;
break;
@@ -1901,14 +1803,12 @@ SerialSetOptionProc(
/*
* Option -sysbuffer {read_size write_size}
- * Option -sysbuffer read_size
+ * Option -sysbuffer read_size
*/
-
if ((len > 1) && (strncmp(optionName, "-sysbuffer", len) == 0)) {
/*
* -sysbuffer 4096 or -sysbuffer {64536 4096}
*/
-
size_t inSize = (size_t) -1, outSize = (size_t) -1;
if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {
@@ -1922,19 +1822,18 @@ SerialSetOptionProc(
outSize = atoi(argv[1]);
}
ckfree((char *) argv);
-
- if ((argc < 1) || (argc > 2) || (inSize <= 0) || (outSize <= 0)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value \"", value,
- "\" for -sysbuffer: should be a list of one or two "
- "integers > 0", NULL);
+ if ((inSize <= 0) || (outSize <= 0)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "bad value for -sysbuffer: should be a list of one or two integers > 0",
+ (char *) NULL);
}
return TCL_ERROR;
}
-
- if (!SetupComm(infoPtr->handle, inSize, outSize)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't setup comm buffers", NULL);
+ if (! SetupComm(infoPtr->handle, inSize, outSize)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't setup comm buffers", (char *) NULL);
}
return TCL_ERROR;
}
@@ -1942,21 +1841,22 @@ SerialSetOptionProc(
infoPtr->sysBufWrite = outSize;
/*
- * Adjust the handshake limits. Yes, the XonXoff limits seem to
- * influence even hardware handshake.
+ * Adjust the handshake limits.
+ * Yes, the XonXoff limits seem to influence even hardware handshake
*/
-
- if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't get comm state", NULL);
+ if (! GetCommState(infoPtr->handle, &dcb)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't get comm state", (char *) NULL);
}
return TCL_ERROR;
}
dcb.XonLim = (WORD) (infoPtr->sysBufRead*1/2);
dcb.XoffLim = (WORD) (infoPtr->sysBufRead*1/4);
- if (!SetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't set comm state", NULL);
+ if (! SetCommState(infoPtr->handle, &dcb)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't set comm state", (char *) NULL);
}
return TCL_ERROR;
}
@@ -1966,9 +1866,9 @@ SerialSetOptionProc(
/*
* Option -pollinterval msec
*/
-
if ((len > 1) && (strncmp(optionName, "-pollinterval", len) == 0)) {
- if (Tcl_GetInt(interp, value, &(infoPtr->blockTime)) != TCL_OK) {
+
+ if ( Tcl_GetInt(interp, value, &(infoPtr->blockTime)) != TCL_OK ) {
return TCL_ERROR;
}
return TCL_OK;
@@ -1977,18 +1877,18 @@ SerialSetOptionProc(
/*
* Option -timeout msec
*/
-
if ((len > 2) && (strncmp(optionName, "-timeout", len) == 0)) {
int msec;
COMMTIMEOUTS tout = {0,0,0,0,0};
- if (Tcl_GetInt(interp, value, &msec) != TCL_OK) {
+ if ( Tcl_GetInt(interp, value, &msec) != TCL_OK ) {
return TCL_ERROR;
}
tout.ReadTotalTimeoutConstant = msec;
- if (!SetCommTimeouts(infoPtr->handle, &tout)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't set comm timeouts", NULL);
+ if (! SetCommTimeouts(infoPtr->handle, &tout)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't set comm timeouts", (char *) NULL);
}
return TCL_ERROR;
}
@@ -1999,39 +1899,38 @@ SerialSetOptionProc(
return Tcl_BadChannelOption(interp, optionName,
"mode handshake pollinterval sysbuffer timeout ttycontrol xchar");
}
-
+
/*
*----------------------------------------------------------------------
*
* SerialGetOptionProc --
*
- * Gets a mode associated with an IO channel. If the optionName arg is
- * non NULL, retrieves the value of that option. If the optionName arg is
- * NULL, retrieves a list of alternating option names and values for the
- * given channel.
+ * Gets a mode associated with an IO channel. If the optionName arg
+ * is non NULL, retrieves the value of that option. If the optionName
+ * arg is NULL, retrieves a list of alternating option names and
+ * values for the given channel.
*
* Results:
- * A standard Tcl result. Also sets the supplied DString to the string
- * value of the option(s) returned.
+ * A standard Tcl result. Also sets the supplied DString to the
+ * string value of the option(s) returned.
*
* Side effects:
- * The string returned by this function is in static storage and may be
- * reused at any time subsequent to the call.
+ * The string returned by this function is in static storage and
+ * may be reused at any time subsequent to the call.
*
*----------------------------------------------------------------------
*/
-
static int
-SerialGetOptionProc(
- ClientData instanceData, /* File state. */
- Tcl_Interp *interp, /* For error reporting - can be NULL. */
- CONST char *optionName, /* Option to get. */
- Tcl_DString *dsPtr) /* Where to store value(s). */
+SerialGetOptionProc(instanceData, interp, optionName, dsPtr)
+ ClientData instanceData; /* File state. */
+ Tcl_Interp *interp; /* For error reporting - can be NULL. */
+ CONST char *optionName; /* Option to get. */
+ Tcl_DString *dsPtr; /* Where to store value(s). */
{
SerialInfo *infoPtr;
DCB dcb;
size_t len;
- int valid = 0; /* Flag if valid option parsed. */
+ int valid = 0; /* flag if valid option parsed */
infoPtr = (SerialInfo *) instanceData;
@@ -2042,20 +1941,23 @@ SerialGetOptionProc(
}
/*
- * Get option -mode
+ * get option -mode
*/
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-mode");
}
- if (len==0 || (len>2 && (strncmp(optionName, "-mode", len) == 0))) {
+ if ((len == 0) ||
+ ((len > 2) && (strncmp(optionName, "-mode", len) == 0))) {
+
char parity;
char *stop;
char buf[2 * TCL_INTEGER_SPACE + 16];
- if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't get comm state", NULL);
+ if (! GetCommState(infoPtr->handle, &dcb)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't get comm state", (char *) NULL);
}
return TCL_ERROR;
}
@@ -2066,7 +1968,7 @@ SerialGetOptionProc(
parity = "noems"[dcb.Parity];
}
stop = (dcb.StopBits == ONESTOPBIT) ? "1" :
- (dcb.StopBits == ONE5STOPBITS) ? "1.5" : "2";
+ (dcb.StopBits == ONE5STOPBITS) ? "1.5" : "2";
wsprintfA(buf, "%d,%c,%d,%s", dcb.BaudRate, parity,
dcb.ByteSize, stop);
@@ -2074,13 +1976,14 @@ SerialGetOptionProc(
}
/*
- * Get option -pollinterval
+ * get option -pollinterval
*/
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-pollinterval");
}
- if (len==0 || (len>1 && strncmp(optionName, "-pollinterval", len)==0)) {
+ if ((len == 0) ||
+ ((len > 1) && (strncmp(optionName, "-pollinterval", len) == 0))) {
char buf[TCL_INTEGER_SPACE + 1];
valid = 1;
@@ -2089,14 +1992,16 @@ SerialGetOptionProc(
}
/*
- * Get option -sysbuffer
+ * get option -sysbuffer
*/
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-sysbuffer");
Tcl_DStringStartSublist(dsPtr);
}
- if (len==0 || (len>1 && strncmp(optionName, "-sysbuffer", len) == 0)) {
+ if ((len == 0) ||
+ ((len > 1) && (strncmp(optionName, "-sysbuffer", len) == 0))) {
+
char buf[TCL_INTEGER_SPACE + 1];
valid = 1;
@@ -2110,20 +2015,23 @@ SerialGetOptionProc(
}
/*
- * Get option -xchar
+ * get option -xchar
*/
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-xchar");
Tcl_DStringStartSublist(dsPtr);
}
- if (len==0 || (len>1 && strncmp(optionName, "-xchar", len) == 0)) {
+ if ((len == 0) ||
+ ((len > 1) && (strncmp(optionName, "-xchar", len) == 0))) {
+
char buf[4];
valid = 1;
- if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't get comm state", NULL);
+ if (! GetCommState(infoPtr->handle, &dcb)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't get comm state", (char *) NULL);
}
return TCL_ERROR;
}
@@ -2137,24 +2045,22 @@ SerialGetOptionProc(
}
/*
- * Get option -lasterror
- *
- * Option is readonly and returned by [fconfigure chan -lasterror] but not
- * returned by unnamed [fconfigure chan].
+ * get option -lasterror
+ * option is readonly and returned by [fconfigure chan -lasterror]
+ * but not returned by unnamed [fconfigure chan]
*/
- if (len>1 && strncmp(optionName, "-lasterror", len)==0) {
+ if ( (len > 1) && (strncmp(optionName, "-lasterror", len) == 0) ) {
valid = 1;
SerialErrorStr(infoPtr->lastError, dsPtr);
}
/*
* get option -queue
- *
- * Option is readonly and returned by [fconfigure chan -queue].
+ * option is readonly and returned by [fconfigure chan -queue]
*/
- if (len>1 && strncmp(optionName, "-queue", len)==0) {
+ if ((len > 1) && (strncmp(optionName, "-queue", len) == 0)) {
char buf[TCL_INTEGER_SPACE + 1];
COMSTAT cStat;
DWORD error;
@@ -2162,10 +2068,9 @@ SerialGetOptionProc(
valid = 1;
- /*
- * Query the pending data in Tcl's internal queues.
+ /*
+ * Query the pending data in Tcl's internal queues
*/
-
inBuffered = Tcl_InputBuffered(infoPtr->channel);
outBuffered = Tcl_OutputBuffered(infoPtr->channel);
@@ -2175,31 +2080,30 @@ SerialGetOptionProc(
* 2. The bytes in the system drivers buffer
* The writer thread should not interfere this action.
*/
-
EnterCriticalSection(&infoPtr->csWrite);
- ClearCommError(infoPtr->handle, &error, &cStat);
- count = (int) cStat.cbOutQue + infoPtr->writeQueue;
+ ClearCommError( infoPtr->handle, &error, &cStat );
+ count = (int)cStat.cbOutQue + infoPtr->writeQueue;
LeaveCriticalSection(&infoPtr->csWrite);
- wsprintfA(buf, "%d", inBuffered + cStat.cbInQue);
+ wsprintfA(buf, "%d", inBuffered + cStat.cbInQue);
Tcl_DStringAppendElement(dsPtr, buf);
- wsprintfA(buf, "%d", outBuffered + count);
+ wsprintfA(buf, "%d", outBuffered + count);
Tcl_DStringAppendElement(dsPtr, buf);
}
/*
* get option -ttystatus
- *
- * Option is readonly and returned by [fconfigure chan -ttystatus] but not
- * returned by unnamed [fconfigure chan].
+ * option is readonly and returned by [fconfigure chan -ttystatus]
+ * but not returned by unnamed [fconfigure chan]
*/
+ if ((len > 4) && (strncmp(optionName, "-ttystatus", len) == 0)) {
- if (len>4 && strncmp(optionName, "-ttystatus", len)==0) {
DWORD status;
- if (!GetCommModemStatus(infoPtr->handle, &status)) {
- if (interp != NULL) {
- Tcl_AppendResult(interp, "can't get tty status", NULL);
+ if (! GetCommModemStatus(infoPtr->handle, &status)) {
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "can't get tty status", (char *) NULL);
}
return TCL_ERROR;
}
@@ -2232,43 +2136,33 @@ SerialGetOptionProc(
*/
static void
-SerialThreadActionProc(
- ClientData instanceData,
- int action)
+SerialThreadActionProc (instanceData, action)
+ ClientData instanceData;
+ int action;
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
- /*
- * We do not access firstSerialPtr in the thread structures. This is not
- * for all serials managed by the thread, but only those we are watching.
- * Removal of the filevent handlers before transfer thus takes care of
- * this structure.
+ /* We do not access firstSerialPtr in the thread structures. This is
+ * not for all serials managed by the thread, but only those we are
+ * watching. Removal of the filevent handlers before transfer thus
+ * takes care of this structure.
*/
Tcl_MutexLock(&serialMutex);
if (action == TCL_CHANNEL_THREAD_INSERT) {
- /*
- * We can't copy the thread information from the channel when the
- * channel is created. At this time the channel back pointer has not
- * been set yet. However in that case the threadId has already been
- * set by TclpCreateCommandChannel itself, so the structure is still
- * good.
+ /* We can't copy the thread information from the channel when
+ * the channel is created. At this time the channel back
+ * pointer has not been set yet. However in that case the
+ * threadId has already been set by TclpCreateCommandChannel
+ * itself, so the structure is still good.
*/
- SerialInit();
- if (infoPtr->channel != NULL) {
- infoPtr->threadId = Tcl_GetChannelThread(infoPtr->channel);
+ SerialInit ();
+ if (infoPtr->channel != NULL) {
+ infoPtr->threadId = Tcl_GetChannelThread (infoPtr->channel);
}
} else {
infoPtr->threadId = NULL;
}
Tcl_MutexUnlock(&serialMutex);
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index 1bf4f97..f3fe979 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -1,12 +1,12 @@
-/*
+/*
* tclWinSock.c --
*
* This file contains Windows-specific socket related code.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* -----------------------------------------------------------------------
*
@@ -47,22 +47,10 @@
#include "tclWinInt.h"
-#ifdef _MSC_VER
-# pragma comment (lib, "ws2_32")
-#endif
-
-/*
- * Support for control over sockets' KEEPALIVE and NODELAY behavior is
- * currently disabled.
- */
-
-#undef TCL_FEATURE_KEEPALIVE_NAGLE
-
/*
- * Make sure to remove the redirection defines set in tclWinPort.h that is in
- * use in other sections of the core, except for us.
+ * Make sure to remove the redirection defines set in tclWinPort.h
+ * that is in use in other sections of the core, except for us.
*/
-
#undef getservbyname
#undef getsockopt
#undef ntohs
@@ -70,21 +58,114 @@
/*
* The following variable is used to tell whether this module has been
- * initialized. If 1, initialization of sockets was successful, if -1 then
- * socket initialization failed (WSAStartup failed).
+ * initialized.
*/
static int initialized = 0;
+
+static int hostnameInitialized = 0;
+static char hostname[255]; /* This buffer should be big enough for
+ * hostname plus domain name. */
+
TCL_DECLARE_MUTEX(socketMutex)
+
/*
- * The following variable holds the network name of this host.
+ * Mingw and Cygwin may not have LPFN_* typedefs.
*/
-static TclInitProcessGlobalValueProc InitializeHostName;
-static ProcessGlobalValue hostName = {
- 0, 0, NULL, NULL, InitializeHostName, NULL, NULL
-};
+#ifdef HAVE_NO_LPFN_DECLS
+ typedef SOCKET (PASCAL FAR *LPFN_ACCEPT)(SOCKET s,
+ struct sockaddr FAR * addr, int FAR * addrlen);
+ typedef int (PASCAL FAR *LPFN_BIND)(SOCKET s,
+ const struct sockaddr FAR *addr, int namelen);
+ typedef int (PASCAL FAR *LPFN_CLOSESOCKET)(SOCKET s);
+ typedef int (PASCAL FAR *LPFN_CONNECT)(SOCKET s,
+ const struct sockaddr FAR *name, int namelen);
+ typedef struct hostent FAR * (PASCAL FAR *LPFN_GETHOSTBYADDR)
+ (const char FAR *addr, int addrlen, int addrtype);
+ typedef struct hostent FAR * (PASCAL FAR *LPFN_GETHOSTBYNAME)
+ (const char FAR * name);
+ typedef int (PASCAL FAR *LPFN_GETHOSTNAME)(char FAR * name,
+ int namelen);
+ typedef int (PASCAL FAR *LPFN_GETPEERNAME)(SOCKET sock,
+ struct sockaddr FAR *name, int FAR *namelen);
+ typedef struct servent FAR * (PASCAL FAR *LPFN_GETSERVBYNAME)
+ (const char FAR * name, const char FAR * proto);
+ typedef int (PASCAL FAR *LPFN_GETSOCKNAME)(SOCKET sock,
+ struct sockaddr FAR *name, int FAR *namelen);
+ typedef int (PASCAL FAR *LPFN_GETSOCKOPT)(SOCKET s, int level,
+ int optname, char FAR * optval, int FAR *optlen);
+ typedef u_short (PASCAL FAR *LPFN_HTONS)(u_short hostshort);
+ typedef unsigned long (PASCAL FAR *LPFN_INET_ADDR)
+ (const char FAR * cp);
+ typedef char FAR * (PASCAL FAR *LPFN_INET_NTOA)
+ (struct in_addr in);
+ typedef int (PASCAL FAR *LPFN_IOCTLSOCKET)(SOCKET s,
+ long cmd, u_long FAR *argp);
+ typedef int (PASCAL FAR *LPFN_LISTEN)(SOCKET s, int backlog);
+ typedef u_short (PASCAL FAR *LPFN_NTOHS)(u_short netshort);
+ typedef int (PASCAL FAR *LPFN_RECV)(SOCKET s, char FAR * buf,
+ int len, int flags);
+ typedef int (PASCAL FAR *LPFN_SELECT)(int nfds,
+ fd_set FAR * readfds, fd_set FAR * writefds,
+ fd_set FAR * exceptfds,
+ const struct timeval FAR * timeout);
+ typedef int (PASCAL FAR *LPFN_SEND)(SOCKET s,
+ const char FAR * buf, int len, int flags);
+ typedef int (PASCAL FAR *LPFN_SETSOCKOPT)(SOCKET s,
+ int level, int optname, const char FAR * optval,
+ int optlen);
+ typedef SOCKET (PASCAL FAR *LPFN_SOCKET)(int af,
+ int type, int protocol);
+ typedef int (PASCAL FAR *LPFN_WSAASYNCSELECT)(SOCKET s,
+ HWND hWnd, u_int wMsg, long lEvent);
+ typedef int (PASCAL FAR *LPFN_WSACLEANUP)(void);
+ typedef int (PASCAL FAR *LPFN_WSAGETLASTERROR)(void);
+ typedef int (PASCAL FAR *LPFN_WSASTARTUP)(WORD wVersionRequired,
+ LPWSADATA lpWSAData);
+#endif
+
+
+/*
+ * The following structure contains pointers to all of the WinSock API
+ * entry points used by Tcl. It is initialized by InitSockets. Since
+ * we dynamically load the Winsock DLL on demand, we must use this
+ * function table to refer to functions in the winsock API.
+ */
+
+static struct {
+ HMODULE hModule; /* Handle to WinSock library. */
+
+ /* Winsock 1.1 functions */
+ LPFN_ACCEPT accept;
+ LPFN_BIND bind;
+ LPFN_CLOSESOCKET closesocket;
+ LPFN_CONNECT connect;
+ LPFN_GETHOSTBYADDR gethostbyaddr;
+ LPFN_GETHOSTBYNAME gethostbyname;
+ LPFN_GETHOSTNAME gethostname;
+ LPFN_GETPEERNAME getpeername;
+ LPFN_GETSERVBYNAME getservbyname;
+ LPFN_GETSOCKNAME getsockname;
+ LPFN_GETSOCKOPT getsockopt;
+ LPFN_HTONS htons;
+ LPFN_INET_ADDR inet_addr;
+ LPFN_INET_NTOA inet_ntoa;
+ LPFN_IOCTLSOCKET ioctlsocket;
+ LPFN_LISTEN listen;
+ LPFN_NTOHS ntohs;
+ LPFN_RECV recv;
+ LPFN_SELECT select;
+ LPFN_SEND send;
+ LPFN_SETSOCKOPT setsockopt;
+ LPFN_SOCKET socket;
+ LPFN_WSAASYNCSELECT WSAAsyncSelect;
+ LPFN_WSACLEANUP WSACleanup;
+ LPFN_WSAGETLASTERROR WSAGetLastError;
+ LPFN_WSASTARTUP WSAStartup;
+
+} winSock;
/*
* The following defines declare the messages used on socket windows.
@@ -97,48 +178,52 @@ static ProcessGlobalValue hostName = {
#define UNSELECT FALSE
/*
- * The following structure is used to store the data associated with each
- * socket.
+ * The following structure is used to store the data associated with
+ * each socket.
*/
typedef struct SocketInfo {
- Tcl_Channel channel; /* Channel associated with this socket. */
- SOCKET socket; /* Windows SOCKET handle. */
- int flags; /* Bit field comprised of the flags described
- * below. */
- int watchEvents; /* OR'ed combination of FD_READ, FD_WRITE,
- * FD_CLOSE, FD_ACCEPT and FD_CONNECT that
- * indicate which events are interesting. */
- int readyEvents; /* OR'ed combination of FD_READ, FD_WRITE,
- * FD_CLOSE, FD_ACCEPT and FD_CONNECT that
- * indicate which events have occurred. */
- int selectEvents; /* OR'ed combination of FD_READ, FD_WRITE,
- * FD_CLOSE, FD_ACCEPT and FD_CONNECT that
- * indicate which events are currently being
- * selected. */
- int acceptEventCount; /* Count of the current number of FD_ACCEPTs
- * that have arrived and not yet processed. */
- Tcl_TcpAcceptProc *acceptProc;
- /* Proc to call on accept. */
- ClientData acceptProcData; /* The data for the accept proc. */
- int lastError; /* Error code from last message. */
- struct SocketInfo *nextPtr; /* The next socket on the per-thread socket
- * list. */
+ Tcl_Channel channel; /* Channel associated with this
+ * socket. */
+ SOCKET socket; /* Windows SOCKET handle. */
+ int flags; /* Bit field comprised of the flags
+ * described below. */
+ int watchEvents; /* OR'ed combination of FD_READ,
+ * FD_WRITE, FD_CLOSE, FD_ACCEPT and
+ * FD_CONNECT that indicate which
+ * events are interesting. */
+ int readyEvents; /* OR'ed combination of FD_READ,
+ * FD_WRITE, FD_CLOSE, FD_ACCEPT and
+ * FD_CONNECT that indicate which
+ * events have occurred. */
+ int selectEvents; /* OR'ed combination of FD_READ,
+ * FD_WRITE, FD_CLOSE, FD_ACCEPT and
+ * FD_CONNECT that indicate which
+ * events are currently being
+ * selected. */
+ int acceptEventCount; /* Count of the current number of
+ * FD_ACCEPTs that have arrived and
+ * not yet processed. */
+ Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */
+ ClientData acceptProcData; /* The data for the accept proc. */
+ int lastError; /* Error code from last message. */
+ struct SocketInfo *nextPtr; /* The next socket on the per-thread
+ * socket list. */
} SocketInfo;
/*
- * The following structure is what is added to the Tcl event queue when a
- * socket event occurs.
+ * The following structure is what is added to the Tcl event queue when
+ * a socket event occurs.
*/
typedef struct SocketEvent {
- Tcl_Event header; /* Information that is standard for all
- * events. */
- SOCKET socket; /* Socket descriptor that is ready. Used to
- * find the SocketInfo structure for the file
- * (can't point directly to the SocketInfo
- * structure because it could go away while
- * the event is queued). */
+ Tcl_Event header; /* Information that is standard for
+ * all events. */
+ SOCKET socket; /* Socket descriptor that is ready. Used
+ * to find the SocketInfo structure for
+ * the file (can't point directly to the
+ * SocketInfo structure because it could
+ * go away while the event is queued). */
} SocketEvent;
/*
@@ -148,28 +233,30 @@ typedef struct SocketEvent {
#define TCP_BUFFER_SIZE 4096
/*
- * The following macros may be used to set the flags field of a SocketInfo
- * structure.
+ * The following macros may be used to set the flags field of
+ * a SocketInfo structure.
*/
-#define SOCKET_ASYNC (1<<0) /* The socket is in blocking mode. */
-#define SOCKET_EOF (1<<1) /* A zero read happened on the
- * socket. */
-#define SOCKET_ASYNC_CONNECT (1<<2) /* This socket uses async connect. */
-#define SOCKET_PENDING (1<<3) /* A message has been sent for this
- * socket */
+#define SOCKET_ASYNC (1<<0) /* The socket is in blocking
+ * mode. */
+#define SOCKET_EOF (1<<1) /* A zero read happened on
+ * the socket. */
+#define SOCKET_ASYNC_CONNECT (1<<2) /* This socket uses async
+ * connect. */
+#define SOCKET_PENDING (1<<3) /* A message has been sent
+ * for this socket */
typedef struct ThreadSpecificData {
- HWND hwnd; /* Handle to window for socket messages. */
- HANDLE socketThread; /* Thread handling the window */
- Tcl_ThreadId threadId; /* Parent thread. */
- HANDLE readyEvent; /* Event indicating that a socket event is
- * ready. Also used to indicate that the
- * socketThread has been initialized and has
- * started. */
- HANDLE socketListLock; /* Win32 Event to lock the socketList */
- SocketInfo *socketList; /* Every open socket in this thread has an
- * entry on this list. */
+ HWND hwnd; /* Handle to window for socket messages. */
+ HANDLE socketThread; /* Thread handling the window */
+ Tcl_ThreadId threadId; /* Parent thread. */
+ HANDLE readyEvent; /* Event indicating that a socket event is
+ * ready. Also used to indicate that the
+ * socketThread has been initialized and has
+ * started. */
+ HANDLE socketListLock; /* Win32 Event to lock the socketList */
+ SocketInfo *socketList; /* Every open socket in this thread has an
+ * entry on this list. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -179,27 +266,25 @@ static WNDCLASS windowClass;
* Static functions defined in this file.
*/
-static SocketInfo * CreateSocket(Tcl_Interp *interp, int port,
- const char *host, int server, const char *myaddr,
- int myport, int async);
-static int CreateSocketAddress(LPSOCKADDR_IN sockaddrPtr,
- const char *host, int port);
-static void InitSockets(void);
-static SocketInfo * NewSocketInfo(SOCKET socket);
-static void SocketExitHandler(ClientData clientData);
-static LRESULT CALLBACK SocketProc(HWND hwnd, UINT message, WPARAM wParam,
- LPARAM lParam);
-static int SocketsEnabled(void);
-static void TcpAccept(SocketInfo *infoPtr);
-static int WaitForSocketEvent(SocketInfo *infoPtr, int events,
- int *errorCodePtr);
-static DWORD WINAPI SocketThread(LPVOID arg);
-static void TcpThreadActionProc(ClientData instanceData,
- int action);
-
-static Tcl_EventCheckProc SocketCheckProc;
-static Tcl_EventProc SocketEventProc;
-static Tcl_EventSetupProc SocketSetupProc;
+static SocketInfo * CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,
+ int port, CONST char *host,
+ int server, CONST char *myaddr,
+ int myport, int async));
+static int CreateSocketAddress _ANSI_ARGS_(
+ (LPSOCKADDR_IN sockaddrPtr,
+ CONST char *host, int port));
+static void InitSockets _ANSI_ARGS_((void));
+static SocketInfo * NewSocketInfo _ANSI_ARGS_((SOCKET socket));
+static Tcl_EventCheckProc SocketCheckProc;
+static Tcl_EventProc SocketEventProc;
+static void SocketExitHandler _ANSI_ARGS_((
+ ClientData clientData));
+static LRESULT CALLBACK SocketProc _ANSI_ARGS_((HWND hwnd,
+ UINT message, WPARAM wParam,
+ LPARAM lParam));
+static Tcl_EventSetupProc SocketSetupProc;
+static int SocketsEnabled _ANSI_ARGS_((void));
+static void TcpAccept _ANSI_ARGS_((SocketInfo *infoPtr));
static Tcl_DriverBlockModeProc TcpBlockProc;
static Tcl_DriverCloseProc TcpCloseProc;
static Tcl_DriverSetOptionProc TcpSetOptionProc;
@@ -208,6 +293,14 @@ static Tcl_DriverInputProc TcpInputProc;
static Tcl_DriverOutputProc TcpOutputProc;
static Tcl_DriverWatchProc TcpWatchProc;
static Tcl_DriverGetHandleProc TcpGetHandleProc;
+static int WaitForSocketEvent _ANSI_ARGS_((
+ SocketInfo *infoPtr, int events,
+ int *errorCodePtr));
+static DWORD WINAPI SocketThread _ANSI_ARGS_((LPVOID arg));
+
+static void TcpThreadActionProc _ANSI_ARGS_ ((
+ ClientData instanceData, int action));
+
/*
* This structure describes the channel type structure for TCP socket
@@ -216,7 +309,7 @@ static Tcl_DriverGetHandleProc TcpGetHandleProc;
static Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
+ TCL_CHANNEL_VERSION_4, /* v4 channel */
TcpCloseProc, /* Close proc. */
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
@@ -229,17 +322,18 @@ static Tcl_ChannelType tcpChannelType = {
TcpBlockProc, /* Set socket into (non-)blocking mode. */
NULL, /* flush proc. */
NULL, /* handler proc. */
- NULL, /* wide seek proc */
+ NULL, /* wide seek proc */
TcpThreadActionProc, /* thread action proc */
- NULL, /* truncate */
};
+
/*
*----------------------------------------------------------------------
*
* InitSockets --
*
- * Initialize the socket module. If winsock startup is successful,
+ * Initialize the socket module. Attempts to load the wsock32.dll
+ * library and set up the winSock function table. If successful,
* registers the event window for the socket notifier code.
*
* Assumes socketMutex is held.
@@ -248,32 +342,132 @@ static Tcl_ChannelType tcpChannelType = {
* None.
*
* Side effects:
- * Initializes winsock, registers a new window class and creates a
- * window for use in asynchronous socket notification.
+ * Dynamically loads wsock32.dll, and registers a new window
+ * class and creates a window for use in asynchronous socket
+ * notification.
*
*----------------------------------------------------------------------
*/
static void
-InitSockets(void)
+InitSockets()
{
DWORD id;
WSADATA wsaData;
DWORD err;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr =
+ (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (!initialized) {
initialized = 1;
TclCreateLateExitHandler(SocketExitHandler, (ClientData) NULL);
+ winSock.hModule = LoadLibraryA("wsock32.dll");
+
+ if (winSock.hModule == NULL) {
+ return;
+ }
+
/*
- * Create the async notification window with a new class. We must
- * create a new class to avoid a Windows 95 bug that causes us to get
- * the wrong message number for socket events if the message window is
- * a subclass of a static control.
+ * Initialize the function table.
*/
+ winSock.accept = (LPFN_ACCEPT)
+ GetProcAddress(winSock.hModule, "accept");
+ winSock.bind = (LPFN_BIND)
+ GetProcAddress(winSock.hModule, "bind");
+ winSock.closesocket = (LPFN_CLOSESOCKET)
+ GetProcAddress(winSock.hModule, "closesocket");
+ winSock.connect = (LPFN_CONNECT)
+ GetProcAddress(winSock.hModule, "connect");
+ winSock.gethostbyaddr = (LPFN_GETHOSTBYADDR)
+ GetProcAddress(winSock.hModule, "gethostbyaddr");
+ winSock.gethostbyname = (LPFN_GETHOSTBYNAME)
+ GetProcAddress(winSock.hModule, "gethostbyname");
+ winSock.gethostname = (LPFN_GETHOSTNAME)
+ GetProcAddress(winSock.hModule, "gethostname");
+ winSock.getpeername = (LPFN_GETPEERNAME)
+ GetProcAddress(winSock.hModule, "getpeername");
+ winSock.getservbyname = (LPFN_GETSERVBYNAME)
+ GetProcAddress(winSock.hModule, "getservbyname");
+ winSock.getsockname = (LPFN_GETSOCKNAME)
+ GetProcAddress(winSock.hModule, "getsockname");
+ winSock.getsockopt = (LPFN_GETSOCKOPT)
+ GetProcAddress(winSock.hModule, "getsockopt");
+ winSock.htons = (LPFN_HTONS)
+ GetProcAddress(winSock.hModule, "htons");
+ winSock.inet_addr = (LPFN_INET_ADDR)
+ GetProcAddress(winSock.hModule, "inet_addr");
+ winSock.inet_ntoa = (LPFN_INET_NTOA)
+ GetProcAddress(winSock.hModule, "inet_ntoa");
+ winSock.ioctlsocket = (LPFN_IOCTLSOCKET)
+ GetProcAddress(winSock.hModule, "ioctlsocket");
+ winSock.listen = (LPFN_LISTEN)
+ GetProcAddress(winSock.hModule, "listen");
+ winSock.ntohs = (LPFN_NTOHS)
+ GetProcAddress(winSock.hModule, "ntohs");
+ winSock.recv = (LPFN_RECV)
+ GetProcAddress(winSock.hModule, "recv");
+ winSock.select = (LPFN_SELECT)
+ GetProcAddress(winSock.hModule, "select");
+ winSock.send = (LPFN_SEND)
+ GetProcAddress(winSock.hModule, "send");
+ winSock.setsockopt = (LPFN_SETSOCKOPT)
+ GetProcAddress(winSock.hModule, "setsockopt");
+ winSock.socket = (LPFN_SOCKET)
+ GetProcAddress(winSock.hModule, "socket");
+ winSock.WSAAsyncSelect = (LPFN_WSAASYNCSELECT)
+ GetProcAddress(winSock.hModule, "WSAAsyncSelect");
+ winSock.WSACleanup = (LPFN_WSACLEANUP)
+ GetProcAddress(winSock.hModule, "WSACleanup");
+ winSock.WSAGetLastError = (LPFN_WSAGETLASTERROR)
+ GetProcAddress(winSock.hModule, "WSAGetLastError");
+ winSock.WSAStartup = (LPFN_WSASTARTUP)
+ GetProcAddress(winSock.hModule, "WSAStartup");
+
+ /*
+ * Now check that all fields are properly initialized. If not,
+ * return zero to indicate that we failed to initialize
+ * properly.
+ */
+
+ if ((winSock.accept == NULL) ||
+ (winSock.bind == NULL) ||
+ (winSock.closesocket == NULL) ||
+ (winSock.connect == NULL) ||
+ (winSock.gethostbyname == NULL) ||
+ (winSock.gethostbyaddr == NULL) ||
+ (winSock.gethostname == NULL) ||
+ (winSock.getpeername == NULL) ||
+ (winSock.getservbyname == NULL) ||
+ (winSock.getsockname == NULL) ||
+ (winSock.getsockopt == NULL) ||
+ (winSock.htons == NULL) ||
+ (winSock.inet_addr == NULL) ||
+ (winSock.inet_ntoa == NULL) ||
+ (winSock.ioctlsocket == NULL) ||
+ (winSock.listen == NULL) ||
+ (winSock.ntohs == NULL) ||
+ (winSock.recv == NULL) ||
+ (winSock.select == NULL) ||
+ (winSock.send == NULL) ||
+ (winSock.setsockopt == NULL) ||
+ (winSock.socket == NULL) ||
+ (winSock.WSAAsyncSelect == NULL) ||
+ (winSock.WSACleanup == NULL) ||
+ (winSock.WSAGetLastError == NULL) ||
+ (winSock.WSAStartup == NULL))
+ {
+ goto unloadLibrary;
+ }
+
+ /*
+ * Create the async notification window with a new class. We
+ * must create a new class to avoid a Windows 95 bug that causes
+ * us to get the wrong message number for socket events if the
+ * message window is a subclass of a static control.
+ */
+
windowClass.style = 0;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
@@ -287,36 +481,35 @@ InitSockets(void)
if (!RegisterClassA(&windowClass)) {
TclWinConvertError(GetLastError());
- goto initFailure;
+ goto unloadLibrary;
}
/*
- * Initialize the winsock library and check the interface version
- * actually loaded. We only ask for the 1.1 interface and do require
- * that it not be less than 1.1.
+ * Initialize the winsock library and check the interface
+ * version actually loaded. We only ask for the 1.1 interface
+ * and do require that it not be less than 1.1.
*/
-#define WSA_VERSION_MAJOR 1
-#define WSA_VERSION_MINOR 1
-#define WSA_VERSION_REQD MAKEWORD(WSA_VERSION_MAJOR, WSA_VERSION_MINOR)
+#define WSA_VERSION_MAJOR 1
+#define WSA_VERSION_MINOR 1
+#define WSA_VERSION_REQD MAKEWORD(WSA_VERSION_MAJOR, WSA_VERSION_MINOR)
- err = WSAStartup((WORD)WSA_VERSION_REQD, &wsaData);
- if (err != 0) {
+ if ((err = winSock.WSAStartup(WSA_VERSION_REQD, &wsaData)) != 0) {
TclWinConvertWSAError(err);
- goto initFailure;
+ goto unloadLibrary;
}
/*
- * Note the byte positions are swapped for the comparison, so that
- * 0x0002 (2.0, MAKEWORD(2,0)) doesn't look less than 0x0101 (1.1).
- * We want the comparison to be 0x0200 < 0x0101.
+ * Note the byte positions are swapped for the comparison, so
+ * that 0x0002 (2.0, MAKEWORD(2,0)) doesn't look less than 0x0101
+ * (1.1). We want the comparison to be 0x0200 < 0x0101.
*/
if (MAKEWORD(HIBYTE(wsaData.wVersion), LOBYTE(wsaData.wVersion))
< MAKEWORD(WSA_VERSION_MINOR, WSA_VERSION_MAJOR)) {
TclWinConvertWSAError(WSAVERNOTSUPPORTED);
- WSACleanup();
- goto initFailure;
+ winSock.WSACleanup();
+ goto unloadLibrary;
}
#undef WSA_VERSION_REQD
@@ -335,38 +528,39 @@ InitSockets(void)
tsdPtr->threadId = Tcl_GetCurrentThread();
tsdPtr->readyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (tsdPtr->readyEvent == NULL) {
- goto initFailure;
+ goto unloadLibrary;
}
tsdPtr->socketListLock = CreateEvent(NULL, FALSE, TRUE, NULL);
if (tsdPtr->socketListLock == NULL) {
- goto initFailure;
+ goto unloadLibrary;
}
- tsdPtr->socketThread = CreateThread(NULL, 256, SocketThread, tsdPtr,
- 0, &id);
+ tsdPtr->socketThread = CreateThread(NULL, 256, SocketThread,
+ tsdPtr, 0, &id);
if (tsdPtr->socketThread == NULL) {
- goto initFailure;
+ goto unloadLibrary;
}
SetThreadPriority(tsdPtr->socketThread, THREAD_PRIORITY_HIGHEST);
/*
- * Wait for the thread to signal when the window has been created and
- * if it is ready to go.
+ * Wait for the thread to signal when the window has
+ * been created and if it is ready to go.
*/
WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
if (tsdPtr->hwnd == NULL) {
- goto initFailure; /* Trouble creating the window */
+ goto unloadLibrary; /* Trouble creating the window */
}
Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);
}
return;
- initFailure:
+unloadLibrary:
TclpFinalizeSockets();
- initialized = -1;
+ FreeLibrary(winSock.hModule);
+ winSock.hModule = NULL;
return;
}
@@ -375,7 +569,7 @@ InitSockets(void)
*
* SocketsEnabled --
*
- * Check that the WinSock was successfully initialized.
+ * Check that the WinSock DLL is loaded and ready.
*
* Results:
* 1 if it is.
@@ -388,11 +582,11 @@ InitSockets(void)
/* ARGSUSED */
static int
-SocketsEnabled(void)
+SocketsEnabled()
{
int enabled;
Tcl_MutexLock(&socketMutex);
- enabled = (initialized == 1);
+ enabled = (winSock.hModule != NULL);
Tcl_MutexUnlock(&socketMutex);
return enabled;
}
@@ -403,7 +597,7 @@ SocketsEnabled(void)
*
* SocketExitHandler --
*
- * Callback invoked during exit clean up to delete the socket
+ * Callback invoked during app exit clean up to delete the socket
* communication window and to release the WinSock DLL.
*
* Results:
@@ -417,19 +611,23 @@ SocketsEnabled(void)
/* ARGSUSED */
static void
-SocketExitHandler(
- ClientData clientData) /* Not used. */
+SocketExitHandler(clientData)
+ ClientData clientData; /* Not used. */
{
Tcl_MutexLock(&socketMutex);
- /*
- * Make sure the socket event handling window is cleaned-up for, at
- * most, this thread.
- */
-
- TclpFinalizeSockets();
- UnregisterClass("TclSocket", TclWinGetTclInstance());
- WSACleanup();
+ if (winSock.hModule) {
+ /*
+ * Make sure the socket event handling window is cleaned-up
+ * for, at most, this thread.
+ */
+ TclpFinalizeSockets();
+ UnregisterClass("TclSocket", TclWinGetTclInstance());
+ winSock.WSACleanup();
+ FreeLibrary(winSock.hModule);
+ winSock.hModule = NULL;
+ }
initialized = 0;
+ hostnameInitialized = 0;
Tcl_MutexUnlock(&socketMutex);
}
@@ -438,10 +636,10 @@ SocketExitHandler(
*
* TclpFinalizeSockets --
*
- * This function is called from Tcl_FinalizeThread to finalize the
- * platform specific socket subsystem. Also, it may be called from within
- * this module to cleanup the state if unable to initialize the sockets
- * subsystem.
+ * This function is called from Tcl_FinalizeThread to finalize
+ * the platform specific socket subsystem.
+ * Also, it may be called from within this module to cleanup
+ * the state if unable to initialize the sockets subsystem.
*
* Results:
* None.
@@ -453,21 +651,19 @@ SocketExitHandler(
*/
void
-TclpFinalizeSockets(void)
+TclpFinalizeSockets()
{
ThreadSpecificData *tsdPtr;
- tsdPtr = (ThreadSpecificData *) TclThreadDataKeyGet(&dataKey);
+ tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
if (tsdPtr != NULL) {
if (tsdPtr->socketThread != NULL) {
if (tsdPtr->hwnd != NULL) {
PostMessage(tsdPtr->hwnd, SOCKET_TERMINATE, 0, 0);
-
/*
* Wait for the thread to exit. This ensures that we are
* completely cleaned up before we leave this function.
*/
-
WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
tsdPtr->hwnd = NULL;
}
@@ -491,27 +687,25 @@ TclpFinalizeSockets(void)
*
* TclpHasSockets --
*
- * This function determines whether sockets are available on the current
- * system and returns an error in interp if they are not. Note that
- * interp may be NULL.
+ * This function determines whether sockets are available on the
+ * current system and returns an error in interp if they are not.
+ * Note that interp may be NULL.
*
* Results:
- * Returns TCL_OK if the system supports sockets, or TCL_ERROR with an
- * error in interp (if non-NULL).
+ * Returns TCL_OK if the system supports sockets, or TCL_ERROR with
+ * an error in interp.
*
* Side effects:
- * If not already prepared, initializes the TSD structure and socket
- * message handling thread associated to the calling thread for the
- * subsystem of the driver.
+ * If not already prepared, initializes the TSD structure and
+ * socket message handling thread associated to the calling thread
+ * for the subsystem of the driver.
*
*----------------------------------------------------------------------
*/
int
-TclpHasSockets(
- Tcl_Interp *interp) /* Where to write an error message if sockets
- * are not present, or NULL if no such message
- * is to be written. */
+TclpHasSockets(interp)
+ Tcl_Interp *interp;
{
Tcl_MutexLock(&socketMutex);
InitSockets();
@@ -532,8 +726,8 @@ TclpHasSockets(
*
* SocketSetupProc --
*
- * This function is invoked before Tcl_DoOneEvent blocks waiting for an
- * event.
+ * This procedure is invoked before Tcl_DoOneEvent blocks waiting
+ * for an event.
*
* Results:
* None.
@@ -545,9 +739,9 @@ TclpHasSockets(
*/
void
-SocketSetupProc(
- ClientData data, /* Not used. */
- int flags) /* Event flags as passed to Tcl_DoOneEvent. */
+SocketSetupProc(data, flags)
+ ClientData data; /* Not used. */
+ int flags; /* Event flags as passed to Tcl_DoOneEvent. */
{
SocketInfo *infoPtr;
Tcl_Time blockTime = { 0, 0 };
@@ -556,13 +750,13 @@ SocketSetupProc(
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
-
+
/*
- * Check to see if there is a ready socket. If so, poll.
+ * Check to see if there is a ready socket. If so, poll.
*/
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
- for (infoPtr = tsdPtr->socketList; infoPtr != NULL;
+ for (infoPtr = tsdPtr->socketList; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr->readyEvents & infoPtr->watchEvents) {
Tcl_SetMaxBlockTime(&blockTime);
@@ -577,8 +771,8 @@ SocketSetupProc(
*
* SocketCheckProc --
*
- * This function is called by Tcl_DoOneEvent to check the socket event
- * source for events.
+ * This procedure is called by Tcl_DoOneEvent to check the socket
+ * event source for events.
*
* Results:
* None.
@@ -590,9 +784,9 @@ SocketSetupProc(
*/
static void
-SocketCheckProc(
- ClientData data, /* Not used. */
- int flags) /* Event flags as passed to Tcl_DoOneEvent. */
+SocketCheckProc(data, flags)
+ ClientData data; /* Not used. */
+ int flags; /* Event flags as passed to Tcl_DoOneEvent. */
{
SocketInfo *infoPtr;
SocketEvent *evPtr;
@@ -601,7 +795,7 @@ SocketCheckProc(
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
-
+
/*
* Queue events for any ready sockets that don't already have events
* queued (caused by persistent states that won't generate WinSock
@@ -609,7 +803,7 @@ SocketCheckProc(
*/
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
- for (infoPtr = tsdPtr->socketList; infoPtr != NULL;
+ for (infoPtr = tsdPtr->socketList; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if ((infoPtr->readyEvents & infoPtr->watchEvents)
&& !(infoPtr->flags & SOCKET_PENDING)) {
@@ -628,27 +822,27 @@ SocketCheckProc(
*
* SocketEventProc --
*
- * This function is called by Tcl_ServiceEvent when a socket event
- * reaches the front of the event queue. This function is responsible for
- * notifying the generic channel code.
+ * This procedure is called by Tcl_ServiceEvent when a socket event
+ * reaches the front of the event queue. This procedure is
+ * responsible for notifying the generic channel code.
*
* Results:
- * Returns 1 if the event was handled, meaning it should be removed from
- * the queue. Returns 0 if the event was not handled, meaning it should
- * stay on the queue. The only time the event isn't handled is if the
- * TCL_FILE_EVENTS flag bit isn't set.
+ * Returns 1 if the event was handled, meaning it should be removed
+ * from the queue. Returns 0 if the event was not handled, meaning
+ * it should stay on the queue. The only time the event isn't
+ * handled is if the TCL_FILE_EVENTS flag bit isn't set.
*
* Side effects:
- * Whatever the channel callback functions do.
+ * Whatever the channel callback procedures do.
*
*----------------------------------------------------------------------
*/
static int
-SocketEventProc(
- Tcl_Event *evPtr, /* Event to service. */
- int flags) /* Flags that indicate what events to handle,
- * such as TCL_FILE_EVENTS. */
+SocketEventProc(evPtr, flags)
+ Tcl_Event *evPtr; /* Event to service. */
+ int flags; /* Flags that indicate what events to
+ * handle, such as TCL_FILE_EVENTS. */
{
SocketInfo *infoPtr;
SocketEvent *eventPtr = (SocketEvent *) evPtr;
@@ -665,7 +859,7 @@ SocketEventProc(
*/
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
- for (infoPtr = tsdPtr->socketList; infoPtr != NULL;
+ for (infoPtr = tsdPtr->socketList; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr->socket == eventPtr->socket) {
break;
@@ -693,21 +887,21 @@ SocketEventProc(
}
/*
- * Mask off unwanted events and compute the read/write mask so we can
- * notify the channel.
+ * Mask off unwanted events and compute the read/write mask so
+ * we can notify the channel.
*/
events = infoPtr->readyEvents & infoPtr->watchEvents;
if (events & FD_CLOSE) {
/*
- * If the socket was closed and the channel is still interested in
- * read events, then we need to ensure that we keep polling for this
- * event until someone does something with the channel. Note that we
- * do this before calling Tcl_NotifyChannel so we don't have to watch
- * out for the channel being deleted out from under us. This may cause
- * a redundant trip through the event loop, but it's simpler than
- * trying to do unwind protection.
+ * If the socket was closed and the channel is still interested
+ * in read events, then we need to ensure that we keep polling
+ * for this event until someone does something with the channel.
+ * Note that we do this before calling Tcl_NotifyChannel so we don't
+ * have to watch out for the channel being deleted out from under
+ * us. This may cause a redundant trip through the event loop, but
+ * it's simpler than trying to do unwind protection.
*/
Tcl_Time blockTime = { 0, 0 };
@@ -719,10 +913,10 @@ SocketEventProc(
/*
* We must check to see if data is really available, since someone
- * 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.
+ * 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.
*/
SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
@@ -732,8 +926,8 @@ SocketEventProc(
FD_SET(infoPtr->socket, &readFds);
timeout.tv_usec = 0;
timeout.tv_sec = 0;
-
- if (select(0, &readFds, NULL, NULL, &timeout) != 0) {
+
+ if (winSock.select(0, &readFds, NULL, NULL, &timeout) != 0) {
mask |= TCL_READABLE;
} else {
infoPtr->readyEvents &= ~(FD_READ);
@@ -744,10 +938,7 @@ SocketEventProc(
if (events & (FD_WRITE | FD_CONNECT)) {
mask |= TCL_WRITABLE;
if (events & FD_CONNECT && infoPtr->lastError != NO_ERROR) {
- /*
- * Connect errors should also fire the readable handler.
- */
-
+ /* connect errors should also fire the readable handler. */
mask |= TCL_READABLE;
}
}
@@ -775,10 +966,10 @@ SocketEventProc(
*/
static int
-TcpBlockProc(
- ClientData instanceData, /* The socket to block/un-block. */
- int mode) /* TCL_MODE_BLOCKING or
- * TCL_MODE_NONBLOCKING. */
+TcpBlockProc(instanceData, mode)
+ ClientData instanceData; /* The socket to block/un-block. */
+ int mode; /* TCL_MODE_BLOCKING or
+ * TCL_MODE_NONBLOCKING. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
@@ -795,9 +986,9 @@ TcpBlockProc(
*
* TcpCloseProc --
*
- * This function is called by the generic IO level to perform channel
- * type specific cleanup on a socket based channel when the channel is
- * closed.
+ * This procedure is called by the generic IO level to perform
+ * channel type specific cleanup on a socket based channel
+ * when the channel is closed.
*
* Results:
* 0 if successful, the value of errno if failed.
@@ -810,41 +1001,41 @@ TcpBlockProc(
/* ARGSUSED */
static int
-TcpCloseProc(
- ClientData instanceData, /* The socket to close. */
- Tcl_Interp *interp) /* Unused. */
+TcpCloseProc(instanceData, interp)
+ ClientData instanceData; /* The socket to close. */
+ Tcl_Interp *interp; /* Unused. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
/* TIP #218 */
int errorCode = 0;
- /* ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); */
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
if (SocketsEnabled()) {
+
/*
- * Clean up the OS socket handle. The default Windows setting for a
- * socket is SO_DONTLINGER, which does a graceful shutdown in the
- * background.
- */
-
- if (closesocket(infoPtr->socket) == SOCKET_ERROR) {
- TclWinConvertWSAError((DWORD) WSAGetLastError());
- errorCode = Tcl_GetErrno();
- }
- }
-
- /*
- * TIP #218. Removed the code removing the structure from the global
- * socket list. This is now done by the thread action callbacks, and only
- * there. This happens before this code is called. We can free without
- * fear of damaging the list.
+ * Clean up the OS socket handle. The default Windows setting
+ * for a socket is SO_DONTLINGER, which does a graceful shutdown
+ * in the background.
+ */
+
+ if (winSock.closesocket(infoPtr->socket) == SOCKET_ERROR) {
+ TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
+ errorCode = Tcl_GetErrno();
+ }
+ }
+
+ /* TIP #218. Removed the code removing the structure
+ * from the global socket list. This is now done by
+ * the thread action callbacks, and only there. This
+ * happens before this code is called. We can free
+ * without fear of damanging the list.
*/
-
ckfree((char *) infoPtr);
return errorCode;
}
@@ -854,7 +1045,8 @@ TcpCloseProc(
*
* NewSocketInfo --
*
- * This function allocates and initializes a new SocketInfo structure.
+ * This function allocates and initializes a new SocketInfo
+ * structure.
*
* Results:
* Returns a newly allocated SocketInfo.
@@ -866,14 +1058,12 @@ TcpCloseProc(
*/
static SocketInfo *
-NewSocketInfo(
- SOCKET socket)
+NewSocketInfo(socket)
+ SOCKET socket;
{
SocketInfo *infoPtr;
- /* ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); */
infoPtr = (SocketInfo *) ckalloc((unsigned) sizeof(SocketInfo));
- infoPtr->channel = 0;
infoPtr->socket = socket;
infoPtr->flags = 0;
infoPtr->watchEvents = 0;
@@ -881,17 +1071,14 @@ NewSocketInfo(
infoPtr->selectEvents = 0;
infoPtr->acceptEventCount = 0;
infoPtr->acceptProc = NULL;
- infoPtr->acceptProcData = NULL;
infoPtr->lastError = 0;
- /*
- * TIP #218. Removed the code inserting the new structure into the global
- * list. This is now handled in the thread action callbacks, and only
- * there.
+ /* TIP #218. Removed the code inserting the new structure
+ * into the global list. This is now handled in the thread
+ * action callbacks, and only there.
*/
-
infoPtr->nextPtr = NULL;
-
+
return infoPtr;
}
@@ -900,8 +1087,8 @@ NewSocketInfo(
*
* CreateSocket --
*
- * This function opens a new socket and initializes the SocketInfo
- * structure.
+ * This function opens a new socket and initializes the
+ * SocketInfo structure.
*
* Results:
* Returns a new SocketInfo, or NULL with an error in interp.
@@ -913,57 +1100,58 @@ NewSocketInfo(
*/
static SocketInfo *
-CreateSocket(
- Tcl_Interp *interp, /* For error reporting; can be NULL. */
- int port, /* Port number to open. */
- const char *host, /* Name of host on which to open port. */
- int server, /* 1 if socket should be a server socket, else
- * 0 for a client socket. */
- const char *myaddr, /* Optional client-side address */
- int myport, /* Optional client-side port */
- int async) /* If nonzero, connect client socket
+CreateSocket(interp, port, host, server, myaddr, myport, async)
+ Tcl_Interp *interp; /* For error reporting; can be NULL. */
+ int port; /* Port number to open. */
+ CONST char *host; /* Name of host on which to open port. */
+ int server; /* 1 if socket should be a server socket,
+ * else 0 for a client socket. */
+ CONST char *myaddr; /* Optional client-side address */
+ int myport; /* Optional client-side port */
+ int async; /* If nonzero, connect client socket
* asynchronously. */
{
u_long flag = 1; /* Indicates nonblocking mode. */
- int asyncConnect = 0; /* Will be 1 if async connect is in
- * progress. */
+ int asyncConnect = 0; /* Will be 1 if async connect is
+ * in progress. */
SOCKADDR_IN sockaddr; /* Socket address */
SOCKADDR_IN mysockaddr; /* Socket address for client */
SOCKET sock = INVALID_SOCKET;
SocketInfo *infoPtr; /* The returned value. */
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr =
+ (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
if (!SocketsEnabled()) {
- return NULL;
+ return NULL;
}
- if (!CreateSocketAddress(&sockaddr, host, port)) {
+ if (! CreateSocketAddress(&sockaddr, host, port)) {
goto error;
}
if ((myaddr != NULL || myport != 0) &&
- !CreateSocketAddress(&mysockaddr, myaddr, myport)) {
+ ! CreateSocketAddress(&mysockaddr, myaddr, myport)) {
goto error;
}
- sock = socket(AF_INET, SOCK_STREAM, 0);
+ sock = winSock.socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
goto error;
}
/*
- * Win-NT has a misfeature that sockets are inherited in child processes
- * by default. Turn off the inherit bit.
+ * Win-NT has a misfeature that sockets are inherited in child
+ * processes by default. Turn off the inherit bit.
*/
- SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
-
+ SetHandleInformation( (HANDLE) sock, HANDLE_FLAG_INHERIT, 0 );
+
/*
* Set kernel space buffering
*/
@@ -972,27 +1160,27 @@ CreateSocket(
if (server) {
/*
- * Bind to the specified port. Note that we must not call setsockopt
+ * Bind to the specified port. Note that we must not call setsockopt
* with SO_REUSEADDR because Microsoft allows addresses to be reused
* even if they are still in use.
- *
- * Bind should not be affected by the socket having already been set
- * into nonblocking mode. If there is trouble, this is one place to
- * look for bugs.
+ *
+ * Bind should not be affected by the socket having already been
+ * set into nonblocking mode. If there is trouble, this is one place
+ * to look for bugs.
*/
-
- if (bind(sock, (SOCKADDR *) &sockaddr, sizeof(SOCKADDR_IN))
- == SOCKET_ERROR) {
- goto error;
- }
-
- /*
- * Set the maximum number of pending connect requests to the max value
- * allowed on each platform (Win32 and Win32s may be different, and
- * there may be differences between TCP/IP stacks).
- */
-
- if (listen(sock, SOMAXCONN) == SOCKET_ERROR) {
+
+ if (winSock.bind(sock, (SOCKADDR *) &sockaddr,
+ sizeof(SOCKADDR_IN)) == SOCKET_ERROR) {
+ goto error;
+ }
+
+ /*
+ * Set the maximum number of pending connect requests to the
+ * max value allowed on each platform (Win32 and Win32s may be
+ * different, and there may be differences between TCP/IP stacks).
+ */
+
+ if (winSock.listen(sock, SOMAXCONN) == SOCKET_ERROR) {
goto error;
}
@@ -1010,24 +1198,25 @@ CreateSocket(
infoPtr->watchEvents |= FD_ACCEPT;
} else {
- /*
- * Try to bind to a local port, if specified.
- */
- if (myaddr != NULL || myport != 0) {
- if (bind(sock, (SOCKADDR *) &mysockaddr, sizeof(SOCKADDR_IN))
- == SOCKET_ERROR) {
+ /*
+ * Try to bind to a local port, if specified.
+ */
+
+ if (myaddr != NULL || myport != 0) {
+ if (winSock.bind(sock, (SOCKADDR *) &mysockaddr,
+ sizeof(SOCKADDR_IN)) == SOCKET_ERROR) {
goto error;
}
- }
-
+ }
+
/*
- * Set the socket into nonblocking mode if the connect should be done
- * in the background.
+ * Set the socket into nonblocking mode if the connect should be
+ * done in the background.
*/
-
+
if (async) {
- if (ioctlsocket(sock, (long) FIONBIO, &flag) == SOCKET_ERROR) {
+ if (winSock.ioctlsocket(sock, (long) FIONBIO, &flag) == SOCKET_ERROR) {
goto error;
}
}
@@ -1036,9 +1225,9 @@ CreateSocket(
* Attempt to connect to the remote socket.
*/
- if (connect(sock, (SOCKADDR *) &sockaddr,
+ if (winSock.connect(sock, (SOCKADDR *) &sockaddr,
sizeof(SOCKADDR_IN)) == SOCKET_ERROR) {
- TclWinConvertWSAError((DWORD) WSAGetLastError());
+ TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
if (Tcl_GetErrno() != EWOULDBLOCK) {
goto error;
}
@@ -1048,7 +1237,7 @@ CreateSocket(
*/
asyncConnect = 1;
- }
+ }
/*
* Add this socket to the global list of sockets.
@@ -1057,7 +1246,7 @@ CreateSocket(
infoPtr = NewSocketInfo(sock);
/*
- * Set up the select mask for read/write events. If the connect
+ * Set up the select mask for read/write events. If the connect
* attempt has not completed, include connect events.
*/
@@ -1069,23 +1258,24 @@ CreateSocket(
}
/*
- * Register for interest in events in the select mask. Note that this
+ * Register for interest in events in the select mask. Note that this
* automatically places the socket into non-blocking mode.
*/
- ioctlsocket(sock, (long) FIONBIO, &flag);
- SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) infoPtr);
+ winSock.ioctlsocket(sock, (long) FIONBIO, &flag);
+ SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
+ (WPARAM) SELECT, (LPARAM) infoPtr);
return infoPtr;
- error:
- TclWinConvertWSAError((DWORD) WSAGetLastError());
+error:
+ TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
if (interp != NULL) {
Tcl_AppendResult(interp, "couldn't open socket: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_PosixError(interp), (char *) NULL);
}
if (sock != INVALID_SOCKET) {
- closesocket(sock);
+ winSock.closesocket(sock);
}
return NULL;
}
@@ -1098,8 +1288,8 @@ CreateSocket(
* This function initializes a sockaddr structure for a host and port.
*
* Results:
- * 1 if the host was valid, 0 if the host could not be converted to an IP
- * address.
+ * 1 if the host was valid, 0 if the host could not be converted to
+ * an IP address.
*
* Side effects:
* Fills in the *sockaddrPtr structure.
@@ -1108,42 +1298,43 @@ CreateSocket(
*/
static int
-CreateSocketAddress(
- LPSOCKADDR_IN sockaddrPtr, /* Socket address */
- const char *host, /* Host. NULL implies INADDR_ANY */
- int port) /* Port number */
+CreateSocketAddress(sockaddrPtr, host, port)
+ LPSOCKADDR_IN sockaddrPtr; /* Socket address */
+ CONST char *host; /* Host. NULL implies INADDR_ANY */
+ int port; /* Port number */
{
- struct hostent *hostent; /* Host database entry */
- struct in_addr addr; /* For 64/32 bit madness */
+ struct hostent *hostent; /* Host database entry */
+ struct in_addr addr; /* For 64/32 bit madness */
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
if (!SocketsEnabled()) {
- Tcl_SetErrno(EFAULT);
- return 0;
+ Tcl_SetErrno(EFAULT);
+ return 0;
}
ZeroMemory(sockaddrPtr, sizeof(SOCKADDR_IN));
sockaddrPtr->sin_family = AF_INET;
- sockaddrPtr->sin_port = htons((u_short) (port & 0xFFFF));
+ sockaddrPtr->sin_port = winSock.htons((u_short) (port & 0xFFFF));
if (host == NULL) {
addr.s_addr = INADDR_ANY;
} else {
- addr.s_addr = inet_addr(host);
- if (addr.s_addr == INADDR_NONE) {
- hostent = gethostbyname(host);
- if (hostent != NULL) {
- memcpy(&addr, hostent->h_addr, (size_t) hostent->h_length);
- } else {
+ addr.s_addr = winSock.inet_addr(host);
+ if (addr.s_addr == INADDR_NONE) {
+ hostent = winSock.gethostbyname(host);
+ if (hostent != NULL) {
+ memcpy(&addr, hostent->h_addr, (size_t) hostent->h_length);
+ } else {
#ifdef EHOSTUNREACH
- Tcl_SetErrno(EHOSTUNREACH);
+ Tcl_SetErrno(EHOSTUNREACH);
#else
#ifdef ENXIO
- Tcl_SetErrno(ENXIO);
+ Tcl_SetErrno(ENXIO);
#endif
#endif
return 0; /* Error. */
@@ -1152,14 +1343,14 @@ CreateSocketAddress(
}
/*
- * NOTE: On 64 bit machines the assignment below is rumored to not do the
- * right thing. Please report errors related to this if you observe
- * incorrect behavior on 64 bit machines such as DEC Alphas. Should we
- * modify this code to do an explicit memcpy?
+ * NOTE: On 64 bit machines the assignment below is rumored to not
+ * do the right thing. Please report errors related to this if you
+ * observe incorrect behavior on 64 bit machines such as DEC Alphas.
+ * Should we modify this code to do an explicit memcpy?
*/
sockaddrPtr->sin_addr.s_addr = addr.s_addr;
- return 1; /* Success. */
+ return 1; /* Success. */
}
/*
@@ -1180,33 +1371,34 @@ CreateSocketAddress(
*/
static int
-WaitForSocketEvent(
- SocketInfo *infoPtr, /* Information about this socket. */
- int events, /* Events to look for. */
- int *errorCodePtr) /* Where to store errors? */
+WaitForSocketEvent(infoPtr, events, errorCodePtr)
+ SocketInfo *infoPtr; /* Information about this socket. */
+ int events; /* Events to look for. */
+ int *errorCodePtr; /* Where to store errors? */
{
int result = 1;
int oldMode;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr =
+ (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
/*
* Be sure to disable event servicing so we are truly modal.
*/
oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
-
+
/*
* Reset WSAAsyncSelect so we have a fresh set of events pending.
*/
- SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT,
- (LPARAM) infoPtr);
+ SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
+ (WPARAM) UNSELECT, (LPARAM) infoPtr);
- SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT,
- (LPARAM) infoPtr);
+ SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
+ (WPARAM) SELECT, (LPARAM) infoPtr);
while (1) {
+
if (infoPtr->lastError) {
*errorCodePtr = infoPtr->lastError;
result = 0;
@@ -1222,10 +1414,9 @@ WaitForSocketEvent(
/*
* Wait until something happens.
*/
-
WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
}
-
+
(void) Tcl_SetServiceMode(oldMode);
return result;
}
@@ -1238,8 +1429,8 @@ WaitForSocketEvent(
* Opens a TCP client socket and creates a channel around it.
*
* Results:
- * The channel or NULL if failed. An error message is returned in the
- * interpreter on failure.
+ * The channel or NULL if failed. An error message is returned
+ * in the interpreter on failure.
*
* Side effects:
* Opens a client socket and creates a new channel.
@@ -1248,14 +1439,14 @@ WaitForSocketEvent(
*/
Tcl_Channel
-Tcl_OpenTcpClient(
- Tcl_Interp *interp, /* For error reporting; can be NULL. */
- int port, /* Port number to open. */
- const char *host, /* Host on which to open port. */
- const char *myaddr, /* Client-side address */
- int myport, /* Client-side port */
- int async) /* If nonzero, should connect client socket
- * asynchronously. */
+Tcl_OpenTcpClient(interp, port, host, myaddr, myport, async)
+ Tcl_Interp *interp; /* For error reporting; can be NULL. */
+ int port; /* Port number to open. */
+ CONST char *host; /* Host on which to open port. */
+ CONST char *myaddr; /* Client-side address */
+ int myport; /* Client-side port */
+ int async; /* If nonzero, should connect
+ * client socket asynchronously. */
{
SocketInfo *infoPtr;
char channelName[16 + TCL_INTEGER_SPACE];
@@ -1279,13 +1470,13 @@ Tcl_OpenTcpClient(
(ClientData) infoPtr, (TCL_READABLE | TCL_WRITABLE));
if (Tcl_SetChannelOption(interp, infoPtr->channel, "-translation",
"auto crlf") == TCL_ERROR) {
- Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
- return (Tcl_Channel) NULL;
+ Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
+ return (Tcl_Channel) NULL;
}
if (Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "")
== TCL_ERROR) {
- Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
- return (Tcl_Channel) NULL;
+ Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
+ return (Tcl_Channel) NULL;
}
return infoPtr->channel;
}
@@ -1309,8 +1500,8 @@ Tcl_OpenTcpClient(
*/
Tcl_Channel
-Tcl_MakeTcpClientChannel(
- ClientData sock) /* The socket to wrap up into a channel. */
+Tcl_MakeTcpClientChannel(sock)
+ ClientData sock; /* The socket to wrap up into a channel. */
{
SocketInfo *infoPtr;
char channelName[16 + TCL_INTEGER_SPACE];
@@ -1326,7 +1517,7 @@ Tcl_MakeTcpClientChannel(
* Set kernel space buffering and non-blocking.
*/
- TclSockMinimumBuffers(PTR2INT(sock), TCP_BUFFER_SIZE);
+ TclSockMinimumBuffers((int) sock, TCP_BUFFER_SIZE);
infoPtr = NewSocketInfo((SOCKET) sock);
@@ -1353,8 +1544,8 @@ Tcl_MakeTcpClientChannel(
* Opens a TCP server socket and creates a channel around it.
*
* Results:
- * The channel or NULL if failed. An error message is returned in the
- * interpreter on failure.
+ * The channel or NULL if failed. An error message is returned
+ * in the interpreter on failure.
*
* Side effects:
* Opens a server socket and creates a new channel.
@@ -1363,14 +1554,14 @@ Tcl_MakeTcpClientChannel(
*/
Tcl_Channel
-Tcl_OpenTcpServer(
- Tcl_Interp *interp, /* For error reporting - may be NULL. */
- int port, /* Port number to open. */
- const char *host, /* Name of local host. */
- Tcl_TcpAcceptProc *acceptProc,
- /* Callback for accepting connections from new
- * clients. */
- ClientData acceptProcData) /* Data for the callback. */
+Tcl_OpenTcpServer(interp, port, host, acceptProc, acceptProcData)
+ Tcl_Interp *interp; /* For error reporting - may be
+ * NULL. */
+ int port; /* Port number to open. */
+ CONST char *host; /* Name of local host. */
+ Tcl_TcpAcceptProc *acceptProc; /* Callback for accepting connections
+ * from new clients. */
+ ClientData acceptProcData; /* Data for the callback. */
{
SocketInfo *infoPtr;
char channelName[16 + TCL_INTEGER_SPACE];
@@ -1397,8 +1588,8 @@ Tcl_OpenTcpServer(
(ClientData) infoPtr, 0);
if (Tcl_SetChannelOption(interp, infoPtr->channel, "-eofchar", "")
== TCL_ERROR) {
- Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
- return (Tcl_Channel) NULL;
+ Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
+ return (Tcl_Channel) NULL;
}
return infoPtr->channel;
@@ -1408,9 +1599,9 @@ Tcl_OpenTcpServer(
*----------------------------------------------------------------------
*
* TcpAccept --
- *
- * Accept a TCP socket connection. This is called by SocketEventProc and
- * it in turns calls the registered accept function.
+ * Accept a TCP socket connection. This is called by
+ * SocketEventProc and it in turns calls the registered accept
+ * procedure.
*
* Results:
* None.
@@ -1422,16 +1613,16 @@ Tcl_OpenTcpServer(
*/
static void
-TcpAccept(
- SocketInfo *infoPtr) /* Socket to accept. */
+TcpAccept(infoPtr)
+ SocketInfo *infoPtr; /* Socket to accept. */
{
SOCKET newSocket;
SocketInfo *newInfoPtr;
SOCKADDR_IN addr;
int len;
char channelName[16 + TCL_INTEGER_SPACE];
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr =
+ (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
/*
* Accept the incoming connection request.
@@ -1439,7 +1630,7 @@ TcpAccept(
len = sizeof(SOCKADDR_IN);
- newSocket = accept(infoPtr->socket, (SOCKADDR *)&addr,
+ newSocket = winSock.accept(infoPtr->socket, (SOCKADDR *)&addr,
&len);
/*
@@ -1449,9 +1640,9 @@ TcpAccept(
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
/*
- * Clear the ready mask so we can detect the next connection request. Note
- * that connection requests are level triggered, so if there is a request
- * already pending, a new event will be generated.
+ * Clear the ready mask so we can detect the next connection request.
+ * Note that connection requests are level triggered, so if there is
+ * a request already pending, a new event will be generated.
*/
if (newSocket == INVALID_SOCKET) {
@@ -1464,7 +1655,7 @@ TcpAccept(
/*
* It is possible that more than one FD_ACCEPT has been sent, so an extra
- * count must be kept. Decrement the count, and reset the readyEvent bit
+ * count must be kept. Decrement the count, and reset the readyEvent bit
* if the count is no longer > 0.
*/
@@ -1477,11 +1668,11 @@ TcpAccept(
SetEvent(tsdPtr->socketListLock);
/*
- * Win-NT has a misfeature that sockets are inherited in child processes
- * by default. Turn off the inherit bit.
+ * Win-NT has a misfeature that sockets are inherited in child
+ * processes by default. Turn off the inherit bit.
*/
- SetHandleInformation((HANDLE) newSocket, HANDLE_FLAG_INHERIT, 0);
+ SetHandleInformation( (HANDLE) newSocket, HANDLE_FLAG_INHERIT, 0 );
/*
* Add this socket to the global list of sockets.
@@ -1512,12 +1703,14 @@ TcpAccept(
}
/*
- * Invoke the accept callback function.
+ * Invoke the accept callback procedure.
*/
if (infoPtr->acceptProc != NULL) {
- (infoPtr->acceptProc) (infoPtr->acceptProcData, newInfoPtr->channel,
- inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+ (infoPtr->acceptProc) (infoPtr->acceptProcData,
+ newInfoPtr->channel,
+ winSock.inet_ntoa(addr.sin_addr),
+ winSock.ntohs(addr.sin_port));
}
}
@@ -1526,8 +1719,8 @@ TcpAccept(
*
* TcpInputProc --
*
- * This function is called by the generic IO level to read data from a
- * socket based channel.
+ * This procedure is called by the generic IO level to read data from
+ * a socket based channel.
*
* Results:
* The number of bytes read or -1 on error.
@@ -1539,34 +1732,35 @@ TcpAccept(
*/
static int
-TcpInputProc(
- ClientData instanceData, /* The socket state. */
- char *buf, /* Where to store data. */
- int toRead, /* Maximum number of bytes to read. */
- int *errorCodePtr) /* Where to store error codes. */
+TcpInputProc(instanceData, buf, toRead, errorCodePtr)
+ ClientData instanceData; /* The socket state. */
+ char *buf; /* Where to store data. */
+ int toRead; /* Maximum number of bytes to read. */
+ int *errorCodePtr; /* Where to store error codes. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
int bytesRead;
DWORD error;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- TclThreadDataKeyGet(&dataKey);
-
+ ThreadSpecificData *tsdPtr =
+ (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
+
*errorCodePtr = 0;
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
if (!SocketsEnabled()) {
- *errorCodePtr = EFAULT;
- return -1;
+ *errorCodePtr = EFAULT;
+ return -1;
}
/*
- * First check to see if EOF was already detected, to prevent calling the
- * socket stack after the first time EOF is detected.
+ * First check to see if EOF was already detected, to prevent
+ * calling the socket stack after the first time EOF is detected.
*/
if (infoPtr->flags & SOCKET_EOF) {
@@ -1578,63 +1772,63 @@ TcpInputProc(
*/
if ((infoPtr->flags & SOCKET_ASYNC_CONNECT)
- && !WaitForSocketEvent(infoPtr, FD_CONNECT, errorCodePtr)) {
+ && ! WaitForSocketEvent(infoPtr, FD_CONNECT, errorCodePtr)) {
return -1;
}
-
+
/*
- * No EOF, and it is connected, so try to read more from the socket. Note
- * that we clear the FD_READ bit because read events are level triggered
- * so a new event will be generated if there is still data available to be
- * read. We have to simulate blocking behavior here since we are always
- * using non-blocking sockets.
+ * No EOF, and it is connected, so try to read more from the socket.
+ * Note that we clear the FD_READ bit because read events are level
+ * triggered so a new event will be generated if there is still data
+ * available to be read. We have to simulate blocking behavior here
+ * since we are always using non-blocking sockets.
*/
while (1) {
SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
(WPARAM) UNSELECT, (LPARAM) infoPtr);
- bytesRead = recv(infoPtr->socket, buf, toRead, 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 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;
}
-
- error = WSAGetLastError();
-
- /*
- * If an RST comes, then ignore the error and report an EOF just like
- * on unix.
- */
-
- if (error == WSAECONNRESET) {
- infoPtr->flags |= SOCKET_EOF;
- bytesRead = 0;
- break;
- }
-
+
+ error = winSock.WSAGetLastError();
+
+ /*
+ * If an RST comes, then ignore the error and report an EOF just like
+ * on unix.
+ */
+
+ if (error == WSAECONNRESET) {
+ infoPtr->flags |= SOCKET_EOF;
+ bytesRead = 0;
+ break;
+ }
+
/*
* Check for error condition or underflow in non-blocking case.
*/
-
+
if ((infoPtr->flags & SOCKET_ASYNC) || (error != WSAEWOULDBLOCK)) {
TclWinConvertWSAError(error);
*errorCodePtr = Tcl_GetErrno();
@@ -1643,19 +1837,19 @@ TcpInputProc(
}
/*
- * In the blocking case, wait until the file becomes readable or
- * closed and try again.
+ * In the blocking case, wait until the file becomes readable
+ * or closed and try again.
*/
if (!WaitForSocketEvent(infoPtr, FD_READ|FD_CLOSE, errorCodePtr)) {
bytesRead = -1;
break;
- }
+ }
}
-
+
SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
(WPARAM) SELECT, (LPARAM) infoPtr);
-
+
return bytesRead;
}
@@ -1664,8 +1858,8 @@ TcpInputProc(
*
* TcpOutputProc --
*
- * This function is called by the generic IO level to write data to a
- * socket based channel.
+ * This procedure is called by the generic IO level to write data
+ * to a socket based channel.
*
* Results:
* The number of bytes written or -1 on failure.
@@ -1677,37 +1871,38 @@ TcpInputProc(
*/
static int
-TcpOutputProc(
- ClientData instanceData, /* The socket state. */
- const char *buf, /* Where to get data. */
- int toWrite, /* Maximum number of bytes to write. */
- int *errorCodePtr) /* Where to store error codes. */
+TcpOutputProc(instanceData, buf, toWrite, errorCodePtr)
+ ClientData instanceData; /* The socket state. */
+ CONST char *buf; /* Where to get data. */
+ int toWrite; /* Maximum number of bytes to write. */
+ int *errorCodePtr; /* Where to store error codes. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
int bytesWritten;
DWORD error;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr =
+ (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
*errorCodePtr = 0;
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
if (!SocketsEnabled()) {
- *errorCodePtr = EFAULT;
- return -1;
+ *errorCodePtr = EFAULT;
+ return -1;
}
/*
* Check to see if the socket is connected before trying to write.
*/
-
+
if ((infoPtr->flags & SOCKET_ASYNC_CONNECT)
- && !WaitForSocketEvent(infoPtr, FD_CONNECT, errorCodePtr)) {
+ && ! WaitForSocketEvent(infoPtr, FD_CONNECT, errorCodePtr)) {
return -1;
}
@@ -1715,36 +1910,36 @@ TcpOutputProc(
SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
(WPARAM) UNSELECT, (LPARAM) infoPtr);
- bytesWritten = send(infoPtr->socket, buf, toWrite, 0);
+ bytesWritten = winSock.send(infoPtr->socket, buf, toWrite, 0);
if (bytesWritten != SOCKET_ERROR) {
/*
- * Since Windows won't generate a new write event until we hit an
- * overflow condition, we need to force the event loop to poll
- * until the condition changes.
+ * Since Windows won't generate a new write event until we hit
+ * an overflow condition, we need to force the event loop to
+ * poll until the condition changes.
*/
if (infoPtr->watchEvents & FD_WRITE) {
Tcl_Time blockTime = { 0, 0 };
Tcl_SetMaxBlockTime(&blockTime);
- }
+ }
break;
}
-
+
/*
- * Check for error condition or overflow. In the event of overflow, we
+ * Check for error condition or overflow. In the event of overflow, we
* need to clear the FD_WRITE flag so we can detect the next writable
- * event. Note that Windows only sends a new writable event after a
+ * event. Note that Windows only sends a new writable event after a
* send fails with WSAEWOULDBLOCK.
*/
- error = WSAGetLastError();
+ error = winSock.WSAGetLastError();
if (error == WSAEWOULDBLOCK) {
infoPtr->readyEvents &= ~(FD_WRITE);
if (infoPtr->flags & SOCKET_ASYNC) {
*errorCodePtr = EWOULDBLOCK;
bytesWritten = -1;
break;
- }
+ }
} else {
TclWinConvertWSAError(error);
*errorCodePtr = Tcl_GetErrno();
@@ -1753,8 +1948,8 @@ TcpOutputProc(
}
/*
- * In the blocking case, wait until the file becomes writable or
- * closed and try again.
+ * In the blocking case, wait until the file becomes writable
+ * or closed and try again.
*/
if (!WaitForSocketEvent(infoPtr, FD_WRITE|FD_CLOSE, errorCodePtr)) {
@@ -1765,7 +1960,7 @@ TcpOutputProc(
SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
(WPARAM) SELECT, (LPARAM) infoPtr);
-
+
return bytesWritten;
}
@@ -1786,48 +1981,45 @@ TcpOutputProc(
*/
static int
-TcpSetOptionProc(
+TcpSetOptionProc (
ClientData instanceData, /* Socket state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
- const char *optionName, /* Name of the option to set. */
- const char *value) /* New value for option. */
+ CONST char *optionName, /* Name of the option to set. */
+ CONST char *value) /* New value for option. */
{
-#ifdef TCL_FEATURE_KEEPALIVE_NAGLE
+/*
SocketInfo *infoPtr;
SOCKET sock;
-#endif
-
+ BOOL val = FALSE;
+ int boolVar, rtn;
+*/
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
if (!SocketsEnabled()) {
if (interp) {
Tcl_AppendResult(interp, "winsock is not initialized", NULL);
}
- return TCL_ERROR;
+ return TCL_ERROR;
}
-#ifdef TCL_FEATURE_KEEPALIVE_NAGLE
+/*
infoPtr = (SocketInfo *) instanceData;
sock = infoPtr->socket;
- if (!strcasecmp(optionName, "-keepalive")) {
- BOOL val = FALSE;
- int boolVar, rtn;
-
+ if (!stricmp(optionName, "-keepalive")) {
if (Tcl_GetBoolean(interp, value, &boolVar) != TCL_OK) {
return TCL_ERROR;
}
- if (boolVar) {
- val = TRUE;
- }
- rtn = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+ if (boolVar) val = TRUE;
+ rtn = winSock.setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
(const char *) &val, sizeof(BOOL));
if (rtn != 0) {
- TclWinConvertWSAError(WSAGetLastError());
+ TclWinConvertWSAError(winSock.WSAGetLastError());
if (interp) {
Tcl_AppendResult(interp, "couldn't set socket option: ",
Tcl_PosixError(interp), NULL);
@@ -1835,20 +2027,16 @@ TcpSetOptionProc(
return TCL_ERROR;
}
return TCL_OK;
- } else if (!strcasecmp(optionName, "-nagle")) {
- BOOL val = FALSE;
- int boolVar, rtn;
+ } else if (!stricmp(optionName, "-nagle")) {
if (Tcl_GetBoolean(interp, value, &boolVar) != TCL_OK) {
return TCL_ERROR;
}
- if (!boolVar) {
- val = TRUE;
- }
- rtn = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+ if (!boolVar) val = TRUE;
+ rtn = winSock.setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(const char *) &val, sizeof(BOOL));
if (rtn != 0) {
- TclWinConvertWSAError(WSAGetLastError());
+ TclWinConvertWSAError(winSock.WSAGetLastError());
if (interp) {
Tcl_AppendResult(interp, "couldn't set socket option: ",
Tcl_PosixError(interp), NULL);
@@ -1859,9 +2047,8 @@ TcpSetOptionProc(
}
return Tcl_BadChannelOption(interp, optionName, "keepalive nagle");
-#else
+*/
return Tcl_BadChannelOption(interp, optionName, "");
-#endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/
}
/*
@@ -1869,14 +2056,15 @@ TcpSetOptionProc(
*
* TcpGetOptionProc --
*
- * Computes an option value for a TCP socket based channel, or a list of
- * all options and their values.
+ * Computes an option value for a TCP socket based channel, or a
+ * list of all options and their values.
*
* Note: This code is based on code contributed by John Haxby.
*
* Results:
- * A standard Tcl result. The value of the specified option or a list of
- * all options and their values is returned in the supplied DString.
+ * A standard Tcl result. The value of the specified option or a
+ * list of all options and their values is returned in the
+ * supplied DString.
*
* Side effects:
* None.
@@ -1885,14 +2073,15 @@ TcpSetOptionProc(
*/
static int
-TcpGetOptionProc(
- ClientData instanceData, /* Socket state. */
- Tcl_Interp *interp, /* For error reporting - can be NULL */
- const char *optionName, /* Name of the option to retrieve the value
- * for, or NULL to get all options and their
- * values. */
- Tcl_DString *dsPtr) /* Where to store the computed value;
- * initialized by caller. */
+TcpGetOptionProc(instanceData, interp, optionName, dsPtr)
+ ClientData instanceData; /* Socket state. */
+ Tcl_Interp *interp; /* For error reporting - can be NULL */
+ CONST char *optionName; /* Name of the option to
+ * retrieve the value for, or
+ * NULL to get all options and
+ * their values. */
+ Tcl_DString *dsPtr; /* Where to store the computed
+ * value; initialized by caller. */
{
SocketInfo *infoPtr;
SOCKADDR_IN sockname;
@@ -1904,22 +2093,23 @@ TcpGetOptionProc(
char buf[TCL_INTEGER_SPACE];
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
if (!SocketsEnabled()) {
if (interp) {
Tcl_AppendResult(interp, "winsock is not initialized", NULL);
}
- return TCL_ERROR;
+ return TCL_ERROR;
}
-
+
infoPtr = (SocketInfo *) instanceData;
sock = (int) infoPtr->socket;
- if (optionName != NULL) {
- len = strlen(optionName);
+ if (optionName != (char *) NULL) {
+ len = strlen(optionName);
}
if ((len > 1) && (optionName[1] == 'e') &&
@@ -1927,12 +2117,12 @@ TcpGetOptionProc(
int optlen;
DWORD err;
int ret;
-
+
optlen = sizeof(int);
- ret = TclWinGetSockOpt((int)sock, SOL_SOCKET, SO_ERROR,
+ ret = TclWinGetSockOpt(sock, SOL_SOCKET, SO_ERROR,
(char *)&err, &optlen);
if (ret == SOCKET_ERROR) {
- err = WSAGetLastError();
+ err = winSock.WSAGetLastError();
}
if (err) {
TclWinConvertWSAError(err);
@@ -1941,136 +2131,140 @@ TcpGetOptionProc(
return TCL_OK;
}
- if ((len == 0) || ((len > 1) && (optionName[1] == 'p') &&
- (strncmp(optionName, "-peername", len) == 0))) {
- if (getpeername(sock, (LPSOCKADDR) &peername, &size) == 0) {
- if (len == 0) {
- Tcl_DStringAppendElement(dsPtr, "-peername");
- Tcl_DStringStartSublist(dsPtr);
- }
- Tcl_DStringAppendElement(dsPtr, inet_ntoa(peername.sin_addr));
+ if ((len == 0) ||
+ ((len > 1) && (optionName[1] == 'p') &&
+ (strncmp(optionName, "-peername", len) == 0))) {
+ if (winSock.getpeername(sock, (LPSOCKADDR) &peername, &size)
+ == 0) {
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-peername");
+ Tcl_DStringStartSublist(dsPtr);
+ }
+ Tcl_DStringAppendElement(dsPtr,
+ winSock.inet_ntoa(peername.sin_addr));
if (peername.sin_addr.s_addr == 0) {
- hostEntPtr = NULL;
- } else {
- hostEntPtr = gethostbyaddr((char *) &(peername.sin_addr),
- sizeof(peername.sin_addr), AF_INET);
- }
- if (hostEntPtr != NULL) {
- Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
+ hostEntPtr = (struct hostent *) NULL;
} else {
- Tcl_DStringAppendElement(dsPtr, inet_ntoa(peername.sin_addr));
- }
- TclFormatInt(buf, ntohs(peername.sin_port));
- Tcl_DStringAppendElement(dsPtr, buf);
- if (len == 0) {
- Tcl_DStringEndSublist(dsPtr);
- } else {
- return TCL_OK;
- }
- } else {
- /*
- * getpeername failed - but if we were asked for all the options
- * (len==0), don't flag an error at that point because it could be
- * an fconfigure request on a server socket (such sockets have no
- * peer). {Copied from unix/tclUnixChan.c}
- */
-
- if (len) {
- TclWinConvertWSAError((DWORD) WSAGetLastError());
- if (interp) {
- Tcl_AppendResult(interp, "can't get peername: ",
- Tcl_PosixError(interp), NULL);
- }
- return TCL_ERROR;
- }
- }
- }
-
- if ((len == 0) || ((len > 1) && (optionName[1] == 's') &&
- (strncmp(optionName, "-sockname", len) == 0))) {
- if (getsockname(sock, (LPSOCKADDR) &sockname, &size) == 0) {
- if (len == 0) {
- Tcl_DStringAppendElement(dsPtr, "-sockname");
- Tcl_DStringStartSublist(dsPtr);
+ hostEntPtr = winSock.gethostbyaddr(
+ (char *) &(peername.sin_addr), sizeof(peername.sin_addr),
+ AF_INET);
}
- Tcl_DStringAppendElement(dsPtr, inet_ntoa(sockname.sin_addr));
+ if (hostEntPtr != (struct hostent *) NULL) {
+ Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
+ } else {
+ Tcl_DStringAppendElement(dsPtr,
+ winSock.inet_ntoa(peername.sin_addr));
+ }
+ TclFormatInt(buf, winSock.ntohs(peername.sin_port));
+ Tcl_DStringAppendElement(dsPtr, buf);
+ if (len == 0) {
+ Tcl_DStringEndSublist(dsPtr);
+ } else {
+ return TCL_OK;
+ }
+ } else {
+ /*
+ * getpeername failed - but if we were asked for all the options
+ * (len==0), don't flag an error at that point because it could
+ * be an fconfigure request on a server socket. (which have
+ * no peer). {copied from unix/tclUnixChan.c}
+ */
+ if (len) {
+ TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
+ if (interp) {
+ Tcl_AppendResult(interp, "can't get peername: ",
+ Tcl_PosixError(interp),
+ (char *) NULL);
+ }
+ return TCL_ERROR;
+ }
+ }
+ }
+
+ if ((len == 0) ||
+ ((len > 1) && (optionName[1] == 's') &&
+ (strncmp(optionName, "-sockname", len) == 0))) {
+ if (winSock.getsockname(sock, (LPSOCKADDR) &sockname, &size)
+ == 0) {
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-sockname");
+ Tcl_DStringStartSublist(dsPtr);
+ }
+ Tcl_DStringAppendElement(dsPtr,
+ winSock.inet_ntoa(sockname.sin_addr));
if (sockname.sin_addr.s_addr == 0) {
- hostEntPtr = NULL;
+ hostEntPtr = (struct hostent *) NULL;
} else {
- hostEntPtr = gethostbyaddr((char *) &(sockname.sin_addr),
- sizeof(peername.sin_addr), AF_INET);
+ hostEntPtr = winSock.gethostbyaddr(
+ (char *) &(sockname.sin_addr), sizeof(peername.sin_addr),
+ AF_INET);
}
- if (hostEntPtr != NULL) {
- Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
- } else {
- Tcl_DStringAppendElement(dsPtr, inet_ntoa(sockname.sin_addr));
- }
- TclFormatInt(buf, ntohs(sockname.sin_port));
- Tcl_DStringAppendElement(dsPtr, buf);
- if (len == 0) {
- Tcl_DStringEndSublist(dsPtr);
- } else {
- return TCL_OK;
- }
- } else {
+ if (hostEntPtr != (struct hostent *) NULL) {
+ Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
+ } else {
+ Tcl_DStringAppendElement(dsPtr,
+ winSock.inet_ntoa(sockname.sin_addr));
+ }
+ TclFormatInt(buf, winSock.ntohs(sockname.sin_port));
+ Tcl_DStringAppendElement(dsPtr, buf);
+ if (len == 0) {
+ Tcl_DStringEndSublist(dsPtr);
+ } else {
+ return TCL_OK;
+ }
+ } else {
if (interp) {
- TclWinConvertWSAError((DWORD) WSAGetLastError());
+ TclWinConvertWSAError((DWORD) winSock.WSAGetLastError());
Tcl_AppendResult(interp, "can't get sockname: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_PosixError(interp),
+ (char *) NULL);
}
return TCL_ERROR;
}
}
-#ifdef TCL_FEATURE_KEEPALIVE_NAGLE
+/*
if (len == 0 || !strncmp(optionName, "-keepalive", len)) {
int optlen;
BOOL opt = FALSE;
-
- if (len == 0) {
- Tcl_DStringAppendElement(dsPtr, "-keepalive");
- }
+
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-keepalive");
+ }
optlen = sizeof(BOOL);
- getsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt, &optlen);
+ winSock.getsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt,
+ &optlen);
if (opt) {
Tcl_DStringAppendElement(dsPtr, "1");
} else {
Tcl_DStringAppendElement(dsPtr, "0");
}
- if (len > 0) {
- return TCL_OK;
- }
+ if (len > 0) return TCL_OK;
}
if (len == 0 || !strncmp(optionName, "-nagle", len)) {
int optlen;
BOOL opt = FALSE;
-
- if (len == 0) {
- Tcl_DStringAppendElement(dsPtr, "-nagle");
- }
+
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-nagle");
+ }
optlen = sizeof(BOOL);
- getsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&opt,
+ winSock.getsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&opt,
&optlen);
if (opt) {
Tcl_DStringAppendElement(dsPtr, "0");
} else {
Tcl_DStringAppendElement(dsPtr, "1");
}
- if (len > 0) {
- return TCL_OK;
- }
+ if (len > 0) return TCL_OK;
}
-#endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/
+*/
if (len > 0) {
-#ifdef TCL_FEATURE_KEEPALIVE_NAGLE
- return Tcl_BadChannelOption(interp, optionName,
- "peername sockname keepalive nagle");
-#else
- return Tcl_BadChannelOption(interp, optionName, "peername sockname");
-#endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/
+ /*return Tcl_BadChannelOption(interp, optionName, "peername sockname keepalive nagle");*/
+ return Tcl_BadChannelOption(interp, optionName, "peername sockname");
}
return TCL_OK;
@@ -2081,45 +2275,45 @@ TcpGetOptionProc(
*
* TcpWatchProc --
*
- * Informs the channel driver of the events that the generic channel code
- * wishes to receive on this socket.
+ * Informs the channel driver of the events that the generic
+ * channel code wishes to receive on this socket.
*
* Results:
* None.
*
* Side effects:
- * May cause the notifier to poll if any of the specified conditions are
- * already true.
+ * May cause the notifier to poll if any of the specified
+ * conditions are already true.
*
*----------------------------------------------------------------------
*/
static void
-TcpWatchProc(
- ClientData instanceData, /* The socket state. */
- int mask) /* Events of interest; an OR-ed combination of
- * TCL_READABLE, TCL_WRITABLE and
- * TCL_EXCEPTION. */
+TcpWatchProc(instanceData, mask)
+ ClientData instanceData; /* The socket state. */
+ int mask; /* Events of interest; an OR-ed
+ * combination of TCL_READABLE,
+ * TCL_WRITABLE and TCL_EXCEPTION. */
{
SocketInfo *infoPtr = (SocketInfo *) instanceData;
-
+
/*
- * Update the watch events mask. Only if the socket is not a server
- * socket. Fix for SF Tcl Bug #557878.
+ * Update the watch events mask. Only if the socket is not a
+ * server socket. Fix for SF Tcl Bug #557878.
*/
- if (!infoPtr->acceptProc) {
- infoPtr->watchEvents = 0;
+ if (!infoPtr->acceptProc) {
+ infoPtr->watchEvents = 0;
if (mask & TCL_READABLE) {
infoPtr->watchEvents |= (FD_READ|FD_CLOSE|FD_ACCEPT);
}
if (mask & TCL_WRITABLE) {
infoPtr->watchEvents |= (FD_WRITE|FD_CLOSE|FD_CONNECT);
}
-
+
/*
- * If there are any conditions already set, then tell the notifier to
- * poll rather than block.
+ * If there are any conditions already set, then tell the notifier to poll
+ * rather than block.
*/
if (infoPtr->readyEvents & infoPtr->watchEvents) {
@@ -2147,10 +2341,10 @@ TcpWatchProc(
*/
static int
-TcpGetHandleProc(
- ClientData instanceData, /* The socket state. */
- int direction, /* Not used. */
- ClientData *handlePtr) /* Where to store the handle. */
+TcpGetHandleProc(instanceData, direction, handlePtr)
+ ClientData instanceData; /* The socket state. */
+ int direction; /* Not used. */
+ ClientData *handlePtr; /* Where to store the handle. */
{
SocketInfo *statePtr = (SocketInfo *) instanceData;
@@ -2175,8 +2369,7 @@ TcpGetHandleProc(
*/
static DWORD WINAPI
-SocketThread(
- LPVOID arg)
+SocketThread(LPVOID arg)
{
MSG msg;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)(arg);
@@ -2185,7 +2378,7 @@ SocketThread(
* Create a dummy window receiving socket events.
*/
- tsdPtr->hwnd = CreateWindow("TclSocket", "TclSocket",
+ tsdPtr->hwnd = CreateWindow("TclSocket", "TclSocket",
WS_TILED, 0, 0, 0, 0, NULL, NULL, windowClass.hInstance, arg);
/*
@@ -2203,9 +2396,9 @@ SocketThread(
}
/*
- * Process all messages on the socket window until WM_QUIT. This threads
- * exits only when instructed to do so by the call to
- * PostMessage(SOCKET_TERMINATE) in TclpFinalizeSockets().
+ * Process all messages on the socket window until WM_QUIT.
+ * This threads exits only when instructed to do so by the
+ * call to PostMessage(SOCKET_TERMINATE) in TclpFinalizeSockets().
*/
while (GetMessage(&msg, NULL, 0, 0) > 0) {
@@ -2218,7 +2411,7 @@ SocketThread(
SetEvent(tsdPtr->readyEvent);
- return msg.wParam;
+ return (DWORD)msg.wParam;
}
@@ -2227,147 +2420,152 @@ SocketThread(
*
* SocketProc --
*
- * This function is called when WSAAsyncSelect has been used to register
- * interest in a socket event, and the event has occurred.
+ * This function is called when WSAAsyncSelect has been used
+ * to register interest in a socket event, and the event has
+ * occurred.
*
* Results:
* 0 on success.
*
* Side effects:
- * The flags for the given socket are updated to reflect the event that
- * occured.
+ * The flags for the given socket are updated to reflect the
+ * event that occured.
*
*----------------------------------------------------------------------
*/
static LRESULT CALLBACK
-SocketProc(
- HWND hwnd,
- UINT message,
- WPARAM wParam,
- LPARAM lParam)
+SocketProc(hwnd, message, wParam, lParam)
+ HWND hwnd;
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
{
int event, error;
SOCKET socket;
SocketInfo *infoPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr =
#ifdef _WIN64
- GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ (ThreadSpecificData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
#else
- GetWindowLong(hwnd, GWL_USERDATA);
+ (ThreadSpecificData *) GetWindowLong(hwnd, GWL_USERDATA);
#endif
switch (message) {
- default:
- return DefWindowProc(hwnd, message, wParam, lParam);
- break;
- case WM_CREATE:
- /*
- * Store the initial tsdPtr, it's from a different thread, so it's not
- * directly accessible, but needed.
- */
+ default:
+ return DefWindowProc(hwnd, message, wParam, lParam);
+ break;
+
+ case WM_CREATE:
+ /*
+ * store the initial tsdPtr, it's from a different thread, so it's
+ * not directly accessible, but needed.
+ */
#ifdef _WIN64
- SetWindowLongPtr(hwnd, GWLP_USERDATA,
- (LONG_PTR) ((LPCREATESTRUCT)lParam)->lpCreateParams);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA,
+ (LONG_PTR) ((LPCREATESTRUCT)lParam)->lpCreateParams);
#else
- SetWindowLong(hwnd, GWL_USERDATA,
- (LONG) ((LPCREATESTRUCT)lParam)->lpCreateParams);
+ SetWindowLong(hwnd, GWL_USERDATA,
+ (LONG) ((LPCREATESTRUCT)lParam)->lpCreateParams);
#endif
- break;
-
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
+ break;
- case SOCKET_MESSAGE:
- event = WSAGETSELECTEVENT(lParam);
- error = WSAGETSELECTERROR(lParam);
- socket = (SOCKET) wParam;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
- /*
- * Find the specified socket on the socket list and update its
- * eventState flag.
- */
+ case SOCKET_MESSAGE:
+ event = WSAGETSELECTEVENT(lParam);
+ error = WSAGETSELECTERROR(lParam);
+ socket = (SOCKET) wParam;
- WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
- for (infoPtr = tsdPtr->socketList; infoPtr != NULL;
- infoPtr = infoPtr->nextPtr) {
- if (infoPtr->socket == socket) {
- /*
- * Update the socket state.
- *
- * A count of FD_ACCEPTS is stored, so if an FD_CLOSE event
- * happens, then clear the FD_ACCEPT count. Otherwise,
- * increment the count if the current event is an FD_ACCEPT.
- */
-
- if (event & FD_CLOSE) {
- infoPtr->acceptEventCount = 0;
- infoPtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT);
- } else if (event & FD_ACCEPT) {
- infoPtr->acceptEventCount++;
- }
+ /*
+ * Find the specified socket on the socket list and update its
+ * eventState flag.
+ */
- if (event & FD_CONNECT) {
+ WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
+ for (infoPtr = tsdPtr->socketList; infoPtr != NULL;
+ infoPtr = infoPtr->nextPtr) {
+ if (infoPtr->socket == socket) {
/*
- * The socket is now connected, clear the async connect
- * flag.
+ * Update the socket state.
*/
- infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
-
/*
- * Remember any error that occurred so we can report
- * connection failures.
+ * A count of FD_ACCEPTS is stored, so if an FD_CLOSE
+ * event happens, then clear the FD_ACCEPT count.
+ * Otherwise, increment the count if the current
+ * event is an FD_ACCEPT.
*/
- if (error != ERROR_SUCCESS) {
- TclWinConvertWSAError((DWORD) error);
- infoPtr->lastError = Tcl_GetErrno();
+ if (event & FD_CLOSE) {
+ infoPtr->acceptEventCount = 0;
+ infoPtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT);
+ } else if (event & FD_ACCEPT) {
+ infoPtr->acceptEventCount++;
}
- }
- if (infoPtr->flags & SOCKET_ASYNC_CONNECT) {
- infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
- if (error != ERROR_SUCCESS) {
- TclWinConvertWSAError((DWORD) error);
- infoPtr->lastError = Tcl_GetErrno();
+ if (event & FD_CONNECT) {
+ /*
+ * The socket is now connected,
+ * clear the async connect flag.
+ */
+
+ infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
+
+ /*
+ * Remember any error that occurred so we can report
+ * connection failures.
+ */
+
+ if (error != ERROR_SUCCESS) {
+ TclWinConvertWSAError((DWORD) error);
+ infoPtr->lastError = Tcl_GetErrno();
+ }
+
+ }
+ if(infoPtr->flags & SOCKET_ASYNC_CONNECT) {
+ infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
+ if (error != ERROR_SUCCESS) {
+ TclWinConvertWSAError((DWORD) error);
+ infoPtr->lastError = Tcl_GetErrno();
+ }
+ infoPtr->readyEvents |= FD_WRITE;
}
- infoPtr->readyEvents |= FD_WRITE;
+ infoPtr->readyEvents |= event;
+
+ /*
+ * Wake up the Main Thread.
+ */
+ SetEvent(tsdPtr->readyEvent);
+ Tcl_ThreadAlert(tsdPtr->threadId);
+ break;
}
- infoPtr->readyEvents |= event;
+ }
+ SetEvent(tsdPtr->socketListLock);
+ break;
+
+ case SOCKET_SELECT:
+ infoPtr = (SocketInfo *) lParam;
+ if (wParam == SELECT) {
+ winSock.WSAAsyncSelect(infoPtr->socket, hwnd,
+ SOCKET_MESSAGE, infoPtr->selectEvents);
+ } else {
/*
- * Wake up the Main Thread.
+ * Clear the selection mask
*/
- SetEvent(tsdPtr->readyEvent);
- Tcl_ThreadAlert(tsdPtr->threadId);
- break;
+ winSock.WSAAsyncSelect(infoPtr->socket, hwnd, 0, 0);
}
- }
- SetEvent(tsdPtr->socketListLock);
- break;
-
- case SOCKET_SELECT:
- infoPtr = (SocketInfo *) lParam;
- if (wParam == SELECT) {
- WSAAsyncSelect(infoPtr->socket, hwnd,
- SOCKET_MESSAGE, infoPtr->selectEvents);
- } else {
- /*
- * Clear the selection mask
- */
-
- WSAAsyncSelect(infoPtr->socket, hwnd, 0, 0);
- }
- break;
+ break;
- case SOCKET_TERMINATE:
- DestroyWindow(hwnd);
- break;
+ case SOCKET_TERMINATE:
+ DestroyWindow(hwnd);
+ break;
}
return 0;
@@ -2381,82 +2579,49 @@ SocketProc(
* Returns the name of the local host.
*
* Results:
- * A string containing the network name for this machine. The caller must
- * not modify or free this string.
+ * A string containing the network name for this machine, or
+ * an empty string if we can't figure out the name. The caller
+ * must not modify or free this string.
*
* Side effects:
- * Caches the name to return for future calls.
- *
- *----------------------------------------------------------------------
- */
-
-const char *
-Tcl_GetHostName(void)
-{
- return Tcl_GetString(TclGetProcessGlobalValue(&hostName));
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * InitializeHostName --
- *
- * This routine sets the process global value of the name of the local
- * host on which the process is running.
- *
- * Results:
* None.
*
*----------------------------------------------------------------------
*/
-void
-InitializeHostName(
- char **valuePtr,
- int *lengthPtr,
- Tcl_Encoding *encodingPtr)
+CONST char *
+Tcl_GetHostName()
{
+ DWORD length;
WCHAR wbuf[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD length = sizeof(wbuf) / sizeof(WCHAR);
- Tcl_DString ds;
- if ((*tclWinProcs->getComputerNameProc)(wbuf, &length) != 0) {
+ Tcl_MutexLock(&socketMutex);
+ InitSockets();
+
+ if (!hostnameInitialized) {
/*
- * Convert string from native to UTF then change to lowercase.
+ * Convert hostname from native to UTF then change to lowercase.
*/
-
- Tcl_UtfToLower(Tcl_WinTCharToUtf((TCHAR *) wbuf, -1, &ds));
-
- } else {
- Tcl_DStringInit(&ds);
- if (TclpHasSockets(NULL) == TCL_OK) {
- /*
- * Buffer length of 255 copied slavishly from previous version of
- * this routine. Presumably there's a more "correct" macro value
- * for a properly sized buffer for a gethostname() call.
- * Maintainers are welcome to supply it.
- */
-
- Tcl_DString inDs;
-
- Tcl_DStringInit(&inDs);
- Tcl_DStringSetLength(&inDs, 255);
- if (gethostname(Tcl_DStringValue(&inDs),
- Tcl_DStringLength(&inDs)) == 0) {
- Tcl_DStringSetLength(&ds, 0);
- } else {
- Tcl_ExternalToUtfDString(NULL,
- Tcl_DStringValue(&inDs), -1, &ds);
- }
- Tcl_DStringFree(&inDs);
+ Tcl_DString ds;
+
+ length = sizeof(hostname);
+ /* same as SocketsEnabled without the socketMutex lock */
+ if ((winSock.hModule != NULL)
+ && (winSock.gethostname(hostname, length) == 0)) {
+ Tcl_ExternalToUtfDString(NULL, hostname, -1, &ds);
+ } else if ((*tclWinProcs->getComputerNameProc)(wbuf, &length) != 0) {
+ Tcl_WinTCharToUtf((TCHAR *) wbuf, -1, &ds);
+ } else {
+ Tcl_DStringInit(&ds);
+ Tcl_DStringSetLength(&ds, 0);
}
+ lstrcpynA(hostname, Tcl_DStringValue(&ds), sizeof(hostname));
+ Tcl_DStringFree(&ds);
+ Tcl_UtfToLower(hostname);
+ hostnameInitialized = 1;
}
-
- *encodingPtr = Tcl_GetEncoding(NULL, "utf-8");
- *lengthPtr = Tcl_DStringLength(&ds);
- *valuePtr = ckalloc((unsigned int) (*lengthPtr)+1);
- memcpy(*valuePtr, Tcl_DStringValue(&ds), (size_t)(*lengthPtr)+1);
- Tcl_DStringFree(&ds);
+ Tcl_MutexUnlock(&socketMutex);
+ return hostname;
}
/*
@@ -2464,10 +2629,10 @@ InitializeHostName(
*
* TclWinGetSockOpt, et al. --
*
- * These functions are wrappers that let us bind the WinSock API
- * dynamically so we can run on systems that don't have the wsock32.dll.
- * We need wrappers for these interfaces because they are called from the
- * generic Tcl code.
+ * These functions are wrappers that let us bind the WinSock
+ * API dynamically so we can run on systems that don't have
+ * the wsock32.dll. We need wrappers for these interfaces
+ * because they are called from the generic Tcl code.
*
* Results:
* As defined for each function.
@@ -2479,80 +2644,71 @@ InitializeHostName(
*/
int
-TclWinGetSockOpt(
- int s,
- int level,
- int optname,
- char * optval,
- int FAR *optlen)
+TclWinGetSockOpt(SOCKET s, int level, int optname, char * optval,
+ int FAR *optlen)
{
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
if (!SocketsEnabled()) {
- return SOCKET_ERROR;
+ return SOCKET_ERROR;
}
-
- return getsockopt((SOCKET)s, level, optname, optval, optlen);
+
+ return winSock.getsockopt(s, level, optname, optval, optlen);
}
int
-TclWinSetSockOpt(
- int s,
- int level,
- int optname,
- const char * optval,
- int optlen)
+TclWinSetSockOpt(SOCKET s, int level, int optname, const char * optval,
+ int optlen)
{
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
-
if (!SocketsEnabled()) {
- return SOCKET_ERROR;
+ return SOCKET_ERROR;
}
- return setsockopt((SOCKET)s, level, optname, optval, optlen);
+ return winSock.setsockopt(s, level, optname, optval, optlen);
}
u_short
-TclWinNToHS(
- u_short netshort)
+TclWinNToHS(u_short netshort)
{
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
if (!SocketsEnabled()) {
- return (u_short) -1;
+ return (u_short) -1;
}
- return ntohs(netshort);
+ return winSock.ntohs(netshort);
}
struct servent *
-TclWinGetServByName(
- const char *name,
- const char *proto)
+TclWinGetServByName(const char * name, const char * proto)
{
/*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
+ * Check that WinSock is initialized; do not call it if not, to
+ * prevent system crashes. This can happen at exit time if the exit
+ * handler for WinSock ran before other exit handlers that want to
+ * use sockets.
*/
-
if (!SocketsEnabled()) {
- return NULL;
+ return (struct servent *) NULL;
}
- return getservbyname(name, proto);
+ return winSock.getservbyname(name, proto);
}
/*
@@ -2572,21 +2728,21 @@ TclWinGetServByName(
*/
static void
-TcpThreadActionProc(
- ClientData instanceData,
- int action)
+TcpThreadActionProc (instanceData, action)
+ ClientData instanceData;
+ int action;
{
ThreadSpecificData *tsdPtr;
SocketInfo *infoPtr = (SocketInfo *) instanceData;
- int notifyCmd;
+ int notifyCmd;
if (action == TCL_CHANNEL_THREAD_INSERT) {
- /*
- * Ensure that socket subsystem is initialized in this thread, or else
- * sockets will not work.
+ /*
+ * Ensure that socket subsystem is initialized in this thread, or
+ * else sockets will not work.
*/
- Tcl_MutexLock(&socketMutex);
+ Tcl_MutexLock(&socketMutex);
InitSockets();
Tcl_MutexUnlock(&socketMutex);
@@ -2602,18 +2758,14 @@ TcpThreadActionProc(
SocketInfo **nextPtrPtr;
int removed = 0;
- tsdPtr = TCL_TSD_INIT(&dataKey);
-
- /*
- * TIP #218, Bugfix: All access to socketList has to be protected by
- * the lock.
- */
+ tsdPtr = TCL_TSD_INIT(&dataKey);
+ /* TIP #218, Bugfix: All access to socketList has to be protected by the lock */
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
for (nextPtrPtr = &(tsdPtr->socketList); (*nextPtrPtr) != NULL;
- nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
+ nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
if ((*nextPtrPtr) == infoPtr) {
- (*nextPtrPtr) = infoPtr->nextPtr;
+ (*nextPtrPtr) = infoPtr->nextPtr;
removed = 1;
break;
}
@@ -2621,9 +2773,9 @@ TcpThreadActionProc(
SetEvent(tsdPtr->socketListLock);
/*
- * This could happen if the channel was created in one thread and then
- * moved to another without updating the thread local data in each
- * thread.
+ * This could happen if the channel was created in one thread
+ * and then moved to another without updating the thread
+ * local data in each thread.
*/
if (!removed) {
@@ -2634,18 +2786,9 @@ TcpThreadActionProc(
}
/*
- * Ensure that, or stop, notifications for the socket occur in this
- * thread.
+ * Ensure that, or stop, notifications for the socket occur in this thread.
*/
SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
- (WPARAM) notifyCmd, (LPARAM) infoPtr);
+ (WPARAM) notifyCmd, (LPARAM) infoPtr);
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinTest.c b/win/tclWinTest.c
index d0bbb09..0ddd76b 100644
--- a/win/tclWinTest.c
+++ b/win/tclWinTest.c
@@ -1,15 +1,16 @@
-/*
+/*
* tclWinTest.c --
*
* Contains commands for platform specific tests on Windows.
*
* Copyright (c) 1996 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tclInt.h"
+#define USE_COMPAT_CONST
+#include "tclWinInt.h"
/*
* For TestplatformChmod on Windows
@@ -26,33 +27,40 @@
#endif
/*
- * Forward declarations of functions defined later in this file:
+ * Forward declarations of procedures defined later in this file:
*/
+int TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
+static int TesteventloopCmd _ANSI_ARGS_((ClientData dummy,
+ Tcl_Interp *interp, int argc, CONST84 char **argv));
+static int TestvolumetypeCmd _ANSI_ARGS_((ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]));
+static int TestwinclockCmd _ANSI_ARGS_(( ClientData dummy,
+ Tcl_Interp* interp,
+ int objc,
+ Tcl_Obj *CONST objv[] ));
+static int TestwinsleepCmd _ANSI_ARGS_(( ClientData dummy,
+ Tcl_Interp* interp,
+ int objc,
+ Tcl_Obj *CONST objv[] ));
+static Tcl_ObjCmdProc TestExceptionCmd;
+static int TestwincpuidCmd _ANSI_ARGS_(( ClientData dummy,
+ Tcl_Interp* interp,
+ int objc,
+ Tcl_Obj *CONST objv[] ));
+static int TestplatformChmod _ANSI_ARGS_((CONST char *nativePath,
+ int pmode));
+static int TestchmodCmd _ANSI_ARGS_((ClientData dummy,
+ Tcl_Interp *interp, int argc, CONST84 char **argv));
-int TclplatformtestInit(Tcl_Interp *interp);
-static int TesteventloopCmd(ClientData dummy, Tcl_Interp *interp,
- int argc, const char **argv);
-static int TestvolumetypeCmd(ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *const objv[]);
-static int TestwinclockCmd(ClientData dummy, Tcl_Interp* interp,
- int objc, Tcl_Obj *const objv[]);
-static int TestwinsleepCmd(ClientData dummy, Tcl_Interp* interp,
- int objc, Tcl_Obj *const objv[]);
-static Tcl_ObjCmdProc TestExceptionCmd;
-static int TestwincpuidCmd(ClientData dummy, Tcl_Interp* interp,
- int objc, Tcl_Obj *const objv[]);
-static int TestplatformChmod(const char *nativePath, int pmode);
-static int TestchmodCmd(ClientData dummy,
- Tcl_Interp *interp, int argc, const char **argv);
/*
*----------------------------------------------------------------------
*
* TclplatformtestInit --
*
- * Defines commands that test platform specific functionality for Windows
- * platforms.
+ * Defines commands that test platform specific functionality for
+ * Windows platforms.
*
* Results:
* A standard Tcl result.
@@ -64,21 +72,27 @@ static int TestchmodCmd(ClientData dummy,
*/
int
-TclplatformtestInit(
- Tcl_Interp *interp) /* Interpreter to add commands to. */
+TclplatformtestInit(interp)
+ Tcl_Interp *interp; /* Interpreter to add commands to. */
{
/*
* Add commands for platform specific tests for Windows here.
*/
- Tcl_CreateCommand(interp, "testchmod", TestchmodCmd, NULL, NULL);
- Tcl_CreateCommand(interp, "testeventloop", TesteventloopCmd, NULL, NULL);
+ Tcl_CreateCommand(interp, "testchmod", TestchmodCmd,
+ (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateCommand(interp, "testeventloop", TesteventloopCmd,
+ (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "testvolumetype", TestvolumetypeCmd,
- NULL, NULL);
- Tcl_CreateObjCommand(interp, "testwinclock", TestwinclockCmd, NULL, NULL);
- Tcl_CreateObjCommand(interp, "testwincpuid", TestwincpuidCmd, NULL, NULL);
- Tcl_CreateObjCommand(interp, "testwinsleep", TestwinsleepCmd, NULL, NULL);
- Tcl_CreateObjCommand(interp, "testexcept", TestExceptionCmd, NULL, NULL);
+ (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateObjCommand(interp, "testwinclock", TestwinclockCmd,
+ (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateObjCommand(interp, "testwincpuid", TestwincpuidCmd,
+ (ClientData) 0, (Tcl_CmdDeleteProc*) NULL );
+ Tcl_CreateObjCommand(interp, "testwinsleep", TestwinsleepCmd,
+ (ClientData) 0, (Tcl_CmdDeleteProc *) NULL );
+ Tcl_CreateObjCommand(interp, "testexcept", TestExceptionCmd,
+ (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
}
@@ -87,9 +101,9 @@ TclplatformtestInit(
*
* TesteventloopCmd --
*
- * This function implements the "testeventloop" command. It is used to
- * test the Tcl notifier from an "external" event loop (i.e. not
- * Tcl_DoOneEvent()).
+ * This procedure implements the "testeventloop" command. It is
+ * used to test the Tcl notifier from an "external" event loop
+ * (i.e. not Tcl_DoOneEvent()).
*
* Results:
* A standard Tcl result.
@@ -101,25 +115,27 @@ TclplatformtestInit(
*/
static int
-TesteventloopCmd(
- ClientData clientData, /* Not used. */
- Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+TesteventloopCmd(clientData, interp, argc, argv)
+ ClientData clientData; /* Not used. */
+ Tcl_Interp *interp; /* Current interpreter. */
+ int argc; /* Number of arguments. */
+ CONST84 char **argv; /* Argument strings. */
{
- static int *framePtr = NULL;/* Pointer to integer on stack frame of
- * innermost invocation of the "wait"
- * subcommand. */
+ static int *framePtr = NULL; /* Pointer to integer on stack frame of
+ * innermost invocation of the "wait"
+ * subcommand. */
- if (argc < 2) {
+ if (argc < 2) {
Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
- " option ... \"", NULL);
- return TCL_ERROR;
+ " option ... \"", (char *) NULL);
+ return TCL_ERROR;
}
if (strcmp(argv[1], "done") == 0) {
*framePtr = 1;
} else if (strcmp(argv[1], "wait") == 0) {
- int *oldFramePtr, done;
+ int *oldFramePtr;
+ int done;
+ MSG msg;
int oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
/*
@@ -130,21 +146,19 @@ TesteventloopCmd(
framePtr = &done;
/*
- * Enter a standard Windows event loop until the flag changes. Note
- * that we do not explicitly call Tcl_ServiceEvent().
+ * Enter a standard Windows event loop until the flag changes.
+ * Note that we do not explicitly call Tcl_ServiceEvent().
*/
done = 0;
while (!done) {
- MSG msg;
-
if (!GetMessage(&msg, NULL, 0, 0)) {
/*
- * The application is exiting, so repost the quit message and
- * start unwinding.
+ * The application is exiting, so repost the quit message
+ * and start unwinding.
*/
- PostQuitMessage((int) msg.wParam);
+ PostQuitMessage((int)msg.wParam);
break;
}
TranslateMessage(&msg);
@@ -154,7 +168,7 @@ TesteventloopCmd(
framePtr = oldFramePtr;
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
- "\": must be done or wait", NULL);
+ "\": must be done or wait", (char *) NULL);
return TCL_ERROR;
}
return TCL_OK;
@@ -165,8 +179,8 @@ TesteventloopCmd(
*
* Testvolumetype --
*
- * This function implements the "testvolumetype" command. It is used to
- * check the volume type (FAT, NTFS) of a volume.
+ * This procedure implements the "testvolumetype" command. It is
+ * used to check the volume type (FAT, NTFS) of a volume.
*
* Results:
* A standard Tcl result.
@@ -178,11 +192,11 @@ TesteventloopCmd(
*/
static int
-TestvolumetypeCmd(
- ClientData clientData, /* Not used. */
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
+TestvolumetypeCmd(clientData, interp, objc, objv)
+ ClientData clientData; /* Not used. */
+ Tcl_Interp *interp; /* Current interpreter. */
+ int objc; /* Number of arguments. */
+ Tcl_Obj *CONST objv[]; /* Argument objects. */
{
#define VOL_BUF_SIZE 32
int found;
@@ -191,24 +205,23 @@ TestvolumetypeCmd(
if (objc > 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?name?");
- return TCL_ERROR;
+ return TCL_ERROR;
}
if (objc == 2) {
/*
- * path has to be really a proper volume, but we don't get query APIs
- * for that until NT5
+ * path has to be really a proper volume, but we don't
+ * get query APIs for that until NT5
*/
-
path = Tcl_GetString(objv[1]);
} else {
path = NULL;
}
- found = GetVolumeInformationA(path, NULL, 0, NULL, NULL, NULL, volType,
- VOL_BUF_SIZE);
+ found = GetVolumeInformationA(path, NULL, 0, NULL, NULL,
+ NULL, volType, VOL_BUF_SIZE);
if (found == 0) {
Tcl_AppendResult(interp, "could not get volume type for \"",
- (path?path:""), "\"", NULL);
+ (path?path:""), "\"", (char *) NULL);
TclWinConvertError(GetLastError());
return TCL_ERROR;
}
@@ -222,9 +235,9 @@ TestvolumetypeCmd(
*
* TestwinclockCmd --
*
- * Command that returns the seconds and microseconds portions of the
- * system clock and of the Tcl clock so that they can be compared to
- * validate that the Tcl clock is staying in sync.
+ * Command that returns the seconds and microseconds portions of
+ * the system clock and of the Tcl clock so that they can be
+ * compared to validate that the Tcl clock is staying in sync.
*
* Usage:
* testclock
@@ -233,9 +246,9 @@ TestvolumetypeCmd(
* None.
*
* Results:
- * Returns a standard Tcl result comprising a four-element list: the
- * seconds and microseconds portions of the system clock, and the seconds
- * and microseconds portions of the Tcl clock.
+ * Returns a standard Tcl result comprising a four-element list:
+ * the seconds and microseconds portions of the system clock,
+ * and the seconds and microseconds portions of the Tcl clock.
*
* Side effects:
* None.
@@ -244,50 +257,54 @@ TestvolumetypeCmd(
*/
static int
-TestwinclockCmd(
- ClientData dummy, /* Unused */
- Tcl_Interp* interp, /* Tcl interpreter */
- int objc, /* Argument count */
- Tcl_Obj *const objv[]) /* Argument vector */
+TestwinclockCmd( ClientData dummy,
+ /* Unused */
+ Tcl_Interp* interp,
+ /* Tcl interpreter */
+ int objc,
+ /* Argument count */
+ Tcl_Obj *CONST objv[] )
+ /* Argument vector */
{
- static const FILETIME posixEpoch = { 0xD53E8000, 0x019DB1DE };
- /* The Posix epoch, expressed as a Windows
- * FILETIME */
+ static CONST FILETIME posixEpoch = { 0xD53E8000, 0x019DB1DE };
+ /* The Posix epoch, expressed as a
+ * Windows FILETIME */
Tcl_Time tclTime; /* Tcl clock */
FILETIME sysTime; /* System clock */
- Tcl_Obj *result; /* Result of the command */
+ Tcl_Obj* result; /* Result of the command */
LARGE_INTEGER t1, t2;
LARGE_INTEGER p1, p2;
- if (objc != 1) {
- Tcl_WrongNumArgs(interp, 1, objv, "");
+ if ( objc != 1 ) {
+ Tcl_WrongNumArgs( interp, 1, objv, "" );
return TCL_ERROR;
}
- QueryPerformanceCounter(&p1);
+ QueryPerformanceCounter( &p1 );
- Tcl_GetTime(&tclTime);
- GetSystemTimeAsFileTime(&sysTime);
+ Tcl_GetTime( &tclTime );
+ GetSystemTimeAsFileTime( &sysTime );
t1.LowPart = posixEpoch.dwLowDateTime;
t1.HighPart = posixEpoch.dwHighDateTime;
t2.LowPart = sysTime.dwLowDateTime;
t2.HighPart = sysTime.dwHighDateTime;
t2.QuadPart -= t1.QuadPart;
- QueryPerformanceCounter(&p2);
+ QueryPerformanceCounter( &p2 );
result = Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, result,
- Tcl_NewIntObj((int) (t2.QuadPart / 10000000)));
- Tcl_ListObjAppendElement(interp, result,
- Tcl_NewIntObj((int) ((t2.QuadPart / 10) % 1000000)));
- Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(tclTime.sec));
- Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(tclTime.usec));
+ Tcl_ListObjAppendElement
+ ( interp, result, Tcl_NewIntObj( (int) (t2.QuadPart / 10000000 ) ) );
+ Tcl_ListObjAppendElement
+ ( interp, result,
+ Tcl_NewIntObj( (int) ( (t2.QuadPart / 10 ) % 1000000 ) ) );
+ Tcl_ListObjAppendElement( interp, result, Tcl_NewIntObj( tclTime.sec ) );
+ Tcl_ListObjAppendElement( interp, result, Tcl_NewIntObj( tclTime.usec ) );
- Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(p1.QuadPart));
- Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(p2.QuadPart));
+ Tcl_ListObjAppendElement( interp, result, Tcl_NewWideIntObj( p1.QuadPart ) );
+ Tcl_ListObjAppendElement( interp, result, Tcl_NewWideIntObj( p2.QuadPart ) );
- Tcl_SetObjResult(interp, result);
+ Tcl_SetObjResult( interp, result );
return TCL_OK;
}
@@ -306,8 +323,8 @@ TestwinclockCmd(
* eax - The value to pass in the EAX register to a CPUID instruction.
*
* Results:
- * Returns a four-element list containing the values from the EAX, EBX,
- * ECX and EDX registers returned from the CPUID instruction.
+ * Returns a four-element list containing the values from the
+ * EAX, EBX, ECX and EDX registers returned from the CPUID instruction.
*
* Side effects:
* None.
@@ -316,34 +333,36 @@ TestwinclockCmd(
*/
static int
-TestwincpuidCmd(
- ClientData dummy,
- Tcl_Interp* interp, /* Tcl interpreter */
- int objc, /* Parameter count */
- Tcl_Obj *const * objv) /* Parameter vector */
+TestwincpuidCmd( ClientData dummy,
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj *CONST * objv ) /* Parameter vector */
{
- int status, index, i;
+ int status;
+ int index;
unsigned int regs[4];
- Tcl_Obj *regsObjs[4];
+ Tcl_Obj * regsObjs[4];
+ int i;
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "eax");
+ if ( objc != 2 ) {
+ Tcl_WrongNumArgs( interp, 1, objv, "eax" );
return TCL_ERROR;
}
- if (Tcl_GetIntFromObj(interp, objv[1], &index) != TCL_OK) {
+ if ( Tcl_GetIntFromObj( interp, objv[1], &index ) != TCL_OK ) {
return TCL_ERROR;
}
- status = TclWinCPUID((unsigned) index, regs);
- if (status != TCL_OK) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("operation not available", -1));
+ status = TclWinCPUID( (unsigned int) index, regs );
+ if ( status != TCL_OK ) {
+ Tcl_SetObjResult( interp, Tcl_NewStringObj( "operation not available",
+ -1 ) );
return status;
}
- for (i=0 ; i<4 ; ++i) {
- regsObjs[i] = Tcl_NewIntObj((int) regs[i]);
+ for ( i = 0; i < 4; ++i ) {
+ regsObjs[i] = Tcl_NewIntObj( (int) regs[i] );
}
- Tcl_SetObjResult(interp, Tcl_NewListObj(4, regsObjs));
+ Tcl_SetObjResult( interp, Tcl_NewListObj( 4, regsObjs ) );
return TCL_OK;
+
}
/*
@@ -351,8 +370,8 @@ TestwincpuidCmd(
*
* TestwinsleepCmd --
*
- * Causes this process to wait for the given number of milliseconds by
- * means of a direct call to Sleep.
+ * Causes this process to wait for the given number of milliseconds
+ * by means of a direct call to Sleep.
*
* Usage:
* testwinsleep <n>
@@ -370,22 +389,24 @@ TestwincpuidCmd(
*/
static int
-TestwinsleepCmd(
- ClientData clientData, /* Unused */
- Tcl_Interp* interp, /* Tcl interpreter */
- int objc, /* Parameter count */
- Tcl_Obj *const * objv) /* Parameter vector */
+TestwinsleepCmd( ClientData clientData,
+ /* Unused */
+ Tcl_Interp* interp,
+ /* Tcl interpreter */
+ int objc,
+ /* Parameter count */
+ Tcl_Obj * CONST * objv )
+ /* Parameter vector */
{
int ms;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "ms");
+ if ( objc != 2 ) {
+ Tcl_WrongNumArgs( interp, 1, objv, "ms" );
return TCL_ERROR;
}
- if (Tcl_GetIntFromObj(interp, objv[1], &ms) != TCL_OK) {
+ if ( Tcl_GetIntFromObj( interp, objv[1], &ms ) != TCL_OK ) {
return TCL_ERROR;
}
- Sleep((DWORD) ms);
+ Sleep( (DWORD) ms );
return TCL_OK;
}
@@ -394,8 +415,8 @@ TestwinsleepCmd(
*
* TestExceptionCmd --
*
- * Causes this process to end with the named exception. Used for testing
- * Tcl_WaitPid().
+ * Causes this process to end with the named exception. Used for
+ * testing Tcl_WaitPid().
*
* Usage:
* testexcept <type>
@@ -417,32 +438,58 @@ TestExceptionCmd(
ClientData dummy, /* Unused */
Tcl_Interp* interp, /* Tcl interpreter */
int objc, /* Argument count */
- Tcl_Obj *const objv[]) /* Argument vector */
+ Tcl_Obj *CONST objv[]) /* Argument vector */
{
- static const char *cmds[] = {
- "access_violation", "datatype_misalignment", "array_bounds",
- "float_denormal", "float_divbyzero", "float_inexact",
- "float_invalidop", "float_overflow", "float_stack", "float_underflow",
- "int_divbyzero", "int_overflow", "private_instruction", "inpageerror",
- "illegal_instruction", "noncontinue", "stack_overflow",
- "invalid_disp", "guard_page", "invalid_handle", "ctrl+c",
- NULL
+ static char *cmds[] = {
+ "access_violation",
+ "datatype_misalignment",
+ "array_bounds",
+ "float_denormal",
+ "float_divbyzero",
+ "float_inexact",
+ "float_invalidop",
+ "float_overflow",
+ "float_stack",
+ "float_underflow",
+ "int_divbyzero",
+ "int_overflow",
+ "private_instruction",
+ "inpageerror",
+ "illegal_instruction",
+ "noncontinue",
+ "stack_overflow",
+ "invalid_disp",
+ "guard_page",
+ "invalid_handle",
+ "ctrl+c",
+ NULL
};
static DWORD exceptions[] = {
- EXCEPTION_ACCESS_VIOLATION, EXCEPTION_DATATYPE_MISALIGNMENT,
- EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_FLT_DENORMAL_OPERAND,
- EXCEPTION_FLT_DIVIDE_BY_ZERO, EXCEPTION_FLT_INEXACT_RESULT,
- EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW,
- EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW,
- EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW,
- EXCEPTION_PRIV_INSTRUCTION, EXCEPTION_IN_PAGE_ERROR,
- EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_NONCONTINUABLE_EXCEPTION,
- EXCEPTION_STACK_OVERFLOW, EXCEPTION_INVALID_DISPOSITION,
- EXCEPTION_GUARD_PAGE, EXCEPTION_INVALID_HANDLE, CONTROL_C_EXIT
+ EXCEPTION_ACCESS_VIOLATION,
+ EXCEPTION_DATATYPE_MISALIGNMENT,
+ EXCEPTION_ARRAY_BOUNDS_EXCEEDED,
+ EXCEPTION_FLT_DENORMAL_OPERAND,
+ EXCEPTION_FLT_DIVIDE_BY_ZERO,
+ EXCEPTION_FLT_INEXACT_RESULT,
+ EXCEPTION_FLT_INVALID_OPERATION,
+ EXCEPTION_FLT_OVERFLOW,
+ EXCEPTION_FLT_STACK_CHECK,
+ EXCEPTION_FLT_UNDERFLOW,
+ EXCEPTION_INT_DIVIDE_BY_ZERO,
+ EXCEPTION_INT_OVERFLOW,
+ EXCEPTION_PRIV_INSTRUCTION,
+ EXCEPTION_IN_PAGE_ERROR,
+ EXCEPTION_ILLEGAL_INSTRUCTION,
+ EXCEPTION_NONCONTINUABLE_EXCEPTION,
+ EXCEPTION_STACK_OVERFLOW,
+ EXCEPTION_INVALID_DISPOSITION,
+ EXCEPTION_GUARD_PAGE,
+ EXCEPTION_INVALID_HANDLE,
+ CONTROL_C_EXIT
};
int cmd;
- if (objc != 2) {
+ if ( objc != 2 ) {
Tcl_WrongNumArgs(interp, 0, objv, "<type-of-exception>");
return TCL_ERROR;
}
@@ -471,307 +518,254 @@ TestExceptionCmd(
return TCL_OK;
}
-static int
-TestplatformChmod(
- const char *nativePath,
- int pmode)
+static int
+TestplatformChmod(CONST char *nativePath, int pmode)
{
- typedef DWORD (WINAPI *getSidLengthRequiredDef)(UCHAR);
- typedef BOOL (WINAPI *initializeSidDef)(PSID, PSID_IDENTIFIER_AUTHORITY,
- BYTE);
- typedef PDWORD (WINAPI *getSidSubAuthorityDef)(PSID, DWORD);
- typedef DWORD (WINAPI *setNamedSecurityInfoADef)(IN LPSTR,
- IN SE_OBJECT_TYPE, IN SECURITY_INFORMATION, IN PSID, IN PSID,
- IN PACL, IN PACL);
- typedef BOOL (WINAPI *getAceDef)(PACL, DWORD, LPVOID *);
- typedef BOOL (WINAPI *addAceDef)(PACL, DWORD, DWORD, LPVOID, DWORD);
- typedef BOOL (WINAPI *equalSidDef)(PSID, PSID);
- typedef BOOL (WINAPI *addAccessDeniedAceDef)(PACL, DWORD, DWORD, PSID);
- typedef BOOL (WINAPI *initializeAclDef)(PACL, DWORD, DWORD);
- typedef DWORD (WINAPI *getLengthSidDef)(PSID);
- typedef BOOL (WINAPI *getAclInformationDef)(PACL, LPVOID, DWORD,
- ACL_INFORMATION_CLASS);
- typedef BOOL (WINAPI *getSecurityDescriptorDaclDef)(PSECURITY_DESCRIPTOR,
- LPBOOL, PACL *, LPBOOL);
- typedef BOOL (WINAPI *lookupAccountNameADef)(LPCSTR, LPCSTR, PSID,
- PDWORD, LPSTR, LPDWORD, PSID_NAME_USE);
- typedef BOOL (WINAPI *getFileSecurityADef)(LPCSTR, SECURITY_INFORMATION,
- PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
-
- static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION
- | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
- static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE
- | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA
- | FILE_WRITE_DATA | DELETE;
+ SID_IDENTIFIER_AUTHORITY userSidAuthority =
+ { SECURITY_WORLD_SID_AUTHORITY };
- /*
- * References to security functions (only available on NT and later).
- */
+ typedef DWORD (WINAPI *getSidLengthRequiredDef) ( UCHAR );
+ typedef BOOL (WINAPI *initializeSidDef) ( PSID,
+ PSID_IDENTIFIER_AUTHORITY, BYTE );
+ typedef PDWORD (WINAPI *getSidSubAuthorityDef) ( PSID, DWORD );
static getSidLengthRequiredDef getSidLengthRequiredProc;
static initializeSidDef initializeSidProc;
static getSidSubAuthorityDef getSidSubAuthorityProc;
- static setNamedSecurityInfoADef setNamedSecurityInfoProc;
- static getAceDef getAceProc;
- static addAceDef addAceProc;
- static equalSidDef equalSidProc;
- static addAccessDeniedAceDef addAccessDeniedAceProc;
- static initializeAclDef initializeAclProc;
- static getLengthSidDef getLengthSidProc;
- static getAclInformationDef getAclInformationProc;
- static getSecurityDescriptorDaclDef getSecurityDescriptorDaclProc;
- static lookupAccountNameADef lookupAccountNameProc;
- static getFileSecurityADef getFileSecurityProc;
- static int initialized = 0;
+ static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION
+ | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
+ static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE
+ | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA
+ | FILE_WRITE_DATA | DELETE;
+
+ PSECURITY_DESCRIPTOR secDesc = 0;
+ DWORD secDescLen;
const BOOL set_readOnly = !(pmode & 0222);
- BOOL acl_readOnly_found = FALSE, curAclPresent, curAclDefaulted;
- SID_IDENTIFIER_AUTHORITY userSidAuthority = {
- SECURITY_WORLD_SID_AUTHORITY
- };
- BYTE *secDesc = 0;
- DWORD secDescLen, attr, newAclSize;
+ BOOL acl_readOnly_found = FALSE;
+
ACL_SIZE_INFORMATION ACLSize;
- PACL curAcl, newAcl = 0;
+ BOOL curAclPresent, curAclDefaulted;
+ PACL curAcl;
+ PACL newAcl = 0;
+ DWORD newAclSize;
+
WORD j;
+
SID *userSid = 0;
- TCHAR *userDomain = 0;
+ TCHAR *userDomain = NULL;
+
+ DWORD attr;
+
int res = 0;
/*
* One time initialization, dynamically load Windows NT features
*/
+ typedef DWORD (WINAPI *setNamedSecurityInfoADef)( IN LPSTR,
+ IN SE_OBJECT_TYPE, IN SECURITY_INFORMATION, IN PSID, IN PSID,
+ IN PACL, IN PACL );
+ typedef BOOL (WINAPI *getAceDef) (PACL, DWORD, LPVOID *);
+ typedef BOOL (WINAPI *addAceDef) ( PACL, DWORD, DWORD, LPVOID, DWORD );
+ typedef BOOL (WINAPI *equalSidDef) ( PSID, PSID );
+ typedef BOOL (WINAPI *addAccessDeniedAceDef) ( PACL, DWORD, DWORD, PSID );
+ typedef BOOL (WINAPI *initializeAclDef) ( PACL, DWORD, DWORD );
+ typedef DWORD (WINAPI *getLengthSidDef) ( PSID );
+ typedef BOOL (WINAPI *getAclInformationDef) (PACL, LPVOID, DWORD,
+ ACL_INFORMATION_CLASS );
+ typedef BOOL (WINAPI *getSecurityDescriptorDaclDef) (PSECURITY_DESCRIPTOR,
+ LPBOOL, PACL *, LPBOOL );
+ typedef BOOL (WINAPI *lookupAccountNameADef) ( LPCSTR, LPCSTR, PSID,
+ PDWORD, LPSTR, LPDWORD, PSID_NAME_USE );
+ typedef BOOL (WINAPI *getFileSecurityADef) ( LPCSTR, SECURITY_INFORMATION,
+ PSECURITY_DESCRIPTOR, DWORD, LPDWORD );
+ static setNamedSecurityInfoADef setNamedSecurityInfoProc;
+ static getAceDef getAceProc;
+ static addAceDef addAceProc;
+ static equalSidDef equalSidProc;
+ static addAccessDeniedAceDef addAccessDeniedAceProc;
+ static initializeAclDef initializeAclProc;
+ static getLengthSidDef getLengthSidProc;
+ static getAclInformationDef getAclInformationProc;
+ static getSecurityDescriptorDaclDef getSecurityDescriptorDaclProc;
+ static lookupAccountNameADef lookupAccountNameProc;
+ static getFileSecurityADef getFileSecurityProc;
+
+ static int initialized = 0;
if (!initialized) {
TCL_DECLARE_MUTEX(initializeMutex)
Tcl_MutexLock(&initializeMutex);
if (!initialized) {
HINSTANCE hInstance = LoadLibrary("Advapi32");
-
if (hInstance != NULL) {
setNamedSecurityInfoProc = (setNamedSecurityInfoADef)
- GetProcAddress(hInstance, "SetNamedSecurityInfoA");
+ GetProcAddress(hInstance, "SetNamedSecurityInfoA");
getFileSecurityProc = (getFileSecurityADef)
- GetProcAddress(hInstance, "GetFileSecurityA");
+ GetProcAddress(hInstance, "GetFileSecurityA");
getAceProc = (getAceDef)
- GetProcAddress(hInstance, "GetAce");
+ GetProcAddress(hInstance, "GetAce");
addAceProc = (addAceDef)
- GetProcAddress(hInstance, "AddAce");
+ GetProcAddress(hInstance, "AddAce");
equalSidProc = (equalSidDef)
- GetProcAddress(hInstance, "EqualSid");
+ GetProcAddress(hInstance, "EqualSid");
addAccessDeniedAceProc = (addAccessDeniedAceDef)
- GetProcAddress(hInstance, "AddAccessDeniedAce");
+ GetProcAddress(hInstance, "AddAccessDeniedAce");
initializeAclProc = (initializeAclDef)
- GetProcAddress(hInstance, "InitializeAcl");
+ GetProcAddress(hInstance, "InitializeAcl");
getLengthSidProc = (getLengthSidDef)
- GetProcAddress(hInstance, "GetLengthSid");
+ GetProcAddress(hInstance, "GetLengthSid");
getAclInformationProc = (getAclInformationDef)
- GetProcAddress(hInstance, "GetAclInformation");
+ GetProcAddress(hInstance, "GetAclInformation");
getSecurityDescriptorDaclProc = (getSecurityDescriptorDaclDef)
- GetProcAddress(hInstance, "GetSecurityDescriptorDacl");
+ GetProcAddress(hInstance, "GetSecurityDescriptorDacl");
lookupAccountNameProc = (lookupAccountNameADef)
- GetProcAddress(hInstance, "LookupAccountNameA");
+ GetProcAddress(hInstance, "LookupAccountNameA");
getSidLengthRequiredProc = (getSidLengthRequiredDef)
- GetProcAddress(hInstance, "GetSidLengthRequired");
+ GetProcAddress(hInstance, "GetSidLengthRequired");
initializeSidProc = (initializeSidDef)
- GetProcAddress(hInstance, "InitializeSid");
+ GetProcAddress(hInstance, "InitializeSid");
getSidSubAuthorityProc = (getSidSubAuthorityDef)
- GetProcAddress(hInstance, "GetSidSubAuthority");
-
- if (setNamedSecurityInfoProc && getAceProc && addAceProc
- && equalSidProc && addAccessDeniedAceProc
- && initializeAclProc && getLengthSidProc
- && getAclInformationProc
- && getSecurityDescriptorDaclProc
- && lookupAccountNameProc && getFileSecurityProc
- && getSidLengthRequiredProc && initializeSidProc
- && getSidSubAuthorityProc) {
+ GetProcAddress(hInstance, "GetSidSubAuthority");
+ if (setNamedSecurityInfoProc && getAceProc
+ && addAceProc && equalSidProc && addAccessDeniedAceProc
+ && initializeAclProc && getLengthSidProc
+ && getAclInformationProc && getSecurityDescriptorDaclProc
+ && lookupAccountNameProc && getFileSecurityProc
+ && getSidLengthRequiredProc && initializeSidProc
+ && getSidSubAuthorityProc)
initialized = 1;
- }
}
- if (!initialized) {
+ if (!initialized)
initialized = -1;
- }
}
Tcl_MutexUnlock(&initializeMutex);
}
- /*
- * Process the chmod request.
- */
-
+ /* Process the chmod request */
attr = GetFileAttributes(nativePath);
- /*
- * nativePath not found
- */
-
+ /* nativePath not found */
if (attr == 0xffffffff) {
res = -1;
goto done;
}
- /*
- * If no ACL API is present or nativePath is not a directory, there is no
- * special handling.
+ /* If no ACL API is present or nativePath is not a directory,
+ * there is no special handling
*/
-
if (initialized < 0 || !(attr & FILE_ATTRIBUTE_DIRECTORY)) {
goto done;
}
-
- /*
- * Set the result to error, if the ACL change is successful it will be
- * reset to 0.
+
+ /* Set the result to error, if the ACL change is successful it will
+ * be reset to 0
*/
-
res = -1;
/*
- * Read the security descriptor for the directory. Note the first call
- * obtains the size of the security descriptor.
+ * Read the security descriptor for the directory. Note the
+ * first call obtains the size of the security descriptor.
*/
-
if (!getFileSecurityProc(nativePath, infoBits, NULL, 0, &secDescLen)) {
- DWORD secDescLen2 = 0;
-
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
- goto done;
- }
-
- secDesc = (BYTE *) ckalloc(secDescLen);
- if (!getFileSecurityProc(nativePath, infoBits,
- (PSECURITY_DESCRIPTOR) secDesc, secDescLen, &secDescLen2)
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ DWORD secDescLen2 = 0;
+ secDesc = (PSECURITY_DESCRIPTOR) ckalloc(secDescLen);
+ if (!getFileSecurityProc(nativePath, infoBits, secDesc,
+ secDescLen, &secDescLen2)
|| (secDescLen < secDescLen2)) {
+ goto done;
+ }
+ } else {
goto done;
}
}
- /*
- * Get the World SID.
- */
-
- userSid = (SID *) ckalloc(getSidLengthRequiredProc((UCHAR) 1));
- initializeSidProc(userSid, &userSidAuthority, (BYTE) 1);
- *(getSidSubAuthorityProc(userSid, 0)) = SECURITY_WORLD_RID;
-
- /*
- * If curAclPresent == false then curAcl and curAclDefaulted not valid.
- */
+ /* Get the World SID */
+ userSid = (SID*) ckalloc(getSidLengthRequiredProc((UCHAR)1));
+ initializeSidProc( userSid, &userSidAuthority, (BYTE)1);
+ *(getSidSubAuthorityProc( userSid, 0)) = SECURITY_WORLD_RID;
- if (!getSecurityDescriptorDaclProc((PSECURITY_DESCRIPTOR) secDesc,
- &curAclPresent, &curAcl, &curAclDefaulted)) {
+ /* If curAclPresent == false then curAcl and curAclDefaulted not valid */
+ if (!getSecurityDescriptorDaclProc(secDesc, &curAclPresent,
+ &curAcl, &curAclDefaulted))
goto done;
- }
+
if (!curAclPresent || !curAcl) {
ACLSize.AclBytesInUse = 0;
ACLSize.AceCount = 0;
- } else if (!getAclInformationProc(curAcl, &ACLSize, sizeof(ACLSize),
- AclSizeInformation)) {
+ } else if (!getAclInformationProc(curAcl, &ACLSize, sizeof(ACLSize),
+ AclSizeInformation))
goto done;
- }
- /*
- * Allocate memory for the new ACL.
- */
-
- newAclSize = ACLSize.AclBytesInUse + sizeof(ACCESS_DENIED_ACE)
- + getLengthSidProc(userSid) - sizeof(DWORD);
- newAcl = (ACL *) ckalloc(newAclSize);
-
- /*
- * Initialize the new ACL.
- */
-
- if (!initializeAclProc(newAcl, newAclSize, ACL_REVISION)) {
+ /* Allocate memory for the new ACL */
+ newAclSize = ACLSize.AclBytesInUse + sizeof (ACCESS_DENIED_ACE)
+ + getLengthSidProc(userSid) - sizeof (DWORD);
+ newAcl = (ACL *) ckalloc (newAclSize);
+
+ /* Initialize the new ACL */
+ if(!initializeAclProc(newAcl, newAclSize, ACL_REVISION)) {
goto done;
}
-
- /*
- * Add denied to make readonly, this will be known as a "read-only tag".
- */
-
- if (set_readOnly && !addAccessDeniedAceProc(newAcl, ACL_REVISION,
- readOnlyMask, userSid)) {
+
+ /* Add denied to make readonly, this will be known as a "read-only tag" */
+ if (set_readOnly && !addAccessDeniedAceProc(newAcl, ACL_REVISION,
+ readOnlyMask, userSid)) {
goto done;
}
-
+
acl_readOnly_found = FALSE;
for (j = 0; j < ACLSize.AceCount; j++) {
- LPVOID pACE2;
+ PACL *pACE2;
ACE_HEADER *phACE2;
-
- if (!getAceProc(curAcl, j, &pACE2)) {
+ if (! getAceProc (curAcl, j, (LPVOID*) &pACE2)) {
goto done;
}
+
+ phACE2 = ((ACE_HEADER *) pACE2);
- phACE2 = (ACE_HEADER *) pACE2;
-
- /*
- * Do NOT propagate inherited ACEs.
- */
-
+ /* Do NOT propagate inherited ACEs */
if (phACE2->AceFlags & INHERITED_ACE) {
continue;
}
-
- /*
- * Skip the "read-only tag" restriction (either added above, or it is
- * being removed).
+
+ /* Skip the "read-only tag" restriction (either added above, or it
+ * is being removed)
*/
-
if (phACE2->AceType == ACCESS_DENIED_ACE_TYPE) {
- ACCESS_DENIED_ACE *pACEd = (ACCESS_DENIED_ACE *) phACE2;
-
- if (pACEd->Mask == readOnlyMask
- && equalSidProc(userSid, (PSID) &pACEd->SidStart)) {
+ ACCESS_DENIED_ACE *pACEd = (ACCESS_DENIED_ACE *)phACE2;
+ if (pACEd->Mask == readOnlyMask && equalSidProc(userSid,
+ (PSID)&(pACEd->SidStart))) {
acl_readOnly_found = TRUE;
continue;
}
}
- /*
- * Copy the current ACE from the old to the new ACL.
- */
-
- if (!addAceProc(newAcl, ACL_REVISION, MAXDWORD, (PACL *)pACE2,
- ((PACE_HEADER) pACE2)->AceSize)) {
+ /* Copy the current ACE from the old to the new ACL */
+ if(! addAceProc (newAcl, ACL_REVISION, MAXDWORD, pACE2,
+ ((PACE_HEADER) pACE2)->AceSize)) {
goto done;
}
}
- /*
- * Apply the new ACL.
- */
-
- if (set_readOnly == acl_readOnly_found || setNamedSecurityInfoProc(
- (LPSTR) nativePath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
- NULL, NULL, newAcl, NULL) == ERROR_SUCCESS) {
+ /* Apply the new ACL */
+ if (set_readOnly == acl_readOnly_found
+ || setNamedSecurityInfoProc((LPSTR)nativePath, SE_FILE_OBJECT,
+ DACL_SECURITY_INFORMATION, NULL, NULL, newAcl, NULL)
+ == ERROR_SUCCESS ) {
res = 0;
}
- done:
- if (secDesc) {
- ckfree((char *) secDesc);
- }
- if (newAcl) {
- ckfree((char *) newAcl);
- }
- if (userSid) {
- ckfree((char *) userSid);
- }
- if (userDomain) {
- ckfree(userDomain);
- }
+ done:
+ if (secDesc) ckfree((char *)secDesc);
+ if (newAcl) ckfree((char *)newAcl);
+ if (userSid) ckfree((char *)userSid);
+ if (userDomain) ckfree(userDomain);
- if (res != 0) {
+ if (res != 0)
return res;
- }
-
- /*
- * Run normal chmod command.
- */
-
+
+ /* Run normal chmod command */
return chmod(nativePath, pmode);
}
@@ -780,10 +774,10 @@ TestplatformChmod(
*
* TestchmodCmd --
*
- * Implements the "testchmod" cmd. Used when testing "file" command. The
- * only attribute used by the Windows platform is the user write flag; if
- * this is not set, the file is made read-only. Otherwise, the file is
- * made read-write.
+ * Implements the "testchmod" cmd. Used when testing "file" command.
+ * The only attribute used by the Windows platform is the user write
+ * flag; if this is not set, the file is made read-only. Otehrwise, the
+ * file is made read-write.
*
* Results:
* A standard Tcl result.
@@ -795,17 +789,17 @@ TestplatformChmod(
*/
static int
-TestchmodCmd(
- ClientData dummy, /* Not used. */
- Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+TestchmodCmd(dummy, interp, argc, argv)
+ ClientData dummy; /* Not used. */
+ Tcl_Interp *interp; /* Current interpreter. */
+ int argc; /* Number of arguments. */
+ CONST84 char **argv; /* Argument strings. */
{
int i, mode;
char *rest;
if (argc < 2) {
- usage:
+ usage:
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
" mode file ?file ...?", NULL);
return TCL_ERROR;
@@ -818,7 +812,7 @@ TestchmodCmd(
for (i = 2; i < argc; i++) {
Tcl_DString buffer;
- const char *translated;
+ CONST char *translated;
translated = Tcl_TranslateFileName(interp, argv[i], &buffer);
if (translated == NULL) {
@@ -833,11 +827,3 @@ TestchmodCmd(
}
return TCL_OK;
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c
index 8544e71..13fd411 100644
--- a/win/tclWinThrd.c
+++ b/win/tclWinThrd.c
@@ -1,4 +1,4 @@
-/*
+/*
* tclWinThread.c --
*
* This file implements the Windows-specific thread operations.
@@ -6,23 +6,25 @@
* Copyright (c) 1998 by Sun Microsystems, Inc.
* Copyright (c) 1999 by Scriptics Corporation
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclWinInt.h"
+#include <fcntl.h>
+#include <io.h>
#include <sys/stat.h>
/*
- * This is the master lock used to serialize access to other serialization
- * data structures.
+ * This is the master lock used to serialize access to other
+ * serialization data structures.
*/
static CRITICAL_SECTION masterLock;
static int init = 0;
-#define MASTER_LOCK TclpMasterLock()
-#define MASTER_UNLOCK TclpMasterUnlock()
+#define MASTER_LOCK TclpMasterLock()
+#define MASTER_UNLOCK TclpMasterUnlock()
/*
@@ -33,39 +35,38 @@ static int init = 0;
static CRITICAL_SECTION initLock;
/*
- * allocLock is used by Tcl's version of malloc for synchronization. For
- * obvious reasons, cannot use any dyamically allocated storage.
+ * allocLock is used by Tcl's version of malloc for synchronization.
+ * For obvious reasons, cannot use any dyamically allocated storage.
*/
#ifdef TCL_THREADS
-static struct Tcl_Mutex_ {
- CRITICAL_SECTION crit;
-} allocLock;
-static Tcl_Mutex allocLockPtr = &allocLock;
+static CRITICAL_SECTION allocLock;
+static Tcl_Mutex allocLockPtr = (Tcl_Mutex) &allocLock;
static int allocOnce = 0;
#endif /* TCL_THREADS */
/*
* The joinLock serializes Create- and ExitThread. This is necessary to
- * prevent a race where a new joinable thread exits before the creating thread
- * had the time to create the necessary data structures in the emulation
- * layer.
+ * prevent a race where a new joinable thread exits before the creating
+ * thread had the time to create the necessary data structures in the
+ * emulation layer.
*/
static CRITICAL_SECTION joinLock;
/*
- * Condition variables are implemented with a combination of a per-thread
- * Windows Event and a per-condition waiting queue. The idea is that each
- * thread has its own Event that it waits on when it is doing a ConditionWait;
- * it uses the same event for all condition variables because it only waits on
- * one at a time. Each condition variable has a queue of waiting threads, and
- * a mutex used to serialize access to this queue.
- *
- * Special thanks to David Nichols and Jim Davidson for advice on the
- * Condition Variable implementation.
+ * Condition variables are implemented with a combination of a
+ * per-thread Windows Event and a per-condition waiting queue.
+ * The idea is that each thread has its own Event that it waits
+ * on when it is doing a ConditionWait; it uses the same event for
+ * all condition variables because it only waits on one at a time.
+ * Each condition variable has a queue of waiting threads, and a
+ * mutex used to serialize access to this queue.
+ *
+ * Special thanks to David Nichols and
+ * Jim Davidson for advice on the Condition Variable implementation.
*/
/*
@@ -85,42 +86,42 @@ static Tcl_ThreadDataKey dataKey;
#endif /* TCL_THREADS */
/*
+ * Additions by AOL for specialized thread memory allocator.
+ */
+
+#if defined(USE_THREAD_ALLOC) && !defined(TCL_MEM_DEBUG)
+static int once;
+static DWORD tlsKey;
+
+typedef struct allocMutex {
+ Tcl_Mutex tlock;
+ CRITICAL_SECTION wlock;
+} allocMutex;
+#endif
+
+/*
* State bits for the thread.
- * WIN_THREAD_UNINIT Uninitialized. Must be zero because of the way
- * ThreadSpecificData is created.
+ * WIN_THREAD_UNINIT Uninitialized. Must be zero because
+ * of the way ThreadSpecificData is created.
* WIN_THREAD_RUNNING Running, not waiting.
* WIN_THREAD_BLOCKED Waiting, or trying to wait.
- */
+ */
#define WIN_THREAD_UNINIT 0x0
#define WIN_THREAD_RUNNING 0x1
#define WIN_THREAD_BLOCKED 0x2
/*
- * The per condition queue pointers and the Mutex used to serialize access to
- * the queue.
+ * The per condition queue pointers and the
+ * Mutex used to serialize access to the queue.
*/
typedef struct WinCondition {
- CRITICAL_SECTION condLock; /* Lock to serialize queuing on the
- * condition. */
+ CRITICAL_SECTION condLock; /* Lock to serialize queuing on the condition */
struct ThreadSpecificData *firstPtr; /* Queue pointers */
struct ThreadSpecificData *lastPtr;
} WinCondition;
-/*
- * Additions by AOL for specialized thread memory allocator.
- */
-
-#ifdef USE_THREAD_ALLOC
-static int once;
-static DWORD tlsKey;
-
-typedef struct allocMutex {
- Tcl_Mutex tlock;
- CRITICAL_SECTION wlock;
-} allocMutex;
-#endif /* USE_THREAD_ALLOC */
/*
*----------------------------------------------------------------------
@@ -130,8 +131,8 @@ typedef struct allocMutex {
* This procedure creates a new thread.
*
* Results:
- * TCL_OK if the thread could be created. The thread ID is returned in a
- * parameter.
+ * TCL_OK if the thread could be created. The thread ID is
+ * returned in a parameter.
*
* Side effects:
* A new thread is created.
@@ -140,25 +141,21 @@ typedef struct allocMutex {
*/
int
-TclpThreadCreate(
- Tcl_ThreadId *idPtr, /* Return, the ID of the thread. */
- Tcl_ThreadCreateProc proc, /* Main() function of the thread. */
- ClientData clientData, /* The one argument to Main(). */
- int stackSize, /* Size of stack for the new thread. */
- int flags) /* Flags controlling behaviour of the new
- * thread. */
+TclpThreadCreate(idPtr, proc, clientData, stackSize, flags)
+ Tcl_ThreadId *idPtr; /* Return, the ID of the thread */
+ Tcl_ThreadCreateProc proc; /* Main() function of the thread */
+ ClientData clientData; /* The one argument to Main() */
+ int stackSize; /* Size of stack for the new thread */
+ int flags; /* Flags controlling behaviour of
+ * the new thread */
{
HANDLE tHandle;
EnterCriticalSection(&joinLock);
- *idPtr = 0; /* must initialize as Tcl_Thread is a pointer and
- * on WIN64 sizeof void* != sizeof unsigned
- */
-
#if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__)
tHandle = (HANDLE) _beginthreadex(NULL, (unsigned) stackSize, proc,
- clientData, 0, (unsigned *)idPtr);
+ clientData, 0, (unsigned *)idPtr);
#else
tHandle = CreateThread(NULL, (DWORD) stackSize,
(LPTHREAD_START_ROUTINE) proc, (LPVOID) clientData,
@@ -166,11 +163,11 @@ TclpThreadCreate(
#endif
if (tHandle == NULL) {
- LeaveCriticalSection(&joinLock);
+ LeaveCriticalSection(&joinLock);
return TCL_ERROR;
} else {
- if (flags & TCL_THREAD_JOINABLE) {
- TclRememberJoinableThread(*idPtr);
+ if (flags & TCL_THREAD_JOINABLE) {
+ TclRememberJoinableThread (*idPtr);
}
/*
@@ -202,12 +199,13 @@ TclpThreadCreate(
*/
int
-Tcl_JoinThread(
- Tcl_ThreadId threadId, /* Id of the thread to wait upon */
- int *result) /* Reference to the storage the result of the
- * thread we wait upon will be written into. */
+Tcl_JoinThread(threadId, result)
+ Tcl_ThreadId threadId; /* Id of the thread to wait upon */
+ int* result; /* Reference to the storage the result
+ * of the thread we wait upon will be
+ * written into. */
{
- return TclJoinThread(threadId, result);
+ return TclJoinThread (threadId, result);
}
/*
@@ -227,11 +225,11 @@ Tcl_JoinThread(
*/
void
-TclpThreadExit(
- int status)
+TclpThreadExit(status)
+ int status;
{
EnterCriticalSection(&joinLock);
- TclSignalExitThread(Tcl_GetCurrentThread(), status);
+ TclSignalExitThread (Tcl_GetCurrentThread (), status);
LeaveCriticalSection(&joinLock);
#if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__)
@@ -258,9 +256,9 @@ TclpThreadExit(
*/
Tcl_ThreadId
-Tcl_GetCurrentThread(void)
+Tcl_GetCurrentThread()
{
- return (Tcl_ThreadId) INT2PTR(GetCurrentThreadId());
+ return (Tcl_ThreadId)GetCurrentThreadId();
}
/*
@@ -269,9 +267,9 @@ Tcl_GetCurrentThread(void)
* TclpInitLock
*
* This procedure is used to grab a lock that serializes initialization
- * and finalization of Tcl. On some platforms this may also initialize
- * the mutex used to serialize creation of more mutexes and thread local
- * storage keys.
+ * and finalization of Tcl. On some platforms this may also initialize
+ * the mutex used to serialize creation of more mutexes and thread
+ * local storage keys.
*
* Results:
* None.
@@ -283,16 +281,15 @@ Tcl_GetCurrentThread(void)
*/
void
-TclpInitLock(void)
+TclpInitLock()
{
if (!init) {
/*
- * There is a fundamental race here that is solved by creating the
- * first Tcl interpreter in a single threaded environment. Once the
- * interpreter has been created, it is safe to create more threads
- * that create interpreters in parallel.
+ * There is a fundamental race here that is solved by creating
+ * the first Tcl interpreter in a single threaded environment.
+ * Once the interpreter has been created, it is safe to create
+ * more threads that create interpreters in parallel.
*/
-
init = 1;
InitializeCriticalSection(&joinLock);
InitializeCriticalSection(&initLock);
@@ -306,8 +303,8 @@ TclpInitLock(void)
*
* TclpInitUnlock
*
- * This procedure is used to release a lock that serializes
- * initialization and finalization of Tcl.
+ * This procedure is used to release a lock that serializes initialization
+ * and finalization of Tcl.
*
* Results:
* None.
@@ -319,7 +316,7 @@ TclpInitLock(void)
*/
void
-TclpInitUnlock(void)
+TclpInitUnlock()
{
LeaveCriticalSection(&initLock);
}
@@ -329,11 +326,11 @@ TclpInitUnlock(void)
*
* TclpMasterLock
*
- * This procedure is used to grab a lock that serializes creation of
- * mutexes, condition variables, and thread local storage keys.
+ * This procedure is used to grab a lock that serializes creation
+ * of mutexes, condition variables, and thread local storage keys.
*
- * This lock must be different than the initLock because the initLock is
- * held during creation of syncronization objects.
+ * This lock must be different than the initLock because the
+ * initLock is held during creation of syncronization objects.
*
* Results:
* None.
@@ -345,16 +342,15 @@ TclpInitUnlock(void)
*/
void
-TclpMasterLock(void)
+TclpMasterLock()
{
if (!init) {
/*
- * There is a fundamental race here that is solved by creating the
- * first Tcl interpreter in a single threaded environment. Once the
- * interpreter has been created, it is safe to create more threads
- * that create interpreters in parallel.
+ * There is a fundamental race here that is solved by creating
+ * the first Tcl interpreter in a single threaded environment.
+ * Once the interpreter has been created, it is safe to create
+ * more threads that create interpreters in parallel.
*/
-
init = 1;
InitializeCriticalSection(&joinLock);
InitializeCriticalSection(&initLock);
@@ -368,8 +364,8 @@ TclpMasterLock(void)
*
* TclpMasterUnlock
*
- * This procedure is used to release a lock that serializes creation and
- * deletion of synchronization objects.
+ * This procedure is used to release a lock that serializes creation
+ * and deletion of synchronization objects.
*
* Results:
* None.
@@ -381,7 +377,7 @@ TclpMasterLock(void)
*/
void
-TclpMasterUnlock(void)
+TclpMasterUnlock()
{
LeaveCriticalSection(&masterLock);
}
@@ -391,13 +387,13 @@ TclpMasterUnlock(void)
*
* Tcl_GetAllocMutex
*
- * This procedure returns a pointer to a statically initialized mutex for
- * use by the memory allocator. The alloctor must use this lock, because
- * all other locks are allocated...
+ * This procedure returns a pointer to a statically initialized
+ * mutex for use by the memory allocator. The alloctor must
+ * use this lock, because all other locks are allocated...
*
* Results:
- * A pointer to a mutex that is suitable for passing to Tcl_MutexLock and
- * Tcl_MutexUnlock.
+ * A pointer to a mutex that is suitable for passing to
+ * Tcl_MutexLock and Tcl_MutexUnlock.
*
* Side effects:
* None.
@@ -406,11 +402,11 @@ TclpMasterUnlock(void)
*/
Tcl_Mutex *
-Tcl_GetAllocMutex(void)
+Tcl_GetAllocMutex()
{
#ifdef TCL_THREADS
if (!allocOnce) {
- InitializeCriticalSection(&allocLock.crit);
+ InitializeCriticalSection(&allocLock);
allocOnce = 1;
}
return &allocLockPtr;
@@ -424,85 +420,74 @@ Tcl_GetAllocMutex(void)
*
* TclpFinalizeLock
*
- * This procedure is used to destroy all private resources used in this
- * file.
+ * This procedure is used to destroy all private resources used in
+ * this file.
*
* Results:
* None.
*
* Side effects:
- * Destroys everything private. TclpInitLock must be held entering this
- * function.
+ * Destroys everything private. TclpInitLock must be held
+ * entering this function.
*
*----------------------------------------------------------------------
*/
void
-TclFinalizeLock(void)
+TclFinalizeLock ()
{
MASTER_LOCK;
DeleteCriticalSection(&joinLock);
-
- /*
- * Destroy the critical section that we are holding!
- */
-
+ /* Destroy the critical section that we are holding! */
DeleteCriticalSection(&masterLock);
init = 0;
-
#ifdef TCL_THREADS
- if (allocOnce) {
- DeleteCriticalSection(&allocLock.crit);
- allocOnce = 0;
- }
+ DeleteCriticalSection(&allocLock);
+ allocOnce = 0;
#endif
-
- LeaveCriticalSection(&initLock);
-
- /*
- * Destroy the critical section that we were holding.
- */
-
+ /* Destroy the critical section that we are holding! */
DeleteCriticalSection(&initLock);
}
#ifdef TCL_THREADS
/* locally used prototype */
-static void FinalizeConditionEvent(ClientData data);
+static void FinalizeConditionEvent(ClientData data);
+
/*
*----------------------------------------------------------------------
*
* Tcl_MutexLock --
*
- * This procedure is invoked to lock a mutex. This is a self initializing
- * mutex that is automatically finalized during Tcl_Finalize.
+ * This procedure is invoked to lock a mutex. This is a self
+ * initializing mutex that is automatically finalized during
+ * Tcl_Finalize.
*
* Results:
* None.
*
* Side effects:
- * May block the current thread. The mutex is aquired when this returns.
+ * May block the current thread. The mutex is aquired when
+ * this returns.
*
*----------------------------------------------------------------------
*/
void
-Tcl_MutexLock(
- Tcl_Mutex *mutexPtr) /* The lock */
+Tcl_MutexLock(mutexPtr)
+ Tcl_Mutex *mutexPtr; /* The lock */
{
CRITICAL_SECTION *csPtr;
-
if (*mutexPtr == NULL) {
MASTER_LOCK;
- /*
+ /*
* Double inside master lock check to avoid a race.
*/
if (*mutexPtr == NULL) {
- csPtr = (CRITICAL_SECTION *) ckalloc(sizeof(CRITICAL_SECTION));
+ csPtr = (CRITICAL_SECTION *)ckalloc(sizeof(CRITICAL_SECTION));
InitializeCriticalSection(csPtr);
*mutexPtr = (Tcl_Mutex)csPtr;
TclRememberMutex(mutexPtr);
@@ -530,11 +515,10 @@ Tcl_MutexLock(
*/
void
-Tcl_MutexUnlock(
- Tcl_Mutex *mutexPtr) /* The lock */
+Tcl_MutexUnlock(mutexPtr)
+ Tcl_Mutex *mutexPtr; /* The lock */
{
CRITICAL_SECTION *csPtr = *((CRITICAL_SECTION **)mutexPtr);
-
LeaveCriticalSection(csPtr);
}
@@ -543,8 +527,8 @@ Tcl_MutexUnlock(
*
* TclpFinalizeMutex --
*
- * This procedure is invoked to clean up one mutex. This is only safe to
- * call at the end of time.
+ * This procedure is invoked to clean up one mutex. This is only
+ * safe to call at the end of time.
*
* Results:
* None.
@@ -556,14 +540,13 @@ Tcl_MutexUnlock(
*/
void
-TclpFinalizeMutex(
- Tcl_Mutex *mutexPtr)
+TclpFinalizeMutex(mutexPtr)
+ Tcl_Mutex *mutexPtr;
{
CRITICAL_SECTION *csPtr = *(CRITICAL_SECTION **)mutexPtr;
-
if (csPtr != NULL) {
DeleteCriticalSection(csPtr);
- ckfree((char *) csPtr);
+ ckfree((char *)csPtr);
*mutexPtr = NULL;
}
}
@@ -571,11 +554,210 @@ TclpFinalizeMutex(
/*
*----------------------------------------------------------------------
*
+ * TclpThreadDataKeyInit --
+ *
+ * This procedure initializes a thread specific data block key.
+ * Each thread has table of pointers to thread specific data.
+ * all threads agree on which table entry is used by each module.
+ * this is remembered in a "data key", that is just an index into
+ * this table. To allow self initialization, the interface
+ * passes a pointer to this key and the first thread to use
+ * the key fills in the pointer to the key. The key should be
+ * a process-wide static.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Will allocate memory the first time this process calls for
+ * this key. In this case it modifies its argument
+ * to hold the pointer to information about the key.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpThreadDataKeyInit(keyPtr)
+ Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk,
+ * really (DWORD **) */
+{
+ DWORD *indexPtr;
+ DWORD newKey;
+
+ MASTER_LOCK;
+ if (*keyPtr == NULL) {
+ indexPtr = (DWORD *)ckalloc(sizeof(DWORD));
+ newKey = TlsAlloc();
+ if (newKey != TLS_OUT_OF_INDEXES) {
+ *indexPtr = newKey;
+ } else {
+ panic("TlsAlloc failed from TclpThreadDataKeyInit!"); /* this should be a fatal error */
+ }
+ *keyPtr = (Tcl_ThreadDataKey)indexPtr;
+ TclRememberDataKey(keyPtr);
+ }
+ MASTER_UNLOCK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpThreadDataKeyGet --
+ *
+ * This procedure returns a pointer to a block of thread local storage.
+ *
+ * Results:
+ * A thread-specific pointer to the data structure, or NULL
+ * if the memory has not been assigned to this key for this thread.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+VOID *
+TclpThreadDataKeyGet(keyPtr)
+ Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk,
+ * really (DWORD **) */
+{
+ DWORD *indexPtr = *(DWORD **)keyPtr;
+ LPVOID result;
+ if (indexPtr == NULL) {
+ return NULL;
+ } else {
+ result = TlsGetValue(*indexPtr);
+ if ((result == NULL) && (GetLastError() != NO_ERROR)) {
+ panic("TlsGetValue failed from TclpThreadDataKeyGet!");
+ }
+ return result;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpThreadDataKeySet --
+ *
+ * This procedure sets the pointer to a block of thread local storage.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets up the thread so future calls to TclpThreadDataKeyGet with
+ * this key will return the data pointer.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpThreadDataKeySet(keyPtr, data)
+ Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk,
+ * really (pthread_key_t **) */
+ VOID *data; /* Thread local storage */
+{
+ DWORD *indexPtr = *(DWORD **)keyPtr;
+ BOOL success;
+ success = TlsSetValue(*indexPtr, (void *)data);
+ if (!success) {
+ panic("TlsSetValue failed from TclpThreadDataKeySet!");
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpFinalizeThreadData --
+ *
+ * This procedure cleans up the thread-local storage. This is
+ * called once for each thread.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Frees up the memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpFinalizeThreadData(keyPtr)
+ Tcl_ThreadDataKey *keyPtr;
+{
+ VOID *result;
+ DWORD *indexPtr;
+ BOOL success;
+
+ if (*keyPtr != NULL) {
+ indexPtr = *(DWORD **)keyPtr;
+ result = (VOID *)TlsGetValue(*indexPtr);
+ if (result != NULL) {
+#if defined(USE_THREAD_ALLOC) && !defined(TCL_MEM_DEBUG)
+ if (indexPtr == &tlsKey) {
+ TclpFreeAllocCache(result);
+ return;
+ }
+#endif
+ ckfree((char *)result);
+ success = TlsSetValue(*indexPtr, (void *)NULL);
+ if (!success) {
+ panic("TlsSetValue failed from TclpFinalizeThreadData!");
+ }
+ } else {
+ if (GetLastError() != NO_ERROR) {
+ panic("TlsGetValue failed from TclpFinalizeThreadData!");
+ }
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpFinalizeThreadDataKey --
+ *
+ * This procedure is invoked to clean up one key. This is a
+ * process-wide storage identifier. The thread finalization code
+ * cleans up the thread local storage itself.
+ *
+ * This assumes the master lock is held.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The key is deallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpFinalizeThreadDataKey(keyPtr)
+ Tcl_ThreadDataKey *keyPtr;
+{
+ DWORD *indexPtr;
+ BOOL success;
+ if (*keyPtr != NULL) {
+ indexPtr = *(DWORD **)keyPtr;
+ success = TlsFree(*indexPtr);
+ if (!success) {
+ panic("TlsFree failed from TclpFinalizeThreadDataKey!");
+ }
+ ckfree((char *)indexPtr);
+ *keyPtr = NULL;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* Tcl_ConditionWait --
*
- * This procedure is invoked to wait on a condition variable. The mutex
- * is atomically released as part of the wait, and automatically grabbed
- * when the condition is signaled.
+ * This procedure is invoked to wait on a condition variable.
+ * The mutex is atomically released as part of the wait, and
+ * automatically grabbed when the condition is signaled.
*
* The mutex must be held when this procedure is called.
*
@@ -583,18 +765,18 @@ TclpFinalizeMutex(
* None.
*
* Side effects:
- * May block the current thread. The mutex is aquired when this returns.
- * Will allocate memory for a HANDLE and initialize this the first time
- * this Tcl_Condition is used.
+ * May block the current thread. The mutex is aquired when
+ * this returns. Will allocate memory for a HANDLE
+ * and initialize this the first time this Tcl_Condition is used.
*
*----------------------------------------------------------------------
*/
void
-Tcl_ConditionWait(
- Tcl_Condition *condPtr, /* Really (WinCondition **) */
- Tcl_Mutex *mutexPtr, /* Really (CRITICAL_SECTION **) */
- Tcl_Time *timePtr) /* Timeout on waiting period */
+Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
+ Tcl_Condition *condPtr; /* Really (WinCondition **) */
+ Tcl_Mutex *mutexPtr; /* Really (CRITICAL_SECTION **) */
+ Tcl_Time *timePtr; /* Timeout on waiting period */
{
WinCondition *winCondPtr; /* Per-condition queue head */
CRITICAL_SECTION *csPtr; /* Caller's Mutex, after casting */
@@ -604,20 +786,21 @@ Tcl_ConditionWait(
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
- * Self initialize the two parts of the condition. The per-condition and
- * per-thread parts need to be handled independently.
+ * Self initialize the two parts of the condition.
+ * The per-condition and per-thread parts need to be
+ * handled independently.
*/
if (tsdPtr->flags == WIN_THREAD_UNINIT) {
MASTER_LOCK;
- /*
+ /*
* Create the per-thread event and queue pointers.
*/
if (tsdPtr->flags == WIN_THREAD_UNINIT) {
tsdPtr->condEvent = CreateEvent(NULL, TRUE /* manual reset */,
- FALSE /* non signaled */, NULL);
+ FALSE /* non signaled */, NULL);
tsdPtr->nextPtr = NULL;
tsdPtr->prevPtr = NULL;
tsdPtr->flags = WIN_THREAD_RUNNING;
@@ -627,12 +810,13 @@ Tcl_ConditionWait(
if (doExit) {
/*
- * Create a per-thread exit handler to clean up the condEvent. We
- * must be careful to do this outside the Master Lock because
- * Tcl_CreateThreadExitHandler uses its own ThreadSpecificData,
- * and initializing that may drop back into the Master Lock.
+ * Create a per-thread exit handler to clean up the condEvent.
+ * We must be careful to do this outside the Master Lock
+ * because Tcl_CreateThreadExitHandler uses its own
+ * ThreadSpecificData, and initializing that may drop
+ * back into the Master Lock.
*/
-
+
Tcl_CreateThreadExitHandler(FinalizeConditionEvent,
(ClientData) tsdPtr);
}
@@ -646,11 +830,11 @@ Tcl_ConditionWait(
*/
if (*condPtr == NULL) {
- winCondPtr = (WinCondition *) ckalloc(sizeof(WinCondition));
+ winCondPtr = (WinCondition *)ckalloc(sizeof(WinCondition));
InitializeCriticalSection(&winCondPtr->condLock);
winCondPtr->firstPtr = NULL;
winCondPtr->lastPtr = NULL;
- *condPtr = (Tcl_Condition) winCondPtr;
+ *condPtr = (Tcl_Condition)winCondPtr;
TclRememberCondition(condPtr);
}
MASTER_UNLOCK;
@@ -664,8 +848,8 @@ Tcl_ConditionWait(
}
/*
- * Queue the thread on the condition, using the per-condition lock for
- * serialization.
+ * Queue the thread on the condition, using
+ * the per-condition lock for serialization.
*/
tsdPtr->flags = WIN_THREAD_BLOCKED;
@@ -674,22 +858,22 @@ Tcl_ConditionWait(
tsdPtr->prevPtr = winCondPtr->lastPtr; /* A: */
winCondPtr->lastPtr = tsdPtr;
if (tsdPtr->prevPtr != NULL) {
- tsdPtr->prevPtr->nextPtr = tsdPtr;
+ tsdPtr->prevPtr->nextPtr = tsdPtr;
}
if (winCondPtr->firstPtr == NULL) {
- winCondPtr->firstPtr = tsdPtr;
+ winCondPtr->firstPtr = tsdPtr;
}
/*
* Unlock the caller's mutex and wait for the condition, or a timeout.
- * There is a minor issue here in that we don't count down the timeout if
- * we get notified, but another thread grabs the condition before we do.
- * In that race condition we'll wait again for the full timeout. Timed
- * waits are dubious anyway. Either you have the locking protocol wrong
- * and are masking a deadlock, or you are using conditions to pause your
- * thread.
+ * There is a minor issue here in that we don't count down the
+ * timeout if we get notified, but another thread grabs the condition
+ * before we do. In that race condition we'll wait again for the
+ * full timeout. Timed waits are dubious anyway. Either you have
+ * the locking protocol wrong and are masking a deadlock,
+ * or you are using conditions to pause your thread.
*/
-
+
LeaveCriticalSection(csPtr);
timeout = 0;
while (!timeout && (tsdPtr->flags & WIN_THREAD_BLOCKED)) {
@@ -702,32 +886,32 @@ Tcl_ConditionWait(
}
/*
- * Be careful on timeouts because the signal might arrive right around the
- * time limit and someone else could have taken us off the queue.
+ * Be careful on timeouts because the signal might arrive right around
+ * the time limit and someone else could have taken us off the queue.
*/
-
+
if (timeout) {
if (tsdPtr->flags & WIN_THREAD_RUNNING) {
timeout = 0;
} else {
/*
- * When dequeuing, we can leave the tsdPtr->nextPtr and
- * tsdPtr->prevPtr with dangling pointers because they are
- * reinitialilzed w/out reading them when the thread is enqueued
- * later.
+ * When dequeuing, we can leave the tsdPtr->nextPtr
+ * and tsdPtr->prevPtr with dangling pointers because
+ * they are reinitialilzed w/out reading them when the
+ * thread is enqueued later.
*/
- if (winCondPtr->firstPtr == tsdPtr) {
- winCondPtr->firstPtr = tsdPtr->nextPtr;
- } else {
- tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
- }
- if (winCondPtr->lastPtr == tsdPtr) {
- winCondPtr->lastPtr = tsdPtr->prevPtr;
- } else {
- tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
- }
- tsdPtr->flags = WIN_THREAD_RUNNING;
+ if (winCondPtr->firstPtr == tsdPtr) {
+ winCondPtr->firstPtr = tsdPtr->nextPtr;
+ } else {
+ tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
+ }
+ if (winCondPtr->lastPtr == tsdPtr) {
+ winCondPtr->lastPtr = tsdPtr->prevPtr;
+ } else {
+ tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
+ }
+ tsdPtr->flags = WIN_THREAD_RUNNING;
}
}
@@ -742,8 +926,8 @@ Tcl_ConditionWait(
*
* This procedure is invoked to signal a condition variable.
*
- * The mutex must be held during this call to avoid races, but this
- * interface does not enforce that.
+ * The mutex must be held during this call to avoid races,
+ * but this interface does not enforce that.
*
* Results:
* None.
@@ -755,13 +939,13 @@ Tcl_ConditionWait(
*/
void
-Tcl_ConditionNotify(
- Tcl_Condition *condPtr)
+Tcl_ConditionNotify(condPtr)
+ Tcl_Condition *condPtr;
{
WinCondition *winCondPtr;
ThreadSpecificData *tsdPtr;
- if (*condPtr != NULL) {
+ if (condPtr != NULL) {
winCondPtr = *((WinCondition **)condPtr);
if (winCondPtr == NULL) {
@@ -769,9 +953,9 @@ Tcl_ConditionNotify(
}
/*
- * Loop through all the threads waiting on the condition and notify
- * them (i.e., broadcast semantics). The queue manipulation is guarded
- * by the per-condition coordinating mutex.
+ * Loop through all the threads waiting on the condition
+ * and notify them (i.e., broadcast semantics). The queue
+ * manipulation is guarded by the per-condition coordinating mutex.
*/
EnterCriticalSection(&winCondPtr->condLock);
@@ -789,7 +973,7 @@ Tcl_ConditionNotify(
LeaveCriticalSection(&winCondPtr->condLock);
} else {
/*
- * No-one has used the condition variable, so there are no waiters.
+ * Noone has used the condition variable, so there are no waiters.
*/
}
}
@@ -799,9 +983,9 @@ Tcl_ConditionNotify(
*
* FinalizeConditionEvent --
*
- * This procedure is invoked to clean up the per-thread event used to
- * implement condition waiting. This is only safe to call at the end of
- * time.
+ * This procedure is invoked to clean up the per-thread
+ * event used to implement condition waiting.
+ * This is only safe to call at the end of time.
*
* Results:
* None.
@@ -813,11 +997,10 @@ Tcl_ConditionNotify(
*/
static void
-FinalizeConditionEvent(
- ClientData data)
+FinalizeConditionEvent(data)
+ ClientData data;
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *) data;
-
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)data;
tsdPtr->flags = WIN_THREAD_UNINIT;
CloseHandle(tsdPtr->condEvent);
}
@@ -827,8 +1010,8 @@ FinalizeConditionEvent(
*
* TclpFinalizeCondition --
*
- * This procedure is invoked to clean up a condition variable. This is
- * only safe to call at the end of time.
+ * This procedure is invoked to clean up a condition variable.
+ * This is only safe to call at the end of time.
*
* This assumes the Master Lock is held.
*
@@ -842,33 +1025,30 @@ FinalizeConditionEvent(
*/
void
-TclpFinalizeCondition(
- Tcl_Condition *condPtr)
+TclpFinalizeCondition(condPtr)
+ Tcl_Condition *condPtr;
{
WinCondition *winCondPtr = *(WinCondition **)condPtr;
/*
- * Note - this is called long after the thread-local storage is reclaimed.
- * The per-thread condition waiting event is reclaimed earlier in a
- * per-thread exit handler, which is called before thread local storage is
- * reclaimed.
+ * Note - this is called long after the thread-local storage is
+ * reclaimed. The per-thread condition waiting event is
+ * reclaimed earlier in a per-thread exit handler, which is
+ * called before thread local storage is reclaimed.
*/
if (winCondPtr != NULL) {
DeleteCriticalSection(&winCondPtr->condLock);
- ckfree((char *) winCondPtr);
+ ckfree((char *)winCondPtr);
*condPtr = NULL;
}
}
-
-
-
/*
* Additions by AOL for specialized thread memory allocator.
*/
-#ifdef USE_THREAD_ALLOC
+#if defined(USE_THREAD_ALLOC) && !defined(TCL_MEM_DEBUG)
Tcl_Mutex *
TclpNewAllocMutex(void)
{
@@ -876,7 +1056,7 @@ TclpNewAllocMutex(void)
lockPtr = malloc(sizeof(struct allocMutex));
if (lockPtr == NULL) {
- Tcl_Panic("could not allocate lock");
+ panic("could not allocate lock");
}
lockPtr->tlock = (Tcl_Mutex) &lockPtr->wlock;
InitializeCriticalSection(&lockPtr->wlock);
@@ -884,14 +1064,11 @@ TclpNewAllocMutex(void)
}
void
-TclpFreeAllocMutex(
- Tcl_Mutex *mutex) /* The alloc mutex to free. */
+TclpFreeAllocMutex(mutex)
+ Tcl_Mutex *mutex; /* The alloc mutex to free. */
{
- allocMutex *lockPtr = (allocMutex *) mutex;
-
- if (!lockPtr) {
- return;
- }
+ allocMutex* lockPtr = (allocMutex*) mutex;
+ if (!lockPtr) return;
DeleteCriticalSection(&lockPtr->wlock);
free(lockPtr);
}
@@ -903,73 +1080,60 @@ TclpGetAllocCache(void)
if (!once) {
/*
- * We need to make sure that TclpFreeAllocCache is called on each
- * thread that calls this, but only on threads that call this.
+ * We need to make sure that TclpFreeAllocCache is called
+ * on each thread that calls this, but only on threads that
+ * call this.
*/
-
- tlsKey = TlsAlloc();
+ tlsKey = TlsAlloc();
once = 1;
if (tlsKey == TLS_OUT_OF_INDEXES) {
- Tcl_Panic("could not allocate thread local storage");
+ panic("could not allocate thread local storage");
}
}
result = TlsGetValue(tlsKey);
if ((result == NULL) && (GetLastError() != NO_ERROR)) {
- Tcl_Panic("TlsGetValue failed from TclpGetAllocCache");
+ panic("TlsGetValue failed from TclpGetAllocCache!");
}
return result;
}
void
-TclpSetAllocCache(
- void *ptr)
+TclpSetAllocCache(void *ptr)
{
BOOL success;
success = TlsSetValue(tlsKey, ptr);
if (!success) {
- Tcl_Panic("TlsSetValue failed from TclpSetAllocCache");
+ panic("TlsSetValue failed from TclpSetAllocCache!");
}
}
void
-TclpFreeAllocCache(
- void *ptr)
+TclpFreeAllocCache(void *ptr)
{
BOOL success;
if (ptr != NULL) {
- /*
- * Called by us in TclpFinalizeThreadData when a thread exits and
- * destroys the tsd key which stores allocator caches.
- */
-
- TclFreeAllocCache(ptr);
- success = TlsSetValue(tlsKey, NULL);
- if (!success) {
- Tcl_Panic("TlsSetValue failed from TclpFreeAllocCache");
- }
- } else if (once) {
- /*
- * Called by us in TclFinalizeThreadAlloc() during the library
- * finalization initiated from Tcl_Finalize()
- */
-
- success = TlsFree(tlsKey);
- if (!success) {
- Tcl_Panic("TlsFree failed from TclpFreeAllocCache");
- }
- once = 0; /* reset for next time. */
+ /*
+ * Called by the pthread lib when a thread exits
+ */
+ TclFreeAllocCache(ptr);
+ success = TlsSetValue(tlsKey, NULL);
+ if (!success) {
+ panic("TlsSetValue failed from TclpFreeAllocCache!");
+ }
+ } else if (once) {
+ /*
+ * Called by us in TclFinalizeThreadAlloc() during
+ * the library finalization initiated from Tcl_Finalize()
+ */
+ success = TlsFree(tlsKey);
+ if (!success) {
+ Tcl_Panic("TlsFree failed from TclpFreeAllocCache!");
+ }
+ once = 0; /* reset for next time. */
}
-
}
+
#endif /* USE_THREAD_ALLOC */
#endif /* TCL_THREADS */
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclWinTime.c b/win/tclWinTime.c
index 3ae108b..dd5699e 100644
--- a/win/tclWinTime.c
+++ b/win/tclWinTime.c
@@ -1,30 +1,29 @@
-/*
+/*
* tclWinTime.c --
*
- * Contains Windows specific versions of Tcl functions that obtain time
- * values from the operating system.
+ * Contains Windows specific versions of Tcl functions that
+ * obtain time values from the operating system.
*
* Copyright 1995-1998 by Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tclInt.h"
+#include "tclWinInt.h"
-#define SECSPERDAY (60L * 60L * 24L)
-#define SECSPERYEAR (SECSPERDAY * 365L)
-#define SECSPER4YEAR (SECSPERYEAR * 4L + SECSPERDAY)
+#define SECSPERDAY (60L * 60L * 24L)
+#define SECSPERYEAR (SECSPERDAY * 365L)
+#define SECSPER4YEAR (SECSPERYEAR * 4L + SECSPERDAY)
/*
- * Number of samples over which to estimate the performance counter.
+ * Number of samples over which to estimate the performance counter
*/
-
-#define SAMPLES 64
+#define SAMPLES 64
/*
- * The following arrays contain the day of year for the last day of each
- * month, where index 1 is January.
+ * The following arrays contain the day of year for the last day of
+ * each month, where index 1 is January.
*/
static int normalDays[] = {
@@ -46,29 +45,38 @@ static Tcl_ThreadDataKey dataKey;
*/
typedef struct TimeInfo {
- CRITICAL_SECTION cs; /* Mutex guarding this structure. */
+
+ CRITICAL_SECTION cs; /* Mutex guarding this structure */
+
int initialized; /* Flag == 1 if this structure is
* initialized. */
- int perfCounterAvailable; /* Flag == 1 if the hardware has a performance
- * counter. */
- HANDLE calibrationThread; /* Handle to the thread that keeps the virtual
- * clock calibrated. */
- HANDLE readyEvent; /* System event used to trigger the requesting
- * thread when the clock calibration procedure
- * is initialized for the first time. */
- HANDLE exitEvent; /* Event to signal out of an exit handler to
- * tell the calibration loop to terminate. */
- LARGE_INTEGER nominalFreq; /* Nominal frequency of the system performance
- * counter, that is, the value returned from
- * QueryPerformanceFrequency. */
+
+ int perfCounterAvailable; /* Flag == 1 if the hardware has a
+ * performance counter */
+
+ HANDLE calibrationThread; /* Handle to the thread that keeps the
+ * virtual clock calibrated. */
+
+ HANDLE readyEvent; /* System event used to
+ * trigger the requesting thread
+ * when the clock calibration procedure
+ * is initialized for the first time */
+
+ HANDLE exitEvent; /* Event to signal out of an exit handler
+ * to tell the calibration loop to
+ * terminate */
+
+ LARGE_INTEGER nominalFreq; /* Nominal frequency of the system
+ * performance counter, that is, the value
+ * returned from QueryPerformanceFrequency. */
/*
- * The following values are used for calculating virtual time. Virtual
- * time is always equal to:
- * lastFileTime + (current perf counter - lastCounter)
+ * The following values are used for calculating virtual time.
+ * Virtual time is always equal to:
+ * lastFileTime + (current perf counter - lastCounter)
* * 10000000 / curCounterFreq
- * and lastFileTime and lastCounter are updated any time that virtual time
- * is returned to a caller.
+ * and lastFileTime and lastCounter are updated any time that
+ * virtual time is returned to a caller.
*/
ULARGE_INTEGER fileTimeLastCall;
@@ -76,14 +84,16 @@ typedef struct TimeInfo {
LARGE_INTEGER curCounterFreq;
/*
- * Data used in developing the estimate of performance counter frequency
+ * Data used in developing the estimate of performance counter
+ * frequency
*/
-
Tcl_WideUInt fileTimeSample[SAMPLES];
- /* Last 64 samples of system time. */
+ /* Last 64 samples of system time */
Tcl_WideInt perfCounterSample[SAMPLES];
- /* Last 64 samples of performance counter. */
- int sampleNo; /* Current sample number. */
+ /* Last 64 samples of performance counter */
+ int sampleNo; /* Current sample number */
+
+
} TimeInfo;
static TimeInfo timeInfo = {
@@ -109,38 +119,33 @@ static TimeInfo timeInfo = {
0
};
+static CONST FILETIME posixEpoch = { 0xD53E8000, 0x019DB1DE };
+
/*
* Declarations for functions defined later in this file.
*/
-static struct tm * ComputeGMT(const time_t *tp);
-static void StopCalibration(ClientData clientData);
-static DWORD WINAPI CalibrationThread(LPVOID arg);
-static void UpdateTimeEachSecond(void);
-static void ResetCounterSamples(Tcl_WideUInt fileTime,
- Tcl_WideInt perfCounter, Tcl_WideInt perfFreq);
-static Tcl_WideInt AccumulateSample(Tcl_WideInt perfCounter,
- Tcl_WideUInt fileTime);
-static void NativeScaleTime(Tcl_Time* timebuf,
- ClientData clientData);
-static void NativeGetTime(Tcl_Time* timebuf,
- ClientData clientData);
-
-/*
- * TIP #233 (Virtualized Time): Data for the time hooks, if any.
- */
-
-Tcl_GetTimeProc *tclGetTimeProcPtr = NativeGetTime;
-Tcl_ScaleTimeProc *tclScaleTimeProcPtr = NativeScaleTime;
-ClientData tclTimeClientData = NULL;
+static struct tm * ComputeGMT _ANSI_ARGS_((const time_t *tp));
+static void StopCalibration _ANSI_ARGS_(( ClientData ));
+static DWORD WINAPI CalibrationThread _ANSI_ARGS_(( LPVOID arg ));
+static void UpdateTimeEachSecond _ANSI_ARGS_(( void ));
+static void ResetCounterSamples _ANSI_ARGS_((
+ Tcl_WideUInt fileTime,
+ Tcl_WideInt perfCounter,
+ Tcl_WideInt perfFreq
+ ));
+static Tcl_WideInt AccumulateSample _ANSI_ARGS_((
+ Tcl_WideInt perfCounter,
+ Tcl_WideUInt fileTime
+ ));
/*
*----------------------------------------------------------------------
*
* TclpGetSeconds --
*
- * This procedure returns the number of seconds from the epoch. On most
- * Unix systems the epoch is Midnight Jan 1, 1970 GMT.
+ * This procedure returns the number of seconds from the epoch.
+ * On most Unix systems the epoch is Midnight Jan 1, 1970 GMT.
*
* Results:
* Number of seconds from the epoch.
@@ -152,11 +157,10 @@ ClientData tclTimeClientData = NULL;
*/
unsigned long
-TclpGetSeconds(void)
+TclpGetSeconds()
{
Tcl_Time t;
-
- (*tclGetTimeProcPtr) (&t, tclTimeClientData); /* Tcl_GetTime inlined. */
+ Tcl_GetTime( &t );
return t.sec;
}
@@ -165,10 +169,11 @@ TclpGetSeconds(void)
*
* TclpGetClicks --
*
- * This procedure returns a value that represents the highest resolution
- * clock available on the system. There are no guarantees on what the
- * resolution will be. In Tcl we will call this value a "click". The
- * start time is also system dependant.
+ * This procedure returns a value that represents the highest
+ * resolution clock available on the system. There are no
+ * guarantees on what the resolution will be. In Tcl we will
+ * call this value a "click". The start time is also system
+ * dependant.
*
* Results:
* Number of clicks from some start time.
@@ -180,19 +185,18 @@ TclpGetSeconds(void)
*/
unsigned long
-TclpGetClicks(void)
+TclpGetClicks()
{
/*
- * Use the Tcl_GetTime abstraction to get the time in microseconds, as
- * nearly as we can, and return it.
+ * Use the Tcl_GetTime abstraction to get the time in microseconds,
+ * as nearly as we can, and return it.
*/
Tcl_Time now; /* Current Tcl time */
unsigned long retval; /* Value to return */
- (*tclGetTimeProcPtr) (&now, tclTimeClientData); /* Tcl_GetTime inlined */
-
- retval = (now.sec * 1000000) + now.usec;
+ Tcl_GetTime( &now );
+ retval = ( now.sec * 1000000 ) + now.usec;
return retval;
}
@@ -202,8 +206,9 @@ TclpGetClicks(void)
*
* TclpGetTimeZone --
*
- * Determines the current timezone. The method varies wildly between
- * different Platform implementations, so its hidden in this function.
+ * Determines the current timezone. The method varies wildly
+ * between different Platform implementations, so its hidden in
+ * this function.
*
* Results:
* Minutes west of GMT.
@@ -215,13 +220,13 @@ TclpGetClicks(void)
*/
int
-TclpGetTimeZone(
- unsigned long currentTime)
+TclpGetTimeZone (currentTime)
+ Tcl_WideInt currentTime;
{
int timeZone;
tzset();
- timeZone = timezone / 60;
+ timeZone = _timezone / 60;
return timeZone;
}
@@ -231,137 +236,79 @@ TclpGetTimeZone(
*
* Tcl_GetTime --
*
- * Gets the current system time in seconds and microseconds since the
- * beginning of the epoch: 00:00 UCT, January 1, 1970.
+ * Gets the current system time in seconds and microseconds
+ * since the beginning of the epoch: 00:00 UCT, January 1, 1970.
*
* Results:
* Returns the current time in timePtr.
*
* Side effects:
- * On the first call, initializes a set of static variables to keep track
- * of the base value of the performance counter, the corresponding wall
- * clock (obtained through ftime) and the frequency of the performance
- * counter. Also spins a thread whose function is to wake up periodically
- * and monitor these values, adjusting them as necessary to correct for
- * drift in the performance counter's oscillator.
+ * On the first call, initializes a set of static variables to
+ * keep track of the base value of the performance counter, the
+ * corresponding wall clock (obtained through ftime) and the
+ * frequency of the performance counter. Also spins a thread
+ * whose function is to wake up periodically and monitor these
+ * values, adjusting them as necessary to correct for drift
+ * in the performance counter's oscillator.
*
*----------------------------------------------------------------------
*/
void
-Tcl_GetTime(
- Tcl_Time *timePtr) /* Location to store time information. */
+Tcl_GetTime(timePtr)
+ Tcl_Time *timePtr; /* Location to store time information. */
{
- (*tclGetTimeProcPtr) (timePtr, tclTimeClientData);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * NativeScaleTime --
- *
- * TIP #233: Scale from virtual time to the real-time. For native scaling
- * the relationship is 1:1 and nothing has to be done.
- *
- * Results:
- * Scales the time in timePtr.
- *
- * Side effects:
- * See above.
- *
- *----------------------------------------------------------------------
- */
+ struct timeb t;
-static void
-NativeScaleTime(
- Tcl_Time *timePtr,
- ClientData clientData)
-{
- /*
- * Native scale is 1:1. Nothing is done.
- */
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * NativeGetTime --
- *
- * TIP #233: Gets the current system time in seconds and microseconds
- * since the beginning of the epoch: 00:00 UCT, January 1, 1970.
- *
- * Results:
- * Returns the current time in timePtr.
- *
- * Side effects:
- * On the first call, initializes a set of static variables to keep track
- * of the base value of the performance counter, the corresponding wall
- * clock (obtained through ftime) and the frequency of the performance
- * counter. Also spins a thread whose function is to wake up periodically
- * and monitor these values, adjusting them as necessary to correct for
- * drift in the performance counter's oscillator.
- *
- *----------------------------------------------------------------------
- */
+ int useFtime = 1; /* Flag == TRUE if we need to fall back
+ * on ftime rather than using the perf
+ * counter */
-static void
-NativeGetTime(
- Tcl_Time *timePtr,
- ClientData clientData)
-{
- struct timeb t;
- int useFtime = 1; /* Flag == TRUE if we need to fall back on
- * ftime rather than using the perf counter. */
+ /* Initialize static storage on the first trip through. */
/*
- * Initialize static storage on the first trip through.
- *
- * Note: Outer check for 'initialized' is a performance win since it
- * avoids an extra mutex lock in the common case.
+ * Note: Outer check for 'initialized' is a performance win
+ * since it avoids an extra mutex lock in the common case.
*/
- if (!timeInfo.initialized) {
+ if ( !timeInfo.initialized ) {
TclpInitLock();
- if (!timeInfo.initialized) {
- timeInfo.perfCounterAvailable =
- QueryPerformanceFrequency(&timeInfo.nominalFreq);
+ if ( !timeInfo.initialized ) {
+ timeInfo.perfCounterAvailable
+ = QueryPerformanceFrequency( &timeInfo.nominalFreq );
/*
- * Some hardware abstraction layers use the CPU clock in place of
- * the real-time clock as a performance counter reference. This
- * results in:
+ * Some hardware abstraction layers use the CPU clock
+ * in place of the real-time clock as a performance counter
+ * reference. This results in:
* - inconsistent results among the processors on
* multi-processor systems.
- * - unpredictable changes in performance counter frequency on
- * "gearshift" processors such as Transmeta and SpeedStep.
+ * - unpredictable changes in performance counter frequency
+ * on "gearshift" processors such as Transmeta and
+ * SpeedStep.
*
* There seems to be no way to test whether the performance
- * counter is reliable, but a useful heuristic is that if its
- * frequency is 1.193182 MHz or 3.579545 MHz, it's derived from a
- * colorburst crystal and is therefore the RTC rather than the
- * TSC.
- *
- * A sloppier but serviceable heuristic is that the RTC crystal is
- * normally less than 15 MHz while the TSC crystal is virtually
- * assured to be greater than 100 MHz. Since Win98SE appears to
- * fiddle with the definition of the perf counter frequency
- * (perhaps in an attempt to calibrate the clock?), we use the
- * latter rule rather than an exact match.
+ * counter is reliable, but a useful heuristic is that
+ * if its frequency is 1.193182 MHz or 3.579545 MHz, it's
+ * derived from a colorburst crystal and is therefore
+ * the RTC rather than the TSC.
*
- * We also assume (perhaps questionably) that the vendors have
- * gotten their act together on Win64, so bypass all this rubbish
- * on that platform.
+ * A sloppier but serviceable heuristic is that the RTC crystal
+ * is normally less than 15 MHz while the TSC crystal is
+ * virtually assured to be greater than 100 MHz. Since Win98SE
+ * appears to fiddle with the definition of the perf counter
+ * frequency (perhaps in an attempt to calibrate the clock?)
+ * we use the latter rule rather than an exact match.
*/
-#if !defined(_WIN64)
- if (timeInfo.perfCounterAvailable
- /*
- * The following lines would do an exact match on crystal
- * frequency:
- * && timeInfo.nominalFreq.QuadPart != (Tcl_WideInt)1193182
- * && timeInfo.nominalFreq.QuadPart != (Tcl_WideInt)3579545
- */
- && timeInfo.nominalFreq.QuadPart > (Tcl_WideInt) 15000000){
+ if ( timeInfo.perfCounterAvailable
+ /* The following lines would do an exact match on
+ * crystal frequency:
+ * && timeInfo.nominalFreq.QuadPart != (Tcl_WideInt) 1193182
+ * && timeInfo.nominalFreq.QuadPart != (Tcl_WideInt) 3579545
+ */
+ && timeInfo.nominalFreq.QuadPart > (Tcl_WideInt) 15000000 ) {
+
/*
* As an exception, if every logical processor on the system
* is on the same chip, we use the performance counter anyway,
@@ -371,109 +318,118 @@ NativeGetTime(
SYSTEM_INFO systemInfo;
unsigned int regs[4];
+ GetSystemInfo( &systemInfo );
+ if ( TclWinCPUID( 0, regs ) == TCL_OK
+
+ && regs[1] == 0x756e6547 /* "Genu" */
+ && regs[3] == 0x49656e69 /* "ineI" */
+ && regs[2] == 0x6c65746e /* "ntel" */
+
+ && TclWinCPUID( 1, regs ) == TCL_OK
+
+ && ( (regs[0] & 0x00000F00) == 0x00000F00 /* Pentium 4 */
+ || ( (regs[0] & 0x00F00000) /* Extended family */
+ && (regs[3] & 0x10000000) ) ) /* Hyperthread */
+ && ( ( ( regs[1] & 0x00FF0000 ) >> 16 ) /* CPU count */
+ == systemInfo.dwNumberOfProcessors )
- GetSystemInfo(&systemInfo);
- if (TclWinCPUID(0, regs) == TCL_OK
- && regs[1] == 0x756e6547 /* "Genu" */
- && regs[3] == 0x49656e69 /* "ineI" */
- && regs[2] == 0x6c65746e /* "ntel" */
- && TclWinCPUID(1, regs) == TCL_OK
- && ((regs[0]&0x00000F00) == 0x00000F00 /* Pentium 4 */
- || ((regs[0] & 0x00F00000) /* Extended family */
- && (regs[3] & 0x10000000))) /* Hyperthread */
- && (((regs[1]&0x00FF0000) >> 16)/* CPU count */
- == systemInfo.dwNumberOfProcessors)) {
+ ) {
timeInfo.perfCounterAvailable = TRUE;
} else {
- timeInfo.perfCounterAvailable = FALSE;
- }
+ timeInfo.perfCounterAvailable = FALSE;
+ }
+
}
-#endif /* above code is Win32 only */
/*
* If the performance counter is available, start a thread to
* calibrate it.
*/
- if (timeInfo.perfCounterAvailable) {
+ if ( timeInfo.perfCounterAvailable ) {
DWORD id;
-
- InitializeCriticalSection(&timeInfo.cs);
- timeInfo.readyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- timeInfo.exitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- timeInfo.calibrationThread = CreateThread(NULL, 256,
- CalibrationThread, (LPVOID) NULL, 0, &id);
- SetThreadPriority(timeInfo.calibrationThread,
- THREAD_PRIORITY_HIGHEST);
+ InitializeCriticalSection( &timeInfo.cs );
+ timeInfo.readyEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+ timeInfo.exitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+ timeInfo.calibrationThread = CreateThread( NULL,
+ 256,
+ CalibrationThread,
+ (LPVOID) NULL,
+ 0,
+ &id );
+ SetThreadPriority( timeInfo.calibrationThread,
+ THREAD_PRIORITY_HIGHEST );
/*
- * Wait for the thread just launched to start running, and
- * create an exit handler that kills it so that it doesn't
- * outlive unloading tclXX.dll
+ * Wait for the thread just launched to start running,
+ * and create an exit handler that kills it so that it
+ * doesn't outlive unloading tclXX.dll
*/
- WaitForSingleObject(timeInfo.readyEvent, INFINITE);
- CloseHandle(timeInfo.readyEvent);
- Tcl_CreateExitHandler(StopCalibration, (ClientData) NULL);
+ WaitForSingleObject( timeInfo.readyEvent, INFINITE );
+ CloseHandle( timeInfo.readyEvent );
+ Tcl_CreateExitHandler( StopCalibration, (ClientData) NULL );
}
timeInfo.initialized = TRUE;
}
TclpInitUnlock();
}
- if (timeInfo.perfCounterAvailable && timeInfo.curCounterFreq.QuadPart!=0) {
+ if ( timeInfo.perfCounterAvailable ) {
/*
- * Query the performance counter and use it to calculate the current
- * time.
+ * Query the performance counter and use it to calculate the
+ * current time.
*/
LARGE_INTEGER curCounter;
- /* Current performance counter. */
- Tcl_WideInt curFileTime;/* Current estimated time, expressed as 100-ns
- * ticks since the Windows epoch. */
+ /* Current performance counter */
+
+ Tcl_WideInt curFileTime;
+ /* Current estimated time, expressed
+ * as 100-ns ticks since the Windows epoch */
+
static LARGE_INTEGER posixEpoch;
- /* Posix epoch expressed as 100-ns ticks since
- * the windows epoch. */
+ /* Posix epoch expressed as 100-ns ticks
+ * since the windows epoch */
+
Tcl_WideInt usecSincePosixEpoch;
- /* Current microseconds since Posix epoch. */
+ /* Current microseconds since Posix epoch */
posixEpoch.LowPart = 0xD53E8000;
posixEpoch.HighPart = 0x019DB1DE;
- EnterCriticalSection(&timeInfo.cs);
+ EnterCriticalSection( &timeInfo.cs );
- QueryPerformanceCounter(&curCounter);
+ QueryPerformanceCounter( &curCounter );
- /*
+ /*
* If it appears to be more than 1.1 seconds since the last trip
- * through the calibration loop, the performance counter may have
- * jumped forward. (See MSDN Knowledge Base article Q274323 for a
- * description of the hardware problem that makes this test
- * necessary.) If the counter jumps, we don't want to use it directly.
- * Instead, we must return system time. Eventually, the calibration
- * loop should recover.
+ * through the calibration loop, the performance counter may
+ * have jumped forward. (See MSDN Knowledge Base article
+ * Q274323 for a description of the hardware problem that makes
+ * this test necessary.) If the counter jumps, we don't want
+ * to use it directly. Instead, we must return system time.
+ * Eventually, the calibration loop should recover.
*/
+ if ( curCounter.QuadPart - timeInfo.perfCounterLastCall.QuadPart
+ < 11 * timeInfo.curCounterFreq.QuadPart / 10 ) {
- if (curCounter.QuadPart - timeInfo.perfCounterLastCall.QuadPart <
- 11 * timeInfo.curCounterFreq.QuadPart / 10) {
- curFileTime = timeInfo.fileTimeLastCall.QuadPart +
- ((curCounter.QuadPart - timeInfo.perfCounterLastCall.QuadPart)
- * 10000000 / timeInfo.curCounterFreq.QuadPart);
+ curFileTime = timeInfo.fileTimeLastCall.QuadPart
+ + ( ( curCounter.QuadPart - timeInfo.perfCounterLastCall.QuadPart )
+ * 10000000 / timeInfo.curCounterFreq.QuadPart );
timeInfo.fileTimeLastCall.QuadPart = curFileTime;
timeInfo.perfCounterLastCall.QuadPart = curCounter.QuadPart;
- usecSincePosixEpoch = (curFileTime - posixEpoch.QuadPart) / 10;
- timePtr->sec = (long) (usecSincePosixEpoch / 1000000);
- timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000);
+ usecSincePosixEpoch = ( curFileTime - posixEpoch.QuadPart ) / 10;
+ timePtr->sec = (long) ( usecSincePosixEpoch / 1000000 );
+ timePtr->usec = (unsigned long ) ( usecSincePosixEpoch % 1000000 );
useFtime = 0;
}
- LeaveCriticalSection(&timeInfo.cs);
+ LeaveCriticalSection( &timeInfo.cs );
}
- if (useFtime) {
- /*
- * High resolution timer is not available. Just use ftime.
- */
+ if ( useFtime ) {
+ /* High resolution timer is not available. Just use ftime */
ftime(&t);
timePtr->sec = (long)t.time;
@@ -493,26 +449,20 @@ NativeGetTime(
* None.
*
* Side effects:
- * Sets the 'exitEvent' event in the 'timeInfo' structure to ask the
- * thread in question to exit, and waits for it to do so.
+ * Sets the 'exitEvent' event in the 'timeInfo' structure to ask
+ * the thread in question to exit, and waits for it to do so.
*
*----------------------------------------------------------------------
*/
static void
-StopCalibration(
- ClientData unused) /* Client data is unused */
+StopCalibration( ClientData unused )
+ /* Client data is unused */
{
- SetEvent(timeInfo.exitEvent);
-
- /*
- * If Tcl_Finalize was called from DllMain, the calibration thread is in a
- * paused state so we need to timeout and continue.
- */
-
- WaitForSingleObject(timeInfo.calibrationThread, 100);
- CloseHandle(timeInfo.exitEvent);
- CloseHandle(timeInfo.calibrationThread);
+ SetEvent( timeInfo.exitEvent );
+ WaitForSingleObject( timeInfo.calibrationThread, INFINITE );
+ CloseHandle( timeInfo.exitEvent );
+ CloseHandle( timeInfo.calibrationThread );
}
/*
@@ -532,10 +482,9 @@ StopCalibration(
*/
char *
-TclpGetTZName(
- int dst)
+TclpGetTZName(int dst)
{
- int len;
+ size_t len;
char *zone, *p;
TIME_ZONE_INFORMATION tz;
Tcl_Encoding encoding;
@@ -546,9 +495,9 @@ TclpGetTZName(
* tzset() under Borland doesn't seem to set up tzname[] at all.
* tzset() under MSVC has the following weird observed behavior:
* First time we call "clock format [clock seconds] -format %Z -gmt 1"
- * we get "GMT", but on all subsequent calls we get the current time
- * ezone string, even though env(TZ) is GMT and the variable _timezone
- * is 0.
+ * we get "GMT", but on all subsequent calls we get the current time
+ * zone string, even though env(TZ) is GMT and the variable _timezone
+ * is 0.
*/
name[0] = '\0';
@@ -556,10 +505,11 @@ TclpGetTZName(
zone = getenv("TZ");
if (zone != NULL) {
/*
- * TZ is of form "NST-4:30NDT", where "NST" would be the name of the
- * standard time zone for this area, "-4:30" is the offset from GMT in
- * hours, and "NDT is the name of the daylight savings time zone in
- * this area. The offset and DST strings are optional.
+ * TZ is of form "NST-4:30NDT", where "NST" would be the
+ * name of the standard time zone for this area, "-4:30" is
+ * the offset from GMT in hours, and "NDT is the name of
+ * the daylight savings time zone in this area. The offset
+ * and DST strings are optional.
*/
len = strlen(zone);
@@ -581,24 +531,23 @@ TclpGetTZName(
}
}
}
- Tcl_ExternalToUtf(NULL, NULL, zone, len, 0, NULL, name,
+ Tcl_ExternalToUtf(NULL, NULL, zone, (int)len, 0, NULL, name,
sizeof(tsdPtr->tzName), NULL, NULL, NULL);
}
if (name[0] == '\0') {
if (GetTimeZoneInformation(&tz) == TIME_ZONE_ID_UNKNOWN) {
/*
- * MSDN: On NT this is returned if DST is not used in the current
- * TZ
+ * MSDN: On NT this is returned if DST is not used in
+ * the current TZ
*/
-
dst = 0;
}
encoding = Tcl_GetEncoding(NULL, "unicode");
- Tcl_ExternalToUtf(NULL, encoding,
- (char *) ((dst) ? tz.DaylightName : tz.StandardName), -1,
+ Tcl_ExternalToUtf(NULL, encoding,
+ (char *) ((dst) ? tz.DaylightName : tz.StandardName), -1,
0, NULL, name, sizeof(tsdPtr->tzName), NULL, NULL, NULL);
Tcl_FreeEncoding(encoding);
- }
+ }
return name;
}
@@ -607,9 +556,9 @@ TclpGetTZName(
*
* TclpGetDate --
*
- * This function converts between seconds and struct tm. If useGMT is
- * true, then the returned date will be in Greenwich Mean Time (GMT).
- * Otherwise, it will be in the local time zone.
+ * This function converts between seconds and struct tm. If
+ * useGMT is true, then the returned date will be in Greenwich
+ * Mean Time (GMT). Otherwise, it will be in the local time zone.
*
* Results:
* Returns a static tm structure.
@@ -621,10 +570,11 @@ TclpGetTZName(
*/
struct tm *
-TclpGetDate(
- CONST time_t *t,
- int useGMT)
+TclpGetDate(t, useGMT)
+ TclpTime_t t;
+ int useGMT;
{
+ const time_t *tp = (const time_t *) t;
struct tm *tmPtr;
time_t time;
@@ -632,44 +582,28 @@ TclpGetDate(
tzset();
/*
- * If we are in the valid range, let the C run-time library handle it.
- * Otherwise we need to fake it. Note that this algorithm ignores
- * daylight savings time before the epoch.
+ * If we are in the valid range, let the C run-time library
+ * handle it. Otherwise we need to fake it. Note that this
+ * algorithm ignores daylight savings time before the epoch.
*/
- /*
- * Hm, Borland's localtime manages to return NULL under certain
- * circumstances (e.g. wintime.test, test 1.2). Nobody tests for this,
- * since 'localtime' isn't supposed to do this, possibly leading to
- * crashes.
- *
- * Patch: We only call this function if we are at least one day into
- * the epoch, else we handle it ourselves (like we do for times < 0).
- * H. Giese, June 2003
- */
-
-#ifdef __BORLANDC__
-#define LOCALTIME_VALIDITY_BOUNDARY SECSPERDAY
-#else
-#define LOCALTIME_VALIDITY_BOUNDARY 0
-#endif
-
- if (*t >= LOCALTIME_VALIDITY_BOUNDARY) {
- return TclpLocaltime(t);
+ if (*tp >= 0) {
+ return localtime(tp);
}
- time = *t - timezone;
+ time = *tp - _timezone;
/*
* If we aren't near to overflowing the long, just add the bias and
- * use the normal calculation. Otherwise we will need to adjust the
- * result at the end.
+ * use the normal calculation. Otherwise we will need to adjust
+ * the result at the end.
*/
- if (*t < (LONG_MAX - 2*SECSPERDAY) && *t > (LONG_MIN + 2*SECSPERDAY)) {
+ if (*tp < (LONG_MAX - 2 * SECSPERDAY)
+ && *tp > (LONG_MIN + 2 * SECSPERDAY)) {
tmPtr = ComputeGMT(&time);
} else {
- tmPtr = ComputeGMT(t);
+ tmPtr = ComputeGMT(tp);
tzset();
@@ -678,7 +612,7 @@ TclpGetDate(
* Propagate seconds overflow into minutes, hours and days.
*/
- time = tmPtr->tm_sec - timezone;
+ time = tmPtr->tm_sec - _timezone;
tmPtr->tm_sec = (int)(time % 60);
if (tmPtr->tm_sec < 0) {
tmPtr->tm_sec += 60;
@@ -705,7 +639,7 @@ TclpGetDate(
tmPtr->tm_wday = (tmPtr->tm_wday + (int)time) % 7;
}
} else {
- tmPtr = ComputeGMT(t);
+ tmPtr = ComputeGMT(tp);
}
return tmPtr;
}
@@ -715,8 +649,8 @@ TclpGetDate(
*
* ComputeGMT --
*
- * This function computes GMT given the number of seconds since the epoch
- * (midnight Jan 1 1970).
+ * This function computes GMT given the number of seconds since
+ * the epoch (midnight Jan 1 1970).
*
* Results:
* Returns a (per thread) statically allocated struct tm.
@@ -728,8 +662,8 @@ TclpGetDate(
*/
static struct tm *
-ComputeGMT(
- const time_t *tp)
+ComputeGMT(tp)
+ const time_t *tp;
{
struct tm *tmPtr;
long tmp, rem;
@@ -744,7 +678,7 @@ ComputeGMT(
*/
tmp = (long)(*tp / SECSPER4YEAR);
- rem = (long)(*tp % SECSPER4YEAR);
+ rem = (LONG)(*tp % SECSPER4YEAR);
/*
* Correct for weird mod semantics so the remainder is always positive.
@@ -756,9 +690,9 @@ ComputeGMT(
}
/*
- * Compute the year after 1900 by taking the 4 year span and adjusting for
- * the remainder. This works because 2000 is a leap year, and 1900/2100
- * are out of the range.
+ * Compute the year after 1900 by taking the 4 year span and adjusting
+ * for the remainder. This works because 2000 is a leap year, and
+ * 1900/2100 are out of the range.
*/
tmp = (tmp * 4) + 70;
@@ -780,13 +714,13 @@ ComputeGMT(
tmPtr->tm_year = tmp;
/*
- * Compute the day of year and leave the seconds in the current day in the
- * remainder.
+ * Compute the day of year and leave the seconds in the current day in
+ * the remainder.
*/
tmPtr->tm_yday = rem / SECSPERDAY;
rem %= SECSPERDAY;
-
+
/*
* Compute the time of day.
*/
@@ -802,7 +736,6 @@ ComputeGMT(
days = (isLeap) ? leapDays : normalDays;
for (tmp = 1; days[tmp] < tmPtr->tm_yday; tmp++) {
- /* empty body */
}
tmPtr->tm_mon = --tmp;
tmPtr->tm_mday = tmPtr->tm_yday - days[tmp];
@@ -828,66 +761,60 @@ ComputeGMT(
*
* CalibrationThread --
*
- * Thread that manages calibration of the hi-resolution time derived from
- * the performance counter, to keep it synchronized with the system
- * clock.
+ * Thread that manages calibration of the hi-resolution time
+ * derived from the performance counter, to keep it synchronized
+ * with the system clock.
*
* Parameters:
- * arg - Client data from the CreateThread call. This parameter points to
- * the static TimeInfo structure.
+ * arg -- Client data from the CreateThread call. This parameter
+ * points to the static TimeInfo structure.
*
* Return value:
- * None. This thread embeds an infinite loop.
+ * None. This thread embeds an infinite loop.
*
* Side effects:
- * At an interval of 1s, this thread performs virtual time discipline.
+ * At an interval of 1 s, this thread performs virtual time discipline.
*
- * Note: When this thread is entered, TclpInitLock has been called to
- * safeguard the static storage. There is therefore no synchronization in the
- * body of this procedure.
+ * Note: When this thread is entered, TclpInitLock has been called
+ * to safeguard the static storage. There is therefore no synchronization
+ * in the body of this procedure.
*
*----------------------------------------------------------------------
*/
static DWORD WINAPI
-CalibrationThread(
- LPVOID arg)
+CalibrationThread( LPVOID arg )
{
FILETIME curFileTime;
DWORD waitResult;
- /*
- * Get initial system time and performance counter.
- */
+ /* Get initial system time and performance counter */
- GetSystemTimeAsFileTime(&curFileTime);
- QueryPerformanceCounter(&timeInfo.perfCounterLastCall);
- QueryPerformanceFrequency(&timeInfo.curCounterFreq);
+ GetSystemTimeAsFileTime( &curFileTime );
+ QueryPerformanceCounter( &timeInfo.perfCounterLastCall );
+ QueryPerformanceFrequency( &timeInfo.curCounterFreq );
timeInfo.fileTimeLastCall.LowPart = curFileTime.dwLowDateTime;
timeInfo.fileTimeLastCall.HighPart = curFileTime.dwHighDateTime;
- ResetCounterSamples(timeInfo.fileTimeLastCall.QuadPart,
- timeInfo.perfCounterLastCall.QuadPart,
- timeInfo.curCounterFreq.QuadPart);
+ ResetCounterSamples( timeInfo.fileTimeLastCall.QuadPart,
+ timeInfo.perfCounterLastCall.QuadPart,
+ timeInfo.curCounterFreq.QuadPart );
/*
- * Wake up the calling thread. When it wakes up, it will release the
+ * Wake up the calling thread. When it wakes up, it will release the
* initialization lock.
*/
- SetEvent(timeInfo.readyEvent);
+ SetEvent( timeInfo.readyEvent );
- /*
- * Run the calibration once a second.
- */
+ /* Run the calibration once a second */
- while (timeInfo.perfCounterAvailable) {
- /*
- * If the exitEvent is set, break out of the loop.
- */
+ for ( ; ; ) {
+
+ /* If the exitEvent is set, break out of the loop. */
waitResult = WaitForSingleObjectEx(timeInfo.exitEvent, 1000, FALSE);
- if (waitResult == WAIT_OBJECT_0) {
+ if ( waitResult == WAIT_OBJECT_0 ) {
break;
}
UpdateTimeEachSecond();
@@ -902,11 +829,11 @@ CalibrationThread(
*
* UpdateTimeEachSecond --
*
- * Callback from the waitable timer in the clock calibration thread that
- * updates system time.
+ * Callback from the waitable timer in the clock calibration thread
+ * that updates system time.
*
* Parameters:
- * info - Pointer to the static TimeInfo structure
+ * info -- Pointer to the static TimeInfo structure
*
* Results:
* None.
@@ -918,116 +845,113 @@ CalibrationThread(
*/
static void
-UpdateTimeEachSecond(void)
+UpdateTimeEachSecond()
{
+
LARGE_INTEGER curPerfCounter;
/* Current value returned from
- * QueryPerformanceCounter. */
- FILETIME curSysTime; /* Current system time. */
- LARGE_INTEGER curFileTime; /* File time at the time this callback was
- * scheduled. */
- Tcl_WideInt estFreq; /* Estimated perf counter frequency. */
- Tcl_WideInt vt0; /* Tcl time right now. */
- Tcl_WideInt vt1; /* Tcl time one second from now. */
- Tcl_WideInt tdiff; /* Difference between system clock and Tcl
- * time. */
- Tcl_WideInt driftFreq; /* Frequency needed to drift virtual time into
- * step over 1 second. */
+ * QueryPerformanceCounter */
+
+ FILETIME curSysTime; /* Current system time */
+
+ LARGE_INTEGER curFileTime; /* File time at the time this callback
+ * was scheduled. */
+
+ Tcl_WideInt estFreq; /* Estimated perf counter frequency */
+
+ Tcl_WideInt vt0; /* Tcl time right now */
+ Tcl_WideInt vt1; /* Tcl time one second from now */
+
+ Tcl_WideInt tdiff; /* Difference between system clock and
+ * Tcl time. */
+
+ Tcl_WideInt driftFreq; /* Frequency needed to drift virtual time
+ * into step over 1 second */
/*
* Sample performance counter and system time.
*/
- QueryPerformanceCounter(&curPerfCounter);
- GetSystemTimeAsFileTime(&curSysTime);
+ QueryPerformanceCounter( &curPerfCounter );
+ GetSystemTimeAsFileTime( &curSysTime );
curFileTime.LowPart = curSysTime.dwLowDateTime;
curFileTime.HighPart = curSysTime.dwHighDateTime;
- EnterCriticalSection(&timeInfo.cs);
+ EnterCriticalSection( &timeInfo.cs );
/*
- * We devide by timeInfo.curCounterFreq.QuadPart in several places. That
- * value should always be positive on a correctly functioning system. But
- * it is good to be defensive about such matters. So if something goes
- * wrong and the value does goes to zero, we clear the
- * timeInfo.perfCounterAvailable in order to cause the calibration thread
- * to shut itself down, then return without additional processing.
+ * Several things may have gone wrong here that have to
+ * be checked for.
+ * (1) The performance counter may have jumped.
+ * (2) The system clock may have been reset.
+ *
+ * In either case, we'll need to reinitialize the circular buffer
+ * with samples relative to the current system time and the NOMINAL
+ * performance frequency (not the actual, because the actual has
+ * probably run slow in the first case). Our estimated frequency
+ * will be the nominal frequency.
*/
- if (timeInfo.curCounterFreq.QuadPart == 0){
- LeaveCriticalSection(&timeInfo.cs);
- timeInfo.perfCounterAvailable = 0;
- return;
- }
-
/*
- * Several things may have gone wrong here that have to be checked for.
- * (1) The performance counter may have jumped.
- * (2) The system clock may have been reset.
- *
- * In either case, we'll need to reinitialize the circular buffer with
- * samples relative to the current system time and the NOMINAL performance
- * frequency (not the actual, because the actual has probably run slow in
- * the first case). Our estimated frequency will be the nominal frequency.
- *
- * Store the current sample into the circular buffer of samples, and
- * estimate the performance counter frequency.
+ * Store the current sample into the circular buffer of samples,
+ * and estimate the performance counter frequency.
*/
- estFreq = AccumulateSample(curPerfCounter.QuadPart,
- (Tcl_WideUInt) curFileTime.QuadPart);
+ estFreq = AccumulateSample( curPerfCounter.QuadPart,
+ (Tcl_WideUInt) curFileTime.QuadPart );
/*
* We want to adjust things so that time appears to be continuous.
- * Virtual file time, right now, is
+ * Virtual file time, right now, is
*
- * vt0 = 10000000 * (curPerfCounter - perfCounterLastCall)
- * / curCounterFreq
- * + fileTimeLastCall
+ * vt0 = 10000000 * ( curPerfCounter - perfCounterLastCall )
+ * / curCounterFreq
+ * + fileTimeLastCall
*
- * Ideally, we would like to drift the clock into place over a period of 2
- * sec, so that virtual time 2 sec from now will be
+ * Ideally, we would like to drift the clock into place over a
+ * period of 2 sec, so that virtual time 2 sec from now will be
*
* vt1 = 20000000 + curFileTime
- *
- * The frequency that we need to use to drift the counter back into place
- * is estFreq * 20000000 / (vt1 - vt0)
+ *
+ * The frequency that we need to use to drift the counter back into
+ * place is estFreq * 20000000 / ( vt1 - vt0 )
*/
-
- vt0 = 10000000 * (curPerfCounter.QuadPart
- - timeInfo.perfCounterLastCall.QuadPart)
- / timeInfo.curCounterFreq.QuadPart
- + timeInfo.fileTimeLastCall.QuadPart;
+
+ vt0 = 10000000 * ( curPerfCounter.QuadPart
+ - timeInfo.perfCounterLastCall.QuadPart )
+ / timeInfo.curCounterFreq.QuadPart
+ + timeInfo.fileTimeLastCall.QuadPart;
vt1 = 20000000 + curFileTime.QuadPart;
/*
- * If we've gotten more than a second away from system time, then drifting
- * the clock is going to be pretty hopeless. Just let it jump. Otherwise,
- * compute the drift frequency and fill in everything.
+ * If we've gotten more than a second away from system time,
+ * then drifting the clock is going to be pretty hopeless.
+ * Just let it jump. Otherwise, compute the drift frequency and
+ * fill in everything.
*/
tdiff = vt0 - curFileTime.QuadPart;
- if (tdiff > 10000000 || tdiff < -10000000) {
+ if ( tdiff > 10000000 || tdiff < -10000000 ) {
timeInfo.fileTimeLastCall.QuadPart = curFileTime.QuadPart;
timeInfo.curCounterFreq.QuadPart = estFreq;
} else {
- driftFreq = estFreq * 20000000 / (vt1 - vt0);
-
- if (driftFreq > 1003*estFreq/1000) {
- driftFreq = 1003*estFreq/1000;
- } else if (driftFreq < 997*estFreq/1000) {
- driftFreq = 997*estFreq/1000;
+ driftFreq = estFreq * 20000000 / ( vt1 - vt0 );
+ if ( driftFreq > 1003 * estFreq / 1000 ) {
+ driftFreq = 1003 * estFreq / 1000;
+ }
+ if ( driftFreq < 997 * estFreq / 1000 ) {
+ driftFreq = 997 * estFreq / 1000;
}
-
timeInfo.fileTimeLastCall.QuadPart = vt0;
timeInfo.curCounterFreq.QuadPart = driftFreq;
}
timeInfo.perfCounterLastCall.QuadPart = curPerfCounter.QuadPart;
- LeaveCriticalSection(&timeInfo.cs);
+ LeaveCriticalSection( &timeInfo.cs );
+
}
-
+
/*
*----------------------------------------------------------------------
*
@@ -1040,21 +964,23 @@ UpdateTimeEachSecond(void)
* None.
*
* Side effects:
- * The array of samples is filled in so that it appears that there are
- * SAMPLES samples at one-second intervals, separated by precisely the
- * given frequency.
+ * The array of samples is filled in so that it appears that there
+ * are SAMPLES samples at one-second intervals, separated by precisely
+ * the given frequency.
*
*----------------------------------------------------------------------
*/
static void
-ResetCounterSamples(
- Tcl_WideUInt fileTime, /* Current file time */
- Tcl_WideInt perfCounter, /* Current performance counter */
- Tcl_WideInt perfFreq) /* Target performance frequency */
+ResetCounterSamples( Tcl_WideUInt fileTime,
+ /* Current file time */
+ Tcl_WideInt perfCounter,
+ /* Current performance counter */
+ Tcl_WideInt perfFreq )
+ /* Target performance frequency */
{
int i;
- for (i=SAMPLES-1 ; i>=0 ; --i) {
+ for ( i = SAMPLES-1; i >= 0; --i ) {
timeInfo.perfCounterSample[i] = perfCounter;
timeInfo.fileTimeSample[i] = fileTime;
perfCounter -= perfFreq;
@@ -1068,84 +994,87 @@ ResetCounterSamples(
*
* AccumulateSample --
*
- * Updates the circular buffer of performance counter and system time
- * samples with a new data point.
+ * Updates the circular buffer of performance counter and system
+ * time samples with a new data point.
*
* Results:
* None.
*
* Side effects:
- * The new data point replaces the oldest point in the circular buffer,
- * and the descriptive statistics are updated to accumulate the new
- * point.
- *
- * Several things may have gone wrong here that have to be checked for.
- * (1) The performance counter may have jumped.
- * (2) The system clock may have been reset.
- *
- * In either case, we'll need to reinitialize the circular buffer with samples
- * relative to the current system time and the NOMINAL performance frequency
- * (not the actual, because the actual has probably run slow in the first
- * case).
+ * The new data point replaces the oldest point in the circular
+ * buffer, and the descriptive statistics are updated to accumulate
+ * the new point.
+ *
+ * Several things may have gone wrong here that have to
+ * be checked for.
+ * (1) The performance counter may have jumped.
+ * (2) The system clock may have been reset.
+ *
+ * In either case, we'll need to reinitialize the circular buffer
+ * with samples relative to the current system time and the NOMINAL
+ * performance frequency (not the actual, because the actual has
+ * probably run slow in the first case).
*/
static Tcl_WideInt
-AccumulateSample(
- Tcl_WideInt perfCounter,
- Tcl_WideUInt fileTime)
+AccumulateSample( Tcl_WideInt perfCounter,
+ Tcl_WideUInt fileTime )
{
- Tcl_WideUInt workFTSample; /* File time sample being removed from or
- * added to the circular buffer. */
- Tcl_WideInt workPCSample; /* Performance counter sample being removed
- * from or added to the circular buffer. */
+ Tcl_WideUInt workFTSample; /* File time sample being removed
+ * from or added to the circular buffer */
+
+ Tcl_WideInt workPCSample; /* Performance counter sample being
+ * removed from or added to the circular
+ * buffer */
+
Tcl_WideUInt lastFTSample; /* Last file time sample recorded */
+
Tcl_WideInt lastPCSample; /* Last performance counter sample recorded */
+
Tcl_WideInt FTdiff; /* Difference between last FT and current */
+
Tcl_WideInt PCdiff; /* Difference between last PC and current */
+
Tcl_WideInt estFreq; /* Estimated performance counter frequency */
- /*
- * Test for jumps and reset the samples if we have one.
- */
+ /* Test for jumps and reset the samples if we have one. */
- if (timeInfo.sampleNo == 0) {
- lastPCSample =
- timeInfo.perfCounterSample[timeInfo.sampleNo + SAMPLES - 1];
- lastFTSample =
- timeInfo.fileTimeSample[timeInfo.sampleNo + SAMPLES - 1];
+ if ( timeInfo.sampleNo == 0 ) {
+ lastPCSample = timeInfo.perfCounterSample[ timeInfo.sampleNo
+ + SAMPLES - 1 ];
+ lastFTSample = timeInfo.fileTimeSample[ timeInfo.sampleNo
+ + SAMPLES - 1 ];
} else {
- lastPCSample = timeInfo.perfCounterSample[timeInfo.sampleNo - 1];
- lastFTSample = timeInfo.fileTimeSample[timeInfo.sampleNo - 1];
+ lastPCSample = timeInfo.perfCounterSample[ timeInfo.sampleNo - 1 ];
+ lastFTSample = timeInfo.fileTimeSample[ timeInfo.sampleNo - 1 ];
}
-
PCdiff = perfCounter - lastPCSample;
FTdiff = fileTime - lastFTSample;
- if (PCdiff < timeInfo.nominalFreq.QuadPart * 9 / 10
- || PCdiff > timeInfo.nominalFreq.QuadPart * 11 / 10
- || FTdiff < 9000000 || FTdiff > 11000000) {
- ResetCounterSamples(fileTime, perfCounter,
- timeInfo.nominalFreq.QuadPart);
+ if ( PCdiff < timeInfo.nominalFreq.QuadPart * 9 / 10
+ || PCdiff > timeInfo.nominalFreq.QuadPart * 11 / 10
+ || FTdiff < 9000000
+ || FTdiff > 11000000 ) {
+ ResetCounterSamples( fileTime, perfCounter,
+ timeInfo.nominalFreq.QuadPart );
return timeInfo.nominalFreq.QuadPart;
- } else {
- /*
- * Estimate the frequency.
- */
-
- workPCSample = timeInfo.perfCounterSample[timeInfo.sampleNo];
- workFTSample = timeInfo.fileTimeSample[timeInfo.sampleNo];
- estFreq = 10000000 * (perfCounter - workPCSample)
- / (fileTime - workFTSample);
- timeInfo.perfCounterSample[timeInfo.sampleNo] = perfCounter;
- timeInfo.fileTimeSample[timeInfo.sampleNo] = (Tcl_WideInt) fileTime;
-
- /*
- * Advance the sample number.
- */
- if (++timeInfo.sampleNo >= SAMPLES) {
+ } else {
+
+ /* Estimate the frequency */
+
+ workPCSample = timeInfo.perfCounterSample[ timeInfo.sampleNo ];
+ workFTSample = timeInfo.fileTimeSample[ timeInfo.sampleNo ];
+ estFreq = 10000000 * ( perfCounter - workPCSample )
+ / ( fileTime - workFTSample );
+ timeInfo.perfCounterSample[ timeInfo.sampleNo ] = perfCounter;
+ timeInfo.fileTimeSample[ timeInfo.sampleNo ] = (Tcl_WideInt) fileTime;
+
+ /* Advance the sample number */
+
+ if ( ++timeInfo.sampleNo >= SAMPLES ) {
timeInfo.sampleNo = 0;
- }
-
+ }
+
return estFreq;
}
}
@@ -1155,7 +1084,8 @@ AccumulateSample(
*
* TclpGmtime --
*
- * Wrapper around the 'gmtime' library function to make it thread safe.
+ * Wrapper around the 'gmtime' library function to make it thread
+ * safe.
*
* Results:
* Returns a pointer to a 'struct tm' in thread-specific data.
@@ -1167,17 +1097,18 @@ AccumulateSample(
*/
struct tm *
-TclpGmtime(
- CONST time_t *timePtr) /* Pointer to the number of seconds since the
- * local system's epoch */
+TclpGmtime( tt )
+ TclpTime_t_CONST tt;
{
+ CONST time_t *timePtr = (CONST time_t *) tt;
+ /* Pointer to the number of seconds
+ * since the local system's epoch */
/*
- * The MS implementation of gmtime is thread safe because it returns the
- * time in a block of thread-local storage, and Windows does not provide a
- * Posix gmtime_r function.
+ * The MS implementation of gmtime is thread safe because
+ * it returns the time in a block of thread-local storage,
+ * and Windows does not provide a Posix gmtime_r function.
*/
-
- return gmtime(timePtr);
+ return gmtime( timePtr );
}
/*
@@ -1198,85 +1129,17 @@ TclpGmtime(
*/
struct tm *
-TclpLocaltime(
- CONST time_t *timePtr) /* Pointer to the number of seconds since the
- * local system's epoch */
-
+TclpLocaltime( tt )
+ TclpTime_t_CONST tt;
{
+ CONST time_t *timePtr = (CONST time_t *) tt;
+ /* Pointer to the number of seconds
+ * since the local system's epoch */
+
/*
- * The MS implementation of localtime is thread safe because it returns
- * the time in a block of thread-local storage, and Windows does not
- * provide a Posix localtime_r function.
+ * The MS implementation of localtime is thread safe because
+ * it returns the time in a block of thread-local storage,
+ * and Windows does not provide a Posix localtime_r function.
*/
-
- return localtime(timePtr);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_SetTimeProc --
- *
- * TIP #233 (Virtualized Time): Registers two handlers for the
- * virtualization of Tcl's access to time information.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Remembers the handlers, alters core behaviour.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tcl_SetTimeProc(
- Tcl_GetTimeProc *getProc,
- Tcl_ScaleTimeProc *scaleProc,
- ClientData clientData)
-{
- tclGetTimeProcPtr = getProc;
- tclScaleTimeProcPtr = scaleProc;
- tclTimeClientData = clientData;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_QueryTimeProc --
- *
- * TIP #233 (Virtualized Time): Query which time handlers are registered.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tcl_QueryTimeProc(
- Tcl_GetTimeProc **getProc,
- Tcl_ScaleTimeProc **scaleProc,
- ClientData *clientData)
-{
- if (getProc) {
- *getProc = tclGetTimeProcPtr;
- }
- if (scaleProc) {
- *scaleProc = tclScaleTimeProcPtr;
- }
- if (clientData) {
- *clientData = tclTimeClientData;
- }
+ return localtime( timePtr );
}
-
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */
diff --git a/win/tclsh.rc b/win/tclsh.rc
index 16eaf83..a1b0b76 100644
--- a/win/tclsh.rc
+++ b/win/tclsh.rc
@@ -7,20 +7,20 @@
//
// build-up the name suffix that defines the type of build this is.
//
-#if TCL_THREADS
+#ifdef TCL_THREADS
#define SUFFIX_THREADS "t"
#else
#define SUFFIX_THREADS ""
#endif
-#if STATIC_BUILD
+#ifdef STATIC_BUILD
#define SUFFIX_STATIC "s"
#else
#define SUFFIX_STATIC ""
#endif
-#if DEBUG && !UNCHECKED
-#define SUFFIX_DEBUG "g"
+#ifdef DEBUG
+#define SUFFIX_DEBUG "d"
#else
#define SUFFIX_DEBUG ""
#endif
@@ -48,7 +48,7 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Tclsh Application\0"
- VALUE "OriginalFilename", "tclsh" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) SUFFIX ".exe\0"
+ VALUE "OriginalFilename", "tclsh" STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) SUFFIX ".exe\0"
VALUE "CompanyName", "ActiveState Corporation\0"
VALUE "FileVersion", TCL_PATCH_LEVEL
VALUE "LegalCopyright", "Copyright \251 2000 by ActiveState Corporation, et al\0"