summaryrefslogtreecommitdiffstats
path: root/Lib/test/output_window.gif
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2020-04-19 21:13:39 (GMT)
committerBenjamin Peterson <benjamin@python.org>2020-04-19 21:13:39 (GMT)
commit8d21aa21f2cbc6d50aab3f420bb23be1d081dac4 (patch)
tree8133f47ade097d9fa33954a0211ea16b9088bfd3 /Lib/test/output_window.gif
parent8323757381eb3f9dbe5b98edd59bfb4a6d80b493 (diff)
downloadcpython-2.7.zip
cpython-2.7.tar.gz
cpython-2.7.tar.bz2
Add empty 2.7.18 NEWS file.v2.7.182.7
Diffstat (limited to 'Lib/test/output_window.gif')
0 files changed, 0 insertions, 0 deletions
value='bug_3480599'>bug_3480599 Tcl is a high-level, general-purpose, interpreted, dynamic programming language. It was designed with the goal of being very simple but powerful.
summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
Diffstat (limited to 'win')
-rw-r--r--win/Makefile.in389
-rw-r--r--win/README16
-rwxr-xr-x[-rw-r--r--]win/buildall.vc.bat8
-rw-r--r--win/coffbase.txt43
-rwxr-xr-xwin/configure8574
-rw-r--r--win/configure.ac (renamed from win/configure.in)160
-rw-r--r--win/makefile.vc381
-rw-r--r--win/rules.vc82
-rw-r--r--win/targets.vc1
-rw-r--r--win/tcl.dsp110
-rw-r--r--win/tcl.hpj.in19
-rw-r--r--win/tcl.m4348
-rw-r--r--win/tcl.rc23
-rw-r--r--win/tclAppInit.c50
-rw-r--r--win/tclConfig.sh.in24
-rw-r--r--win/tclWin32Dll.c388
-rw-r--r--win/tclWinChan.c629
-rw-r--r--win/tclWinConsole.c2438
-rw-r--r--win/tclWinDde.c175
-rw-r--r--win/tclWinError.c23
-rw-r--r--win/tclWinFCmd.c294
-rw-r--r--win/tclWinFile.c392
-rw-r--r--win/tclWinInit.c243
-rw-r--r--win/tclWinInt.h76
-rw-r--r--win/tclWinLoad.c87
-rw-r--r--win/tclWinNotify.c516
-rw-r--r--win/tclWinPanic.c88
-rw-r--r--win/tclWinPipe.c318
-rw-r--r--win/tclWinPort.h83
-rw-r--r--win/tclWinReg.c184
-rw-r--r--win/tclWinSerial.c382
-rw-r--r--win/tclWinSock.c923
-rw-r--r--win/tclWinTest.c87
-rw-r--r--win/tclWinThrd.c131
-rw-r--r--win/tclWinTime.c865
-rw-r--r--win/tclooConfig.sh2
-rw-r--r--win/tclsh.exe.manifest.in2
-rw-r--r--win/tclsh.rc22
-rw-r--r--win/tcltest.exe.manifest.in53
-rw-r--r--win/tcltest.rc16
-rw-r--r--win/vctool.bat174
-rwxr-xr-xwin/x86_64-w64-mingw32-nmakehlp.exebin25600 -> 25088 bytes
42 files changed, 10257 insertions, 8562 deletions
diff --git a/win/Makefile.in b/win/Makefile.in
index 63bd318..7a56163 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -53,7 +53,7 @@ LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir)
SCRIPT_INSTALL_DIR = $(INSTALL_ROOT)$(TCL_LIBRARY)
# Path name to use when installing Tcl modules.
-MODULE_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)/../tcl8
+MODULE_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)/../tcl9
# Directory in which to install the include file tcl.h:
INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir)
@@ -73,9 +73,6 @@ MAN3_INSTALL_DIR = $(MAN_INSTALL_DIR)/man3
# 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
-TCL_DBGX = @TCL_DBGX@
-
# warning flags
CFLAGS_WARNING = @CFLAGS_WARNING@
@@ -88,7 +85,7 @@ CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@
#CFLAGS = $(CFLAGS_DEBUG)
#CFLAGS = $(CFLAGS_OPTIMIZE)
#CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE)
-CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -D_ATL_XP_TARGETING=1 -D__USE_MINGW_ANSI_STDIO=0 -DMP_FIXED_CUTOFFS -DMP_NO_STDINT
+CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DMP_FIXED_CUTOFFS -D__USE_MINGW_ANSI_STDIO=0
# To compile without backward compatibility and deprecated code uncomment the
# following
@@ -104,11 +101,14 @@ COMPILE_DEBUG_FLAGS =
SRC_DIR = @srcdir@
ROOT_DIR = @srcdir@/..
TOP_DIR = $(shell cd @srcdir@/..; pwd -W 2>/dev/null || pwd -P)
+BUILD_DIR = @builddir@
GENERIC_DIR = $(TOP_DIR)/generic
WIN_DIR = $(TOP_DIR)/win
COMPAT_DIR = $(TOP_DIR)/compat
PKGS_DIR = $(TOP_DIR)/pkgs
+TOOL_DIR = $(TOP_DIR)/tools
ZLIB_DIR = $(COMPAT_DIR)/zlib
+MINIZIP_DIR = $(ZLIB_DIR)/contrib/minizip
TOMMATH_DIR = $(TOP_DIR)/libtommath
# Converts a POSIX path to a Windows native path.
@@ -122,17 +122,15 @@ TCL_LIBRARY_NATIVE = $(shell $(CYGPATH) '$(TCL_LIBRARY)')
GENERIC_DIR_NATIVE = $(shell $(CYGPATH) '$(GENERIC_DIR)')
WIN_DIR_NATIVE = $(shell $(CYGPATH) '$(WIN_DIR)')
ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)')
+TOOL_DIR_NATIVE = $(shell $(CYGPATH) '$(TOOL_DIR)')
SCRIPT_INSTALL_DIR_NATIVE = $(shell $(CYGPATH) '$(SCRIPT_INSTALL_DIR)')
INCLUDE_INSTALL_DIR_NATIVE = $(shell $(CYGPATH) '$(INCLUDE_INSTALL_DIR)')
MAN_INSTALL_DIR_NATIVE = $(shell $(CYGPATH) '$(MAN_INSTALL_DIR)')
ROOT_DIR_WIN_NATIVE = $(shell cd '$(ROOT_DIR)' ; pwd -W 2>/dev/null || pwd -P)
ZLIB_DIR_NATIVE = $(shell $(CYGPATH) '$(ZLIB_DIR)')
+MINIZIP_DIR_NATIVE = $(shell $(CYGPATH) '$(MINIZIP_DIR)')
TOMMATH_DIR_NATIVE = $(shell $(CYGPATH) '$(TOMMATH_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 -P)
-LIBRARY_DIR = $(shell $(CYGPATH) '$(LIBRARY_DIR1)')
DLLSUFFIX = @DLLSUFFIX@
LIBSUFFIX = @LIBSUFFIX@
EXESUFFIX = @EXESUFFIX@
@@ -144,30 +142,37 @@ 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_ZIP_FILE = @TCL_ZIP_FILE@
+TCL_VFS_PATH = libtcl.vfs/tcl_library
+TCL_VFS_ROOT = libtcl.vfs
+
+
TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@
TCL_DLL_FILE = @TCL_DLL_FILE@
TCL_LIB_FILE = @TCL_LIB_FILE@
-DDE_DLL_FILE = tcldde$(DDEVER)${DLLSUFFIX}
+DDE_DLL_FILE = tcl9dde$(DDEVER)${DLLSUFFIX}
+DDE_DLL_FILE8 = tcldde$(DDEVER)${DLLSUFFIX}
DDE_LIB_FILE = @LIBPREFIX@tcldde$(DDEVER)${DLLSUFFIX}${LIBSUFFIX}
-REG_DLL_FILE = tclreg$(REGVER)${DLLSUFFIX}
-REG_LIB_FILE = @LIBPREFIX@tclreg$(REGVER)${DLLSUFFIX}${LIBSUFFIX}
+REG_DLL_FILE = tcl9registry$(REGVER)${DLLSUFFIX}
+REG_DLL_FILE8 = tclregistry$(REGVER)${DLLSUFFIX}
+REG_LIB_FILE = @LIBPREFIX@tclregistry$(REGVER)${DLLSUFFIX}${LIBSUFFIX}
TEST_DLL_FILE = tcltest$(VER)${DLLSUFFIX}
TEST_EXE_FILE = tcltest${EXESUFFIX}
TEST_LIB_FILE = @LIBPREFIX@tcltest$(VER)${DLLSUFFIX}${LIBSUFFIX}
TEST_LOAD_PRMS = lappend ::auto_path {$(ROOT_DIR_WIN_NATIVE)/tests};\
- package ifneeded dde 1.4.4 [list load ${DDE_DLL_FILE} Dde];\
- package ifneeded registry 1.3.5 [list load ${REG_DLL_FILE} Registry]
-TEST_LOAD_FACILITIES = package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load ${TEST_DLL_FILE}];\
+ package ifneeded dde 1.4.5 [list load ${DDE_DLL_FILE}];\
+ package ifneeded registry 1.3.7 [list load ${REG_DLL_FILE}]
+TEST_LOAD_FACILITIES = package ifneeded tcl::test ${VERSION}@TCL_PATCH_LEVEL@ [list load ${TEST_DLL_FILE} Tcltest];\
$(TEST_LOAD_PRMS)
ZLIB_DLL_FILE = zlib1.dll
+TOMMATH_DLL_FILE = libtommath.dll
-SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@
+SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ @TOMMATH_DLL_FILE@
STATIC_LIBRARIES = $(TCL_LIB_FILE)
TCLSH = tclsh$(VER)${EXESUFFIX}
WINE = @WINE@
CAT32 = cat32$(EXEEXT)
-MAN2TCL = man2tcl$(EXEEXT)
# For cross-compiled builds, TCL_EXE is the name of a tclsh executable that is
# available *BEFORE* running make for the first time. Certain build targets
@@ -202,16 +207,64 @@ SHLIB_LD = @SHLIB_LD@
SHLIB_LD_LIBS = @SHLIB_LD_LIBS@
SHLIB_CFLAGS = @SHLIB_CFLAGS@
SHLIB_SUFFIX = @SHLIB_SUFFIX@
-LIBS = @LIBS@ $(shell $(CYGPATH) '@ZLIB_LIBS@')
+LIBS = @LIBS@ $(shell $(CYGPATH) '@ZLIB_LIBS@') $(shell $(CYGPATH) '@TOMMATH_LIBS@')
RMDIR = rm -rf
MKDIR = mkdir -p
SHELL = @SHELL@
RM = rm -f
COPY = cp
+LN = ln
GDB = gdb
-CC_SWITCHES = -I"${GENERIC_DIR_NATIVE}" -I"${TOMMATH_DIR_NATIVE}" \
+###
+# Tip 430 - ZipFS Modifications
+###
+
+TCL_ZIP_FILE = @TCL_ZIP_FILE@
+TCL_VFS_PATH = libtcl.vfs/tcl_library
+TCL_VFS_ROOT = libtcl.vfs
+
+HOST_CC = @CC_FOR_BUILD@
+HOST_EXEEXT = @EXEEXT_FOR_BUILD@
+HOST_OBJEXT = @OBJEXT_FOR_BUILD@
+ZIPFS_BUILD = @ZIPFS_BUILD@
+NATIVE_ZIP = @ZIP_PROG@
+ZIP_PROG_OPTIONS = @ZIP_PROG_OPTIONS@
+ZIP_PROG_VFSSEARCH = @ZIP_PROG_VFSSEARCH@
+SHARED_BUILD = @SHARED_BUILD@
+INSTALL_MSGS = @INSTALL_MSGS@
+INSTALL_LIBRARIES = @INSTALL_LIBRARIES@
+
+# Fully qualify library path so that `make test`
+# does not depend on the current directory.
+# Only define these if not embedding the library
+ifeq ($(ZIPFS_BUILD), 0)
+LIBRARY_DIR1 = $(shell cd '$(ROOT_DIR_NATIVE)/library' ; pwd -P)
+LIBRARY_DIR = $(shell $(CYGPATH) '$(LIBRARY_DIR1)')
+endif
+
+# Minizip
+MINIZIP_OBJS = \
+ adler32.$(HOST_OBJEXT) \
+ compress.$(HOST_OBJEXT) \
+ crc32.$(HOST_OBJEXT) \
+ deflate.$(HOST_OBJEXT) \
+ infback.$(HOST_OBJEXT) \
+ inffast.$(HOST_OBJEXT) \
+ inflate.$(HOST_OBJEXT) \
+ inftrees.$(HOST_OBJEXT) \
+ ioapi.$(HOST_OBJEXT) \
+ iowin32.$(HOST_OBJEXT) \
+ trees.$(HOST_OBJEXT) \
+ uncompr.$(HOST_OBJEXT) \
+ zip.$(HOST_OBJEXT) \
+ zutil.$(HOST_OBJEXT) \
+ minizip.$(HOST_OBJEXT)
+
+ZIP_INSTALL_OBJS = @ZIP_INSTALL_OBJS@
+
+CC_SWITCHES = -I"${BUILD_DIR}" -I"${GENERIC_DIR_NATIVE}" -I"${TOMMATH_DIR_NATIVE}" \
-I"${ZLIB_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \
${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} -DMP_PREC=4 \
${AC_FLAGS} ${COMPILE_DEBUG_FLAGS} ${NO_DEPRECATED_FLAGS}
@@ -226,6 +279,7 @@ ${AC_FLAGS} ${COMPILE_DEBUG_FLAGS}
TCLTEST_OBJS = \
tclTest.$(OBJEXT) \
+ tclTestABSList.$(OBJEXT) \
tclTestObj.$(OBJEXT) \
tclTestProcBodyObj.$(OBJEXT) \
tclThreadTest.$(OBJEXT) \
@@ -237,12 +291,14 @@ GENERIC_OBJS = \
regfree.$(OBJEXT) \
regerror.$(OBJEXT) \
tclAlloc.$(OBJEXT) \
+ tclArithSeries.$(OBJEXT) \
tclAssembly.$(OBJEXT) \
tclAsync.$(OBJEXT) \
tclBasic.$(OBJEXT) \
tclBinary.$(OBJEXT) \
tclCkalloc.$(OBJEXT) \
tclClock.$(OBJEXT) \
+ tclClockFmt.$(OBJEXT) \
tclCmdAH.$(OBJEXT) \
tclCmdIL.$(OBJEXT) \
tclCmdMZ.$(OBJEXT) \
@@ -265,6 +321,7 @@ GENERIC_OBJS = \
tclGet.$(OBJEXT) \
tclHash.$(OBJEXT) \
tclHistory.$(OBJEXT) \
+ tclIcu.$(OBJEXT) \
tclIndexObj.$(OBJEXT) \
tclInterp.$(OBJEXT) \
tclIO.$(OBJEXT) \
@@ -288,6 +345,7 @@ GENERIC_OBJS = \
tclOODefineCmds.$(OBJEXT) \
tclOOInfo.$(OBJEXT) \
tclOOMethod.$(OBJEXT) \
+ tclOOProp.$(OBJEXT) \
tclOOStubInit.$(OBJEXT) \
tclObj.$(OBJEXT) \
tclOptimize.$(OBJEXT) \
@@ -300,11 +358,13 @@ GENERIC_OBJS = \
tclPosixStr.$(OBJEXT) \
tclPreserve.$(OBJEXT) \
tclProc.$(OBJEXT) \
+ tclProcess.$(OBJEXT) \
tclRegexp.$(OBJEXT) \
tclResolve.$(OBJEXT) \
tclResult.$(OBJEXT) \
tclScan.$(OBJEXT) \
tclStringObj.$(OBJEXT) \
+ tclStrIdxTree.$(OBJEXT) \
tclStrToD.$(OBJEXT) \
tclStubInit.$(OBJEXT) \
tclThread.$(OBJEXT) \
@@ -317,6 +377,7 @@ GENERIC_OBJS = \
tclUtf.$(OBJEXT) \
tclUtil.$(OBJEXT) \
tclVar.$(OBJEXT) \
+ tclZipfs.$(OBJEXT) \
tclZlib.$(OBJEXT)
TOMMATH_OBJS = \
@@ -339,12 +400,15 @@ TOMMATH_OBJS = \
bn_s_mp_div_3.${OBJEXT} \
bn_mp_exch.${OBJEXT} \
bn_mp_expt_n.${OBJEXT} \
+ bn_mp_get_mag_u64.${OBJEXT} \
bn_mp_grow.${OBJEXT} \
bn_mp_init.${OBJEXT} \
bn_mp_init_copy.${OBJEXT} \
+ bn_mp_init_i64.${OBJEXT} \
bn_mp_init_multi.${OBJEXT} \
bn_mp_init_set.${OBJEXT} \
bn_mp_init_size.${OBJEXT} \
+ bn_mp_init_u64.${OBJEXT} \
bn_mp_lshd.${OBJEXT} \
bn_mp_mod.${OBJEXT} \
bn_mp_mod_2d.${OBJEXT} \
@@ -360,7 +424,8 @@ TOMMATH_OBJS = \
bn_mp_radix_smap.${OBJEXT} \
bn_mp_read_radix.${OBJEXT} \
bn_mp_rshd.${OBJEXT} \
- bn_mp_set.${OBJEXT} \
+ bn_mp_set_i64.${OBJEXT} \
+ bn_mp_set_u64.${OBJEXT} \
bn_mp_shrink.${OBJEXT} \
bn_mp_sqr.${OBJEXT} \
bn_mp_sqrt.${OBJEXT} \
@@ -409,8 +474,11 @@ REG_OBJS = tclWinReg.$(OBJEXT)
STUB_OBJS = \
tclStubLib.$(OBJEXT) \
+ tclStubCall.$(OBJEXT) \
+ tclStubLibTbl.$(OBJEXT) \
tclTomMathStubLib.$(OBJEXT) \
- tclOOStubLib.$(OBJEXT)
+ tclOOStubLib.$(OBJEXT) \
+ tclWinPanic.$(OBJEXT)
TCLSH_OBJS = tclAppInit.$(OBJEXT)
@@ -427,7 +495,7 @@ ZLIB_OBJS = \
uncompr.$(OBJEXT) \
zutil.$(OBJEXT)
-TCL_OBJS = ${GENERIC_OBJS} ${WIN_OBJS} @ZLIB_OBJS@ $(TOMMATH_OBJS)
+TCL_OBJS = ${GENERIC_OBJS} ${WIN_OBJS} @ZLIB_OBJS@ @TOMMATH_OBJS@
TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n]
@@ -464,19 +532,41 @@ tcltest.sh: tcltest.cmd
tcltest: binaries $(TEST_EXE_FILE) $(TEST_DLL_FILE) $(CAT32) tcltest.cmd
-binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions $(TCLSH)
+binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions ${TCL_ZIP_FILE} $(TCLSH)
-winextensions: ${DDE_DLL_FILE} ${REG_DLL_FILE}
+winextensions: ${DDE_DLL_FILE} ${REG_DLL_FILE} ${DDE_DLL_FILE8} ${REG_DLL_FILE8}
libraries:
doc:
-$(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES)
+tclzipfile: ${TCL_ZIP_FILE}
+
+${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} ${DDE_DLL_FILE} ${REG_DLL_FILE}
+ @rm -rf ${TCL_VFS_ROOT}
+ @mkdir -p ${TCL_VFS_PATH}
+ @echo "creating ${TCL_VFS_PATH} (prepare compression)"
+ @( \
+ $(COPY) -a $(TOP_DIR)/library/* ${TCL_VFS_PATH}; \
+ $(COPY) -a ${TCL_VFS_PATH}/manifest.txt ${TCL_VFS_PATH}/pkgIndex.tcl; \
+ rm -rf ${TCL_VFS_PATH}/dde; \
+ rm -rf ${TCL_VFS_PATH}/registry; \
+ )
+ (zip=`(realpath '${NATIVE_ZIP}' || readlink -m '${NATIVE_ZIP}') 2>/dev/null || \
+ (echo '${NATIVE_ZIP}' | sed "s?^\./?$$(pwd)/?")`; \
+ cd ${TCL_VFS_ROOT} && \
+ $$zip ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} >/dev/null && \
+ echo "${TCL_ZIP_FILE} successful created with $$zip" && \
+ cd ..)
+
+$(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) ${TCL_ZIP_FILE}
$(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \
tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE)
$(COPY) tclsh.exe.manifest $(TCLSH).manifest
@VC_MANIFEST_EMBED_EXE@
+ @if test "${ZIPFS_BUILD}" = "2" ; then \
+ cat ${TCL_ZIP_FILE} >> ${TCLSH}; \
+ fi
cat32.$(OBJEXT): cat.c
$(CC) -c $(CC_SWITCHES) -DUNICODE -D_UNICODE @DEPARG@ $(CC_OBJNAME)
@@ -487,24 +577,27 @@ $(CAT32): cat32.$(OBJEXT)
# The following targets are configured by autoconf to generate either a shared
# library or static library
-${TCL_STUB_LIB_FILE}: ${STUB_OBJS}
+${TCL_STUB_LIB_FILE}: ${STUB_OBJS} ${DDE_OBJS} ${REG_OBJS}
@$(RM) ${TCL_STUB_LIB_FILE}
- @MAKE_STUB_LIB@ ${STUB_OBJS}
+ @MAKE_STUB_LIB@ ${STUB_OBJS} ${DDE_OBJS} ${REG_OBJS}
@POST_MAKE_LIB@
-${TCL_DLL_FILE}: ${TCL_LIB_FILE} ${TCL_OBJS} tcl.$(RES)
+${TCL_DLL_FILE}: ${TCL_LIB_FILE} ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ @TOMMATH_DLL_FILE@ ${TCL_ZIP_FILE}
@$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE)
@MAKE_DLL@ ${TCL_OBJS} tcl.$(RES) $(SHLIB_LD_LIBS)
$(COPY) tclsh.exe.manifest ${TCL_DLL_FILE}.manifest
@VC_MANIFEST_EMBED_DLL@
+ @if test "${ZIPFS_BUILD}" = "1" ; then \
+ cat ${TCL_ZIP_FILE} >> ${TCL_DLL_FILE}; \
+ fi
ifeq (,$(findstring --disable-shared,$(PKG_CFG_ARGS)))
${TCL_LIB_FILE}:
@$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE)
else
-${TCL_LIB_FILE}: ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS}
+${TCL_LIB_FILE}: ${TCL_OBJS} tclWinPanic.$(OBJEXT) ${DDE_OBJS} ${REG_OBJS}
@$(RM) ${TCL_LIB_FILE}
- @MAKE_LIB@ ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS}
+ @MAKE_LIB@ ${TCL_OBJS} tclWinPanic.$(OBJEXT) ${DDE_OBJS} ${REG_OBJS}
@POST_MAKE_LIB@
endif
@@ -516,6 +609,14 @@ ${REG_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${REG_OBJS}
@MAKE_DLL@ ${REG_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
$(COPY) tclsh.exe.manifest ${REG_DLL_FILE}.manifest
+${DDE_DLL_FILE8}: ${TCL_STUB_LIB_FILE} tcl8WinDde.$(OBJEXT)
+ @MAKE_DLL@ tcl8WinDde.$(OBJEXT) $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
+ $(COPY) tclsh.exe.manifest ${DDE_DLL_FILE8}.manifest
+
+${REG_DLL_FILE8}: ${TCL_STUB_LIB_FILE} tcl8WinReg.$(OBJEXT)
+ @MAKE_DLL@ -DTCL_MAJOR_VERSION=8 tcl8WinReg.$(OBJEXT) $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
+ $(COPY) tclsh.exe.manifest ${REG_DLL_FILE8}.manifest
+
${TEST_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS}
@$(RM) ${TEST_DLL_FILE} ${TEST_LIB_FILE}
@MAKE_DLL@ ${TCLTEST_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
@@ -524,7 +625,7 @@ ${TEST_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS}
${TEST_EXE_FILE}: @LIBRARIES@ ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS} tclTestMain.${OBJEXT}
@$(RM) ${TEST_EXE_FILE}
$(CC) $(CFLAGS) $(TCLTEST_OBJS) tclTestMain.$(OBJEXT) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \
- tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE)
+ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE)
$(COPY) tclsh.exe.manifest ${TEST_EXE_FILE}.manifest
# use prebuilt zlib1.dll
@@ -539,6 +640,18 @@ ${ZLIB_DLL_FILE}: ${TCL_STUB_LIB_FILE}
$(COPY) $(ZLIB_DIR)/win64/${ZLIB_DLL_FILE} ${ZLIB_DLL_FILE}; \
fi;
+# use pre-built libtommath.dll
+${TOMMATH_DLL_FILE}: ${TCL_STUB_LIB_FILE}
+ @if test "@TOMMATH_LIBS@set" = "${TOMMATH_DIR_NATIVE}/win64-arm/tommath.libset" ; then \
+ $(COPY) $(TOMMATH_DIR)/win64-arm/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \
+ elif test "@TOMMATH_LIBS@set" = "${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.aset" ; then \
+ $(COPY) $(TOMMATH_DIR)/win64-arm/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \
+ elif test "@TOMMATH_LIBS@set" = "${TOMMATH_DIR_NATIVE}/win32/tommath.libset" ; then \
+ $(COPY) $(TOMMATH_DIR)/win32/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \
+ else \
+ $(COPY) $(TOMMATH_DIR)/win64/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \
+ fi;
+
# Add the object extension to the implicit rules. By default .obj is not
# automatically added.
@@ -560,15 +673,27 @@ tclWinPipe.${OBJEXT}: tclWinPipe.c
tclWinReg.${OBJEXT}: tclWinReg.c
$(CC) -c $(CC_SWITCHES) $(EXTFLAGS) @DEPARG@ $(CC_OBJNAME)
+tcl8WinReg.${OBJEXT}: tclWinReg.c
+ $(CC) -o $@ -c $(CC_SWITCHES) -DTCL_MAJOR_VERSION=8 $(EXTFLAGS) @DEPARG@ $(CC_OBJNAME)
+
tclWinDde.${OBJEXT}: tclWinDde.c
$(CC) -c $(CC_SWITCHES) $(EXTFLAGS) @DEPARG@ $(CC_OBJNAME)
+tcl8WinDde.${OBJEXT}: tclWinDde.c
+ $(CC) -o $@ -c $(CC_SWITCHES) -DTCL_MAJOR_VERSION=8 $(EXTFLAGS) @DEPARG@ $(CC_OBJNAME)
+
tclAppInit.${OBJEXT}: tclAppInit.c
$(CC) -c $(CC_SWITCHES) $(EXTFLAGS) -DUNICODE -D_UNICODE @DEPARG@ $(CC_OBJNAME)
tclMainW.${OBJEXT}: tclMain.c
$(CC) -c $(CC_SWITCHES) -DBUILD_tcl -DUNICODE -D_UNICODE @DEPARG@ $(CC_OBJNAME)
+# TIP #430, ZipFS Support
+tclZipfs.${OBJEXT}: $(GENERIC_DIR)/tclZipfs.c
+ $(CC) -c $(CC_SWITCHES) -DBUILD_tcl \
+ $(ZLIB_INCLUDE) -I$(MINIZIP_DIR_NATIVE) @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
@@ -590,11 +715,14 @@ tclPkgConfig.${OBJEXT}: tclPkgConfig.c
-DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY_NATIVE)\"" \
-DCFG_RUNTIME_INCDIR="\"$(includedir_native)\"" \
-DCFG_RUNTIME_DOCDIR="\"$(mandir_native)\"" \
+ -DCFG_RUNTIME_DLLFILE="\"$(TCL_DLL_FILE)\"" \
-DBUILD_tcl \
@DEPARG@ $(CC_OBJNAME)
tclEvent.${OBJEXT}: tclEvent.c tclUuid.h
+tclTest.${OBJEXT}: tclTest.c tclUuid.h
+
$(TOP_DIR)/manifest.uuid:
printf "git-" >$(TOP_DIR)/manifest.uuid
(cd $(TOP_DIR); git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid || \
@@ -613,12 +741,24 @@ tclUuid.h: $(TOP_DIR)/manifest.uuid
tclStubLib.${OBJEXT}: tclStubLib.c
$(CC) -c $(CC_SWITCHES) -DSTATIC_BUILD @CFLAGS_NOLTO@ @DEPARG@ $(CC_OBJNAME)
+tclStubCall.${OBJEXT}: tclStubCall.c
+ $(CC) -c $(CC_SWITCHES) -DSTATIC_BUILD \
+ -DCFG_RUNTIME_DLLFILE="\"$(TCL_DLL_FILE)\"" \
+ -DCFG_RUNTIME_BINDIR="\"$(bindir_native)\"" \
+ @DEPARG@ $(CC_OBJNAME)
+
+tclStubLibTbl.${OBJEXT}: tclStubLibTbl.c
+ $(CC) -c $(CC_SWITCHES) -DSTATIC_BUILD @DEPARG@ $(CC_OBJNAME)
+
tclTomMathStubLib.${OBJEXT}: tclTomMathStubLib.c
$(CC) -c $(CC_SWITCHES) @CFLAGS_NOLTO@ @DEPARG@ $(CC_OBJNAME)
tclOOStubLib.${OBJEXT}: tclOOStubLib.c
$(CC) -c $(CC_SWITCHES) @CFLAGS_NOLTO@ @DEPARG@ $(CC_OBJNAME)
+tclWinPanic.${OBJEXT}: tclWinPanic.c
+ $(CC) -c $(CC_SWITCHES) -DSTATIC_BUILD @DEPARG@ $(CC_OBJNAME)
+
# Implicit rule for all object files that will end up in the Tcl library
%.${OBJEXT}: %.c
@@ -627,6 +767,59 @@ tclOOStubLib.${OBJEXT}: tclOOStubLib.c
.rc.$(RES):
$(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(WIN_DIR_NATIVE)" @DEPARG@
+
+
+#--------------------------------------------------------------------------
+# Minizip implementation
+#--------------------------------------------------------------------------
+adler32.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/adler32.c
+
+compress.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/compress.c
+
+crc32.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/crc32.c
+
+deflate.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/deflate.c
+
+ioapi.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c
+
+iowin32.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/iowin32.c
+
+infback.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/infback.c
+
+inffast.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inffast.c
+
+inflate.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inflate.c
+
+inftrees.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inftrees.c
+
+trees.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/trees.c
+
+uncompr.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/uncompr.c
+
+zip.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/zip.c
+
+zutil.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/zutil.c
+
+minizip.$(HOST_OBJEXT):
+ $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c
+
+minizip${HOST_EXEEXT}: $(MINIZIP_OBJS)
+ $(HOST_CC) -o $@ $(MINIZIP_OBJS)
+
# 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
@@ -639,15 +832,15 @@ gendate:
--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.
+INSTALL_BASE_TARGETS = install-binaries $(INSTALL_LIBRARIES) $(INSTALL_MSGS) $(INSTALL_TZDATA)
+INSTALL_DOC_TARGETS = install-doc
+INSTALL_PACKAGE_TARGETS = install-packages
+INSTALL_DEV_TARGETS = install-headers
+INSTALL_EXTRA_TARGETS =
+INSTALL_TARGETS = $(INSTALL_BASE_TARGETS) $(INSTALL_DOC_TARGETS) $(INSTALL_DEV_TARGETS) \
+ $(INSTALL_PACKAGE_TARGETS) $(INSTALL_EXTRA_TARGETS)
-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-packages
+install: $(INSTALL_TARGETS)
install-binaries: binaries
@for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)"; \
@@ -659,7 +852,7 @@ install-binaries: binaries
else true; \
fi; \
done;
- @for i in dde${DDEDOTVER} reg${REGDOTVER}; \
+ @for i in dde${DDEDOTVER} registry${REGDOTVER}; \
do \
if [ ! -d "$(LIB_INSTALL_DIR)/$$i" ] ; then \
echo "Making directory $(LIB_INSTALL_DIR)/$$i"; \
@@ -667,14 +860,14 @@ install-binaries: binaries
else true; \
fi; \
done;
- @for i in $(TCL_DLL_FILE) $(ZLIB_DLL_FILE) $(TCLSH); \
+ @for i in $(TCL_DLL_FILE) $(ZLIB_DLL_FILE) $(TOMMATH_DLL_FILE) $(TCLSH); \
do \
if [ -f $$i ]; then \
echo "Installing $$i to $(BIN_INSTALL_DIR)/"; \
$(COPY) $$i "$(BIN_INSTALL_DIR)"; \
fi; \
done
- @for i in tclConfig.sh tclooConfig.sh $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE); \
+ @for i in tclConfig.sh tclooConfig.sh $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) @ZLIB_LIBS@ @TOMMATH_LIBS@; \
do \
if [ -f $$i ]; then \
echo "Installing $$i to $(LIB_INSTALL_DIR)/"; \
@@ -687,19 +880,27 @@ install-binaries: binaries
$(COPY) $(ROOT_DIR)/library/dde/pkgIndex.tcl \
"$(LIB_INSTALL_DIR)/dde${DDEDOTVER}"; \
fi
+ @if [ -f $(DDE_DLL_FILE8) ]; then \
+ echo Installing $(DDE_DLL_FILE8); \
+ $(COPY) $(DDE_DLL_FILE8) "$(LIB_INSTALL_DIR)/dde${DDEDOTVER}"; \
+ fi
@if [ -f $(DDE_LIB_FILE) ]; then \
echo Installing $(DDE_LIB_FILE); \
$(COPY) $(DDE_LIB_FILE) "$(LIB_INSTALL_DIR)/dde${DDEDOTVER}"; \
fi
@if [ -f $(REG_DLL_FILE) ]; then \
echo Installing $(REG_DLL_FILE); \
- $(COPY) $(REG_DLL_FILE) "$(LIB_INSTALL_DIR)/reg${REGDOTVER}"; \
- $(COPY) $(ROOT_DIR)/library/reg/pkgIndex.tcl \
- "$(LIB_INSTALL_DIR)/reg${REGDOTVER}"; \
+ $(COPY) $(REG_DLL_FILE) "$(LIB_INSTALL_DIR)/registry${REGDOTVER}"; \
+ $(COPY) $(ROOT_DIR)/library/registry/pkgIndex.tcl \
+ "$(LIB_INSTALL_DIR)/registry${REGDOTVER}"; \
+ fi
+ @if [ -f $(REG_DLL_FILE8) ]; then \
+ echo Installing $(REG_DLL_FILE8); \
+ $(COPY) $(REG_DLL_FILE8) "$(LIB_INSTALL_DIR)/registry${REGDOTVER}"; \
fi
@if [ -f $(REG_LIB_FILE) ]; then \
echo Installing $(REG_LIB_FILE); \
- $(COPY) $(REG_LIB_FILE) "$(LIB_INSTALL_DIR)/reg${REGDOTVER}"; \
+ $(COPY) $(REG_LIB_FILE) "$(LIB_INSTALL_DIR)/registry${REGDOTVER}"; \
fi
install-libraries: libraries install-tzdata install-msgs
@@ -712,7 +913,7 @@ install-libraries: libraries install-tzdata install-msgs
else true; \
fi; \
done;
- @for i in http1.0 opt0.4 encoding; \
+ @for i in opt0.4 cookiejar0.2 encoding; \
do \
if [ ! -d "$(SCRIPT_INSTALL_DIR)/$$i" ] ; then \
echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
@@ -720,7 +921,7 @@ install-libraries: libraries install-tzdata install-msgs
else true; \
fi; \
done;
- @for i in 8.4 8.4/platform 8.5 8.6; \
+ @for i in 9.0 9.0/platform; \
do \
if [ ! -d "$(MODULE_INSTALL_DIR)/$$i" ] ; then \
echo "Making directory $(MODULE_INSTALL_DIR)/$$i"; \
@@ -728,40 +929,29 @@ install-libraries: libraries install-tzdata install-msgs
else true; \
fi; \
done;
- @echo "Installing header files";
- @for i in "$(GENERIC_DIR)/tcl.h" "$(GENERIC_DIR)/tclDecls.h" \
- "$(GENERIC_DIR)/tclOO.h" "$(GENERIC_DIR)/tclOODecls.h" \
- "$(GENERIC_DIR)/tclPlatDecls.h" \
- "$(GENERIC_DIR)/tclTomMath.h" \
- "$(GENERIC_DIR)/tclTomMathDecls.h"; \
- do \
- $(COPY) "$$i" "$(INCLUDE_INSTALL_DIR)"; \
- done;
@echo "Installing library files to $(SCRIPT_INSTALL_DIR)";
- @for i in $(ROOT_DIR)/library/*.tcl $(ROOT_DIR)/library/tclIndex; \
- do \
+ @for i in $(ROOT_DIR)/library/*.tcl $(ROOT_DIR)/library/tclIndex; do \
$(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)"; \
done;
- @echo "Installing library http1.0 directory";
- @for j in $(ROOT_DIR)/library/http1.0/*.tcl; \
- do \
- $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/http1.0"; \
+ @echo "Installing package cookiejar 0.2"
+ @for j in $(ROOT_DIR)/library/cookiejar/*.tcl \
+ $(ROOT_DIR)/library/cookiejar/*.gz; do \
+ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/cookiejar0.2"; \
done;
- @echo "Installing package http 2.9.8 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/http/http.tcl "$(MODULE_INSTALL_DIR)/8.6/http-2.9.8.tm";
- @echo "Installing library opt0.4 directory";
- @for j in $(ROOT_DIR)/library/opt/*.tcl; \
- do \
+ @echo "Installing package http 2.10.0 as a Tcl Module";
+ @$(COPY) $(ROOT_DIR)/library/http/http.tcl "$(MODULE_INSTALL_DIR)/9.0/http-2.10.0.tm";
+ @echo "Installing package opt 0.4.7";
+ @for j in $(ROOT_DIR)/library/opt/*.tcl; do \
$(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \
done;
- @echo "Installing package msgcat 1.6.1 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl "$(MODULE_INSTALL_DIR)/8.5/msgcat-1.6.1.tm";
+ @echo "Installing package msgcat 1.7.1 as a Tcl Module";
+ @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl "$(MODULE_INSTALL_DIR)/9.0/msgcat-1.7.1.tm";
@echo "Installing package tcltest 2.5.9 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl "$(MODULE_INSTALL_DIR)/8.5/tcltest-2.5.9.tm";
+ @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl "$(MODULE_INSTALL_DIR)/9.0/tcltest-2.5.9.tm";
@echo "Installing package platform 1.0.19 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl "$(MODULE_INSTALL_DIR)/8.4/platform-1.0.19.tm";
+ @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl "$(MODULE_INSTALL_DIR)/9.0/platform-1.0.19.tm";
@echo "Installing package platform::shell 1.1.4 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/platform/shell.tcl "$(MODULE_INSTALL_DIR)/8.4/platform/shell-1.1.4.tm";
+ @$(COPY) $(ROOT_DIR)/library/platform/shell.tcl "$(MODULE_INSTALL_DIR)/9.0/platform/shell-1.1.4.tm";
@echo "Installing encodings";
@for i in $(ROOT_DIR)/library/encoding/*.enc ; do \
$(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)/encoding"; \
@@ -779,6 +969,27 @@ install-msgs:
install-doc: doc
+install-headers:
+ @for i in "$(INCLUDE_INSTALL_DIR)"; \
+ do \
+ if [ ! -d "$$i" ] ; then \
+ echo "Making directory $$i"; \
+ $(MKDIR) "$$i"; \
+ chmod 755 "$$i"; \
+ else true; \
+ fi; \
+ done;
+ @echo "Installing header files to $(INCLUDE_INSTALL_DIR)/";
+ @for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \
+ $(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \
+ $(GENERIC_DIR)/tclPlatDecls.h \
+ $(GENERIC_DIR)/tclTomMath.h \
+ $(GENERIC_DIR)/tclTomMathDecls.h \
+ $(TOMMATH_DIR)/tommath.h ; \
+ do \
+ $(COPY) $$i "$(INCLUDE_INSTALL_DIR)"; \
+ done;
+
# Optional target to install private headers
install-private-headers: libraries
@for i in $(PRIVATE_INCLUDE_INSTALL_DIR); \
@@ -806,19 +1017,19 @@ test: test-tcl test-packages
test-tcl: tcltest
TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
- ./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \
+ $(WINE) ./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \
-load "$(TEST_LOAD_FACILITIES)"
# Useful target to launch a built tclsh with the proper path,...
runtest: tcltest
@TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
- ./$(TCLSH) $(TESTFLAGS) -load "$(TEST_LOAD_FACILITIES)" $(SCRIPT)
+ $(WINE) ./$(TCLSH) $(TESTFLAGS) -load "$(TEST_LOAD_FACILITIES)" $(SCRIPT)
# 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)
+ $(WINE) ./$(TCLSH) $(SCRIPT)
# This target can be used to run tclsh inside either gdb or insight
gdb: binaries
@@ -841,7 +1052,7 @@ Makefile: $(SRC_DIR)/Makefile.in
./config.status
cleanhelp:
- $(RM) *.hlp *.cnt *.GID *.rtf man2tcl.exe
+ $(RM) *.hlp *.cnt *.GID
clean: cleanhelp clean-packages
$(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out
@@ -850,11 +1061,12 @@ clean: cleanhelp clean-packages
find . -maxdepth 1 -type f -regex '\./tcl\(sh[^.]+\|test\|[^.]+.dll\)\.[^.]*\(\.manifest\)?' \
-a -not -name 'tclsh.exe.manifest' -exec rm {} \;
$(RM) *.pch *.ilk *.pdb *.zip
+ $(RM) minizip${HOST_EXEEXT} *.${HOST_OBJEXT}
$(RMDIR) *.vfs
distclean: distclean-packages clean
$(RM) Makefile config.status config.cache config.log tclConfig.sh \
- tcl.hpj config.status.lineno tclsh.exe.manifest tclUuid.h
+ config.status.lineno tclsh.exe.manifest tclUuid.h
#
# Bundled package targets
@@ -872,7 +1084,7 @@ packages:
if [ ! -f $(PKG_DIR)/$$pkg/Makefile ]; then \
( cd $(PKG_DIR)/$$pkg; \
echo "Configuring package '$$i' wd = `$(CYGPATH) $$(pwd -P)`"; \
- $$i/configure --with-tcl=$$builddir --with-tclinclude=$(GENERIC_DIR_NATIVE) $(PKG_CFG_ARGS) --enable-shared --enable-threads; ) \
+ $$i/configure --with-tcl=$$builddir --with-tclinclude=$(GENERIC_DIR_NATIVE) $(PKG_CFG_ARGS) --enable-shared; ) \
fi ; \
echo "Building package '$$pkg'"; \
( cd $(PKG_DIR)/$$pkg; $(MAKE); ) \
@@ -943,20 +1155,30 @@ $(GENERIC_DIR)/tclStubInit.c: $(GENERIC_DIR)/tcl.decls \
@echo "Developers may want to run \"make genstubs\" to regenerate."
@echo "This warning can be safely ignored, do not report as a bug!"
+$(GENERIC_DIR)/tclOOScript.h: $(TOOL_DIR)/tclOOScript.tcl
+ @echo "Warning: tclOOScript.h may be out of date."
+ @echo "Developers may want to run \"make genscript\" to regenerate."
+ @echo "This warning can be safely ignored, do not report as a bug!"
+
genstubs:
- $(TCL_EXE) -encoding utf-8 "$(ROOT_DIR_NATIVE)/tools/genStubs.tcl" \
+ $(TCL_EXE) "$(TOOL_DIR_NATIVE)/genStubs.tcl" \
"$(GENERIC_DIR_NATIVE)" \
"$(GENERIC_DIR_NATIVE)/tcl.decls" \
"$(GENERIC_DIR_NATIVE)/tclInt.decls" \
"$(GENERIC_DIR_NATIVE)/tclTomMath.decls"
- $(TCL_EXE) -encoding utf-8 "$(ROOT_DIR_NATIVE)/tools/genStubs.tcl" \
+ $(TCL_EXE) "$(TOOL_DIR_NATIVE)/genStubs.tcl" \
"$(GENERIC_DIR_NATIVE)" \
"$(GENERIC_DIR_NATIVE)/tclOO.decls"
+genscript:
+ $(TCL_EXE) "$(TOOL_DIR_NATIVE)/makeHeader.tcl" \
+ "$(TOOL_DIR_NATIVE)/tclOOScript.tcl" \
+ "$(GENERIC_DIR_NATIVE)/tclOOScript.h"
+
#
# This target creates the HTML folder for Tcl & Tk and places it in
# DISTDIR/html. It uses the tcltk-man2html.tcl tool from the Tcl group's tool
-# workspace. It depends on the Tcl & Tk being in directories called tcl8.* &
+# workspace. It depends on the Tcl & Tk being in directories called tcl9.* &
# tk8.* up two directories from the TOOL_DIR.
#
@@ -981,6 +1203,7 @@ html-tk: $(TCLSH)
.PHONY: install-doc install-private-headers test test-tcl runtest shell
.PHONY: gdb depend cleanhelp clean distclean packages install-packages
.PHONY: test-packages clean-packages distclean-packages genstubs html
-.PHONY: html-tcl html-tk
+.PHONY: html-tcl html-tk genscript
+.PHONY: tclzipfile
# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/win/README b/win/README
index 86e9e59..9b001ba 100644
--- a/win/README
+++ b/win/README
@@ -1,4 +1,4 @@
-Tcl 8.6 for Windows
+Tcl 9.0 for Windows
1. Introduction
---------------
@@ -16,11 +16,11 @@ The information in this file is maintained on the web at:
In order to compile Tcl for Windows, you need the following:
- Tcl 8.6 Source Distribution (plus any patches)
+ Tcl 9.0 Source Distribution (plus any patches)
and
- Visual C++ 6 or newer
+ Visual Studio 2015 or newer
or
@@ -80,11 +80,13 @@ 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 tclsh86.exe, you must ensure that tcl86.dll
-and zlib1.dll are on your path, in the system directory, or in the
-directory containing tclsh86.exe.
+Note that in order to run tclsh90.exe, you must ensure that tcl90.dll,
+libtommath.dll and zlib1.dll are on your path, in the system
+directory, or in the directory containing tclsh90.exe.
-Note: Tcl no longer provides support for Win32s.
+Note: Tcl no longer provides support for systems earlier than Windows 7.
+You will also need the Windows Universal C runtime (UCRT):
+ [https://support.microsoft.com/en-us/topic/update-for-universal-c-runtime-in-windows-c0514201-7fe6-95a3-b0a5-287930f3560c]
3. Test suite
-------------
diff --git a/win/buildall.vc.bat b/win/buildall.vc.bat
index deb9e39..941f27e 100644..100755
--- a/win/buildall.vc.bat
+++ b/win/buildall.vc.bat
@@ -38,7 +38,9 @@ if defined WINDOWSSDKDIR (goto :startBuilding)
:: might not be correct. You should call it yourself prior to running
:: this batchfile.
::
-call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat"
+REM call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat"
+set "VSCMD_START_DIR=%CD%"
+call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"
if errorlevel 1 (goto no_vcvars)
:startBuilding
@@ -66,8 +68,8 @@ if errorlevel 1 goto error
:: Build the static core and shell.
::
-set OPTS=static,msvcrt
-if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt
+set OPTS=static
+if not %SYMBOLS%.==. set OPTS=symbols,static
nmake -nologo -f makefile.vc shell OPTS=%OPTS% %1
if errorlevel 1 goto error
diff --git a/win/coffbase.txt b/win/coffbase.txt
deleted file mode 100644
index a0ea5cf..0000000
--- a/win/coffbase.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-;
-; This file defines the virtual base addresses for the Dynamic Link Libraries
-; that are part of the Tcl system. The first token on a line is the key (or name
-; of the DLL) and the second token is the virtual base address, in hexadecimal.
-; The third token is the maximum size of the DLL image file, including symbols.
-;
-; Using a specified "preferred load address" should speed loading time by avoiding
-; relocations (NT supported only). It is assumed extension authors will contribute
-; their modules to this grand-master list. You can use the dumpbin utility with
-; the /headers option to get the "size of image" data (already in hex). If the
-; maximum size is too small a linker warning will occur. Modules can overlap when
-; they're mutually exclusive. This info is placed in the DLL's PE header by the
-; linker with the `-base:@$(TCLDIR)\win\coffbase.txt,<key>` option.
-
-tcl 0x10000000 0x00200000
-tcldde 0x10200000 0x00010000
-tclreg 0x10210000 0x00010000
-tk 0x10220000 0x00200000
-expect 0x10480000 0x00080000
-itcl 0x10500000 0x00080000
-itk 0x10580000 0x00080000
-bltlite 0x10600000 0x00080000
-blt 0x10680000 0x00080000
-iocpsock 0x10700000 0x00080000
-tls 0x10780000 0x00100000
-winico 0x10880000 0x00010000
-sample 0x108B0000 0x00010000
-tile 0x10900000 0x00080000
-memchan 0x109D0000 0x00010000
-tdom 0x109E0000 0x00080000
-tclvfs 0x10A70000 0x00010000
-tkvideo 0x10B00000 0x00010000
-tclsdl 0x10B20000 0x00080000
-vqtcl 0x10C00000 0x00010000
-tdbc 0x10C40000 0x00010000
-thread 0x10C80000 0x00020000
-nsf 0x10ca0000 0x00080000
-;
-; insert new packages here
-;
-snack 0x1E000000 0x00400000
-sound 0x1E400000 0x00400000
-snackogg 0x1E800000 0x00200000
diff --git a/win/configure b/win/configure
index 7c44026..8ae43b4 100755
--- a/win/configure
+++ b/win/configure
@@ -1,81 +1,469 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for tcl 8.6.
+# Generated by GNU Autoconf 2.72 for tcl 9.0.
+#
+#
+# Copyright (C) 1992-1996, 1998-2017, 2020-2023 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. ##
-## --------------------- ##
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
emulate sh
NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # Pre-4.2 versions of Zsh do 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
+ setopt NO_GLOB_SUBST
+else case e in #(
+ e) case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac ;;
+esac
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
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
+as_nl='
+'
+export as_nl
+IFS=" "" $as_nl"
+
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
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2) ; then :; else exec 2>/dev/null; fi
+
+# The user is always right.
+if ${PATH_SEPARATOR+false} :; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
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
+ IFS=$as_save_IFS
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+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
+ printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed 'exec'.
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else case e in #(
+ e) case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" )
+then :
+
+else case e in #(
+ e) exitcode=1; echo positional parameters were not saved. ;;
+esac
+fi
+test x\$exitcode = x0 || exit 1
+blah=\$(echo \$(echo blah))
+test x\"\$blah\" = xblah || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null
+then :
+ as_have_required=yes
+else case e in #(
+ e) as_have_required=no ;;
+esac
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
+then :
+
+else case e in #(
+ e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
+then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
done
+IFS=$as_save_IFS
+if $as_found
+then :
+
+else case e in #(
+ e) if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi ;;
+esac
+fi
+
+
+ if test "x$CONFIG_SHELL" != x
+then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed 'exec'.
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno
+then :
+ printf "%s\n" "$0: This script requires a shell more modern than all"
+ printf "%s\n" "$0: the shells that I found on your system."
+ if test ${ZSH_VERSION+y} ; then
+ printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi ;;
+esac
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else case e in #(
+ e) as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ } ;;
+esac
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else case e in #(
+ e) as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ } ;;
+esac
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ printf "%s\n" "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
as_expr=expr
else
as_expr=false
fi
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
-# Name of the executable.
-as_me=`$as_basename "$0" ||
+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'`
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" 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'
@@ -83,238 +471,351 @@ 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 |
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
sed '
+ t clear
+ :clear
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
N
- s,$,-,
- : loop
- s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
t loop
- s,-$,,
- s,^['$as_cr_digits']*\n,,
+ s/-\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; }; }
+ chmod +x "$as_me.lineno" ||
+ { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# 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
+ # original and so on. Autoconf is especially sensitive 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= ;;
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
esac
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n. New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
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
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.
+ # In both cases, we have to default to 'cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
-rm -f conf$$ conf$$.exe conf$$.file
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
+ as_mkdir_p='mkdir -p "$as_dir"'
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
-as_executable_p="test -f"
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# 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'"
+as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated
# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
+as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+as_tr_sh="eval sed '$as_sed_sh'" # deprecated
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" $as_nl"
-
-# CDPATH.
-$as_unset CDPATH
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/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.
#
ac_default_prefix=/usr/local
+ac_clean_files=
ac_config_libobj_dir=.
+LIBOBJS=
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='tcl'
PACKAGE_TARNAME='tcl'
-PACKAGE_VERSION='8.6'
-PACKAGE_STRING='tcl 8.6'
+PACKAGE_VERSION='9.0'
+PACKAGE_STRING='tcl 9.0'
PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
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>
+#include <stddef.h>
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
#endif
-#if STDC_HEADERS
+#ifdef HAVE_STDLIB_H
# 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
+#ifdef HAVE_STRING_H
# include <string.h>
#endif
-#if HAVE_STRINGS_H
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#else
-# if HAVE_STDINT_H
-# include <stdint.h>
-# endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
#endif
-#if HAVE_UNISTD_H
+#ifdef 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_NOLTO ZLIB_DLL_FILE ZLIB_LIBS ZLIB_OBJS TCL_ZLIB_LIB_NAME CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCL_WIN_VERSION MACHINE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL PKG_CFG_ARGS TCL_EXE TCL_LIB_FILE TCL_LIB_FLAG TCL_STATIC_LIB_FILE TCL_STATIC_LIB_FLAG TCL_IMPORT_LIB_FILE TCL_IMPORT_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_DLL_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TCL_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TCL_BUILD_LIB_SPEC TCL_CC_SEARCH_FLAGS TCL_LD_SEARCH_FLAGS TCL_BUILD_EXP_FILE TCL_EXP_FILE TCL_PACKAGE_PATH TCL_DDE_VERSION TCL_DDE_MAJOR_VERSION TCL_DDE_MINOR_VERSION TCL_REG_VERSION TCL_REG_MAJOR_VERSION TCL_REG_MINOR_VERSION RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS'
+ac_header_c_list=
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+RES
+RC_DEFINES
+RC_DEFINE
+RC_INCLUDE
+RC_TYPE
+RC_OUT
+TCL_REG_MINOR_VERSION
+TCL_REG_MAJOR_VERSION
+TCL_REG_VERSION
+TCL_DDE_MINOR_VERSION
+TCL_DDE_MAJOR_VERSION
+TCL_DDE_VERSION
+TCL_PACKAGE_PATH
+TCL_BUILD_LIB_SPEC
+MAKE_EXE
+MAKE_DLL
+POST_MAKE_LIB
+MAKE_STUB_LIB
+MAKE_LIB
+LIBRARIES
+EXESUFFIX
+LIBSUFFIX
+LIBPREFIX
+DLLSUFFIX
+LIBS_GUI
+TCL_SHARED_BUILD
+SHLIB_SUFFIX
+SHLIB_CFLAGS
+SHLIB_LD_LIBS
+SHLIB_LD
+STLIB_LD
+LDFLAGS_WINDOW
+LDFLAGS_CONSOLE
+LDFLAGS_OPTIMIZE
+LDFLAGS_DEBUG
+CC_EXENAME
+CC_OBJNAME
+DEPARG
+EXTRA_CFLAGS
+CFG_TCL_UNSHARED_LIB_SUFFIX
+CFG_TCL_SHARED_LIB_SUFFIX
+TCL_BIN_DIR
+TCL_SRC_DIR
+TCL_DLL_FILE
+TCL_BUILD_STUB_LIB_PATH
+TCL_BUILD_STUB_LIB_SPEC
+TCL_INCLUDE_SPEC
+TCL_STUB_LIB_PATH
+TCL_STUB_LIB_SPEC
+TCL_STUB_LIB_FLAG
+TCL_STUB_LIB_FILE
+TCL_LIB_SPEC
+TCL_IMPORT_LIB_FLAG
+TCL_IMPORT_LIB_FILE
+TCL_STATIC_LIB_FLAG
+TCL_STATIC_LIB_FILE
+TCL_LIB_FLAG
+TCL_LIB_FILE
+TCL_EXE
+PKG_CFG_ARGS
+TCL_PATCH_LEVEL
+TCL_MINOR_VERSION
+TCL_MAJOR_VERSION
+TCL_VERSION
+MACHINE
+TCL_WIN_VERSION
+VC_MANIFEST_EMBED_EXE
+VC_MANIFEST_EMBED_DLL
+CPP
+LDFLAGS_DEFAULT
+CFLAGS_DEFAULT
+INSTALL_MSGS
+INSTALL_LIBRARIES
+TCL_ZIP_FILE
+ZIPFS_BUILD
+ZIP_INSTALL_OBJS
+ZIP_PROG_VFSSEARCH
+ZIP_PROG_OPTIONS
+ZIP_PROG
+TCLSH_PROG
+EXEEXT_FOR_BUILD
+CC_FOR_BUILD
+TCL_TOMMATH_LIB_NAME
+TCL_ZLIB_LIB_NAME
+TOMMATH_OBJS
+ZLIB_OBJS
+TOMMATH_LIBS
+ZLIB_LIBS
+TOMMATH_DLL_FILE
+ZLIB_DLL_FILE
+CFLAGS_NOLTO
+CFLAGS_WARNING
+CFLAGS_OPTIMIZE
+CFLAGS_DEBUG
+DL_LIBS
+WINE
+CYGPATH
+SHARED_BUILD
+SET_MAKE
+RC
+RANLIB
+AR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+runstatedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL
+OBJEXT_FOR_BUILD'
ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_encoding
+enable_shared
+enable_64bit
+enable_zipfs
+enable_symbols
+enable_embedded_manifest
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
# Initialize some variables set by options.
ac_init_help=
ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
# The variables have the same names as the options, with
# dashes changed to underlines.
cache_file=/dev/null
@@ -337,34 +838,48 @@ x_libraries=NONE
# 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.
+# (The list follows the same order as the GNU Coding Standards.)
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
ac_prev=
+ac_dashdash=
for ac_option
do
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
+ eval $ac_prev=\$ac_option
ac_prev=
continue
fi
- ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
@@ -386,33 +901,59 @@ do
--config-cache | -C)
cache_file=config.cache ;;
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ -datadir | --datadir | --datadi | --datad)
ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
datadir=$ac_optarg ;;
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
-disable-* | --disable-*)
- ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ ac_useropt=`expr "x$ac_option" : 'x-*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" ;;
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: '$ac_useropt'"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
-enable-* | --enable-*)
- ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# 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"`;;
- *) ac_optarg=yes ;;
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: '$ac_useropt'"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
esac
- eval "enable_$ac_feature='$ac_optarg'" ;;
+ eval enable_$ac_useropt=\$ac_optarg ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -439,6 +980,12 @@ do
-host=* | --host=* | --hos=* | --ho=*)
host_alias=$ac_optarg ;;
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
@@ -463,13 +1010,16 @@ do
| --libexe=* | --libex=* | --libe=*)
libexecdir=$ac_optarg ;;
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
-localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
+ | --localstate | --localstat | --localsta | --localst | --locals)
ac_prev=localstatedir ;;
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
localstatedir=$ac_optarg ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
@@ -534,10 +1084,29 @@ do
| --progr-tra=* | --program-tr=* | --program-t=*)
program_transform_name=$ac_optarg ;;
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -584,26 +1153,36 @@ do
ac_init_version=: ;;
-with-* | --with-*)
- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# 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'`
- case $ac_option in
- *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
- *) ac_optarg=yes ;;
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: '$ac_useropt'"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
esac
- eval "with_$ac_package='$ac_optarg'" ;;
+ eval with_$ac_useropt=\$ac_optarg ;;
-without-* | --without-*)
- ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ ac_useropt=`expr "x$ac_option" : 'x-*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" ;;
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: '$ac_useropt'"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
--x)
# Obsolete; use --with-x.
@@ -623,27 +1202,26 @@ do
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
- -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; }
+ -*) as_fn_error $? "unrecognized option: '$ac_option'
+Try '$0 --help' for more information"
;;
*=*)
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'"
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: '$ac_envvar'" ;;
+ esac
+ 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
+ printf "%s\n" "$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}
+ printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
;;
esac
@@ -651,34 +1229,39 @@ 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; }; }
+ as_fn_error $? "missing argument to $ac_option"
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; }; };;
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
esac
-done
+fi
-# Be sure to have absolute paths.
-for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
- localstatedir libdir includedir oldincludedir infodir mandir
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir runstatedir
do
- eval ac_val=$`echo $ac_var`
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
case $ac_val in
- [\\/$]* | ?:[\\/]* ) ;;
- *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
- { (exit 1); exit 1; }; };;
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done
-# There might be people who depend on the old broken behavior: `$host'
+# 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
@@ -689,8 +1272,6 @@ target=$target_alias
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
@@ -702,74 +1283,72 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias-
test "$silent" = yes && exec 6>/dev/null
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
# 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'`
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
+ if test ! -r "$srcdir/$ac_unique_file"; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
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; }; }
- else
- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
- { (exit 1); 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
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
#
# Report the --help message.
@@ -778,7 +1357,7 @@ 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 tcl 8.6 to adapt to many kinds of systems.
+'configure' configures tcl 9.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -792,41 +1371,46 @@ Configuration:
--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
+ -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'
+ -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 \`..']
+ --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]
+ [$ac_default_prefix]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
+ [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'.
+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]
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --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]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/tcl]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
_ACEOF
cat <<\_ACEOF
@@ -835,18 +1419,17 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of tcl 8.6:";;
+ short | recursive ) echo "Configuration of tcl 9.0:";;
esac
cat <<\_ACEOF
Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-threads build with threads (default: on)
--enable-shared build and link with shared libraries (default: on)
- --enable-time64bit force 64-bit time_t for 32-bit build (default: off)
--enable-64bit enable 64bit support (where applicable)
- --enable-wince enable Win/CE support (where applicable)
+ --enable-zipfs build with Zipfs support (default: on)
--enable-symbols build with debugging symbols (default: off)
--enable-embedded-manifest
embed manifest if possible (default: yes)
@@ -855,135 +1438,301 @@ 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>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) 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
+Use these variables to override the choices made by 'configure' or to help
it to find libraries and programs with nonstandard names/locations.
+Report bugs to the package provider.
_ACEOF
+ac_status=$?
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
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && 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 "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
case $srcdir in
- .) # No --srcdir option. We are building in place.
+ .) # 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_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
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;;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
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
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for configure.gnu first; this name is used for a wrapper for
+ # Metaconfig's "Configure" on case-insensitive file systems.
+ 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
else
- echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi
- cd $ac_popdir
+ printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
done
fi
-test -n "$ac_init_help" && exit 0
+test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-tcl configure 8.6
-generated by GNU Autoconf 2.59
+tcl configure 9.0
+generated by GNU Autoconf 2.72
-Copyright (C) 2003 Free Software Foundation, Inc.
+Copyright (C) 2023 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
+ exit
fi
-exec 5>config.log
-cat >&5 <<_ACEOF
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest.beam
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext
+then :
+ ac_retval=0
+else case e in #(
+ e) printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1 ;;
+esac
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+ eval "$3=yes"
+else case e in #(
+ e) eval "$3=no" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
+esac
+fi
+eval ac_res=\$$3
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main (void)
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main (void)
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else case e in #(
+ e) eval "$3=yes" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
+esac
+fi
+eval ac_res=\$$3
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }
+then :
+ ac_retval=0
+else case e in #(
+ e) printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1 ;;
+esac
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+ac_configure_args_raw=
+for ac_arg
+do
+ case $ac_arg in
+ *\'*)
+ ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append ac_configure_args_raw " '$ac_arg'"
+done
+
+case $ac_configure_args_raw in
+ *$as_nl*)
+ ac_safe_unquote= ;;
+ *)
+ ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab.
+ ac_unsafe_a="$ac_unsafe_z#~"
+ ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
+ ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
+esac
+
+cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by tcl $as_me 8.6, which was
-generated by GNU Autoconf 2.59. Invocation command line was
+It was created by tcl $as_me 9.0, which was
+generated by GNU Autoconf 2.72. Invocation command line was
- $ $0 $@
+ $ $0$ac_configure_args_raw
_ACEOF
+exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
@@ -1002,7 +1751,7 @@ uname -v = `(uname -v) 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`
+/usr/bin/hostinfo = `(/usr/bin/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`
@@ -1013,9 +1762,14 @@ 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ printf "%s\n" "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
} >&5
@@ -1037,7 +1791,6 @@ _ACEOF
ac_configure_args=
ac_configure_args0=
ac_configure_args1=
-ac_sep=
ac_must_keep_next=false
for ac_pass in 1 2
do
@@ -1048,13 +1801,13 @@ do
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
continue ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *\'*)
+ ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
case $ac_pass in
- 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
2)
- ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ as_fn_append ac_configure_args1 " '$ac_arg'"
if test $ac_must_keep_next = true; then
ac_must_keep_next=false # Got value, back to normal.
else
@@ -1070,217 +1823,575 @@ do
-* ) 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=" "
+ as_fn_append ac_configure_args " '$ac_arg'"
;;
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; }
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset 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.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?
+ # Sanitize IFS.
+ IFS=" "" $as_nl"
# Save into config.log some information that might help in debugging.
{
echo
- cat <<\_ASBOX
-## ---------------- ##
+ printf "%s\n" "## ---------------- ##
## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
echo
# The following way of writing the cache mishandles newlines in values,
-{
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
(set) 2>&1 |
- case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
sed -n \
- "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
- ;;
+ "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"
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
;;
- esac;
-}
+ esac |
+ sort
+)
echo
- cat <<\_ASBOX
-## ----------------- ##
+ printf "%s\n" "## ----------------- ##
## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
echo
for ac_var in $ac_subst_vars
do
- eval ac_val=$`echo $ac_var`
- echo "$ac_var='"'"'$ac_val'"'"'"
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ printf "%s\n" "$ac_var='\''$ac_val'\''"
done | sort
echo
if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------- ##
-## Output files. ##
-## ------------- ##
-_ASBOX
+ printf "%s\n" "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
echo
for ac_var in $ac_subst_files
do
- eval ac_val=$`echo $ac_var`
- echo "$ac_var='"'"'$ac_val'"'"'"
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ printf "%s\n" "$ac_var='\''$ac_val'\''"
done | sort
echo
fi
if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
+ printf "%s\n" "## ----------- ##
## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
echo
- sed "/^$/d" confdefs.h | sort
+ cat confdefs.h
echo
fi
test "$ac_signal" != 0 &&
- echo "$as_me: caught signal $ac_signal"
- echo "$as_me: exit $exit_status"
+ printf "%s\n" "$as_me: caught signal $ac_signal"
+ printf "%s\n" "$as_me: exit $exit_status"
} >&5
- rm -f core *.core &&
- rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
exit $exit_status
- ' 0
+' 0
for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+ trap 'ac_signal='$ac_signal'; as_fn_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
+rm -f -r conftest* confdefs.h
-# Predefined preprocessor variables.
+printf "%s\n" "/* confdefs.h */" > confdefs.h
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
+# Predefined preprocessor variables.
+printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
+printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
+printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
+printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
+printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
+printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
# 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
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
+# Prefer an explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+ ac_site_files="$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+ ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
+else
+ ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
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;}
+
+for ac_site_file in $ac_site_files
+do
+ case $ac_site_file in #(
+ */*) :
+ ;; #(
+ *) :
+ ac_site_file=./$ac_site_file ;;
+esac
+ if test -f "$ac_site_file" && test -r "$ac_site_file"; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file"
+ . "$ac_site_file" \
+ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See 'config.log' for more details" "$LINENO" 5; }
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;}
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
case $cache_file in
- [\\/]* | ?:[\\/]* ) . $cache_file;;
- *) . ./$cache_file;;
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
esac
fi
else
- { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
>$cache_file
fi
+# Test code for whether the C compiler supports C89 (global declarations)
+ac_c_conftest_c89_globals='
+/* Does the compiler advertise C89 conformance?
+ Do not test the value of __STDC__, because some compilers set it to 0
+ while being otherwise adequately conformant. */
+#if !defined __STDC__
+# error "Compiler does not advertise C89 conformance"
+#endif
+
+#include <stddef.h>
+#include <stdarg.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */
+struct buf { int x; };
+struct buf * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (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;
+}
+
+/* C89 style stringification. */
+#define noexpand_stringify(a) #a
+const char *stringified = noexpand_stringify(arbitrary+token=sequence);
+
+/* C89 style token pasting. Exercises some of the corner cases that
+ e.g. old MSVC gets wrong, but not very hard. */
+#define noexpand_concat(a,b) a##b
+#define expand_concat(a,b) noexpand_concat(a,b)
+extern int vA;
+extern int vbee;
+#define aye A
+#define bee B
+int *pvA = &expand_concat(v,aye);
+int *pvbee = &noexpand_concat(v,bee);
+
+/* 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 do not provoke an error unfortunately, instead are silently treated
+ as an "x". The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously \x00 != x always comes out true, for an
+ array size at least. It is necessary to write \x00 == 0 to get something
+ that is true only with -std. */
+int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) '\''x'\''
+int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
+ int, int);'
+
+# Test code for whether the C compiler supports C89 (body of main).
+ac_c_conftest_c89_main='
+ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
+'
+
+# Test code for whether the C compiler supports C99 (global declarations)
+ac_c_conftest_c99_globals='
+/* Does the compiler advertise C99 conformance? */
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# error "Compiler does not advertise C99 conformance"
+#endif
+
+// See if C++-style comments work.
+
+#include <stdbool.h>
+extern int puts (const char *);
+extern int printf (const char *, ...);
+extern int dprintf (int, const char *, ...);
+extern void *malloc (size_t);
+extern void free (void *);
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+// dprintf is used instead of fprintf to avoid needing to declare
+// FILE and stderr.
+#define debug(...) dprintf (2, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ #error "your preprocessor is broken"
+#endif
+#if BIG_OK
+#else
+ #error "your preprocessor is broken"
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str = "";
+ int number = 0;
+ float fnumber = 0;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case '\''s'\'': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case '\''d'\'': // int
+ number = va_arg (args_copy, int);
+ break;
+ case '\''f'\'': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+
+ return *str && number && fnumber;
+}
+'
+
+# Test code for whether the C compiler supports C99 (body of main).
+ac_c_conftest_c99_main='
+ // Check bool.
+ _Bool success = false;
+ success |= (argc != 0);
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+ // Work around memory leak warnings.
+ free (ia);
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[0] = argv[0][0];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
+ || dynamic_array[ni.number - 1] != 543);
+'
+
+# Test code for whether the C compiler supports C11 (global declarations)
+ac_c_conftest_c11_globals='
+/* Does the compiler advertise C11 conformance? */
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
+# error "Compiler does not advertise C11 conformance"
+#endif
+
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
+
+// Check _Alignof.
+enum
+{
+ int_alignment = _Alignof (int),
+ int_array_alignment = _Alignof (int[100]),
+ char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
+
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
+
+// Check _Static_assert.
+struct test_static_assert
+{
+ int x;
+ _Static_assert (sizeof (int) <= sizeof (long int),
+ "_Static_assert does not work in struct");
+ long int y;
+};
+
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
+
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
+
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+ union {
+ struct { int i; int j; };
+ struct { int k; long int l; } w;
+ };
+ int m;
+} v1;
+'
+
+# Test code for whether the C compiler supports C11 (body of main).
+ac_c_conftest_c11_main='
+ _Static_assert ((offsetof (struct anonymous, i)
+ == offsetof (struct anonymous, w.k)),
+ "Anonymous union alignment botch");
+ v1.i = 2;
+ v1.w.k = 5;
+ ok |= v1.i != 5;
+'
+
+# Test code for whether the C compiler supports C11 (complete).
+ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+${ac_c_conftest_c11_globals}
+
+int
+main (int argc, char **argv)
+{
+ int ok = 0;
+ ${ac_c_conftest_c89_main}
+ ${ac_c_conftest_c99_main}
+ ${ac_c_conftest_c11_main}
+ return ok;
+}
+"
+
+# Test code for whether the C compiler supports C99 (complete).
+ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+
+int
+main (int argc, char **argv)
+{
+ int ok = 0;
+ ${ac_c_conftest_c89_main}
+ ${ac_c_conftest_c99_main}
+ return ok;
+}
+"
+
+# Test code for whether the C compiler supports C89 (complete).
+ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
+
+int
+main (int argc, char **argv)
+{
+ int ok = 0;
+ ${ac_c_conftest_c89_main}
+ return ok;
+}
+"
+
+as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
+as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
+as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
+as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
+as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
+as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
+as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
+as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
+as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
# 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
+for ac_var in $ac_precious_vars; 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"
+ 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;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&5
+printf "%s\n" "$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;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was not set in the previous run" >&5
+printf "%s\n" "$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=:
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' has changed since the previous run:" >&5
+printf "%s\n" "$as_me: error: '$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&5
+printf "%s\n" "$as_me: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: '$ac_old_val'" >&5
+printf "%s\n" "$as_me: former value: '$ac_old_val'" >&2;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: '$ac_new_val'" >&5
+printf "%s\n" "$as_me: current value: '$ac_new_val'" >&2;}
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=`printf "%s\n" "$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'" ;;
+ *) as_fn_append 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; }; }
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run '${MAKE-make} distclean' and/or 'rm $cache_file'
+ and start over" "$LINENO" 5
fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -1292,40 +2403,15 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 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.6
-TCL_MAJOR_VERSION=8
-TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".17"
+TCL_VERSION=9.0
+TCL_MAJOR_VERSION=9
+TCL_MINOR_VERSION=0
+TCL_PATCH_LEVEL=".3"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
TCL_DDE_VERSION=1.4
@@ -1368,6 +2454,15 @@ 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'
@@ -1376,172 +2471,164 @@ 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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "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.
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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
- CC=$ac_ct_CC
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
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.
+ 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
-else
- if test -n "$CC"; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
-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
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
-else
- if test -n "$CC"; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
ac_prog_rejected=no
@@ -1549,19 +2636,24 @@ 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
@@ -1572,146 +2664,280 @@ if test $ac_prog_rejected = yes; then
# 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+' '}$@"
+ ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
fi
fi
-fi
+fi ;;
+esac
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
+
fi
if test -z "$CC"; then
if test -n "$ac_tool_prefix"; then
- for ac_prog in cl
+ for ac_prog in cl.exe
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
-else
- if test -n "$CC"; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
+
test -n "$CC" && break
done
fi
if test -z "$CC"; then
ac_ct_CC=$CC
- for ac_prog in cl
+ for ac_prog in cl.exe
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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
+
test -n "$ac_ct_CC" && break
done
- CC=$ac_ct_CC
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}clang"
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi ;;
+esac
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="clang"
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi ;;
+esac
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
fi
fi
-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; }; }
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See 'config.log' for more details" "$LINENO" 5; }
# 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
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion -version; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main ()
+main (void)
{
;
@@ -1719,155 +2945,213 @@ main ()
}
_ACEOF
ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
+ac_clean_files="$ac_clean_files a.out a.out.dSYM 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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+printf %s "checking whether the C compiler works... " >&6; }
+ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to 'no'.
+# So ignore a value of 'no', otherwise this would lead to 'EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
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.
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
;;
[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
+ if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an '-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
break;;
* )
break;;
esac
done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+test "$ac_cv_exeext" = no && ac_cv_exeext=
-{ { 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; }; }
+else case e in #(
+ e) ac_file='' ;;
+esac
fi
+if test -z "$ac_file"
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-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
- 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
- fi
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See 'config.log' for more details" "$LINENO" 5; }
+else case e in #(
+ e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; } ;;
+esac
fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+printf %s "checking for C compiler default output file name... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+printf "%s\n" "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
+rm -f -r a.out a.out.dSYM 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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+printf %s "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&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'.
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+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_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.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; }; }
+else case e in #(
+ e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See 'config.log' for more details" "$LINENO" 5; } ;;
+esac
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 conftest$ac_cv_exeext
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+printf "%s\n" "$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. */
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main (void)
+{
+FILE *f = fopen ("conftest.out", "w");
+ if (!f)
+ return 1;
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+printf %s "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error 77 "cannot run C compiled programs.
+If you meant to cross compile, use '--host'.
+See 'config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+printf "%s\n" "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext \
+ conftest.o conftest.obj conftest.out
+ac_clean_files=$ac_clean_files_save
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+printf %s "checking for suffix of object files... " >&6; }
+if test ${ac_cv_objext+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main ()
+main (void)
{
;
@@ -1875,49 +3159,54 @@ main ()
}
_ACEOF
rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
*) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
break;;
esac
done
-else
- echo "$as_me: failed program was:" >&5
+else case e in #(
+ e) printf "%s\n" "$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; }; }
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See 'config.log' for more details" "$LINENO" 5; } ;;
+esac
fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
+rm -f conftest.$ac_cv_objext conftest.$ac_ext ;;
+esac
fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+printf "%s\n" "$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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main ()
+main (void)
{
#ifndef __GNUC__
choke me
@@ -1927,99 +3216,100 @@ 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
+if ac_fn_c_try_compile "$LINENO"
+then :
ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_compiler_gnu=no
+else case e in #(
+ e) ac_compiler_gnu=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
+ ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
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_test_CFLAGS=${CFLAGS+y}
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
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main ()
+main (void)
{
;
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
+if ac_fn_c_try_compile "$LINENO"
+then :
ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+else case e in #(
+ e) CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main (void)
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else case e in #(
+ e) ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main (void)
+{
-ac_cv_prog_cc_g=no
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag ;;
+esac
fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
-if test "$ac_test_CFLAGS" = set; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
@@ -2034,264 +3324,155 @@ 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_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) ac_cv_prog_cc_c11=no
ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* 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;
-}
+$ac_c_conftest_c11_program
_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__"
+for ac_arg in '' -std=gnu11
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
-
+ if ac_fn_c_try_compile "$LINENO"
+then :
+ ac_cv_prog_cc_c11=$ac_arg
fi
-rm -f conftest.err conftest.$ac_objext
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+ test "x$ac_cv_prog_cc_c11" != "xno" && break
done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
-
+rm -f conftest.$ac_ext
+CC=$ac_save_CC ;;
+esac
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" ;;
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else case e in #(
+ e) if test "x$ac_cv_prog_cc_c11" = x
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else case e in #(
+ e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+ CC="$CC $ac_cv_prog_cc_c11" ;;
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
+fi
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+ ac_prog_cc_stdc=c11 ;;
+esac
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
+$ac_c_conftest_c99_program
_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
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"
+then :
+ ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+ test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC ;;
+esac
+fi
-continue
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else case e in #(
+ e) if test "x$ac_cv_prog_cc_c99" = x
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else case e in #(
+ e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+ CC="$CC $ac_cv_prog_cc_c99" ;;
+esac
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
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+ ac_prog_cc_stdc=c99 ;;
+esac
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-$ac_declaration
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
+$ac_c_conftest_c89_program
_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
-
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"
+then :
+ ac_cv_prog_cc_c89=$ac_arg
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
done
-rm -f conftest*
-if test -n "$ac_declaration"; then
- echo '#ifdef __cplusplus' >>confdefs.h
- echo $ac_declaration >>confdefs.h
- echo '#endif' >>confdefs.h
+rm -f conftest.$ac_ext
+CC=$ac_save_CC ;;
+esac
fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else case e in #(
+ e) if test "x$ac_cv_prog_cc_c89" = x
+then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else case e in #(
+ e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+ CC="$CC $ac_cv_prog_cc_c89" ;;
+esac
+fi
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+ ac_prog_cc_stdc=c89 ;;
+esac
+fi
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'
@@ -2299,61 +3480,35 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+printf %s "checking for inline... " >&6; }
+if test ${ac_cv_c_inline+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* 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; }
+static $ac_kw foo_t static_foo (void) {return 0; }
+$ac_kw foo_t foo (void) {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
-
+if ac_fn_c_try_compile "$LINENO"
+then :
+ ac_cv_c_inline=$ac_kw
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
done
-
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
-echo "${ECHO_T}$ac_cv_c_inline" >&6
-
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+printf "%s\n" "$ac_cv_c_inline" >&6; }
case $ac_cv_c_inline in
inline | yes) ;;
@@ -2370,499 +3525,107 @@ _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>
-#include <stdlib.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
-else
- if test -n "$AR"; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_AR+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
- echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+printf "%s\n" "$AR" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_AR+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+printf "%s\n" "$ac_ct_AR" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
- AR=$ac_ct_AR
+ if test "x$ac_ct_AR" = x; then
+ AR=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
else
AR="$ac_cv_prog_AR"
fi
@@ -2870,78 +3633,103 @@ 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
-else
- if test -n "$RANLIB"; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_RANLIB+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
- echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+printf "%s\n" "$RANLIB" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
+
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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_RANLIB+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+printf "%s\n" "$ac_ct_RANLIB" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
- RANLIB=$ac_ct_RANLIB
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
else
RANLIB="$ac_cv_prog_RANLIB"
fi
@@ -2949,78 +3737,103 @@ 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
-else
- if test -n "$RC"; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_RC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
fi
RC=$ac_cv_prog_RC
if test -n "$RC"; then
- echo "$as_me:$LINENO: result: $RC" >&5
-echo "${ECHO_T}$RC" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
+printf "%s\n" "$RC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_RC+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
-fi
+fi ;;
+esac
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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
+printf "%s\n" "$ac_ct_RC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
- RC=$ac_ct_RC
+ if test "x$ac_ct_RC" = x; then
+ RC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RC=$ac_ct_RC
+ fi
else
RC="$ac_cv_prog_RC"
fi
@@ -3030,14 +3843,15 @@ 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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
set x ${MAKE-make}
-ac_make=`echo "" | sed 'y,:./+-,___p_,'`
-if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.make <<\_ACEOF
+ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval test \${ac_cv_prog_make_${ac_make}_set+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat >conftest.make <<\_ACEOF
SHELL = /bin/sh
all:
@echo '@@@%%%=$(MAKE)=@@@%%%'
@@ -3049,15 +3863,16 @@ case `${MAKE-make} -f conftest.make 2>/dev/null` in
*)
eval ac_cv_prog_make_${ac_make}_set=no;;
esac
-rm -f conftest.make
+rm -f conftest.make ;;
+esac
fi
if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
SET_MAKE=
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
SET_MAKE="MAKE=${MAKE-make}"
fi
@@ -3069,65 +3884,24 @@ fi
-#--------------------------------------------------------------------
-# Check whether --enable-threads or --disable-threads was given.
-#--------------------------------------------------------------------
-
-
- echo "$as_me:$LINENO: checking for building with threads" >&5
-echo $ECHO_N "checking for building with threads... $ECHO_C" >&6
- # 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=yes
-fi;
-
- if test "$tcl_ok" = "yes"; then
- echo "$as_me:$LINENO: result: yes (default)" >&5
-echo "${ECHO_T}yes (default)" >&6
- TCL_THREADS=1
- cat >>confdefs.h <<\_ACEOF
-#define TCL_THREADS 1
-_ACEOF
-
- # USE_THREAD_ALLOC tells us to try the special thread-based
- # allocator that significantly reduces lock contention
- cat >>confdefs.h <<\_ACEOF
-#define USE_THREAD_ALLOC 1
-_ACEOF
-
- else
- TCL_THREADS=0
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&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;
+# Check whether --with-encoding was given.
+if test ${with_encoding+y}
+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
+ printf "%s\n" "#define TCL_CFGVAL_ENCODING \"${with_tcencoding}\"" >>confdefs.h
else
- # Default encoding on windows is not "iso8859-1"
- cat >>confdefs.h <<\_ACEOF
-#define TCL_CFGVAL_ENCODING "cp1252"
-_ACEOF
+ printf "%s\n" "#define TCL_CFGVAL_ENCODING \"utf-8\"" >>confdefs.h
fi
@@ -3138,49 +3912,31 @@ _ACEOF
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking how to build libraries" >&5
-echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6
- # 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;
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
+printf %s "checking how to build libraries... " >&6; }
+ # Check whether --enable-shared was given.
+if test ${enable_shared+y}
+then :
+ enableval=$enable_shared; tcl_ok=$enableval
+else case e in #(
+ e) tcl_ok=yes ;;
+esac
+fi
+
if test "$tcl_ok" = "yes" ; then
- echo "$as_me:$LINENO: result: shared" >&5
-echo "${ECHO_T}shared" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: shared" >&5
+printf "%s\n" "shared" >&6; }
SHARED_BUILD=1
else
- echo "$as_me:$LINENO: result: static" >&5
-echo "${ECHO_T}static" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: static" >&5
+printf "%s\n" "static" >&6; }
SHARED_BUILD=0
-cat >>confdefs.h <<\_ACEOF
-#define STATIC_BUILD 1
-_ACEOF
+printf "%s\n" "#define STATIC_BUILD 1" >>confdefs.h
fi
-#--------------------------------------------------------------------
-# Check whether --enable-time64bit was given.
-#--------------------------------------------------------------------
-
-echo "$as_me:$LINENO: checking force of 64-bit time_t" >&5
-echo $ECHO_N "checking force of 64-bit time_t... $ECHO_C" >&6
-# Check whether --enable-time64bit or --disable-time64bit was given.
-if test "${enable_time64bit+set}" = set; then
- enableval="$enable_time64bit"
- tcl_ok=$enableval
-else
- tcl_ok=no
-fi;
-echo "$as_me:$LINENO: result: \"$tcl_ok\"" >&5
-echo "${ECHO_T}\"$tcl_ok\"" >&6
-if test "$tcl_ok" = "yes"; then
- CFLAGS="${CFLAGS} -D_USE_64BIT_TIME_T"
-fi
#--------------------------------------------------------------------
# The statements below define a collection of compile flags. This
@@ -3188,94 +3944,147 @@ fi
# after SC_ENABLE_SHARED checks the configure switches.
#--------------------------------------------------------------------
+ac_header= ac_cache=
+for ac_item in $ac_header_c_list
+do
+ if test $ac_cache; then
+ ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
+ if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
+ printf "%s\n" "#define $ac_item 1" >> confdefs.h
+ fi
+ ac_header= ac_cache=
+ elif test $ac_header; then
+ ac_cache=$ac_item
+ else
+ ac_header=$ac_item
+ fi
+done
+
+
+
+
+
+
+
+
+if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
+then :
+
+printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
# 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
- # 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
-
- # 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
- # 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
-
- echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5
-echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6
-
-# 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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
+printf %s "checking if 64bit support is requested... " >&6; }
+ # Check whether --enable-64bit was given.
+if test ${enable_64bit+y}
+then :
+ enableval=$enable_64bit; do64bit=$enableval
+else case e in #(
+ e) do64bit=no ;;
+esac
+fi
+
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
+printf "%s\n" "$do64bit" >&6; }
# Set some defaults (may get changed below)
EXTRA_CFLAGS=""
-cat >>confdefs.h <<\_ACEOF
-#define MODULE_SCOPE extern
-_ACEOF
+printf "%s\n" "#define MODULE_SCOPE extern" >>confdefs.h
# 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
-else
- if test -n "$CYGPATH"; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CYGPATH+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
ac_cv_prog_CYGPATH="cygpath -m"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
-fi
+fi ;;
+esac
fi
CYGPATH=$ac_cv_prog_CYGPATH
if test -n "$CYGPATH"; then
- echo "$as_me:$LINENO: result: $CYGPATH" >&5
-echo "${ECHO_T}$CYGPATH" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
+printf "%s\n" "$CYGPATH" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
fi
+ # Extract the first word of "wine", so it can be a program name with args.
+set dummy wine; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_WINE+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) if test -n "$WINE"; then
+ ac_cv_prog_WINE="$WINE" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ ac_cv_prog_WINE="wine"
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi ;;
+esac
+fi
+WINE=$ac_cv_prog_WINE
+if test -n "$WINE"; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WINE" >&5
+printf "%s\n" "$WINE" >&6; }
+else
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+
SHLIB_SUFFIX=".dll"
# MACHINE is IX86 for LINK, but this is used by the manifest,
@@ -3284,16 +4093,13 @@ fi
if test "$GCC" = "yes"; then
- echo "$as_me:$LINENO: checking for cross-compile version of gcc" >&5
-echo $ECHO_N "checking for cross-compile version of gcc... $ECHO_C" >&6
-if test "${ac_cv_cross+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5
+printf %s "checking for cross-compile version of gcc... " >&6; }
+if test ${ac_cv_cross+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifndef _WIN32
@@ -3301,47 +4107,26 @@ cat >>conftest.$ac_ext <<_ACEOF
#endif
int
-main ()
+main (void)
{
;
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
+if ac_fn_c_try_compile "$LINENO"
+then :
ac_cv_cross=no
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_cross=yes
+else case e in #(
+ e) ac_cv_cross=yes ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $ac_cv_cross" >&5
-echo "${ECHO_T}$ac_cv_cross" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5
+printf "%s\n" "$ac_cv_cross" >&6; }
if test "$ac_cv_cross" = "yes"; then
case "$do64bit" in
@@ -3383,20 +4168,20 @@ echo "${ECHO_T}$ac_cv_cross" >&6
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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Windows native path bug in windres" >&5
+printf %s "checking for Windows native path bug in windres... " >&6; }
cyg_conftest=`$CYGPATH $conftest`
if { ac_try='$RC -o conftest.res.o $cyg_conftest'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ { { eval echo "\"\$as_me\":${as_lineno-$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
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } ; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
else
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
CYGPATH=echo
fi
conftest=
@@ -3414,16 +4199,13 @@ echo "${ECHO_T}yes" >&6
if test "${GCC}" = "yes" ; then
extra_cflags="-pipe"
extra_ldflags="-pipe -static-libgcc"
- echo "$as_me:$LINENO: checking for mingw32 version of gcc" >&5
-echo $ECHO_N "checking for mingw32 version of gcc... $ECHO_C" >&6
-if test "${ac_cv_win32+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mingw32 version of gcc" >&5
+printf %s "checking for mingw32 version of gcc... " >&6; }
+if test ${ac_cv_win32+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifdef _WIN32
@@ -3431,115 +4213,116 @@ cat >>conftest.$ac_ext <<_ACEOF
#endif
int
-main ()
+main (void)
{
;
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
+if ac_fn_c_try_compile "$LINENO"
+then :
ac_cv_win32=no
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_win32=yes
+else case e in #(
+ e) ac_cv_win32=yes ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $ac_cv_win32" >&5
-echo "${ECHO_T}$ac_cv_win32" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_win32" >&5
+printf "%s\n" "$ac_cv_win32" >&6; }
if test "$ac_cv_win32" != "yes"; then
- { { echo "$as_me:$LINENO: error: ${CC} cannot produce win32 executables." >&5
-echo "$as_me: error: ${CC} cannot produce win32 executables." >&2;}
- { (exit 1); exit 1; }; }
+ as_fn_error $? "${CC} cannot produce win32 executables." "$LINENO" 5
fi
if test "$do64bit" != "arm64" -a "$do64bit" != "aarch64"; then
extra_cflags="$extra_cflags -DHAVE_CPUID=1"
fi
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
- echo "$as_me:$LINENO: checking for working -municode linker flag" >&5
-echo $ECHO_N "checking for working -municode linker flag... $ECHO_C" >&6
-if test "${ac_cv_municode+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working -municode linker flag" >&5
+printf %s "checking for working -municode linker flag... " >&6; }
+if test ${ac_cv_municode+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e)
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }
+then :
+ ac_retval=0
+else case e in #(
+ e) printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1 ;;
+esac
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <windows.h>
int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;}
int
-main ()
+main (void)
{
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"
+then :
ac_cv_municode=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_municode=no
+else case e in #(
+ e) ac_cv_municode=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $ac_cv_municode" >&5
-echo "${ECHO_T}$ac_cv_municode" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_municode" >&5
+printf "%s\n" "$ac_cv_municode" >&6; }
CFLAGS=$hold_cflags
if test "$ac_cv_municode" = "yes" ; then
extra_ldflags="$extra_ldflags -municode"
@@ -3547,60 +4330,36 @@ echo "${ECHO_T}$ac_cv_municode" >&6
extra_cflags="$extra_cflags -DTCL_BROKEN_MAINARGS"
fi
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto"
- echo "$as_me:$LINENO: checking for working -fno-lto" >&5
-echo $ECHO_N "checking for working -fno-lto... $ECHO_C" >&6
-if test "${ac_cv_nolto+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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working -fno-lto" >&5
+printf %s "checking for working -fno-lto... " >&6; }
+if test ${ac_cv_nolto+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main ()
+main (void)
{
;
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
+if ac_fn_c_try_compile "$LINENO"
+then :
ac_cv_nolto=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_nolto=no
+else case e in #(
+ e) ac_cv_nolto=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $ac_cv_nolto" >&5
-echo "${ECHO_T}$ac_cv_nolto" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_nolto" >&5
+printf "%s\n" "$ac_cv_nolto" >&6; }
CFLAGS=$hold_cflags
if test "$ac_cv_nolto" = "yes" ; then
CFLAGS_NOLTO="-fno-lto"
@@ -3608,137 +4367,125 @@ echo "${ECHO_T}$ac_cv_nolto" >&6
CFLAGS_NOLTO=""
fi
- echo "$as_me:$LINENO: checking if the linker understands --disable-high-entropy-va" >&5
-echo $ECHO_N "checking if the linker understands --disable-high-entropy-va... $ECHO_C" >&6
-if test "${tcl_cv_ld_high_entropy+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker understands --disable-high-entropy-va" >&5
+printf %s "checking if the linker understands --disable-high-entropy-va... " >&6; }
+if test ${tcl_cv_ld_high_entropy+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e)
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Wl,--disable-high-entropy-va"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main ()
+main (void)
{
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"
+then :
tcl_cv_ld_high_entropy=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_ld_high_entropy=no
+else case e in #(
+ e) tcl_cv_ld_high_entropy=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- CFLAGS=$hold_cflags
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS=$hold_cflags ;;
+esac
fi
-echo "$as_me:$LINENO: result: $tcl_cv_ld_high_entropy" >&5
-echo "${ECHO_T}$tcl_cv_ld_high_entropy" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_high_entropy" >&5
+printf "%s\n" "$tcl_cv_ld_high_entropy" >&6; }
if test $tcl_cv_ld_high_entropy = yes; then
extra_ldflags="$extra_ldflags -Wl,--disable-high-entropy-va"
fi
+
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -finput-charset" >&5
+printf %s "checking if the compiler understands -finput-charset... " >&6; }
+if test ${tcl_cv_cc_input_charset+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e)
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main (void)
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+ tcl_cv_cc_input_charset=yes
+else case e in #(
+ e) tcl_cv_cc_input_charset=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ CFLAGS=$hold_cflags ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_input_charset" >&5
+printf "%s\n" "$tcl_cv_cc_input_charset" >&6; }
+ if test $tcl_cv_cc_input_charset = yes; then
+ extra_cflags="$extra_cflags -finput-charset=UTF-8"
+ fi
fi
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Wl,--enable-auto-image-base"
- echo "$as_me:$LINENO: checking for working --enable-auto-image-base" >&5
-echo $ECHO_N "checking for working --enable-auto-image-base... $ECHO_C" >&6
-if test "${ac_cv_enable_auto_image_base+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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working --enable-auto-image-base" >&5
+printf %s "checking for working --enable-auto-image-base... " >&6; }
+if test ${ac_cv_enable_auto_image_base+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main ()
+main (void)
{
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"
+then :
ac_cv_enable_auto_image_base=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_enable_auto_image_base=no
+else case e in #(
+ e) ac_cv_enable_auto_image_base=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $ac_cv_enable_auto_image_base" >&5
-echo "${ECHO_T}$ac_cv_enable_auto_image_base" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_auto_image_base" >&5
+printf "%s\n" "$ac_cv_enable_auto_image_base" >&6; }
CFLAGS=$hold_cflags
if test "$ac_cv_enable_auto_image_base" = "yes" ; then
extra_ldflags="$extra_ldflags -Wl,--enable-auto-image-base"
fi
- echo "$as_me:$LINENO: checking compiler flags" >&5
-echo $ECHO_N "checking compiler flags... $ECHO_C" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking compiler flags" >&5
+printf %s "checking compiler flags... " >&6; }
if test "${GCC}" = "yes" ; then
SHLIB_LD=""
SHLIB_LD_LIBS='${LIBS}'
LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -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_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32 -lwinspool"
STLIB_LD='${AR} cr'
RC_OUT=-o
RC_TYPE=
@@ -3753,29 +4500,26 @@ 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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
+printf "%s\n" "using static flags" >&6; }
runtime=
LIBRARIES="\${STATIC_LIBRARIES}"
- EXESUFFIX="s\${DBGX}.exe"
+ EXESUFFIX="s.exe"
else
# dynamic
- echo "$as_me:$LINENO: result: using shared flags" >&5
-echo "${ECHO_T}using shared flags" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
+printf "%s\n" "using shared flags" >&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; }; }
+ as_fn_error $? "${CC} does not support the -shared option.
+ You will need to upgrade to a newer version of the toolchain." "$LINENO" 5
fi
runtime=
# Add SHLIB_LD_LIBS to the Make rule, not here.
- EXESUFFIX="\${DBGX}.exe"
+ EXESUFFIX=".exe"
LIBRARIES="\${SHARED_LIBRARIES}"
fi
# Link with gcc since ld does not link to default libs like
@@ -3786,16 +4530,16 @@ echo "$as_me: error: ${CC} does not support the -shared option.
-Wl,--out-implib,\$(patsubst %.dll,lib%.dll.a,\$@)"
# DLLSUFFIX is separate because it is the building block for
# users of tclConfig.sh that may build shared or static.
- DLLSUFFIX="\${DBGX}.dll"
- LIBSUFFIX="\${DBGX}.a"
- LIBFLAGSUFFIX="\${DBGX}"
+ DLLSUFFIX=".dll"
+ LIBSUFFIX=".a"
+ LIBFLAGSUFFIX=""
SHLIB_SUFFIX=.dll
EXTRA_CFLAGS="${extra_cflags}"
CFLAGS_DEBUG=-g
CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- CFLAGS_WARNING="-Wall -Wpointer-arith"
+ CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
LDFLAGS_DEBUG=
LDFLAGS_OPTIMIZE=
@@ -3804,7 +4548,7 @@ echo "$as_me: error: ${CC} does not support the -shared option.
CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
;;
*)
- CFLAGS_WARNING="${CFLAGS_WARNING} -Wdeclaration-after-statement"
+ CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -fextended-identifiers"
;;
esac
@@ -3832,25 +4576,21 @@ 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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using 64-bit $MACHINE mode" >&5
+printf "%s\n" " Using 64-bit $MACHINE mode" >&6; }
;;
arm64|aarch64)
MACHINE="ARM64"
- echo "$as_me:$LINENO: result: Using ARM64 $MACHINE mode" >&5
-echo "${ECHO_T} Using ARM64 $MACHINE mode" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using ARM64 $MACHINE mode" >&5
+printf "%s\n" " Using ARM64 $MACHINE mode" >&6; }
;;
ia64)
MACHINE="IA64"
- echo "$as_me:$LINENO: result: Using IA64 $MACHINE mode" >&5
-echo "${ECHO_T} Using IA64 $MACHINE mode" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using IA64 $MACHINE mode" >&5
+printf "%s\n" " Using IA64 $MACHINE mode" >&6; }
;;
*)
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifndef _WIN64
@@ -3858,68 +4598,46 @@ cat >>conftest.$ac_ext <<_ACEOF
#endif
int
-main ()
+main (void)
{
;
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
+if ac_fn_c_try_compile "$LINENO"
+then :
tcl_win_64bit=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_win_64bit=no
-
+else case e in #(
+ e) tcl_win_64bit=no
+ ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using 64-bit $MACHINE mode" >&5
+printf "%s\n" " Using 64-bit $MACHINE mode" >&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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
+printf "%s\n" "using static flags" >&6; }
runtime=-MT
LIBRARIES="\${STATIC_LIBRARIES}"
- EXESUFFIX="s\${DBGX}.exe"
+ EXESUFFIX="s.exe"
else
# dynamic
- echo "$as_me:$LINENO: result: using shared flags" >&5
-echo "${ECHO_T}using shared flags" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
+printf "%s\n" "using shared flags" >&6; }
runtime=-MD
# Add SHLIB_LD_LIBS to the Make rule, not here.
LIBRARIES="\${SHARED_LIBRARIES}"
- EXESUFFIX="\${DBGX}.exe"
+ EXESUFFIX=".exe"
case "x`echo \${VisualStudioVersion}`" in
x1[4-9]*)
lflags="${lflags} -nodefaultlib:ucrt.lib"
@@ -3931,9 +4649,9 @@ echo "${ECHO_T}using shared flags" >&6
MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\$@"
# DLLSUFFIX is separate because it is the building block for
# users of tclConfig.sh that may build shared or static.
- DLLSUFFIX="\${DBGX}.dll"
- LIBSUFFIX="\${DBGX}.lib"
- LIBFLAGSUFFIX="\${DBGX}"
+ DLLSUFFIX=".dll"
+ LIBSUFFIX=".lib"
+ LIBFLAGSUFFIX=""
if test "$do64bit" != "no" ; then
case "$do64bit" in
@@ -3947,8 +4665,8 @@ echo "${ECHO_T}using shared flags" >&6
MACHINE="IA64"
;;
esac
- echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5
-echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using 64-bit $MACHINE mode" >&5
+printf "%s\n" " Using 64-bit $MACHINE mode" >&6; }
fi
LIBS="netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib"
@@ -3981,111 +4699,7 @@ echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6
LINKBIN="link"
fi
- if test "$doWince" != "no" ; then
- # Set defaults for common evc4/PPC2003 setup
- # Currently Tcl requires 300+, possibly 420+ for sockets
- CEVERSION=420; # could be 211 300 301 400 420 ...
- TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
- ARCH=ARM; # could be ARM MIPS X86EM ...
- PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
- if test "$doWince" != "yes"; then
- # If !yes then the user specified something
- # Reset ARCH to allow user to skip specifying it
- ARCH=
- eval `echo $doWince | awk -F "," '{ \
- if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
- if ($1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
- if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
- if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
- if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
- }'`
- if test "x${ARCH}" = "x" ; then
- ARCH=$TARGETCPU;
- fi
- fi
- OSVERSION=WCE$CEVERSION;
- if test "x${WCEROOT}" = "x" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
- if test ! -d "${WCEROOT}" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
- fi
- fi
- if test "x${SDKROOT}" = "x" ; then
- SDKROOT="C:/Program Files/Windows CE Tools"
- if test ! -d "${SDKROOT}" ; then
- SDKROOT="C:/Windows CE Tools"
- fi
- fi
- # The space-based-path will work for the Makefile, but will
- # not work if AC_TRY_COMPILE is called.
- WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
- 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; }; }
- 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; }; }
- else
- CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
- if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
- CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
- fi
- CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
- fi
- fi
-
- if test "$doWince" != "no" ; then
- CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
- if test "${TARGETCPU}" = "X86"; then
- CC="${CEBINROOT}/cl.exe"
- else
- CC="${CEBINROOT}/cl${ARCH}.exe"
- fi
- CC="\"${CC}\" -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
- RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
- 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
-#define $i 1
-_ACEOF
-
- done
-# if test "${ARCH}" = "X86EM"; then
-# AC_DEFINE_UNQUOTED(_WIN32_WCE_EMULATION)
-# fi
- cat >>confdefs.h <<_ACEOF
-#define _WIN32_WCE $CEVERSION
-_ACEOF
-
- cat >>confdefs.h <<_ACEOF
-#define UNDER_CE $CEVERSION
-_ACEOF
-
- 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
- LIBS="coredll.lib corelibc.lib ws2.lib"
- fi
- # celib currently stuck at wce300 status
- #LIBS="$LIBS \${CELIB_DIR}/wince-${ARCH}-pocket-${OSVERSION}-release/celib.lib"
- 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"
- fi
+ LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib winspool.lib"
SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
SHLIB_LD_LIBS='${LIBS}'
@@ -4116,7 +4730,7 @@ _ACEOF
# Specify linker flags depending on the type of app being
# built -- Console vs. Window.
- if test "$doWince" != "no" -a "${TARGETCPU}" != "X86"; then
+ if test "${TARGETCPU}" != "X86"; then
LDFLAGS_CONSOLE="-link ${lflags}"
LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
else
@@ -4126,26 +4740,66 @@ _ACEOF
fi
if test "$do64bit" != "no" ; then
- cat >>confdefs.h <<\_ACEOF
-#define TCL_CFG_DO64BIT 1
-_ACEOF
+ printf "%s\n" "#define TCL_CFG_DO64BIT 1" >>confdefs.h
fi
if test "${GCC}" = "yes" ; then
- echo "$as_me:$LINENO: checking for SEH support in compiler" >&5
-echo $ECHO_N "checking for SEH support in compiler... $ECHO_C" >&6
-if test "${tcl_cv_seh+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5
+printf %s "checking for SEH support in compiler... " >&6; }
+if test ${tcl_cv_seh+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) 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
+else case e in #(
+ e)
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
+# executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+then :
+ ac_retval=0
+else case e in #(
+ e) printf "%s\n" "$as_me: program exited with status $ac_status" >&5
+ printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status ;;
+esac
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define WIN32_LEAN_AND_MEAN
@@ -4164,37 +4818,26 @@ cat >>conftest.$ac_ext <<_ACEOF
}
_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
+if ac_fn_c_try_run "$LINENO"
+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
+else case e in #(
+ e) tcl_cv_seh=no ;;
+esac
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
+esac
fi
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $tcl_cv_seh" >&5
-echo "${ECHO_T}$tcl_cv_seh" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5
+printf "%s\n" "$tcl_cv_seh" >&6; }
if test "$tcl_cv_seh" = "no" ; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_NO_SEH 1
-_ACEOF
+printf "%s\n" "#define HAVE_NO_SEH 1" >>confdefs.h
fi
@@ -4204,16 +4847,13 @@ _ACEOF
# with Cygwin's version as of 2002-04-10, define it to be int,
# sufficient for getting the current code to work.
#
- echo "$as_me:$LINENO: checking for EXCEPTION_DISPOSITION support in include files" >&5
-echo $ECHO_N "checking for EXCEPTION_DISPOSITION support in include files... $ECHO_C" >&6
-if test "${tcl_cv_eh_disposition+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5
+printf %s "checking for EXCEPTION_DISPOSITION support in include files... " >&6; }
+if test ${tcl_cv_eh_disposition+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
# define WIN32_LEAN_AND_MEAN
@@ -4221,7 +4861,7 @@ cat >>conftest.$ac_ext <<_ACEOF
# undef WIN32_LEAN_AND_MEAN
int
-main ()
+main (void)
{
EXCEPTION_DISPOSITION x;
@@ -4230,141 +4870,49 @@ 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
+if ac_fn_c_try_compile "$LINENO"
+then :
tcl_cv_eh_disposition=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_eh_disposition=no
+else case e in #(
+ e) tcl_cv_eh_disposition=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $tcl_cv_eh_disposition" >&5
-echo "${ECHO_T}$tcl_cv_eh_disposition" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5
+printf "%s\n" "$tcl_cv_eh_disposition" >&6; }
if test "$tcl_cv_eh_disposition" = "no" ; then
-cat >>confdefs.h <<\_ACEOF
-#define EXCEPTION_DISPOSITION int
-_ACEOF
+printf "%s\n" "#define EXCEPTION_DISPOSITION int" >>confdefs.h
fi
- # Check to see if winnt.h defines CHAR, SHORT, and LONG
- # even if VOID has already been #defined. The win32api
- # used by mingw and cygwin is known to do this.
-
- echo "$as_me:$LINENO: checking for winnt.h that ignores VOID define" >&5
-echo $ECHO_N "checking for winnt.h that ignores VOID define... $ECHO_C" >&6
-if test "${tcl_cv_winnt_ignore_void+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
- #define VOID void
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #undef WIN32_LEAN_AND_MEAN
-
-int
-main ()
-{
-
- CHAR c;
- SHORT s;
- LONG l;
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_winnt_ignore_void=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ ac_fn_c_check_header_compile "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdbool_h" = xyes
+then :
-tcl_cv_winnt_ignore_void=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+printf "%s\n" "#define HAVE_STDBOOL_H 1" >>confdefs.h
fi
-echo "$as_me:$LINENO: result: $tcl_cv_winnt_ignore_void" >&5
-echo "${ECHO_T}$tcl_cv_winnt_ignore_void" >&6
- if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_WINNT_IGNORE_VOID 1
-_ACEOF
- fi
# See if the compiler supports casting to a union type.
# This is used to stop gcc from printing a compiler
# warning when initializing a union member.
- echo "$as_me:$LINENO: checking for cast to union support" >&5
-echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6
-if test "${tcl_cv_cast_to_union+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
+printf %s "checking for cast to union support... " >&6; }
+if test ${tcl_cv_cast_to_union+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main ()
+main (void)
{
union foo { int i; double d; };
@@ -4374,45 +4922,22 @@ 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
+if ac_fn_c_try_compile "$LINENO"
+then :
tcl_cv_cast_to_union=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cast_to_union=no
+else case e in #(
+ e) tcl_cv_cast_to_union=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5
-echo "${ECHO_T}$tcl_cv_cast_to_union" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
+printf "%s\n" "$tcl_cv_cast_to_union" >&6; }
if test "$tcl_cv_cast_to_union" = "yes"; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CAST_TO_UNION 1
-_ACEOF
+printf "%s\n" "#define HAVE_CAST_TO_UNION 1" >>confdefs.h
fi
fi
@@ -4436,428 +4961,344 @@ case ${host_alias} in
esac
#------------------------------------------------------------------------
-# Add stuff for zlib; note that this is mostly done in the makefile now
-# as we just assume that the platform hasn't got a usable z.lib
+# Add stuff for zlib/libtommath; note that this is mostly done in the
+# makefile now as we just assume that the platform hasn't got usable
+# z.lib/tommath.lib
#------------------------------------------------------------------------
-if test "${enable_shared+set}" = "set"; then
+if test "${enable_shared+set}" = "set"
+then :
enableval="$enable_shared"
tcl_ok=$enableval
-else
-
+else case e in #(
+ e)
tcl_ok=yes
-
+ ;;
+esac
fi
-
zlib_lib_name=zdll.lib
-if test "$tcl_ok" = "yes"; then
+tommath_lib_name=tommath.lib
+if test "$tcl_ok" = "yes"
+then :
ZLIB_DLL_FILE=\${ZLIB_DLL_FILE}
- if test "$do64bit" != "no"; then
+ TOMMATH_DLL_FILE=\${TOMMATH_DLL_FILE}
+
+
+printf "%s\n" "#define TCL_WITH_EXTERNAL_TOMMATH 1" >>confdefs.h
+
+ if test "$do64bit" != "no"
+then :
+
- if test "$do64bit" = "arm64" -o "$do64bit" = "aarch64"; then
+printf "%s\n" "#define MP_64BIT 1" >>confdefs.h
- if test "$GCC" = "yes"; then
+ if test "$do64bit" = "arm64" -o "$do64bit" = "aarch64"
+then :
+
+ if test "$GCC" = "yes"
+then :
ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64-arm/libz.dll.a
- zlib_lib_name=libz.dll.a
+ TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.a
-else
+ zlib_lib_name=libz.dll.a
+ tommath_lib_name=libtommath.dll.a
+else case e in #(
+ e)
ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64-arm/zdll.lib
+ TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64-arm/tommath.lib
+ ;;
+esac
fi
-
-else
-
- if test "$GCC" = "yes"; then
+else case e in #(
+ e)
+ if test "$GCC" = "yes"
+then :
ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64/libz.dll.a
- zlib_lib_name=libz.dll.a
+ TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64/libtommath.dll.a
-else
+ zlib_lib_name=libz.dll.a
+ tommath_lib_name=libtommath.dll.a
+else case e in #(
+ e)
ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64/zdll.lib
+ TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win64/tommath.lib
+ ;;
+esac
fi
-
-
+ ;;
+esac
fi
-
-else
-
+else case e in #(
+ e)
ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win32/zdll.lib
+ TOMMATH_LIBS=\${TOMMATH_DIR_NATIVE}/win32/tommath.lib
+ ;;
+esac
fi
+else case e in #(
+ e)
-else
+printf "%s\n" "#define TCL_WITH_INTERNAL_ZLIB 1" >>confdefs.h
ZLIB_OBJS=\${ZLIB_OBJS}
+ TOMMATH_OBJS=\${TOMMATH_OBJS}
+ ;;
+esac
fi
-
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ZLIB 1
-_ACEOF
-
TCL_ZLIB_LIB_NAME=$zlib_lib_name
+TCL_TOMMATH_LIB_NAME=$tommath_lib_name
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
+ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "
+#include <stdint.h>
+"
+if test "x$ac_cv_type_intptr_t" = xyes
+then :
+printf "%s\n" "#define HAVE_INTPTR_T 1" >>confdefs.h
+fi
+ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "
+#include <stdint.h>
+"
+if test "x$ac_cv_type_uintptr_t" = xyes
+then :
+printf "%s\n" "#define HAVE_UINTPTR_T 1" >>confdefs.h
-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
+fi
-#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
+#--------------------------------------------------------------------
+# Zipfs support - Tip 430
+#--------------------------------------------------------------------
+# Check whether --enable-zipfs was given.
+if test ${enable_zipfs+y}
+then :
+ enableval=$enable_zipfs; tcl_ok=$enableval
+else case e in #(
+ e) tcl_ok=yes ;;
+esac
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
+if test "$tcl_ok" = "yes" ; then
+ #
+ # Find a native compiler
+ #
+ # Put a plausible default for CC_FOR_BUILD in Makefile.
+if test -z "$CC_FOR_BUILD"; then
+ if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+ else
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5
+printf %s "checking for gcc... " >&6; }
+ if test ${ac_cv_path_cc+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e)
+ search_path=`echo ${PATH} | sed -e 's/:/ /g'`
+ for dir in $search_path ; do
+ for j in `ls -r $dir/gcc 2> /dev/null` \
+ `ls -r $dir/gcc 2> /dev/null` ; do
+ if test x"$ac_cv_path_cc" = x ; then
+ if test -f "$j" ; then
+ ac_cv_path_cc=$j
+ break
+ fi
+ fi
+ done
+ done
+ ;;
+esac
fi
-done
-
-
-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
+ fi
+fi
-ac_cv_type_intptr_t=no
+# Also set EXEEXT_FOR_BUILD.
+if test "x$cross_compiling" = "xno"; then
+ EXEEXT_FOR_BUILD='$(EXEEXT)'
+ OBJEXT_FOR_BUILD='$(OBJEXT)'
+else
+ OBJEXT_FOR_BUILD='.no'
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5
+printf %s "checking for build system executable suffix... " >&6; }
+if test ${bfd_cv_build_exeext+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.c
+ bfd_cv_build_exeext=
+ ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ rm -f conftest*
+ test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5
+printf "%s\n" "$bfd_cv_build_exeext" >&6; }
+ EXEEXT_FOR_BUILD=""
+ test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
+fi
+
+ #
+ # Find a native zip implementation
+ #
+
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
+printf %s "checking for tclsh... " >&6; }
+
+ if test ${ac_cv_path_tclsh+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e)
+ search_path=`echo ${PATH} | sed -e 's/:/ /g'`
+ for dir in $search_path ; do
+ for j in `ls -r $dir/tclsh[8-9]*.exe 2> /dev/null` \
+ `ls -r $dir/tclsh* 2> /dev/null` ; do
+ if test x"$ac_cv_path_tclsh" = x ; then
+ if test -f "$j" ; then
+ ac_cv_path_tclsh=$j
+ break
+ fi
+ fi
+ done
+ done
+ ;;
+esac
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
+ if test -f "$ac_cv_path_tclsh" ; then
+ TCLSH_PROG="$ac_cv_path_tclsh"
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5
+printf "%s\n" "$TCLSH_PROG" >&6; }
+ else
+ # It is not an error if an installed version of Tcl can't be located.
+ TCLSH_PROG=""
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5
+printf "%s\n" "No tclsh found on PATH" >&6; }
+ fi
-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
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ ZIP_INSTALL_OBJS=""
+
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zip" >&5
+printf %s "checking for zip... " >&6; }
+ if test ${ac_cv_path_zip+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e)
+ search_path=`echo ${PATH} | sed -e 's/:/ /g'`
+ for dir in $search_path ; do
+ for j in `ls -r $dir/zip 2> /dev/null` \
+ `ls -r $dir/zip 2> /dev/null` ; do
+ if test x"$ac_cv_path_zip" = x ; then
+ if test -f "$j" ; then
+ ac_cv_path_zip=$j
+ break
+ fi
+ fi
+ done
done
+ ;;
+esac
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
+ if test -f "$ac_cv_path_zip" ; then
+ ZIP_PROG="$ac_cv_path_zip"
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5
+printf "%s\n" "$ZIP_PROG" >&6; }
+ ZIP_PROG_OPTIONS="-rq"
+ ZIP_PROG_VFSSEARCH="*"
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5
+printf "%s\n" "Found INFO Zip in environment" >&6; }
+ # Use standard arguments for zip
+ else
+ # It is not an error if an installed version of Zip can't be located.
+ # We can use the locally distributed minizip instead
+ ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
+ ZIP_PROG_OPTIONS="-o -r"
+ ZIP_PROG_VFSSEARCH="*"
+ ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5
+printf "%s\n" "No zip found on PATH building minizip" >&6; }
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
+ ZIPFS_BUILD=1
+ TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip
else
+ ZIPFS_BUILD=0
+ TCL_ZIP_FILE=
+fi
+# Do checking message here to not mess up interleaved configure output
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5
+printf %s "checking for building with zipfs... " >&6; }
+if test "${ZIPFS_BUILD}" = 1; then
+ if test "${SHARED_BUILD}" = 0; then
+ ZIPFS_BUILD=2;
- 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
+printf "%s\n" "#define ZIPFS_BUILD 2" >>confdefs.h
- 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
+ else
- ;
- 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
+printf "%s\n" "#define ZIPFS_BUILD 1" >>confdefs.h
+\
+ fi
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_ok=no
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+INSTALL_LIBRARIES=install-libraries
+INSTALL_MSGS=install-msgs
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
+
#--------------------------------------------------------------------
@@ -4868,16 +5309,13 @@ fi
# 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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for FINDEX_INFO_LEVELS in winbase.h" >&5
+printf %s "checking for FINDEX_INFO_LEVELS in winbase.h... " >&6; }
+if test ${tcl_cv_findex_enums+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define WIN32_LEAN_AND_MEAN
@@ -4885,7 +5323,7 @@ cat >>conftest.$ac_ext <<_ACEOF
#undef WIN32_LEAN_AND_MEAN
int
-main ()
+main (void)
{
FINDEX_INFO_LEVELS i;
@@ -4895,60 +5333,34 @@ 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
+if ac_fn_c_try_compile "$LINENO"
+then :
tcl_cv_findex_enums=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_findex_enums=no
+else case e in #(
+ e) tcl_cv_findex_enums=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $tcl_cv_findex_enums" >&5
-echo "${ECHO_T}$tcl_cv_findex_enums" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_findex_enums" >&5
+printf "%s\n" "$tcl_cv_findex_enums" >&6; }
if test "$tcl_cv_findex_enums" = "no"; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_NO_FINDEX_ENUMS 1
-_ACEOF
+printf "%s\n" "#define HAVE_NO_FINDEX_ENUMS 1" >>confdefs.h
fi
# See if the compiler supports intrinsics.
-echo "$as_me:$LINENO: checking for intrinsics support in compiler" >&5
-echo $ECHO_N "checking for intrinsics support in compiler... $ECHO_C" >&6
-if test "${tcl_cv_intrinsics+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for intrinsics support in compiler" >&5
+printf %s "checking for intrinsics support in compiler... " >&6; }
+if test ${tcl_cv_intrinsics+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define WIN32_LEAN_AND_MEAN
@@ -4957,7 +5369,7 @@ cat >>conftest.$ac_ext <<_ACEOF
#include <intrin.h>
int
-main ()
+main (void)
{
__cpuidex(0,0,0);
@@ -4966,67 +5378,41 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"
+then :
tcl_cv_intrinsics=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_intrinsics=no
+else case e in #(
+ e) tcl_cv_intrinsics=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $tcl_cv_intrinsics" >&5
-echo "${ECHO_T}$tcl_cv_intrinsics" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intrinsics" >&5
+printf "%s\n" "$tcl_cv_intrinsics" >&6; }
if test "$tcl_cv_intrinsics" = "yes"; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_INTRIN_H 1
-_ACEOF
+printf "%s\n" "#define HAVE_INTRIN_H 1" >>confdefs.h
fi
# See if the compiler supports cpuid header.
-echo "$as_me:$LINENO: checking for cpuid.h" >&5
-echo $ECHO_N "checking for cpuid.h... $ECHO_C" >&6
-if test "${tcl_cv_cpuid_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cpuid.h" >&5
+printf %s "checking for cpuid.h... " >&6; }
+if test ${tcl_cv_cpuid_h+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <cpuid.h>
int
-main ()
+main (void)
{
__get_cpuid(0, 0, 0, 0, 0);
@@ -5035,111 +5421,62 @@ 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
+if ac_fn_c_try_compile "$LINENO"
+then :
tcl_cv_cpuid_h=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cpuid_h=no
+else case e in #(
+ e) tcl_cv_cpuid_h=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cpuid_h" >&5
-echo "${ECHO_T}$tcl_cv_cpuid_h" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cpuid_h" >&5
+printf "%s\n" "$tcl_cv_cpuid_h" >&6; }
if test "$tcl_cv_cpuid_h" = "yes"; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CPUID_H 1
-_ACEOF
+printf "%s\n" "#define HAVE_CPUID_H 1" >>confdefs.h
fi
# See if the <wspiapi.h> header file is present
-echo "$as_me:$LINENO: checking for wspiapi.h" >&5
-echo $ECHO_N "checking for wspiapi.h... $ECHO_C" >&6
-if test "${tcl_cv_wspiapi_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wspiapi.h" >&5
+printf %s "checking for wspiapi.h... " >&6; }
+if test ${tcl_cv_wspiapi_h+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <wspiapi.h>
int
-main ()
+main (void)
{
;
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
+if ac_fn_c_try_compile "$LINENO"
+then :
tcl_cv_wspiapi_h=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_wspiapi_h=no
+else case e in #(
+ e) tcl_cv_wspiapi_h=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $tcl_cv_wspiapi_h" >&5
-echo "${ECHO_T}$tcl_cv_wspiapi_h" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_wspiapi_h" >&5
+printf "%s\n" "$tcl_cv_wspiapi_h" >&6; }
if test "$tcl_cv_wspiapi_h" = "yes"; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_WSPIAPI_H 1
-_ACEOF
+printf "%s\n" "#define HAVE_WSPIAPI_H 1" >>confdefs.h
fi
@@ -5147,16 +5484,13 @@ fi
# 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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for FINDEX_INFO_LEVELS in winbase.h" >&5
+printf %s "checking for FINDEX_INFO_LEVELS in winbase.h... " >&6; }
+if test ${tcl_cv_findex_enums+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define WIN32_LEAN_AND_MEAN
@@ -5164,7 +5498,7 @@ cat >>conftest.$ac_ext <<_ACEOF
#undef WIN32_LEAN_AND_MEAN
int
-main ()
+main (void)
{
FINDEX_INFO_LEVELS i;
@@ -5174,45 +5508,22 @@ 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
+if ac_fn_c_try_compile "$LINENO"
+then :
tcl_cv_findex_enums=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_findex_enums=no
+else case e in #(
+ e) tcl_cv_findex_enums=no ;;
+esac
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $tcl_cv_findex_enums" >&5
-echo "${ECHO_T}$tcl_cv_findex_enums" >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_findex_enums" >&5
+printf "%s\n" "$tcl_cv_findex_enums" >&6; }
if test "$tcl_cv_findex_enums" = "no"; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_NO_FINDEX_ENUMS 1
-_ACEOF
+printf "%s\n" "#define HAVE_NO_FINDEX_ENUMS 1" >>confdefs.h
fi
@@ -5223,39 +5534,35 @@ fi
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for build with symbols" >&5
-echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6
- # 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;
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
+printf %s "checking for build with symbols... " >&6; }
+ # Check whether --enable-symbols was given.
+if test ${enable_symbols+y}
+then :
+ enableval=$enable_symbols; tcl_ok=$enableval
+else case e in #(
+ e) tcl_ok=no ;;
+esac
+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=""
-cat >>confdefs.h <<\_ACEOF
-#define NDEBUG 1
-_ACEOF
+printf "%s\n" "#define NDEBUG 1" >>confdefs.h
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
- cat >>confdefs.h <<\_ACEOF
-#define TCL_CFG_OPTIMIZED 1
-_ACEOF
+ printf "%s\n" "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h
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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
+printf "%s\n" "yes (standard debugging)" >&6; }
fi
fi
@@ -5263,52 +5570,319 @@ echo "${ECHO_T}yes (standard debugging)" >&6
if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
-cat >>confdefs.h <<\_ACEOF
-#define TCL_MEM_DEBUG 1
-_ACEOF
+printf "%s\n" "#define TCL_MEM_DEBUG 1" >>confdefs.h
fi
if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then
-cat >>confdefs.h <<\_ACEOF
-#define TCL_COMPILE_DEBUG 1
-_ACEOF
+printf "%s\n" "#define TCL_COMPILE_DEBUG 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define TCL_COMPILE_STATS 1
-_ACEOF
+printf "%s\n" "#define TCL_COMPILE_STATS 1" >>confdefs.h
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
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem compile debugging" >&5
+printf "%s\n" "enabled symbols mem compile debugging" >&6; }
else
- echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
-echo "${ECHO_T}enabled $tcl_ok debugging" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
+printf "%s\n" "enabled $tcl_ok debugging" >&6; }
fi
fi
-TCL_DBGX=${DBGX}
-
#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------
+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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+printf %s "checking how to run the C preprocessor... " >&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+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) # Double quotes because $CC needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" 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.
+ # 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+
+else case e in #(
+ e) # Broken: fails on valid input.
+continue ;;
+esac
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+ # Broken: success on invalid input.
+continue
+else case e in #(
+ e) # Passes both tests.
+ac_preproc_ok=:
+break ;;
+esac
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok
+then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+ ;;
+esac
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+printf "%s\n" "$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.
+ # 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+
+else case e in #(
+ e) # Broken: fails on valid input.
+continue ;;
+esac
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+ # Broken: success on invalid input.
+continue
+else case e in #(
+ e) # Passes both tests.
+ac_preproc_ok=:
+break ;;
+esac
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok
+then :
+
+else case e in #(
+ e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See 'config.log' for more details" "$LINENO" 5; } ;;
+esac
+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
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep -e" >&5
+printf %s "checking for egrep -e... " >&6; }
+if test ${ac_cv_path_EGREP_TRADITIONAL+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) if test -z "$EGREP_TRADITIONAL"; then
+ ac_path_EGREP_TRADITIONAL_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_prog in grep ggrep
+ do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP_TRADITIONAL="$as_dir$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP_TRADITIONAL" || continue
+# Check for GNU ac_path_EGREP_TRADITIONAL and select it if it is found.
+ # Check for GNU $ac_path_EGREP_TRADITIONAL
+case `"$ac_path_EGREP_TRADITIONAL" --version 2>&1` in #(
+*GNU*)
+ ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" ac_path_EGREP_TRADITIONAL_found=:;;
+#(
+*)
+ ac_count=0
+ printf %s 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ printf "%s\n" 'EGREP_TRADITIONAL' >> "conftest.nl"
+ "$ac_path_EGREP_TRADITIONAL" -E 'EGR(EP|AC)_TRADITIONAL$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_TRADITIONAL_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL"
+ ac_path_EGREP_TRADITIONAL_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_TRADITIONAL_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP_TRADITIONAL"; then
+ :
+ fi
+else
+ ac_cv_path_EGREP_TRADITIONAL=$EGREP_TRADITIONAL
+fi
+
+ if test "$ac_cv_path_EGREP_TRADITIONAL"
+then :
+ ac_cv_path_EGREP_TRADITIONAL="$ac_cv_path_EGREP_TRADITIONAL -E"
+else case e in #(
+ e) if test -z "$EGREP_TRADITIONAL"; then
+ ac_path_EGREP_TRADITIONAL_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ for ac_prog in egrep
+ do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP_TRADITIONAL="$as_dir$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP_TRADITIONAL" || continue
+# Check for GNU ac_path_EGREP_TRADITIONAL and select it if it is found.
+ # Check for GNU $ac_path_EGREP_TRADITIONAL
+case `"$ac_path_EGREP_TRADITIONAL" --version 2>&1` in #(
+*GNU*)
+ ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" ac_path_EGREP_TRADITIONAL_found=:;;
+#(
+*)
+ ac_count=0
+ printf %s 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ printf "%s\n" 'EGREP_TRADITIONAL' >> "conftest.nl"
+ "$ac_path_EGREP_TRADITIONAL" 'EGR(EP|AC)_TRADITIONAL$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_TRADITIONAL_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL"
+ ac_path_EGREP_TRADITIONAL_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
- 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
+ $ac_path_EGREP_TRADITIONAL_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP_TRADITIONAL"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
else
- embed_ok=yes
-fi;
+ ac_cv_path_EGREP_TRADITIONAL=$EGREP_TRADITIONAL
+fi
+ ;;
+esac
+fi ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP_TRADITIONAL" >&5
+printf "%s\n" "$ac_cv_path_EGREP_TRADITIONAL" >&6; }
+ EGREP_TRADITIONAL=$ac_cv_path_EGREP_TRADITIONAL
+
+
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to embed manifest" >&5
+printf %s "checking whether to embed manifest... " >&6; }
+ # Check whether --enable-embedded-manifest was given.
+if test ${enable_embedded_manifest+y}
+then :
+ enableval=$enable_embedded_manifest; embed_ok=$enableval
+else case e in #(
+ e) embed_ok=yes ;;
+esac
+fi
+
VC_MANIFEST_EMBED_DLL=
VC_MANIFEST_EMBED_EXE=
@@ -5316,11 +5890,7 @@ fi;
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
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#if defined(_MSC_VER) && _MSC_VER >= 1400
@@ -5329,7 +5899,8 @@ print("manifest needed")
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "manifest needed" >/dev/null 2>&1; then
+ $EGREP_TRADITIONAL "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
@@ -5345,11 +5916,11 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
fi
fi
-rm -f conftest*
+rm -rf conftest*
fi
- echo "$as_me:$LINENO: result: $result" >&5
-echo "${ECHO_T}$result" >&6
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $result" >&5
+printf "%s\n" "$result" >&6; }
@@ -5368,8 +5939,8 @@ eval "TCL_SRC_DIR=\"`cd $srcdir/..; $CYGPATH $(pwd)`\""
eval "TCL_DLL_FILE=tcl${VER}${DLLSUFFIX}"
-eval "TCL_STUB_LIB_FILE=\"${LIBPREFIX}tclstub${VER}${LIBSUFFIX}\""
-eval "TCL_STUB_LIB_FLAG=\"-ltclstub${VER}${LIBFLAGSUFFIX}\""
+eval "TCL_STUB_LIB_FILE=\"${LIBPREFIX}tclstub${LIBSUFFIX}\""
+eval "TCL_STUB_LIB_FLAG=\"-ltclstub${LIBFLAGSUFFIX}\""
eval "TCL_BUILD_STUB_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TCL_STUB_LIB_FLAG}\""
eval "TCL_STUB_LIB_SPEC=\"-L${libdir} ${TCL_STUB_LIB_FLAG}\""
eval "TCL_BUILD_STUB_LIB_PATH=\"`$CYGPATH $(pwd)`/${TCL_STUB_LIB_FILE}\""
@@ -5388,11 +5959,6 @@ eval "TCL_LIB_SPEC=\"-L${libdir} ${TCL_LIB_FLAG}\""
# Install time header dir can be set via --includedir
eval "TCL_INCLUDE_SPEC=\"-I${includedir}\""
-eval "DLLSUFFIX=${DLLSUFFIX}"
-eval "LIBPREFIX=${LIBPREFIX}"
-eval "LIBSUFFIX=${LIBSUFFIX}"
-eval "EXESUFFIX=${EXESUFFIX}"
-
TCL_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TCL_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
@@ -5405,17 +5971,9 @@ CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}
#--------------------------------------------------------------------
if test ${SHARED_BUILD} = 0 ; then
- if test "${DBGX}" = "g"; then
- RC_DEFINES="${RC_DEFINE} STATIC_BUILD ${RC_DEFINE} DEBUG"
- else
- RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
- fi
+ RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
else
- if test "${DBGX}" = "g"; then
- RC_DEFINES="${RC_DEFINE} DEBUG"
- else
- RC_DEFINES=""
- fi
+ RC_DEFINES=""
fi
#--------------------------------------------------------------------
@@ -5473,7 +6031,6 @@ TCL_WIN_VERSION="$TCL_VERSION.$TCL_RELEASE_LEVEL.`echo $TCL_PATCH_LEVEL | tr -d
-
# win/tcl.m4 doesn't set (CFLAGS)
@@ -5511,12 +6068,6 @@ TCL_WIN_VERSION="$TCL_VERSION.$TCL_RELEASE_LEVEL.`echo $TCL_PATCH_LEVEL | tr -d
-# empty on win, but needs sub'ing
-
-
-
-
-
@@ -5536,7 +6087,7 @@ TCL_WIN_VERSION="$TCL_VERSION.$TCL_RELEASE_LEVEL.`echo $TCL_PATCH_LEVEL | tr -d
- ac_config_files="$ac_config_files Makefile tclConfig.sh tcl.hpj tclsh.exe.manifest"
+ac_config_files="$ac_config_files Makefile tclConfig.sh tclsh.exe.manifest"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -5548,47 +6099,78 @@ cat >confcache <<\_ACEOF
# 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
+# '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
# 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.
+# So, we kill variables containing newlines.
# 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.
-{
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
(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 \).
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}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"
+ # 'set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
;;
- esac;
-} |
+ esac |
+ sort
+) |
sed '
+ /^ac_cv_env_/b end
t clear
- : clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
t end
- /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- : end' >>confcache
-if diff $cache_file confcache >/dev/null 2>&1; then :; else
- if test -w $cache_file; then
- test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
- cat confcache >$cache_file
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
else
- echo "not updating unwritable cache $cache_file"
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
fi
fi
rm -f confcache
@@ -5597,63 +6179,53 @@ 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).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/;
-s/:*\${srcdir}:*/:/;
-s/:*@srcdir@:*/:/;
-s/^\([^=]*=[ ]*\):*/\1/;
-s/:*$//;
-s/^[^=]*=[ ]*$//;
-}'
-fi
-
# 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,
+# take arguments), then branch to the quote section. Otherwise,
# look for a macro that doesn't take arguments.
-cat >confdef2opt.sed <<\_ACEOF
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
t clear
-: clear
-s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
t quote
-s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
+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
+b any
+:quote
+s/[][ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
ac_libobjs=
ac_ltlibobjs=
+U=
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'
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs
@@ -5661,12 +6233,14 @@ LTLIBOBJS=$ac_ltlibobjs
-: ${CONFIG_STATUS=./config.status}
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
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
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
@@ -5676,81 +6250,237 @@ cat >$CONFIG_STATUS <<_ACEOF
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
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
emulate sh
NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # Pre-4.2 versions of Zsh do 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
+ setopt NO_GLOB_SUBST
+else case e in #(
+ e) case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac ;;
+esac
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
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
+as_nl='
+'
+export as_nl
+IFS=" "" $as_nl"
+
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
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2) ; then :; else exec 2>/dev/null; fi
+
+# The user is always right.
+if ${PATH_SEPARATOR+false} :; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
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
+ IFS=$as_save_IFS
+ case $as_dir in #(((
+ '') as_dir=./ ;;
+ */) ;;
+ *) as_dir=$as_dir/ ;;
+ esac
+ test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+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
+ printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
-done
+ printf "%s\n" "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else case e in #(
+ e) as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ } ;;
+esac
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else case e in #(
+ e) as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ } ;;
+esac
+fi # as_fn_arith
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
as_expr=expr
else
as_expr=false
fi
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
-# Name of the executable.
-as_me=`$as_basename "$0" ||
+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'`
-
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" 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'
@@ -5758,181 +6488,145 @@ 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:$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= ;;
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
esac
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n. New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
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
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.
+ # In both cases, we have to default to 'cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
-rm -f conf$$ conf$$.exe conf$$.file
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+} # as_fn_mkdir_p
if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
+ as_mkdir_p='mkdir -p "$as_dir"'
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
-as_executable_p="test -f"
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# 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'"
+as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated
# 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"
+as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+as_tr_sh="eval sed '$as_sed_sh'" # deprecated
-# CDPATH.
-$as_unset CDPATH
exec 6>&1
-
-# Open the log real soon, to keep \$[0] and so on meaningful, and to
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, 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 tcl $as_me 8.6, which was
-generated by GNU Autoconf 2.59. Invocation command line was
+# values after options handling.
+ac_log="
+This file was extended by tcl $as_me 9.0, which was
+generated by GNU Autoconf 2.72. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -5940,124 +6634,118 @@ generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_COMMANDS = $CONFIG_COMMANDS
$ $0 $@
-_CSEOF
-echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
-echo >&5
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
_ACEOF
-# Files that config.status was made for.
-if test -n "$ac_config_files"; then
- echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
-fi
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
-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_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
-cat >>$CONFIG_STATUS <<\_ACEOF
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
+'$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
-Usage: $0 [OPTIONS] [FILE]...
+Usage: $0 [OPTION]... [TAG]...
-h, --help print this help, then exit
- -V, --version print version number, then exit
- -q, --quiet do not print progress messages
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ 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
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
Configuration files:
$config_files
-Report bugs to <bug-autoconf@gnu.org>."
-_ACEOF
+Report bugs to the package provider."
-cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
+ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-tcl config.status 8.6
-configured by $0, generated by GNU Autoconf 2.59,
- with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+tcl config.status 9.0
+configured by $0, generated by GNU Autoconf 2.72,
+ with options \\"\$ac_cs_config\\"
-Copyright (C) 2003 Free Software Foundation, Inc.
+Copyright (C) 2023 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
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
_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.
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
ac_need_defaults=:
while test $# != 0
do
case $1 in
- --*=*)
- ac_option=`expr "x$1" : 'x\([^=]*\)='`
- ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
ac_shift=:
;;
- -*)
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ 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 )
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ printf "%s\n" "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ printf "%s\n" "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --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"
+ case $ac_optarg in
+ *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ printf "%s\n" "$ac_cs_usage"; exit ;;
-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; }; } ;;
+ -*) as_fn_error $? "unrecognized option: '$1'
+Try '$0 --help' for more information." ;;
- *) ac_config_targets="$ac_config_targets $1" ;;
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
esac
shift
@@ -6071,456 +6759,463 @@ if $ac_cs_silent; then
fi
_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
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
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
fi
_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ printf "%s\n" "$ac_log"
+} >&5
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-
-cat >>$CONFIG_STATUS <<\_ACEOF
+# Handling of arguments.
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" ;;
- "tclsh.exe.manifest" ) CONFIG_FILES="$CONFIG_FILES tclsh.exe.manifest" ;;
- *) { { 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; }; };;
+ case $ac_config_target in
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "tclConfig.sh") CONFIG_FILES="$CONFIG_FILES tclConfig.sh" ;;
+ "tclsh.exe.manifest") CONFIG_FILES="$CONFIG_FILES tclsh.exe.manifest" ;;
+
+ *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;;
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
+ test ${CONFIG_FILES+y} || 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,
+# simply because there is no reason against having 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.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to '$tmp'.
$debug ||
{
- trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
- trap '{ (exit 1); exit 1; }' 1 2 13 15
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_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=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
} ||
{
- tmp=./confstat$$-$RANDOM
- (umask 077 && mkdir $tmp)
-} ||
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with './config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
{
- echo "$me: cannot create a temporary directory in ." >&2
- { (exit 1); exit 1; }
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
}
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries 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).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
-#
-# CONFIG_FILES section.
-#
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
-# 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_NOLTO@,$CFLAGS_NOLTO,;t t
-s,@ZLIB_DLL_FILE@,$ZLIB_DLL_FILE,;t t
-s,@ZLIB_LIBS@,$ZLIB_LIBS,;t t
-s,@ZLIB_OBJS@,$ZLIB_OBJS,;t t
-s,@TCL_ZLIB_LIB_NAME@,$TCL_ZLIB_LIB_NAME,;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_WIN_VERSION@,$TCL_WIN_VERSION,;t t
-s,@MACHINE@,$MACHINE,;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,@PKG_CFG_ARGS@,$PKG_CFG_ARGS,;t t
-s,@TCL_EXE@,$TCL_EXE,;t t
-s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t
-s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t
-s,@TCL_STATIC_LIB_FILE@,$TCL_STATIC_LIB_FILE,;t t
-s,@TCL_STATIC_LIB_FLAG@,$TCL_STATIC_LIB_FLAG,;t t
-s,@TCL_IMPORT_LIB_FILE@,$TCL_IMPORT_LIB_FILE,;t t
-s,@TCL_IMPORT_LIB_FLAG@,$TCL_IMPORT_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,@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,@MAKE_STUB_LIB@,$MAKE_STUB_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_CC_SEARCH_FLAGS@,$TCL_CC_SEARCH_FLAGS,;t t
-s,@TCL_LD_SEARCH_FLAGS@,$TCL_LD_SEARCH_FLAGS,;t t
-s,@TCL_BUILD_EXP_FILE@,$TCL_BUILD_EXP_FILE,;t t
-s,@TCL_EXP_FILE@,$TCL_EXP_FILE,;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_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,@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
+eval set X " :F $CONFIG_FILES "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
- 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`
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain ':'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # 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. */
+ configure_input='Generated from '`
+ printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+printf "%s\n" "$as_me: creating $ac_file" >&6;}
fi
- done
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
- fi
-fi # test -n "$CONFIG_FILES"
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`printf "%s\n" "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
-_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_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
esac
- # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
- ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+ ac_dir=`$as_dirname -- "$ac_file" ||
$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; }; }; }
-
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
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 "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
case $srcdir in
- .) # No --srcdir option. We are building in place.
+ .) # 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_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
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 ;;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-# 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
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+_ACEOF
- 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; }
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
- sed "$ac_vpsub
+
+# Neutralize VPATH when '$srcdir' = '.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
$extrasub
_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
: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
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;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&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable 'datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable 'datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
-done
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-{ (exit 0); exit 0; }
+ esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
_ACEOF
-chmod +x $CONFIG_STATUS
ac_clean_files=$ac_clean_files_save
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
# configure is writing to config.log, and then calls config.status.
# config.status does its own redirection, appending to config.log.
@@ -6540,7 +7235,12 @@ if test "$no_create" != yes; then
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; }
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
+
diff --git a/win/configure.in b/win/configure.ac
index dd7adbc..b43cb85 100644
--- a/win/configure.in
+++ b/win/configure.ac
@@ -3,19 +3,19 @@
# generate the file "configure", which is run during Tcl installation
# to configure the system for the local environment.
-AC_INIT([tcl],[8.6])
+AC_INIT([tcl],[9.0])
AC_CONFIG_SRCDIR([../generic/tcl.h])
-AC_PREREQ([2.59])
+AC_PREREQ([2.69])
# 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.6
-TCL_MAJOR_VERSION=8
-TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".17"
+TCL_VERSION=9.0
+TCL_MAJOR_VERSION=9
+TCL_MINOR_VERSION=0
+TCL_PATCH_LEVEL=".3"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
TCL_DDE_VERSION=1.4
@@ -60,7 +60,6 @@ fi
AC_PROG_CC
AC_C_INLINE
-AC_HEADER_STDC
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib)
@@ -79,12 +78,6 @@ AC_PROG_MAKE_SET
AC_OBJEXT
AC_EXEEXT
-#--------------------------------------------------------------------
-# Check whether --enable-threads or --disable-threads was given.
-#--------------------------------------------------------------------
-
-SC_ENABLE_THREADS
-
#------------------------------------------------------------------------
# Embedded configuration information, encoding to use for the values, TIP #59
#------------------------------------------------------------------------
@@ -99,20 +92,6 @@ SC_TCL_CFG_ENCODING
SC_ENABLE_SHARED
#--------------------------------------------------------------------
-# Check whether --enable-time64bit was given.
-#--------------------------------------------------------------------
-
-AC_MSG_CHECKING([force of 64-bit time_t])
-AC_ARG_ENABLE(time64bit,
- AS_HELP_STRING([--enable-time64bit],
- [force 64-bit time_t for 32-bit build (default: off)]),
- [tcl_ok=$enableval], [tcl_ok=no])
-AC_MSG_RESULT("$tcl_ok")
-if test "$tcl_ok" = "yes"; then
- CFLAGS="${CFLAGS} -D_USE_64BIT_TIME_T"
-fi
-
-#--------------------------------------------------------------------
# The statements below define a collection of compile flags. This
# macro depends on the value of SHARED_BUILD, and should be called
# after SC_ENABLE_SHARED checks the configure switches.
@@ -131,8 +110,9 @@ case ${host_alias} in
esac
#------------------------------------------------------------------------
-# Add stuff for zlib; note that this is mostly done in the makefile now
-# as we just assume that the platform hasn't got a usable z.lib
+# Add stuff for zlib/libtommath; note that this is mostly done in the
+# makefile now as we just assume that the platform hasn't got usable
+# z.lib/tommath.lib
#------------------------------------------------------------------------
AS_IF([test "${enable_shared+set}" = "set"], [
@@ -142,64 +122,92 @@ AS_IF([test "${enable_shared+set}" = "set"], [
tcl_ok=yes
])
zlib_lib_name=zdll.lib
+tommath_lib_name=tommath.lib
AS_IF([test "$tcl_ok" = "yes"], [
AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}])
+ AC_SUBST(TOMMATH_DLL_FILE,[\${TOMMATH_DLL_FILE}])
+ AC_DEFINE(TCL_WITH_EXTERNAL_TOMMATH, 1, [Tcl with external libtommath])
AS_IF([test "$do64bit" != "no"], [
+ AC_DEFINE(MP_64BIT, 1, [Using libtommath.dll in 64-bit mode])
AS_IF([test "$do64bit" = "arm64" -o "$do64bit" = "aarch64"], [
AS_IF([test "$GCC" = "yes"],[
AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64-arm/libz.dll.a])
+ AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.a])
zlib_lib_name=libz.dll.a
+ tommath_lib_name=libtommath.dll.a
], [
AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64-arm/zdll.lib])
+ AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64-arm/tommath.lib])
])
], [
AS_IF([test "$GCC" = "yes"],[
AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/libz.dll.a])
+ AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64/libtommath.dll.a])
zlib_lib_name=libz.dll.a
+ tommath_lib_name=libtommath.dll.a
], [
AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/zdll.lib])
+ AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win64/tommath.lib])
])
])
], [
AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win32/zdll.lib])
+ AC_SUBST(TOMMATH_LIBS,[\${TOMMATH_DIR_NATIVE}/win32/tommath.lib])
])
], [
+ AC_DEFINE(TCL_WITH_INTERNAL_ZLIB, 1, [Tcl with internal zlib])
AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])
+ AC_SUBST(TOMMATH_OBJS,[\${TOMMATH_OBJS}])
])
-AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?])
AC_SUBST(TCL_ZLIB_LIB_NAME, $zlib_lib_name)
+AC_SUBST(TCL_TOMMATH_LIB_NAME, $tommath_lib_name)
+AC_CHECK_TYPES([intptr_t, uintptr_t],,,[[
+#include <stdint.h>
+]])
-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.])
+#--------------------------------------------------------------------
+# Zipfs support - Tip 430
+#--------------------------------------------------------------------
+AC_ARG_ENABLE(zipfs,
+ AS_HELP_STRING([--enable-zipfs],
+ [build with Zipfs support (default: on)]),
+ [tcl_ok=$enableval], [tcl_ok=yes])
+if test "$tcl_ok" = "yes" ; then
+ #
+ # Find a native compiler
+ #
+ AX_CC_FOR_BUILD
+ #
+ # Find a native zip implementation
+ #
+ SC_PROG_TCLSH
+ SC_ZIPFS_SUPPORT
+ ZIPFS_BUILD=1
+ TCL_ZIP_FILE=libtcl${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_PATCH_LEVEL}.zip
+else
+ ZIPFS_BUILD=0
+ TCL_ZIP_FILE=
+fi
+# Do checking message here to not mess up interleaved configure output
+AC_MSG_CHECKING([for building with zipfs])
+if test "${ZIPFS_BUILD}" = 1; then
+ if test "${SHARED_BUILD}" = 0; then
+ ZIPFS_BUILD=2;
+ AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?])
+ else
+ AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\
fi
-])
+ AC_MSG_RESULT([yes])
+else
+AC_MSG_RESULT([no])
+INSTALL_LIBRARIES=install-libraries
+INSTALL_MSGS=install-msgs
+fi
+AC_SUBST(ZIPFS_BUILD)
+AC_SUBST(TCL_ZIP_FILE)
+AC_SUBST(INSTALL_LIBRARIES)
+AC_SUBST(INSTALL_MSGS)
+
#--------------------------------------------------------------------
# Perform additinal compiler tests.
@@ -309,8 +317,6 @@ fi
SC_ENABLE_SYMBOLS
-TCL_DBGX=${DBGX}
-
#--------------------------------------------------------------------
# Embed the manifest if we can determine how
#--------------------------------------------------------------------
@@ -331,8 +337,8 @@ eval "TCL_SRC_DIR=\"`cd $srcdir/..; $CYGPATH $(pwd)`\""
eval "TCL_DLL_FILE=tcl${VER}${DLLSUFFIX}"
-eval "TCL_STUB_LIB_FILE=\"${LIBPREFIX}tclstub${VER}${LIBSUFFIX}\""
-eval "TCL_STUB_LIB_FLAG=\"-ltclstub${VER}${LIBFLAGSUFFIX}\""
+eval "TCL_STUB_LIB_FILE=\"${LIBPREFIX}tclstub${LIBSUFFIX}\""
+eval "TCL_STUB_LIB_FLAG=\"-ltclstub${LIBFLAGSUFFIX}\""
eval "TCL_BUILD_STUB_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TCL_STUB_LIB_FLAG}\""
eval "TCL_STUB_LIB_SPEC=\"-L${libdir} ${TCL_STUB_LIB_FLAG}\""
eval "TCL_BUILD_STUB_LIB_PATH=\"`$CYGPATH $(pwd)`/${TCL_STUB_LIB_FILE}\""
@@ -351,11 +357,6 @@ eval "TCL_LIB_SPEC=\"-L${libdir} ${TCL_LIB_FLAG}\""
# Install time header dir can be set via --includedir
eval "TCL_INCLUDE_SPEC=\"-I${includedir}\""
-eval "DLLSUFFIX=${DLLSUFFIX}"
-eval "LIBPREFIX=${LIBPREFIX}"
-eval "LIBSUFFIX=${LIBSUFFIX}"
-eval "EXESUFFIX=${EXESUFFIX}"
-
TCL_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TCL_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
@@ -368,17 +369,9 @@ CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}
#--------------------------------------------------------------------
if test ${SHARED_BUILD} = 0 ; then
- if test "${DBGX}" = "g"; then
- RC_DEFINES="${RC_DEFINE} STATIC_BUILD ${RC_DEFINE} DEBUG"
- else
- RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
- fi
+ RC_DEFINES="${RC_DEFINE} STATIC_BUILD"
else
- if test "${DBGX}" = "g"; then
- RC_DEFINES="${RC_DEFINE} DEBUG"
- else
- RC_DEFINES=""
- fi
+ RC_DEFINES=""
fi
#--------------------------------------------------------------------
@@ -433,7 +426,6 @@ AC_SUBST(TCL_DLL_FILE)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)
-AC_SUBST(TCL_DBGX)
AC_SUBST(CFG_TCL_SHARED_LIB_SUFFIX)
AC_SUBST(CFG_TCL_UNSHARED_LIB_SUFFIX)
@@ -474,13 +466,7 @@ AC_SUBST(POST_MAKE_LIB)
AC_SUBST(MAKE_DLL)
AC_SUBST(MAKE_EXE)
-# empty on win, but needs sub'ing
AC_SUBST(TCL_BUILD_LIB_SPEC)
-AC_SUBST(TCL_CC_SEARCH_FLAGS)
-AC_SUBST(TCL_LD_SEARCH_FLAGS)
-AC_SUBST(TCL_BUILD_EXP_FILE)
-AC_SUBST(TCL_EXP_FILE)
-AC_SUBST(DL_LIBS)
AC_SUBST(TCL_PACKAGE_PATH)
# win only
@@ -499,7 +485,7 @@ AC_SUBST(RC_DEFINE)
AC_SUBST(RC_DEFINES)
AC_SUBST(RES)
-AC_CONFIG_FILES([Makefile tclConfig.sh tcl.hpj tclsh.exe.manifest])
+AC_CONFIG_FILES([Makefile tclConfig.sh tclsh.exe.manifest])
AC_OUTPUT
dnl Local Variables:
diff --git a/win/makefile.vc b/win/makefile.vc
index c88c0ec..175c4b2 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -52,28 +52,29 @@
# 64-bit compiler, if your SDK has it.
#
# Basic macros and options usable on the commandline (see rules.vc for more info):
-# OPTS=msvcrt,nothreads,pdbs,profile,static,staticpkg,symbols,thrdalloc,time64bit,unchecked,none
+# OPTS=nomsvcrt,noembed,nothreads,pdbs,profile,static,symbols,thrdalloc,unchecked,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.
#
-# msvcrt = Affects 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
+# noembed = Without this option, the Tcl core library scripts
+# are embedded into the executable if "static" is
+# specified in OPTS, or into the DLL otherwise. If
+# "noembed" is specified, the scripts are not embedded
+# but copied to the installation target (as in 8.6).
+# nomsvcrt = Affects the static option only to switch it from
+# using msvcrt(d) as the C runtime [by default] to
+# libcmt(d). This is useful for static embedding
# support.
# none = Overrides all other options to nothing.
# nothreads = Turns off full multithreading support (default on).
# pdbs = Produce separate debug symbol files.
# profile = Adds profiling hooks. Map file is assumed.
# static = Builds a static library of the core instead of a
-# dll. The shell will be static (and large), as well.
-# staticpkg = Affects the static option only to switch
-# tclshXX.exe to have the dde and reg extension linked
-# inside it.
+# dll. The shell will be static (and large), and
+# have the dde and registry extensions linked inside.
# symbols = Adds symbols for step debugging.
# thrdalloc = Use the thread allocator (shared global free pool).
-# time64bit = Forces a build using 64-bit time_t for 32-bit build
-# (CRT library should support this).
# unchecked = Allows a symbols build to not use the debug
# enabled runtime (msvcrt.dll not msvcrtd.dll
# or libcmt.lib not libcmtd.lib).
@@ -140,10 +141,40 @@ RCFILE = tcl.rc
# the build configuration, macros, output directories etc.
!include "rules.vc"
+#
+# The tclsh executable without the embedded libzip. We need this
+# separately from tclsh to have dependency and build order work right.
+# Ditto for the DLL and tcltest
+TCLSHRAW=$(TCLSH:.exe=-raw.exe)
+TCLLIBRAW=$(TCLLIB:.dll=-raw.dll)
+
# Tcl version info based on macros set up by rules.vc
DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+# The staticpkg option is not longer supported in Tcl 8.7
+# though extensions may still be using it. If specified together
+# with "static", ignore it as that is now the default for
+# static build. For non-static builds, no longer supported
+# now (was permitted in 8.6)
+!if $(TCL_USE_STATIC_PACKAGES)
+!if $(STATIC_BUILD)
+!message *** NOTE: The "staticpkg" option redundant in 8.7.
+!else
+!message *** NOTE: The "staticpkg" option ignored for shared library builds.
+!endif
+!endif
+
+!if [nmakehlp -f $(OPTS) "noembed"]
+!message *** Option noembed specified. Tcl script library will not be appended to the binary.
+TCL_EMBED_SCRIPTS = 0
+TCL_TEST_LIBRARY=$(ROOT:\=/)/library
+!else
+!message *** Tcl script library will be appended to the binary.
+TCL_EMBED_SCRIPTS = 1
+TCL_TEST_LIBRARY=
+!endif
+
# We need versions of various core packages to generate appropriate
# file names during installation.
!if [echo REM = This file is generated from makefile.vc > versions.vc]
@@ -154,6 +185,9 @@ VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
!if [echo PKG_OPT_VER = \>> versions.vc] \
&& [nmakehlp -V ..\library\opt\pkgIndex.tcl opt >> versions.vc]
!endif
+!if [echo PKG_COOKIEJAR_VER = \>> versions.vc] \
+ && [nmakehlp -V ..\library\cookiejar\pkgIndex.tcl cookiejar >> versions.vc]
+!endif
!if [echo PKG_TCLTEST_VER = \>> versions.vc] \
&& [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc]
!endif
@@ -170,7 +204,7 @@ VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
&& [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]
+ && [nmakehlp -V ..\library\registry\pkgIndex.tcl "registry " >> versions.vc]
!endif
!include versions.vc
@@ -181,23 +215,17 @@ DDEVERSION = $(DDEDOTVERSION:.=)
REGDOTVERSION = 1.3
REGVERSION = $(REGDOTVERSION:.=)
-TCLREGLIBNAME = $(PROJECT)reg$(REGVERSION)$(SUFX:t=).$(EXT)
+TCLREGLIBNAME = $(PROJECT)9registry$(REGVERSION)$(SUFX:t=).$(EXT)
TCLREGLIB = $(OUT_DIR)\$(TCLREGLIBNAME)
-TCLDDELIBNAME = $(PROJECT)dde$(DDEVERSION)$(SUFX:t=).$(EXT)
+TCLDDELIBNAME = $(PROJECT)9dde$(DDEVERSION)$(SUFX:t=).$(EXT)
TCLDDELIB = $(OUT_DIR)\$(TCLDDELIBNAME)
TCLTEST = $(OUT_DIR)\$(PROJECT)test$(VERSION)$(SUFX:t=).exe
-CAT32 = $(OUT_DIR)\cat32.exe
+TCLTESTRAW = $(TCLTEST:.exe=-raw.exe)
TCLSHOBJS = \
$(TMP_DIR)\tclAppInit.obj \
-!if !$(STATIC_BUILD)
-!if $(TCL_USE_STATIC_PACKAGES)
- $(TMP_DIR)\tclWinReg.obj \
- $(TMP_DIR)\tclWinDde.obj \
-!endif
-!endif
$(TMP_DIR)\tclsh.res
TCLTESTOBJS = \
@@ -206,11 +234,9 @@ TCLTESTOBJS = \
$(TMP_DIR)\tclTestProcBodyObj.obj \
$(TMP_DIR)\tclThreadTest.obj \
$(TMP_DIR)\tclWinTest.obj \
+ $(TMP_DIR)\tclTestABSList.obj \
!if !$(STATIC_BUILD)
-!if $(TCL_USE_STATIC_PACKAGES)
- $(TMP_DIR)\tclWinReg.obj \
- $(TMP_DIR)\tclWinDde.obj \
-!endif
+ $(OUT_DIR)\tommath.lib \
!endif
$(TMP_DIR)\testMain.obj \
$(TMP_DIR)\tcltest.res
@@ -220,6 +246,7 @@ COREOBJS = \
$(TMP_DIR)\regerror.obj \
$(TMP_DIR)\regexec.obj \
$(TMP_DIR)\regfree.obj \
+ $(TMP_DIR)\tclArithSeries.obj \
$(TMP_DIR)\tclAlloc.obj \
$(TMP_DIR)\tclAssembly.obj \
$(TMP_DIR)\tclAsync.obj \
@@ -227,6 +254,7 @@ COREOBJS = \
$(TMP_DIR)\tclBinary.obj \
$(TMP_DIR)\tclCkalloc.obj \
$(TMP_DIR)\tclClock.obj \
+ $(TMP_DIR)\tclClockFmt.obj \
$(TMP_DIR)\tclCmdAH.obj \
$(TMP_DIR)\tclCmdIL.obj \
$(TMP_DIR)\tclCmdMZ.obj \
@@ -249,6 +277,7 @@ COREOBJS = \
$(TMP_DIR)\tclGet.obj \
$(TMP_DIR)\tclHash.obj \
$(TMP_DIR)\tclHistory.obj \
+ $(TMP_DIR)\tclIcu.obj \
$(TMP_DIR)\tclIndexObj.obj \
$(TMP_DIR)\tclInterp.obj \
$(TMP_DIR)\tclIO.obj \
@@ -272,6 +301,7 @@ COREOBJS = \
$(TMP_DIR)\tclOODefineCmds.obj \
$(TMP_DIR)\tclOOInfo.obj \
$(TMP_DIR)\tclOOMethod.obj \
+ $(TMP_DIR)\tclOOProp.obj \
$(TMP_DIR)\tclOOStubInit.obj \
$(TMP_DIR)\tclObj.obj \
$(TMP_DIR)\tclOptimize.obj \
@@ -284,11 +314,13 @@ COREOBJS = \
$(TMP_DIR)\tclPosixStr.obj \
$(TMP_DIR)\tclPreserve.obj \
$(TMP_DIR)\tclProc.obj \
+ $(TMP_DIR)\tclProcess.obj \
$(TMP_DIR)\tclRegexp.obj \
$(TMP_DIR)\tclResolve.obj \
$(TMP_DIR)\tclResult.obj \
$(TMP_DIR)\tclScan.obj \
$(TMP_DIR)\tclStringObj.obj \
+ $(TMP_DIR)\tclStrIdxTree.obj \
$(TMP_DIR)\tclStrToD.obj \
$(TMP_DIR)\tclStubInit.obj \
$(TMP_DIR)\tclThread.obj \
@@ -301,6 +333,7 @@ COREOBJS = \
$(TMP_DIR)\tclUtf.obj \
$(TMP_DIR)\tclUtil.obj \
$(TMP_DIR)\tclVar.obj \
+ $(TMP_DIR)\tclZipfs.obj \
$(TMP_DIR)\tclZlib.obj
!if $(STATIC_BUILD)
@@ -320,6 +353,7 @@ ZLIBOBJS = \
ZLIBOBJS = $(OUT_DIR)\zdll.lib
!endif
+!if $(STATIC_BUILD)
TOMMATHOBJS = \
$(TMP_DIR)\bn_mp_add.obj \
$(TMP_DIR)\bn_mp_add_d.obj \
@@ -340,12 +374,15 @@ TOMMATHOBJS = \
$(TMP_DIR)\bn_s_mp_div_3.obj \
$(TMP_DIR)\bn_mp_exch.obj \
$(TMP_DIR)\bn_mp_expt_n.obj \
+ $(TMP_DIR)\bn_mp_get_mag_u64.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_i64.obj \
$(TMP_DIR)\bn_mp_init_multi.obj \
$(TMP_DIR)\bn_mp_init_set.obj \
$(TMP_DIR)\bn_mp_init_size.obj \
+ $(TMP_DIR)\bn_mp_init_u64.obj \
$(TMP_DIR)\bn_mp_lshd.obj \
$(TMP_DIR)\bn_mp_mod.obj \
$(TMP_DIR)\bn_mp_mod_2d.obj \
@@ -361,7 +398,8 @@ TOMMATHOBJS = \
$(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_i64.obj \
+ $(TMP_DIR)\bn_mp_set_u64.obj \
$(TMP_DIR)\bn_mp_shrink.obj \
$(TMP_DIR)\bn_mp_sqr.obj \
$(TMP_DIR)\bn_mp_sqrt.obj \
@@ -386,6 +424,9 @@ TOMMATHOBJS = \
$(TMP_DIR)\bn_s_mp_sub.obj \
$(TMP_DIR)\bn_s_mp_toom_sqr.obj \
$(TMP_DIR)\bn_s_mp_toom_mul.obj
+!else
+TOMMATHOBJS = $(OUT_DIR)\tommath.lib
+!endif
PLATFORMOBJS = \
$(TMP_DIR)\tclWin32Dll.obj \
@@ -403,6 +444,7 @@ PLATFORMOBJS = \
$(TMP_DIR)\tclWinThrd.obj \
$(TMP_DIR)\tclWinTime.obj \
!if $(STATIC_BUILD)
+ $(TMP_DIR)\tclWinPanic.obj \
$(TMP_DIR)\tclWinReg.obj \
$(TMP_DIR)\tclWinDde.obj \
!else
@@ -413,18 +455,28 @@ TCLOBJS = $(COREOBJS) $(ZLIBOBJS) $(TOMMATHOBJS) $(PLATFORMOBJS)
TCLSTUBOBJS = \
$(TMP_DIR)\tclStubLib.obj \
+ $(TMP_DIR)\tclStubCall.obj \
+ $(TMP_DIR)\tclStubLibTbl.obj \
$(TMP_DIR)\tclTomMathStubLib.obj \
- $(TMP_DIR)\tclOOStubLib.obj
+ $(TMP_DIR)\tclOOStubLib.obj \
+ $(TMP_DIR)\tclWinPanic.obj
### The following paths CANNOT have spaces in them as they appear on
### the left side of implicit rules.
TOMMATHDIR = $(ROOT)\libtommath
PKGSDIR = $(ROOT)\pkgs
+LIBTCLVFSSUBDIR = libtcl.vfs
+LIBTCLVFS = $(OUT_DIR)\$(LIBTCLVFSSUBDIR)
+
# Additional include and C macro definitions for the implicit rules
# defined in rules.vc
PRJ_INCLUDES = -I"$(TOMMATHDIR)"
-PRJ_DEFINES = /DMP_PREC=4 /Dinline=__inline /DHAVE_ZLIB=1 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DMP_FIXED_CUTOFFS
+PRJ_DEFINES = /DMP_PREC=4 /Dinline=__inline /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DMP_FIXED_CUTOFFS
+
+!if $(STATIC_BUILD)
+PRJ_DEFINES = $(PRJ_DEFINES) /DTCL_WITH_INTERNAL_ZLIB
+!endif
# Additional Link libraries needed beyond those in rules.vc
PRJ_LIBS = netapi32.lib user32.lib userenv.lib ws2_32.lib
@@ -448,8 +500,9 @@ TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
# of the noembed setting. A copy is made as $(TCLLIBRAW)
# as the $(TCLLIB) binary is potentially modified later.
# dlls - these are the registry and dde DLL's or static libraries
-# $(TCLSH) - the Tcl shell. This needs $(TCLLIB) to be built first as
-# it links against it.
+# $(TCLSH) - the Tcl shell WITHOUT any embedded zip. This needs $(TCLLIB)
+# to be built first as it links against it. A copy is made
+# as $(TCLSHRAW) as $(TCLSH) binary may be modified later.
# $(TCLSCRIPTZIP) - the zip file that is to be embedded. Note this also
# ships separately and needs to be built irrespective of the
# whether it is embedded or not. All above targets need to
@@ -466,12 +519,30 @@ TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
# release - Everything that builds as part of a release
#---------------------------------------------------------------------
-release: setup $(TCLSH) $(TCLSTUBLIB) dlls pkgs
-all: setup $(TCLSH) $(TCLSTUBLIB) dlls $(CAT32) pkgs
-core: setup $(TCLLIB) $(TCLSTUBLIB)
-shell: setup $(TCLSH)
-dlls: setup $(TCLREGLIB) $(TCLDDELIB) $(OUT_DIR)\zlib1.dll
-tcltest: setup $(TCLTEST) dlls $(CAT32)
+release: setup libtclzip core dlls shell pkgs
+all: setup libtclzip core dlls shell pkgs
+
+core: setup $(TCLLIB)
+!if $(TCL_EMBED_SCRIPTS) && !$(STATIC_BUILD)
+core: libtclzip
+ @$(COPY) /b "$(TCLLIBRAW)"+"$(TCLSCRIPTZIP)" "$(TCLLIB)"
+!endif
+
+shell: setup core $(TCLSH)
+!if $(TCL_EMBED_SCRIPTS) && $(STATIC_BUILD)
+shell: libtclzip
+ @$(COPY) /b "$(TCLSHRAW)"+"$(TCLSCRIPTZIP)" "$(TCLSH)"
+!endif
+
+dlls: setup $(TCLREGLIB) $(TCLDDELIB) $(OUT_DIR)\zlib1.dll $(OUT_DIR)\libtommath.dll
+libtclzip: $(TCLSCRIPTZIP)
+
+tcltest: setup core $(TCLTEST) dlls
+!if $(TCL_EMBED_SCRIPTS) && $(STATIC_BUILD)
+tcltest: libtclzip
+ @$(COPY) /b "$(TCLTESTRAW)"+"$(TCLSCRIPTZIP)" "$(TCLTEST)"
+!endif
+
install: install-binaries install-libraries install-docs install-pkgs
!if $(SYMBOLS)
install: install-pdbs
@@ -479,19 +550,19 @@ install: install-pdbs
setup: default-setup
test: test-core test-pkgs
-test-core: setup $(TCLTEST) dlls $(CAT32)
- set TCL_LIBRARY=$(ROOT:\=/)/library
+test-core: tcltest
+ set TCL_LIBRARY=$(TCL_TEST_LIBRARY)
$(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile <<
- package ifneeded dde 1.4.4 [list load "$(TCLDDELIB:\=/)" Dde]
- package ifneeded registry 1.3.5 [list load "$(TCLREGLIB:\=/)" Registry]
+ package ifneeded dde 1.4.5 [list load "$(TCLDDELIB:\=/)"]
+ package ifneeded registry 1.3.7 [list load "$(TCLREGLIB:\=/)"]
<<
-runtest: setup $(TCLTEST) dlls $(CAT32)
- set TCL_LIBRARY=$(ROOT:\=/)/library
+runtest: setup $(TCLTEST) dlls
+ set TCL_LIBRARY=$(TCL_TEST_LIBRARY)
$(DEBUGGER) $(TCLTEST) $(SCRIPT)
-runshell: setup $(TCLSH) dlls
- set TCL_LIBRARY=$(ROOT:\=/)/library
+runshell: setup core shell dlls
+ set TCL_LIBRARY=$(TCL_TEST_LIBRARY)
$(DEBUGGER) $(TCLSH) $(SCRIPT)
!if $(STATIC_BUILD)
@@ -508,6 +579,9 @@ $(TCLLIB): $(TCLOBJS)
$**
<<
$(_VC_MANIFEST_EMBED_DLL)
+!if $(TCL_EMBED_SCRIPTS) && !$(STATIC_BUILD)
+ $(COPY) $@ $(TCLLIBRAW)
+!endif
$(TCLIMPLIB): $(TCLLIB)
@@ -520,11 +594,18 @@ $(TCLSH): $(TCLSHOBJS) $(TCLSTUBLIB) $(TCLIMPLIB)
$(CONEXECMD) -stack:2300000 $**
copy $(TMP_DIR)\tclsh.exe.manifest $(TCLSH).manifest
$(_VC_MANIFEST_EMBED_EXE)
+!if $(TCL_EMBED_SCRIPTS) && $(STATIC_BUILD)
+ $(COPY) $@ $(TCLSHRAW)
+!endif
+
$(TCLTEST): $(TCLTESTOBJS) $(TCLSTUBLIB) $(TCLIMPLIB)
$(CONEXECMD) -stack:2300000 $**
copy $(TMP_DIR)\tclsh.exe.manifest $(TCLTEST).manifest
$(_VC_MANIFEST_EMBED_EXE)
+!if $(TCL_EMBED_SCRIPTS) && $(STATIC_BUILD)
+ $(COPY) $@ $(TCLTESTRAW)
+!endif
!if $(STATIC_BUILD)
$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj
@@ -549,18 +630,47 @@ $(OUT_DIR)\zlib1.dll: $(COMPATDIR)\zlib\win64-arm\zlib1.dll
$(COPY) $(COMPATDIR)\zlib\win64-arm\zlib1.dll $(OUT_DIR)\zlib1.dll
$(OUT_DIR)\zdll.lib: $(COMPATDIR)\zlib\win64-arm\zdll.lib
$(COPY) $(COMPATDIR)\zlib\win64-arm\zdll.lib $(OUT_DIR)\zdll.lib
+$(OUT_DIR)\libtommath.dll: $(TOMMATHDIR)\win64-arm\libtommath.dll
+ $(COPY) $(TOMMATHDIR)\win64-arm\libtommath.dll $(OUT_DIR)\libtommath.dll
+$(OUT_DIR)\tommath.lib: $(TOMMATHDIR)\win64-arm\tommath.lib
+ $(COPY) $(TOMMATHDIR)\win64-arm\tommath.lib $(OUT_DIR)\tommath.lib
!elseif "$(MACHINE)" == "IX86"
$(OUT_DIR)\zlib1.dll: $(COMPATDIR)\zlib\win32\zlib1.dll
$(COPY) $(COMPATDIR)\zlib\win32\zlib1.dll $(OUT_DIR)\zlib1.dll
$(OUT_DIR)\zdll.lib: $(COMPATDIR)\zlib\win32\zdll.lib
$(COPY) $(COMPATDIR)\zlib\win32\zdll.lib $(OUT_DIR)\zdll.lib
+$(OUT_DIR)\libtommath.dll: $(TOMMATHDIR)\win32\libtommath.dll
+ $(COPY) $(TOMMATHDIR)\win32\libtommath.dll $(OUT_DIR)\libtommath.dll
+$(OUT_DIR)\tommath.lib: $(TOMMATHDIR)\win32\tommath.lib
+ $(COPY) $(TOMMATHDIR)\win32\tommath.lib $(OUT_DIR)\tommath.lib
!else
$(OUT_DIR)\zlib1.dll: $(COMPATDIR)\zlib\win64\zlib1.dll
$(COPY) $(COMPATDIR)\zlib\win64\zlib1.dll $(OUT_DIR)\zlib1.dll
$(OUT_DIR)\zdll.lib: $(COMPATDIR)\zlib\win64\zdll.lib
$(COPY) $(COMPATDIR)\zlib\win64\zdll.lib $(OUT_DIR)\zdll.lib
+$(OUT_DIR)\libtommath.dll: $(TOMMATHDIR)\win64\libtommath.dll
+ $(COPY) $(TOMMATHDIR)\win64\libtommath.dll $(OUT_DIR)\libtommath.dll
+$(OUT_DIR)\tommath.lib: $(TOMMATHDIR)\win64\tommath.lib
+ $(COPY) $(TOMMATHDIR)\win64\tommath.lib $(OUT_DIR)\tommath.lib
!endif
+$(TCLSCRIPTZIP): $(TCLLIB) $(TCLSH) dlls
+ @echo Building Tcl library zip file $(TCLSCRIPTZIP)
+ @set TCL_LIBRARY=$(ROOT:\=/)/library
+ @if exist "$(LIBTCLVFS)" $(RMDIR) "$(LIBTCLVFS)"
+ @$(MKDIR) "$(LIBTCLVFS)"
+ @$(CPYDIR) $(LIBDIR) "$(LIBTCLVFS)\tcl_library"
+ @move /y "$(LIBTCLVFS)\tcl_library\manifest.txt" "$(LIBTCLVFS)\tcl_library\pkgIndex.tcl" > NUL
+# Remove the registry and dde directories as the DLLS are still external
+ @del "$(LIBTCLVFS)\tcl_library\registry\pkgIndex.tcl"
+ @rmdir "$(LIBTCLVFS)\tcl_library\registry"
+ @del "$(LIBTCLVFS)\tcl_library\dde\pkgIndex.tcl"
+ @rmdir "$(LIBTCLVFS)\tcl_library\dde"
+ @echo cd {$(OUT_DIR)} > "$(OUT_DIR)\zipper.tcl"
+ @echo file delete -force {$(@F)} >> "$(OUT_DIR)\zipper.tcl"
+ @echo zipfs mkzip {$(@F)} {$(LIBTCLVFSSUBDIR)} {$(LIBTCLVFSSUBDIR)} >> "$(OUT_DIR)\zipper.tcl"
+ @$(TCLSH_NATIVE) "$(OUT_DIR)/zipper.tcl"
+
pkgs:
@for /d %d in ($(PKGSDIR)\*) do \
@if exist "%~fd\win\makefile.vc" ( \
@@ -601,12 +711,6 @@ hose-pkgs:
popd \
)
-$(CAT32): $(WIN_DIR)\cat.c
- $(cc32) $(cflags) $(crt) /D_CRT_NONSTDC_NO_DEPRECATE /DCONSOLE \
- /DUNICODE /D_UNICODE -Fo$(TMP_DIR)\ $?
- $(CONEXECMD) -stack:16384 $(TMP_DIR)\cat.obj
- $(_VC_MANIFEST_EMBED_EXE)
-
#---------------------------------------------------------------------
# Regenerate the stubs files. [Development use only]
#---------------------------------------------------------------------
@@ -615,35 +719,18 @@ genstubs:
!if !exist($(TCLSH))
@echo Build tclsh first!
!else
- $(TCLSH) -encoding utf-8 $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \
+ $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \
$(GENERICDIR:\=/)/tcl.decls $(GENERICDIR:\=/)/tclInt.decls \
$(GENERICDIR:\=/)/tclTomMath.decls
- $(TCLSH) -encoding utf-8 $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \
+ $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \
$(GENERICDIR:\=/)/tclOO.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.
-#----------------------------------------------------------------------
-
-gentommath_h:
-!if !exist($(TCLSH))
- @echo Build tclsh first!
-!else
- $(TCLSH) "$(TOOLSDIR:\=/)/fix_tommath_h.tcl" \
- "$(TOMMATHDIR:\=/)/tommath.h" \
- > "$(GENERICDIR)\tclTomMath.h"
-!endif
-
#---------------------------------------------------------------------
# Build the Windows HTML help file.
#---------------------------------------------------------------------
-# NOTE: you can define HHC on the command-line to override this.
-# nmake does not set macro values if already set on the command line.
!if defined(PROCESSOR_ARCHITECTURE) && "$(PROCESSOR_ARCHITECTURE)" == "AMD64"
HHC="%ProgramFiles(x86)%\HTML Help Workshop\hhc.exe"
!else
@@ -654,30 +741,32 @@ HTMLBASE=TclTk$(VERSION)
HHPFILE=$(HTMLDIR)\$(HTMLBASE).hhp
CHMFILE=$(HTMLDIR)\$(HTMLBASE).chm
-htmlhelp: chmsetup $(CHMFILE)
+htmlhelp: $(CHMFILE)
-$(CHMFILE): $(DOCDIR)\*
+htmldocs: $(DOCDIR)\*
@$(TCLSH) $(TOOLSDIR)\tcltk-man2html.tcl "--htmldir=$(HTMLDIR)"
+
+$(CHMFILE): htmldocs chmsetup
@echo Compiling HTML help project
-"$(HHC)" <<$(HHPFILE) >NUL
[OPTIONS]
Compatibility=1.1 or later
Compiled file=$(HTMLBASE).chm
-Default topic=contents.htm
+Default topic=index.html
Display compile progress=no
Error log file=$(HTMLBASE).log
Full-text search=Yes
Language=0x409 English (United States)
Title=Tcl/Tk $(DOTVERSION) Help
[FILES]
-contents.htm
+index.html
docs.css
-Keywords\*.htm
-TclCmd\*.htm
-TclLib\*.htm
-TkCmd\*.htm
-TkLib\*.htm
-UserCmd\*.htm
+Keywords\*.html
+TclCmd\*.html
+TclLib\*.html
+TkCmd\*.html
+TkLib\*.html
+UserCmd\*.html
<<
chmsetup:
@@ -700,7 +789,6 @@ $(OUT_DIR)\tcl.nmake:
@type << >$@
CORE_MACHINE = $(MACHINE)
CORE_DEBUG = $(DEBUG)
-CORE_TCL_THREADS = $(TCL_THREADS)
CORE_USE_THREAD_ALLOC = $(USE_THREAD_ALLOC)
<<
@@ -725,7 +813,6 @@ $(OUT_DIR)\tclConfig.sh: $(WIN_DIR)\tclConfig.sh.in
@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
@LIBS@ $(baselibs) $(PRJ_LIBS)
@prefix@ $(_INSTALLDIR)
@@ -738,10 +825,7 @@ $(OUT_DIR)\tclConfig.sh: $(WIN_DIR)\tclConfig.sh.in
@STLIB_LD@ $(lib32) -nologo
@SHLIB_LD_LIBS@ $(baselibs) $(PRJ_LIBS)
@SHLIB_SUFFIX@ .dll
-@DL_LIBS@
@LDFLAGS@
-@TCL_CC_SEARCH_FLAGS@
-@TCL_LD_SEARCH_FLAGS@
@LIBOBJS@
@RANLIB@
@TCL_LIB_FLAG@ $(PROJECT)$(VERSION)$(SUFX).lib
@@ -753,7 +837,6 @@ $(OUT_DIR)\tclConfig.sh: $(WIN_DIR)\tclConfig.sh.in
@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)
@@ -765,6 +848,7 @@ $(OUT_DIR)\tclConfig.sh: $(WIN_DIR)\tclConfig.sh.in
@TCL_SHARED_BUILD@ 1
!endif
@TCL_ZLIB_LIB_NAME@ zdll.lib
+@TCL_TOMMATH_LIB_NAME@ tommath.lib
<<
@@ -787,7 +871,6 @@ gendate:
$(TMP_DIR)\testMain.obj: $(WIN_DIR)\tclAppInit.c
$(cc32) $(appcflags) /DTCL_TEST /DUNICODE /D_UNICODE \
- /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
-Fo$@ $?
$(TMP_DIR)\tclMainW.obj: $(GENERICDIR)\tclMain.c
@@ -802,21 +885,43 @@ $(TMP_DIR)\tclUuid.h: $(ROOT)\manifest.uuid
copy $(WIN_DIR)\tclUuid.h.in+$(ROOT)\manifest.uuid $(TMP_DIR)\tclUuid.h
$(TMP_DIR)\tclEvent.obj: $(GENERICDIR)\tclEvent.c $(TMP_DIR)\tclUuid.h
- $(cc32) $(pkgcflags) -I$(TMP_DIR) \
+ $(cc32) $(pkgcflags) -I$(COMPATDIR)\zlib -I$(TMP_DIR) \
-Fo$@ $(GENERICDIR)\tclEvent.c
-$(TMP_DIR)\tclTest.obj: $(GENERICDIR)\tclTest.c
- $(cc32) $(appcflags) -Fo$@ $?
+$(TMP_DIR)\tclTest.obj: $(GENERICDIR)\tclTest.c $(TMP_DIR)\tclUuid.h
+ $(cc32) $(appcflags) -I$(TMP_DIR) \
+ -Fo$@ $(GENERICDIR)\tclTest.c
$(TMP_DIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c
$(cc32) $(appcflags) -Fo$@ $?
+$(TMP_DIR)\tclTestABSList.obj: $(GENERICDIR)\tclTestABSList.c
+ $(cc32) $(appcflags) -Fo$@ $?
+
$(TMP_DIR)\tclWinTest.obj: $(WIN_DIR)\tclWinTest.c
$(CCAPPCMD) $?
+$(TMP_DIR)\tclZipfs.obj: $(GENERICDIR)\tclZipfs.c
+ $(cc32) $(pkgcflags) \
+ -I$(COMPATDIR)\zlib -I$(COMPATDIR)\zlib\contrib\minizip \
+ -Fo$@ $?
+
$(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c
$(cc32) $(pkgcflags) -I$(COMPATDIR)\zlib -Fo$@ $?
+# Following the lead of the autoconf based make, we define the
+# CFG_RUNTIME_*DIR flags specifically for tclPkgConfig
+# and not as part of the global defines. These are all defined
+# as empty strings because they are intended to represent paths
+# at *runtime*, not build time. This may make sense on Unix systems
+# where end-user does configure and make on the target system. It
+# makes no sense on Windows where binary distributions may be installed
+# anywhere. Storing build time paths as runtime paths is misleading
+# at best and inefficient at worst as the code goes looking for
+# files and directories that do not exist.
+# Note: the same is true for the other CFG_RUNTIME* and CFG_INSTALL*
+# settings as well but they are historical and I do not want to change
+# them.
$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c
$(cc32) $(pkgcflags) \
/DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \
@@ -829,22 +934,21 @@ $(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c
/DCFG_RUNTIME_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \
/DCFG_RUNTIME_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \
/DCFG_RUNTIME_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \
+ /DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \
-Fo$@ $?
$(TMP_DIR)\tclAppInit.obj: $(WIN_DIR)\tclAppInit.c
$(cc32) $(appcflags) /DUNICODE /D_UNICODE \
- /DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \
-Fo$@ $?
### The following objects should be built using the stub interfaces
-### *ALL* extensions need to built with /DTCL_THREADS=1
$(TMP_DIR)\tclWinReg.obj: $(WIN_DIR)\tclWinReg.c
- $(cc32) $(appcflags) /DUSE_TCL_STUBS -Fo$@ $?
+ $(cc32) $(appcflags_nostubs) /DUSE_TCL_STUBS=1 -Fo$@ $?
$(TMP_DIR)\tclWinDde.obj: $(WIN_DIR)\tclWinDde.c
- $(cc32) $(appcflags) /DUSE_TCL_STUBS -Fo$@ $?
+ $(cc32) $(appcflags_nostubs) /DUSE_TCL_STUBS=1 -Fo$@ $?
### The following objects are part of the stub library and should not
@@ -854,12 +958,24 @@ $(TMP_DIR)\tclWinDde.obj: $(WIN_DIR)\tclWinDde.c
$(TMP_DIR)\tclStubLib.obj: $(GENERICDIR)\tclStubLib.c
$(cc32) $(stubscflags) -Fo$@ $?
+$(TMP_DIR)\tclStubCall.obj: $(GENERICDIR)\tclStubCall.c
+ $(cc32) $(stubscflags) \
+ /DCFG_RUNTIME_DLLFILE="\"$(TCLLIBNAME)\"" \
+ /DCFG_RUNTIME_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \
+ $(TCL_INCLUDES) -Fo$@ $?
+
+$(TMP_DIR)\tclStubLibTbl.obj: $(GENERICDIR)\tclStubLibTbl.c
+ $(cc32) $(stubscflags) $(TCL_INCLUDES) -Fo$@ $?
+
$(TMP_DIR)\tclTomMathStubLib.obj: $(GENERICDIR)\tclTomMathStubLib.c
$(cc32) $(stubscflags) -Fo$@ $?
$(TMP_DIR)\tclOOStubLib.obj: $(GENERICDIR)\tclOOStubLib.c
$(cc32) $(stubscflags) -Fo$@ $?
+$(TMP_DIR)\tclWinPanic.obj: $(WIN_DIR)\tclWinPanic.c
+ $(cc32) $(stubscflags) -Fo$@ $?
+
$(TMP_DIR)\tclsh.exe.manifest: $(WIN_DIR)\tclsh.exe.manifest.in
@nmakehlp -s << $** >$@
@MACHINE@ $(MACHINE:IX86=X86)
@@ -933,6 +1049,11 @@ install-binaries:
!endif
@$(CPY) "$(TCLIMPLIB)" "$(LIB_INSTALL_DIR)\"
@$(CPY) "$(OUT_DIR)\zlib1.dll" "$(BIN_INSTALL_DIR)\"
+ @$(CPY) "$(OUT_DIR)\libtommath.dll" "$(BIN_INSTALL_DIR)\"
+!if !$(STATIC_BUILD)
+ @$(CPY) "$(OUT_DIR)\zdll.lib" "$(LIB_INSTALL_DIR)\"
+ @$(CPY) "$(OUT_DIR)\tommath.lib" "$(LIB_INSTALL_DIR)\"
+!endif
!if exist($(TCLSH))
@echo Installing $(TCLSHNAME)
@$(CPY) "$(TCLSH)" "$(BIN_INSTALL_DIR)\"
@@ -941,20 +1062,6 @@ install-binaries:
@$(CPY) "$(TCLSTUBLIB)" "$(LIB_INSTALL_DIR)\"
install-libraries: tclConfig tcl-nmake install-msgs install-tzdata
- @if not exist "$(SCRIPT_INSTALL_DIR)" \
- $(MKDIR) "$(SCRIPT_INSTALL_DIR)"
- @if not exist "$(SCRIPT_INSTALL_DIR)\opt0.4" \
- $(MKDIR) "$(SCRIPT_INSTALL_DIR)\opt0.4"
- @if not exist "$(MODULE_INSTALL_DIR)" \
- $(MKDIR) "$(MODULE_INSTALL_DIR)"
- @if not exist "$(MODULE_INSTALL_DIR)\8.4" \
- $(MKDIR) "$(MODULE_INSTALL_DIR)\8.4"
- @if not exist "$(MODULE_INSTALL_DIR)\8.4\platform" \
- $(MKDIR) "$(MODULE_INSTALL_DIR)\8.4\platform"
- @if not exist "$(MODULE_INSTALL_DIR)\8.5" \
- $(MKDIR) "$(MODULE_INSTALL_DIR)\8.5"
- @if not exist "$(MODULE_INSTALL_DIR)\8.6" \
- $(MKDIR) "$(MODULE_INSTALL_DIR)\8.6"
@if not exist "$(LIB_INSTALL_DIR)\nmake" \
$(MKDIR) "$(LIB_INSTALL_DIR)\nmake"
@echo Installing header files
@@ -965,73 +1072,87 @@ install-libraries: tclConfig tcl-nmake install-msgs install-tzdata
@$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
@$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\"
@$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\"
+ @$(CPY) "$(TOMMATHDIR)\tommath.h" "$(INCLUDE_INSTALL_DIR)\"
+!if !$(TCL_EMBED_SCRIPTS)
@echo Installing library files to $(SCRIPT_INSTALL_DIR)
- @$(CPY) "$(ROOT)\library\*.tcl" "$(SCRIPT_INSTALL_DIR)\"
+ @if not exist "$(SCRIPT_INSTALL_DIR)" \
+ $(MKDIR) "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) "$(ROOT)\library\*.tcl" "$(SCRIPT_INSTALL_DIR)\"
@$(CPY) "$(ROOT)\library\tclIndex" "$(SCRIPT_INSTALL_DIR)\"
+!endif
@$(CPY) "$(OUT_DIR)\tclConfig.sh" "$(LIB_INSTALL_DIR)\"
@$(CPY) "$(WIN_DIR)\tclooConfig.sh" "$(LIB_INSTALL_DIR)\"
+ @$(CPY) "$(TCLSCRIPTZIP)" "$(LIB_INSTALL_DIR)\"
@$(CPY) "$(WIN_DIR)\rules.vc" "$(LIB_INSTALL_DIR)\nmake\"
@$(CPY) "$(WIN_DIR)\targets.vc" "$(LIB_INSTALL_DIR)\nmake\"
@$(CPY) "$(WIN_DIR)\nmakehlp.c" "$(LIB_INSTALL_DIR)\nmake\"
@$(CPY) "$(WIN_DIR)\x86_64-w64-mingw32-nmakehlp.exe" "$(LIB_INSTALL_DIR)\nmake\"
@$(CPY) "$(OUT_DIR)\tcl.nmake" "$(LIB_INSTALL_DIR)\nmake\"
- @echo Installing package http 1.0 (obsolete)
- @$(CPY) "$(ROOT)\library\http1.0\*.tcl" \
- "$(SCRIPT_INSTALL_DIR)\http1.0\"
+!if !$(TCL_EMBED_SCRIPTS)
+ @echo Installing package cookiejar $(PKG_COOKIEJAR_VER)
+ @if not exist "$(SCRIPT_INSTALL_DIR)\cookiejar0.2" \
+ $(MKDIR) "$(SCRIPT_INSTALL_DIR)\cookiejar0.2"
+ @$(CPY) "$(ROOT)\library\cookiejar\*.tcl" \
+ "$(SCRIPT_INSTALL_DIR)\cookiejar0.2\"
+ @$(CPY) "$(ROOT)\library\cookiejar\*.gz" \
+ "$(SCRIPT_INSTALL_DIR)\cookiejar0.2\"
@echo Installing package opt $(PKG_OPT_VER)
+ @if not exist "$(SCRIPT_INSTALL_DIR)\opt0.4" \
+ $(MKDIR) "$(SCRIPT_INSTALL_DIR)\opt0.4"
@$(CPY) "$(ROOT)\library\opt\*.tcl" \
"$(SCRIPT_INSTALL_DIR)\opt0.4\"
+ @if not exist "$(MODULE_INSTALL_DIR)" \
+ $(MKDIR) "$(MODULE_INSTALL_DIR)"
@echo Installing package http $(PKG_HTTP_VER) as a Tcl Module
+ @if not exist "$(MODULE_INSTALL_DIR)\9.0" \
+ $(MKDIR) "$(MODULE_INSTALL_DIR)\9.0"
@$(COPY) "$(ROOT)\library\http\http.tcl" \
- "$(MODULE_INSTALL_DIR)\8.6\http-$(PKG_HTTP_VER).tm"
+ "$(MODULE_INSTALL_DIR)\9.0\http-$(PKG_HTTP_VER).tm"
@echo Installing package msgcat $(PKG_MSGCAT_VER) as a Tcl Module
@$(COPY) "$(ROOT)\library\msgcat\msgcat.tcl" \
- "$(MODULE_INSTALL_DIR)\8.5\msgcat-$(PKG_MSGCAT_VER).tm"
+ "$(MODULE_INSTALL_DIR)\9.0\msgcat-$(PKG_MSGCAT_VER).tm"
@echo Installing package tcltest $(PKG_TCLTEST_VER) as a Tcl Module
@$(COPY) "$(ROOT)\library\tcltest\tcltest.tcl" \
- "$(MODULE_INSTALL_DIR)\8.5\tcltest-$(PKG_TCLTEST_VER).tm"
+ "$(MODULE_INSTALL_DIR)\9.0\tcltest-$(PKG_TCLTEST_VER).tm"
@echo Installing package platform $(PKG_PLATFORM_VER) as a Tcl Module
+ @if not exist "$(MODULE_INSTALL_DIR)\9.0\platform" \
+ $(MKDIR) "$(MODULE_INSTALL_DIR)\9.0\platform"
@$(COPY) "$(ROOT)\library\platform\platform.tcl" \
- "$(MODULE_INSTALL_DIR)\8.4\platform-$(PKG_PLATFORM_VER).tm"
+ "$(MODULE_INSTALL_DIR)\9.0\platform-$(PKG_PLATFORM_VER).tm"
@echo Installing package platform::shell $(PKG_SHELL_VER) as a Tcl Module
@$(COPY) "$(ROOT)\library\platform\shell.tcl" \
- "$(MODULE_INSTALL_DIR)\8.4\platform\shell-$(PKG_SHELL_VER).tm"
- @echo Installing $(TCLDDELIBNAME)
-!if $(STATIC_BUILD)
-!if !$(TCL_USE_STATIC_PACKAGES)
- @$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\"
+ "$(MODULE_INSTALL_DIR)\9.0\platform\shell-$(PKG_SHELL_VER).tm"
!endif
-!else
+ @echo Installing $(TCLDDELIBNAME)
@$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\"
@$(CPY) "$(ROOT)\library\dde\pkgIndex.tcl" \
"$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\"
-!endif
@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
+ @$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\registry$(REGDOTVERSION)\"
+ @$(CPY) "$(ROOT)\library\registry\pkgIndex.tcl" \
+ "$(LIB_INSTALL_DIR)\registry$(REGDOTVERSION)\"
+!if !$(TCL_EMBED_SCRIPTS)
@echo Installing encodings
@$(CPY) "$(ROOT)\library\encoding\*.enc" \
"$(SCRIPT_INSTALL_DIR)\encoding\"
+!endif
# "emacs font-lock highlighting fix
install-tzdata:
+!if !$(TCL_EMBED_SCRIPTS)
@echo Installing time zone data
@set TCL_LIBRARY=$(ROOT:\=/)/library
@$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \
"$(ROOT:\=/)/library/tzdata" "$(SCRIPT_INSTALL_DIR)/tzdata"
+!endif
install-msgs:
+!if !$(TCL_EMBED_SCRIPTS)
@echo Installing message catalogs
@set TCL_LIBRARY=$(ROOT:\=/)/library
@$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \
"$(ROOT:\=/)/library/msgs" "$(SCRIPT_INSTALL_DIR)/msgs"
+!endif
install-pdbs:
@echo Installing debug symbols
diff --git a/win/rules.vc b/win/rules.vc
index c6c3b5f..0b47765 100644
--- a/win/rules.vc
+++ b/win/rules.vc
@@ -24,7 +24,7 @@ _RULES_VC = 1
# For modifications that are not backward-compatible, you *must* change
# the major version.
RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 10
+RULES_VERSION_MINOR = 15
# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
@@ -697,7 +697,7 @@ LINKERFLAGS = $(LINKERFLAGS) -ltcg
&& [nmakehlp -V "$(_TCL_H)" "define TCL_MAJOR_VERSION" >> versions.vc]
!endif
!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+ && [nmakehlp -V "$(_TCL_H)" "define TCL_MINOR_VERSION" >> versions.vc]
!endif
!if [echo TCL_RELEASE_SERIAL = \>> versions.vc] \
&& [nmakehlp -V "$(_TCL_H)" TCL_RELEASE_SERIAL >> versions.vc]
@@ -877,6 +877,11 @@ TCL_THREADS = 0
USE_THREAD_ALLOC= 0
!endif
+!if [nmakehlp -f $(OPTS) "tcl8"]
+!message *** Build for Tcl8
+TCL_BUILD_FOR = 8
+!endif
+
!if $(TCL_MAJOR_VERSION) == 8
!if [nmakehlp -f $(OPTS) "time64bit"]
!message *** Force 64-bit time_t
@@ -1089,7 +1094,7 @@ SUFX = $(SUFX:x=)
!else
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
EXT = lib
-!if !$(MSVCRT)
+!if $(MSVCRT) && $(TCL_VERSION) > 86 || !$(MSVCRT) && $(TCL_VERSION) < 87
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX = $(SUFX:x=)
!endif
@@ -1130,8 +1135,8 @@ STUBPREFIX = $(PROJECT)stub
#
# TIP 430. Unused for 8.6 but no harm defining it to allow a common rules.vc
-TCLSCRIPTZIPNAME = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip
-TKSCRIPTZIPNAME = libtk$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip
+TCL_ZIP_FILE = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip
+TK_ZIP_FILE = libtk$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip
!if $(DOING_TCL)
TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe
@@ -1139,9 +1144,13 @@ TCLSH = $(OUT_DIR)\$(TCLSHNAME)
TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
-TCLSCRIPTZIP = $(OUT_DIR)\$(TCLSCRIPTZIPNAME)
+TCLSCRIPTZIP = $(OUT_DIR)\$(TCL_ZIP_FILE)
+!if $(TCL_MAJOR_VERSION) == 8
TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+!else
+TCLSTUBLIBNAME = $(STUBPREFIX).lib
+!endif
TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
TCL_INCLUDES = -I"$(WIN_DIR)" -I"$(GENERICDIR)"
@@ -1157,7 +1166,11 @@ TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
!endif
+!if $(TCL_MAJOR_VERSION) == 8
TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
+!else
+TCLSTUBLIB = $(_TCLDIR)\lib\tclstub.lib
+!endif
TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
@@ -1167,7 +1180,7 @@ TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)t$(SUFX:t=).lib
TCL_LIBRARY = $(_TCLDIR)\lib
TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
-TCLSCRIPTZIP = $(_TCLDIR)\lib\$(TCLSCRIPTZIPNAME)
+TCLSCRIPTZIP = $(_TCLDIR)\lib\$(TCL_ZIP_FILE)
TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
TCL_INCLUDES = -I"$(_TCLDIR)\include"
@@ -1177,7 +1190,11 @@ TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!if !exist($(TCLSH))
TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
!endif
+!if $(TCL_MAJOR_VERSION) == 8
TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
+!else
+TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub.lib
+!endif
TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
@@ -1187,13 +1204,17 @@ TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)t$(SUFX:t=).lib
TCL_LIBRARY = $(_TCLDIR)\library
TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
-TCLSCRIPTZIP = $(_TCLDIR)\win\$(BUILDDIRTOP)\$(TCLSCRIPTZIPNAME)
+TCLSCRIPTZIP = $(_TCLDIR)\win\$(BUILDDIRTOP)\$(TCL_ZIP_FILE)
TCLTOOLSDIR = $(_TCLDIR)\tools
TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
!endif # TCLINSTALL
+!if !$(STATIC_BUILD) && "$(TCL_BUILD_FOR)" == "8"
+tcllibs = "$(TCLSTUBLIB)"
+!else
tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
+!endif
!endif # $(DOING_TCL)
@@ -1213,14 +1234,18 @@ WISHNAMEPREFIX = wish
WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
TKLIBNAME8 = tk$(TK_VERSION)$(SUFX).$(EXT)
TKLIBNAME9 = tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
-!if $(TCL_MAJOR_VERSION) == 8
+!if $(TCL_MAJOR_VERSION) == 8 || "$(TCL_BUILD_FOR)" == "8"
TKLIBNAME = tk$(TK_VERSION)$(SUFX).$(EXT)
TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
!else
TKLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
TKIMPLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).lib
!endif
+!if $(TK_MAJOR_VERSION) == 8
TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
+!else
+TKSTUBLIBNAME = tkstub.lib
+!endif
!if $(DOING_TK)
WISH = $(OUT_DIR)\$(WISHNAME)
@@ -1228,7 +1253,7 @@ TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
TKLIB = $(OUT_DIR)\$(TKLIBNAME)
TK_INCLUDES = -I"$(WIN_DIR)" -I"$(GENERICDIR)"
-TKSCRIPTZIP = $(OUT_DIR)\$(TKSCRIPTZIPNAME)
+TKSCRIPTZIP = $(OUT_DIR)\$(TK_ZIP_FILE)
!else # effectively NEED_TK
@@ -1243,7 +1268,7 @@ TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
!endif
TK_INCLUDES = -I"$(_TKDIR)\include"
-TKSCRIPTZIP = $(_TKDIR)\lib\$(TKSCRIPTZIPNAME)
+TKSCRIPTZIP = $(_TKDIR)\lib\$(TK_ZIP_FILE)
!else # Building against Tk sources
@@ -1257,7 +1282,7 @@ TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
!endif
TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
-TKSCRIPTZIP = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSCRIPTZIPNAME)
+TKSCRIPTZIP = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TK_ZIP_FILE)
!endif # TKINSTALL
@@ -1268,16 +1293,22 @@ tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
# Various output paths
PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-PRJLIBNAME8 = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-PRJLIBNAME9 = tcl9$(PROJECT)$(VERSION)$(SUFX).$(EXT)
-!if $(TCL_MAJOR_VERSION) == 8
+# Even when building against Tcl 9, PRJLIBNAME8 must have "t"
+PRJLIBNAME8 = $(PROJECT)$(VERSION)t$(SUFX:t=).$(EXT)
+# Even when building against Tcl 8, PRJLIBNAME9 must not have "t"
+PRJLIBNAME9 = tcl9$(PROJECT)$(VERSION)$(SUFX:t=).$(EXT)
+!if $(TCL_MAJOR_VERSION) == 8 || "$(TCL_BUILD_FOR)" == "8"
PRJLIBNAME = $(PRJLIBNAME8)
!else
PRJLIBNAME = $(PRJLIBNAME9)
!endif
PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
+!if $(TCL_MAJOR_VERSION) == 8
PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+!else
+PRJSTUBLIBNAME = $(STUBPREFIX).lib
+!endif
PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
# If extension parent makefile has not defined a resource definition file,
@@ -1417,9 +1448,9 @@ OPTDEFINES = $(OPTDEFINES) /DNO_STRTOI64=1
!if "$(_USE_64BIT_TIME_T)" == "1"
OPTDEFINES = $(OPTDEFINES) /D_USE_64BIT_TIME_T=1
!endif
-
-# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
-COMPILERFLAGS = /D_ATL_XP_TARGETING
+!endif
+!if "$(TCL_BUILD_FOR)" == "8"
+OPTDEFINES = $(OPTDEFINES) /DTCL_MAJOR_VERSION=8 /DTK_MAJOR_VERSION=8
!endif
# Like the TEA system only set this non empty for non-Tk extensions
@@ -1427,9 +1458,9 @@ COMPILERFLAGS = /D_ATL_XP_TARGETING
# so we pass both
!if !$(DOING_TCL) && !$(DOING_TK)
PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- /DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
- /DMODULE_SCOPE=extern
+ /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ /DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+ /DMODULE_SCOPE=extern
!endif
# crt picks the C run time based on selected OPTS
@@ -1503,6 +1534,10 @@ INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WIN_DIR)" -I"$(COMPATDIR)"
# cflags contains generic flags used for building practically all object files
cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
+!if $(TCL_MAJOR_VERSION) == 8 && $(TCL_MINOR_VERSION) < 7
+cflags = $(cflags) -DTcl_Size=int
+!endif
+
# appcflags contains $(cflags) and flags for building the application
# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
# flags used for building shared object files The two differ in the
@@ -1606,7 +1641,7 @@ default-target: $(DEFAULT_BUILD_TARGET)
!if $(MULTIPLATFORM_INSTALL)
default-pkgindex:
- @echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
+ @echo if {[package vsatisfies [package provide Tcl] 9.0]} { > $(OUT_DIR)\pkgIndex.tcl
@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
[list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
@echo } else { >> $(OUT_DIR)\pkgIndex.tcl
@@ -1615,7 +1650,7 @@ default-pkgindex:
@echo } >> $(OUT_DIR)\pkgIndex.tcl
!else
default-pkgindex:
- @echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
+ @echo if {[package vsatisfies [package provide Tcl] 9.0]} { > $(OUT_DIR)\pkgIndex.tcl
@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
[list load [file join $$dir $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
@echo } else { >> $(OUT_DIR)\pkgIndex.tcl
@@ -1655,6 +1690,7 @@ default-install-libraries: default-install-scripts
default-install-scripts: $(OUT_DIR)\pkgIndex.tcl
@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
diff --git a/win/targets.vc b/win/targets.vc
index 077e8f7..08f8441 100644
--- a/win/targets.vc
+++ b/win/targets.vc
@@ -53,6 +53,7 @@ default-install: default-install-stubs
default-install: default-install-headers
default-install-headers:
@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+ @if not exist "$(INCLUDE_INSTALL_DIR)" $(MKDIR) "$(INCLUDE_INSTALL_DIR)"
@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
!endif
diff --git a/win/tcl.dsp b/win/tcl.dsp
index 4f35cb3..a5e4a63 100644
--- a/win/tcl.dsp
+++ b/win/tcl.dsp
@@ -34,18 +34,18 @@ CFG=tcl - Win32 Debug Static
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release\tcl_Dynamic"
-# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=none MSVCDIR=IDE"
+# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc MSVCDIR=IDE"
# PROP BASE Rebuild_Opt "-a"
-# PROP BASE Target_File "Release\tclsh86.exe"
+# PROP BASE Target_File "Release\tclsh90.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 Cmd_Line "nmake -nologo -f makefile.vc MSVCDIR=IDE"
# PROP Rebuild_Opt "clean release"
-# PROP Target_File "Release\tclsh86t.exe"
+# PROP Target_File "Release\tclsh90t.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -57,7 +57,7 @@ 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\tclsh86g.exe"
+# PROP BASE Target_File "Debug\tclsh90g.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
@@ -66,7 +66,7 @@ CFG=tcl - Win32 Debug Static
# 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\tclsh86tg.exe"
+# PROP Target_File "Debug\tclsh90tg.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\tclsh86sg.exe"
+# PROP BASE Target_File "Debug\tclsh90sg.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\tclsh86sg.exe"
+# PROP Target_File "Debug\tclsh90sg.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\tclsh86s.exe"
+# PROP BASE Target_File "Release\tclsh90s.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\tclsh86s.exe"
+# PROP Target_File "Release\tclsh90s.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -136,26 +136,10 @@ CFG=tcl - Win32 Debug Static
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\compat\dirent.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\dirent2.h
-# End Source File
-# Begin Source File
-
SOURCE=..\compat\dlfcn.h
# End Source File
# Begin Source File
-SOURCE=..\compat\fixstrtod.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\float.h
-# End Source File
-# Begin Source File
-
SOURCE=..\compat\gettod.c
# End Source File
# Begin Source File
@@ -164,56 +148,12 @@ SOURCE=..\compat\limits.h
# End Source File
# Begin Source File
-SOURCE=..\compat\memcmp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\opendir.c
-# End Source File
-# Begin Source File
-
SOURCE=..\compat\README
# End Source File
# Begin Source File
-SOURCE=..\compat\stdlib.h
-# End Source File
-# Begin Source File
-
SOURCE=..\compat\string.h
# End Source File
-# Begin Source File
-
-SOURCE=..\compat\strncasecmp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\strstr.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\strtod.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\strtol.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\strtoul.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\tclErrno.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\unistd.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\compat\waitpid.c
-# End Source File
# End Group
# Begin Group "doc"
@@ -292,10 +232,6 @@ SOURCE=..\doc\CallDel.3
# End Source File
# Begin Source File
-SOURCE=..\doc\case.n
-# End Source File
-# Begin Source File
-
SOURCE=..\doc\catch.n
# End Source File
# Begin Source File
@@ -776,7 +712,7 @@ SOURCE=..\doc\safe.n
# End Source File
# Begin Source File
-SOURCE=..\doc\SaveResult.3
+SOURCE=..\doc\SaveInterpState.3
# End Source File
# Begin Source File
@@ -840,7 +776,7 @@ SOURCE=..\doc\SplitPath.3
# End Source File
# Begin Source File
-SOURCE=..\doc\StaticPkg.3
+SOURCE=..\doc\StaticLibrary.3
# End Source File
# Begin Source File
@@ -1268,6 +1204,10 @@ SOURCE=..\generic\tclProc.c
# End Source File
# Begin Source File
+SOURCE=..\generic\tclProcess.c
+# End Source File
+# Begin Source File
+
SOURCE=..\generic\tclRegexp.c
# End Source File
# Begin Source File
@@ -1300,6 +1240,14 @@ SOURCE=..\generic\tclStubLib.c
# End Source File
# Begin Source File
+SOURCE=..\generic\tclStubCall.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\generic\tclStubLibTbl.c
+# End Source File
+# Begin Source File
+
SOURCE=..\generic\tclOOStubLib.c
# End Source File
# Begin Source File
@@ -1424,7 +1372,7 @@ SOURCE=.\configure
# End Source File
# Begin Source File
-SOURCE=.\configure.in
+SOURCE=.\configure.ac
# End Source File
# Begin Source File
@@ -1456,10 +1404,6 @@ SOURCE=.\rules.vc
# End Source File
# Begin Source File
-SOURCE=.\tcl.hpj.in
-# End Source File
-# Begin Source File
-
SOURCE=.\tcl.m4
# End Source File
# Begin Source File
@@ -1528,6 +1472,10 @@ SOURCE=.\tclWinNotify.c
# End Source File
# Begin Source File
+SOURCE=.\tclWinPanic.c
+# End Source File
+# Begin Source File
+
SOURCE=.\tclWinPipe.c
# End Source File
# Begin Source File
diff --git a/win/tcl.hpj.in b/win/tcl.hpj.in
deleted file mode 100644
index a94cea6..0000000
--- a/win/tcl.hpj.in
+++ /dev/null
@@ -1,19 +0,0 @@
-; This file is maintained by HCW. Do not modify this file directly.
-
-[OPTIONS]
-HCW=0
-LCID=0x409 0x0 0x0 ;English (United States)
-REPORT=Yes
-TITLE=Tcl/Tk Reference Manual
-CNT=tcl86.cnt
-COPYRIGHT=Copyright © 2000 Ajuba Solutions
-HLP=tcl86.hlp
-
-[FILES]
-tcl.rtf
-
-[WINDOWS]
-main="Tcl/Tk Reference Manual",,0
-
-[CONFIG]
-BrowseButtons()
diff --git a/win/tcl.m4 b/win/tcl.m4
index c8ceadb..d12e6f5 100644
--- a/win/tcl.m4
+++ b/win/tcl.m4
@@ -279,14 +279,6 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [
TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
fi
- #
- # eval is required to do the TCL_DBGX substitution
- #
-
- eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
- eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
- eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
-
eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
@@ -372,42 +364,7 @@ AC_DEFUN([SC_ENABLE_SHARED], [
SHARED_BUILD=0
AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
fi
-])
-
-#------------------------------------------------------------------------
-# SC_ENABLE_THREADS --
-#
-# Specify if thread support should be enabled
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-threads=yes|no
-#
-# Defines the following vars:
-# TCL_THREADS
-#------------------------------------------------------------------------
-
-AC_DEFUN([SC_ENABLE_THREADS], [
- AC_MSG_CHECKING(for building with threads)
- AC_ARG_ENABLE(threads, [ --enable-threads build with threads (default: on)],
- [tcl_ok=$enableval], [tcl_ok=yes])
-
- if test "$tcl_ok" = "yes"; then
- AC_MSG_RESULT([yes (default)])
- TCL_THREADS=1
- AC_DEFINE(TCL_THREADS)
- # USE_THREAD_ALLOC tells us to try the special thread-based
- # allocator that significantly reduces lock contention
- AC_DEFINE(USE_THREAD_ALLOC)
- else
- TCL_THREADS=0
- AC_MSG_RESULT(no)
- fi
- AC_SUBST(TCL_THREADS)
+ AC_SUBST(SHARED_BUILD)
])
#------------------------------------------------------------------------
@@ -434,7 +391,6 @@ AC_DEFUN([SC_ENABLE_THREADS], [
# Sets to $(CFLAGS_OPTIMIZE) if false
# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
# Sets to $(LDFLAGS_OPTIMIZE) if false
-# DBGX Debug library extension
#
#------------------------------------------------------------------------
@@ -445,7 +401,6 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
if test "$tcl_ok" = "no"; then
CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
- DBGX=""
AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?])
AC_MSG_RESULT([no])
@@ -453,7 +408,6 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
else
CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
- DBGX=g
if test "$tcl_ok" = "yes"; then
AC_MSG_RESULT([yes (standard debugging)])
fi
@@ -537,22 +491,12 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
AC_ARG_ENABLE(64bit,[ --enable-64bit enable 64bit support (where applicable)], [do64bit=$enableval], [do64bit=no])
AC_MSG_RESULT($do64bit)
- # Cross-compiling options for Windows/CE builds
-
- AC_MSG_CHECKING([if Windows/CE build is requested])
- AC_ARG_ENABLE(wince,[ --enable-wince enable Win/CE support (where applicable)], [doWince=$enableval], [doWince=no])
- AC_MSG_RESULT($doWince)
-
- AC_MSG_CHECKING([for Windows/CE celib directory])
- AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR],
- CELIB_DIR=$withval, CELIB_DIR=NO_CELIB)
- AC_MSG_RESULT([$CELIB_DIR])
-
# Set some defaults (may get changed below)
EXTRA_CFLAGS=""
AC_DEFINE(MODULE_SCOPE, [extern], [No need to mark inidividual symbols as hidden])
AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
+ AC_CHECK_PROG(WINE, wine, wine,)
SHLIB_SUFFIX=".dll"
@@ -691,6 +635,15 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
if test $tcl_cv_ld_high_entropy = yes; then
extra_ldflags="$extra_ldflags -Wl,--disable-high-entropy-va"
fi
+
+ AC_CACHE_CHECK([if the compiler understands -finput-charset],
+ tcl_cv_cc_input_charset, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -finput-charset=UTF-8"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_input_charset=yes],[tcl_cv_cc_input_charset=no])
+ CFLAGS=$hold_cflags])
+ if test $tcl_cv_cc_input_charset = yes; then
+ extra_cflags="$extra_cflags -finput-charset=UTF-8"
+ fi
fi
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Wl,--enable-auto-image-base"
@@ -711,7 +664,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
SHLIB_LD_LIBS='${LIBS}'
LIBS="-lnetapi32 -lkernel32 -luser32 -ladvapi32 -luserenv -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_GUI="-lgdi32 -lcomdlg32 -limm32 -lcomctl32 -lshell32 -luuid -lole32 -loleaut32 -lwinspool"
STLIB_LD='${AR} cr'
RC_OUT=-o
RC_TYPE=
@@ -729,7 +682,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
AC_MSG_RESULT([using static flags])
runtime=
LIBRARIES="\${STATIC_LIBRARIES}"
- EXESUFFIX="s\${DBGX}.exe"
+ EXESUFFIX="s.exe"
else
# dynamic
AC_MSG_RESULT([using shared flags])
@@ -743,7 +696,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
runtime=
# Add SHLIB_LD_LIBS to the Make rule, not here.
- EXESUFFIX="\${DBGX}.exe"
+ EXESUFFIX=".exe"
LIBRARIES="\${SHARED_LIBRARIES}"
fi
# Link with gcc since ld does not link to default libs like
@@ -754,16 +707,16 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
-Wl,--out-implib,\$(patsubst %.dll,lib%.dll.a,\[$]@)"
# DLLSUFFIX is separate because it is the building block for
# users of tclConfig.sh that may build shared or static.
- DLLSUFFIX="\${DBGX}.dll"
- LIBSUFFIX="\${DBGX}.a"
- LIBFLAGSUFFIX="\${DBGX}"
+ DLLSUFFIX=".dll"
+ LIBSUFFIX=".a"
+ LIBFLAGSUFFIX=""
SHLIB_SUFFIX=.dll
EXTRA_CFLAGS="${extra_cflags}"
CFLAGS_DEBUG=-g
CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- CFLAGS_WARNING="-Wall -Wpointer-arith"
+ CFLAGS_WARNING="-Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
LDFLAGS_DEBUG=
LDFLAGS_OPTIMIZE=
@@ -772,7 +725,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
;;
*)
- CFLAGS_WARNING="${CFLAGS_WARNING} -Wdeclaration-after-statement"
+ CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -fextended-identifiers"
;;
esac
@@ -832,14 +785,14 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
AC_MSG_RESULT([using static flags])
runtime=-MT
LIBRARIES="\${STATIC_LIBRARIES}"
- EXESUFFIX="s\${DBGX}.exe"
+ EXESUFFIX="s.exe"
else
# dynamic
AC_MSG_RESULT([using shared flags])
runtime=-MD
# Add SHLIB_LD_LIBS to the Make rule, not here.
LIBRARIES="\${SHARED_LIBRARIES}"
- EXESUFFIX="\${DBGX}.exe"
+ EXESUFFIX=".exe"
case "x`echo \${VisualStudioVersion}`" in
x1[[4-9]]*)
lflags="${lflags} -nodefaultlib:ucrt.lib"
@@ -851,9 +804,9 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
MAKE_DLL="\${SHLIB_LD} \$(LDFLAGS) -out:\[$]@"
# DLLSUFFIX is separate because it is the building block for
# users of tclConfig.sh that may build shared or static.
- DLLSUFFIX="\${DBGX}.dll"
- LIBSUFFIX="\${DBGX}.lib"
- LIBFLAGSUFFIX="\${DBGX}"
+ DLLSUFFIX=".dll"
+ LIBSUFFIX=".lib"
+ LIBFLAGSUFFIX=""
if test "$do64bit" != "no" ; then
case "$do64bit" in
@@ -900,98 +853,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
LINKBIN="link"
fi
- if test "$doWince" != "no" ; then
- # Set defaults for common evc4/PPC2003 setup
- # Currently Tcl requires 300+, possibly 420+ for sockets
- CEVERSION=420; # could be 211 300 301 400 420 ...
- TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
- ARCH=ARM; # could be ARM MIPS X86EM ...
- PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
- if test "$doWince" != "yes"; then
- # If !yes then the user specified something
- # Reset ARCH to allow user to skip specifying it
- ARCH=
- eval `echo $doWince | awk -F "," '{ \
- if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
- if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
- if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
- if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
- if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
- }'`
- if test "x${ARCH}" = "x" ; then
- ARCH=$TARGETCPU;
- fi
- fi
- OSVERSION=WCE$CEVERSION;
- if test "x${WCEROOT}" = "x" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
- if test ! -d "${WCEROOT}" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
- fi
- fi
- if test "x${SDKROOT}" = "x" ; then
- SDKROOT="C:/Program Files/Windows CE Tools"
- if test ! -d "${SDKROOT}" ; then
- SDKROOT="C:/Windows CE Tools"
- fi
- fi
- # The space-based-path will work for the Makefile, but will
- # not work if AC_TRY_COMPILE is called.
- WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
- SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
- CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
- if test ! -d "${CELIB_DIR}/inc"; then
- AC_MSG_ERROR([Invalid celib directory "${CELIB_DIR}"])
- fi
- if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"\
- -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
- AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
- else
- CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
- if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
- CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
- fi
- CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
- fi
- fi
-
- if test "$doWince" != "no" ; then
- CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
- if test "${TARGETCPU}" = "X86"; then
- CC="${CEBINROOT}/cl.exe"
- else
- CC="${CEBINROOT}/cl${ARCH}.exe"
- fi
- CC="\"${CC}\" -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
- RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
- arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
- defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _DLL _WINDOWS"
- for i in $defs ; do
- AC_DEFINE_UNQUOTED($i)
- done
-# if test "${ARCH}" = "X86EM"; then
-# AC_DEFINE_UNQUOTED(_WIN32_WCE_EMULATION)
-# fi
- AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION)
- AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION)
- 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\""
- AC_SUBST(CELIB_DIR)
- if test "${CEVERSION}" -lt 400 ; then
- LIBS="coredll.lib corelibc.lib winsock.lib"
- else
- LIBS="coredll.lib corelibc.lib ws2.lib"
- fi
- # celib currently stuck at wce300 status
- #LIBS="$LIBS \${CELIB_DIR}/wince-${ARCH}-pocket-${OSVERSION}-release/celib.lib"
- 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"
- fi
+ LIBS_GUI="gdi32.lib comdlg32.lib imm32.lib comctl32.lib shell32.lib uuid.lib winspool.lib"
SHLIB_LD="${LINKBIN} -dll -incremental:no ${lflags}"
SHLIB_LD_LIBS='${LIBS}'
@@ -1022,7 +884,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
# Specify linker flags depending on the type of app being
# built -- Console vs. Window.
- if test "$doWince" != "no" -a "${TARGETCPU}" != "X86"; then
+ if test "${TARGETCPU}" != "X86"; then
LDFLAGS_CONSOLE="-link ${lflags}"
LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
else
@@ -1086,29 +948,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
fi
- # Check to see if winnt.h defines CHAR, SHORT, and LONG
- # even if VOID has already been #defined. The win32api
- # used by mingw and cygwin is known to do this.
-
- AC_CACHE_CHECK(for winnt.h that ignores VOID define,
- tcl_cv_winnt_ignore_void,
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
- #define VOID void
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #undef WIN32_LEAN_AND_MEAN
- ]], [[
- CHAR c;
- SHORT s;
- LONG l;
- ]])],
- [tcl_cv_winnt_ignore_void=yes],
- [tcl_cv_winnt_ignore_void=no])
- )
- if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
- AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
- [Defined when cygwin/mingw ignores VOID define in winnt.h])
- fi
+ AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have <stdbool.h>?])],)
# See if the compiler supports casting to a union type.
# This is used to stop gcc from printing a compiler
@@ -1155,13 +995,13 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
#------------------------------------------------------------------------
AC_DEFUN([SC_WITH_TCL], [
- if test -d ../../tcl8.6$1/win; then
- TCL_BIN_DEFAULT=../../tcl8.6$1/win
+ if test -d ../../tcl9.0$1/win; then
+ TCL_BIN_DEFAULT=../../tcl9.0$1/win
else
- TCL_BIN_DEFAULT=../../tcl8.6/win
+ TCL_BIN_DEFAULT=../../tcl9.0/win
fi
- AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.6 binaries from DIR],
+ AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 9.x 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)
@@ -1270,8 +1110,7 @@ AC_DEFUN([SC_TCL_CFG_ENCODING], [
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")
+ AC_DEFINE(TCL_CFGVAL_ENCODING,"utf-8")
fi
])
@@ -1326,3 +1165,126 @@ print("manifest needed")
AC_SUBST(VC_MANIFEST_EMBED_DLL)
AC_SUBST(VC_MANIFEST_EMBED_EXE)
])
+
+#------------------------------------------------------------------------
+# SC_CC_FOR_BUILD
+# For cross compiles, locate a C compiler that can generate native binaries.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# CC_FOR_BUILD
+# EXEEXT_FOR_BUILD
+#------------------------------------------------------------------------
+
+dnl Get a default for CC_FOR_BUILD to put into Makefile.
+AC_DEFUN([AX_CC_FOR_BUILD],
+[# Put a plausible default for CC_FOR_BUILD in Makefile.
+if test -z "$CC_FOR_BUILD"; then
+ if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+ else
+ AC_MSG_CHECKING([for gcc])
+ AC_CACHE_VAL(ac_cv_path_cc, [
+ search_path=`echo ${PATH} | sed -e 's/:/ /g'`
+ for dir in $search_path ; do
+ for j in `ls -r $dir/gcc 2> /dev/null` \
+ `ls -r $dir/gcc 2> /dev/null` ; do
+ if test x"$ac_cv_path_cc" = x ; then
+ if test -f "$j" ; then
+ ac_cv_path_cc=$j
+ break
+ fi
+ fi
+ done
+ done
+ ])
+ fi
+fi
+AC_SUBST(CC_FOR_BUILD)
+# Also set EXEEXT_FOR_BUILD.
+if test "x$cross_compiling" = "xno"; then
+ EXEEXT_FOR_BUILD='$(EXEEXT)'
+ OBJEXT_FOR_BUILD='$(OBJEXT)'
+else
+ OBJEXT_FOR_BUILD='.no'
+ AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext,
+ [rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.c
+ bfd_cv_build_exeext=
+ ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ rm -f conftest*
+ test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no])
+ EXEEXT_FOR_BUILD=""
+ test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
+fi
+AC_SUBST(EXEEXT_FOR_BUILD)])dnl
+AC_SUBST(OBJEXT_FOR_BUILD)])dnl
+
+
+
+#------------------------------------------------------------------------
+# SC_ZIPFS_SUPPORT
+# Locate a zip encoder installed on the system path, or none.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# ZIP_PROG
+# ZIP_PROG_OPTIONS
+# ZIP_PROG_VFSSEARCH
+# ZIP_INSTALL_OBJS
+#------------------------------------------------------------------------
+
+AC_DEFUN([SC_ZIPFS_SUPPORT], [
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ ZIP_INSTALL_OBJS=""
+
+ AC_MSG_CHECKING([for zip])
+ AC_CACHE_VAL(ac_cv_path_zip, [
+ search_path=`echo ${PATH} | sed -e 's/:/ /g'`
+ for dir in $search_path ; do
+ for j in `ls -r $dir/zip 2> /dev/null` \
+ `ls -r $dir/zip 2> /dev/null` ; do
+ if test x"$ac_cv_path_zip" = x ; then
+ if test -f "$j" ; then
+ ac_cv_path_zip=$j
+ break
+ fi
+ fi
+ done
+ done
+ ])
+ if test -f "$ac_cv_path_zip" ; then
+ ZIP_PROG="$ac_cv_path_zip"
+ AC_MSG_RESULT([$ZIP_PROG])
+ ZIP_PROG_OPTIONS="-rq"
+ ZIP_PROG_VFSSEARCH="*"
+ AC_MSG_RESULT([Found INFO Zip in environment])
+ # Use standard arguments for zip
+ else
+ # It is not an error if an installed version of Zip can't be located.
+ # We can use the locally distributed minizip instead
+ ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
+ ZIP_PROG_OPTIONS="-o -r"
+ ZIP_PROG_VFSSEARCH="*"
+ ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
+ AC_MSG_RESULT([No zip found on PATH building minizip])
+ fi
+ AC_SUBST(ZIP_PROG)
+ AC_SUBST(ZIP_PROG_OPTIONS)
+ AC_SUBST(ZIP_PROG_VFSSEARCH)
+ AC_SUBST(ZIP_INSTALL_OBJS)
+])
diff --git a/win/tcl.rc b/win/tcl.rc
index 06024d4..e09dfb3 100644
--- a/win/tcl.rc
+++ b/win/tcl.rc
@@ -1,3 +1,4 @@
+//
// Version Resource Script
//
@@ -7,35 +8,29 @@
//
// build-up the name suffix that defines the type of build this is.
//
-#if TCL_THREADS
-#define SUFFIX_THREADS "t"
-#else
-#define SUFFIX_THREADS ""
-#endif
-
#if DEBUG && !UNCHECKED
#define SUFFIX_DEBUG "g"
#else
#define SUFFIX_DEBUG ""
#endif
-#define SUFFIX SUFFIX_THREADS SUFFIX_DEBUG
+#define SUFFIX SUFFIX_DEBUG
LANGUAGE 0x9, 0x1 /* LANG_ENGLISH, SUBLANG_DEFAULT */
VS_VERSION_INFO VERSIONINFO
- FILEVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
+ FILEVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
PRODUCTVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
- FILEFLAGSMASK 0x3fL
+ FILEFLAGSMASK 0x3fL
#ifdef DEBUG
- FILEFLAGS VS_FF_DEBUG
+ FILEFLAGS VS_FF_DEBUG
#else
- FILEFLAGS 0x0L
+ FILEFLAGS 0x0L
#endif
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
diff --git a/win/tclAppInit.c b/win/tclAppInit.c
index 058b92a..c293952 100644
--- a/win/tclAppInit.c
+++ b/win/tclAppInit.c
@@ -15,30 +15,41 @@
*/
#include "tcl.h"
-#define WIN32_LEAN_AND_MEAN
-#define STRICT /* See MSDN Article Q83456 */
-#include <windows.h>
-#undef STRICT
-#undef WIN32_LEAN_AND_MEAN
-#include <locale.h>
-#include <stdlib.h>
-#include <tchar.h>
-#if TCL_MAJOR_VERSION < 9 && TCL_MINOR_VERSION < 7
+#if TCL_MAJOR_VERSION < 9
+# if defined(USE_TCL_STUBS)
+# error "Don't build with USE_TCL_STUBS!"
+# endif
+# if TCL_MINOR_VERSION < 7
# define Tcl_LibraryInitProc Tcl_PackageInitProc
# define Tcl_StaticLibrary Tcl_StaticPackage
+# endif
#endif
#ifdef TCL_TEST
+#ifdef __cplusplus
+extern "C" {
+#endif
extern Tcl_LibraryInitProc Tcltest_Init;
extern Tcl_LibraryInitProc Tcltest_SafeInit;
+#ifdef __cplusplus
+}
+#endif
#endif /* TCL_TEST */
-#if defined(STATIC_BUILD) && defined(TCL_USE_STATIC_PACKAGES) && TCL_USE_STATIC_PACKAGES
+#if defined(STATIC_BUILD)
extern Tcl_LibraryInitProc Registry_Init;
extern Tcl_LibraryInitProc Dde_Init;
extern Tcl_LibraryInitProc Dde_SafeInit;
#endif
+#define WIN32_LEAN_AND_MEAN
+#define STRICT /* See MSDN Article Q83456 */
+#include <windows.h>
+#undef STRICT
+#undef WIN32_LEAN_AND_MEAN
+#include <locale.h>
+#include <stdlib.h>
+#include <tchar.h>
#if defined(__GNUC__) || defined(TCL_BROKEN_MAINARGS)
int _CRT_glob = 0;
#endif /* __GNUC__ || TCL_BROKEN_MAINARGS */
@@ -163,11 +174,11 @@ int
Tcl_AppInit(
Tcl_Interp *interp) /* Interpreter for application. */
{
- if ((Tcl_Init)(interp) == TCL_ERROR) {
+ if (Tcl_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
-#if defined(STATIC_BUILD) && defined(TCL_USE_STATIC_PACKAGES) && TCL_USE_STATIC_PACKAGES
+#if defined(STATIC_BUILD)
if (Registry_Init(interp) == TCL_ERROR) {
return TCL_ERROR;
}
@@ -199,7 +210,7 @@ Tcl_AppInit(
*/
/*
- * Call Tcl_CreateCommand for application-specific commands, if they
+ * Call Tcl_CreateObjCommand for application-specific commands, if they
* weren't already created by the init procedures called above.
*/
@@ -210,8 +221,10 @@ Tcl_AppInit(
* user-specific startup file will be run under any conditions.
*/
- (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL,
- Tcl_NewStringObj("~/tclshrc.tcl", -1), TCL_GLOBAL_ONLY);
+ (void)Tcl_EvalEx(interp,
+ "set tcl_rcFileName [file tildeexpand ~/tclshrc.tcl]",
+ TCL_AUTO_LENGTH, TCL_EVAL_GLOBAL);
+
return TCL_OK;
}
@@ -272,11 +285,10 @@ setargv(
}
}
- /* Make sure we don't call ckalloc through the (not yet initialized) stub table */
- #undef Tcl_Alloc
- #undef Tcl_DbCkalloc
+ /* Make sure we don't call Tcl_Alloc through the (not yet initialized) stub table */
+# undef Tcl_Alloc
- argSpace = (TCHAR *)ckalloc(size * sizeof(char *)
+ argSpace = (TCHAR *)Tcl_Alloc(size * sizeof(char *)
+ (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR));
argv = (TCHAR **) argSpace;
argSpace += size * (sizeof(char *)/sizeof(TCHAR));
diff --git a/win/tclConfig.sh.in b/win/tclConfig.sh.in
index aba0532..c980af6 100644
--- a/win/tclConfig.sh.in
+++ b/win/tclConfig.sh.in
@@ -23,10 +23,6 @@ TCL_CC='@CC@'
# -D flags for use with the C compiler.
TCL_DEFS='@DEFS@'
-# If TCL was built with debugging symbols, generated libraries contain
-# this string at the end of the library name (before the extension).
-TCL_DBGX=@TCL_DBGX@
-
# Default flags used in an optimized and debuggable build, respectively.
TCL_CFLAGS_DEBUG='@CFLAGS_DEBUG@'
TCL_CFLAGS_OPTIMIZE='@CFLAGS_OPTIMIZE@'
@@ -41,12 +37,12 @@ TCL_SHARED_BUILD=@TCL_SHARED_BUILD@
# The name of the Tcl library (may be either a .a file or a shared library):
TCL_LIB_FILE='@TCL_LIB_FILE@'
+# The name of a zip containing the /library and /encodings (may be either a .zip file or a shared library):
+TCL_ZIP_FILE='@TCL_ZIP_FILE@'
+
# Flag to indicate whether shared libraries need export files.
TCL_NEEDS_EXP_FILE=''
-# Deprecated. Same as TCL_UNSHARED_LIB_SUFFIX
-TCL_EXPORT_FILE_SUFFIX='@CFG_TCL_UNSHARED_LIB_SUFFIX@'
-
# Additional libraries to use when linking Tcl.
TCL_LIBS='@LIBS@'
@@ -74,7 +70,7 @@ TCL_SHLIB_LD='@SHLIB_LD@'
TCL_STLIB_LD='@STLIB_LD@'
# Either '$LIBS' (if dependent libraries should be included when linking
-# shared libraries) or an empty string. See Tcl's configure.in for more
+# shared libraries) or an empty string. See Tcl's configure.ac for more
# explanation.
TCL_SHLIB_LD_LIBS='@SHLIB_LD_LIBS@'
@@ -83,7 +79,7 @@ TCL_SHLIB_SUFFIX='@SHLIB_SUFFIX@'
# Library file(s) to include in tclsh and other base applications
# in order to provide facilities needed by DLOBJ above.
-TCL_DL_LIBS='@DL_LIBS@'
+TCL_DL_LIBS=''
# Flags to pass to the compiler when linking object files into
# an executable tclsh or tcltest binary.
@@ -93,8 +89,8 @@ TCL_LD_FLAGS='@LDFLAGS@'
# run-time dynamic linker where to look for shared libraries such as
# libtcl.so. Used when linking applications. Only works if there
# is a variable "LIB_RUNTIME_DIR" defined in the Makefile.
-TCL_CC_SEARCH_FLAGS='@TCL_CC_SEARCH_FLAGS@'
-TCL_LD_SEARCH_FLAGS='@TCL_LD_SEARCH_FLAGS@'
+TCL_CC_SEARCH_FLAGS=''
+TCL_LD_SEARCH_FLAGS=''
# Additional object files linked with Tcl to provide compatibility
# with standard facilities from ANSI C or POSIX.
@@ -173,8 +169,8 @@ TCL_BUILD_STUB_LIB_PATH='@TCL_BUILD_STUB_LIB_PATH@'
# Path to the Tcl stub library in the install directory.
TCL_STUB_LIB_PATH='@TCL_STUB_LIB_PATH@'
-# Flag, 1: we built Tcl with threads enabled, 0 we didn't
-TCL_THREADS=@TCL_THREADS@
-
# Name of the zlib library that extensions should use
TCL_ZLIB_LIB_NAME='@TCL_ZLIB_LIB_NAME@'
+
+# Name of the tommath library that extensions should use
+TCL_TOMMATH_LIB_NAME='@TCL_TOMMATH_LIB_NAME@'
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c
index dac5965..3b7bbea 100644
--- a/win/tclWin32Dll.c
+++ b/win/tclWin32Dll.c
@@ -4,8 +4,8 @@
* This file contains the DLL entry point and other low-level bit bashing
* code that needs inline assembly.
*
- * Copyright (c) 1995-1996 Sun Microsystems, Inc.
- * Copyright (c) 1998-2000 Scriptics Corporation.
+ * Copyright © 1995-1996 Sun Microsystems, Inc.
+ * Copyright © 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.
@@ -14,7 +14,7 @@
#include "tclWinInt.h"
#if defined(HAVE_CPUID_H)
# include <cpuid.h>
-#elif defined(HAVE_INTRIN_H)
+#elif defined(_MSC_VER)
# include <intrin.h>
#endif
@@ -27,14 +27,6 @@
static HINSTANCE hInstance; /* HINSTANCE of this DLL. */
/*
- * VC++ 5.x has no 'cpuid' assembler instruction, so we must emulate it
- */
-
-#if defined(_MSC_VER) && (_MSC_VER <= 1100) && defined (_M_IX86)
-#define cpuid __asm __emit 0fh __asm __emit 0a2h
-#endif
-
-/*
* The following declaration is for the VC++ DLL entry point.
*/
@@ -119,10 +111,8 @@ BOOL APIENTRY
DllMain(
HINSTANCE hInst, /* Library instance handle. */
DWORD reason, /* Reason this function is being called. */
- LPVOID reserved) /* Not used. */
+ TCL_UNUSED(LPVOID))
{
- (void)reserved;
-
switch (reason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hInst);
@@ -156,7 +146,7 @@ DllMain(
*----------------------------------------------------------------------
*/
-HINSTANCE
+void *
TclWinGetTclInstance(void)
{
return hInstance;
@@ -189,40 +179,16 @@ TclWinInit(
GetVersionExW(&os);
/*
- * We no longer support Win32s or Win9x or Windows CE, so just in case
- * someone manages to get a runtime there, make sure they know that.
+ * We no longer support Win32s or Win9x or Windows CE or Windows XP, so just
+ * in case someone manages to get a runtime there, make sure they know that.
*/
if (os.dwPlatformId != VER_PLATFORM_WIN32_NT) {
- Tcl_Panic("Windows NT is the only supported platform");
+ Tcl_Panic("Windows 7 is the minimum supported platform");
}
}
/*
- *----------------------------------------------------------------------
- *
- * TclWinGetPlatformId --
- *
- * Determines whether running under NT, 95, or Win32s, to allow runtime
- * conditional code.
- *
- * Results:
- * The return value is always:
- * VER_PLATFORM_WIN32_NT Win32 on Windows NT, 2000, XP
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclWinGetPlatformId(void)
-{
- return VER_PLATFORM_WIN32_NT;
-}
-
-/*
*-------------------------------------------------------------------------
*
* TclWinNoBackslash --
@@ -283,34 +249,14 @@ TclWinEncodingsCleanup(void)
dlIter = driveLetterLookup;
while (dlIter != NULL) {
dlIter2 = dlIter->nextPtr;
- ckfree(dlIter->volumeName);
- ckfree(dlIter);
+ Tcl_Free(dlIter->volumeName);
+ Tcl_Free(dlIter);
dlIter = dlIter2;
}
Tcl_MutexUnlock(&mountPointMap);
}
/*
- *---------------------------------------------------------------------------
- *
- * TclWinResetInterfaces --
- *
- * Called during finalization to reset us to a safe state for reuse.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *---------------------------------------------------------------------------
- */
-void
-TclWinResetInterfaces(void)
-{
-}
-
-/*
*--------------------------------------------------------------------
*
* TclWinDriveLetterForVolMountPoint
@@ -397,8 +343,8 @@ TclWinDriveLetterForVolMountPoint(
* Now dlPtr2 points to the structure to free.
*/
- ckfree(dlPtr2->volumeName);
- ckfree(dlPtr2);
+ Tcl_Free(dlPtr2->volumeName);
+ Tcl_Free(dlPtr2);
/*
* Restart the loop - we could try to be clever and continue half
@@ -433,7 +379,7 @@ TclWinDriveLetterForVolMountPoint(
}
}
if (!alreadyStored) {
- dlPtr2 = (MountPointMap *)ckalloc(sizeof(MountPointMap));
+ dlPtr2 = (MountPointMap *)Tcl_Alloc(sizeof(MountPointMap));
dlPtr2->volumeName = (WCHAR *)TclNativeDupInternalRep(Target);
dlPtr2->driveLetter = (WCHAR) drive[0];
dlPtr2->nextPtr = driveLetterLookup;
@@ -459,7 +405,7 @@ TclWinDriveLetterForVolMountPoint(
* that fact and store '-1' so we don't have to look it up each time.
*/
- dlPtr2 = (MountPointMap *)ckalloc(sizeof(MountPointMap));
+ dlPtr2 = (MountPointMap *)Tcl_Alloc(sizeof(MountPointMap));
dlPtr2->volumeName = (WCHAR *)TclNativeDupInternalRep((void *)mountPoint);
dlPtr2->driveLetter = (WCHAR)-1;
dlPtr2->nextPtr = driveLetterLookup;
@@ -469,176 +415,6 @@ TclWinDriveLetterForVolMountPoint(
}
/*
- *---------------------------------------------------------------------------
- *
- * Tcl_WinUtfToTChar, Tcl_WinTCharToUtf --
- *
- * Convert between UTF-8 and Unicode when running Windows.
- *
- * On Mac and Unix, 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 Windows, 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.
- * This saves you the trouble of writing the
- * following type of fragment over and over:
- *
- * encoding <- Tcl_GetEncoding("unicode");
- * nativeBuffer <- UtfToExternal(encoding, utfBuffer);
- * Tcl_FreeEncoding(encoding);
- *
- * By convention, in Windows a WCHAR is a Unicode character. If you plan
- * on targeting a Unicode interface when running on Windows, these
- * functions should be used. If you plan on targetting a "char" oriented
- * function on Windows, 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.
- *
- * Side effects:
- * None.
- *
- *---------------------------------------------------------------------------
- */
-
-TCHAR *
-Tcl_WinUtfToTChar(
- const char *string, /* Source string in UTF-8. */
- int len, /* Source string length in bytes, or -1 for
- * strlen(). */
- Tcl_DString *dsPtr) /* Uninitialized or free DString in which the
- * converted string is stored. */
-{
-#if TCL_UTF_MAX > 4
- Tcl_UniChar ch = 0;
- TCHAR *w, *wString;
- const char *p, *end;
- int oldLength;
-#endif
-
- Tcl_DStringInit(dsPtr);
- if (!string) {
- return NULL;
- }
-#if TCL_UTF_MAX > 4
-
- if (len < 0) {
- len = strlen(string);
- }
-
- /*
- * Unicode string length in Tcl_UniChars will be <= UTF-8 string length in
- * bytes.
- */
-
- oldLength = Tcl_DStringLength(dsPtr);
-
- Tcl_DStringSetLength(dsPtr,
- oldLength + (int) ((len + 1) * sizeof(TCHAR)));
- wString = (TCHAR *) (Tcl_DStringValue(dsPtr) + oldLength);
-
- w = wString;
- p = string;
- end = string + len - 4;
- while (p < end) {
- p += TclUtfToUniChar(p, &ch);
- if (ch > 0xFFFF) {
- *w++ = (WCHAR) (0xD800 + ((ch -= 0x10000) >> 10));
- *w++ = (WCHAR) (0xDC00 | (ch & 0x3FF));
- } else {
- *w++ = ch;
- }
- }
- end += 4;
- while (p < end) {
- if (Tcl_UtfCharComplete(p, end-p)) {
- p += TclUtfToUniChar(p, &ch);
- } else {
- ch = UCHAR(*p++);
- }
- if (ch > 0xFFFF) {
- *w++ = (WCHAR) (0xD800 + ((ch -= 0x10000) >> 10));
- *w++ = (WCHAR) (0xDC00 | (ch & 0x3FF));
- } else {
- *w++ = ch;
- }
- }
- *w = '\0';
- Tcl_DStringSetLength(dsPtr,
- oldLength + ((char *) w - (char *) wString));
-
- return wString;
-#else
- return (TCHAR *)Tcl_UtfToUniCharDString(string, len, dsPtr);
-#endif
-}
-
-char *
-Tcl_WinTCharToUtf(
- const TCHAR *string, /* Source string in Unicode. */
- int len, /* Source string length in bytes, or -1 for
- * platform-specific string length. */
- Tcl_DString *dsPtr) /* Uninitialized or free DString in which the
- * converted string is stored. */
-{
-#if TCL_UTF_MAX > 4
- const WCHAR *w, *wEnd;
- char *p, *result;
- int oldLength, blen = 1;
-#endif
-
- Tcl_DStringInit(dsPtr);
- if (!string) {
- return NULL;
- }
- if (len < 0) {
- len = (int)wcslen((WCHAR *)string);
- } else {
- len /= 2;
- }
-#if TCL_UTF_MAX > 4
- oldLength = Tcl_DStringLength(dsPtr);
- Tcl_DStringSetLength(dsPtr, oldLength + (len + 1) * 4);
- result = Tcl_DStringValue(dsPtr) + oldLength;
-
- p = result;
- wEnd = (WCHAR *)string + len;
- for (w = (WCHAR *)string; w < wEnd; ) {
- if (!blen && ((*w & 0xFC00) != 0xDC00)) {
- /* Special case for handling high surrogates. */
- p += Tcl_UniCharToUtf(-1, p);
- }
- blen = Tcl_UniCharToUtf(*w, p);
- p += blen;
- if ((*w >= 0xD800) && (blen < 3)) {
- /* Indication that high surrogate is handled */
- blen = 0;
- }
- w++;
- }
- if (!blen) {
- /* Special case for handling high surrogates. */
- p += Tcl_UniCharToUtf(-1, p);
- }
- Tcl_DStringSetLength(dsPtr, oldLength + (p - result));
-
- return result;
-#else
- return Tcl_UniCharToUtfDString((Tcl_UniChar *)string, len, dsPtr);
-#endif
-}
-
-/*
*------------------------------------------------------------------------
*
* TclWinCPUID --
@@ -658,144 +434,23 @@ Tcl_WinTCharToUtf(
int
TclWinCPUID(
- unsigned int index, /* Which CPUID value to retrieve. */
- unsigned int *regsPtr) /* Registers after the CPUID. */
+ int index, /* Which CPUID value to retrieve. */
+ int *regsPtr) /* Registers after the CPUID. */
{
int status = TCL_ERROR;
#if defined(HAVE_CPUID_H)
- __get_cpuid(index, &regsPtr[0], &regsPtr[1], &regsPtr[2], &regsPtr[3]);
- status = TCL_OK;
-
-#elif defined(HAVE_INTRIN_H) && defined(_WIN64) && defined(HAVE_CPUID)
-
- __cpuid((int *)regsPtr, (int)index);
+ unsigned int *regs = (unsigned int *)regsPtr;
+ __get_cpuid(index, &regs[0], &regs[1], &regs[2], &regs[3]);
status = TCL_OK;
-#elif defined(__GNUC__) && defined(HAVE_CPUID)
-# if defined(_WIN64)
- /*
- * Execute the CPUID instruction with the given index, and store results
- * off 'regPtr'.
- */
-
- __asm__ __volatile__(
- /*
- * Do the CPUID instruction, and save the results in the 'regsPtr'
- * area.
- */
-
- "movl %[rptr], %%edi" "\n\t"
- "movl %[index], %%eax" "\n\t"
- "cpuid" "\n\t"
- "movl %%eax, 0x0(%%edi)" "\n\t"
- "movl %%ebx, 0x4(%%edi)" "\n\t"
- "movl %%ecx, 0x8(%%edi)" "\n\t"
- "movl %%edx, 0xC(%%edi)" "\n\t"
-
- :
- /* No outputs */
- :
- [index] "m" (index),
- [rptr] "m" (regsPtr)
- :
- "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
- status = TCL_OK;
-
-# else
-
- TCLEXCEPTION_REGISTRATION registration;
-
- /*
- * Execute the CPUID instruction with the given index, and store results
- * off 'regPtr'.
- */
-
- __asm__ __volatile__(
- /*
- * Construct an TCLEXCEPTION_REGISTRATION to protect the CPUID
- * instruction (early 486's don't have CPUID)
- */
-
- "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 TCLEXCEPTION_REGISTRATION on the chain
- */
-
- "movl %%edx, %%fs:0" "\n\t"
-
- /*
- * Do the CPUID instruction, and save the results in the 'regsPtr'
- * area.
- */
-
- "movl %[rptr], %%edi" "\n\t"
- "movl %[index], %%eax" "\n\t"
- "cpuid" "\n\t"
- "movl %%eax, 0x0(%%edi)" "\n\t"
- "movl %%ebx, 0x4(%%edi)" "\n\t"
- "movl %%ecx, 0x8(%%edi)" "\n\t"
- "movl %%edx, 0xC(%%edi)" "\n\t"
-
- /*
- * Come here on a normal exit. Recover the TCLEXCEPTION_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 TCLEXCEPTION_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
- * TCLEXCEPTION_REGISTRATION in case the stack is unbalanced.
- */
+#elif defined(_MSC_VER) && defined(_WIN64) && defined(HAVE_CPUID)
- "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 */
- :
- [index] "m" (index),
- [rptr] "m" (regsPtr),
- [registration] "m" (registration),
- [ok] "i" (TCL_OK),
- [error] "i" (TCL_ERROR)
- :
- "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
- status = registration.status;
-
-# endif /* !_WIN64 */
-#elif defined(_MSC_VER) && defined(HAVE_CPUID)
-# if defined(_WIN64)
-
- __cpuid(regsPtr, index);
+ __cpuid((int *)regsPtr, index);
status = TCL_OK;
-# elif defined (_M_IX86)
+#elif defined (_M_IX86)
/*
* Define a structure in the stack frame to hold the registers.
*/
@@ -842,7 +497,6 @@ TclWinCPUID(
/* do nothing */
}
-# endif
#else
(void)index;
(void)regsPtr;
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index 98cba33..393b48c 100644
--- a/win/tclWinChan.c
+++ b/win/tclWinChan.c
@@ -4,7 +4,7 @@
* Channel drivers for Windows channels based on files, command pipes and
* TCP sockets.
*
- * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright © 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.
@@ -26,7 +26,8 @@
#define FILE_TYPE_CONSOLE (FILE_TYPE_PIPE+2)
/*
- * The following structure contains per-instance data for a file based channel.
+ * The following structure contains per-instance data for a file based
+ * channel.
*/
typedef struct FileInfo {
@@ -44,7 +45,7 @@ typedef struct FileInfo {
* pending on the channel. */
} FileInfo;
-typedef struct ThreadSpecificData {
+typedef struct {
/*
* List of all file channels currently open.
*/
@@ -59,7 +60,7 @@ static Tcl_ThreadDataKey dataKey;
* events are generated.
*/
-typedef struct FileEvent {
+typedef struct {
Tcl_Event header; /* Information that is standard for all
* events. */
FileInfo *infoPtr; /* Pointer to file info structure. Note that
@@ -72,34 +73,33 @@ 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 FileClose2Proc(ClientData instanceData,
+static int FileBlockProc(void *instanceData, int mode);
+static void FileChannelExitHandler(void *clientData);
+static void FileCheckProc(void *clientData, int flags);
+static int FileCloseProc(void *instanceData,
Tcl_Interp *interp, int flags);
static int FileEventProc(Tcl_Event *evPtr, int flags);
-static int FileGetHandleProc(ClientData instanceData,
- int direction, ClientData *handlePtr);
+static int FileGetHandleProc(void *instanceData,
+ int direction, void **handlePtr);
+static int FileGetOptionProc(void *instanceData,
+ Tcl_Interp *interp, const char *optionName,
+ Tcl_DString *dsPtr);
static ThreadSpecificData *FileInit(void);
-static int FileInputProc(ClientData instanceData, char *buf,
+static int FileInputProc(void *instanceData, char *buf,
int toRead, int *errorCode);
-static int FileOutputProc(ClientData instanceData,
+static int FileOutputProc(void *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,
+static long long FileWideSeekProc(void *instanceData,
+ long long offset, int mode, int *errorCode);
+static void FileSetupProc(void *clientData, int flags);
+static void FileWatchProc(void *instanceData, int mask);
+static void FileThreadActionProc(void *instanceData,
int action);
-static int FileTruncateProc(ClientData instanceData,
- Tcl_WideInt length);
+static int FileTruncateProc(void *instanceData,
+ long long length);
static DWORD FileGetType(HANDLE handle);
static int NativeIsComPort(const WCHAR *nativeName);
-static Tcl_Channel OpenFileChannel(HANDLE handle, char *channelName,
+static Tcl_Channel OpenFileChannel(HANDLE handle, char *channelName,
int permissions, int appendMode);
/*
@@ -107,24 +107,67 @@ static Tcl_Channel OpenFileChannel(HANDLE handle, char *channelName,
*/
static const Tcl_ChannelType fileChannelType = {
- "file", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
- FileCloseProc, /* Close proc. */
- FileInputProc, /* Input proc. */
- FileOutputProc, /* Output proc. */
- FileSeekProc, /* Seek proc. */
+ "file",
+ TCL_CHANNEL_VERSION_5,
+ NULL, /* Deprecated. */
+ FileInputProc,
+ FileOutputProc,
+ NULL, /* Deprecated. */
NULL, /* Set option proc. */
- NULL, /* Get option proc. */
- FileWatchProc, /* Set up the notifier to watch the channel. */
- FileGetHandleProc, /* Get an OS handle from channel. */
- FileClose2Proc, /* close2proc. */
- FileBlockProc, /* Set blocking or non-blocking mode.*/
- NULL, /* flush proc. */
- NULL, /* handler proc. */
- FileWideSeekProc, /* Wide seek proc. */
- FileThreadActionProc, /* Thread action proc. */
- FileTruncateProc /* Truncate proc. */
+ FileGetOptionProc,
+ FileWatchProc,
+ FileGetHandleProc,
+ FileCloseProc,
+ FileBlockProc,
+ NULL, /* Flush proc. */
+ NULL, /* Bubbled event handler proc. */
+ FileWideSeekProc,
+ FileThreadActionProc,
+ FileTruncateProc
};
+
+/*
+ * General useful clarification macros.
+ */
+
+#define SET_FLAG(var, flag) ((var) |= (flag))
+#define CLEAR_FLAG(var, flag) ((var) &= ~(flag))
+#define TEST_FLAG(value, flag) (((value) & (flag)) != 0)
+
+/*
+ * The number of 100-ns intervals between the Windows system epoch (1601-01-01
+ * on the proleptic Gregorian calendar) and the Posix epoch (1970-01-01).
+ */
+
+#define POSIX_EPOCH_AS_FILETIME \
+ ((long long) 116444736 * (long long) 1000000000)
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclWinGenerateChannelName --
+ *
+ * This function generates names for channels.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Creates a new window and creates an exit handler.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+TclWinGenerateChannelName(
+ char channelName[], /* Buffer to accept the name. */
+ const char *channelTypeName,/* Name of type of channel. */
+ void *channelImpl) /* Pointer to channel implementation
+ * structure, used to generate a unique
+ * ID. */
+{
+ snprintf(channelName, 16 + TCL_INTEGER_SPACE, "%s%" TCL_Z_MODIFIER "x",
+ channelTypeName, (size_t) channelImpl);
+}
/*
*----------------------------------------------------------------------
@@ -146,7 +189,7 @@ static ThreadSpecificData *
FileInit(void)
{
ThreadSpecificData *tsdPtr =
- (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
+ (ThreadSpecificData *) TclThreadDataKeyGet(&dataKey);
if (tsdPtr == NULL) {
tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -176,10 +219,8 @@ FileInit(void)
static void
FileChannelExitHandler(
- ClientData clientData) /* Old window proc */
+ TCL_UNUSED(void *))
{
- (void)clientData;
-
Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL);
}
@@ -202,15 +243,14 @@ FileChannelExitHandler(
void
FileSetupProc(
- ClientData data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
FileInfo *infoPtr;
Tcl_Time blockTime = { 0, 0 };
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- (void)data;
- if (!(flags & TCL_FILE_EVENTS)) {
+ if (!TEST_FLAG(flags, TCL_FILE_EVENTS)) {
return;
}
@@ -246,15 +286,14 @@ FileSetupProc(
static void
FileCheckProc(
- ClientData data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
FileEvent *evPtr;
FileInfo *infoPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- (void)data;
- if (!(flags & TCL_FILE_EVENTS)) {
+ if (!TEST_FLAG(flags, TCL_FILE_EVENTS)) {
return;
}
@@ -265,9 +304,9 @@ FileCheckProc(
for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
- if (infoPtr->watchMask && !(infoPtr->flags & FILE_PENDING)) {
- infoPtr->flags |= FILE_PENDING;
- evPtr = (FileEvent *)ckalloc(sizeof(FileEvent));
+ if (infoPtr->watchMask && !TEST_FLAG(infoPtr->flags, FILE_PENDING)) {
+ SET_FLAG(infoPtr->flags, FILE_PENDING);
+ evPtr = (FileEvent *)Tcl_Alloc(sizeof(FileEvent));
evPtr->header.proc = FileEventProc;
evPtr->infoPtr = infoPtr;
Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
@@ -306,7 +345,7 @@ FileEventProc(
FileInfo *infoPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- if (!(flags & TCL_FILE_EVENTS)) {
+ if (!TEST_FLAG(flags, TCL_FILE_EVENTS)) {
return 0;
}
@@ -320,7 +359,7 @@ FileEventProc(
for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (fileEvPtr->infoPtr == infoPtr) {
- infoPtr->flags &= ~(FILE_PENDING);
+ CLEAR_FLAG(infoPtr->flags, FILE_PENDING);
Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask);
break;
}
@@ -346,7 +385,7 @@ FileEventProc(
static int
FileBlockProc(
- ClientData instanceData, /* Instance data for channel. */
+ void *instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
@@ -360,9 +399,9 @@ FileBlockProc(
*/
if (mode == TCL_MODE_NONBLOCKING) {
- infoPtr->flags |= FILE_ASYNC;
+ SET_FLAG(infoPtr->flags, FILE_ASYNC);
} else {
- infoPtr->flags &= ~(FILE_ASYNC);
+ CLEAR_FLAG(infoPtr->flags, FILE_ASYNC);
}
return 0;
}
@@ -370,7 +409,7 @@ FileBlockProc(
/*
*----------------------------------------------------------------------
*
- * FileCloseProc/FileClose2Proc --
+ * FileCloseProc --
*
* Closes the IO channel.
*
@@ -385,14 +424,18 @@ FileBlockProc(
static int
FileCloseProc(
- ClientData instanceData, /* Pointer to FileInfo structure. */
- Tcl_Interp *interp) /* Not used. */
+ void *instanceData, /* Pointer to FileInfo structure. */
+ TCL_UNUSED(Tcl_Interp *),
+ int flags)
{
FileInfo *fileInfoPtr = (FileInfo *)instanceData;
FileInfo *infoPtr;
ThreadSpecificData *tsdPtr;
int errorCode = 0;
- (void)interp;
+
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
/*
* Remove the file from the watch list.
@@ -411,7 +454,7 @@ FileCloseProc(
&& (GetStdHandle(STD_OUTPUT_HANDLE) != fileInfoPtr->handle)
&& (GetStdHandle(STD_ERROR_HANDLE) != fileInfoPtr->handle))) {
if (CloseHandle(fileInfoPtr->handle) == FALSE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
errorCode = errno;
}
}
@@ -435,99 +478,9 @@ FileCloseProc(
break;
}
}
- ckfree(fileInfoPtr);
+ Tcl_Free(fileInfoPtr);
return errorCode;
}
-
-static int
-FileClose2Proc(
- ClientData instanceData, /* Pointer to FileInfo structure. */
- Tcl_Interp *interp, /* Not used. */
- int flags)
-{
- if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) == 0) {
- return FileCloseProc(instanceData, interp);
- }
- return EINVAL;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * 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.
- *
- * Side effects:
- * 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. */
-{
- FileInfo *infoPtr = (FileInfo *)instanceData;
- LONG newPos, newPosHigh, oldPos, oldPosHigh;
- DWORD moveMethod;
-
- *errorCodePtr = 0;
- if (mode == SEEK_SET) {
- moveMethod = FILE_BEGIN;
- } else if (mode == SEEK_CUR) {
- moveMethod = FILE_CURRENT;
- } else {
- moveMethod = FILE_END;
- }
-
- /*
- * Save our current place in case we need to roll-back the seek.
- */
-
- oldPosHigh = 0;
- oldPos = (int)SetFilePointer(infoPtr->handle, 0, &oldPosHigh, FILE_CURRENT);
- if (oldPos == (LONG)INVALID_SET_FILE_POINTER) {
- DWORD winError = GetLastError();
-
- if (winError != NO_ERROR) {
- TclWinConvertError(winError);
- *errorCodePtr = errno;
- return -1;
- }
- }
-
- newPosHigh = (offset < 0 ? -1 : 0);
- newPos = (int)SetFilePointer(infoPtr->handle, offset, &newPosHigh, moveMethod);
- if (newPos == (LONG)INVALID_SET_FILE_POINTER) {
- DWORD winError = GetLastError();
-
- if (winError != NO_ERROR) {
- TclWinConvertError(winError);
- *errorCodePtr = errno;
- return -1;
- }
- }
-
- /*
- * Check for expressability in our return type, and roll-back otherwise.
- */
-
- if (newPosHigh != 0) {
- *errorCodePtr = EOVERFLOW;
- SetFilePointer(infoPtr->handle, oldPos, &oldPosHigh, FILE_BEGIN);
- return -1;
- }
- return (int) newPos;
-}
/*
*----------------------------------------------------------------------
@@ -547,10 +500,10 @@ FileSeekProc(
*----------------------------------------------------------------------
*/
-static Tcl_WideInt
+static long long
FileWideSeekProc(
- ClientData instanceData, /* File state. */
- Tcl_WideInt offset, /* Offset to seek to. */
+ void *instanceData, /* File state. */
+ long long offset, /* Offset to seek to. */
int mode, /* Relative to where should we seek? */
int *errorCodePtr) /* To store error code. */
{
@@ -567,19 +520,20 @@ FileWideSeekProc(
moveMethod = FILE_END;
}
- newPosHigh = Tcl_WideAsLong(offset >> 32);
- newPos = (int)SetFilePointer(infoPtr->handle, Tcl_WideAsLong(offset),
+ newPosHigh = (LONG)(offset >> 32);
+ newPos = SetFilePointer(infoPtr->handle, (LONG)offset,
&newPosHigh, moveMethod);
- if (newPos == (LONG)INVALID_SET_FILE_POINTER) {
+ if (newPos == (LONG) INVALID_SET_FILE_POINTER) {
DWORD winError = GetLastError();
if (winError != NO_ERROR) {
- TclWinConvertError(winError);
+ Tcl_WinConvertError(winError);
*errorCodePtr = errno;
return -1;
}
}
- return (((Tcl_WideInt)((unsigned)newPos)) | (Tcl_LongAsWide(newPosHigh) << 32));
+ return (((long long)((unsigned)newPos))
+ | ((long long)newPosHigh << 32));
}
/*
@@ -600,8 +554,8 @@ FileWideSeekProc(
static int
FileTruncateProc(
- ClientData instanceData, /* File state. */
- Tcl_WideInt length) /* Length to truncate at. */
+ void *instanceData, /* File state. */
+ long long length) /* Length to truncate at. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
LONG newPos, newPosHigh, oldPos, oldPosHigh;
@@ -611,11 +565,12 @@ FileTruncateProc(
*/
oldPosHigh = 0;
- oldPos = (int)SetFilePointer(infoPtr->handle, 0, &oldPosHigh, FILE_CURRENT);
- if (oldPos == (LONG)INVALID_SET_FILE_POINTER) {
+ oldPos = SetFilePointer(infoPtr->handle, 0, &oldPosHigh, FILE_CURRENT);
+ if (oldPos == (LONG) INVALID_SET_FILE_POINTER) {
DWORD winError = GetLastError();
+
if (winError != NO_ERROR) {
- TclWinConvertError(winError);
+ Tcl_WinConvertError(winError);
return errno;
}
}
@@ -624,13 +579,14 @@ FileTruncateProc(
* Move to where we want to truncate
*/
- newPosHigh = Tcl_WideAsLong(length >> 32);
- newPos = (int)SetFilePointer(infoPtr->handle, Tcl_WideAsLong(length),
+ newPosHigh = (LONG)(length >> 32);
+ newPos = SetFilePointer(infoPtr->handle, (LONG)length,
&newPosHigh, FILE_BEGIN);
- if (newPos == (LONG)INVALID_SET_FILE_POINTER) {
+ if (newPos == (LONG) INVALID_SET_FILE_POINTER) {
DWORD winError = GetLastError();
+
if (winError != NO_ERROR) {
- TclWinConvertError(winError);
+ Tcl_WinConvertError(winError);
return errno;
}
}
@@ -641,7 +597,7 @@ FileTruncateProc(
*/
if (!SetEndOfFile(infoPtr->handle)) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return errno;
}
@@ -674,7 +630,7 @@ FileTruncateProc(
static int
FileInputProc(
- ClientData instanceData, /* File state. */
+ void *instanceData, /* File state. */
char *buf, /* Where to store data read. */
int bufSize, /* Num bytes available in buffer. */
int *errorCode) /* Where to store error code. */
@@ -685,9 +641,9 @@ FileInputProc(
*errorCode = 0;
/*
- * TODO: This comment appears to be out of date. We *do* have a
- * console driver, over in tclWinConsole.c. After some Windows
- * developer confirms, this comment should be revised.
+ * TODO: This comment appears to be out of date. We *do* have a console
+ * driver, over in tclWinConsole.c. After some Windows developer confirms,
+ * this comment should be revised.
*
* 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
@@ -701,7 +657,7 @@ FileInputProc(
return (int)bytesRead;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
*errorCode = errno;
if (errno == EPIPE) {
return 0;
@@ -729,7 +685,7 @@ FileInputProc(
static int
FileOutputProc(
- ClientData instanceData, /* File state. */
+ void *instanceData, /* File state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCode) /* Where to store error code. */
@@ -744,13 +700,13 @@ FileOutputProc(
* seek to the end of the file before writing the current buffer.
*/
- if (infoPtr->flags & FILE_APPEND) {
+ if (TEST_FLAG(infoPtr->flags, FILE_APPEND)) {
SetFilePointer(infoPtr->handle, 0, NULL, FILE_END);
}
if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite,
&bytesWritten, (LPOVERLAPPED) NULL) == FALSE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
*errorCode = errno;
return -1;
}
@@ -776,7 +732,7 @@ FileOutputProc(
static void
FileWatchProc(
- ClientData instanceData, /* File state. */
+ void *instanceData, /* File state. */
int mask) /* What events to watch for; OR-ed combination
* of TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
@@ -815,18 +771,192 @@ FileWatchProc(
static int
FileGetHandleProc(
- ClientData instanceData, /* The file state. */
+ void *instanceData, /* The file state. */
int direction, /* TCL_READABLE or TCL_WRITABLE */
- ClientData *handlePtr) /* Where to store the handle. */
+ void **handlePtr) /* Where to store the handle. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
- if (direction & infoPtr->validMask) {
- *handlePtr = (ClientData) infoPtr->handle;
- return TCL_OK;
- } else {
+ if (!TEST_FLAG(direction, infoPtr->validMask)) {
return TCL_ERROR;
}
+
+ *handlePtr = (void *)infoPtr->handle;
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileGetOptionProc --
+ *
+ * Gets an option associated with an open file. 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. Sets error message if needed
+ * (by calling Tcl_BadChannelOption).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline ULONGLONG
+CombineDwords(
+ DWORD hi,
+ DWORD lo)
+{
+ ULARGE_INTEGER converter;
+
+ converter.LowPart = lo;
+ converter.HighPart = hi;
+ return converter.QuadPart;
+}
+
+static inline time_t
+ToCTime(
+ FILETIME fileTime) /* UTC time */
+{
+ LARGE_INTEGER convertedTime;
+
+ convertedTime.LowPart = fileTime.dwLowDateTime;
+ convertedTime.HighPart = (LONG) fileTime.dwHighDateTime;
+
+ return (time_t) ((convertedTime.QuadPart -
+ (long long) POSIX_EPOCH_AS_FILETIME) / (long long) 10000000);
+}
+
+static Tcl_Obj *
+StatOpenFile(
+ FileInfo *infoPtr)
+{
+ DWORD attr;
+ int dev, nlink = 1;
+ unsigned short mode;
+ unsigned long long size, inode;
+ long long atime, ctime, mtime;
+ BY_HANDLE_FILE_INFORMATION data;
+ Tcl_Obj *dictObj;
+
+ if (GetFileInformationByHandle(infoPtr->handle, &data) != TRUE) {
+ Tcl_SetErrno(ENOENT);
+ return NULL;
+ }
+
+ atime = ToCTime(data.ftLastAccessTime);
+ mtime = ToCTime(data.ftLastWriteTime);
+ ctime = ToCTime(data.ftCreationTime);
+ attr = data.dwFileAttributes;
+ size = CombineDwords(data.nFileSizeHigh, data.nFileSizeLow);
+ 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 = CombineDwords(data.nFileIndexHigh, data.nFileIndexLow);
+
+ dev = data.dwVolumeSerialNumber;
+
+ /*
+ * Note that this code has no idea whether the file can be executed.
+ */
+
+ mode = (attr & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR|S_IEXEC : S_IFREG;
+ mode |= (attr & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD|S_IWRITE;
+ mode |= (mode & (S_IREAD|S_IWRITE|S_IEXEC)) >> 3;
+ mode |= (mode & (S_IREAD|S_IWRITE|S_IEXEC)) >> 6;
+
+ /*
+ * We don't construct a Tcl_StatBuf; we're using the info immediately.
+ */
+
+ TclNewObj(dictObj);
+#define STORE_ELEM(name, value) TclDictPut(NULL, dictObj, name, value)
+
+ STORE_ELEM("dev", Tcl_NewWideIntObj((long) dev));
+ STORE_ELEM("ino", Tcl_NewWideIntObj((long long) inode));
+ STORE_ELEM("nlink", Tcl_NewIntObj(nlink));
+ STORE_ELEM("uid", Tcl_NewIntObj(0));
+ STORE_ELEM("gid", Tcl_NewIntObj(0));
+ STORE_ELEM("size", Tcl_NewWideIntObj((long long) size));
+ STORE_ELEM("atime", Tcl_NewWideIntObj(atime));
+ STORE_ELEM("mtime", Tcl_NewWideIntObj(mtime));
+ STORE_ELEM("ctime", Tcl_NewWideIntObj(ctime));
+ STORE_ELEM("mode", Tcl_NewWideIntObj(mode));
+
+ /*
+ * Windows only has files and directories, as far as we're concerned.
+ * Anything else and we definitely couldn't have got here anyway.
+ */
+ if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+ STORE_ELEM("type", Tcl_NewStringObj("directory", TCL_INDEX_NONE));
+ } else {
+ STORE_ELEM("type", Tcl_NewStringObj("file", TCL_INDEX_NONE));
+ }
+#undef STORE_ELEM
+
+ return dictObj;
+}
+
+static int
+FileGetOptionProc(
+ void *instanceData, /* The file state. */
+ Tcl_Interp *interp, /* For error reporting. */
+ const char *optionName, /* What option to read, or NULL for all. */
+ Tcl_DString *dsPtr) /* Where to write the value read. */
+{
+ FileInfo *infoPtr = (FileInfo *)instanceData;
+ int valid = 0; /* Flag if valid option parsed. */
+ int len;
+
+ if (optionName == NULL) {
+ len = 0;
+ valid = 1;
+ } else {
+ len = strlen(optionName);
+ }
+
+ /*
+ * Get option -stat
+ * Option is readonly and returned by [fconfigure chan -stat] but not
+ * returned by [fconfigure chan] without explicit option name.
+ */
+
+ if ((len > 1) && (strncmp(optionName, "-stat", len) == 0)) {
+ Tcl_Obj *dictObj = StatOpenFile(infoPtr);
+ const char *dictContents;
+ Tcl_Size dictLength;
+
+ if (dictObj == NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read file channel status: %s",
+ Tcl_PosixError(interp)));
+ return TCL_ERROR;
+ }
+
+ /*
+ * Transfer dictionary to the DString. Note that we don't do this as
+ * an element as this is an option that can't be retrieved with a
+ * general probe.
+ */
+
+ dictContents = TclGetStringFromObj(dictObj, &dictLength);
+ Tcl_DStringAppend(dsPtr, dictContents, dictLength);
+ Tcl_DecrRefCount(dictObj);
+ return TCL_OK;
+ }
+
+ if (valid) {
+ return TCL_OK;
+ }
+ return Tcl_BadChannelOption(interp, optionName,
+ "stat");
}
/*
@@ -866,30 +996,27 @@ TclpOpenFileChannel(
nativeName = (const WCHAR *)Tcl_FSGetNativePath(pathPtr);
if (nativeName == NULL) {
- if (interp != (Tcl_Interp *) NULL) {
+ if (interp) {
/*
* We need this just to ensure we return the correct error messages under
- * some circumstances (relative paths only), so because the normalization
+ * some circumstances (relative paths only), so because the normalization
* is very expensive, don't invoke it for native or absolute paths.
- * Note: since paths starting with ~ are absolute, it also considers tilde expansion,
- * (proper error message of tests *io-40.17 "tilde substitution in open")
+ * Note: since paths starting with ~ are relative in 9.0 for windows,
+ * it doesn't need to consider tilde expansion (in opposite to 8.x).
*/
if (
(
- (
!TclFSCwdIsNative() &&
(Tcl_FSGetPathType(pathPtr) != TCL_PATH_ABSOLUTE)
- ) ||
- (*TclGetString(pathPtr) == '~') /* possible tilde expansion */
) &&
Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL
) {
return NULL;
}
- Tcl_AppendResult(interp, "couldn't open \"",
- TclGetString(pathPtr), "\": filename is invalid on this platform",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't open \"%s\": filename is invalid on this platform",
+ TclGetString(pathPtr)));
}
return NULL;
}
@@ -937,39 +1064,40 @@ TclpOpenFileChannel(
}
/*
- * [2413550] Avoid double-open of serial ports on Windows
- * Special handling for Windows serial ports by a "name-hint"
- * to directly open it with the OVERLAPPED flag set.
+ * [2413550] Avoid double-open of serial ports on Windows. Special
+ * handling for Windows serial ports by a "name-hint" to directly open it
+ * with the OVERLAPPED flag set.
*/
- if( NativeIsComPort(nativeName) ) {
-
+ if (NativeIsComPort(nativeName)) {
handle = TclWinSerialOpen(INVALID_HANDLE_VALUE, nativeName, accessMode);
if (handle == INVALID_HANDLE_VALUE) {
- TclWinConvertError(GetLastError());
- if (interp != (Tcl_Interp *) NULL) {
- Tcl_AppendResult(interp, "couldn't open serial \"",
- TclGetString(pathPtr), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_WinConvertError(GetLastError());
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't open serial \"%s\": %s",
+ TclGetString(pathPtr), Tcl_PosixError(interp)));
}
return NULL;
}
/*
- * For natively-named Windows serial ports we are done.
- */
+ * For natively-named Windows serial ports we are done.
+ */
+
channel = TclWinOpenSerialChannel(handle, channelName,
channelPermissions);
return channel;
}
+
/*
* If the file is being created, get the file attributes from the
* permissions argument, else use the existing file attributes.
*/
- if (mode & O_CREAT) {
- if (permissions & S_IWRITE) {
+ if (TEST_FLAG(mode, O_CREAT)) {
+ if (TEST_FLAG(permissions, S_IWRITE)) {
flags = FILE_ATTRIBUTE_NORMAL;
} else {
flags = FILE_ATTRIBUTE_READONLY;
@@ -998,10 +1126,11 @@ TclpOpenFileChannel(
DWORD err = GetLastError();
if ((err & 0xFFFFL) == ERROR_OPEN_FAILED) {
- err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND;
+ err = TEST_FLAG(mode, O_CREAT) ? ERROR_FILE_EXISTS
+ : ERROR_FILE_NOT_FOUND;
}
- TclWinConvertError(err);
- if (interp != (Tcl_Interp *) NULL) {
+ Tcl_WinConvertError(err);
+ if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't open \"%s\": %s",
TclGetString(pathPtr), Tcl_PosixError(interp)));
@@ -1014,9 +1143,9 @@ TclpOpenFileChannel(
switch (FileGetType(handle)) {
case FILE_TYPE_SERIAL:
/*
- * Natively named serial ports "com1-9", "\\\\.\\comXX" are
- * already done with the code above.
- * Here we handle all other serial port names.
+ * Natively named serial ports "com1-9", "\\\\.\\comXX" are already
+ * done with the code above. Here we handle all other serial port
+ * names.
*
* Reopen channel for OVERLAPPED operation. Normally this shouldn't
* fail, because the channel exists.
@@ -1024,8 +1153,8 @@ TclpOpenFileChannel(
handle = TclWinSerialOpen(handle, nativeName, accessMode);
if (handle == INVALID_HANDLE_VALUE) {
- TclWinConvertError(GetLastError());
- if (interp != (Tcl_Interp *) NULL) {
+ Tcl_WinConvertError(GetLastError());
+ if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't reopen serial \"%s\": %s",
TclGetString(pathPtr), Tcl_PosixError(interp)));
@@ -1040,10 +1169,10 @@ TclpOpenFileChannel(
channelPermissions);
break;
case FILE_TYPE_PIPE:
- if (channelPermissions & TCL_READABLE) {
+ if (TEST_FLAG(channelPermissions, TCL_READABLE)) {
readFile = TclWinMakeFile(handle);
}
- if (channelPermissions & TCL_WRITABLE) {
+ if (TEST_FLAG(channelPermissions, TCL_WRITABLE)) {
writeFile = TclWinMakeFile(handle);
}
channel = TclpCreateCommandChannel(readFile, writeFile, NULL, 0, NULL);
@@ -1052,7 +1181,8 @@ TclpOpenFileChannel(
case FILE_TYPE_DISK:
case FILE_TYPE_UNKNOWN:
channel = OpenFileChannel(handle, channelName,
- channelPermissions, (mode & O_APPEND) ? FILE_APPEND : 0);
+ channelPermissions,
+ TEST_FLAG(mode, O_APPEND) ? FILE_APPEND : 0);
break;
default:
@@ -1066,7 +1196,7 @@ TclpOpenFileChannel(
"couldn't open \"%s\": bad file type",
TclGetString(pathPtr)));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "CHANNEL", "BAD_TYPE",
- NULL);
+ (char *)NULL);
break;
}
@@ -1091,7 +1221,7 @@ TclpOpenFileChannel(
Tcl_Channel
Tcl_MakeFileChannel(
- ClientData rawHandle, /* OS level handle */
+ void *rawHandle, /* OS level handle */
int mode) /* OR'ed combination of TCL_READABLE and
* TCL_WRITABLE to indicate file mode. */
{
@@ -1105,7 +1235,7 @@ Tcl_MakeFileChannel(
TclFile readFile = NULL, writeFile = NULL;
BOOL result;
- if (mode == 0) {
+ if ((mode & (TCL_READABLE|TCL_WRITABLE)) == 0) {
return NULL;
}
@@ -1117,10 +1247,10 @@ Tcl_MakeFileChannel(
channel = TclWinOpenConsoleChannel(handle, channelName, mode);
break;
case FILE_TYPE_PIPE:
- if (mode & TCL_READABLE) {
+ if (TEST_FLAG(mode, TCL_READABLE)) {
readFile = TclWinMakeFile(handle);
}
- if (mode & TCL_WRITABLE) {
+ if (TEST_FLAG(mode, TCL_WRITABLE)) {
writeFile = TclWinMakeFile(handle);
}
channel = TclpCreateCommandChannel(readFile, writeFile, NULL, 0, NULL);
@@ -1340,9 +1470,8 @@ TclpGetDefaultStdChannel(
*/
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);
+ Tcl_CloseEx(NULL, channel, 0);
return (Tcl_Channel) NULL;
}
return channel;
@@ -1388,11 +1517,12 @@ OpenFileChannel(
for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
if (infoPtr->handle == (HANDLE) handle) {
- return (permissions==infoPtr->validMask) ? infoPtr->channel : NULL;
+ return ((permissions & (TCL_READABLE|TCL_WRITABLE|TCL_EXCEPTION))==infoPtr->validMask)
+ ? infoPtr->channel : NULL;
}
}
- infoPtr = (FileInfo *)ckalloc(sizeof(FileInfo));
+ infoPtr = (FileInfo *)Tcl_Alloc(sizeof(FileInfo));
/*
* TIP #218. Removed the code inserting the new structure into the global
@@ -1401,13 +1531,12 @@ OpenFileChannel(
*/
infoPtr->nextPtr = NULL;
- infoPtr->validMask = permissions;
+ infoPtr->validMask = permissions & (TCL_READABLE|TCL_WRITABLE|TCL_EXCEPTION);
infoPtr->watchMask = 0;
infoPtr->flags = appendMode;
infoPtr->handle = handle;
infoPtr->dirty = 0;
- snprintf(channelName, 16 + TCL_INTEGER_SPACE, "file%" TCL_Z_MODIFIER "x", (size_t) infoPtr);
-
+ TclWinGenerateChannelName(channelName, "file", infoPtr);
infoPtr->channel = Tcl_CreateChannel(&fileChannelType, channelName,
infoPtr, permissions);
@@ -1417,7 +1546,6 @@ OpenFileChannel(
*/
Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
- Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
return infoPtr->channel;
}
@@ -1479,11 +1607,11 @@ TclWinFlushDirtyChannels(void)
static void
FileThreadActionProc(
- ClientData instanceData,
+ void *instanceData,
int action)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- FileInfo *infoPtr = ( FileInfo *)instanceData;
+ FileInfo *infoPtr = (FileInfo *)instanceData;
if (action == TCL_CHANNEL_THREAD_INSERT) {
infoPtr->nextPtr = tsdPtr->firstFilePtr;
@@ -1567,10 +1695,11 @@ FileGetType(
*
* NativeIsComPort --
*
- * Determines if a path refers to a Windows serial port.
- * A simple and efficient solution is to use a "name hint" to detect
- * COM ports by their filename instead of resorting to a syscall
- * to detect serialness after the fact.
+ * Determines if a path refers to a Windows serial port. A simple and
+ * efficient solution is to use a "name hint" to detect COM ports by
+ * their filename instead of resorting to a syscall to detect serialness
+ * after the fact.
+ *
* The following patterns cover common serial port names:
* COM[1-9]
* \\.\COM[0-9]+
@@ -1586,18 +1715,18 @@ NativeIsComPort(
const WCHAR *nativePath) /* Path of file to access, native encoding. */
{
const WCHAR *p = (const WCHAR *) nativePath;
- int i, len = (int)wcslen(p);
+ size_t i, len = wcslen(p);
/*
* 1. Look for com[1-9]:?
*/
- if ( (len == 4) && (_wcsnicmp(p, L"com", 3) == 0) ) {
+ if ((len == 4) && (_wcsnicmp(p, L"com", 3) == 0)) {
/*
- * The 4th character must be a digit 1..9
- */
+ * The 4th character must be a digit 1..9
+ */
- if ( (p[3] < L'1') || (p[3] > L'9') ) {
+ if ((p[3] < '1') || (p[3] > '9')) {
return 0;
}
return 1;
@@ -1609,11 +1738,11 @@ NativeIsComPort(
if ((len >= 8) && (_wcsnicmp(p, L"\\\\.\\com", 7) == 0)) {
/*
- * Charaters 8..end must be a digits 0..9
- */
+ * Charaters 8..end must be a digits 0..9
+ */
- for ( i=7; i<len; i++ ) {
- if ( (p[i] < '0') || (p[i] > '9') ) {
+ for (i=7; i<len; i++) {
+ if ((p[i] < '0') || (p[i] > '9')) {
return 0;
}
}
diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c
index 0bfa5a5..9e9f6c0 100644
--- a/win/tclWinConsole.c
+++ b/win/tclWinConsole.c
@@ -2,130 +2,221 @@
* tclWinConsole.c --
*
* This file implements the Windows-specific console functions, and the
- * "console" channel driver.
+ * "console" channel driver. Windows 7 or later required.
*
- * Copyright (c) 1999 by Scriptics Corp.
+ * Copyright © 2022 Ashok P. Nadkarni
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#ifdef TCL_CONSOLE_DEBUG
+#undef NDEBUG /* Enable asserts */
+#endif
+
#include "tclWinInt.h"
+#include <assert.h>
+#include <ctype.h>
/*
- * The following variable is used to tell whether this module has been
- * initialized.
+ * A general note on the design: The console channel driver differs from
+ * most other drivers in the following respects:
+ *
+ * - There can be at most 3 console handles at any time since Windows does
+ * support allocation of more than one console (with three handles
+ * corresponding to stdin, stdout, stderr)
+ *
+ * - Consoles are created / inherited at process startup. There is currently
+ * no way in Tcl to programmatically create a console. Even if these were
+ * added the above Windows limitation would still apply.
+ *
+ * - Unlike files, sockets etc. where there is a one-to-one
+ * correspondence between Tcl channels and operating system handles,
+ * std* channels are shared amongst threads which means there can be
+ * multiple Tcl channels corresponding to a single console handle.
+ *
+ * - Even with multiple threads, more than one file event handler is
+ * unlikely. It does not make sense for multiple threads to register
+ * handlers for stdin because the input would be randomly fragmented amongst
+ * the threads.
+ *
+ * Various design factors are driven by the above, e.g. use of lists instead
+ * of hash tables (at most 3 console handles) and use of global instead of
+ * per thread queues which simplifies lock management particularly because
+ * thread-console relation is not one-one and is likely more performant as
+ * well with fewer locks needing to be obtained.
+ *
+ * Some additional design notes/reminders for the future:
+ *
+ * Aligned, synchronous reads are done directly by interpreter thread.
+ * Unaligned or asynchronous reads are done through the reader thread.
+ *
+ * The reader thread does not read ahead. That is, it will not post a read
+ * until some interpreter thread is actually requesting a read. This is
+ * because an interpreter may (for example) turn off echo for passwords and
+ * the read ahead would come in the way of that.
+ *
+ * If multiple threads are reading from stdin, the input is sprayed in
+ * random fashion. This is not good application design and hence no plan to
+ * address this (not clear what should be done even in theory).
+ *
+ * For output, we do not restrict all output to the console writer threads.
+ * See ConsoleOutputProc for the conditions.
+ *
+ * Locks are never held when calling the ReadConsole/WriteConsole API's
+ * since they may block.
*/
-static int initialized = 0;
+static int gInitialized = 0;
/*
- * The consoleMutex locks around access to the initialized variable, and it is
- * used to protect background threads from being terminated while they are
- * using APIs that hold locks.
+ * INPUT_BUFFER_SIZE is size of buffer passed to ReadConsole in bytes.
+ * Note that ReadConsole will only allow reading of line lengths up to the
+ * max of 256 and buffer size passed to it. So dropping this below 512
+ * means user can type at most 256 chars.
*/
-
-TCL_DECLARE_MUTEX(consoleMutex)
+#ifndef INPUT_BUFFER_SIZE
+#define INPUT_BUFFER_SIZE 8192 /* In bytes, so 4096 chars */
+#endif
/*
- * Bit masks used in the flags field of the ConsoleInfo structure below.
+ * CONSOLE_BUFFER_SIZE is size of storage used in ring buffers.
+ * In theory, at least sizeof(WCHAR) but note the Tcl channel bug
+ * https://core.tcl-lang.org/tcl/tktview/b3977d199b08e3979a8da970553d5209b3042e9c
+ * will cause failures in test suite if close to max input line in the suite.
*/
-
-#define CONSOLE_PENDING (1<<0) /* Message is pending in the queue. */
-#define CONSOLE_ASYNC (1<<1) /* Channel is non-blocking. */
+#ifndef CONSOLE_BUFFER_SIZE
+#define CONSOLE_BUFFER_SIZE 8192 /* In bytes */
+#endif
/*
- * Bit masks used in the sharedFlags field of the ConsoleInfo structure below.
+ * Ring buffer for storing data. Actual data is from bufPtr[start]:bufPtr[size-1]
+ * and bufPtr[0]:bufPtr[length - (size-start)].
*/
-
-#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_BUFFER_SIZE (8*1024)
+typedef struct RingBuffer {
+ char *bufPtr; /* Pointer to buffer storage */
+ Tcl_Size capacity; /* Size of the buffer in RingBufferChar */
+ Tcl_Size start; /* Start of the data within the buffer. */
+ Tcl_Size length; /* Number of RingBufferChar*/
+} RingBuffer;
+
+#define RingBufferLength(ringPtr_) \
+ ((ringPtr_)->length)
+#define RingBufferHasFreeSpace(ringPtr_) \
+ ((ringPtr_)->length < (ringPtr_)->capacity)
+#define RINGBUFFER_ASSERT(ringPtr_) \
+ assert(RingBufferCheck(ringPtr_))
/*
- * Structure containing handles associated with one of the special console
- * threads.
+ * The Win32 console API does not support non-blocking I/O in any form. Thus
+ * the actual calls are made on a separate thread. Moreover, separate
+ * threads are needed for each handle because (for example) blocking on user
+ * input on stdin should not prevent output to stdout when non-blocking i/o
+ * is configured at the script level.
+ *
+ * In the input (e.g. stdin) case, the console stdin thread is the producer
+ * writing to the buffer ring buffer. The Tcl interpreter threads are the
+ * consumer. For the output (e.g. stdout/stderr) case, the Tcl interpreter
+ * are the producers while the console stdout/stderr threads are the
+ * consumers.
+ *
+ * Consoles are identified purely by handles and multiple threads may open
+ * them (as stdin/stdout/stderr are shared).
+ *
+ * Note on reference counting - a ConsoleHandleInfo instance has multiple
+ * references to it - one each from every channel that is attached to it
+ * plus one from the console thread itself which also serves as the reference
+ * from gConsoleHandleInfoList.
*/
-
-typedef struct ConsoleThreadInfo {
- HANDLE thread; /* Handle to reader or writer thread. */
- HANDLE readyEvent; /* Manual-reset event to signal _to_ the main
- * thread when the worker thread has finished
- * waiting for its normal work to happen. */
- TclPipeThreadInfo *TI; /* Thread info structure of writer and reader. */
-} ConsoleThreadInfo;
+typedef struct ConsoleHandleInfo {
+ struct ConsoleHandleInfo *nextPtr; /* Process-global list of consoles */
+ HANDLE console; /* Console handle */
+ HANDLE consoleThread; /* Handle to thread doing actual i/o on the
+ * console */
+ SRWLOCK lock; /* Controls access to this structure. Cheaper
+ * than CRITICAL_SECTION but note does not
+ * support recursive locks or Try* style
+ * attempts. */
+ CONDITION_VARIABLE consoleThreadCV;/* For awakening console thread */
+ CONDITION_VARIABLE interpThreadCV; /* For awakening interpthread(s) */
+ RingBuffer buffer; /* Buffer for data transferred between console
+ * threads and Tcl threads. For input consoles,
+ * written by the console thread and read by Tcl
+ * threads. The converse for output threads */
+ DWORD initMode; /* Initial console mode. */
+ DWORD lastError; /* An error caused by the last background
+ * operation. Set to 0 if no error has been
+ * detected. */
+ int numRefs; /* See comments above */
+ int permissions; /* TCL_READABLE for input consoles,
+ * TCL_WRITABLE for output. Only one or the
+ * other can be set. */
+ int flags; /* State flags */
+} ConsoleHandleInfo;
+
+enum ConsoleHandleInfoFlags {
+ CONSOLE_DATA_AWAITED = 1 /* An interpreter is awaiting data */
+};
/*
* This structure describes per-instance data for a console based channel.
+ *
+ * Note on locking - this structure has no locks because it is accessed
+ * only from the thread owning channel EXCEPT when a console traverses it
+ * looking for a channel that is watching for events on the console. Even
+ * in that case, no locking is required because that access is only under
+ * the gConsoleLock lock which prevents the channel from being removed from
+ * the gWatchingChannelList which in turn means it will not be deallocated
+ * from under the console thread. Access to individual fields does not need
+ * to be controlled because
+ * - the console thread does not write to any fields
+ * - changes to the nextWatchingChannelPtr field
+ * - changes to other fields do not matter because after being read for
+ * queueing events, they are verified again when the event is received
+ * in the interpreter thread (since they could have changed anyways while
+ * the event was in-flight on the event queue)
+ *
+ * Note on reference counting - a structure instance may be referenced from
+ * three places:
+ * - the Tcl channel subsystem. This reference is created when on channel
+ * opening and dropped on channel close. This also covers the reference
+ * from gWatchingChannelList since queueing / dequeuing from that list
+ * happens in conjunction with channel operations.
+ * - the Tcl event queue entries. This reference is added when the event
+ * is queued and dropped on receipt.
*/
-
-typedef struct ConsoleInfo {
- HANDLE handle;
- int type;
- struct ConsoleInfo *nextPtr;/* Pointer to next registered console. */
+typedef struct ConsoleChannelInfo {
+ HANDLE handle; /* Console handle */
+ Tcl_ThreadId threadId; /* Id of owning thread */
+ struct ConsoleChannelInfo *nextWatchingChannelPtr;
+ /* Pointer to next channel watching events. */
Tcl_Channel channel; /* Pointer to channel structure. */
- int validMask; /* OR'ed combination of TCL_READABLE,
+ DWORD initMode; /* Initial console mode. */
+ int numRefs; /* See comments above */
+ int permissions; /* 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. */
- Tcl_ThreadId threadId; /* Thread to which events should be reported.
- * This value is used by the reader/writer
- * threads. */
- ConsoleThreadInfo writer; /* A specialized thread for handling
- * asynchronous writes to the console; the
- * waiting starts when a control event is sent,
- * and a reset event is sent back to the main
- * thread when the write is done. */
- ConsoleThreadInfo reader; /* A specialized thread for handling
- * asynchronous reads from the console; the
- * waiting starts when a control event is sent,
- * and a reset event is sent back to the main
- * thread when input is available. */
- 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 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. */
- char buffer[CONSOLE_BUFFER_SIZE];
- /* 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.
- */
+ int flags; /* State flags */
+} ConsoleChannelInfo;
- ConsoleInfo *firstConsolePtr;
-} ThreadSpecificData;
-
-static Tcl_ThreadDataKey dataKey;
+enum ConsoleChannelInfoFlags {
+ CONSOLE_EVENT_QUEUED = 1, /* Notification event already queued */
+ CONSOLE_ASYNC = 2, /* Channel is non-blocking. */
+ CONSOLE_READ_OPS = 4 /* Channel supports read-related ops. */
+};
/*
* The following structure is what is added to the Tcl event queue when
* console events are generated.
*/
-typedef struct ConsoleEvent {
- Tcl_Event header; /* Information that is standard for all
- * events. */
- ConsoleInfo *infoPtr; /* Pointer to console info structure. Note
+typedef struct {
+ Tcl_Event header; /* Information that is standard for all events. */
+ ConsoleChannelInfo *chanInfoPtr;
+ /* Pointer to console info structure. Note
* that we still have to verify that the
* console exists before dereferencing this
* pointer. */
@@ -135,35 +226,84 @@ typedef struct ConsoleEvent {
* Declarations for functions used only in this file.
*/
-static int ConsoleBlockModeProc(ClientData instanceData,
- int mode);
-static void ConsoleCheckProc(ClientData clientData, int flags);
-static int ConsoleCloseProc(ClientData instanceData,
- Tcl_Interp *interp);
-static int ConsoleClose2Proc(ClientData instanceData,
+static int ConsoleBlockModeProc(void *instanceData, int mode);
+static void ConsoleCheckProc(void *clientData, int flags);
+static int ConsoleCloseProc(void *instanceData,
Tcl_Interp *interp, int flags);
static int ConsoleEventProc(Tcl_Event *evPtr, int flags);
-static void ConsoleExitHandler(ClientData clientData);
-static int ConsoleGetHandleProc(ClientData instanceData,
- int direction, ClientData *handlePtr);
+static void ConsoleExitHandler(void *clientData);
+static int ConsoleGetHandleProc(void *instanceData,
+ int direction, void **handlePtr);
+static int ConsoleGetOptionProc(void *instanceData,
+ Tcl_Interp *interp, const char *optionName,
+ Tcl_DString *dsPtr);
static void ConsoleInit(void);
-static int ConsoleInputProc(ClientData instanceData, char *buf,
+static int ConsoleInputProc(void *instanceData, char *buf,
int toRead, int *errorCode);
-static int ConsoleOutputProc(ClientData instanceData,
+static int ConsoleOutputProc(void *instanceData,
const char *buf, int toWrite, int *errorCode);
+static int ConsoleSetOptionProc(void *instanceData,
+ Tcl_Interp *interp, const char *optionName,
+ const char *value);
+static void ConsoleSetupProc(void *clientData, int flags);
+static void ConsoleWatchProc(void *instanceData, int mask);
+static void ProcExitHandler(void *clientData);
+static void ConsoleThreadActionProc(void *instanceData, int action);
+static DWORD ReadConsoleChars(HANDLE hConsole, WCHAR *lpBuffer,
+ Tcl_Size nChars, Tcl_Size *nCharsReadPtr);
+static DWORD WriteConsoleChars(HANDLE hConsole,
+ const WCHAR *lpBuffer, Tcl_Size nChars,
+ Tcl_Size *nCharsWritten);
+static void RingBufferInit(RingBuffer *ringPtr, Tcl_Size capacity);
+static void RingBufferClear(RingBuffer *ringPtr);
+static Tcl_Size RingBufferIn(RingBuffer *ringPtr, const char *srcPtr,
+ Tcl_Size srcLen, int partialCopyOk);
+static Tcl_Size RingBufferOut(RingBuffer *ringPtr, char *dstPtr,
+ Tcl_Size dstCapacity, int partialCopyOk);
+static ConsoleHandleInfo *AllocateConsoleHandleInfo(HANDLE consoleHandle,
+ int permissions);
+static ConsoleHandleInfo *FindConsoleInfo(const ConsoleChannelInfo *);
static DWORD WINAPI ConsoleReaderThread(LPVOID arg);
-static void ConsoleSetupProc(ClientData clientData, int flags);
-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 BOOL ReadConsoleBytes(HANDLE hConsole, LPVOID lpBuffer,
- DWORD nbytes, LPDWORD nbytesread);
-static BOOL WriteConsoleBytes(HANDLE hConsole,
- const void *lpBuffer, DWORD nbytes,
- LPDWORD nbyteswritten);
+static void NudgeWatchers(HANDLE consoleHandle);
+#ifndef NDEBUG
+static int RingBufferCheck(const RingBuffer *ringPtr);
+#endif
+
+/*
+ * Static data.
+ */
+
+typedef struct {
+ /* Currently this struct is only used to detect thread initialization */
+ int notUsed; /* Dummy field */
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * All access to static data is controlled through a single process-wide
+ * lock. A process can have only a single console at a time, with three
+ * handles for stdin, stdout and stderr. Creation/destruction of consoles is
+ * a relatively rare event (currently only possible during process start),
+ * the number of consoles (as opposed to channels) is small (only stdin,
+ * stdout and stderr), and contention low. More finer-grained locking would
+ * likely not only complicate implementation but be slower due to multiple
+ * locks being held. Note console channels also differ from other Tcl
+ * channel types in that the channel<->OS descriptor mapping is not one-to-one.
+ */
+SRWLOCK gConsoleLock;
+
+/* Process-wide list of console handles. Access control through gConsoleLock */
+static ConsoleHandleInfo *gConsoleHandleInfoList;
+
+/*
+ * Process-wide list of channels that are listening for events. Again access
+ * control through gConsoleLock. Common list for all threads is simplifies
+ * locking and bookkeeping and is workable because in practice multiple
+ * threads are very unlikely to be all waiting on stdin (not workable
+ * because input would be randomly distributed to threads)
+ */
+static ConsoleChannelInfo *gWatchingChannelList;
/*
* This structure describes the channel type structure for command console
@@ -171,82 +311,313 @@ static BOOL WriteConsoleBytes(HANDLE hConsole,
*/
static const Tcl_ChannelType consoleChannelType = {
- "console", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
- ConsoleCloseProc, /* Close proc. */
- ConsoleInputProc, /* Input proc. */
- ConsoleOutputProc, /* Output proc. */
- NULL, /* Seek proc. */
- NULL, /* Set option proc. */
- NULL, /* Get option proc. */
- ConsoleWatchProc, /* Set up notifier to watch the channel. */
- ConsoleGetHandleProc, /* Get an OS handle from channel. */
- ConsoleClose2Proc, /* close2proc. */
- ConsoleBlockModeProc, /* Set blocking or non-blocking mode. */
+ "console",
+ TCL_CHANNEL_VERSION_5,
+ NULL, /* Deprecated. */
+ ConsoleInputProc,
+ ConsoleOutputProc,
+ NULL, /* Deprecated. */
+ ConsoleSetOptionProc,
+ ConsoleGetOptionProc,
+ ConsoleWatchProc,
+ ConsoleGetHandleProc,
+ ConsoleCloseProc,
+ ConsoleBlockModeProc,
NULL, /* Flush proc. */
- NULL, /* Handler proc. */
- NULL, /* Wide seek proc. */
- ConsoleThreadActionProc, /* Thread action proc. */
+ NULL, /* Bubbled event handler proc. */
+ NULL, /* Seek proc. */
+ ConsoleThreadActionProc,
NULL /* Truncation proc. */
};
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * RingBufferInit --
+ *
+ * Initializes the ring buffer to a given size.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Panics on allocation failure.
+ *
+ *------------------------------------------------------------------------
+ */
+static void
+RingBufferInit(
+ RingBuffer *ringPtr,
+ Tcl_Size capacity)
+{
+ if (capacity <= 0 || capacity > TCL_SIZE_MAX) {
+ Tcl_Panic("Internal error: invalid ring buffer capacity requested.");
+ }
+ ringPtr->bufPtr = (char *)Tcl_Alloc(capacity);
+ ringPtr->capacity = capacity;
+ ringPtr->start = 0;
+ ringPtr->length = 0;
+}
/*
- *----------------------------------------------------------------------
+ *------------------------------------------------------------------------
*
- * ReadConsoleBytes, WriteConsoleBytes --
+ * RingBufferClear
*
- * Wrapper for ReadConsoleW, that takes and returns number of bytes
- * instead of number of WCHARS.
+ * Clears the contents of a ring buffer.
*
- *----------------------------------------------------------------------
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The allocated internal buffer is freed.
+ *
+ *------------------------------------------------------------------------
+ */
+static void
+RingBufferClear(
+ RingBuffer *ringPtr)
+{
+ if (ringPtr->bufPtr) {
+ Tcl_Free(ringPtr->bufPtr);
+ ringPtr->bufPtr = NULL;
+ }
+ ringPtr->capacity = 0;
+ ringPtr->start = 0;
+ ringPtr->length = 0;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * RingBufferIn --
+ *
+ * Appends data to the ring buffer.
+ *
+ * Results:
+ * Returns number of bytes copied.
+ *
+ * Side effects:
+ * Internal buffer is updated.
+ *
+ *------------------------------------------------------------------------
*/
+static Tcl_Size
+RingBufferIn(
+ RingBuffer *ringPtr,
+ const char *srcPtr, /* Source to be copied */
+ Tcl_Size srcLen, /* Length of source */
+ int partialCopyOk) /* If true, partial copy is permitted */
+{
+ Tcl_Size freeSpace;
+
+ RINGBUFFER_ASSERT(ringPtr);
+
+ freeSpace = ringPtr->capacity - ringPtr->length;
+ if (freeSpace < srcLen) {
+ if (!partialCopyOk) {
+ return 0;
+ }
+ /* Copy only as much as free space allows */
+ srcLen = freeSpace;
+ }
+
+ if (ringPtr->capacity - ringPtr->start > ringPtr->length) {
+ /* There is room at the back */
+ Tcl_Size endSpaceStart = ringPtr->start + ringPtr->length;
+ Tcl_Size endSpace = ringPtr->capacity - endSpaceStart;
+ if (endSpace >= srcLen) {
+ /* Everything fits at the back */
+ memmove(endSpaceStart + ringPtr->bufPtr, srcPtr, srcLen);
+ } else {
+ /* srcLen > endSpace */
+ memmove(endSpaceStart + ringPtr->bufPtr, srcPtr, endSpace);
+ memmove(ringPtr->bufPtr, endSpace + srcPtr, srcLen - endSpace);
+ }
+ } else {
+ /* No room at the back. Existing data wrap to front. */
+ Tcl_Size wrapLen =
+ ringPtr->start + ringPtr->length - ringPtr->capacity;
+ memmove(wrapLen + ringPtr->bufPtr, srcPtr, srcLen);
+ }
+
+ ringPtr->length += srcLen;
+
+ RINGBUFFER_ASSERT(ringPtr);
+
+ return srcLen;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * RingBufferOut --
+ *
+ * Moves data out of the ring buffer. If dstPtr is NULL, the data
+ * is simply removed.
+ *
+ * Results:
+ * Returns number of bytes copied or removed.
+ *
+ * Side effects:
+ * Internal buffer is updated.
+ *
+ *------------------------------------------------------------------------
+ */
+static Tcl_Size
+RingBufferOut(
+ RingBuffer *ringPtr,
+ char *dstPtr, /* Buffer for output data. May be NULL */
+ Tcl_Size dstCapacity, /* Size of buffer */
+ int partialCopyOk) /* If true, return what's available */
+{
+ Tcl_Size leadLen;
+
+ RINGBUFFER_ASSERT(ringPtr);
+
+ if (dstCapacity > ringPtr->length) {
+ if (dstPtr && !partialCopyOk) {
+ return 0;
+ }
+ dstCapacity = ringPtr->length;
+ }
+
+ if (ringPtr->start <= (ringPtr->capacity - ringPtr->length)) {
+ /* No content wrap around. So leadLen is entire content */
+ leadLen = ringPtr->length;
+ } else {
+ /* Content wraps around so lead segment stretches to end of buffer */
+ leadLen = ringPtr->capacity - ringPtr->start;
+ }
+ if (leadLen >= dstCapacity) {
+ if (dstPtr) {
+ memmove(dstPtr, ringPtr->start + ringPtr->bufPtr, dstCapacity);
+ }
+ ringPtr->start += dstCapacity;
+ } else {
+ Tcl_Size wrapLen = dstCapacity - leadLen;
+ if (dstPtr) {
+ memmove(dstPtr, ringPtr->start + ringPtr->bufPtr, leadLen);
+ memmove(leadLen + dstPtr, ringPtr->bufPtr, wrapLen);
+ }
+ ringPtr->start = wrapLen;
+ }
+
+ ringPtr->length -= dstCapacity;
+ if (ringPtr->start == ringPtr->capacity || ringPtr->length == 0) {
+ ringPtr->start = 0;
+ }
+
+ RINGBUFFER_ASSERT(ringPtr);
-static BOOL
-ReadConsoleBytes(
+ return dstCapacity;
+}
+
+#ifndef NDEBUG
+static int
+RingBufferCheck(
+ const RingBuffer *ringPtr)
+{
+ return (ringPtr->bufPtr != NULL && ringPtr->capacity == CONSOLE_BUFFER_SIZE
+ && ringPtr->start < ringPtr->capacity
+ && ringPtr->length <= ringPtr->capacity);
+}
+#endif
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ReadConsoleChars --
+ *
+ * Wrapper for ReadConsoleW.
+ *
+ * Results:
+ * Returns 0 on success, else Windows error code.
+ *
+ * Side effects:
+ * On success the number of characters (not bytes) read is stored in
+ * *nCharsReadPtr. This will be 0 if the operation was interrupted by
+ * a Ctrl-C or a CancelIo call.
+ *
+ *------------------------------------------------------------------------
+ */
+static DWORD
+ReadConsoleChars(
HANDLE hConsole,
- LPVOID lpBuffer,
- DWORD nbytes,
- LPDWORD nbytesread)
+ WCHAR *lpBuffer,
+ Tcl_Size nChars,
+ Tcl_Size *nCharsReadPtr)
{
- DWORD ntchars;
- BOOL result;
+ DWORD nRead;
/*
- * If user types a Ctrl-Break or Ctrl-C, ReadConsole will return
- * success with ntchars == 0 and GetLastError() will be
- * ERROR_OPERATION_ABORTED. We do not want to treat this case
- * as EOF so we will loop around again. If no Ctrl signal handlers
- * have been established, the default signal OS handler in a separate
- * thread will terminate the program. If a Ctrl signal handler
- * has been established (through an extension for example), it
- * will run and take whatever action it deems appropriate.
+ * If user types a Ctrl-Break or Ctrl-C, ReadConsole will return success
+ * with ntchars == 0 and GetLastError() will be ERROR_OPERATION_ABORTED.
+ * If no Ctrl signal handlers have been established, the default signal
+ * OS handler in a separate thread will terminate the program. If a Ctrl
+ * signal handler has been established (through an extension for
+ * example), it will run and take whatever action it deems appropriate.
+ *
+ * If one thread closes its channel, it calls CancelSynchronousIo on the
+ * console handle which results again in success being returned and
+ * GetLastError() being ERROR_OPERATION_ABORTED but ntchars in
+ * unmodified.
+ *
+ * In both cases above we will return success but with nbytesread as 0.
+ * This allows caller to check for thread termination etc.
+ *
+ * See https://bugs.python.org/issue30237
+ * or https://github.com/microsoft/terminal/issues/12143
*/
- do {
- result = ReadConsoleW(hConsole, lpBuffer, nbytes / sizeof(WCHAR), &ntchars,
- NULL);
- } while (result && ntchars == 0 && GetLastError() == ERROR_OPERATION_ABORTED);
- if (nbytesread != NULL) {
- *nbytesread = ntchars * sizeof(WCHAR);
+ nRead = (DWORD)-1;
+ if (!ReadConsoleW(hConsole, lpBuffer, nChars, &nRead, NULL)) {
+ return GetLastError();
+ }
+ if ((nRead == 0 || nRead == (DWORD)-1)
+ && GetLastError() == ERROR_OPERATION_ABORTED) {
+ nRead = 0;
}
- return result;
+ *nCharsReadPtr = nRead;
+ return 0;
}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * WriteConsoleChars --
+ *
+ * Wrapper for WriteConsoleW.
+ *
+ * Results:
+ * Returns 0 on success, Windows error code on failure.
+ *
+ * Side effects:
+ * On success the number of characters (not bytes) written is stored in
+ * *nCharsWrittenPtr. This will be 0 if the operation was interrupted by
+ * a Ctrl-C or a CancelIo call.
+ *
+ *------------------------------------------------------------------------
+ */
-static BOOL
-WriteConsoleBytes(
+static DWORD
+WriteConsoleChars(
HANDLE hConsole,
- const void *lpBuffer,
- DWORD nbytes,
- LPDWORD nbyteswritten)
+ const WCHAR *lpBuffer,
+ Tcl_Size nChars,
+ Tcl_Size *nCharsWrittenPtr)
{
- DWORD ntchars;
- BOOL result;
+ DWORD nCharsWritten;
- result = WriteConsoleW(hConsole, lpBuffer, nbytes / sizeof(WCHAR), &ntchars,
- NULL);
- if (nbyteswritten != NULL) {
- *nbyteswritten = ntchars * sizeof(WCHAR);
+ /* See comments in ReadConsoleChars, not sure that applies here */
+ nCharsWritten = (DWORD)-1;
+ if (!WriteConsoleW(hConsole, lpBuffer, nChars, &nCharsWritten, NULL)) {
+ return GetLastError();
+ }
+ if (nCharsWritten == (DWORD) -1) {
+ nCharsWritten = 0;
}
- return result;
+ *nCharsWrittenPtr = nCharsWritten;
+ return 0;
}
/*
@@ -273,19 +644,19 @@ ConsoleInit(void)
* is a speed enhancement.
*/
- if (!initialized) {
- Tcl_MutexLock(&consoleMutex);
- if (!initialized) {
- initialized = 1;
+ if (!gInitialized) {
+ AcquireSRWLockExclusive(&gConsoleLock);
+ if (!gInitialized) {
+ gInitialized = 1;
Tcl_CreateExitHandler(ProcExitHandler, NULL);
}
- Tcl_MutexUnlock(&consoleMutex);
+ ReleaseSRWLockExclusive(&gConsoleLock);
}
if (TclThreadDataKeyGet(&dataKey) == NULL) {
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- tsdPtr->firstConsolePtr = NULL;
+ tsdPtr->notUsed = 0;
Tcl_CreateEventSource(ConsoleSetupProc, ConsoleCheckProc, NULL);
Tcl_CreateThreadExitHandler(ConsoleExitHandler, NULL);
}
@@ -310,10 +681,8 @@ ConsoleInit(void)
static void
ConsoleExitHandler(
- ClientData clientData) /* Old window proc. */
+ TCL_UNUSED(void *))
{
- (void)clientData;
-
Tcl_DeleteEventSource(ConsoleSetupProc, ConsoleCheckProc, NULL);
}
@@ -336,13 +705,50 @@ ConsoleExitHandler(
static void
ProcExitHandler(
- ClientData clientData) /* Old window proc. */
+ TCL_UNUSED(void *))
{
- (void)clientData;
-
- Tcl_MutexLock(&consoleMutex);
- initialized = 0;
- Tcl_MutexUnlock(&consoleMutex);
+ AcquireSRWLockExclusive(&gConsoleLock);
+ gInitialized = 0;
+ ReleaseSRWLockExclusive(&gConsoleLock);
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * NudgeWatchers --
+ *
+ * Wakes up all threads which have file event watchers on the passed
+ * console handle.
+ *
+ * The function locks and releases gConsoleLock.
+ * Caller must not be holding locks that will violate lock hierarchy.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * As above.
+ *------------------------------------------------------------------------
+ */
+static void
+NudgeWatchers(
+ HANDLE consoleHandle)
+{
+ ConsoleChannelInfo *chanInfoPtr;
+ AcquireSRWLockShared(&gConsoleLock); /* Shared-read lock */
+ for (chanInfoPtr = gWatchingChannelList; chanInfoPtr;
+ chanInfoPtr = chanInfoPtr->nextWatchingChannelPtr) {
+ /*
+ * Notify channels interested in our handle AND that have
+ * a thread attached.
+ * No lock needed for chanInfoPtr. See ConsoleChannelInfo.
+ */
+ if (chanInfoPtr->handle == consoleHandle
+ && chanInfoPtr->threadId != NULL) {
+ Tcl_ThreadAlert(chanInfoPtr->threadId);
+ }
+ }
+ ReleaseSRWLockShared(&gConsoleLock);
}
/*
@@ -351,7 +757,9 @@ ProcExitHandler(
* ConsoleSetupProc --
*
* This procedure is invoked before Tcl_DoOneEvent blocks waiting for an
- * event.
+ * event. It walks the channel list and if any input channel has data
+ * available or output channel has space for data, sets the event loop
+ * blocking time to 0 so that it will poll immediately.
*
* Results:
* None.
@@ -364,38 +772,47 @@ ProcExitHandler(
void
ConsoleSetupProc(
- ClientData data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
- ConsoleInfo *infoPtr;
+ ConsoleChannelInfo *chanInfoPtr;
Tcl_Time blockTime = { 0, 0 };
int block = 1;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- (void)data;
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
/*
- * Look to see if any events are already pending. If they are, poll.
+ * Walk the list of channels. See general comments for struct
+ * ConsoleChannelInfo with regard to locking and field access.
*/
-
- for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
- infoPtr = infoPtr->nextPtr) {
- if (infoPtr->watchMask & TCL_WRITABLE) {
- if (WaitForSingleObject(infoPtr->writer.readyEvent,
- 0) != WAIT_TIMEOUT) {
- block = 0;
- }
- }
- if (infoPtr->watchMask & TCL_READABLE) {
- if (WaitForRead(infoPtr, 0) >= 0) {
- block = 0;
+ AcquireSRWLockShared(&gConsoleLock); /* READ lock - no data modification */
+
+ for (chanInfoPtr = gWatchingChannelList; block && chanInfoPtr != NULL;
+ chanInfoPtr = chanInfoPtr->nextWatchingChannelPtr) {
+ ConsoleHandleInfo *handleInfoPtr = FindConsoleInfo(chanInfoPtr);
+ if (handleInfoPtr != NULL) {
+ AcquireSRWLockShared(&handleInfoPtr->lock);
+ /* Remember at most one of READABLE, WRITABLE set */
+ if (chanInfoPtr->watchMask & TCL_READABLE) {
+ if (RingBufferLength(&handleInfoPtr->buffer) > 0
+ || handleInfoPtr->lastError != ERROR_SUCCESS) {
+ block = 0; /* Input data available */
+ }
+ } else if (chanInfoPtr->watchMask & TCL_WRITABLE) {
+ if (RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
+ /* TCL_WRITABLE */
+ block = 0; /* Output space available */
+ }
}
+ ReleaseSRWLockShared(&handleInfoPtr->lock);
}
}
+ ReleaseSRWLockShared(&gConsoleLock);
+
if (!block) {
+ /* At least one channel is readable/writable. Set block time to 0 */
Tcl_SetMaxBlockTime(&blockTime);
}
}
@@ -419,57 +836,87 @@ ConsoleSetupProc(
static void
ConsoleCheckProc(
- ClientData data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
- ConsoleInfo *infoPtr;
+ ConsoleChannelInfo *chanInfoPtr;
+ Tcl_ThreadId me;
int needEvent;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!(flags & TCL_FILE_EVENTS)) {
return;
}
+ me = Tcl_GetCurrentThread();
+
/*
- * Queue events for any ready consoles that don't already have events
- * queued.
+ * Acquire a shared lock. Note this is ok even though we potentially
+ * modify the chanInfoPtr->flags because chanInfoPtr is only modified
+ * when it belongs to this thread and no other thread will write to it.
+ * THe shared lock is intended to protect the global gWatchingChannelList
+ * as we traverse it.
*/
+ AcquireSRWLockShared(&gConsoleLock);
- for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
- infoPtr = infoPtr->nextPtr) {
- if (infoPtr->flags & CONSOLE_PENDING) {
+ for (chanInfoPtr = gWatchingChannelList; chanInfoPtr != NULL;
+ chanInfoPtr = chanInfoPtr->nextWatchingChannelPtr) {
+ ConsoleHandleInfo *handleInfoPtr;
+
+ if (chanInfoPtr->threadId != me) {
+ /* Some other thread owns the channel */
+ continue;
+ }
+ if (chanInfoPtr->flags & CONSOLE_EVENT_QUEUED) {
+ /* A notification event already queued. No point in another. */
continue;
}
- /*
- * Queue an event if the console is signaled for reading or writing.
- */
+ handleInfoPtr = FindConsoleInfo(chanInfoPtr);
+ /* Pointer is safe to access as we are holding gConsoleLock */
- needEvent = 0;
- if (infoPtr->watchMask & TCL_WRITABLE) {
- if (WaitForSingleObject(infoPtr->writer.readyEvent,
- 0) != WAIT_TIMEOUT) {
- needEvent = 1;
- }
+ if (handleInfoPtr == NULL) {
+ /* Stale event */
+ continue;
}
- if (infoPtr->watchMask & TCL_READABLE) {
- if (WaitForRead(infoPtr, 0) >= 0) {
- needEvent = 1;
+ needEvent = 0;
+ AcquireSRWLockShared(&handleInfoPtr->lock);
+ /* Rememeber channel is read or write, never both */
+ if (chanInfoPtr->watchMask & TCL_READABLE) {
+ if (RingBufferLength(&handleInfoPtr->buffer) > 0
+ || handleInfoPtr->lastError != ERROR_SUCCESS) {
+ needEvent = 1; /* Input data available or error/EOF */
+ }
+ /*
+ * TCL_READABLE watch means someone is looking out for data being
+ * available, let reader thread know. Note channel need not be
+ * ASYNC! (Bug [baa51423c2])
+ */
+ handleInfoPtr->flags |= CONSOLE_DATA_AWAITED;
+ WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
+ } else if (chanInfoPtr->watchMask & TCL_WRITABLE) {
+ if (RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
+ needEvent = 1; /* Output space available */
}
}
+ ReleaseSRWLockShared(&handleInfoPtr->lock);
if (needEvent) {
- ConsoleEvent *evPtr = (ConsoleEvent *)ckalloc(sizeof(ConsoleEvent));
+ ConsoleEvent *evPtr = (ConsoleEvent *)Tcl_Alloc(sizeof(ConsoleEvent));
- infoPtr->flags |= CONSOLE_PENDING;
+ /* See note above loop why this can be accessed without locks */
+ chanInfoPtr->flags |= CONSOLE_EVENT_QUEUED;
+ chanInfoPtr->numRefs += 1; /* So it does not go away while event
+ * is in queue */
evPtr->header.proc = ConsoleEventProc;
- evPtr->infoPtr = infoPtr;
+ evPtr->chanInfoPtr = chanInfoPtr;
Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
}
}
+
+ ReleaseSRWLockShared(&gConsoleLock);
}
-
+
/*
*----------------------------------------------------------------------
*
@@ -488,11 +935,11 @@ ConsoleCheckProc(
static int
ConsoleBlockModeProc(
- ClientData instanceData, /* Instance data for channel. */
+ void *instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
- ConsoleInfo *infoPtr = (ConsoleInfo *)instanceData;
+ ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
/*
* Consoles on Windows can not be switched between blocking and
@@ -503,9 +950,9 @@ ConsoleBlockModeProc(
*/
if (mode == TCL_MODE_NONBLOCKING) {
- infoPtr->flags |= CONSOLE_ASYNC;
+ chanInfoPtr->flags |= CONSOLE_ASYNC;
} else {
- infoPtr->flags &= ~CONSOLE_ASYNC;
+ chanInfoPtr->flags &= ~CONSOLE_ASYNC;
}
return 0;
}
@@ -513,7 +960,7 @@ ConsoleBlockModeProc(
/*
*----------------------------------------------------------------------
*
- * ConsoleCloseProc/ConsoleClose2Proc --
+ * ConsoleCloseProc --
*
* Closes a console based IO channel.
*
@@ -528,101 +975,105 @@ ConsoleBlockModeProc(
static int
ConsoleCloseProc(
- ClientData instanceData, /* Pointer to ConsoleInfo structure. */
- Tcl_Interp *interp) /* For error reporting. */
+ void *instanceData, /* Pointer to ConsoleChannelInfo structure. */
+ TCL_UNUSED(Tcl_Interp *),
+ int flags)
{
- ConsoleInfo *consolePtr = (ConsoleInfo *)instanceData;
+ ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
+ ConsoleHandleInfo *handleInfoPtr;
int errorCode = 0;
- ConsoleInfo *infoPtr, **nextPtrPtr;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ ConsoleChannelInfo **nextPtrPtr;
+ int closeHandle;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
/*
- * 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.
+ * 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 while exiting. Note an explicit close in script will
+ * still close the handle. That's historical behavior on all platforms.
*/
+ if (!TclInThreadExit()
+ || ( (GetStdHandle(STD_INPUT_HANDLE) != chanInfoPtr->handle)
+ && (GetStdHandle(STD_OUTPUT_HANDLE) != chanInfoPtr->handle)
+ && (GetStdHandle(STD_ERROR_HANDLE) != chanInfoPtr->handle))) {
+ closeHandle = 1;
+ } else {
+ closeHandle = 0;
+ }
+
+ AcquireSRWLockExclusive(&gConsoleLock);
- if (consolePtr->reader.thread) {
- TclPipeThreadStop(&consolePtr->reader.TI, consolePtr->reader.thread);
- CloseHandle(consolePtr->reader.thread);
- CloseHandle(consolePtr->reader.readyEvent);
- consolePtr->reader.thread = NULL;
+ /* Remove channel from watchers' list */
+ for (nextPtrPtr = &gWatchingChannelList; *nextPtrPtr != NULL;
+ nextPtrPtr = &(*nextPtrPtr)->nextWatchingChannelPtr) {
+ if (*nextPtrPtr == (ConsoleChannelInfo *) chanInfoPtr) {
+ *nextPtrPtr = (*nextPtrPtr)->nextWatchingChannelPtr;
+ break;
+ }
}
- 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.
- */
+ handleInfoPtr = FindConsoleInfo(chanInfoPtr);
+ if (handleInfoPtr) {
+ /*
+ * Console thread may be blocked either waiting for console i/o
+ * or waiting on the condition variable for buffer empty/full
+ */
+ AcquireSRWLockShared(&handleInfoPtr->lock);
- if (consolePtr->writer.thread) {
- if (consolePtr->toWrite) {
+ if (closeHandle) {
+ handleInfoPtr->console = INVALID_HANDLE_VALUE;
+ }
+
+ /* Break the thread out of blocking console i/o */
+ handleInfoPtr->numRefs -= 1; /* Remove reference from this channel */
+ if (handleInfoPtr->numRefs == 1) {
/*
- * We only need to wait if there is something to write. This may
- * prevent infinite wait on exit. [Python Bug 216289]
+ * Abort the i/o if no other threads are listening on it.
+ * Note without this check, an input line will be skipped on
+ * the cancel.
*/
-
- WaitForSingleObject(consolePtr->writer.readyEvent, 5000);
+ CancelSynchronousIo(handleInfoPtr->consoleThread);
}
- TclPipeThreadStop(&consolePtr->writer.TI, consolePtr->writer.thread);
- CloseHandle(consolePtr->writer.thread);
- CloseHandle(consolePtr->writer.readyEvent);
- consolePtr->writer.thread = NULL;
+ /*
+ * Wake up the console handling thread. Note we do not explicitly
+ * tell it handle is closed (below). It will find out on next access
+ */
+ WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
+
+ ReleaseSRWLockShared(&handleInfoPtr->lock);
}
- consolePtr->validMask &= ~TCL_WRITABLE;
- /*
- * 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.
- */
+ ReleaseSRWLockExclusive(&gConsoleLock);
- if (!TclInThreadExit()
- || ((GetStdHandle(STD_INPUT_HANDLE) != consolePtr->handle)
- && (GetStdHandle(STD_OUTPUT_HANDLE) != consolePtr->handle)
- && (GetStdHandle(STD_ERROR_HANDLE) != consolePtr->handle))) {
- if (CloseHandle(consolePtr->handle) == FALSE) {
- TclWinConvertError(GetLastError());
+ chanInfoPtr->channel = NULL;
+ chanInfoPtr->watchMask = 0;
+ chanInfoPtr->permissions = 0;
+
+ if (closeHandle && chanInfoPtr->handle != INVALID_HANDLE_VALUE) {
+ if (CloseHandle(chanInfoPtr->handle) == FALSE) {
+ Tcl_WinConvertError(GetLastError());
errorCode = errno;
}
+ chanInfoPtr->handle = INVALID_HANDLE_VALUE;
}
- consolePtr->watchMask &= consolePtr->validMask;
-
/*
- * Remove the file from the list of watched files.
+ * Note, we can check and manipulate numRefs without a lock because
+ * we have removed it from the watch queue so the console thread cannot
+ * get at it.
*/
-
- for (nextPtrPtr = &(tsdPtr->firstConsolePtr), infoPtr = *nextPtrPtr;
- infoPtr != NULL;
- nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) {
- if (infoPtr == (ConsoleInfo *) consolePtr) {
- *nextPtrPtr = infoPtr->nextPtr;
- break;
- }
- }
- if (consolePtr->writeBuf != NULL) {
- ckfree(consolePtr->writeBuf);
- consolePtr->writeBuf = 0;
+ if (chanInfoPtr->numRefs > 1) {
+ /* There may be references already on the event queue */
+ chanInfoPtr->numRefs -= 1;
+ } else {
+ Tcl_Free(chanInfoPtr);
}
- ckfree(consolePtr);
return errorCode;
}
-
-static int
-ConsoleClose2Proc(
- ClientData instanceData, /* Pointer to ConsoleInfo structure. */
- Tcl_Interp *interp, /* For error reporting. */
- int flags)
-{
- if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) == 0) {
- return ConsoleCloseProc(instanceData, interp);
- }
- return EINVAL;
-}
/*
*----------------------------------------------------------------------
@@ -641,80 +1092,143 @@ ConsoleClose2Proc(
*
*----------------------------------------------------------------------
*/
-
static int
ConsoleInputProc(
- ClientData instanceData, /* Console state. */
- char *buf, /* Where to store data read. */
+ void *instanceData, /* Console state. */
+ char *bufPtr, /* 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;
- int result;
-
- *errorCode = 0;
-
- /*
- * Synchronize with the reader thread.
- */
+ ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
+ ConsoleHandleInfo *handleInfoPtr;
+ Tcl_Size numRead;
- result = WaitForRead(infoPtr, (infoPtr->flags & CONSOLE_ASYNC) ? 0 : 1);
+ if (chanInfoPtr->handle == INVALID_HANDLE_VALUE) {
+ return 0; /* EOF */
+ }
- /*
- * If an error occurred, return immediately.
- */
+ *errorCode = 0;
- if (result == -1) {
- *errorCode = errno;
- return -1;
+ AcquireSRWLockShared(&gConsoleLock);
+ handleInfoPtr = FindConsoleInfo(chanInfoPtr);
+ if (handleInfoPtr == NULL) {
+ /* Really shouldn't happen since channel is holding a reference */
+ ReleaseSRWLockShared(&gConsoleLock);
+ return 0; /* EOF */
}
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
+ ReleaseSRWLockShared(&gConsoleLock); /* AFTER acquiring handleInfoPtr->lock */
- if (infoPtr->readFlags & CONSOLE_BUFFERED) {
+ while (1) {
+ numRead = RingBufferOut(&handleInfoPtr->buffer, bufPtr, bufSize, 1);
/*
- * Data is stored in the buffer.
+ * Note: even if channel is closed or has an error, as long there is
+ * buffered data, we will pass it up.
*/
+ if (numRead != 0) {
+ break;
+ }
+ /*
+ * No data available.
+ * - If an error was recorded, generate that and reset it.
+ * - If EOF, indicate as much. It is up to the application to close
+ * the channel.
+ * - Otherwise, if non-blocking return EAGAIN or wait for more data.
+ */
+ if (handleInfoPtr->lastError != 0) {
+ if (handleInfoPtr->lastError == ERROR_INVALID_HANDLE) {
+ numRead = 0; /* Treat as EOF */
+ } else {
+ Tcl_WinConvertError(handleInfoPtr->lastError);
+ handleInfoPtr->lastError = 0;
+ *errorCode = Tcl_GetErrno();
+ numRead = -1;
+ }
+ break;
+ }
+ if (handleInfoPtr->console == INVALID_HANDLE_VALUE) {
+ /* EOF - break with numRead == 0 */
+ chanInfoPtr->handle = INVALID_HANDLE_VALUE;
+ break;
+ }
- if (bufSize < (infoPtr->bytesRead - infoPtr->offset)) {
- memcpy(buf, &infoPtr->buffer[infoPtr->offset], bufSize);
- bytesRead = bufSize;
- infoPtr->offset += bufSize;
- } else {
- memcpy(buf, &infoPtr->buffer[infoPtr->offset], bufSize);
- bytesRead = infoPtr->bytesRead - infoPtr->offset;
-
- /*
- * Reset the buffer.
- */
+ /* For async, tell caller we are blocked */
+ if (chanInfoPtr->flags & CONSOLE_ASYNC) {
+ *errorCode = EWOULDBLOCK;
+ numRead = -1;
+ break;
+ }
- infoPtr->readFlags &= ~CONSOLE_BUFFERED;
- infoPtr->offset = 0;
+ /*
+ * Blocking read. Just get data from directly from console. There
+ * is a small complication in that
+ * 1. The destination buffer should be WCHAR aligned.
+ * 2. We can only read even number of bytes (wide-character API).
+ * 3. Caller has large enough buffer (else length of line user can
+ * enter will be limited)
+ * If any condition is not met, we defer to the
+ * reader thread which handles these cases rather than dealing with
+ * them here (which is a little trickier than it might sound.)
+ *
+ * TODO - not clear this block is a useful optimization. bufSize by
+ * default is 4K which is < INPUT_BUFFER_SIZE and will rarely be
+ * increased on stdin.
+ */
+ if ((1 & (size_t)bufPtr) == 0 /* aligned buffer */
+ && (1 & bufSize) == 0 /* Even number of bytes */
+ && bufSize > INPUT_BUFFER_SIZE) {
+ DWORD lastError;
+ Tcl_Size numChars;
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ lastError = ReadConsoleChars(chanInfoPtr->handle,
+ (WCHAR *)bufPtr, bufSize / sizeof(WCHAR), &numChars);
+ /* NOTE lock released so DON'T break. Return instead */
+ if (lastError != ERROR_SUCCESS) {
+ Tcl_WinConvertError(lastError);
+ *errorCode = Tcl_GetErrno();
+ return -1;
+ } else if (numChars > 0) {
+ /* Successfully read something. */
+ return numChars * sizeof(WCHAR);
+ } else {
+ /*
+ * Ctrl-C/Ctrl-Brk interrupt. Loop around to retry.
+ * We have to reacquire the lock. No worried about handleInfoPtr
+ * having gone away since the channel holds a reference.
+ */
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
+ continue;
+ }
+ }
+ /*
+ * Deferring blocking read to reader thread.
+ * Release the lock and sleep. Note that because the channel
+ * holds a reference count on handleInfoPtr, it will not
+ * be deallocated while the lock is released.
+ */
+ handleInfoPtr->flags |= CONSOLE_DATA_AWAITED;
+ WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
+ if (!SleepConditionVariableSRW(&handleInfoPtr->interpThreadCV,
+ &handleInfoPtr->lock, INFINITE, 0)) {
+ Tcl_WinConvertError(GetLastError());
+ *errorCode = Tcl_GetErrno();
+ numRead = -1;
+ break;
}
- return bytesRead;
+ /* Lock is reacquired, loop back to try again */
}
- /*
- * 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) {
- /*
- * TODO: This potentially writes beyond the limits specified
- * by the caller. In practice this is harmless, since all writes
- * are into ChannelBuffers, and those have padding, but still
- * ought to remove this, unless some Windows wizard can give
- * a reason not to.
- */
- buf[count] = '\0';
- return count;
+ /* We read data. Ask for more if either async or watching for reads */
+ if ((chanInfoPtr->flags & CONSOLE_ASYNC)
+ || (chanInfoPtr->watchMask & TCL_READABLE)) {
+ handleInfoPtr->flags |= CONSOLE_DATA_AWAITED;
+ WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
}
- return -1;
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ return numRead;
}
/*
@@ -734,82 +1248,113 @@ ConsoleInputProc(
*
*----------------------------------------------------------------------
*/
-
static int
ConsoleOutputProc(
- ClientData instanceData, /* Console state. */
+ void *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;
- ConsoleThreadInfo *threadInfo = &infoPtr->writer;
- DWORD bytesWritten, timeout;
+ ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
+ ConsoleHandleInfo *handleInfoPtr;
+ Tcl_Size numWritten;
*errorCode = 0;
- /* avoid blocking if pipe-thread exited */
- timeout = (infoPtr->flags & CONSOLE_ASYNC) || !TclPipeThreadIsAlive(&threadInfo->TI)
- || TclInExit() || TclInThreadExit() ? 0 : INFINITE;
- if (WaitForSingleObject(threadInfo->readyEvent, timeout) == WAIT_TIMEOUT) {
- /*
- * The writer thread is blocked waiting for a write to complete and
- * the channel is in non-blocking mode.
- */
-
- errno = EWOULDBLOCK;
- goto error;
+ if (chanInfoPtr->handle == INVALID_HANDLE_VALUE) {
+ /* Some other thread would have *previously* closed the stdio handle */
+ *errorCode = EPIPE;
+ return -1;
}
- /*
- * Check for a background error on the last write.
- */
-
- if (infoPtr->writeError) {
- TclWinConvertError(infoPtr->writeError);
- infoPtr->writeError = 0;
- goto error;
+ AcquireSRWLockShared(&gConsoleLock);
+ handleInfoPtr = FindConsoleInfo(chanInfoPtr);
+ if (handleInfoPtr == NULL) {
+ /* Really shouldn't happen since channel is holding a reference */
+ *errorCode = EPIPE;
+ ReleaseSRWLockShared(&gConsoleLock);
+ return -1;
}
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
+ ReleaseSRWLockShared(&gConsoleLock); /* AFTER acquiring handleInfoPtr->lock */
+
+ /* Keep looping until all written. Break out for async and errors */
+ numWritten = 0;
+ while (1) {
+ /* Check for error and closing on every loop. */
+ if (handleInfoPtr->lastError != 0) {
+ Tcl_WinConvertError(handleInfoPtr->lastError);
+ *errorCode = Tcl_GetErrno();
+ numWritten = -1;
+ break;
+ }
+ if (handleInfoPtr->console == INVALID_HANDLE_VALUE) {
+ *errorCode = EPIPE;
+ chanInfoPtr->handle = INVALID_HANDLE_VALUE;
+ numWritten = -1;
+ break;
+ }
- if (infoPtr->flags & CONSOLE_ASYNC) {
/*
- * The console is non-blocking, so copy the data into the output
- * buffer and restart the writer thread.
+ * We can either write directly or through the console thread's
+ * ring buffer. We have to do the latter when
+ * (1) the operation is async since WriteConsoleChars is always blocking
+ * (2) when there is already data in the ring buffer because we don't
+ * want to reorder output from within a thread
+ * (3) when there are an odd number of bytes since WriteConsole
+ * takes whole WCHARs
+ * (4) when the pointer is not aligned on WCHAR
+ * The ring buffer deals with cases (3) and (4). It would be harder
+ * to duplicate that here.
*/
-
- if (toWrite > infoPtr->writeBufLen) {
+ if ((chanInfoPtr->flags & CONSOLE_ASYNC) /* Case (1) */
+ || RingBufferLength(&handleInfoPtr->buffer) != 0 /* Case (2) */
+ || (toWrite & 1) != 0 /* Case (3) */
+ || (PTR2INT(buf) & 1) != 0) { /* Case (4) */
+ numWritten += RingBufferIn(&handleInfoPtr->buffer,
+ numWritten + buf, toWrite - numWritten, 1);
+ if (numWritten == toWrite || chanInfoPtr->flags & CONSOLE_ASYNC) {
+ /* All done or async, just accept whatever was written */
+ break;
+ }
/*
- * Reallocate the buffer to be large enough to hold the data.
+ * Release the lock and sleep. Note that because the channel
+ * holds a reference count on handleInfoPtr, it will not
+ * be deallocated while the lock is released.
*/
-
- if (infoPtr->writeBuf) {
- ckfree(infoPtr->writeBuf);
+ WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
+ if (!SleepConditionVariableSRW(&handleInfoPtr->interpThreadCV,
+ &handleInfoPtr->lock, INFINITE, 0)) {
+ /* Report the error */
+ Tcl_WinConvertError(GetLastError());
+ *errorCode = Tcl_GetErrno();
+ numWritten = -1;
+ break;
+ }
+ } else {
+ /* Direct output */
+ DWORD winStatus;
+ HANDLE consoleHandle = handleInfoPtr->console;
+ /* Unlock before blocking in WriteConsole */
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ /* UNLOCKED so return, DON'T break out of loop as it will unlock
+ * again! */
+ winStatus = WriteConsoleChars(consoleHandle,
+ (WCHAR *)buf, toWrite / sizeof(WCHAR), &numWritten);
+ if (winStatus == ERROR_SUCCESS) {
+ return numWritten * sizeof(WCHAR);
+ } else {
+ Tcl_WinConvertError(winStatus);
+ *errorCode = Tcl_GetErrno();
+ return -1;
}
- infoPtr->writeBufLen = toWrite;
- infoPtr->writeBuf = (char *)ckalloc(toWrite);
}
- memcpy(infoPtr->writeBuf, buf, toWrite);
- infoPtr->toWrite = toWrite;
- ResetEvent(threadInfo->readyEvent);
- TclPipeThreadSignal(&threadInfo->TI);
- bytesWritten = toWrite;
- } else {
- /*
- * 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) {
- TclWinConvertError(GetLastError());
- goto error;
- }
+ /* Lock must have been reacquired before continuing loop */
}
- return bytesWritten;
-
- error:
- *errorCode = errno;
- return -1;
+ WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ return numWritten;
}
/*
@@ -840,66 +1385,83 @@ ConsoleEventProc(
* such as TCL_FILE_EVENTS. */
{
ConsoleEvent *consoleEvPtr = (ConsoleEvent *) evPtr;
- ConsoleInfo *infoPtr;
- int mask;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ ConsoleChannelInfo *chanInfoPtr;
+ int freeChannel;
+ int mask = 0;
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
}
+ chanInfoPtr = consoleEvPtr->chanInfoPtr;
/*
- * 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.
+ * We know chanInfoPtr is valid because its reference count would have
+ * been incremented when the event was queued. The corresponding release
+ * happens in this function.
*/
- for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
- infoPtr = infoPtr->nextPtr) {
- if (consoleEvPtr->infoPtr == infoPtr) {
- infoPtr->flags &= ~CONSOLE_PENDING;
- break;
- }
- }
-
/*
- * Remove stale events.
+ * Global lock used for chanInfoPtr. A read (shared) lock suffices
+ * because all access is within the channel owning thread with the
+ * exception of watchers which is a read-only access. See comments
+ * to ConsoleChannelInfo.
*/
-
- if (!infoPtr) {
- return 1;
- }
+ AcquireSRWLockShared(&gConsoleLock);
+ chanInfoPtr->flags &= ~CONSOLE_EVENT_QUEUED;
/*
- * 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.
+ * Only handle the event if the Tcl channel has not gone away AND is
+ * still owned by this thread AND is still watching events.
*/
-
- mask = 0;
- if (infoPtr->watchMask & TCL_WRITABLE) {
- if (WaitForSingleObject(infoPtr->writer.readyEvent,
- 0) != WAIT_TIMEOUT) {
- mask = TCL_WRITABLE;
- }
- }
-
- if (infoPtr->watchMask & TCL_READABLE) {
- if (WaitForRead(infoPtr, 0) >= 0) {
- if (infoPtr->readFlags & CONSOLE_EOF) {
+ if (chanInfoPtr->channel && chanInfoPtr->threadId == Tcl_GetCurrentThread()
+ && (chanInfoPtr->watchMask & (TCL_READABLE|TCL_WRITABLE))) {
+ ConsoleHandleInfo *handleInfoPtr = FindConsoleInfo(chanInfoPtr);
+ if (handleInfoPtr == NULL) {
+ /* Console was closed. EOF->read event only (not write) */
+ if (chanInfoPtr->watchMask & TCL_READABLE) {
mask = TCL_READABLE;
- } else {
- mask |= TCL_READABLE;
}
+ } else {
+ AcquireSRWLockShared(&handleInfoPtr->lock);
+ /* Remember at most one of READABLE, WRITABLE set */
+ if ((chanInfoPtr->watchMask & TCL_READABLE)
+ && RingBufferLength(&handleInfoPtr->buffer)) {
+ mask = TCL_READABLE;
+ } else if ((chanInfoPtr->watchMask & TCL_WRITABLE)
+ && RingBufferHasFreeSpace(&handleInfoPtr->buffer)) {
+ /* Generate write event space available */
+ mask = TCL_WRITABLE;
+ }
+ ReleaseSRWLockShared(&handleInfoPtr->lock);
}
}
/*
- * Inform the channel of the events.
+ * Tcl_NotifyChannel can recurse through the file event callback so need
+ * to release locks first. Our reference still holds so no danger of
+ * chanInfoPtr being deallocated if the callback closes the channel.
*/
+ ReleaseSRWLockShared(&gConsoleLock);
+ if (mask) {
+ Tcl_NotifyChannel(chanInfoPtr->channel, mask);
+ /* Note: chanInfoPtr ref count may have changed */
+ }
+
+ /* No need to lock - see comments earlier */
+
+ /* Remove the reference to the channel from event record */
+ if (chanInfoPtr->numRefs > 1) {
+ chanInfoPtr->numRefs -= 1;
+ freeChannel = 0;
+ } else {
+ assert(chanInfoPtr->channel == NULL);
+ freeChannel = 1;
+ }
+
+ if (freeChannel) {
+ Tcl_Free(chanInfoPtr);
+ }
- Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask & mask);
return 1;
}
@@ -921,43 +1483,57 @@ 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. */
+ void *instanceData, /* Console state. */
+ int newMask) /* What events to watch for, one of
+ * TCL_READABLE, TCL_WRITABLE */
{
- ConsoleInfo **nextPtrPtr, *ptr;
- ConsoleInfo *infoPtr = (ConsoleInfo *)instanceData;
- int oldMask = infoPtr->watchMask;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ ConsoleChannelInfo **nextPtrPtr, *ptr;
+ ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
+ int oldMask = chanInfoPtr->watchMask;
/*
* 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;
- if (infoPtr->watchMask) {
+ chanInfoPtr->watchMask = newMask & chanInfoPtr->permissions;
+ if (chanInfoPtr->watchMask) {
Tcl_Time blockTime = { 0, 0 };
if (!oldMask) {
- infoPtr->nextPtr = tsdPtr->firstConsolePtr;
- tsdPtr->firstConsolePtr = infoPtr;
+ AcquireSRWLockExclusive(&gConsoleLock);
+ /* Add to list of watched channels */
+ chanInfoPtr->nextWatchingChannelPtr = gWatchingChannelList;
+ gWatchingChannelList = chanInfoPtr;
+
+ /*
+ * For read channels, need to tell the console reader thread
+ * that we are looking for data since it will not do reads until
+ * it knows someone is awaiting.
+ */
+ ConsoleHandleInfo *handleInfoPtr = FindConsoleInfo(chanInfoPtr);
+ if (handleInfoPtr) {
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
+ handleInfoPtr->flags |= CONSOLE_DATA_AWAITED;
+ WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ }
+ ReleaseSRWLockExclusive(&gConsoleLock);
}
Tcl_SetMaxBlockTime(&blockTime);
} else if (oldMask) {
- /*
- * Remove the console from the list of watched consoles.
- */
+ /* Remove from list of watched channels */
- for (nextPtrPtr = &(tsdPtr->firstConsolePtr), ptr = *nextPtrPtr;
+ AcquireSRWLockExclusive(&gConsoleLock);
+ for (nextPtrPtr = &gWatchingChannelList, ptr = *nextPtrPtr;
ptr != NULL;
- nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
- if (infoPtr == ptr) {
- *nextPtrPtr = ptr->nextPtr;
+ nextPtrPtr = &ptr->nextWatchingChannelPtr, ptr = *nextPtrPtr) {
+ if (chanInfoPtr == ptr) {
+ *nextPtrPtr = ptr->nextWatchingChannelPtr;
break;
}
}
+ ReleaseSRWLockExclusive(&gConsoleLock);
}
}
@@ -981,119 +1557,67 @@ ConsoleWatchProc(
static int
ConsoleGetHandleProc(
- ClientData instanceData, /* The console state. */
- int direction, /* TCL_READABLE or TCL_WRITABLE. */
- ClientData *handlePtr) /* Where to store the handle. */
+ void *instanceData, /* The console state. */
+ TCL_UNUSED(int) /*direction*/,
+ void **handlePtr) /* Where to store the handle. */
{
- ConsoleInfo *infoPtr = (ConsoleInfo *)instanceData;
- (void)direction;
+ ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
- *handlePtr = infoPtr->handle;
+ if (chanInfoPtr->handle == INVALID_HANDLE_VALUE) {
+ return TCL_ERROR;
+ }
+ *handlePtr = chanInfoPtr->handle;
return TCL_OK;
}
/*
- *----------------------------------------------------------------------
+ *------------------------------------------------------------------------
*
- * WaitForRead --
+ * ConsoleDataAvailable --
*
- * 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).
+ * Checks if there is data in the console input queue.
*
* 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 the input queue has data, -1 on error else 0 if empty.
*
* Side effects:
- * Updates the shared state flags. If no error occurred, the reader
- * thread is blocked waiting for a signal from the main thread.
+ * None.
*
- *----------------------------------------------------------------------
+ *------------------------------------------------------------------------
*/
-
static int
-WaitForRead(
- ConsoleInfo *infoPtr, /* Console state. */
- int blocking) /* Indicates whether call should be blocking
- * or not. */
+ConsoleDataAvailable(
+ HANDLE consoleHandle)
{
- DWORD timeout, count;
- HANDLE *handle = (HANDLE *)infoPtr->handle;
- ConsoleThreadInfo *threadInfo = &infoPtr->reader;
- INPUT_RECORD input;
-
- while (1) {
- /*
- * Synchronize with the reader thread.
- */
-
- /* avoid blocking if pipe-thread exited */
- timeout = (!blocking || !TclPipeThreadIsAlive(&threadInfo->TI)
- || TclInExit() || TclInThreadExit()) ? 0 : INFINITE;
- if (WaitForSingleObject(threadInfo->readyEvent, timeout) == WAIT_TIMEOUT) {
- /*
- * The reader thread is blocked waiting for data and the channel
- * is in non-blocking mode.
- */
-
- errno = EWOULDBLOCK;
- return -1;
- }
-
- /*
- * 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 (PeekConsoleInputW(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;
- }
-
- /*
- * Ignore errors if there is data in the buffer.
- */
-
- if (infoPtr->readFlags & CONSOLE_BUFFERED) {
- return 0;
- } else {
- return -1;
- }
- }
+ INPUT_RECORD input[10];
+ DWORD count;
+ DWORD i;
- /*
- * If there is data in the buffer, the console must be readable (since
- * it is a line-oriented device).
- */
-
- if (infoPtr->readFlags & CONSOLE_BUFFERED) {
+ /*
+ * Need at least one keyboard event.
+ */
+ if (PeekConsoleInputW(consoleHandle, input,
+ sizeof(input) / sizeof(input[0]), &count) == FALSE) {
+ return -1;
+ }
+ /*
+ * Even if windows size and mouse events are disabled, can still have
+ * events other than keyboard, like focus events. Look for at least one
+ * keydown event because a trailing LF keyup is always present from the
+ * last input. However, if our buffer is full, assume there is a key
+ * down somewhere in the unread buffer. I suppose we could expand the
+ * buffer but not worth...
+ */
+ if (count == (sizeof(input)/sizeof(input[0]))) {
+ return 1;
+ }
+ for (i = 0; i < count; ++i) {
+ if (input[i].EventType == KEY_EVENT
+ && input[i].Event.KeyEvent.bKeyDown) {
return 1;
}
-
- /*
- * There wasn't any data available, so reset the thread and try again.
- */
-
- ResetEvent(threadInfo->readyEvent);
- TclPipeThreadSignal(&threadInfo->TI);
}
+ return 0;
}
/*
@@ -1105,90 +1629,193 @@ WaitForRead(
* available on a console.
*
* Results:
- * None.
+ * Always 0.
*
* 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.
*
*----------------------------------------------------------------------
*/
-
static DWORD WINAPI
ConsoleReaderThread(
LPVOID arg)
{
- TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg;
- ConsoleInfo *infoPtr = NULL; /* access info only after success init/wait */
- HANDLE handle = NULL;
- ConsoleThreadInfo *threadInfo = NULL;
- int done = 0;
+ ConsoleHandleInfo *handleInfoPtr = (ConsoleHandleInfo *) arg;
+ ConsoleHandleInfo **iterator;
+ Tcl_Size inputLen = 0;
+ Tcl_Size inputOffset = 0;
+ Tcl_Size lastReadSize = 0;
+ DWORD sleepTime;
+ char inputChars[INPUT_BUFFER_SIZE];
- while (!done) {
- /*
- * Wait for the main thread to signal before attempting to read.
- */
+ /*
+ * Keep looping until one of the following happens.
+ * - there are no more channels listening on the console
+ * - the console handle has been closed
+ */
+
+ /* This thread is holding a reference so pointer is safe */
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
- if (!TclPipeThreadWaitForSignal(&pipeTI)) {
- /* exit */
+ while (1) {
+
+ if (handleInfoPtr->numRefs == 1) {
+ /*
+ * Sole reference. That's this thread. Exit since no clients
+ * and no way for a thread to attach to a console after process
+ * start.
+ */
break;
}
- if (!infoPtr) {
- infoPtr = (ConsoleInfo *)pipeTI->clientData;
- handle = infoPtr->handle;
- threadInfo = &infoPtr->reader;
- }
-
/*
- * Look for data on the console, but first ignore any events that are
- * not KEY_EVENTs.
+ * Shared buffer has no data. If we have some in our private buffer
+ * copy that. Else check if there has been an error. In both cases
+ * notify the interp threads.
*/
+ if (inputLen > 0 || handleInfoPtr->lastError != 0) {
+ HANDLE consoleHandle;
+ if (inputLen > 0) {
+ /* Private buffer has data. Copy it over. */
+ Tcl_Size nStored;
+
+ assert((inputLen - inputOffset) > 0);
+ nStored = RingBufferIn(&handleInfoPtr->buffer,
+ inputOffset + inputChars, inputLen - inputOffset,
+ 1);
+ inputOffset += nStored;
+ if (inputOffset == inputLen) {
+ /* Temp buffer now empty */
+ inputOffset = 0;
+ inputLen = 0;
+ }
+ } else {
+ /*
+ * On error, nothing but inform caller and wait
+ * We do not want to exit until there are no client interps.
+ */
+ }
- if (ReadConsoleBytes(handle, infoPtr->buffer, CONSOLE_BUFFER_SIZE,
- (LPDWORD) &infoPtr->bytesRead) != FALSE) {
/*
- * Data was stored in the buffer.
+ * Wake up any threads waiting either synchronously or
+ * asynchronously. Since we are providing data, turn off the
+ * AWAITED flag. If the data provided is not sufficient the
+ * clients will request again. Note we have to wake up ALL
+ * awaiting threads, not just one, so they can all reissue
+ * requests if needed. (In a properly designed app, at most one
+ * thread should be reading standard input but...)
*/
+ handleInfoPtr->flags &= ~CONSOLE_DATA_AWAITED;
+ /* Wake synchronous channels */
+ WakeAllConditionVariable(&handleInfoPtr->interpThreadCV);
+ /*
+ * Wake up async channels registered for file events. Note in
+ * order to follow the locking hierarchy, we need to release
+ * handleInfoPtr->lock before calling NudgeWatchers.
+ */
+ consoleHandle = handleInfoPtr->console;
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ NudgeWatchers(consoleHandle);
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
- infoPtr->readFlags |= CONSOLE_BUFFERED;
- } else {
- DWORD err = GetLastError();
-
- if (err == (DWORD) EOF) {
- infoPtr->readFlags = CONSOLE_EOF;
- }
- done = 1;
+ /*
+ * Loop back to recheck for exit conditions changes while the
+ * lock was not held.
+ */
+ continue;
}
- /*
- * Signal the main thread by signalling the readable event and then
- * waking up the notifier thread.
- */
-
- SetEvent(threadInfo->readyEvent);
+ assert(inputLen == 0);
/*
- * 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.
+ * Read more data in two cases:
+ * 1. The previous read filled the buffer and there could be more
+ * data in the console internal *text* buffer. Note
+ * ConsolePendingInput (checked in ConsoleDataAvailable) will NOT
+ * show this. It holds input events not yet translated to text.
+ * 2. Tcl threads want more data AND there is data in the
+ * ConsolePendingInput buffer. The latter check necessary because
+ * we do not want to read ahead because the interp thread might
+ * change the read mode, e.g. turning off echo for password
+ * input. So only do so if at least one interpreter has requested
+ * data.
*/
-
- Tcl_MutexLock(&consoleMutex);
- if (infoPtr->threadId != NULL) {
+ if (lastReadSize == sizeof(inputChars)
+ || ((handleInfoPtr->flags & CONSOLE_DATA_AWAITED)
+ && ConsoleDataAvailable(handleInfoPtr->console))) {
+ DWORD error;
+ /* Do not hold the lock while blocked in console */
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ error = ReadConsoleChars(handleInfoPtr->console,
+ (WCHAR *)inputChars, sizeof(inputChars) / sizeof(WCHAR),
+ &inputLen);
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
+ if (error == 0) {
+ inputLen *= sizeof(WCHAR);
+ lastReadSize = inputLen;
+ } else {
+ /*
+ * We only store the last error. It is up to channel
+ * handlers whether to close or not in case of errors.
+ */
+ lastReadSize = 0;
+ handleInfoPtr->lastError = error;
+ if (handleInfoPtr->lastError == ERROR_INVALID_HANDLE) {
+ handleInfoPtr->console = INVALID_HANDLE_VALUE;
+ }
+ }
+ } else {
/*
- * TIP #218. When in flight ignore the event, no one will receive
- * it anyway.
+ * Either no one was asking for data, or no data was available.
+ * In the former case, wait until someone wakes us asking for
+ * data. In the latter case, there is no alternative but to
+ * poll since ReadConsole does not support async operation.
+ * So sleep for a short while and loop back to retry.
*/
+ sleepTime =
+ handleInfoPtr->flags & CONSOLE_DATA_AWAITED ? 50 : INFINITE;
+ SleepConditionVariableSRW(&handleInfoPtr->consoleThreadCV,
+ &handleInfoPtr->lock, sleepTime, 0);
+ }
+
+ /* Loop again to check for exit or wait for readers to wake us */
+ }
- Tcl_ThreadAlert(infoPtr->threadId);
+ /*
+ * Exiting:
+ * - remove the console from global list
+ * - close the handle if still valid
+ * - release the structure
+ * Note there is not need to check for any watchers because we only
+ * exit when there are no channels open to this console.
+ */
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ AcquireSRWLockExclusive(&gConsoleLock); /* Modifying - exclusive lock */
+ for (iterator = &gConsoleHandleInfoList; *iterator;
+ iterator = &(*iterator)->nextPtr) {
+ if (*iterator == handleInfoPtr) {
+ *iterator = handleInfoPtr->nextPtr;
+ break;
}
- Tcl_MutexUnlock(&consoleMutex);
}
+ ReleaseSRWLockExclusive(&gConsoleLock);
- /* Worker exit, so inform the main thread or free TI-structure (if owned) */
- TclPipeThreadExit(&pipeTI);
+ /* No need for relocking - no other thread should have access to it now */
+ RingBufferClear(&handleInfoPtr->buffer);
+
+ if (handleInfoPtr->console != INVALID_HANDLE_VALUE
+ && handleInfoPtr->lastError != ERROR_INVALID_HANDLE) {
+ SetConsoleMode(handleInfoPtr->console, handleInfoPtr->initMode);
+ /*
+ * NOTE: we do not call CloseHandle(handleInfoPtr->console) here.
+ * As per the GetStdHandle documentation, it need not be closed.
+ * Other components may be directly using it. Note however that
+ * an explicit chan close script command does close the handle
+ * for all threads.
+ */
+ }
+
+ Tcl_Free(handleInfoPtr);
return 0;
}
@@ -1205,89 +1832,255 @@ ConsoleReaderThread(
* 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.
*
*----------------------------------------------------------------------
*/
-
static DWORD WINAPI
ConsoleWriterThread(
LPVOID arg)
{
- TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg;
- ConsoleInfo *infoPtr = NULL; /* access info only after success init/wait */
- HANDLE handle = NULL;
- ConsoleThreadInfo *threadInfo = NULL;
- DWORD count, toWrite;
- char *buf;
- int done = 0;
-
- while (!done) {
- /*
- * Wait for the main thread to signal before attempting to write.
- */
- if (!TclPipeThreadWaitForSignal(&pipeTI)) {
- /* exit */
- break;
- }
- if (!infoPtr) {
- infoPtr = (ConsoleInfo *)pipeTI->clientData;
- handle = infoPtr->handle;
- threadInfo = &infoPtr->writer;
- }
+ ConsoleHandleInfo *handleInfoPtr = (ConsoleHandleInfo *) arg;
+ ConsoleHandleInfo **iterator;
+ BOOL success;
+ Tcl_Size numBytes;
+ /*
+ * This buffer size has no relation really with the size of the shared
+ * buffer. Could be bigger or smaller. Make larger as multiple threads
+ * could potentially be writing to it.
+ */
+ char buffer[2*CONSOLE_BUFFER_SIZE];
- buf = infoPtr->writeBuf;
- toWrite = infoPtr->toWrite;
+ /*
+ * Keep looping until one of the following happens.
+ *
+ * - there are not more channels listening on the console
+ * - the console handle has been closed
+ *
+ * On each iteration,
+ * - if the channel buffer is empty, wait for some channel writer to write
+ * - if there is data in our buffer, write it to the console
+ */
+
+ /* This thread is holding a reference so pointer is safe */
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
+ while (1) {
+ /* handleInfoPtr->lock must be held on entry to loop */
+
+ int offset;
+ HANDLE consoleHandle;
/*
- * Loop until all of the bytes are written or an error occurs.
+ * Sadly, we need to do another copy because do not want to hold
+ * a lock on handleInfoPtr->buffer while calling WriteConsole as that
+ * might block. Also, we only want to copy an integral number of
+ * WCHAR's, i.e. even number of chars so do some length checks up
+ * front.
*/
-
- while (toWrite > 0) {
- if (WriteConsoleBytes(handle, buf, (DWORD) toWrite,
- &count) == FALSE) {
- infoPtr->writeError = GetLastError();
- done = 1;
+ numBytes = RingBufferLength(&handleInfoPtr->buffer);
+ numBytes &= ~1; /* Copy integral number of WCHARs -> even number of bytes */
+ if (numBytes == 0) {
+ /* No data to write */
+ if (handleInfoPtr->numRefs == 1) {
+ /*
+ * Sole reference. That's this thread. Exit since no clients
+ * and no buffered output.
+ */
break;
}
- toWrite -= count;
- buf += count;
+ /* Wake up any threads waiting synchronously. */
+ WakeConditionVariable(&handleInfoPtr->interpThreadCV);
+ success = SleepConditionVariableSRW(&handleInfoPtr->consoleThreadCV,
+ &handleInfoPtr->lock, INFINITE, 0);
+ /* Note: lock has been acquired again! */
+ if (!success && GetLastError() != ERROR_TIMEOUT) {
+ /* TODO - what can be done? Should not happen */
+ /* For now keep going */
+ }
+ continue;
}
- /*
- * Signal the main thread by signalling the writable event and then
- * waking up the notifier thread.
- */
-
- SetEvent(threadInfo->readyEvent);
+ /* We have data to write */
+ if ((size_t)numBytes > (sizeof(buffer) / sizeof(buffer[0]))) {
+ numBytes = sizeof(buffer);
+ }
+ /* No need to check result, we already checked length bytes available */
+ RingBufferOut(&handleInfoPtr->buffer, buffer, numBytes, 0);
+
+ consoleHandle = handleInfoPtr->console;
+ WakeConditionVariable(&handleInfoPtr->interpThreadCV);
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ offset = 0;
+ while (numBytes > 0) {
+ Tcl_Size numWChars = numBytes / sizeof(WCHAR);
+ DWORD status;
+ status = WriteConsoleChars(handleInfoPtr->console,
+ (WCHAR *)(offset + buffer), numWChars, &numWChars);
+ if (status != 0) {
+ /* Only overwrite if no previous error */
+ if (handleInfoPtr->lastError == 0) {
+ handleInfoPtr->lastError = status;
+ }
+ if (status == ERROR_INVALID_HANDLE) {
+ handleInfoPtr->console = INVALID_HANDLE_VALUE;
+ }
+ /* Assume this write is done but keep looping in case
+ * it is a transient error. Not sure just closing handle
+ * and exiting thread is a good idea until all references
+ * from interp threads are gone.
+ */
+ break;
+ }
+ numBytes -= numWChars * sizeof(WCHAR);
+ offset += numWChars * sizeof(WCHAR);
+ }
+ /* Wake up any threads waiting synchronously. */
+ WakeConditionVariable(&handleInfoPtr->interpThreadCV);
/*
- * 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.
+ * Wake up all channels registered for file events. Note in
+ * order to follow the locking hierarchy, we cannot hold any locks
+ * when calling NudgeWatchers.
*/
+ NudgeWatchers(consoleHandle);
- Tcl_MutexLock(&consoleMutex);
- if (infoPtr->threadId != NULL) {
- /*
- * TIP #218. When in flight ignore the event, no one will receive
- * it anyway.
- */
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
+ }
- Tcl_ThreadAlert(infoPtr->threadId);
+ /*
+ * Exiting:
+ * - remove the console from global list
+ * - release the structure
+ * NOTE: we do not call CloseHandle(handleInfoPtr->console) here.
+ * As per the GetStdHandle documentation, it need not be closed.
+ * Other components may be directly using it. Note however that
+ * an explicit chan close script command does close the handle
+ * for all threads.
+ */
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+ AcquireSRWLockExclusive(&gConsoleLock); /* Modifying - exclusive lock */
+ for (iterator = &gConsoleHandleInfoList; *iterator;
+ iterator = &(*iterator)->nextPtr) {
+ if (*iterator == handleInfoPtr) {
+ *iterator = handleInfoPtr->nextPtr;
+ break;
}
- Tcl_MutexUnlock(&consoleMutex);
}
+ ReleaseSRWLockExclusive(&gConsoleLock);
- /* Worker exit, so inform the main thread or free TI-structure (if owned) */
- TclPipeThreadExit(&pipeTI);
+ RingBufferClear(&handleInfoPtr->buffer);
+ Tcl_Free(handleInfoPtr);
return 0;
}
/*
+ *------------------------------------------------------------------------
+ *
+ * AllocateConsoleHandleInfo --
+ *
+ * Allocates a ConsoleHandleInfo for the passed console handle. As
+ * a side effect starts a console thread to handle i/o on the handle.
+ *
+ * Important: Caller must be holding an EXCLUSIVE lock on gConsoleLock
+ * when calling this function. The lock continues to be held on return.
+ *
+ * Results:
+ * Pointer to an unlocked ConsoleHandleInfo structure. The reference
+ * count on the structure is 1. This corresponds to the common reference
+ * from the console thread and the gConsoleHandleInfoList. Returns NULL
+ * on error.
+ *
+ * Side effects:
+ * A console reader or writer thread is started. The returned structure
+ * is placed on the active console handler list gConsoleHandleInfoList.
+ *
+ *------------------------------------------------------------------------
+ */
+static ConsoleHandleInfo *
+AllocateConsoleHandleInfo(
+ HANDLE consoleHandle,
+ int permissions) /* TCL_READABLE or TCL_WRITABLE */
+{
+ ConsoleHandleInfo *handleInfoPtr;
+ DWORD consoleMode;
+
+ handleInfoPtr = (ConsoleHandleInfo *)Tcl_Alloc(sizeof(*handleInfoPtr));
+ memset(handleInfoPtr, 0, sizeof(*handleInfoPtr));
+ handleInfoPtr->console = consoleHandle;
+ InitializeSRWLock(&handleInfoPtr->lock);
+ InitializeConditionVariable(&handleInfoPtr->consoleThreadCV);
+ InitializeConditionVariable(&handleInfoPtr->interpThreadCV);
+ RingBufferInit(&handleInfoPtr->buffer, CONSOLE_BUFFER_SIZE);
+ handleInfoPtr->lastError = 0;
+ handleInfoPtr->permissions = permissions;
+ handleInfoPtr->numRefs = 1; /* See function header */
+ if (permissions == TCL_READABLE) {
+ GetConsoleMode(consoleHandle, &handleInfoPtr->initMode);
+ consoleMode = handleInfoPtr->initMode;
+ consoleMode &= ~(ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);
+ consoleMode |= ENABLE_LINE_INPUT;
+ SetConsoleMode(consoleHandle, consoleMode);
+ }
+ handleInfoPtr->consoleThread = CreateThread(
+ NULL, /* default security descriptor */
+ 2*CONSOLE_BUFFER_SIZE, /* Stack size - gets rounded up to granularity */
+ permissions == TCL_READABLE ? ConsoleReaderThread : ConsoleWriterThread,
+ handleInfoPtr, /* Pass to thread */
+ 0, /* Flags - no special cases */
+ NULL); /* Don't care about thread id */
+ if (handleInfoPtr->consoleThread == NULL) {
+ /* Note - SRWLock and condition variables do not need finalization */
+ RingBufferClear(&handleInfoPtr->buffer);
+ Tcl_Free(handleInfoPtr);
+ return NULL;
+ }
+
+ /* Chain onto global list */
+ handleInfoPtr->nextPtr = gConsoleHandleInfoList;
+ gConsoleHandleInfoList = handleInfoPtr;
+
+ return handleInfoPtr;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * FindConsoleInfo --
+ *
+ * Finds the ConsoleHandleInfo record for a given ConsoleChannelInfo.
+ * The found record must match the console handle. It is the caller's
+ * responsibility to check the permissions (read/write) in the returned
+ * ConsoleHandleInfo match permissions in chanInfoPtr. This function does
+ * not check that.
+ *
+ * Important: Caller must be holding an shared or exclusive lock on
+ * gConsoleMutex. That ensures the returned pointer stays valid on
+ * return without risk of deallocation by other threads.
+ *
+ * Results:
+ * Pointer to the found ConsoleHandleInfo or NULL if not found
+ *
+ * Side effects:
+ * None.
+ *
+ *------------------------------------------------------------------------
+ */
+static ConsoleHandleInfo *
+FindConsoleInfo(
+ const ConsoleChannelInfo *chanInfoPtr)
+{
+ ConsoleHandleInfo *handleInfoPtr;
+ for (handleInfoPtr = gConsoleHandleInfoList; handleInfoPtr;
+ handleInfoPtr = handleInfoPtr->nextPtr) {
+ if (handleInfoPtr->console == chanInfoPtr->handle) {
+ return handleInfoPtr;
+ }
+ }
+ return NULL;
+}
+
+/*
*----------------------------------------------------------------------
*
* TclWinOpenConsoleChannel --
@@ -1304,30 +2097,30 @@ ConsoleWriterThread(
*
*----------------------------------------------------------------------
*/
-
Tcl_Channel
TclWinOpenConsoleChannel(
HANDLE handle,
char *channelName,
int permissions)
{
- ConsoleInfo *infoPtr;
- DWORD modes;
+ ConsoleChannelInfo *chanInfoPtr;
+ ConsoleHandleInfo *handleInfoPtr;
- ConsoleInit();
+ /* A console handle can either be input or output, not both */
+ if (permissions != TCL_READABLE && permissions != TCL_WRITABLE) {
+ return NULL;
+ }
- /*
- * See if a channel with this handle already exists.
- */
+ ConsoleInit();
- infoPtr = (ConsoleInfo *)ckalloc(sizeof(ConsoleInfo));
- memset(infoPtr, 0, sizeof(ConsoleInfo));
+ chanInfoPtr = (ConsoleChannelInfo *)Tcl_Alloc(sizeof(*chanInfoPtr));
+ memset(chanInfoPtr, 0, sizeof(*chanInfoPtr));
- infoPtr->validMask = permissions;
- infoPtr->handle = handle;
- infoPtr->channel = (Tcl_Channel) NULL;
+ chanInfoPtr->permissions = permissions;
+ chanInfoPtr->handle = handle;
+ chanInfoPtr->channel = (Tcl_Channel) NULL;
- infoPtr->threadId = Tcl_GetCurrentThread();
+ chanInfoPtr->threadId = Tcl_GetCurrentThread();
/*
* Use the pointer for the name of the result channel. This keeps the
@@ -1335,10 +2128,7 @@ TclWinOpenConsoleChannel(
* for instance).
*/
- snprintf(channelName, 16 + TCL_INTEGER_SPACE, "file%" TCL_Z_MODIFIER "x", (size_t) infoPtr);
-
- infoPtr->channel = Tcl_CreateChannel(&consoleChannelType, channelName,
- infoPtr, permissions);
+ TclWinGenerateChannelName(channelName, "file", chanInfoPtr);
if (permissions & TCL_READABLE) {
/*
@@ -1347,36 +2137,75 @@ TclWinOpenConsoleChannel(
* 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;
- SetConsoleMode(infoPtr->handle, modes);
+ chanInfoPtr->flags |= CONSOLE_READ_OPS;
+ GetConsoleMode(handle, &chanInfoPtr->initMode);
- infoPtr->reader.readyEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
- infoPtr->reader.thread = CreateThread(NULL, 256, ConsoleReaderThread,
- TclPipeThreadCreateTI(&infoPtr->reader.TI, infoPtr,
- infoPtr->reader.readyEvent), 0, NULL);
+#ifdef OBSOLETE
+ /* Why was priority being set on console input? Code smell */
SetThreadPriority(infoPtr->reader.thread, THREAD_PRIORITY_HIGHEST);
+#endif
+ } else {
+ /* Already checked permissions is WRITABLE if not READABLE */
+ /* TODO - enable ansi escape processing? */
}
- if (permissions & TCL_WRITABLE) {
+ /*
+ * Global lock but that's ok. See comments top of file. Allocations
+ * will happen only a few times in the life of a process and that too
+ * generally at start up where only one thread is active.
+ */
+ AcquireSRWLockExclusive(&gConsoleLock); /*Allocate needs exclusive lock */
- infoPtr->writer.readyEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
- infoPtr->writer.thread = CreateThread(NULL, 256, ConsoleWriterThread,
- TclPipeThreadCreateTI(&infoPtr->writer.TI, infoPtr,
- infoPtr->writer.readyEvent), 0, NULL);
- SetThreadPriority(infoPtr->writer.thread, THREAD_PRIORITY_HIGHEST);
+ handleInfoPtr = FindConsoleInfo(chanInfoPtr);
+ if (handleInfoPtr == NULL) {
+ /* Not found. Allocate one */
+ handleInfoPtr = AllocateConsoleHandleInfo(handle, permissions);
+ } else {
+ /* Found. Its direction (read/write) better be the same */
+ if (handleInfoPtr->permissions != permissions) {
+ handleInfoPtr = NULL;
+ }
}
+ if (handleInfoPtr == NULL) {
+ ReleaseSRWLockExclusive(&gConsoleLock);
+ if (permissions == TCL_READABLE) {
+ SetConsoleMode(handle, chanInfoPtr->initMode);
+ }
+ Tcl_Free(chanInfoPtr);
+ return NULL;
+ }
+
+ /*
+ * There is effectively a reference to this structure from the Tcl
+ * channel subsystem. So record that. This reference will be dropped
+ * when the Tcl channel is closed.
+ */
+ chanInfoPtr->numRefs = 1;
+
/*
- * Files have default translation of AUTO and ^Z eof char, which means
+ * Need to keep track of number of referencing channels for closing.
+ * The pointer is safe since there is a reference held to it from
+ * gConsoleHandleInfoList but still need to lock the structure itself
+ */
+ AcquireSRWLockExclusive(&handleInfoPtr->lock);
+ handleInfoPtr->numRefs += 1;
+ ReleaseSRWLockExclusive(&handleInfoPtr->lock);
+
+ ReleaseSRWLockExclusive(&gConsoleLock);
+
+ /* Note Tcl_CreateChannel never fails other than panic on error */
+ chanInfoPtr->channel = Tcl_CreateChannel(&consoleChannelType, channelName,
+ chanInfoPtr, permissions);
+
+ /*
+ * Consoles 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 {}");
- Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", "unicode");
- return infoPtr->channel;
+ Tcl_SetChannelOption(NULL, chanInfoPtr->channel, "-translation", "auto");
+ Tcl_SetChannelOption(NULL, chanInfoPtr->channel, "-encoding", "utf-16");
+ return chanInfoPtr->channel;
}
/*
@@ -1397,36 +2226,221 @@ TclWinOpenConsoleChannel(
static void
ConsoleThreadActionProc(
- ClientData instanceData,
+ void *instanceData,
int action)
{
- ConsoleInfo *infoPtr = (ConsoleInfo *)instanceData;
+ ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
+
+ /* No need for any locks as no other thread will be writing to it */
+ if (action == TCL_CHANNEL_THREAD_INSERT) {
+ ConsoleInit(); /* Needed to set up event source handlers for this thread */
+ chanInfoPtr->threadId = Tcl_GetCurrentThread();
+ } else {
+ chanInfoPtr->threadId = NULL;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConsoleSetOptionProc --
+ *
+ * Sets an option on a channel.
+ *
+ * Results:
+ * 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 console. Sets Error message if needed (by
+ * calling Tcl_BadChannelOption).
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ConsoleSetOptionProc(
+ void *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. */
+{
+ ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
+ int len = strlen(optionName);
+ int vlen = strlen(value);
/*
- * 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 fileevent handlers before transfer thus takes care of
- * this structure.
+ * Option -inputmode normal|password|raw
*/
- Tcl_MutexLock(&consoleMutex);
- if (action == TCL_CHANNEL_THREAD_INSERT) {
+ if ((chanInfoPtr->flags & CONSOLE_READ_OPS) && (len > 1) &&
+ (strncmp(optionName, "-inputmode", len) == 0)) {
+ DWORD mode;
+
+ if (GetConsoleMode(chanInfoPtr->handle, &mode) == 0) {
+ Tcl_WinConvertError(GetLastError());
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read console mode: %s",
+ Tcl_PosixError(interp)));
+ }
+ return TCL_ERROR;
+ }
+ if (strncasecmp(value, "NORMAL", vlen) == 0) {
+ mode |=
+ ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+ } else if (strncasecmp(value, "PASSWORD", vlen) == 0) {
+ mode |= ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT;
+ mode &= ~ENABLE_ECHO_INPUT;
+ } else if (strncasecmp(value, "RAW", vlen) == 0) {
+ mode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
+ } else if (strncasecmp(value, "RESET", vlen) == 0) {
+ /*
+ * Reset to the initial mode, whatever that is.
+ */
+ mode = chanInfoPtr->initMode;
+ } else {
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad mode \"%s\" for -inputmode: must be"
+ " normal, password, raw, or reset", value));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE",
+ "VALUE", (char *)NULL);
+ }
+ return TCL_ERROR;
+ }
+ if (SetConsoleMode(chanInfoPtr->handle, mode) == 0) {
+ Tcl_WinConvertError(GetLastError());
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't set console mode: %s",
+ Tcl_PosixError(interp)));
+ }
+ return TCL_ERROR;
+ }
+
+ return TCL_OK;
+ }
+
+ if (chanInfoPtr->flags & CONSOLE_READ_OPS) {
+ return Tcl_BadChannelOption(interp, optionName, "inputmode");
+ } else {
+ return Tcl_BadChannelOption(interp, optionName, "");
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConsoleGetOptionProc --
+ *
+ * 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. Sets error message if needed
+ * (by calling Tcl_BadChannelOption).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConsoleGetOptionProc(
+ void *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). */
+{
+ ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
+ int valid = 0; /* Flag if valid option parsed. */
+ unsigned int len;
+ char buf[TCL_INTEGER_SPACE];
+
+ if (optionName == NULL) {
+ len = 0;
+ } else {
+ len = strlen(optionName);
+ }
+
+ /*
+ * Get option -inputmode
+ *
+ * This is a great simplification of the underlying reality, but actually
+ * represents what almost all scripts really want to know.
+ */
+
+ if (chanInfoPtr->flags & CONSOLE_READ_OPS) {
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-inputmode");
+ }
+ if (len==0 || (len>1 && strncmp(optionName, "-inputmode", len)==0)) {
+ DWORD mode;
+
+ valid = 1;
+ if (GetConsoleMode(chanInfoPtr->handle, &mode) == 0) {
+ Tcl_WinConvertError(GetLastError());
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read console mode: %s",
+ Tcl_PosixError(interp)));
+ }
+ return TCL_ERROR;
+ }
+ if (mode & ENABLE_LINE_INPUT) {
+ if (mode & ENABLE_ECHO_INPUT) {
+ Tcl_DStringAppendElement(dsPtr, "normal");
+ } else {
+ Tcl_DStringAppendElement(dsPtr, "password");
+ }
+ } else {
+ Tcl_DStringAppendElement(dsPtr, "raw");
+ }
+ }
+ } else {
/*
- * 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.
+ * Output channel. Get option -winsize
+ * Option is readonly and returned by [fconfigure chan -winsize] but not
+ * returned by [fconfigure chan] without explicit option name.
*/
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-winsize");
+ }
- ConsoleInit();
- if (infoPtr->channel != NULL) {
- infoPtr->threadId = Tcl_GetChannelThread(infoPtr->channel);
+ if (len == 0 || (len > 1 && strncmp(optionName, "-winsize", len) == 0)) {
+ CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
+
+ valid = 1;
+ if (!GetConsoleScreenBufferInfo(chanInfoPtr->handle,
+ &consoleInfo)) {
+ Tcl_WinConvertError(GetLastError());
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read console size: %s",
+ Tcl_PosixError(interp)));
+ }
+ return TCL_ERROR;
+ }
+ Tcl_DStringStartSublist(dsPtr);
+ snprintf(buf, sizeof(buf), "%d",
+ consoleInfo.srWindow.Right - consoleInfo.srWindow.Left + 1);
+ Tcl_DStringAppendElement(dsPtr, buf);
+ snprintf(buf, sizeof(buf), "%d",
+ consoleInfo.srWindow.Bottom - consoleInfo.srWindow.Top + 1);
+ Tcl_DStringAppendElement(dsPtr, buf);
+ Tcl_DStringEndSublist(dsPtr);
}
+ }
+
+ if (valid) {
+ return TCL_OK;
+ }
+ if (chanInfoPtr->flags & CONSOLE_READ_OPS) {
+ return Tcl_BadChannelOption(interp, optionName, "inputmode");
} else {
- infoPtr->threadId = NULL;
+ return Tcl_BadChannelOption(interp, optionName, "winsize");
}
- Tcl_MutexUnlock(&consoleMutex);
}
/*
diff --git a/win/tclWinDde.c b/win/tclWinDde.c
index ee3aa75..ebcd736 100644
--- a/win/tclWinDde.c
+++ b/win/tclWinDde.c
@@ -79,7 +79,7 @@ static DWORD ddeInstance; /* The application instance handle given to us
* by DdeInitialize. */
static int ddeIsServer = 0;
-#define TCL_DDE_VERSION "1.4.4"
+#define TCL_DDE_VERSION "1.4.5"
#define TCL_DDE_PACKAGE_NAME "dde"
#define TCL_DDE_SERVICE_NAME L"TclEval"
#define TCL_DDE_EXECUTE_RESULT L"$TCLEVAL$EXECUTE$RESULT"
@@ -90,8 +90,24 @@ static int ddeIsServer = 0;
TCL_DECLARE_MUTEX(ddeMutex)
+#if (TCL_MAJOR_VERSION < 9) && defined(TCL_MINOR_VERSION) && (TCL_MINOR_VERSION < 7)
+# if TCL_UTF_MAX > 3
+# define Tcl_WCharToUtfDString(a,b,c) Tcl_WinTCharToUtf((TCHAR *)(a),(b)*sizeof(WCHAR),c)
+# define Tcl_UtfToWCharDString(a,b,c) (WCHAR *)Tcl_WinUtfToTChar(a,b,c)
+# else
+# define Tcl_WCharToUtfDString Tcl_UniCharToUtfDString
+# define Tcl_UtfToWCharDString Tcl_UtfToUniCharDString
+# endif
+#ifndef Tcl_Size
+# define Tcl_Size int
+#endif
+#ifndef Tcl_CreateObjCommand2
+# define Tcl_CreateObjCommand2 Tcl_CreateObjCommand
+#endif
+#endif
+
/*
- * Forward declarations for functions defined later in this file.
+ * Declarations for functions defined in this file.
*/
static LRESULT CALLBACK DdeClientWindowProc(HWND hwnd, UINT uMsg,
@@ -114,43 +130,19 @@ static int MakeDdeConnection(Tcl_Interp *interp,
const WCHAR *name, HCONV *ddeConvPtr);
static void SetDdeError(Tcl_Interp *interp);
static int DdeObjCmd(void *clientData,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
-#if (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
-# if TCL_UTF_MAX > 3
-# define Tcl_WCharToUtfDString(a,b,c) Tcl_WinTCharToUtf((TCHAR *)(a),(b)*sizeof(WCHAR),c)
-# define Tcl_UtfToWCharDString(a,b,c) (WCHAR *)Tcl_WinUtfToTChar(a,b,c)
-# else
-# define Tcl_WCharToUtfDString Tcl_UniCharToUtfDString
-# define Tcl_UtfToWCharDString Tcl_UtfToUniCharDString
-# endif
-#endif
-
-static unsigned char *
-getByteArrayFromObj(
- Tcl_Obj *objPtr,
- size_t *lengthPtr
-) {
- int length;
-
- unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, &length);
-#if TCL_MAJOR_VERSION > 8
- if (sizeof(TCL_HASH_TYPE) > sizeof(int)) {
- /* 64-bit and TIP #494 situation: */
- *lengthPtr = *(TCL_HASH_TYPE *) objPtr->internalRep.twoPtrValue.ptr1;
- } else
-#endif
- /* 32-bit or without TIP #494 */
- *lengthPtr = (size_t) (unsigned) length;
- return result;
-}
-
#ifdef __cplusplus
extern "C" {
#endif
DLLEXPORT int Dde_Init(Tcl_Interp *interp);
DLLEXPORT int Dde_SafeInit(Tcl_Interp *interp);
+#if TCL_MAJOR_VERSION < 9
+/* With those additional entries, "load tcldde14.dll" works without 3th argument */
+DLLEXPORT int Tcldde_Init(Tcl_Interp *interp);
+DLLEXPORT int Tcldde_SafeInit(Tcl_Interp *interp);
+#endif
#ifdef __cplusplus
}
#endif
@@ -179,10 +171,18 @@ Dde_Init(
return TCL_ERROR;
}
- Tcl_CreateObjCommand(interp, "dde", DdeObjCmd, NULL, NULL);
+ Tcl_CreateObjCommand2(interp, "dde", DdeObjCmd, NULL, NULL);
Tcl_CreateExitHandler(DdeExitProc, NULL);
return Tcl_PkgProvideEx(interp, TCL_DDE_PACKAGE_NAME, TCL_DDE_VERSION, NULL);
}
+#if TCL_MAJOR_VERSION < 9
+int
+Tcldde_Init(
+ Tcl_Interp *interp)
+{
+ return Dde_Init(interp);
+}
+#endif
/*
*----------------------------------------------------------------------
@@ -210,6 +210,14 @@ Dde_SafeInit(
}
return result;
}
+#if TCL_MAJOR_VERSION < 9
+int
+Tcldde_SafeInit(
+ Tcl_Interp *interp)
+{
+ return Dde_SafeInit(interp);
+}
+#endif
/*
*----------------------------------------------------------------------
@@ -302,19 +310,20 @@ Initialize(void)
static const WCHAR *
DdeSetServerName(
Tcl_Interp *interp,
- const WCHAR *name, /* The name that will be used to refer to the
+ const WCHAR *name, /* The name that will be used to refer to the
* interpreter in later "send" commands. Must
* be globally unique. */
- int flags, /* DDE_FLAG_FORCE or 0 */
+ int flags, /* DDE_FLAG_FORCE or 0 */
Tcl_Obj *handlerPtr) /* Name of the optional proc/command to handle
* incoming Dde eval's */
{
- int suffix, offset;
+ int suffix;
RegisteredInterp *riPtr, *prevPtr;
Tcl_DString dString;
const WCHAR *actualName;
Tcl_Obj *srvListPtr = NULL, **srvPtrPtr = NULL;
- int n, srvCount = 0, lastSuffix, r = TCL_OK;
+ Tcl_Size n, srvCount = 0, offset;
+ int lastSuffix, r = TCL_OK;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
@@ -440,7 +449,7 @@ DdeSetServerName(
Tcl_ExposeCommand(interp, "dde", "dde");
}
- Tcl_CreateObjCommand(interp, "dde", DdeObjCmd,
+ Tcl_CreateObjCommand2(interp, "dde", DdeObjCmd,
riPtr, DeleteProc);
if (Tcl_IsSafe(interp)) {
Tcl_HideCommand(interp, "dde", "dde");
@@ -506,7 +515,7 @@ DdeGetRegistrationPtr(
static void
DeleteProc(
- void *clientData) /* The interp we are deleting. */
+ void *clientData) /* The interp we are deleting. */
{
RegisteredInterp *riPtr = (RegisteredInterp *) clientData;
RegisteredInterp *searchPtr, *prevPtr;
@@ -559,8 +568,8 @@ DeleteProc(
static Tcl_Obj *
ExecuteRemoteObject(
- RegisteredInterp *riPtr, /* Info about this server. */
- Tcl_Obj *ddeObjectPtr) /* The object to execute. */
+ RegisteredInterp *riPtr, /* Info about this server. */
+ Tcl_Obj *ddeObjectPtr) /* The object to execute. */
{
Tcl_Obj *returnPackagePtr;
int result = TCL_OK;
@@ -569,7 +578,7 @@ ExecuteRemoteObject(
Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj("permission denied: "
"a handler procedure must be defined for use in a safe "
"interp", -1));
- Tcl_SetErrorCode(riPtr->interp, "TCL", "DDE", "SECURITY_CHECK", NULL);
+ Tcl_SetErrorCode(riPtr->interp, "TCL", "DDE", "SECURITY_CHECK", (char *)NULL);
result = TCL_ERROR;
}
@@ -647,7 +656,7 @@ DdeServerProc(
/* Transaction-dependent data. */
{
Tcl_DString dString;
- size_t len;
+ Tcl_Size len;
DWORD dlen;
WCHAR *utilString;
Tcl_Obj *ddeObjectPtr;
@@ -767,8 +776,7 @@ DdeServerProc(
CP_WINUNICODE);
if (_wcsicmp(utilString, TCL_DDE_EXECUTE_RESULT) == 0) {
returnString =
- Tcl_GetString(convPtr->returnPackagePtr);
- len = convPtr->returnPackagePtr->length;
+ Tcl_GetStringFromObj(convPtr->returnPackagePtr, &len);
if (uFmt != CF_TEXT) {
Tcl_DStringInit(&dsBuf);
Tcl_UtfToWCharDString(returnString, len, &dsBuf);
@@ -790,8 +798,7 @@ DdeServerProc(
convPtr->riPtr->interp, Tcl_DStringValue(&ds), NULL,
TCL_GLOBAL_ONLY);
if (variableObjPtr != NULL) {
- returnString = Tcl_GetString(variableObjPtr);
- len = variableObjPtr->length;
+ returnString = Tcl_GetStringFromObj(variableObjPtr, &len);
if (uFmt != CF_TEXT) {
Tcl_DStringInit(&dsBuf);
Tcl_UtfToWCharDString(returnString, len, &dsBuf);
@@ -939,8 +946,8 @@ DdeServerProc(
*/
HSZPAIR *returnPtr;
- int i;
- int numItems;
+ Tcl_Size i;
+ DWORD numItems;
for (i = 0, riPtr = tsdPtr->interpListPtr; riPtr != NULL;
i++, riPtr = riPtr->nextPtr) {
@@ -949,12 +956,15 @@ DdeServerProc(
*/
}
- numItems = i;
+ if ((size_t)i >= UINT_MAX/sizeof(HSZPAIR)) {
+ return NULL;
+ }
+ numItems = (DWORD)i;
ddeReturn = DdeCreateDataHandle(ddeInstance, NULL,
- (numItems + 1) * sizeof(HSZPAIR), 0, 0, 0, 0);
+ (numItems + 1) * (DWORD)sizeof(HSZPAIR), 0, 0, 0, 0);
returnPtr = (HSZPAIR *) DdeAccessData(ddeReturn, &dlen);
len = dlen;
- for (i = 0, riPtr = tsdPtr->interpListPtr; i < numItems;
+ for (i = 0, riPtr = tsdPtr->interpListPtr; i < (Tcl_Size)numItems;
i++, riPtr = riPtr->nextPtr) {
returnPtr[i].hszSvc = DdeCreateStringHandleW(ddeInstance,
TCL_DDE_SERVICE_NAME, CP_WINUNICODE);
@@ -1040,7 +1050,7 @@ MakeDdeConnection(
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"no registered server named \"%s\"", Tcl_DStringValue(&dString)));
Tcl_DStringFree(&dString);
- Tcl_SetErrorCode(interp, "TCL", "DDE", "NO_SERVER", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "DDE", "NO_SERVER", (char *)NULL);
}
return TCL_ERROR;
}
@@ -1246,7 +1256,7 @@ DdeGetServicesList(
static void
SetDdeError(
- Tcl_Interp *interp) /* The interp to put the message in. */
+ Tcl_Interp *interp) /* The interp to put the message in. */
{
const char *errorMessage, *errorCode;
@@ -1271,7 +1281,7 @@ SetDdeError(
}
Tcl_SetObjResult(interp, Tcl_NewStringObj(errorMessage, -1));
- Tcl_SetErrorCode(interp, "TCL", "DDE", errorCode, NULL);
+ Tcl_SetErrorCode(interp, "TCL", "DDE", errorCode, (char *)NULL);
}
/*
@@ -1293,9 +1303,9 @@ SetDdeError(
static int
DdeObjCmd(
- void *dummy, /* Not used. */
+ void *dummy, /* Not used. */
Tcl_Interp *interp, /* The interp we are sending from */
- int objc, /* Number of arguments */
+ Tcl_Size objc, /* Number of arguments */
Tcl_Obj *const *objv) /* The arguments */
{
static const char *const ddeCommands[] = {
@@ -1314,7 +1324,7 @@ DdeObjCmd(
"-async", "-binary", NULL
};
enum DdeExecOptions {
- DDE_EXEC_ASYNC, DDE_EXEC_BINARY
+ DDE_EXEC_ASYNC, DDE_EXEC_BINARY
};
static const char *const ddeEvalOptions[] = {
"-async", NULL
@@ -1323,9 +1333,9 @@ DdeObjCmd(
"-binary", NULL
};
- int index, i, argIndex;
- size_t length;
- int flags = 0, result = TCL_OK, firstArg = 0;
+ int index, argIndex;
+ Tcl_Size length, i, firstArg = 0;
+ int flags = 0, result = TCL_OK;
HSZ ddeService = NULL, ddeTopic = NULL, ddeItem = NULL, ddeCookie = NULL;
HDDEDATA ddeData = NULL, ddeItemData = NULL, ddeReturn;
HCONV hConv = NULL;
@@ -1487,9 +1497,8 @@ DdeObjCmd(
Initialize();
if (firstArg != 1) {
- const char *src = Tcl_GetString(objv[firstArg]);
+ const char *src = Tcl_GetStringFromObj(objv[firstArg], &length);
- length = objv[firstArg]->length;
Tcl_DStringInit(&serviceBuf);
Tcl_UtfToWCharDString(src, length, &serviceBuf);
serviceName = (WCHAR *) Tcl_DStringValue(&serviceBuf);
@@ -1506,9 +1515,8 @@ DdeObjCmd(
}
if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) {
- const char *src = Tcl_GetString(objv[firstArg + 1]);
+ const char *src = Tcl_GetStringFromObj(objv[firstArg + 1], &length);
- length = objv[firstArg + 1]->length;
Tcl_DStringInit(&topicBuf);
topicName = Tcl_UtfToWCharDString(src, length, &topicBuf);
length = Tcl_DStringLength(&topicBuf) / sizeof(WCHAR);
@@ -1538,19 +1546,18 @@ DdeObjCmd(
break;
case DDE_EXECUTE: {
- size_t dataLength;
+ Tcl_Size dataLength;
const void *dataString;
Tcl_DString dsBuf;
Tcl_DStringInit(&dsBuf);
if (flags & DDE_FLAG_BINARY) {
dataString =
- getByteArrayFromObj(objv[firstArg + 2], &dataLength);
+ Tcl_GetByteArrayFromObj(objv[firstArg + 2], &dataLength);
} else {
const char *src;
- src = Tcl_GetString(objv[firstArg + 2]);
- dataLength = objv[firstArg + 2]->length;
+ src = Tcl_GetStringFromObj(objv[firstArg + 2], &dataLength);
Tcl_DStringInit(&dsBuf);
dataString =
Tcl_UtfToWCharDString(src, dataLength, &dsBuf);
@@ -1561,7 +1568,7 @@ DdeObjCmd(
Tcl_SetObjResult(interp,
Tcl_NewStringObj("cannot execute null data", -1));
Tcl_DStringFree(&dsBuf);
- Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", (char *)NULL);
result = TCL_ERROR;
break;
}
@@ -1603,8 +1610,7 @@ DdeObjCmd(
const WCHAR *itemString;
const char *src;
- src = Tcl_GetString(objv[firstArg + 2]);
- length = objv[firstArg + 2]->length;
+ src = Tcl_GetStringFromObj(objv[firstArg + 2], &length);
Tcl_DStringInit(&itemBuf);
itemString = Tcl_UtfToWCharDString(src, length, &itemBuf);
length = Tcl_DStringLength(&itemBuf) / sizeof(WCHAR);
@@ -1612,7 +1618,7 @@ DdeObjCmd(
if (length == 0) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("cannot request value of null data", -1));
- Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", (char *)NULL);
result = TCL_ERROR;
goto cleanup;
}
@@ -1645,7 +1651,7 @@ DdeObjCmd(
if ((tmp >= sizeof(WCHAR))
&& !dataString[tmp / sizeof(WCHAR) - 1]) {
- tmp -= sizeof(WCHAR);
+ tmp -= (DWORD)sizeof(WCHAR);
}
Tcl_DStringInit(&dsBuf);
Tcl_WCharToUtfDString(dataString, tmp>>1, &dsBuf);
@@ -1671,26 +1677,24 @@ DdeObjCmd(
BYTE *dataString;
const char *src;
- src = Tcl_GetString(objv[firstArg + 2]);
- length = objv[firstArg + 2]->length;
+ src = Tcl_GetStringFromObj(objv[firstArg + 2], &length);
Tcl_DStringInit(&itemBuf);
itemString = Tcl_UtfToWCharDString(src, length, &itemBuf);
length = Tcl_DStringLength(&itemBuf) / sizeof(WCHAR);
if (length == 0) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("cannot have a null item", -1));
- Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", (char *)NULL);
result = TCL_ERROR;
goto cleanup;
}
Tcl_DStringInit(&dsBuf);
if (flags & DDE_FLAG_BINARY) {
dataString = (BYTE *)
- getByteArrayFromObj(objv[firstArg + 3], &length);
+ Tcl_GetByteArrayFromObj(objv[firstArg + 3], &length);
} else {
const char *data =
- Tcl_GetString(objv[firstArg + 3]);
- length = objv[firstArg + 3]->length;
+ Tcl_GetStringFromObj(objv[firstArg + 3], &length);
Tcl_DStringInit(&dsBuf);
dataString = (BYTE *)
Tcl_UtfToWCharDString(data, length, &dsBuf);
@@ -1734,7 +1738,7 @@ DdeObjCmd(
if (serviceName == NULL) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("invalid service name \"\"", -1));
- Tcl_SetErrorCode(interp, "TCL", "DDE", "NO_SERVER", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "DDE", "NO_SERVER", (char *)NULL);
result = TCL_ERROR;
goto cleanup;
}
@@ -1783,7 +1787,7 @@ DdeObjCmd(
"permission denied: a handler procedure must be"
" defined for use in a safe interp", -1));
Tcl_SetErrorCode(interp, "TCL", "DDE", "SECURITY_CHECK",
- NULL);
+ (char *)NULL);
result = TCL_ERROR;
}
@@ -1848,14 +1852,13 @@ DdeObjCmd(
invalidServerResponse:
Tcl_SetObjResult(interp,
Tcl_NewStringObj("invalid data returned from server", -1));
- Tcl_SetErrorCode(interp, "TCL", "DDE", "BAD_RESPONSE", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "DDE", "BAD_RESPONSE", (char *)NULL);
result = TCL_ERROR;
goto cleanup;
}
objPtr = Tcl_ConcatObj(objc, objv);
- string = Tcl_GetString(objPtr);
- length = objPtr->length;
+ string = Tcl_GetStringFromObj(objPtr, &length);
Tcl_DStringInit(&dsBuf);
Tcl_UtfToWCharDString(string, length, &dsBuf);
string = Tcl_DStringValue(&dsBuf);
@@ -1905,7 +1908,7 @@ DdeObjCmd(
length = DdeGetData(ddeData, NULL, 0, 0);
ddeDataString = (WCHAR *) Tcl_Alloc(length);
DdeGetData(ddeData, (BYTE *) ddeDataString, (DWORD) length, 0);
- if (length > sizeof(WCHAR)) {
+ if (length > (Tcl_Size)sizeof(WCHAR)) {
length -= sizeof(WCHAR);
}
Tcl_DStringInit(&dsBuf);
diff --git a/win/tclWinError.c b/win/tclWinError.c
index 690859f..fb1c04c 100644
--- a/win/tclWinError.c
+++ b/win/tclWinError.c
@@ -4,7 +4,7 @@
* This file contains code for converting from Win32 errors to errno
* errors.
*
- * Copyright (c) 1995-1996 Sun Microsystems, Inc.
+ * Copyright © 1995-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.
@@ -334,7 +334,7 @@ static const unsigned char wsaErrorTable[] = {
/*
*----------------------------------------------------------------------
*
- * TclWinConvertError --
+ * Tcl_WinConvertError --
*
* This routine converts a Win32 error into an errno value.
*
@@ -348,12 +348,12 @@ static const unsigned char wsaErrorTable[] = {
*/
void
-TclWinConvertError(
- DWORD errCode) /* Win32 error code. */
+Tcl_WinConvertError(
+ unsigned errCode) /* Win32 error code. */
{
- if (errCode >= sizeof(errorTable)/sizeof(errorTable[0])) {
+ if ((unsigned)errCode >= sizeof(errorTable)/sizeof(errorTable[0])) {
errCode -= WSAEWOULDBLOCK;
- if (errCode >= sizeof(wsaErrorTable)/sizeof(wsaErrorTable[0])) {
+ if ((unsigned)errCode >= sizeof(wsaErrorTable)/sizeof(wsaErrorTable[0])) {
Tcl_SetErrno(errorTable[1]);
} else {
Tcl_SetErrno(wsaErrorTable[errCode]);
@@ -381,7 +381,7 @@ TclWinConvertError(
*----------------------------------------------------------------------
*/
-MODULE_SCOPE TCL_NORETURN void
+MODULE_SCOPE void
tclWinDebugPanic(
const char *format, ...)
{
@@ -406,16 +406,13 @@ tclWinDebugPanic(
}
OutputDebugStringW(msgString);
} else {
+ if (!isatty(fileno(stderr))) {
+ fprintf(stderr, "\xEF\xBB\xBF");
+ }
vfprintf(stderr, format, argList);
fprintf(stderr, "\n");
fflush(stderr);
}
-# if defined(__GNUC__)
- __builtin_trap();
-# else
- DebugBreak();
-# endif
- abort();
}
#endif
/*
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c
index ba76b5e..a9173da 100644
--- a/win/tclWinFCmd.c
+++ b/win/tclWinFCmd.c
@@ -4,7 +4,7 @@
* This file implements the Windows specific portion of file manipulation
* subcommands of the "file" command.
*
- * Copyright (c) 1996-1998 Sun Microsystems, Inc.
+ * Copyright © 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.
@@ -53,7 +53,6 @@ enum {
static const int attributeArray[] = {FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_HIDDEN,
0, FILE_ATTRIBUTE_READONLY, 0, FILE_ATTRIBUTE_SYSTEM};
-
const char *const tclpFileAttrStrings[] = {
"-archive", "-hidden", "-longname", "-readonly",
"-shortname", "-system", NULL
@@ -145,8 +144,8 @@ TclpObjRenameFile(
Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr)
{
- return DoRenameFile((WCHAR *)Tcl_FSGetNativePath(srcPathPtr),
- (WCHAR *)Tcl_FSGetNativePath(destPathPtr));
+ return DoRenameFile((const WCHAR *)Tcl_FSGetNativePath(srcPathPtr),
+ (const WCHAR *)Tcl_FSGetNativePath(destPathPtr));
}
static int
@@ -163,7 +162,7 @@ DoRenameFile(
int retval = -1;
/*
- * The MoveFileW API acts differently under Win95/98 and NT WRT NULL and
+ * The MoveFile API acts differently under Win95/98 and NT WRT NULL and
* "". Avoid passing these values.
*/
@@ -174,7 +173,7 @@ DoRenameFile(
}
/*
- * The MoveFileW API would throw an exception under NT if one of the
+ * The MoveFile API would throw an exception under NT if one of the
* arguments is a char block device.
*/
@@ -195,7 +194,7 @@ DoRenameFile(
/*
* Construct an TCLEXCEPTION_REGISTRATION to protect the call to
- * MoveFileW.
+ * MoveFile.
*/
"leal %[registration], %%edx" "\n\t"
@@ -224,7 +223,7 @@ DoRenameFile(
/*
* Come here on normal exit. Recover the TCLEXCEPTION_REGISTRATION and
- * put the status return from MoveFileW into it.
+ * put the status return from MoveFile into it.
*/
"movl %%fs:0, %%edx" "\n\t"
@@ -279,7 +278,7 @@ DoRenameFile(
return retval;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
srcAttr = GetFileAttributesW(nativeSrc);
dstAttr = GetFileAttributesW(nativeDst);
@@ -309,7 +308,8 @@ DoRenameFile(
if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {
WCHAR *nativeSrcRest, *nativeDstRest;
const char **srcArgv, **dstArgv;
- int size, srcArgc, dstArgc;
+ size_t size;
+ Tcl_Size srcArgc, dstArgc;
WCHAR nativeSrcPath[MAX_PATH];
WCHAR nativeDstPath[MAX_PATH];
Tcl_DString srcString, dstString;
@@ -328,8 +328,10 @@ DoRenameFile(
CharLowerW(nativeSrcPath);
CharLowerW(nativeDstPath);
- src = Tcl_WinTCharToUtf((TCHAR *)nativeSrcPath, -1, &srcString);
- dst = Tcl_WinTCharToUtf((TCHAR *)nativeDstPath, -1, &dstString);
+ Tcl_DStringInit(&srcString);
+ Tcl_DStringInit(&dstString);
+ src = Tcl_WCharToUtfDString(nativeSrcPath, TCL_INDEX_NONE, &srcString);
+ dst = Tcl_WCharToUtfDString(nativeDstPath, TCL_INDEX_NONE, &dstString);
/*
* Check whether the destination path is actually inside the
@@ -369,15 +371,15 @@ DoRenameFile(
* 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 MoveFileW system call already handles the case of moving
+ * The MoveFile system call already handles the case of moving
* a file between filesystems.
*/
Tcl_SetErrno(EXDEV);
}
- ckfree(srcArgv);
- ckfree(dstArgv);
+ Tcl_Free((void *)srcArgv);
+ Tcl_Free((void *)dstArgv);
}
/*
@@ -408,8 +410,7 @@ DoRenameFile(
* directory back, for completeness.
*/
- if (MoveFileW(nativeSrc,
- nativeDst) != FALSE) {
+ if (MoveFileW(nativeSrc, nativeDst) != FALSE) {
return TCL_OK;
}
@@ -418,7 +419,7 @@ DoRenameFile(
* be, but report this one.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
CreateDirectoryW(nativeDst, NULL);
SetFileAttributesW(nativeDst, dstAttr);
if (Tcl_GetErrno() == EACCES) {
@@ -455,15 +456,15 @@ DoRenameFile(
return TCL_ERROR;
}
nativeTmp = (WCHAR *) tempBuf;
- nativeRest[0] = L'\0';
+ nativeRest[0] = '\0';
result = TCL_ERROR;
- nativePrefix = (WCHAR *) L"tclr";
+ nativePrefix = (WCHAR *)L"tclr";
if (GetTempFileNameW(nativeTmp, nativePrefix,
0, tempBuf) != 0) {
/*
* Strictly speaking, need the following DeleteFile and
- * MoveFileW to be joined as an atomic operation so no
+ * MoveFile to be joined as an atomic operation so no
* other app comes along in the meantime and creates the
* same temp file.
*/
@@ -486,7 +487,7 @@ DoRenameFile(
* error. Could happen if an open file refers to dst.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
if (Tcl_GetErrno() == EACCES) {
/*
* Decode the EACCES to a more meaningful error.
@@ -534,8 +535,8 @@ TclpObjCopyFile(
Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr)
{
- return DoCopyFile((WCHAR *)Tcl_FSGetNativePath(srcPathPtr),
- (WCHAR *)Tcl_FSGetNativePath(destPathPtr));
+ return DoCopyFile((const WCHAR *)Tcl_FSGetNativePath(srcPathPtr),
+ (const WCHAR *)Tcl_FSGetNativePath(destPathPtr));
}
static int
@@ -667,7 +668,7 @@ DoCopyFile(
return retval;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
if (Tcl_GetErrno() == EBADF) {
Tcl_SetErrno(EACCES);
return TCL_ERROR;
@@ -694,8 +695,7 @@ DoCopyFile(
if (dstAttr & FILE_ATTRIBUTE_READONLY) {
SetFileAttributesW(nativeDst,
dstAttr & ~((DWORD)FILE_ATTRIBUTE_READONLY));
- if (CopyFileW(nativeSrc, nativeDst,
- 0) != FALSE) {
+ if (CopyFileW(nativeSrc, nativeDst, 0) != FALSE) {
return TCL_OK;
}
@@ -704,7 +704,7 @@ DoCopyFile(
* attributes of dst.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
SetFileAttributesW(nativeDst, dstAttr);
}
}
@@ -764,7 +764,7 @@ TclpDeleteFile(
if (DeleteFileW(path) != FALSE) {
return TCL_OK;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
if (Tcl_GetErrno() == EACCES) {
attr = GetFileAttributesW(path);
@@ -791,11 +791,10 @@ TclpDeleteFile(
int res = SetFileAttributesW(path,
attr & ~((DWORD) FILE_ATTRIBUTE_READONLY));
- if ((res != 0) &&
- (DeleteFileW(path) != FALSE)) {
+ if ((res != 0) && (DeleteFileW(path) != FALSE)) {
return TCL_OK;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
if (res != 0) {
SetFileAttributesW(path, attr);
}
@@ -854,7 +853,7 @@ int
TclpObjCreateDirectory(
Tcl_Obj *pathPtr)
{
- return DoCreateDirectory((WCHAR *)Tcl_FSGetNativePath(pathPtr));
+ return DoCreateDirectory((const WCHAR *)Tcl_FSGetNativePath(pathPtr));
}
static int
@@ -864,7 +863,7 @@ DoCreateDirectory(
if (CreateDirectoryW(nativePath, NULL) == 0) {
DWORD error = GetLastError();
- TclWinConvertError(error);
+ Tcl_WinConvertError(error);
return TCL_ERROR;
}
return TCL_OK;
@@ -917,8 +916,10 @@ TclpObjCopyDirectory(
}
if (normDestPtr != destPathPtr) { Tcl_IncrRefCount(normDestPtr); }
- Tcl_WinUtfToTChar(Tcl_GetString(normSrcPtr), -1, &srcString);
- Tcl_WinUtfToTChar(Tcl_GetString(normDestPtr), -1, &dstString);
+ Tcl_DStringInit(&srcString);
+ Tcl_DStringInit(&dstString);
+ Tcl_UtfToWCharDString(TclGetString(normSrcPtr), TCL_INDEX_NONE, &srcString);
+ Tcl_UtfToWCharDString(TclGetString(normDestPtr), TCL_INDEX_NONE, &dstString);
ret = TraverseWinTree(TraversalCopy, &srcString, &dstString, &ds);
@@ -931,7 +932,7 @@ TclpObjCopyDirectory(
} else if (!strcmp(Tcl_DStringValue(&ds), TclGetString(normDestPtr))) {
*errorPtr = destPathPtr;
} else {
- *errorPtr = TclDStringToObj(&ds);
+ *errorPtr = Tcl_DStringToObj(&ds);
}
Tcl_DStringFree(&ds);
Tcl_IncrRefCount(*errorPtr);
@@ -994,11 +995,12 @@ TclpObjRemoveDirectory(
return TCL_ERROR;
}
if (normPtr != pathPtr) { Tcl_IncrRefCount(normPtr); }
- Tcl_WinUtfToTChar(Tcl_GetString(normPtr), -1, &native);
+ Tcl_DStringInit(&native);
+ Tcl_UtfToWCharDString(TclGetString(normPtr), TCL_INDEX_NONE, &native);
ret = DoRemoveDirectory(&native, recursive, &ds);
Tcl_DStringFree(&native);
} else {
- ret = DoRemoveJustDirectory((WCHAR *)Tcl_FSGetNativePath(pathPtr), 0, &ds);
+ ret = DoRemoveJustDirectory((const WCHAR *)Tcl_FSGetNativePath(pathPtr), 0, &ds);
}
if (ret != TCL_OK) {
@@ -1007,7 +1009,7 @@ TclpObjRemoveDirectory(
!strcmp(Tcl_DStringValue(&ds), TclGetString(normPtr))) {
*errorPtr = pathPtr;
} else {
- *errorPtr = TclDStringToObj(&ds);
+ *errorPtr = Tcl_DStringToObj(&ds);
}
Tcl_IncrRefCount(*errorPtr);
}
@@ -1060,7 +1062,7 @@ DoRemoveJustDirectory(
}
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
if (Tcl_GetErrno() == EACCES) {
attr = GetFileAttributesW(nativePath);
@@ -1087,14 +1089,13 @@ DoRemoveJustDirectory(
if (attr & FILE_ATTRIBUTE_READONLY) {
attr &= ~FILE_ATTRIBUTE_READONLY;
- if (SetFileAttributesW(nativePath,
- attr) == FALSE) {
+ if (SetFileAttributesW(nativePath, attr) == FALSE) {
goto end;
}
if (RemoveDirectoryW(nativePath) != FALSE) {
return TCL_OK;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
SetFileAttributesW(nativePath,
attr | FILE_ATTRIBUTE_READONLY);
}
@@ -1120,9 +1121,14 @@ DoRemoveJustDirectory(
end:
if (errorPtr != NULL) {
- char *p = Tcl_WinTCharToUtf((TCHAR *)nativePath, -1, errorPtr);
+ char *p;
+
+ Tcl_DStringInit(errorPtr);
+ p = Tcl_WCharToUtfDString(nativePath, TCL_INDEX_NONE, errorPtr);
for (; *p; ++p) {
- if (*p == '\\') *p = '/';
+ if (*p == '\\') {
+ *p = '/';
+ }
}
}
return TCL_ERROR;
@@ -1198,7 +1204,7 @@ TraverseWinTree(
nativeErrfile = NULL;
result = TCL_OK;
- oldTargetLen = 0; /* lint. */
+ oldTargetLen = 0;
nativeSource = (WCHAR *) Tcl_DStringValue(sourcePtr);
nativeTarget = (WCHAR *)
@@ -1238,7 +1244,7 @@ TraverseWinTree(
* Can't read directory.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
nativeErrfile = nativeSource;
goto end;
}
@@ -1267,7 +1273,7 @@ TraverseWinTree(
found = 1;
for (; found; found = FindNextFileW(handle, &data)) {
WCHAR *nativeName;
- size_t len;
+ int len;
WCHAR *wp = data.cFileName;
if (*wp == '.') {
@@ -1332,9 +1338,10 @@ TraverseWinTree(
end:
if (nativeErrfile != NULL) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
if (errorPtr != NULL) {
- Tcl_WinTCharToUtf((TCHAR *)nativeErrfile, -1, errorPtr);
+ Tcl_DStringInit(errorPtr);
+ Tcl_WCharToUtfDString(nativeErrfile, TCL_INDEX_NONE, errorPtr);
}
result = TCL_ERROR;
}
@@ -1382,11 +1389,10 @@ TraversalCopy(
if (DoCreateDirectory(nativeDst) == TCL_OK) {
DWORD attr = GetFileAttributesW(nativeSrc);
- if (SetFileAttributesW(nativeDst,
- attr) != FALSE) {
+ if (SetFileAttributesW(nativeDst, attr) != FALSE) {
return TCL_OK;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
}
break;
case DOTREE_POSTD:
@@ -1399,7 +1405,8 @@ TraversalCopy(
*/
if (errorPtr != NULL) {
- Tcl_WinTCharToUtf((TCHAR *)nativeDst, -1, errorPtr);
+ Tcl_DStringInit(errorPtr);
+ Tcl_WCharToUtfDString(nativeDst, TCL_INDEX_NONE, errorPtr);
}
return TCL_ERROR;
}
@@ -1428,7 +1435,7 @@ TraversalCopy(
static int
TraversalDelete(
const WCHAR *nativeSrc, /* Source pathname to delete. */
- const WCHAR *dstPtr, /* Not used. */
+ TCL_UNUSED(const WCHAR *) /*dstPtr*/,
int type, /* Reason for call - see TraverseWinTree() */
Tcl_DString *errorPtr) /* If non-NULL, initialized DString filled
* with UTF-8 name of file causing error. */
@@ -1454,7 +1461,8 @@ TraversalDelete(
}
if (errorPtr != NULL) {
- Tcl_WinTCharToUtf((TCHAR *)nativeSrc, -1, errorPtr);
+ Tcl_DStringInit(errorPtr);
+ Tcl_WCharToUtfDString(nativeSrc, TCL_INDEX_NONE, errorPtr);
}
return TCL_ERROR;
}
@@ -1482,7 +1490,7 @@ StatError(
Tcl_Obj *fileName) /* The name of the file which caused the
* error. */
{
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s",
TclGetString(fileName), Tcl_PosixError(interp)));
}
@@ -1517,7 +1525,7 @@ GetWinFileAttributes(
const WCHAR *nativeName;
int attr;
- nativeName = (WCHAR *)Tcl_FSGetNativePath(fileName);
+ nativeName = (const WCHAR *)Tcl_FSGetNativePath(fileName);
result = GetFileAttributesW(nativeName);
if (result == 0xFFFFFFFF) {
@@ -1535,8 +1543,8 @@ GetWinFileAttributes(
* We test for, and fix that case, here.
*/
- int len;
- const char *str = Tcl_GetStringFromObj(fileName,&len);
+ Tcl_Size len;
+ const char *str = TclGetStringFromObj(fileName, &len);
if (len < 4) {
if (len == 0) {
@@ -1560,7 +1568,7 @@ GetWinFileAttributes(
}
}
- *attributePtrPtr = Tcl_NewBooleanObj(attr);
+ TclNewIntObj(*attributePtrPtr, attr != 0);
return TCL_OK;
}
@@ -1590,12 +1598,12 @@ GetWinFileAttributes(
static int
ConvertFileNameFormat(
Tcl_Interp *interp, /* The interp we are using for errors. */
- int objIndex, /* The index of the attribute. */
+ TCL_UNUSED(int) /*objIndex*/,
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_Size pathc, i, length;
Tcl_Obj *splitPath;
splitPath = Tcl_FSSplitPath(fileName, &pathc);
@@ -1604,7 +1612,7 @@ ConvertFileNameFormat(
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"could not read \"%s\": no such file or directory",
- Tcl_GetString(fileName)));
+ TclGetString(fileName)));
errno = ENOENT;
Tcl_PosixError(interp);
}
@@ -1621,12 +1629,11 @@ ConvertFileNameFormat(
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] == ':'))
+ pathv = TclGetStringFromObj(elt, &length);
+ if ((pathv[0] == '/') || ((length == 3) && (pathv[1] == ':'))
|| (strcmp(pathv, ".") == 0) || (strcmp(pathv, "..") == 0)) {
/*
* Handle "/", "//machine/export", "c:/", "." or ".." by just
@@ -1649,7 +1656,6 @@ ConvertFileNameFormat(
Tcl_DString dsTemp;
const WCHAR *nativeName;
const char *tempString;
- int tempLen;
WIN32_FIND_DATAW data;
HANDLE handle;
DWORD attr;
@@ -1662,9 +1668,9 @@ ConvertFileNameFormat(
* likely to lead to infinite loops.
*/
+ tempString = TclGetStringFromObj(tempPath, &length);
Tcl_DStringInit(&ds);
- tempString = Tcl_GetStringFromObj(tempPath,&tempLen);
- nativeName = (WCHAR *)Tcl_WinUtfToTChar(tempString, tempLen, &ds);
+ nativeName = Tcl_UtfToWCharDString(tempString, length, &ds);
Tcl_DecrRefCount(tempPath);
handle = FindFirstFileW(nativeName, &data);
if (handle == INVALID_HANDLE_VALUE) {
@@ -1701,7 +1707,7 @@ ConvertFileNameFormat(
}
/*
- * Purify reports a extraneous UMR in Tcl_WinTCharToUtf() trying
+ * Purify reports a extraneous UMR in Tcl_WCharToUtfDString() 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
@@ -1713,27 +1719,16 @@ ConvertFileNameFormat(
*/
Tcl_DStringInit(&dsTemp);
- Tcl_WinTCharToUtf((TCHAR *)nativeName, -1, &dsTemp);
+ Tcl_WCharToUtfDString(nativeName, TCL_INDEX_NONE, &dsTemp);
Tcl_DStringFree(&ds);
- /*
- * Deal with issues of tildes being absolute.
- */
-
- if (Tcl_DStringValue(&dsTemp)[0] == '~') {
- TclNewLiteralStringObj(tempPath, "./");
- Tcl_AppendToObj(tempPath, Tcl_DStringValue(&dsTemp),
- Tcl_DStringLength(&dsTemp));
- Tcl_DStringFree(&dsTemp);
- } else {
- tempPath = TclDStringToObj(&dsTemp);
- }
+ tempPath = Tcl_DStringToObj(&dsTemp);
Tcl_ListObjReplace(NULL, splitPath, i, 1, 1, &tempPath);
FindClose(handle);
}
}
- *attributePtrPtr = Tcl_FSJoinPath(splitPath, -1);
+ *attributePtrPtr = Tcl_FSJoinPath(splitPath, TCL_INDEX_NONE);
if (splitPath != NULL) {
/*
@@ -1844,7 +1839,7 @@ SetWinFileAttributes(
int yesNo, result;
const WCHAR *nativeName;
- nativeName = (WCHAR *)Tcl_FSGetNativePath(fileName);
+ nativeName = (const WCHAR *)Tcl_FSGetNativePath(fileName);
fileAttributes = old = GetFileAttributesW(nativeName);
if (fileAttributes == 0xFFFFFFFF) {
@@ -1893,11 +1888,11 @@ 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 *attributePtr) /* The new value of the attribute. */
+ TCL_UNUSED(Tcl_Obj *) /*attributePtr*/)
{
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"cannot set attribute \"%s\" for file \"%s\": attribute is readonly",
- tclpFileAttrStrings[objIndex], Tcl_GetString(fileName)));
+ tclpFileAttrStrings[objIndex], TclGetString(fileName)));
errno = EINVAL;
Tcl_PosixError(interp);
return TCL_ERROR;
@@ -1937,7 +1932,7 @@ TclpObjListVolumes(void)
if (GetLogicalDriveStringsA(sizeof(buf), buf) == 0) {
/*
- * GetVolumeInformationW() will detect all drives, but causes
+ * GetVolumeInformationW() 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 GetVolumeInformationW() to
@@ -1953,14 +1948,14 @@ TclpObjListVolumes(void)
buf[0] = (char) ('a' + i);
if (GetVolumeInformationA(buf, NULL, 0, NULL, NULL, NULL, NULL, 0)
|| (GetLastError() == ERROR_NOT_READY)) {
- elemPtr = Tcl_NewStringObj(buf, -1);
+ elemPtr = Tcl_NewStringObj(buf, TCL_INDEX_NONE);
Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
}
}
} else {
for (p = buf; *p != '\0'; p += 4) {
p[2] = '/';
- elemPtr = Tcl_NewStringObj(p, -1);
+ elemPtr = Tcl_NewStringObj(p, TCL_INDEX_NONE);
Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
}
}
@@ -1970,6 +1965,121 @@ TclpObjListVolumes(void)
}
/*
+ *----------------------------------------------------------------------
+ *
+ * TclpCreateTemporaryDirectory --
+ *
+ * Creates a temporary directory, possibly based on the supplied bits and
+ * pieces of template supplied in the arguments.
+ *
+ * Results:
+ * An object (refcount 0) containing the name of the newly-created
+ * directory, or NULL on failure.
+ *
+ * Side effects:
+ * Accesses the native filesystem. Makes a directory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclpCreateTemporaryDirectory(
+ Tcl_Obj *dirObj,
+ Tcl_Obj *basenameObj)
+{
+ Tcl_DString base, name; /* Contains WCHARs */
+ int baseLen;
+ DWORD error;
+ WCHAR tempBuf[MAX_PATH + 1];
+ DWORD len = GetTempPathW(MAX_PATH, tempBuf);
+
+ /*
+ * Build the path in writable memory from the user-supplied pieces and
+ * some defaults. First, the parent temporary directory.
+ */
+
+ if (dirObj) {
+ TclGetString(dirObj);
+ if (dirObj->length < 1) {
+ goto useSystemTemp;
+ }
+ Tcl_DStringInit(&base);
+ Tcl_UtfToWCharDString(TclGetString(dirObj), TCL_INDEX_NONE, &base);
+ if (dirObj->bytes[dirObj->length - 1] != '\\') {
+ Tcl_UtfToWCharDString("\\", TCL_INDEX_NONE, &base);
+ }
+ } else {
+ useSystemTemp:
+ Tcl_DStringInit(&base);
+ Tcl_DStringAppend(&base, (char *) tempBuf, len * sizeof(WCHAR));
+ }
+
+ /*
+ * Next, the base of the directory name.
+ */
+
+#define DEFAULT_TEMP_DIR_PREFIX "tcl"
+#define SUFFIX_LENGTH 8
+
+ if (basenameObj) {
+ Tcl_UtfToWCharDString(TclGetString(basenameObj), TCL_INDEX_NONE, &base);
+ } else {
+ Tcl_UtfToWCharDString(DEFAULT_TEMP_DIR_PREFIX, TCL_INDEX_NONE, &base);
+ }
+ Tcl_UtfToWCharDString("_", TCL_INDEX_NONE, &base);
+
+ /*
+ * Now we keep on trying random suffixes until we get one that works
+ * (i.e., that doesn't trigger the ERROR_ALREADY_EXISTS error). Note that
+ * SUFFIX_LENGTH is longer than on Unix because we expect to be not on a
+ * case-sensitive filesystem.
+ */
+
+ baseLen = Tcl_DStringLength(&base);
+ do {
+ char tempbuf[SUFFIX_LENGTH + 1];
+ int i;
+ static const char randChars[] =
+ "QWERTYUIOPASDFGHJKLZXCVBNM1234567890";
+ static const int numRandChars = sizeof(randChars) - 1;
+
+ /*
+ * Put a random suffix on the end.
+ */
+
+ error = ERROR_SUCCESS;
+ tempbuf[SUFFIX_LENGTH] = '\0';
+ for (i = 0 ; i < SUFFIX_LENGTH; i++) {
+ tempbuf[i] = randChars[(int) (rand() % numRandChars)];
+ }
+ Tcl_DStringSetLength(&base, baseLen);
+ Tcl_UtfToWCharDString(tempbuf, TCL_INDEX_NONE, &base);
+ } while (!CreateDirectoryW((LPCWSTR) Tcl_DStringValue(&base), NULL)
+ && (error = GetLastError()) == ERROR_ALREADY_EXISTS);
+
+ /*
+ * Check for other errors. The big ones are ERROR_PATH_NOT_FOUND and
+ * ERROR_ACCESS_DENIED.
+ */
+
+ if (error != ERROR_SUCCESS) {
+ Tcl_WinConvertError(error);
+ Tcl_DStringFree(&base);
+ return NULL;
+ }
+
+ /*
+ * We actually made the directory, so we're done! Report what we made back
+ * as a (clean) Tcl_Obj.
+ */
+
+ Tcl_DStringInit(&name);
+ Tcl_WCharToUtfDString((LPCWSTR) Tcl_DStringValue(&base), TCL_INDEX_NONE, &name);
+ Tcl_DStringFree(&base);
+ return Tcl_DStringToObj(&name);
+}
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/win/tclWinFile.c b/win/tclWinFile.c
index eeb48b7..c520478 100644
--- a/win/tclWinFile.c
+++ b/win/tclWinFile.c
@@ -6,7 +6,7 @@
* files, which can be manipulated through the Win32 console redirection
* interfaces.
*
- * Copyright (c) 1995-1998 Sun Microsystems, Inc.
+ * Copyright © 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.
@@ -29,7 +29,7 @@
*/
#define POSIX_EPOCH_AS_FILETIME \
- ((Tcl_WideInt)116444736 * (Tcl_WideInt)1000000000)
+ ((long long) 116444736 * (long long) 1000000000)
/*
* Declarations for 'link' related information. This information should come
@@ -149,8 +149,8 @@ typedef struct {
* Other typedefs required by this code.
*/
-static time_t ToCTime(FILETIME fileTime);
-static void FromCTime(time_t posixTime, FILETIME *fileTime);
+static __time64_t ToCTime(FILETIME fileTime);
+static void FromCTime(__time64_t posixTime, FILETIME *fileTime);
/*
* Declarations for local functions defined in this file:
@@ -170,13 +170,14 @@ static int NativeWriteReparse(const WCHAR *LinkDirectory,
static int NativeMatchType(int isDrive, DWORD attr,
const WCHAR *nativeName, Tcl_GlobTypeData *types);
static int WinIsDrive(const char *name, size_t nameLen);
-static int WinIsReserved(const char *path);
+static size_t WinIsReserved(const char *path);
static Tcl_Obj * WinReadLink(const WCHAR *LinkSource);
static Tcl_Obj * WinReadLinkDirectory(const WCHAR *LinkDirectory);
static int WinLink(const WCHAR *LinkSource,
const WCHAR *LinkTarget, int linkAction);
static int WinSymLinkDirectory(const WCHAR *LinkDirectory,
const WCHAR *LinkTarget);
+MODULE_SCOPE void tclWinDebugPanic(const char *format, ...);
/*
*--------------------------------------------------------------------
@@ -208,7 +209,7 @@ WinLink(
* Invalid file.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return -1;
}
@@ -232,7 +233,7 @@ WinLink(
* Invalid file.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return -1;
}
@@ -246,7 +247,7 @@ WinLink(
* The target doesn't exist.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
/*
* It is a file.
@@ -261,14 +262,9 @@ WinLink(
return 0;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
} else if (linkAction & TCL_CREATE_SYMBOLIC_LINK) {
- if (!tclWinProcs.createSymbolicLink) {
- /*
- * Can't symlink files.
- */
- Tcl_SetErrno(EINVAL);
- } else if (tclWinProcs.createSymbolicLink(linkSourcePath, linkTargetPath,
+ if (CreateSymbolicLinkW(linkSourcePath, linkTargetPath,
0x2 /* SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE */)) {
/*
* Success!
@@ -276,7 +272,7 @@ WinLink(
return 0;
} else {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
}
} else {
Tcl_SetErrno(ENODEV);
@@ -331,7 +327,7 @@ WinReadLink(
* Invalid file.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return NULL;
}
@@ -345,7 +341,7 @@ WinReadLink(
* The source doesn't exist.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return NULL;
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
@@ -506,7 +502,7 @@ TclWinSymLinkDelete(
* Error setting junction.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
CloseHandle(hFile);
} else {
CloseHandle(hFile);
@@ -643,10 +639,11 @@ WinReadLinkDirectory(
}
}
- Tcl_WinTCharToUtf((TCHAR *)
+ Tcl_DStringInit(&ds);
+ Tcl_WCharToUtfDString(
reparseBuffer->MountPointReparseBuffer.PathBuffer,
reparseBuffer->MountPointReparseBuffer
- .SubstituteNameLength, &ds);
+ .SubstituteNameLength>>1, &ds);
copy = Tcl_DStringValue(&ds)+offset;
len = Tcl_DStringLength(&ds)-offset;
@@ -698,7 +695,7 @@ NativeReadReparse(
* Error creating directory.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return -1;
}
@@ -712,7 +709,7 @@ NativeReadReparse(
* Error setting junction.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
CloseHandle(hFile);
return -1;
}
@@ -754,7 +751,7 @@ NativeWriteReparse(
* Error creating directory.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return -1;
}
hFile = CreateFileW(linkDirPath, GENERIC_WRITE, 0, NULL,
@@ -765,7 +762,7 @@ NativeWriteReparse(
* Error creating directory.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return -1;
}
@@ -780,7 +777,7 @@ NativeWriteReparse(
* Error setting junction.
*/
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
CloseHandle(hFile);
RemoveDirectoryW(linkDirPath);
return -1;
@@ -811,7 +808,7 @@ NativeWriteReparse(
*----------------------------------------------------------------------
*/
-MODULE_SCOPE TCL_NORETURN void
+void
tclWinDebugPanic(
const char *format, ...)
{
@@ -841,16 +838,6 @@ tclWinDebugPanic(
MessageBoxW(NULL, msgString, L"Fatal Error",
MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
}
-#if defined(__GNUC__)
- __builtin_trap();
-#elif defined(_WIN64)
- __debugbreak();
-#elif defined(_MSC_VER) && defined (_M_IX86)
- _asm {int 3}
-#else
- DebugBreak();
-#endif
- abort();
}
/*
@@ -872,25 +859,15 @@ tclWinDebugPanic(
void
TclpFindExecutable(
- const char *argv0) /* If NULL, install PanicMessageBox, otherwise
- * ignore. */
+ TCL_UNUSED(const char *))
{
WCHAR wName[MAX_PATH];
char name[MAX_PATH * 3];
- /*
- * Under Windows we ignore argv0, and return the path for the file used to
- * create this process. Only if it is NULL, install a new panic handler.
- */
-
- if (argv0 == NULL) {
- Tcl_SetPanicProc(tclWinDebugPanic);
- }
-
GetModuleFileNameW(NULL, wName, sizeof(wName)/sizeof(WCHAR));
WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, sizeof(name), NULL, NULL);
TclWinNoBackslash(name);
- TclSetObjNameOfExecutable(Tcl_NewStringObj(name, -1), NULL);
+ TclSetObjNameOfExecutable(Tcl_NewStringObj(name, TCL_INDEX_NONE), NULL);
}
/*
@@ -940,14 +917,14 @@ TclpMatchInDirectory(
* Match a single file directly.
*/
- int len;
DWORD attr;
WIN32_FILE_ATTRIBUTE_DATA data;
+ Tcl_Size len = 0;
const char *str;
if (norm != pathPtr) { Tcl_IncrRefCount(norm); }
str = TclGetStringFromObj(norm, &len);
- native = (WCHAR *)Tcl_FSGetNativePath(pathPtr);
+ native = (const WCHAR *)Tcl_FSGetNativePath(pathPtr);
if (GetFileAttributesExW(native,
GetFileExInfoStandard, &data) != TRUE) {
@@ -956,7 +933,7 @@ 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);
}
if (norm != pathPtr) { Tcl_DecrRefCount(norm); }
@@ -968,7 +945,7 @@ TclpMatchInDirectory(
WIN32_FIND_DATAW data;
const char *dirName; /* UTF-8 dir name, later with pattern
* appended. */
- int dirLength;
+ Tcl_Size dirLength;
int matchSpecialDots;
Tcl_DString ds; /* Native encoding of dir, also used
* temporarily for other things. */
@@ -1000,7 +977,7 @@ TclpMatchInDirectory(
attr = GetFileAttributesW(native);
if ((attr == INVALID_FILE_ATTRIBUTES)
- || ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
+ || ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
if (fileNamePtr != pathPtr) { Tcl_DecrRefCount(fileNamePtr); }
return TCL_OK;
}
@@ -1011,7 +988,7 @@ TclpMatchInDirectory(
*/
Tcl_DStringInit(&dsOrig);
- dirName = Tcl_GetStringFromObj(fileNamePtr, &dirLength);
+ dirName = TclGetStringFromObj(fileNamePtr, &dirLength);
Tcl_DStringAppend(&dsOrig, dirName, dirLength);
lastChar = dirName[dirLength -1];
@@ -1035,12 +1012,13 @@ TclpMatchInDirectory(
* pattern.
*/
- dirName = Tcl_DStringAppend(&dsOrig, pattern, -1);
+ dirName = Tcl_DStringAppend(&dsOrig, pattern, TCL_INDEX_NONE);
} else {
dirName = TclDStringAppendLiteral(&dsOrig, "*.*");
}
- native = (WCHAR *)Tcl_WinUtfToTChar(dirName, -1, &ds);
+ Tcl_DStringInit(&ds);
+ native = Tcl_UtfToWCharDString(dirName, TCL_INDEX_NONE, &ds);
if ((types == NULL) || (types->type != TCL_GLOB_TYPE_DIR)) {
handle = FindFirstFileW(native, &data);
} else {
@@ -1067,7 +1045,7 @@ TclpMatchInDirectory(
return TCL_OK;
}
- TclWinConvertError(err);
+ Tcl_WinConvertError(err);
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't read directory \"%s\": %s",
@@ -1112,7 +1090,8 @@ TclpMatchInDirectory(
native = data.cFileName;
attr = data.dwFileAttributes;
- utfname = Tcl_WinTCharToUtf((TCHAR *)native, -1, &ds);
+ Tcl_DStringInit(&ds);
+ utfname = Tcl_WCharToUtfDString(native, TCL_INDEX_NONE, &ds);
if (!matchSpecialDots) {
/*
@@ -1254,7 +1233,7 @@ WinIsDrive(
* (not any trailing :).
*/
-static int
+static size_t
WinIsReserved(
const char *path) /* Path in UTF-8 */
{
@@ -1466,23 +1445,23 @@ TclpGetUserHome(
if (domain == NULL) {
const char *ptr;
- /*
- * Treat the current user as a special case because the general case
- * below does not properly retrieve the path. The NetUserGetInfo
- * call returns an empty path and the code defaults to the user's
- * name in the profiles directory. On modern Windows systems, this
- * is generally wrong as when the account is a Microsoft account,
- * for example abcdefghi@outlook.com, the directory name is
- * abcde and not abcdefghi.
- *
- * Note we could have just used env(USERPROFILE) here but
- * the intent is to retrieve (as on Unix) the system's view
- * of the home irrespective of environment settings of HOME
- * and USERPROFILE.
- *
- * Fixing this for the general user needs more investigating but
- * at least for the current user we can use a direct call.
- */
+ /*
+ * Treat the current user as a special case because the general case
+ * below does not properly retrieve the path. The NetUserGetInfo
+ * call returns an empty path and the code defaults to the user's
+ * name in the profiles directory. On modern Windows systems, this
+ * is generally wrong as when the account is a Microsoft account,
+ * for example abcdefghi@outlook.com, the directory name is
+ * abcde and not abcdefghi.
+ *
+ * Note we could have just used env(USERPROFILE) here but
+ * the intent is to retrieve (as on Unix) the system's view
+ * of the home irrespective of environment settings of HOME
+ * and USERPROFILE.
+ *
+ * Fixing this for the general user needs more investigating but
+ * at least for the current user we can use a direct call.
+ */
ptr = TclpGetUserName(&ds);
if (ptr != NULL && strcasecmp(name, ptr) == 0) {
HANDLE hProcess;
@@ -1494,9 +1473,7 @@ TclpGetUserHome(
HANDLE hToken;
if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
if (GetUserProfileDirectoryW(hToken, buf, &nChars)) {
- Tcl_WinTCharToUtf((TCHAR *)buf,
- (nChars-1)*sizeof(WCHAR), bufferPtr);
- result = Tcl_DStringValue(bufferPtr);
+ result = Tcl_WCharToUtfDString(buf, nChars-1, (bufferPtr));
rc = 1;
}
CloseHandle(hToken);
@@ -1505,13 +1482,15 @@ TclpGetUserHome(
}
Tcl_DStringFree(&ds);
} else {
- wName = (WCHAR *)Tcl_WinUtfToTChar(domain + 1, -1, &ds);
+ Tcl_DStringInit(&ds);
+ wName = Tcl_UtfToWCharDString(domain + 1, TCL_INDEX_NONE, &ds);
rc = NetGetDCName(NULL, wName, (LPBYTE *) &wDomain);
Tcl_DStringFree(&ds);
nameLen = domain - name;
}
if (rc == 0) {
- wName = (WCHAR *)Tcl_WinUtfToTChar(name, nameLen, &ds);
+ Tcl_DStringInit(&ds);
+ wName = Tcl_UtfToWCharDString(name, nameLen, &ds);
while (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) &uiPtr) != 0) {
/*
* User does not exist; if domain was not specified, try again
@@ -1539,7 +1518,7 @@ TclpGetUserHome(
wHomeDir = uiPtr->usri1_home_dir;
if ((wHomeDir != NULL) && (wHomeDir[0] != '\0')) {
size = lstrlenW(wHomeDir);
- Tcl_WinTCharToUtf((TCHAR *)wHomeDir, size*sizeof(WCHAR), bufferPtr);
+ Tcl_WCharToUtfDString(wHomeDir, size, bufferPtr);
} else {
WCHAR buf[MAX_PATH];
/*
@@ -1548,7 +1527,7 @@ TclpGetUserHome(
*/
GetProfilesDirectoryW(buf, &size);
- Tcl_WinTCharToUtf((TCHAR *)buf, (size-1)*sizeof(WCHAR), bufferPtr);
+ Tcl_WCharToUtfDString(buf, size-1, bufferPtr);
Tcl_DStringAppend(bufferPtr, "/", 1);
Tcl_DStringAppend(bufferPtr, name, nameLen);
}
@@ -1563,12 +1542,12 @@ TclpGetUserHome(
result[i] = '/';
}
}
- NetApiBufferFree((void *) uiPtr);
+ NetApiBufferFree((void *)uiPtr);
}
Tcl_DStringFree(&ds);
}
if (wDomain != NULL) {
- NetApiBufferFree((void *) wDomain);
+ NetApiBufferFree((void *)wDomain);
}
return result;
@@ -1609,7 +1588,7 @@ NativeAccess(
DWORD lasterror = GetLastError();
if (lasterror != ERROR_SHARING_VIOLATION) {
- TclWinConvertError(lasterror);
+ Tcl_WinConvertError(lasterror);
return -1;
}
}
@@ -1735,7 +1714,7 @@ NativeAccess(
* to EACCES - just what we want!
*/
- TclWinConvertError((DWORD) error);
+ Tcl_WinConvertError((DWORD) error);
return -1;
}
@@ -1840,7 +1819,7 @@ NativeAccess(
*/
accessError:
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
if (sdPtr != NULL) {
HeapFree(GetProcessHeap(), 0, sdPtr);
}
@@ -1883,7 +1862,7 @@ static int
NativeIsExec(
const WCHAR *path)
{
- size_t len = wcslen(path);
+ int len = wcslen(path);
if (len < 5) {
return 0;
@@ -1934,7 +1913,7 @@ TclpObjChdir(
result = SetCurrentDirectoryW(nativePath);
if (result == 0) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return -1;
}
return 0;
@@ -1973,7 +1952,7 @@ TclpGetCwd(
WCHAR *native;
if (GetCurrentDirectoryW(MAX_PATH, buffer) == 0) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"error getting working directory name: %s",
@@ -1991,7 +1970,8 @@ TclpGetCwd(
&& (native[2] == '\\') && (native[3] == '\\')) {
native += 2;
}
- Tcl_WinTCharToUtf((TCHAR *) native, -1, bufferPtr);
+ Tcl_DStringInit(bufferPtr);
+ Tcl_WCharToUtfDString(native, TCL_INDEX_NONE, bufferPtr);
/*
* Convert to forward slashes for easier use in scripts.
@@ -2081,30 +2061,30 @@ NativeStat(
BY_HANDLE_FILE_INFORMATION data;
if (GetFileInformationByHandle(fileHandle,&data) != TRUE) {
- fileType = GetFileType(fileHandle);
- CloseHandle(fileHandle);
- if (fileType != FILE_TYPE_CHAR && fileType != FILE_TYPE_DISK) {
- Tcl_SetErrno(ENOENT);
- return -1;
- }
-
- /*
+ fileType = GetFileType(fileHandle);
+ CloseHandle(fileHandle);
+ if (fileType != FILE_TYPE_CHAR && fileType != FILE_TYPE_DISK) {
+ Tcl_SetErrno(ENOENT);
+ return -1;
+ }
+
+ /*
* Mock up the expected structure
*/
- memset(&data, 0, sizeof(data));
- statPtr->st_atime = 0;
- statPtr->st_mtime = 0;
- statPtr->st_ctime = 0;
- } else {
- CloseHandle(fileHandle);
- statPtr->st_atime = ToCTime(data.ftLastAccessTime);
- statPtr->st_mtime = ToCTime(data.ftLastWriteTime);
- statPtr->st_ctime = ToCTime(data.ftCreationTime);
- }
+ memset(&data, 0, sizeof(data));
+ statPtr->st_atime = 0;
+ statPtr->st_mtime = 0;
+ statPtr->st_ctime = 0;
+ } else {
+ CloseHandle(fileHandle);
+ statPtr->st_atime = ToCTime(data.ftLastAccessTime);
+ statPtr->st_mtime = ToCTime(data.ftLastWriteTime);
+ statPtr->st_ctime = ToCTime(data.ftCreationTime);
+ }
attr = data.dwFileAttributes;
- statPtr->st_size = ((Tcl_WideInt)data.nFileSizeLow) |
- (((Tcl_WideInt)data.nFileSizeHigh) << 32);
+ statPtr->st_size = ((long long) data.nFileSizeLow) |
+ (((long long) data.nFileSizeHigh) << 32);
/*
* On Unix, for directories, nlink apparently depends on the number of
@@ -2137,12 +2117,12 @@ NativeStat(
DWORD lasterror = GetLastError();
if (lasterror != ERROR_SHARING_VIOLATION) {
- TclWinConvertError(lasterror);
+ Tcl_WinConvertError(lasterror);
return -1;
}
hFind = FindFirstFileW(nativePath, &ffd);
if (hFind == INVALID_HANDLE_VALUE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return -1;
}
memcpy(&data, &ffd, sizeof(data));
@@ -2151,8 +2131,8 @@ NativeStat(
attr = data.dwFileAttributes;
- statPtr->st_size = ((Tcl_WideInt)data.nFileSizeLow) |
- (((Tcl_WideInt)data.nFileSizeHigh) << 32);
+ statPtr->st_size = ((long long) data.nFileSizeLow) |
+ (((long long) data.nFileSizeHigh) << 32);
statPtr->st_atime = ToCTime(data.ftLastAccessTime);
statPtr->st_mtime = ToCTime(data.ftLastWriteTime);
statPtr->st_ctime = ToCTime(data.ftCreationTime);
@@ -2161,11 +2141,11 @@ NativeStat(
dev = NativeDev(nativePath);
mode = NativeStatMode(attr, checkLinks, NativeIsExec(nativePath));
if (fileType == FILE_TYPE_CHAR) {
- mode &= ~S_IFMT;
- mode |= S_IFCHR;
+ mode &= ~S_IFMT;
+ mode |= S_IFCHR;
} else if (fileType == FILE_TYPE_DISK) {
- mode &= ~S_IFMT;
- mode |= S_IFBLK;
+ mode &= ~S_IFMT;
+ mode |= S_IFBLK;
}
statPtr->st_dev = (dev_t) dev;
@@ -2199,7 +2179,8 @@ NativeDev(
const char *fullPath;
GetFullPathNameW(nativePath, MAX_PATH, nativeFullPath, &nativePart);
- fullPath = Tcl_WinTCharToUtf((TCHAR *)nativeFullPath, -1, &ds);
+ Tcl_DStringInit(&ds);
+ fullPath = Tcl_WCharToUtfDString(nativeFullPath, TCL_INDEX_NONE, &ds);
if ((fullPath[0] == '\\') && (fullPath[1] == '\\')) {
const char *p;
@@ -2220,7 +2201,8 @@ NativeDev(
} else {
p++;
}
- nativeVol = (WCHAR *)Tcl_WinUtfToTChar(fullPath, p - fullPath, &volString);
+ Tcl_DStringInit(&volString);
+ nativeVol = Tcl_UtfToWCharDString(fullPath, p - fullPath, &volString);
dw = (DWORD) -1;
GetVolumeInformationW(nativeVol, NULL, 0, &dw, NULL, NULL, NULL, 0);
@@ -2294,7 +2276,7 @@ NativeStatMode(
*
* ToCTime --
*
- * Converts a Windows FILETIME to a time_t in UTC.
+ * Converts a Windows FILETIME to a __time64_t in UTC.
*
* Results:
* Returns the count of seconds from the Posix epoch.
@@ -2302,7 +2284,7 @@ NativeStatMode(
*------------------------------------------------------------------------
*/
-static time_t
+static __time64_t
ToCTime(
FILETIME fileTime) /* UTC time */
{
@@ -2311,8 +2293,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 (__time64_t) ((convertedTime.QuadPart -
+ (long long) POSIX_EPOCH_AS_FILETIME) / (long long) 10000000);
}
/*
@@ -2320,7 +2302,7 @@ ToCTime(
*
* FromCTime --
*
- * Converts a time_t to a Windows FILETIME
+ * Converts a __time64_t to a Windows FILETIME
*
* Results:
* Returns the count of 100-ns ticks seconds from the Windows epoch.
@@ -2330,7 +2312,7 @@ ToCTime(
static void
FromCTime(
- time_t posixTime,
+ __time64_t posixTime,
FILETIME *fileTime) /* UTC Time */
{
LARGE_INTEGER convertedTime;
@@ -2362,14 +2344,14 @@ FromCTime(
*----------------------------------------------------------------------
*/
-ClientData
+void *
TclpGetNativeCwd(
- ClientData clientData)
+ void *clientData)
{
WCHAR buffer[MAX_PATH];
if (GetCurrentDirectoryW(MAX_PATH, buffer) == 0) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return NULL;
}
@@ -2480,12 +2462,12 @@ TclpFilesystemPathType(
if (normPath == NULL) {
return NULL;
}
- path = Tcl_GetString(normPath);
+ path = TclGetString(normPath);
if (path == NULL) {
return NULL;
}
- firstSeparator = strchr(path, '/');
+ firstSeparator = strchr((char *)path, '/');
if (firstSeparator == NULL) {
found = GetVolumeInformationW((const WCHAR *)Tcl_FSGetNativePath(pathPtr),
NULL, 0, NULL, NULL, NULL, volType, VOL_BUF_SIZE);
@@ -2503,8 +2485,9 @@ TclpFilesystemPathType(
} else {
Tcl_DString ds;
- Tcl_WinTCharToUtf((TCHAR *)volType, -1, &ds);
- return TclDStringToObj(&ds);
+ Tcl_DStringInit(&ds);
+ Tcl_WCharToUtfDString(volType, TCL_INDEX_NONE, &ds);
+ return Tcl_DStringToObj(&ds);
}
#undef VOL_BUF_SIZE
}
@@ -2546,7 +2529,7 @@ TclpFilesystemPathType(
int
TclpObjNormalizePath(
- Tcl_Interp *interp, /* not used */
+ TCL_UNUSED(Tcl_Interp *),
Tcl_Obj *pathPtr, /* An unshared object containing the path to
* normalize */
int nextCheckpoint) /* offset to start at in pathPtr */
@@ -2557,10 +2540,9 @@ TclpObjNormalizePath(
Tcl_Obj *temp = NULL;
int isDrive = 1;
Tcl_DString ds; /* Some workspace. */
- (void)interp;
Tcl_DStringInit(&dsNorm);
- path = Tcl_GetString(pathPtr);
+ path = TclGetString(pathPtr);
currentPathEndPosition = path + nextCheckpoint;
if (*currentPathEndPosition == '/') {
@@ -2575,7 +2557,10 @@ TclpObjNormalizePath(
*/
WIN32_FILE_ATTRIBUTE_DATA data;
- const WCHAR *nativePath = (WCHAR *)Tcl_WinUtfToTChar(path,
+ const WCHAR *nativePath;
+
+ Tcl_DStringInit(&ds);
+ nativePath = Tcl_UtfToWCharDString(path,
currentPathEndPosition - path, &ds);
if (GetFileAttributesExW(nativePath,
@@ -2585,14 +2570,14 @@ TclpObjNormalizePath(
*/
if (isDrive) {
- int len = WinIsReserved(path);
+ size_t len = WinIsReserved(path);
if (len > 0) {
/*
* Actually it does exist - COM1, etc.
*/
- int i;
+ size_t i;
for (i=0 ; i<len ; i++) {
WCHAR wc = ((WCHAR *)nativePath)[i];
@@ -2604,7 +2589,7 @@ TclpObjNormalizePath(
}
Tcl_DStringAppend(&dsNorm,
(const char *)nativePath,
- (int)(sizeof(WCHAR) * len));
+ sizeof(WCHAR) * len);
lastValidPathEnd = currentPathEndPosition;
} else if (nextCheckpoint == 0) {
/*
@@ -2649,18 +2634,18 @@ TclpObjNormalizePath(
*/
nextCheckpoint = 0;
- Tcl_AppendToObj(to, currentPathEndPosition, -1);
+ Tcl_AppendToObj(to, currentPathEndPosition, TCL_INDEX_NONE);
/*
* Convert link to forward slashes.
*/
- for (path = Tcl_GetString(to); *path != 0; path++) {
+ for (path = TclGetString(to); *path != 0; path++) {
if (*path == '\\') {
*path = '/';
}
}
- path = Tcl_GetString(to);
+ path = TclGetString(to);
currentPathEndPosition = path + nextCheckpoint;
if (temp != NULL) {
Tcl_DecrRefCount(temp);
@@ -2750,7 +2735,7 @@ TclpObjNormalizePath(
sizeof(WCHAR));
Tcl_DStringAppend(&dsNorm,
(const char *) nativeName,
- (int) (wcslen(nativeName)*sizeof(WCHAR)));
+ wcslen(nativeName)*sizeof(WCHAR));
}
}
}
@@ -2775,24 +2760,25 @@ TclpObjNormalizePath(
* Convert the entire known path to long form.
*/
- if (1) {
- WCHAR wpath[MAX_PATH];
- const WCHAR *nativePath =
- Tcl_WinUtfToTChar(path, lastValidPathEnd - path, &ds);
- DWORD wpathlen = GetLongPathNameProc(nativePath,
- (WCHAR *) wpath, MAX_PATH);
+ WCHAR wpath[MAX_PATH];
+ const WCHAR *nativePath;
+ DWORD wpathlen;
- /*
- * We have to make the drive letter uppercase.
- */
+ Tcl_DStringInit(&ds);
+ nativePath =
+ Tcl_UtfToWCharDString(path, lastValidPathEnd - path, &ds);
+ wpathlen = GetLongPathNameProc(nativePath,
+ (WCHAR *) wpath, MAX_PATH);
+ /*
+ * We have to make the drive letter uppercase.
+ */
- if (wpath[0] >= 'a') {
- wpath[0] -= ('a' - 'A');
- }
- Tcl_DStringAppend(&dsNorm, (const char *) wpath,
- wpathlen * sizeof(WCHAR));
- Tcl_DStringFree(&ds);
+ if (wpath[0] >= 'a') {
+ wpath[0] -= ('a' - 'A');
}
+ Tcl_DStringAppend(&dsNorm, (const char *) wpath,
+ wpathlen * sizeof(WCHAR));
+ Tcl_DStringFree(&ds);
#endif /* TclNORM_LONG_PATH */
}
@@ -2808,21 +2794,22 @@ TclpObjNormalizePath(
* native encoding, so we have to convert it to Utf.
*/
- Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&dsNorm),
- Tcl_DStringLength(&dsNorm), &ds);
+ Tcl_DStringInit(&ds);
+ Tcl_WCharToUtfDString((const WCHAR *) Tcl_DStringValue(&dsNorm),
+ Tcl_DStringLength(&dsNorm)>>1, &ds);
nextCheckpoint = Tcl_DStringLength(&ds);
if (*lastValidPathEnd != 0) {
/*
* Not the end of the string.
*/
- int len;
Tcl_Obj *tmpPathPtr;
+ Tcl_Size len;
tmpPathPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds),
nextCheckpoint);
- Tcl_AppendToObj(tmpPathPtr, lastValidPathEnd, -1);
- path = Tcl_GetStringFromObj(tmpPathPtr, &len);
+ Tcl_AppendToObj(tmpPathPtr, lastValidPathEnd, TCL_INDEX_NONE);
+ path = TclGetStringFromObj(tmpPathPtr, &len);
Tcl_SetStringObj(pathPtr, path, len);
Tcl_DecrRefCount(tmpPathPtr);
} else {
@@ -2891,10 +2878,10 @@ TclWinVolumeRelativeNormalize(
* current volume.
*/
- const char *drive = Tcl_GetString(useThisCwd);
+ const char *drive = TclGetString(useThisCwd);
absolutePath = Tcl_NewStringObj(drive,2);
- Tcl_AppendToObj(absolutePath, path, -1);
+ Tcl_AppendToObj(absolutePath, path, TCL_INDEX_NONE);
Tcl_IncrRefCount(absolutePath);
/*
@@ -2906,9 +2893,8 @@ TclWinVolumeRelativeNormalize(
* also on drive C.
*/
- int cwdLen;
- const char *drive =
- Tcl_GetStringFromObj(useThisCwd, &cwdLen);
+ Tcl_Size cwdLen;
+ const char *drive = TclGetStringFromObj(useThisCwd, &cwdLen);
char drive_cur = path[0];
if (drive_cur >= 'a') {
@@ -2948,7 +2934,7 @@ TclWinVolumeRelativeNormalize(
Tcl_AppendToObj(absolutePath, "/", 1);
}
Tcl_IncrRefCount(absolutePath);
- Tcl_AppendToObj(absolutePath, path+2, -1);
+ Tcl_AppendToObj(absolutePath, path+2, TCL_INDEX_NONE);
}
*useThisCwdPtr = useThisCwd;
return absolutePath;
@@ -2977,14 +2963,15 @@ TclWinVolumeRelativeNormalize(
Tcl_Obj *
TclpNativeToNormalized(
- ClientData clientData)
+ void *clientData)
{
Tcl_DString ds;
Tcl_Obj *objPtr;
- int len;
+ size_t len;
char *copy, *p;
- Tcl_WinTCharToUtf((TCHAR *) clientData, -1, &ds);
+ Tcl_DStringInit(&ds);
+ Tcl_WCharToUtfDString((const WCHAR *) clientData, TCL_INDEX_NONE, &ds);
copy = Tcl_DStringValue(&ds);
len = Tcl_DStringLength(&ds);
@@ -3036,17 +3023,15 @@ TclpNativeToNormalized(
*---------------------------------------------------------------------------
*/
-ClientData
+void *
TclNativeCreateNativeRep(
Tcl_Obj *pathPtr)
{
WCHAR *nativePathPtr = NULL;
const char *str;
Tcl_Obj *validPathPtr;
- int len;
+ Tcl_Size len;
WCHAR *wp;
- Tcl_DString ds;
- Tcl_Encoding utf8;
if (TclFSCwdIsNative() || Tcl_FSGetPathType(pathPtr) == TCL_PATH_ABSOLUTE) {
/*
@@ -3082,11 +3067,7 @@ TclNativeCreateNativeRep(
Tcl_IncrRefCount(validPathPtr);
}
- utf8 = Tcl_GetEncoding(NULL, "utf-8");
- str = Tcl_GetStringFromObj(validPathPtr, &len);
- str = Tcl_UtfToExternalDString(utf8, str, len, &ds);
- len = Tcl_DStringLength(&ds);
- Tcl_FreeEncoding(utf8);
+ str = TclGetStringFromObj(validPathPtr, &len);
if (strlen(str) != (size_t)len) {
/*
@@ -3117,9 +3098,9 @@ TclNativeCreateNativeRep(
* Overallocate 6 chars, making some room for extended paths
*/
- wp = nativePathPtr = (WCHAR *)ckalloc((len + 6) * sizeof(WCHAR));
+ wp = nativePathPtr = (WCHAR *)Tcl_Alloc((len + 6) * sizeof(WCHAR));
if (nativePathPtr==0) {
- goto done;
+ goto done;
}
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, nativePathPtr,
len + 2);
@@ -3182,7 +3163,6 @@ TclNativeCreateNativeRep(
}
done:
- Tcl_DStringFree(&ds);
TclDecrRefCount(validPathPtr);
return nativePathPtr;
}
@@ -3204,9 +3184,9 @@ TclNativeCreateNativeRep(
*---------------------------------------------------------------------------
*/
-ClientData
+void *
TclNativeDupInternalRep(
- ClientData clientData)
+ void *clientData)
{
char *copy;
size_t len;
@@ -3217,7 +3197,7 @@ TclNativeDupInternalRep(
len = sizeof(WCHAR) * (wcslen((const WCHAR *) clientData) + 1);
- copy = (char *)ckalloc(len);
+ copy = (char *)Tcl_Alloc(len);
memcpy(copy, clientData, len);
return copy;
}
@@ -3272,7 +3252,7 @@ TclpUtime(
if (fileHandle == INVALID_HANDLE_VALUE ||
!SetFileTime(fileHandle, NULL, &lastAccessTime, &lastModTime)) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
res = -1;
}
if (fileHandle != INVALID_HANDLE_VALUE) {
@@ -3310,12 +3290,12 @@ TclWinFileOwned(
if (GetNamedSecurityInfoW((LPWSTR) native, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION, &ownerSid, NULL, NULL, NULL,
&secd) != ERROR_SUCCESS) {
- /*
+ /*
* Either not a file, or we do not have access to it in which case we
* are in all likelihood not the owner.
*/
- return 0;
+ return 0;
}
/*
@@ -3326,19 +3306,19 @@ TclWinFileOwned(
*/
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
- /*
+ /*
* Find out how big the buffer needs to be.
*/
- bufsz = 0;
- GetTokenInformation(token, TokenUser, NULL, 0, &bufsz);
- if (bufsz) {
- buf = (LPBYTE)ckalloc(bufsz);
- if (GetTokenInformation(token, TokenUser, buf, bufsz, &bufsz)) {
- owned = EqualSid(ownerSid, ((PTOKEN_USER) buf)->User.Sid);
- }
- }
- CloseHandle(token);
+ bufsz = 0;
+ GetTokenInformation(token, TokenUser, NULL, 0, &bufsz);
+ if (bufsz) {
+ buf = (LPBYTE)Tcl_Alloc(bufsz);
+ if (GetTokenInformation(token, TokenUser, buf, bufsz, &bufsz)) {
+ owned = EqualSid(ownerSid, ((PTOKEN_USER) buf)->User.Sid);
+ }
+ }
+ CloseHandle(token);
}
/*
@@ -3346,10 +3326,10 @@ TclWinFileOwned(
*/
if (secd) {
- LocalFree(secd); /* Also frees ownerSid */
+ LocalFree(secd); /* Also frees ownerSid */
}
if (buf) {
- ckfree(buf);
+ Tcl_Free(buf);
}
return (owned != 0); /* Convert non-0 to 1 */
diff --git a/win/tclWinInit.c b/win/tclWinInit.c
index 29e177d..b3ea057 100644
--- a/win/tclWinInit.c
+++ b/win/tclWinInit.c
@@ -3,8 +3,8 @@
*
* Contains the Windows-specific interpreter initialization functions.
*
- * Copyright (c) 1994-1997 Sun Microsystems, Inc.
- * Copyright (c) 1998-1999 Scriptics Corporation.
+ * Copyright © 1994-1997 Sun Microsystems, Inc.
+ * Copyright © 1998-1999 Scriptics Corporation.
* All rights reserved.
*
* See the file "license.terms" for information on usage and redistribution of
@@ -12,6 +12,7 @@
*/
#include "tclWinInt.h"
+#include <assert.h>
#include <winnt.h>
#include <winbase.h>
#include <lmcons.h>
@@ -36,11 +37,6 @@ typedef struct {
} OemId;
/*
- * Windows version dependend functions
- */
-TclWinProcs tclWinProcs;
-
-/*
* The following arrays contain the human readable strings for the
* processor values.
*/
@@ -68,8 +64,131 @@ static ProcessGlobalValue defaultLibraryDir =
{0, 0, NULL, NULL, InitializeDefaultLibraryDir, NULL, NULL};
static ProcessGlobalValue sourceLibraryDir =
{0, 0, NULL, NULL, InitializeSourceLibraryDir, NULL, NULL};
+
/*
+ * TclpGetWindowsVersionOnce --
+ *
+ * Callback to retrieve Windows version information. To be invoked only
+ * through InitOnceExecuteOnce for thread safety.
+ *
+ * Results:
+ * None.
+ */
+static BOOL CALLBACK TclpGetWindowsVersionOnce(
+ TCL_UNUSED(PINIT_ONCE),
+ TCL_UNUSED(PVOID),
+ PVOID *lpContext)
+{
+ typedef int(__stdcall getVersionProc)(void *);
+ static OSVERSIONINFOW osInfo;
+
+ /*
+ * GetVersionExW will not return the "real" Windows version so use
+ * RtlGetVersion if available and falling back.
+ */
+ HMODULE handle = GetModuleHandleW(L"NTDLL");
+ getVersionProc *getVersion =
+ (getVersionProc *)(void *)GetProcAddress(handle, "RtlGetVersion");
+
+ osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
+ if (getVersion == NULL || getVersion(&osInfo)) {
+ if (!GetVersionExW(&osInfo)) {
+ /* Should never happen but ...*/
+ return FALSE;
+ }
+ }
+ *lpContext = (LPVOID)&osInfo;
+ return TRUE;
+}
+
+/*
+ * TclpGetWindowsVersion --
+ *
+ * Returns a pointer to the OSVERSIONINFOW structure containing the
+ * version information for the current Windows version.
+ *
+ * Results:
+ * Pointer to OSVERSIONINFOW structure.
+ */
+static const OSVERSIONINFOW *TclpGetWindowsVersion(void)
+{
+ static INIT_ONCE osInfoOnce = INIT_ONCE_STATIC_INIT;
+ OSVERSIONINFOW *osInfoPtr = NULL;
+ BOOL result = InitOnceExecuteOnce(
+ &osInfoOnce, TclpGetWindowsVersionOnce, NULL, (LPVOID *)&osInfoPtr);
+ return result ? osInfoPtr : NULL;
+}
+
+/*
+ * TclpGetCodePageOnce --
+ *
+ * Callback to retrieve user code page. To be invoked only
+ * through InitOnceExecuteOnce for thread safety.
+ *
+ * Results:
+ * None.
+ */
+static BOOL CALLBACK
+TclpGetCodePageOnce(
+ TCL_UNUSED(PINIT_ONCE),
+ TCL_UNUSED(PVOID),
+ PVOID *lpContext)
+{
+ static char codePage[20];
+ codePage[0] = 'c';
+ codePage[1] = 'p';
+ DWORD size = sizeof(codePage) - 2;
+
+ /*
+ * When retrieving code page from registry,
+ * - use ANSI API's since all values will be ASCII and saves conversion
+ * - use RegGetValue, not RegQueryValueEx, since the latter does not
+ * guarantee the value is null terminated
+ * - added bonus, RegGetValue is much more convenient to use
+ */
+ if (RegGetValueA(HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage",
+ "ACP", RRF_RT_REG_SZ, NULL, codePage+2,
+ &size) != ERROR_SUCCESS) {
+ /* On failure, fallback to GetACP() */
+ UINT acp = GetACP();
+ snprintf(codePage, sizeof(codePage), "cp%u", acp);
+ }
+ if (strcmp(codePage, "cp65001") == 0) {
+ strcpy(codePage, "utf-8");
+ }
+ *lpContext = (LPVOID)&codePage[0];
+ return TRUE;
+}
+
+/*
+ * TclpGetCodePage --
+ *
+ * Returns a pointer to the string identifying the user code page.
+ *
+ * For consistency with Windows, which caches the code page at program
+ * startup, the code page is not updated even if the value in the registry
+ * changes. (This is similar to environment variables.)
+ */
+static const char *
+TclpGetCodePage(void)
+{
+ static INIT_ONCE codePageOnce = INIT_ONCE_STATIC_INIT;
+ const char *codePagePtr = NULL;
+ BOOL result = InitOnceExecuteOnce(
+ &codePageOnce, TclpGetCodePageOnce, NULL, (LPVOID *)&codePagePtr);
+#ifdef NDEBUG
+ (void) result; /* Keep gcc unused variable quiet */
+#else
+ assert(result == TRUE);
+#endif
+ assert(codePagePtr != NULL);
+ return codePagePtr;
+}
+
+
+/*
*---------------------------------------------------------------------------
*
* TclpInitPlatform --
@@ -93,7 +212,6 @@ TclpInitPlatform(void)
{
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2);
- HMODULE handle;
tclPlatform = TCL_PLATFORM_WINDOWS;
@@ -113,18 +231,10 @@ TclpInitPlatform(void)
TclWinInit(GetModuleHandleW(NULL));
#endif
- /*
- * Fill available functions depending on windows version
- */
- handle = GetModuleHandleW(L"KERNEL32");
- tclWinProcs.cancelSynchronousIo =
- (BOOL (WINAPI *)(HANDLE))(void *)GetProcAddress(handle,
- "CancelSynchronousIo");
- tclWinProcs.createSymbolicLink =
- (BOOLEAN (WINAPI *)(LPCWSTR, LPCWSTR, DWORD))(void *)GetProcAddress(handle,
- "CreateSymbolicLinkW");
+ /* Initialize code page once at startup, will not be updated */
+ (void)TclpGetCodePage();
}
-
+
/*
*-------------------------------------------------------------------------
*
@@ -145,14 +255,14 @@ TclpInitPlatform(void)
void
TclpInitLibraryPath(
char **valuePtr,
- int *lengthPtr,
+ size_t *lengthPtr,
Tcl_Encoding *encodingPtr)
{
#define LIBRARY_SIZE 64
Tcl_Obj *pathPtr;
char installLib[LIBRARY_SIZE];
const char *bytes;
- int length;
+ Tcl_Size length;
TclNewObj(pathPtr);
@@ -190,7 +300,7 @@ TclpInitLibraryPath(
*encodingPtr = NULL;
bytes = TclGetStringFromObj(pathPtr, &length);
*lengthPtr = length++;
- *valuePtr = (char *)ckalloc(length);
+ *valuePtr = (char *)Tcl_Alloc(length);
memcpy(*valuePtr, bytes, length);
Tcl_DecrRefCount(pathPtr);
}
@@ -202,8 +312,8 @@ TclpInitLibraryPath(
*
* 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.
- * "tcl9.0") also append the path to this version (e.g.,
- * "tcl9.0/../tcl8.6")
+ * "tcl8.6") also append the path to this version (e.g.,
+ * "tcl8.6/../tcl9.0")
*
* Results:
* None.
@@ -219,7 +329,7 @@ AppendEnvironment(
Tcl_Obj *pathPtr,
const char *lib)
{
- int pathc;
+ Tcl_Size pathc;
WCHAR wBuf[MAX_PATH];
char buf[MAX_PATH * 3];
Tcl_Obj *objPtr;
@@ -229,7 +339,7 @@ AppendEnvironment(
/*
* The shortlib value needs to be the tail component of the lib path. For
- * example, "lib/tcl8.6" -> "tcl8.6" while "usr/share/tcl8.6" -> "tcl8.6".
+ * example, "lib/tcl9.0" -> "tcl9.0" while "usr/share/tcl9.0" -> "tcl9.0".
*/
for (shortlib = (char *) &lib[strlen(lib)-1]; shortlib>lib ; shortlib--) {
@@ -254,7 +364,7 @@ AppendEnvironment(
WideCharToMultiByte(CP_UTF8, 0, wBuf, -1, buf, MAX_PATH * 3, NULL, NULL);
if (buf[0] != '\0') {
- objPtr = Tcl_NewStringObj(buf, -1);
+ objPtr = Tcl_NewStringObj(buf, TCL_INDEX_NONE);
Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
TclWinNoBackslash(buf);
@@ -276,12 +386,12 @@ AppendEnvironment(
pathv[pathc - 1] = shortlib;
Tcl_DStringInit(&ds);
(void) Tcl_JoinPath(pathc, pathv, &ds);
- objPtr = TclDStringToObj(&ds);
+ objPtr = Tcl_DStringToObj(&ds);
} else {
- objPtr = Tcl_NewStringObj(buf, -1);
+ objPtr = Tcl_NewStringObj(buf, TCL_INDEX_NONE);
}
Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
- ckfree(pathv);
+ Tcl_Free((void *)pathv);
}
}
@@ -305,7 +415,7 @@ AppendEnvironment(
static void
InitializeDefaultLibraryDir(
char **valuePtr,
- int *lengthPtr,
+ size_t *lengthPtr,
Tcl_Encoding *encodingPtr)
{
HMODULE hModule = (HMODULE)TclWinGetTclInstance();
@@ -327,7 +437,7 @@ InitializeDefaultLibraryDir(
TclWinNoBackslash(name);
snprintf(end + 1, LIBRARY_SIZE, "lib/tcl%s", TCL_VERSION);
*lengthPtr = strlen(name);
- *valuePtr = (char *)ckalloc(*lengthPtr + 1);
+ *valuePtr = (char *)Tcl_Alloc(*lengthPtr + 1);
*encodingPtr = NULL;
memcpy(*valuePtr, name, *lengthPtr + 1);
}
@@ -353,7 +463,7 @@ InitializeDefaultLibraryDir(
static void
InitializeSourceLibraryDir(
char **valuePtr,
- int *lengthPtr,
+ size_t *lengthPtr,
Tcl_Encoding *encodingPtr)
{
HMODULE hModule = (HMODULE)TclWinGetTclInstance();
@@ -375,7 +485,7 @@ InitializeSourceLibraryDir(
TclWinNoBackslash(name);
snprintf(end + 1, LIBRARY_SIZE, "../library");
*lengthPtr = strlen(name);
- *valuePtr = (char *)ckalloc(*lengthPtr + 1);
+ *valuePtr = (char *)Tcl_Alloc(*lengthPtr + 1);
*encodingPtr = NULL;
memcpy(*valuePtr, name, *lengthPtr + 1);
}
@@ -414,29 +524,32 @@ TclpSetInitialEncodings(void)
Tcl_DStringFree(&encodingName);
}
-void TclWinSetInterfaces(
- int dummy) /* Not used. */
+const char *
+Tcl_GetEncodingNameForUser(Tcl_DString *bufPtr)
{
- (void)dummy;
+ Tcl_DStringInit(bufPtr);
+ Tcl_DStringAppend(bufPtr, TclpGetCodePage(), -1);
+ return Tcl_DStringValue(bufPtr);
}
const char *
Tcl_GetEncodingNameFromEnvironment(
Tcl_DString *bufPtr)
{
- UINT acp = GetACP();
-
- Tcl_DStringInit(bufPtr);
- if (acp == CP_UTF8) {
+ const OSVERSIONINFOW *osInfoPtr = TclpGetWindowsVersion();
+ /*
+ * TIP 716 - for Build 18362 or higher, force utf-8. Note Windows build
+ * numbers always increase, so no need to check major / minor versions.
+ */
+ if (osInfoPtr && osInfoPtr->dwBuildNumber >= 18362) {
+ Tcl_DStringInit(bufPtr);
Tcl_DStringAppend(bufPtr, "utf-8", 5);
+ return Tcl_DStringValue(bufPtr);
} else {
- Tcl_DStringSetLength(bufPtr, 2 + TCL_INTEGER_SPACE);
- snprintf(Tcl_DStringValue(bufPtr), 2 + TCL_INTEGER_SPACE, "cp%d", acp);
- Tcl_DStringSetLength(bufPtr, strlen(Tcl_DStringValue(bufPtr)));
+ return Tcl_GetEncodingNameForUser(bufPtr);
}
- return Tcl_DStringValue(bufPtr);
}
-
+
const char *
TclpGetUserName(
Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with
@@ -452,12 +565,12 @@ TclpGetUserName(
return NULL;
}
cchUserNameLen--;
- cchUserNameLen *= sizeof(WCHAR);
- Tcl_WinTCharToUtf((TCHAR *)szUserName, cchUserNameLen, bufferPtr);
+ Tcl_DStringInit(bufferPtr);
+ Tcl_WCharToUtfDString(szUserName, cchUserNameLen, bufferPtr);
}
return Tcl_DStringValue(bufferPtr);
}
-
+
/*
*---------------------------------------------------------------------------
*
@@ -525,19 +638,6 @@ TclpSetVariables(
TCL_GLOBAL_ONLY);
}
-#ifndef NDEBUG
- /*
- * 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",
- TCL_GLOBAL_ONLY);
-#endif
-
/*
* Set up the HOME environment variable from the HOMEDRIVE & HOMEPATH
* environment variables, if necessary.
@@ -548,11 +648,11 @@ TclpSetVariables(
if (ptr == NULL) {
ptr = Tcl_GetVar2(interp, "env", "HOMEDRIVE", TCL_GLOBAL_ONLY);
if (ptr != NULL) {
- Tcl_DStringAppend(&ds, ptr, -1);
+ Tcl_DStringAppend(&ds, ptr, TCL_INDEX_NONE);
}
ptr = Tcl_GetVar2(interp, "env", "HOMEPATH", TCL_GLOBAL_ONLY);
if (ptr != NULL) {
- Tcl_DStringAppend(&ds, ptr, -1);
+ Tcl_DStringAppend(&ds, ptr, TCL_INDEX_NONE);
}
if (Tcl_DStringLength(&ds) > 0) {
Tcl_SetVar2(interp, "env", "HOME", Tcl_DStringValue(&ds),
@@ -608,16 +708,16 @@ TclpSetVariables(
*----------------------------------------------------------------------
*/
-int
+Tcl_Size
TclpFindVariable(
const char *name, /* Name of desired environment variable
* (UTF-8). */
- int *lengthPtr) /* Used to return length of name (for
+ Tcl_Size *lengthPtr) /* Used to return length of name (for
* successful searches) or number of non-NULL
* entries in environ (for unsuccessful
* searches). */
{
- int i, length, result = -1;
+ Tcl_Size i, length, result = TCL_INDEX_NONE;
const WCHAR *env;
const char *p1, *p2;
char *envUpper, *nameUpper;
@@ -628,7 +728,7 @@ TclpFindVariable(
*/
length = strlen(name);
- nameUpper = (char *)ckalloc(length + 1);
+ nameUpper = (char *)Tcl_Alloc(length + 1);
memcpy(nameUpper, name, length+1);
Tcl_UtfToUpper(nameUpper);
@@ -640,12 +740,13 @@ TclpFindVariable(
* after the equal sign.
*/
- envUpper = Tcl_WinTCharToUtf((TCHAR *)env, -1, &envString);
+ Tcl_DStringInit(&envString);
+ envUpper = Tcl_WCharToUtfDString(env, TCL_INDEX_NONE, &envString);
p1 = strchr(envUpper, '=');
if (p1 == NULL) {
continue;
}
- length = (int) (p1 - envUpper);
+ length = p1 - envUpper;
Tcl_DStringSetLength(&envString, length+1);
Tcl_UtfToUpper(envUpper);
@@ -667,7 +768,7 @@ TclpFindVariable(
done:
Tcl_DStringFree(&envString);
- ckfree(nameUpper);
+ Tcl_Free(nameUpper);
return result;
}
diff --git a/win/tclWinInt.h b/win/tclWinInt.h
index b7974b8..c37daf7 100644
--- a/win/tclWinInt.h
+++ b/win/tclWinInt.h
@@ -32,42 +32,6 @@ typedef struct TCLEXCEPTION_REGISTRATION {
#endif
/*
- * Windows version dependend functions
- */
-typedef struct TclWinProcs {
- BOOL (WINAPI *cancelSynchronousIo)(HANDLE);
- BOOLEAN (WINAPI *createSymbolicLink)(LPCWSTR, LPCWSTR, DWORD);
-} TclWinProcs;
-
-MODULE_SCOPE TclWinProcs tclWinProcs;
-
-/*
- * Some versions of Borland C have a define for the OSVERSIONINFO for
- * Win32s and for NT, but not for Windows 95.
- * Define VER_PLATFORM_WIN32_CE for those without newer headers.
- */
-
-#ifndef VER_PLATFORM_WIN32_WINDOWS
-#define VER_PLATFORM_WIN32_WINDOWS 1
-#endif
-#ifndef VER_PLATFORM_WIN32_CE
-#define VER_PLATFORM_WIN32_CE 3
-#endif
-
-#ifndef TCL_Z_MODIFIER
-# ifdef _WIN64
-# if defined(__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO
-# define TCL_Z_MODIFIER "ll"
-# else
-# define TCL_Z_MODIFIER "I"
-# endif
-# else
-# define TCL_Z_MODIFIER ""
-# endif
-#endif
-#define TCL_I_MODIFIER TCL_Z_MODIFIER
-
-/*
* Declarations of functions that are not accessible by way of the
* stubs table.
*/
@@ -88,14 +52,8 @@ MODULE_SCOPE int TclWinSymLinkCopyDirectory(const WCHAR *LinkOriginal,
MODULE_SCOPE int TclWinSymLinkDelete(const WCHAR *LinkOriginal,
int linkOnly);
MODULE_SCOPE int TclWinFileOwned(Tcl_Obj *);
-#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 *);
-#endif /* TCL_THREADS */
-
+MODULE_SCOPE void TclWinGenerateChannelName(char channelName[],
+ const char *channelTypeName, void *channelImpl);
MODULE_SCOPE const char*TclpGetUserName(Tcl_DString *bufferPtr);
/* Needed by tclWinFile.c and tclWinFCmd.c */
@@ -117,12 +75,10 @@ typedef struct TclPipeThreadInfo {
* to do read/write operation. Additionally
* used as signal to stop (state set to -1) */
volatile LONG state; /* Indicates current state of the thread */
- ClientData clientData; /* Referenced data of the main thread */
- HANDLE evWakeUp; /* Optional wake-up event worker set by shutdown */
+ void *clientData; /* Referenced data of the main thread */
} TclPipeThreadInfo;
-
-/* If pipe-workers will use some tcl subsystem, we can use ckalloc without
+/* If pipe-workers will use some tcl subsystem, we can use Tcl_Alloc without
* more overhead for finalize thread (should be executed anyway)
*
* #define _PTI_USE_CKALLOC 1
@@ -134,18 +90,19 @@ typedef struct TclPipeThreadInfo {
* State PTI_STATE_STOP possible from idle state only, worker owns TI structure.
* Otherwise PTI_STATE_END used (main thread hold ownership of the TI).
*/
-
-#define PTI_STATE_IDLE 0 /* idle or not yet initialzed */
-#define PTI_STATE_WORK 1 /* in work */
-#define PTI_STATE_STOP 2 /* thread should stop work (owns TI structure) */
-#define PTI_STATE_END 4 /* thread should stop work (worker is busy) */
-#define PTI_STATE_DOWN 8 /* worker is down */
-
+enum PipeWorkerStates {
+ PTI_STATE_IDLE = 0, /* idle or not yet initialzed */
+ PTI_STATE_WORK = 1, /* in work */
+ PTI_STATE_STOP = 2, /* thread should stop work (owns TI structure) */
+ PTI_STATE_END = 4, /* thread should stop work (worker is busy) */
+ PTI_STATE_DOWN = 8 /* worker is down */
+};
MODULE_SCOPE
TclPipeThreadInfo * TclPipeThreadCreateTI(TclPipeThreadInfo **pipeTIPtr,
- ClientData clientData, HANDLE wakeEvent);
-MODULE_SCOPE int TclPipeThreadWaitForSignal(TclPipeThreadInfo **pipeTIPtr);
+ void *clientData);
+MODULE_SCOPE int TclPipeThreadWaitForSignal(
+ TclPipeThreadInfo **pipeTIPtr);
static inline void
TclPipeThreadSignal(
@@ -165,8 +122,9 @@ TclPipeThreadIsAlive(
return (pipeTI && pipeTI->state != PTI_STATE_DOWN);
};
-MODULE_SCOPE int TclPipeThreadStopSignal(TclPipeThreadInfo **pipeTIPtr, HANDLE wakeEvent);
-MODULE_SCOPE void TclPipeThreadStop(TclPipeThreadInfo **pipeTIPtr, HANDLE hThread);
+MODULE_SCOPE int TclPipeThreadStopSignal(TclPipeThreadInfo **pipeTIPtr);
+MODULE_SCOPE void TclPipeThreadStop(TclPipeThreadInfo **pipeTIPtr,
+ HANDLE hThread);
MODULE_SCOPE void TclPipeThreadExit(TclPipeThreadInfo **pipeTIPtr);
#endif /* _TCLWININT */
diff --git a/win/tclWinLoad.c b/win/tclWinLoad.c
index b62920b..335e5bc 100644
--- a/win/tclWinLoad.c
+++ b/win/tclWinLoad.c
@@ -5,7 +5,7 @@
* the Windows "LoadLibrary" and "GetProcAddress" API for dynamic
* loading.
*
- * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright © 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.
@@ -20,7 +20,9 @@
*/
static WCHAR *dllDirectoryName = NULL;
+#if TCL_THREADS
static Tcl_Mutex dllDirectoryNameMutex;
+#endif
/*
* Static functions defined within this file.
@@ -61,13 +63,12 @@ TclpDlopen(
/* Filled with address of Tcl_FSUnloadFileProc
* function which should be used for this
* file. */
- int flags)
+ TCL_UNUSED(int) /*flags*/)
{
HINSTANCE hInstance = NULL;
const WCHAR *nativeName;
Tcl_LoadHandle handlePtr;
DWORD firstError;
- (void)flags;
/*
* First try the full path the user gave us. This is particularly
@@ -96,7 +97,8 @@ TclpDlopen(
firstError = (nativeName == NULL) ?
ERROR_MOD_NOT_FOUND : GetLastError();
- nativeName = (WCHAR *)Tcl_WinUtfToTChar(Tcl_GetString(pathPtr), -1, &ds);
+ Tcl_DStringInit(&ds);
+ nativeName = Tcl_UtfToWCharDString(TclGetString(pathPtr), TCL_INDEX_NONE, &ds);
hInstance = LoadLibraryExW(nativeName, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
Tcl_DStringFree(&ds);
@@ -137,31 +139,31 @@ TclpDlopen(
Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_NOT_FOUND", (char *)NULL);
notFoundMsg:
Tcl_AppendToObj(errMsg, "this library or a dependent library"
- " could not be found in library path", -1);
+ " could not be found in library path", TCL_INDEX_NONE);
break;
case ERROR_PROC_NOT_FOUND:
Tcl_SetErrorCode(interp, "WIN_LOAD", "PROC_NOT_FOUND", (char *)NULL);
Tcl_AppendToObj(errMsg, "A function specified in the import"
" table could not be resolved by the system. Windows"
- " is not telling which one, I'm sorry.", -1);
+ " is not telling which one, I'm sorry.", TCL_INDEX_NONE);
break;
case ERROR_INVALID_DLL:
Tcl_SetErrorCode(interp, "WIN_LOAD", "INVALID_DLL", (char *)NULL);
Tcl_AppendToObj(errMsg, "this library or a dependent library"
- " is damaged", -1);
+ " is damaged", TCL_INDEX_NONE);
break;
case ERROR_DLL_INIT_FAILED:
Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_INIT_FAILED", (char *)NULL);
Tcl_AppendToObj(errMsg, "the library initialization"
- " routine failed", -1);
+ " routine failed", TCL_INDEX_NONE);
break;
case ERROR_BAD_EXE_FORMAT:
Tcl_SetErrorCode(interp, "WIN_LOAD", "BAD_EXE_FORMAT", (char *)NULL);
- Tcl_AppendToObj(errMsg, "Bad exe format. Possibly a 32/64-bit mismatch.", -1);
+ Tcl_AppendToObj(errMsg, "Bad exe format. Possibly a 32/64-bit mismatch.", TCL_INDEX_NONE);
break;
default:
- TclWinConvertError(lastError);
- Tcl_AppendToObj(errMsg, Tcl_PosixError(interp), -1);
+ Tcl_WinConvertError(lastError);
+ Tcl_AppendToObj(errMsg, Tcl_PosixError(interp), TCL_INDEX_NONE);
}
Tcl_SetObjResult(interp, errMsg);
}
@@ -172,8 +174,8 @@ TclpDlopen(
* Succeded; package everything up for Tcl.
*/
- handlePtr = (Tcl_LoadHandle)ckalloc(sizeof(struct Tcl_LoadHandle_));
- handlePtr->clientData = hInstance;
+ handlePtr = (Tcl_LoadHandle)Tcl_Alloc(sizeof(struct Tcl_LoadHandle_));
+ handlePtr->clientData = (void *)hInstance;
handlePtr->findSymbolProcPtr = &FindSymbol;
handlePtr->unloadFileProcPtr = &UnloadFile;
*loadHandle = handlePtr;
@@ -218,7 +220,7 @@ FindSymbol(
Tcl_DStringInit(&ds);
TclDStringAppendLiteral(&ds, "_");
- sym2 = Tcl_DStringAppend(&ds, symbol, -1);
+ sym2 = Tcl_DStringAppend(&ds, symbol, TCL_INDEX_NONE);
proc = (void *)GetProcAddress(hInstance, sym2);
Tcl_DStringFree(&ds);
}
@@ -257,40 +259,7 @@ UnloadFile(
HINSTANCE hInstance = (HINSTANCE) loadHandle->clientData;
FreeLibrary(hInstance);
- ckfree(loadHandle);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclGuessPackageName --
- *
- * If the "load" command is invoked without providing a package name,
- * this function 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.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclGuessPackageName(
- 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. */
-{
- (void)fileName;
- (void)bufPtr;
-
- return 0;
+ Tcl_Free(loadHandle);
}
/*
@@ -413,7 +382,7 @@ InitDLLDirectoryName(void)
id *= 16777619;
}
- TclWinConvertError(lastError);
+ Tcl_WinConvertError(lastError);
return TCL_ERROR;
/*
@@ -421,7 +390,7 @@ InitDLLDirectoryName(void)
*/
copyToGlobalBuffer:
- dllDirectoryName = (WCHAR *)ckalloc((nameLen+1) * sizeof(WCHAR));
+ dllDirectoryName = (WCHAR *)Tcl_Alloc((nameLen+1) * sizeof(WCHAR));
wcscpy(dllDirectoryName, name);
return TCL_OK;
}
@@ -436,22 +405,20 @@ InitDLLDirectoryName(void)
MODULE_SCOPE void *
TclpLoadMemoryGetBuffer(
- size_t size) /* Dummy: unused by this implementation */
+ TCL_UNUSED(size_t))
{
return NULL;
}
MODULE_SCOPE int
TclpLoadMemory(
- void *buffer, /* Dummy: unused by this implementation */
- size_t size, /* Dummy: unused by this implementation */
- int codeSize, /* Dummy: unused by this implementation */
- const char *path, /* Dummy: unused by this implementation */
- Tcl_LoadHandle *loadHandle, /* Dummy: unused by this implementation */
- Tcl_FSUnloadFileProc **unloadProcPtr,
- /* Dummy: unused by this implementation */
- int flags)
- /* Dummy: unused by this implementation */
+ TCL_UNUSED(void *),
+ TCL_UNUSED(size_t),
+ TCL_UNUSED(Tcl_Size),
+ TCL_UNUSED(const char *),
+ TCL_UNUSED(Tcl_LoadHandle *),
+ TCL_UNUSED(Tcl_FSUnloadFileProc **),
+ TCL_UNUSED(int))
{
return TCL_ERROR;
}
diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c
index 83db956..2c93a41 100644
--- a/win/tclWinNotify.c
+++ b/win/tclWinNotify.c
@@ -5,7 +5,7 @@
* 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.
+ * Copyright © 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.
@@ -27,7 +27,7 @@
* created for each thread that is using the notifier.
*/
-typedef struct ThreadSpecificData {
+typedef struct {
CRITICAL_SECTION crit; /* Monitor for this notifier. */
DWORD thread; /* Identifier for thread associated with this
* notifier. */
@@ -36,7 +36,6 @@ typedef struct ThreadSpecificData {
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. */
} ThreadSpecificData;
@@ -50,15 +49,16 @@ static Tcl_ThreadDataKey dataKey;
*/
static int notifierCount = 0;
-static const WCHAR classname[] = L"TclNotifier";
-TCL_DECLARE_MUTEX(notifierMutex)
+static const WCHAR className[] = L"TclNotifier";
+static int initialized = 0;
+static CRITICAL_SECTION 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);
/*
*----------------------------------------------------------------------
@@ -76,58 +76,63 @@ static LRESULT CALLBACK NotifierProc(HWND hwnd, UINT message,
*----------------------------------------------------------------------
*/
-ClientData
-Tcl_InitNotifier(void)
+void *
+TclpInitNotifier(void)
{
- if (tclNotifierHooks.initNotifierProc) {
- return tclNotifierHooks.initNotifierProc();
- } else {
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- WNDCLASSW windowClass;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- /*
- * Register Notifier window class if this is the first thread to use
- * this module.
- */
+ TclpGlobalLock();
+ if (!initialized) {
+ initialized = 1;
+ InitializeCriticalSection(&notifierMutex);
+ }
+ TclpGlobalUnlock();
- Tcl_MutexLock(&notifierMutex);
- if (notifierCount == 0) {
- windowClass.style = 0;
- windowClass.cbClsExtra = 0;
- windowClass.cbWndExtra = 0;
- windowClass.hInstance = TclWinGetTclInstance();
- windowClass.hbrBackground = NULL;
- windowClass.lpszMenuName = NULL;
- windowClass.lpszClassName = classname;
- windowClass.lpfnWndProc = NotifierProc;
- windowClass.hIcon = NULL;
- windowClass.hCursor = NULL;
-
- if (!RegisterClassW(&windowClass)) {
- Tcl_Panic("Unable to register TclNotifier window class");
- }
+ /*
+ * Register Notifier window class if this is the first thread to use this
+ * module.
+ */
+
+ EnterCriticalSection(&notifierMutex);
+ if (notifierCount == 0) {
+ WNDCLASSW clazz;
+
+ clazz.style = 0;
+ clazz.cbClsExtra = 0;
+ clazz.cbWndExtra = 0;
+ clazz.hInstance = (HINSTANCE) TclWinGetTclInstance();
+ clazz.hbrBackground = NULL;
+ clazz.lpszMenuName = NULL;
+ clazz.lpszClassName = className;
+ clazz.lpfnWndProc = NotifierProc;
+ clazz.hIcon = NULL;
+ clazz.hCursor = NULL;
+
+ if (!RegisterClassW(&clazz)) {
+ Tcl_Panic("Tcl_InitNotifier: %s",
+ "unable to register TclNotifier window class");
}
- notifierCount++;
- Tcl_MutexUnlock(&notifierMutex);
+ }
+ notifierCount++;
+ LeaveCriticalSection(&notifierMutex);
- tsdPtr->pending = 0;
- tsdPtr->timerActive = 0;
+ tsdPtr->pending = 0;
+ tsdPtr->timerActive = 0;
- InitializeCriticalSection(&tsdPtr->crit);
+ InitializeCriticalSection(&tsdPtr->crit);
- tsdPtr->hwnd = NULL;
- tsdPtr->thread = GetCurrentThreadId();
- tsdPtr->event = CreateEventW(NULL, TRUE /* manual */,
- FALSE /* !signaled */, NULL);
+ tsdPtr->hwnd = NULL;
+ tsdPtr->thread = GetCurrentThreadId();
+ tsdPtr->event = CreateEventW(NULL, TRUE /* manual */,
+ FALSE /* !signaled */, NULL);
- return tsdPtr;
- }
+ return tsdPtr;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_FinalizeNotifier --
+ * TclpFinalizeNotifier --
*
* This function is called to cleanup the notifier state before a thread
* is terminated.
@@ -142,60 +147,57 @@ Tcl_InitNotifier(void)
*/
void
-Tcl_FinalizeNotifier(
- ClientData clientData) /* Pointer to notifier data. */
+TclpFinalizeNotifier(
+ void *clientData) /* Pointer to notifier data. */
{
- if (tclNotifierHooks.finalizeNotifierProc) {
- tclNotifierHooks.finalizeNotifierProc(clientData);
- return;
- } else {
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
+ 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.
- *
- * Fixes Bug #217982 reported by Hugh Vu and Gene Leache.
- */
+ /*
+ * 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;
- }
+ if (tsdPtr == NULL) {
+ return;
+ }
- DeleteCriticalSection(&tsdPtr->crit);
- CloseHandle(tsdPtr->event);
+ DeleteCriticalSection(&tsdPtr->crit);
+ CloseHandle(tsdPtr->event);
- /*
- * Clean up the timer and messaging window for this thread.
- */
+ /*
+ * Clean up the timer and messaging window for this thread.
+ */
- if (tsdPtr->hwnd) {
- KillTimer(tsdPtr->hwnd, INTERVAL_TIMER);
- DestroyWindow(tsdPtr->hwnd);
- }
+ if (tsdPtr->hwnd) {
+ KillTimer(tsdPtr->hwnd, INTERVAL_TIMER);
+ DestroyWindow(tsdPtr->hwnd);
+ }
- /*
- * 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);
+ EnterCriticalSection(&notifierMutex);
+ if (notifierCount) {
notifierCount--;
if (notifierCount == 0) {
- UnregisterClassW(classname, TclWinGetTclInstance());
+ UnregisterClassW(className, (HINSTANCE) TclWinGetTclInstance());
}
- Tcl_MutexUnlock(&notifierMutex);
}
+ LeaveCriticalSection(&notifierMutex);
}
/*
*----------------------------------------------------------------------
*
- * Tcl_AlertNotifier --
+ * TclpAlertNotifier --
*
* Wake up the specified notifier from any thread. This routine is called
* by the platform independent notifier code whenever the Tcl_ThreadAlert
@@ -215,42 +217,37 @@ Tcl_FinalizeNotifier(
*/
void
-Tcl_AlertNotifier(
- ClientData clientData) /* Pointer to thread data. */
+TclpAlertNotifier(
+ void *clientData) /* Pointer to thread data. */
{
- if (tclNotifierHooks.alertNotifierProc) {
- tclNotifierHooks.alertNotifierProc(clientData);
- return;
- } else {
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
+ 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.
+ */
+
+ if (tsdPtr->hwnd) {
/*
- * 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.
+ * We do need to lock around access to the pending flag.
*/
- if (tsdPtr->hwnd) {
- /*
- * We do need to lock around access to the pending flag.
- */
-
- EnterCriticalSection(&tsdPtr->crit);
- if (!tsdPtr->pending) {
- PostMessageW(tsdPtr->hwnd, WM_WAKEUP, 0, 0);
- }
- tsdPtr->pending = 1;
- LeaveCriticalSection(&tsdPtr->crit);
- } else {
- SetEvent(tsdPtr->event);
+ EnterCriticalSection(&tsdPtr->crit);
+ if (!tsdPtr->pending) {
+ PostMessageW(tsdPtr->hwnd, WM_WAKEUP, 0, 0);
}
+ tsdPtr->pending = 1;
+ LeaveCriticalSection(&tsdPtr->crit);
+ } else {
+ SetEvent(tsdPtr->event);
}
}
/*
*----------------------------------------------------------------------
*
- * Tcl_SetTimer --
+ * TclpSetTimer --
*
* This procedure sets the current notifier timer value. The notifier
* will ensure that Tcl_ServiceAll() is called after the specified
@@ -266,55 +263,49 @@ Tcl_AlertNotifier(
*/
void
-Tcl_SetTimer(
+TclpSetTimer(
const Tcl_Time *timePtr) /* Maximum block time, or NULL. */
{
- if (tclNotifierHooks.setTimerProc) {
- tclNotifierHooks.setTimerProc(timePtr);
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ UINT timeout;
+
+ /*
+ * 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) {
return;
- } else {
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- UINT timeout;
+ }
+ if (!timePtr) {
+ timeout = 0;
+ } else {
/*
- * 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.
+ * Make sure we pass a non-zero value into the timeout argument.
+ * Windows seems to get confused by zero length timers.
*/
- if (!tsdPtr->hwnd) {
- return;
+ timeout = (UINT)timePtr->sec * 1000 + (unsigned long)timePtr->usec / 1000;
+ if (timeout == 0) {
+ timeout = 1;
}
+ }
- if (!timePtr) {
- timeout = 0;
- } else {
- /*
- * Make sure we pass a non-zero value into the timeout argument.
- * Windows seems to get confused by zero length timers.
- */
-
- timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
- if (timeout == 0) {
- timeout = 1;
- }
- }
- tsdPtr->timeout = timeout;
- if (timeout != 0) {
- tsdPtr->timerActive = 1;
- SetTimer(tsdPtr->hwnd, INTERVAL_TIMER,
- (unsigned long) tsdPtr->timeout, NULL);
- } else {
- tsdPtr->timerActive = 0;
- KillTimer(tsdPtr->hwnd, INTERVAL_TIMER);
- }
+ if (timeout != 0) {
+ tsdPtr->timerActive = 1;
+ SetTimer(tsdPtr->hwnd, INTERVAL_TIMER, timeout, NULL);
+ } else {
+ tsdPtr->timerActive = 0;
+ KillTimer(tsdPtr->hwnd, INTERVAL_TIMER);
}
}
/*
*----------------------------------------------------------------------
*
- * Tcl_ServiceModeHook --
+ * TclpServiceModeHook --
*
* This function is invoked whenever the service mode changes.
*
@@ -329,46 +320,66 @@ Tcl_SetTimer(
*/
void
-Tcl_ServiceModeHook(
+TclpServiceModeHook(
int mode) /* Either TCL_SERVICE_ALL, or
* TCL_SERVICE_NONE. */
{
- if (tclNotifierHooks.serviceModeHookProc) {
- tclNotifierHooks.serviceModeHookProc(mode);
- return;
- } else {
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ 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 = CreateWindowW(classname, classname,
- WS_TILED, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(),
- NULL);
+ if (mode == TCL_SERVICE_ALL && !tsdPtr->hwnd) {
+ tsdPtr->hwnd = CreateWindowW(className, className, WS_TILED,
+ 0, 0, 0, 0, NULL, NULL, (HINSTANCE) 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.
- */
+ /*
+ * 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.
+ */
- Tcl_AlertNotifier(tsdPtr);
- }
+ Tcl_AlertNotifier(tsdPtr);
}
}
/*
*----------------------------------------------------------------------
*
+ * TclAsyncNotifier --
+ *
+ * This procedure is a no-op on Windows.
+ *
+ * Result:
+ * Always true.
+ *
+ * Side effetcs:
+ * None.
+ *----------------------------------------------------------------------
+ */
+
+int
+TclAsyncNotifier(
+ TCL_UNUSED(int), /* Signal number. */
+ TCL_UNUSED(Tcl_ThreadId), /* Target thread. */
+ TCL_UNUSED(void *), /* Notifier data. */
+ TCL_UNUSED(int *), /* Flag to mark. */
+ TCL_UNUSED(int)) /* Value of mark. */
+{
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* NotifierProc --
*
* This procedure is invoked by Windows to process events on the notifier
@@ -412,7 +423,30 @@ NotifierProc(
/*
*----------------------------------------------------------------------
*
- * Tcl_WaitForEvent --
+ * TclpNotifierData --
+ *
+ * This function returns a void pointer to be associated
+ * with a Tcl_AsyncHandler.
+ *
+ * Results:
+ * On Windows, returns always NULL.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void *
+TclpNotifierData(void)
+{
+ return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpWaitForEvent --
*
* 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
@@ -429,103 +463,99 @@ NotifierProc(
*/
int
-Tcl_WaitForEvent(
+TclpWaitForEvent(
const Tcl_Time *timePtr) /* Maximum block time, or NULL. */
{
- if (tclNotifierHooks.waitForEventProc) {
- return tclNotifierHooks.waitForEventProc(timePtr);
- } else {
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- MSG msg;
- DWORD timeout, result;
- int status;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ MSG msg;
+ DWORD timeout, result;
+ int status;
+ /*
+ * Compute the timeout in milliseconds.
+ */
+
+ if (timePtr) {
/*
- * Compute the timeout in milliseconds.
+ * TIP #233 (Virtualized Time). Convert virtual domain delay to
+ * real-time.
*/
- if (timePtr) {
- /*
- * TIP #233 (Virtualized Time). Convert virtual domain delay to
- * real-time.
- */
+ Tcl_Time myTime;
- Tcl_Time myTime;
+ myTime.sec = timePtr->sec;
+ myTime.usec = timePtr->usec;
- myTime.sec = timePtr->sec;
- myTime.usec = timePtr->usec;
+ if (myTime.sec != 0 || myTime.usec != 0) {
+ TclScaleTime(&myTime);
+ }
- if (myTime.sec != 0 || myTime.usec != 0) {
- tclScaleTimeProcPtr(&myTime, tclTimeClientData);
- }
+ timeout = (DWORD)myTime.sec * 1000 + (unsigned long)myTime.usec / 1000;
+ } else {
+ timeout = INFINITE;
+ }
- timeout = myTime.sec * 1000 + myTime.usec / 1000;
- } else {
- timeout = INFINITE;
- }
+ /*
+ * Check to see if there are any messages in the queue before waiting
+ * because MsgWaitForMultipleObjects will not wake up if there are events
+ * currently sitting in the queue.
+ */
+ if (!PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) {
/*
- * Check to see if there are any messages in the queue before waiting
- * because MsgWaitForMultipleObjects will not wake up if there are
- * events currently sitting in the queue.
+ * Wait for something to happen (a signal from another thread, a
+ * message, or timeout) or loop servicing asynchronous procedure calls
+ * queued to this thread.
*/
- if (!PeekMessageW(&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.
- */
-
- again:
+ do {
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;
- }
+ } while (result == WAIT_IO_COMPLETION);
+
+ if (result == WAIT_FAILED) {
+ status = -1;
+ goto end;
}
+ }
+
+ /*
+ * Check to see if there are any messages to process.
+ */
+ if (PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) {
/*
- * Check to see if there are any messages to process.
+ * Retrieve and dispatch the first message.
*/
- if (PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) {
+ result = GetMessageW(&msg, NULL, 0, 0);
+ if (result == 0) {
+ /*
+ * We received a request to exit this thread (WM_QUIT), so
+ * propagate the quit message and start unwinding.
+ */
+
+ PostQuitMessage((int) msg.wParam);
+ status = -1;
+ } else if (result == (DWORD) -1) {
/*
- * Retrieve and dispatch the first message.
+ * We got an error from the system. I have no idea why this would
+ * happen, so we'll just unwind.
*/
- result = GetMessageW(&msg, NULL, 0, 0);
- if (result == 0) {
- /*
- * We received a request to exit this thread (WM_QUIT), so
- * propagate the quit message and start unwinding.
- */
-
- PostQuitMessage((int) msg.wParam);
- status = -1;
- } else if (result == (DWORD)-1) {
- /*
- * We got an error from the system. I have no idea why this
- * would happen, so we'll just unwind.
- */
-
- status = -1;
- } else {
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- status = 1;
- }
+ status = -1;
} else {
- status = 0;
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ status = 1;
}
-
- end:
- ResetEvent(tsdPtr->event);
- return status;
+ } else {
+ status = 0;
}
+
+ end:
+ ResetEvent(tsdPtr->event);
+ return status;
}
/*
@@ -579,8 +609,8 @@ Tcl_Sleep(
* TIP #233: Scale delay from virtual to real-time.
*/
- tclScaleTimeProcPtr(&vdelay, tclTimeClientData);
- sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000;
+ TclScaleTime(&vdelay);
+ sleepTime = (DWORD)vdelay.sec * 1000 + (unsigned long)vdelay.usec / 1000;
for (;;) {
SleepEx(sleepTime, TRUE);
@@ -594,8 +624,8 @@ Tcl_Sleep(
vdelay.sec = desired.sec - now.sec;
vdelay.usec = desired.usec - now.usec;
- tclScaleTimeProcPtr(&vdelay, tclTimeClientData);
- sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000;
+ TclScaleTime(&vdelay);
+ sleepTime = (DWORD)vdelay.sec * 1000 + (unsigned long)vdelay.usec / 1000;
}
}
diff --git a/win/tclWinPanic.c b/win/tclWinPanic.c
new file mode 100644
index 0000000..3d9e98c
--- /dev/null
+++ b/win/tclWinPanic.c
@@ -0,0 +1,88 @@
+/*
+ * tclWinPanic.c --
+ *
+ * Contains the Windows-specific command-line panic proc.
+ *
+ * Copyright © 2013 Jan Nijtmans.
+ * 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 "tclInt.h"
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ConsolePanic --
+ *
+ * Display a message. If a debugger is present, present it directly to
+ * the debugger, otherwise send it to stderr.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TCL_NORETURN void
+Tcl_ConsolePanic(
+ const char *format, ...)
+{
+#define TCL_MAX_WARN_LEN 26000
+ va_list argList;
+ WCHAR msgString[TCL_MAX_WARN_LEN];
+ char buf[TCL_MAX_WARN_LEN * 3];
+ HANDLE handle = GetStdHandle(STD_ERROR_HANDLE);
+ DWORD dummy;
+
+ va_start(argList, format);
+ vsnprintf(buf+3, sizeof(buf)-3, format, argList);
+ buf[sizeof(buf)-1] = 0;
+ msgString[TCL_MAX_WARN_LEN-1] = '\0';
+ MultiByteToWideChar(CP_UTF8, 0, buf+3, -1, msgString, TCL_MAX_WARN_LEN);
+
+ /*
+ * Truncate MessageBox string if it is too long to not overflow the buffer.
+ */
+
+ if (msgString[TCL_MAX_WARN_LEN-1] != '\0') {
+ memcpy(msgString + (TCL_MAX_WARN_LEN - 5), L" ...", 5 * sizeof(WCHAR));
+ }
+
+ if (IsDebuggerPresent()) {
+ OutputDebugStringW(msgString);
+ } else if (_isatty(2)) {
+ WriteConsoleW(handle, msgString, (DWORD)wcslen(msgString), &dummy, 0);
+ } else {
+ buf[0] = '\xEF'; buf[1] = '\xBB'; buf[2] = '\xBF'; /* UTF-8 bom */
+ WriteFile(handle, buf, (DWORD)strlen(buf), &dummy, 0);
+ WriteFile(handle, "\n", 1, &dummy, 0);
+ FlushFileBuffers(handle);
+ }
+# if defined(__GNUC__)
+ __builtin_trap();
+# elif defined(_WIN64)
+ __debugbreak();
+# elif defined(_MSC_VER)
+ _asm {int 3}
+# else
+ DebugBreak();
+# endif
+#if defined(_WIN32)
+ ExitProcess(1);
+#else
+ abort();
+#endif
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * End:
+ */
diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c
index 22b20b8..71d1e4b 100644
--- a/win/tclWinPipe.c
+++ b/win/tclWinPipe.c
@@ -4,7 +4,7 @@
* 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.
+ * Copyright © 1996-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.
@@ -61,7 +61,7 @@ typedef struct {
typedef struct ProcInfo {
HANDLE hProcess;
- DWORD dwProcessId;
+ int dwProcessId;
struct ProcInfo *nextPtr;
} ProcInfo;
@@ -104,7 +104,7 @@ typedef struct PipeInfo {
TclFile readFile; /* Output from pipe. */
TclFile writeFile; /* Input from pipe. */
TclFile errorFile; /* Error output from pipe. */
- int numPids; /* Number of processes attached to pipe. */
+ size_t numPids; /* Number of processes attached to pipe. */
Tcl_Pid *pidPtr; /* Pids of attached processes. */
Tcl_ThreadId threadId; /* Thread to which events should be reported.
* This value is used by the reader/writer
@@ -171,28 +171,28 @@ typedef struct {
static int ApplicationType(Tcl_Interp *interp,
const char *fileName, char *fullName);
-static void BuildCommandLine(const char *executable, int argc,
+static void BuildCommandLine(const char *executable, size_t 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);
-static int PipeClose2Proc(ClientData instanceData,
+static int PipeBlockModeProc(void *instanceData, int mode);
+static void PipeCheckProc(void *clientData, int flags);
+static int PipeClose2Proc(void *instanceData,
Tcl_Interp *interp, int flags);
static int PipeEventProc(Tcl_Event *evPtr, int flags);
-static int PipeGetHandleProc(ClientData instanceData,
- int direction, ClientData *handlePtr);
+static int PipeGetHandleProc(void *instanceData,
+ int direction, void **handlePtr);
static void PipeInit(void);
-static int PipeInputProc(ClientData instanceData, char *buf,
+static int PipeInputProc(void *instanceData, char *buf,
int toRead, int *errorCode);
-static int PipeOutputProc(ClientData instanceData,
+static int PipeOutputProc(void *instanceData,
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 void PipeSetupProc(void *clientData, int flags);
+static void PipeWatchProc(void *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,
+static void PipeThreadActionProc(void *instanceData,
int action);
/*
@@ -201,23 +201,23 @@ static void PipeThreadActionProc(ClientData instanceData,
*/
static const Tcl_ChannelType pipeChannelType = {
- "pipe", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
- TCL_CLOSE2PROC, /* Close proc. */
- PipeInputProc, /* Input proc. */
- PipeOutputProc, /* Output proc. */
- NULL, /* Seek proc. */
+ "pipe",
+ TCL_CHANNEL_VERSION_5,
+ NULL, /* Deprecated. */
+ PipeInputProc,
+ PipeOutputProc,
+ NULL, /* Deprecated. */
NULL, /* Set option proc. */
NULL, /* Get option proc. */
- PipeWatchProc, /* Set up notifier to watch the channel. */
- PipeGetHandleProc, /* Get an OS handle from channel. */
- PipeClose2Proc, /* close2proc */
- PipeBlockModeProc, /* Set blocking or non-blocking mode.*/
- NULL, /* flush proc. */
- NULL, /* handler proc. */
- NULL, /* wide seek proc */
- PipeThreadActionProc, /* thread action proc */
- NULL /* truncate */
+ PipeWatchProc,
+ PipeGetHandleProc,
+ PipeClose2Proc,
+ PipeBlockModeProc,
+ NULL, /* Flush proc. */
+ NULL, /* Bubbled event handler proc. */
+ NULL, /* Seek proc. */
+ PipeThreadActionProc,
+ NULL /* Truncate proc. */
};
/*
@@ -310,7 +310,7 @@ TclpFinalizePipes(void)
void
PipeSetupProc(
- ClientData data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
PipeInfo *infoPtr;
@@ -363,7 +363,7 @@ PipeSetupProc(
static void
PipeCheckProc(
- ClientData data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
PipeInfo *infoPtr;
@@ -402,7 +402,7 @@ PipeCheckProc(
if (needEvent) {
infoPtr->flags |= PIPE_PENDING;
- evPtr = (PipeEvent *)ckalloc(sizeof(PipeEvent));
+ evPtr = (PipeEvent *)Tcl_Alloc(sizeof(PipeEvent));
evPtr->header.proc = PipeEventProc;
evPtr->infoPtr = infoPtr;
Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
@@ -433,7 +433,7 @@ TclWinMakeFile(
{
WinFile *filePtr;
- filePtr = (WinFile *)ckalloc(sizeof(WinFile));
+ filePtr = (WinFile *)Tcl_Alloc(sizeof(WinFile));
filePtr->type = WIN_FILE;
filePtr->handle = handle;
@@ -500,7 +500,7 @@ TclpMakeFile(
HANDLE handle;
if (Tcl_GetChannelHandle(channel, direction,
- (ClientData *) &handle) == TCL_OK) {
+ (void **) &handle) == TCL_OK) {
return TclWinMakeFile(handle);
} else {
return (TclFile) NULL;
@@ -549,7 +549,7 @@ TclpOpenFile(
accessMode = (GENERIC_READ | GENERIC_WRITE);
break;
default:
- TclWinConvertError(ERROR_INVALID_FUNCTION);
+ Tcl_WinConvertError(ERROR_INVALID_FUNCTION);
return NULL;
}
@@ -577,7 +577,8 @@ TclpOpenFile(
break;
}
- nativePath = (WCHAR *)Tcl_WinUtfToTChar(path, -1, &ds);
+ Tcl_DStringInit(&ds);
+ nativePath = Tcl_UtfToWCharDString(path, TCL_INDEX_NONE, &ds);
/*
* If the file is not being created, use the existing file attributes.
@@ -612,7 +613,7 @@ TclpOpenFile(
if ((err & 0xFFFFL) == ERROR_OPEN_FAILED) {
err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND;
}
- TclWinConvertError(err);
+ Tcl_WinConvertError(err);
return NULL;
}
@@ -650,7 +651,7 @@ TclpCreateTempFile(
const char *contents) /* String to write into temp file, or NULL. */
{
WCHAR name[MAX_PATH];
- const char *native;
+ const char *native = NULL;
Tcl_DString dstring;
HANDLE handle;
@@ -678,7 +679,10 @@ TclpCreateTempFile(
* Convert the contents from UTF to native encoding
*/
- native = Tcl_UtfToExternalDString(NULL, contents, -1, &dstring);
+ if (Tcl_UtfToExternalDStringEx(NULL, NULL, contents, TCL_INDEX_NONE, 0, &dstring, NULL) != TCL_OK) {
+ goto error;
+ }
+ native = Tcl_DStringValue(&dstring);
toCopy = Tcl_DStringLength(&dstring);
for (p = native; toCopy > 0; p++, toCopy--) {
@@ -718,7 +722,9 @@ TclpCreateTempFile(
Tcl_DStringFree(&dstring);
}
- TclWinConvertError(GetLastError());
+ if (native != NULL) {
+ Tcl_WinConvertError(GetLastError());
+ }
CloseHandle(handle);
DeleteFileW(name);
return NULL;
@@ -783,7 +789,7 @@ TclpCreatePipe(
return 1;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return 0;
}
@@ -824,8 +830,8 @@ TclpCloseFile(
&& (GetStdHandle(STD_ERROR_HANDLE) != filePtr->handle))) {
if (filePtr->handle != NULL &&
CloseHandle(filePtr->handle) == FALSE) {
- TclWinConvertError(GetLastError());
- ckfree(filePtr);
+ Tcl_WinConvertError(GetLastError());
+ Tcl_Free(filePtr);
return -1;
}
}
@@ -835,7 +841,7 @@ TclpCloseFile(
Tcl_Panic("TclpCloseFile: unexpected file type");
}
- ckfree(filePtr);
+ Tcl_Free(filePtr);
return 0;
}
@@ -850,7 +856,7 @@ TclpCloseFile(
* 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.
+ * process has already been reaped, TCL_INDEX_NONE is returned.
*
* Side effects:
* None.
@@ -858,7 +864,7 @@ TclpCloseFile(
*--------------------------------------------------------------------------
*/
-int
+Tcl_Size
TclpGetPid(
Tcl_Pid pid) /* The HANDLE of the child process. */
{
@@ -868,13 +874,13 @@ TclpGetPid(
Tcl_MutexLock(&pipeMutex);
for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
- if (infoPtr->hProcess == (HANDLE) pid) {
+ if (infoPtr->dwProcessId == (Tcl_Size)pid) {
Tcl_MutexUnlock(&pipeMutex);
return infoPtr->dwProcessId;
}
}
Tcl_MutexUnlock(&pipeMutex);
- return (unsigned long) -1;
+ return -1;
}
/*
@@ -910,7 +916,7 @@ TclpCreateProcess(
* occurred when creating the child process.
* Error messages from the child process
* itself are sent to errorFile. */
- int argc, /* Number of arguments in following array. */
+ size_t 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
@@ -940,7 +946,7 @@ TclpCreateProcess(
PROCESS_INFORMATION procInfo;
SECURITY_ATTRIBUTES secAtts;
HANDLE hProcess, h, inputHandle, outputHandle, errorHandle;
- char execPath[MAX_PATH * TCL_UTF_MAX];
+ char execPath[MAX_PATH * 3];
WinFile *filePtr;
PipeInit();
@@ -1025,7 +1031,7 @@ TclpCreateProcess(
0, TRUE, DUPLICATE_SAME_ACCESS);
}
if (startInfo.hStdInput == INVALID_HANDLE_VALUE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't duplicate input handle: %s",
Tcl_PosixError(interp)));
@@ -1054,7 +1060,7 @@ TclpCreateProcess(
&startInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
}
if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't duplicate output handle: %s",
Tcl_PosixError(interp)));
@@ -1074,7 +1080,7 @@ TclpCreateProcess(
0, TRUE, DUPLICATE_SAME_ACCESS);
}
if (startInfo.hStdError == INVALID_HANDLE_VALUE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't duplicate error handle: %s",
Tcl_PosixError(interp)));
@@ -1136,7 +1142,7 @@ TclpCreateProcess(
if (CreateProcessW(NULL, (WCHAR *) Tcl_DStringValue(&cmdLine),
NULL, NULL, TRUE, (DWORD) createFlags, NULL, NULL, &startInfo,
&procInfo) == 0) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s",
argv[0], Tcl_PosixError(interp)));
goto end;
@@ -1155,14 +1161,14 @@ TclpCreateProcess(
* 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
+ * CreateProcessW() and CloseHandle(), the problem does not occur." PSS ID
* Number: Q124121
*/
WaitForInputIdle(procInfo.hProcess, 5000);
CloseHandle(procInfo.hThread);
- *pidPtr = (Tcl_Pid) procInfo.hProcess;
+ *pidPtr = (Tcl_Pid)INT2PTR(procInfo.dwProcessId);
if (*pidPtr != 0) {
TclWinAddProcess(procInfo.hProcess, procInfo.dwProcessId);
}
@@ -1181,7 +1187,6 @@ TclpCreateProcess(
}
return result;
}
-
/*
*----------------------------------------------------------------------
@@ -1277,20 +1282,21 @@ ApplicationType(
* Using the raw SearchPathW() 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, SearchPathW will not find the program "a.b.exe" if the arguments
+ * 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;
Tcl_DStringInit(&nameBuf);
- Tcl_DStringAppend(&nameBuf, originalName, -1);
+ Tcl_DStringAppend(&nameBuf, originalName, TCL_INDEX_NONE);
nameLen = Tcl_DStringLength(&nameBuf);
for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) {
Tcl_DStringSetLength(&nameBuf, nameLen);
- Tcl_DStringAppend(&nameBuf, extensions[i], -1);
- nativeName = (WCHAR *)Tcl_WinUtfToTChar(Tcl_DStringValue(&nameBuf),
+ Tcl_DStringAppend(&nameBuf, extensions[i], TCL_INDEX_NONE);
+ Tcl_DStringInit(&ds);
+ nativeName = Tcl_UtfToWCharDString(Tcl_DStringValue(&nameBuf),
Tcl_DStringLength(&nameBuf), &ds);
found = SearchPathW(NULL, nativeName, NULL, MAX_PATH,
nativeFullPath, &rest);
@@ -1308,12 +1314,13 @@ ApplicationType(
if ((attr == 0xFFFFFFFF) || (attr & FILE_ATTRIBUTE_DIRECTORY)) {
continue;
}
- strcpy(fullName, Tcl_WinTCharToUtf((TCHAR *)nativeFullPath, -1, &ds));
+ Tcl_DStringInit(&ds);
+ strcpy(fullName, Tcl_WCharToUtfDString(nativeFullPath, TCL_INDEX_NONE, &ds));
Tcl_DStringFree(&ds);
ext = strrchr(fullName, '.');
if ((ext != NULL) &&
- (strcasecmp(ext, ".cmd") == 0 || strcasecmp(ext, ".bat") == 0)) {
+ (strcasecmp(ext, ".cmd") == 0 || strcasecmp(ext, ".bat") == 0)) {
applType = APPL_DOS;
break;
}
@@ -1338,7 +1345,7 @@ ApplicationType(
}
header.e_magic = 0;
- ReadFile(hFile, (void *) &header, sizeof(header), &read, NULL);
+ 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
@@ -1373,7 +1380,7 @@ ApplicationType(
buf[0] = '\0';
SetFilePointer(hFile, header.e_lfanew, NULL, FILE_BEGIN);
- ReadFile(hFile, (void *) buf, 2, &read, NULL);
+ ReadFile(hFile, (void *)buf, 2, &read, NULL);
CloseHandle(hFile);
if ((buf[0] == 'N') && (buf[1] == 'E')) {
@@ -1396,7 +1403,7 @@ ApplicationType(
Tcl_DStringFree(&nameBuf);
if (applType == APPL_NONE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s",
originalName, Tcl_PosixError(interp)));
return APPL_NONE;
@@ -1411,7 +1418,8 @@ ApplicationType(
*/
GetShortPathNameW(nativeFullPath, nativeFullPath, MAX_PATH);
- strcpy(fullName, Tcl_WinTCharToUtf((TCHAR *)nativeFullPath, -1, &ds));
+ Tcl_DStringInit(&ds);
+ strcpy(fullName, Tcl_WCharToUtfDString(nativeFullPath, TCL_INDEX_NONE, &ds));
Tcl_DStringFree(&ds);
}
return applType;
@@ -1423,7 +1431,7 @@ ApplicationType(
* BuildCommandLine --
*
* The command line arguments are stored in linePtr separated by spaces,
- * in a form that CreateProcess() understands. Special characters in
+ * in a form that CreateProcessW() understands. Special characters in
* individual arguments from argv[] must be quoted when being stored in
* cmdLine.
*
@@ -1466,7 +1474,7 @@ QuoteCmdLineBackslash(
Tcl_DStringAppend(dsPtr, start, (int) (current - start));
}
} else {
- if (bspos > start) { /* part before first backslash */
+ if (bspos > start) { /* part before first backslash */
Tcl_DStringAppend(dsPtr, start, (int) (bspos - start));
}
while (bspos++ < current) { /* each backslash twice */
@@ -1509,7 +1517,7 @@ QuoteCmdLinePart(
TclDStringAppendLiteral(dsPtr, "\""); /* opening escape quote-char */
do {
- *bspos = NULL;
+ *bspos = NULL;
special++;
if (*special == '\\') {
/*
@@ -1544,13 +1552,14 @@ static void
BuildCommandLine(
const char *executable, /* Full path of executable (including
* extension). Replacement for argv[0]. */
- int argc, /* Number of arguments. */
+ size_t argc, /* Number of arguments. */
const char **argv, /* Argument strings in UTF. */
Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the
* command line (WCHAR). */
{
const char *arg, *start, *special, *bspos;
- int quote = 0, i;
+ int quote = 0;
+ size_t i;
Tcl_DString ds;
#ifdef TCL_WIN_PIPE_FULLESC
/* full escape inclusive %-subst avoidance */
@@ -1644,7 +1653,7 @@ BuildCommandLine(
* Nothing to escape.
*/
- Tcl_DStringAppend(&ds, arg, -1);
+ Tcl_DStringAppend(&ds, arg, TCL_INDEX_NONE);
} else {
start = arg;
for (special = arg; *special != '\0'; ) {
@@ -1748,7 +1757,8 @@ BuildCommandLine(
}
}
Tcl_DStringFree(linePtr);
- Tcl_WinUtfToTChar(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), linePtr);
+ Tcl_DStringInit(linePtr);
+ Tcl_UtfToWCharDString(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), linePtr);
Tcl_DStringFree(&ds);
}
@@ -1775,11 +1785,11 @@ TclpCreateCommandChannel(
TclFile writeFile, /* If non-null, gives the file for writing. */
TclFile errorFile, /* If non-null, gives the file where errors
* can be read. */
- int numPids, /* The number of pids in the pid array. */
+ size_t numPids, /* The number of pids in the pid array. */
Tcl_Pid *pidPtr) /* An array of process identifiers. */
{
char channelName[16 + TCL_INTEGER_SPACE];
- PipeInfo *infoPtr = (PipeInfo *)ckalloc(sizeof(PipeInfo));
+ PipeInfo *infoPtr = (PipeInfo *)Tcl_Alloc(sizeof(PipeInfo));
PipeInit();
@@ -1807,12 +1817,11 @@ TclpCreateCommandChannel(
infoPtr->readable = CreateEventW(NULL, TRUE, TRUE, NULL);
infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread,
- TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr, infoPtr->readable),
- 0, NULL);
+ TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr), 0, NULL);
SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST);
infoPtr->validMask |= TCL_READABLE;
} else {
- infoPtr->readTI = NULL;
+ infoPtr->readTI = NULL;
infoPtr->readThread = 0;
}
if (writeFile != NULL) {
@@ -1822,13 +1831,12 @@ TclpCreateCommandChannel(
infoPtr->writable = CreateEventW(NULL, TRUE, TRUE, NULL);
infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread,
- TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr, infoPtr->writable),
- 0, NULL);
+ TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr), 0, NULL);
SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST);
infoPtr->validMask |= TCL_WRITABLE;
} else {
- infoPtr->writeTI = NULL;
- infoPtr->writeThread = 0;
+ infoPtr->writeTI = NULL;
+ infoPtr->writeThread = 0;
}
/*
@@ -1838,18 +1846,11 @@ TclpCreateCommandChannel(
* unique, in case channels share handles (stdin/stdout).
*/
- snprintf(channelName, sizeof(channelName), "file%" TCL_Z_MODIFIER "x", (size_t) infoPtr);
+ TclWinGenerateChannelName(channelName, "file", infoPtr);
infoPtr->channel = Tcl_CreateChannel(&pipeChannelType, channelName,
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.
- */
-
Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
- Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
return infoPtr->channel;
}
@@ -1872,7 +1873,7 @@ Tcl_CreatePipe(
Tcl_Interp *interp, /* Errors returned in result.*/
Tcl_Channel *rchan, /* Where to return the read side. */
Tcl_Channel *wchan, /* Where to return the write side. */
- int flags) /* Reserved for future use. */
+ TCL_UNUSED(int) /*flags*/) /* Reserved for future use. */
{
HANDLE readHandle, writeHandle;
SECURITY_ATTRIBUTES sec;
@@ -1882,16 +1883,16 @@ Tcl_CreatePipe(
sec.bInheritHandle = FALSE;
if (!CreatePipe(&readHandle, &writeHandle, &sec, 0)) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"pipe creation failed: %s", Tcl_PosixError(interp)));
return TCL_ERROR;
}
- *rchan = Tcl_MakeFileChannel((ClientData) readHandle, TCL_READABLE);
+ *rchan = Tcl_MakeFileChannel((void *)readHandle, TCL_READABLE);
Tcl_RegisterChannel(interp, *rchan);
- *wchan = Tcl_MakeFileChannel((ClientData) writeHandle, TCL_WRITABLE);
+ *wchan = Tcl_MakeFileChannel((void *)writeHandle, TCL_WRITABLE);
Tcl_RegisterChannel(interp, *wchan);
return TCL_OK;
@@ -1922,7 +1923,7 @@ TclGetAndDetachPids(
PipeInfo *pipePtr;
const Tcl_ChannelType *chanTypePtr;
Tcl_Obj *pidsObj;
- int i;
+ size_t i;
/*
* Punt if the channel is not a command channel.
@@ -1937,13 +1938,13 @@ TclGetAndDetachPids(
TclNewObj(pidsObj);
for (i = 0; i < pipePtr->numPids; i++) {
Tcl_ListObjAppendElement(NULL, pidsObj,
- Tcl_NewWideIntObj((unsigned)
+ Tcl_NewWideIntObj(
TclpGetPid(pipePtr->pidPtr[i])));
Tcl_DetachPids(1, &pipePtr->pidPtr[i]);
}
Tcl_SetObjResult(interp, pidsObj);
if (pipePtr->numPids > 0) {
- ckfree(pipePtr->pidPtr);
+ Tcl_Free(pipePtr->pidPtr);
pipePtr->numPids = 0;
}
}
@@ -1966,7 +1967,7 @@ TclGetAndDetachPids(
static int
PipeBlockModeProc(
- ClientData instanceData, /* Instance data for channel. */
+ void *instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
@@ -2005,7 +2006,7 @@ PipeBlockModeProc(
static int
PipeClose2Proc(
- ClientData instanceData, /* Pointer to PipeInfo structure. */
+ void *instanceData, /* Pointer to PipeInfo structure. */
Tcl_Interp *interp, /* For error reporting. */
int flags) /* Flags that indicate which side to close. */
{
@@ -2051,7 +2052,7 @@ PipeClose2Proc(
if ((pipePtr->flags & PIPE_ASYNC) && inExit) {
/* give it a chance to leave honorably */
- TclPipeThreadStopSignal(&pipePtr->writeTI, pipePtr->writable);
+ TclPipeThreadStopSignal(&pipePtr->writeTI);
if (WaitForSingleObject(pipePtr->writable, 20) == WAIT_TIMEOUT) {
return EWOULDBLOCK;
@@ -2128,9 +2129,10 @@ PipeClose2Proc(
if (pipePtr->errorFile) {
WinFile *filePtr = (WinFile *) pipePtr->errorFile;
- errChan = Tcl_MakeFileChannel((ClientData) filePtr->handle,
+ errChan = Tcl_MakeFileChannel((void *)filePtr->handle,
TCL_READABLE);
- ckfree(filePtr);
+ Tcl_Free(filePtr);
+ Tcl_SetChannelOption(NULL, errChan, "-profile", "replace");
} else {
errChan = NULL;
}
@@ -2140,14 +2142,14 @@ PipeClose2Proc(
}
if (pipePtr->numPids > 0) {
- ckfree(pipePtr->pidPtr);
+ Tcl_Free(pipePtr->pidPtr);
}
if (pipePtr->writeBuf != NULL) {
- ckfree(pipePtr->writeBuf);
+ Tcl_Free(pipePtr->writeBuf);
}
- ckfree(pipePtr);
+ Tcl_Free(pipePtr);
if (errorCode == 0) {
return result;
@@ -2175,7 +2177,7 @@ PipeClose2Proc(
static int
PipeInputProc(
- ClientData instanceData, /* Pipe state. */
+ void *instanceData, /* Pipe state. */
char *buf, /* Where to store data read. */
int bufSize, /* How much space is available in the
* buffer? */
@@ -2240,7 +2242,7 @@ PipeInputProc(
return bytesRead;
}
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
if (errno == EPIPE) {
infoPtr->readFlags |= PIPE_EOF;
return 0;
@@ -2269,7 +2271,7 @@ PipeInputProc(
static int
PipeOutputProc(
- ClientData instanceData, /* Pipe state. */
+ void *instanceData, /* Pipe state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCode) /* Where to store error code. */
@@ -2299,7 +2301,7 @@ PipeOutputProc(
*/
if (infoPtr->writeError) {
- TclWinConvertError(infoPtr->writeError);
+ Tcl_WinConvertError(infoPtr->writeError);
infoPtr->writeError = 0;
goto error;
}
@@ -2316,10 +2318,10 @@ PipeOutputProc(
*/
if (infoPtr->writeBuf) {
- ckfree(infoPtr->writeBuf);
+ Tcl_Free(infoPtr->writeBuf);
}
infoPtr->writeBufLen = toWrite;
- infoPtr->writeBuf = (char *)ckalloc(toWrite);
+ infoPtr->writeBuf = (char *)Tcl_Alloc(toWrite);
}
memcpy(infoPtr->writeBuf, buf, toWrite);
infoPtr->toWrite = toWrite;
@@ -2334,7 +2336,7 @@ PipeOutputProc(
if (WriteFile(filePtr->handle, (LPVOID) buf, (DWORD) toWrite,
&bytesWritten, (LPOVERLAPPED) NULL) == FALSE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
goto error;
}
}
@@ -2451,7 +2453,7 @@ PipeEventProc(
static void
PipeWatchProc(
- ClientData instanceData, /* Pipe state. */
+ void *instanceData, /* Pipe state. */
int mask) /* What events to watch for, OR-ed combination
* of TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
@@ -2513,21 +2515,21 @@ PipeWatchProc(
static int
PipeGetHandleProc(
- ClientData instanceData, /* The pipe state. */
+ void *instanceData, /* The pipe state. */
int direction, /* TCL_READABLE or TCL_WRITABLE */
- ClientData *handlePtr) /* Where to store the handle. */
+ void **handlePtr) /* Where to store the handle. */
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
WinFile *filePtr;
if (direction == TCL_READABLE && infoPtr->readFile) {
filePtr = (WinFile*) infoPtr->readFile;
- *handlePtr = (ClientData) filePtr->handle;
+ *handlePtr = (void *)filePtr->handle;
return TCL_OK;
}
if (direction == TCL_WRITABLE && infoPtr->writeFile) {
filePtr = (WinFile*) infoPtr->writeFile;
- *handlePtr = (ClientData) filePtr->handle;
+ *handlePtr = (void *)filePtr->handle;
return TCL_OK;
}
return TCL_ERROR;
@@ -2581,7 +2583,7 @@ Tcl_WaitPid(
prevPtrPtr = &procList;
for (infoPtr = procList; infoPtr != NULL;
prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr->nextPtr) {
- if (infoPtr->hProcess == (HANDLE) pid) {
+ if (infoPtr->dwProcessId == (Tcl_Size)pid) {
*prevPtrPtr = infoPtr->nextPtr;
break;
}
@@ -2691,7 +2693,7 @@ Tcl_WaitPid(
} else {
errno = ECHILD;
*statPtr = 0xC0000000 | ECHILD;
- result = (Tcl_Pid) -1;
+ result = (Tcl_Pid)-1;
}
/*
@@ -2699,7 +2701,7 @@ Tcl_WaitPid(
*/
CloseHandle(infoPtr->hProcess);
- ckfree(infoPtr);
+ Tcl_Free(infoPtr);
return result;
}
@@ -2725,9 +2727,9 @@ Tcl_WaitPid(
void
TclWinAddProcess(
void *hProcess, /* Handle to process */
- unsigned long id) /* Global process identifier */
+ Tcl_Size id) /* Global process identifier */
{
- ProcInfo *procPtr = (ProcInfo *)ckalloc(sizeof(ProcInfo));
+ ProcInfo *procPtr = (ProcInfo *)Tcl_Alloc(sizeof(ProcInfo));
PipeInit();
@@ -2758,7 +2760,7 @@ TclWinAddProcess(
int
Tcl_PidObjCmd(
- ClientData dummy, /* Not used. */
+ TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* Argument strings. */
@@ -2766,17 +2768,17 @@ Tcl_PidObjCmd(
Tcl_Channel chan;
const Tcl_ChannelType *chanTypePtr;
PipeInfo *pipePtr;
- int i;
+ size_t i;
Tcl_Obj *resultPtr;
if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "?channelId?");
+ Tcl_WrongNumArgs(interp, 1, objv, "?channel?");
return TCL_ERROR;
}
if (objc == 1) {
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj((unsigned) getpid()));
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(getpid()));
} else {
- chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]),
+ chan = Tcl_GetChannel(interp, TclGetString(objv[1]),
NULL);
if (chan == (Tcl_Channel) NULL) {
return TCL_ERROR;
@@ -2790,7 +2792,7 @@ Tcl_PidObjCmd(
TclNewObj(resultPtr);
for (i = 0; i < pipePtr->numPids; i++) {
Tcl_ListObjAppendElement(/*interp*/ NULL, resultPtr,
- Tcl_NewWideIntObj((unsigned)
+ Tcl_NewWideIntObj(
TclpGetPid(pipePtr->pidPtr[i])));
}
Tcl_SetObjResult(interp, resultPtr);
@@ -2866,7 +2868,7 @@ WaitForRead(
if (PeekNamedPipe(handle, (LPVOID) NULL, (DWORD) 0,
(LPDWORD) NULL, &count, (LPDWORD) NULL) != TRUE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
/*
* Check to see if the peek failed because of EOF.
@@ -3152,7 +3154,7 @@ PipeWriterThread(
static void
PipeThreadActionProc(
- ClientData instanceData,
+ void *instanceData,
int action)
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
@@ -3204,16 +3206,17 @@ PipeThreadActionProc(
Tcl_Channel
TclpOpenTemporaryFile(
- Tcl_Obj *dirObj,
+ TCL_UNUSED(Tcl_Obj *) /*dirObj*/,
Tcl_Obj *basenameObj,
- Tcl_Obj *extensionObj,
+ TCL_UNUSED(Tcl_Obj *) /*extensionObj*/,
Tcl_Obj *resultingNameObj)
{
WCHAR name[MAX_PATH];
char *namePtr;
HANDLE handle;
DWORD flags = FILE_ATTRIBUTE_TEMPORARY;
- int length, counter, counter2;
+ Tcl_Size length;
+ int counter, counter2;
Tcl_DString buf;
if (!resultingNameObj) {
@@ -3227,9 +3230,10 @@ TclpOpenTemporaryFile(
}
namePtr += length * sizeof(WCHAR);
if (basenameObj) {
- const char *string = Tcl_GetString(basenameObj);
+ const char *string = TclGetStringFromObj(basenameObj, &length);
- Tcl_WinUtfToTChar(string, basenameObj->length, &buf);
+ Tcl_DStringInit(&buf);
+ Tcl_UtfToWCharDString(string, length, &buf);
memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf));
namePtr += Tcl_DStringLength(&buf);
Tcl_DStringFree(&buf);
@@ -3249,7 +3253,8 @@ TclpOpenTemporaryFile(
snprintf(number, sizeof(number), "%d.TMP", counter);
counter = (unsigned short) (counter + 1);
- Tcl_WinUtfToTChar(number, strlen(number), &buf);
+ Tcl_DStringInit(&buf);
+ Tcl_UtfToWCharDString(number, strlen(number), &buf);
Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf) + 1);
memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf) + 1);
Tcl_DStringFree(&buf);
@@ -3270,11 +3275,11 @@ TclpOpenTemporaryFile(
TclDecrRefCount(tmpObj);
}
- return Tcl_MakeFileChannel((ClientData) handle,
+ return Tcl_MakeFileChannel((void *)handle,
TCL_READABLE|TCL_WRITABLE);
gotError:
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return NULL;
}
@@ -3294,19 +3299,17 @@ TclpOpenTemporaryFile(
TclPipeThreadInfo *
TclPipeThreadCreateTI(
TclPipeThreadInfo **pipeTIPtr,
- ClientData clientData,
- HANDLE wakeEvent)
+ void *clientData)
{
TclPipeThreadInfo *pipeTI;
#ifndef _PTI_USE_CKALLOC
pipeTI = (TclPipeThreadInfo *)malloc(sizeof(TclPipeThreadInfo));
#else
- pipeTI = (TclPipeThreadInfo *)ckalloc(sizeof(TclPipeThreadInfo));
+ pipeTI = (TclPipeThreadInfo *)Tcl_Alloc(sizeof(TclPipeThreadInfo));
#endif /* !_PTI_USE_CKALLOC */
pipeTI->evControl = CreateEventW(NULL, FALSE, FALSE, NULL);
pipeTI->state = PTI_STATE_IDLE;
pipeTI->clientData = clientData;
- pipeTI->evWakeUp = wakeEvent;
return (*pipeTIPtr = pipeTI);
}
@@ -3334,14 +3337,11 @@ TclPipeThreadWaitForSignal(
TclPipeThreadInfo *pipeTI = *pipeTIPtr;
LONG state;
DWORD waitResult;
- HANDLE wakeEvent;
if (!pipeTI) {
return 0;
}
- wakeEvent = pipeTI->evWakeUp;
-
/*
* Wait for the main thread to signal before attempting to do the work.
*/
@@ -3401,11 +3401,6 @@ TclPipeThreadWaitForSignal(
if (state != PTI_STATE_STOP) {
*pipeTIPtr = NULL;
- } else {
- pipeTI->evWakeUp = NULL;
- }
- if (wakeEvent) {
- SetEvent(wakeEvent);
}
return 0;
}
@@ -3428,8 +3423,7 @@ TclPipeThreadWaitForSignal(
int
TclPipeThreadStopSignal(
- TclPipeThreadInfo **pipeTIPtr,
- HANDLE wakeEvent)
+ TclPipeThreadInfo **pipeTIPtr)
{
TclPipeThreadInfo *pipeTI = *pipeTIPtr;
HANDLE evControl;
@@ -3439,7 +3433,6 @@ TclPipeThreadStopSignal(
return 1;
}
evControl = pipeTI->evControl;
- pipeTI->evWakeUp = wakeEvent;
state = InterlockedCompareExchange(&pipeTI->state, PTI_STATE_STOP,
PTI_STATE_IDLE);
switch (state) {
@@ -3450,7 +3443,7 @@ TclPipeThreadStopSignal(
SetEvent(evControl);
*pipeTIPtr = NULL;
- /* FALLTHRU */
+ TCL_FALLTHROUGH();
case PTI_STATE_DOWN:
return 1;
@@ -3503,7 +3496,6 @@ TclPipeThreadStop(
}
pipeTI = *pipeTIPtr;
evControl = pipeTI->evControl;
- pipeTI->evWakeUp = NULL;
/*
* Try to sane stop the pipe worker, corresponding its current state
@@ -3588,9 +3580,7 @@ TclPipeThreadStop(
* Cancel all sync-IO of this thread (may be blocked there).
*/
- if (tclWinProcs.cancelSynchronousIo) {
- tclWinProcs.cancelSynchronousIo(hThread);
- }
+ CancelSynchronousIo(hThread);
/*
* Wait at most 20 milliseconds for the reader thread to close
@@ -3657,14 +3647,11 @@ TclPipeThreadStop(
*pipeTIPtr = NULL;
if (pipeTI) {
- if (pipeTI->evWakeUp) {
- SetEvent(pipeTI->evWakeUp);
- }
CloseHandle(pipeTI->evControl);
#ifndef _PTI_USE_CKALLOC
free(pipeTI);
#else
- ckfree(pipeTI);
+ Tcl_Free(pipeTI);
#endif /* !_PTI_USE_CKALLOC */
}
}
@@ -3708,13 +3695,10 @@ TclPipeThreadExit(
state = InterlockedExchange(&pipeTI->state, PTI_STATE_DOWN);
if (state == PTI_STATE_STOP) {
CloseHandle(pipeTI->evControl);
- if (pipeTI->evWakeUp) {
- SetEvent(pipeTI->evWakeUp);
- }
#ifndef _PTI_USE_CKALLOC
free(pipeTI);
#else
- ckfree(pipeTI);
+ Tcl_Free(pipeTI);
/* be sure all subsystems used are finalized */
Tcl_FinalizeThread();
#endif /* !_PTI_USE_CKALLOC */
diff --git a/win/tclWinPort.h b/win/tclWinPort.h
index ef6918f..afb76df 100644
--- a/win/tclWinPort.h
+++ b/win/tclWinPort.h
@@ -18,18 +18,22 @@
/* See [Bug 3354324]: file mtime sets wrong time */
# define __MINGW_USE_VC2005_COMPAT
#endif
+#if defined(_MSC_VER) && defined(_WIN64) && !defined(STATIC_BUILD) \
+ && !defined(MP_32BIT) && !defined(MP_64BIT)
+# define MP_64BIT
+#endif
/*
* We must specify the lower version we intend to support.
*
- * WINVER = 0x0501 means Windows XP and above
+ * WINVER = 0x0601 means Windows 7 and above
*/
#ifndef WINVER
-# define WINVER 0x0501
+# define WINVER 0x0601
#endif
#ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
+# define _WIN32_WINNT 0x0601
#endif
#define WIN32_LEAN_AND_MEAN
@@ -54,15 +58,6 @@ typedef DWORD_PTR * PDWORD_PTR;
# include <wspiapi.h>
#endif
-#ifdef CHECK_UNICODE_CALLS
-# define _UNICODE
-# define UNICODE
-# define __TCHAR_DEFINED
- typedef float *_TCHAR;
-# define _TCHAR_DEFINED
- typedef float *TCHAR;
-#endif /* CHECK_UNICODE_CALLS */
-
/*
* Pull in the typedef of TCHAR for windows.
*/
@@ -97,7 +92,6 @@ typedef DWORD_PTR * PDWORD_PTR;
# include <inttypes.h>
#endif
#include <limits.h>
-
#ifndef __GNUC__
# define strncasecmp _strnicmp
# define strcasecmp _stricmp
@@ -111,11 +105,7 @@ typedef DWORD_PTR * PDWORD_PTR;
#ifndef __MWERKS__
#include <sys/stat.h>
#include <sys/timeb.h>
-# ifdef __BORLANDC__
-# include <utime.h>
-# else
-# include <sys/utime.h>
-# endif /* __BORLANDC__ */
+#include <sys/utime.h>
#endif /* __MWERKS__ */
/*
@@ -124,7 +114,7 @@ typedef DWORD_PTR * PDWORD_PTR;
*/
#ifndef ENOTEMPTY
-# define ENOTEMPTY 41 /* Directory not empty */
+# define ENOTEMPTY 41 /* Directory not empty */
#endif
#ifndef EREMOTE
# define EREMOTE 66 /* The object is remote */
@@ -256,7 +246,6 @@ typedef DWORD_PTR * PDWORD_PTR;
# define EWOULDBLOCK 140 /* Operation would block */
#endif
-
/* Visual Studio doesn't have these, so just choose some high numbers */
#ifndef ESOCKTNOSUPPORT
# define ESOCKTNOSUPPORT 240 /* Socket type not supported */
@@ -425,7 +414,6 @@ typedef DWORD_PTR * PDWORD_PTR;
# endif
#endif /* !S_ISLNK */
-
/*
* Define MAXPATHLEN in terms of MAXPATH if available
*/
@@ -457,46 +445,25 @@ typedef DWORD_PTR * PDWORD_PTR;
#if defined(_MSC_VER) || defined(__MSVCRT__)
# define environ _environ
-# if defined(_MSC_VER) && (_MSC_VER < 1600)
-# define hypot _hypot
-# endif
# define exception _exception
# undef EDEADLOCK
-# if defined(_MSC_VER) && (_MSC_VER >= 1700)
+# if defined(_MSC_VER)
# define timezone _timezone
# endif
#endif /* _MSC_VER || __MSVCRT__ */
-/*
- * Borland's timezone and environ functions.
- */
-
-#ifdef __BORLANDC__
-# define timezone _timezone
-# define environ _environ
-#endif /* __BORLANDC__ */
-
-#ifdef __WATCOMC__
-# 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 defined(_MSC_VER)
# pragma warning(disable:4090) /* see: https://developercommunity.visualstudio.com/t/c-compiler-incorrect-propagation-of-const-qualifie/390711 */
# pragma warning(disable:4146)
# pragma warning(disable:4244)
-# if _MSC_VER >= 1400
-# pragma warning(disable:4267)
-# pragma warning(disable:4996)
-# endif
+#if !defined(_WIN64)
+# pragma warning(disable:4305)
+#endif
+# pragma warning(disable:4267)
+# pragma warning(disable:4996)
+# pragma warning(disable:5287) /* See [1dcda0e862] */
#endif
+
/*
*---------------------------------------------------------------------------
* The following macros and declarations represent the interface between
@@ -546,31 +513,28 @@ typedef DWORD_PTR * PDWORD_PTR;
* use by tclAlloc.c.
*/
-#define TclpSysAlloc(size, isBin) ((void*)HeapAlloc(GetProcessHeap(), \
- (DWORD)0, (DWORD)size))
+#define TclpSysAlloc(size) ((void*)HeapAlloc(GetProcessHeap(), \
+ 0, size))
#define TclpSysFree(ptr) (HeapFree(GetProcessHeap(), \
- (DWORD)0, (HGLOBAL)ptr))
+ 0, (HGLOBAL)ptr))
#define TclpSysRealloc(ptr, size) ((void*)HeapReAlloc(GetProcessHeap(), \
- (DWORD)0, (LPVOID)ptr, (DWORD)size))
+ 0, (LPVOID)ptr, size))
/* This type is not defined in the Windows headers */
#define socklen_t int
-
/*
* The following macros have trivial definitions, allowing generic code to
* address platform-specific issues.
*/
-#define TclpReleaseFile(file) ckfree((char *) file)
+#define TclpReleaseFile(file) Tcl_Free(file)
/*
* The following macros and declarations wrap the C runtime library
* functions.
*/
-#define TclpExit exit
-
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
#endif /* INVALID_SET_FILE_POINTER */
@@ -579,7 +543,4 @@ typedef DWORD_PTR * PDWORD_PTR;
# define LABEL_SECURITY_INFORMATION (0x00000010L)
#endif
-#define Tcl_DirEntry void
-#define TclDIR void
-
#endif /* _TCLWINPORT */
diff --git a/win/tclWinReg.c b/win/tclWinReg.c
index d54ead2..493d28d 100644
--- a/win/tclWinReg.c
+++ b/win/tclWinReg.c
@@ -52,8 +52,9 @@
* 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
+enum OpenKeysFlags {
+ REG_CREATE = 1
+};
/*
* The following tables contain the mapping from registry root names to the
@@ -86,12 +87,28 @@ static const char *const typeNames[] = {
static DWORD lastType = REG_RESOURCE_LIST;
+#if (TCL_MAJOR_VERSION < 9) && defined(TCL_MINOR_VERSION) && (TCL_MINOR_VERSION < 7)
+# if TCL_UTF_MAX > 3
+# define Tcl_WCharToUtfDString(a,b,c) Tcl_WinTCharToUtf((TCHAR *)(a),(b)*sizeof(WCHAR),c)
+# define Tcl_UtfToWCharDString(a,b,c) (WCHAR *)Tcl_WinUtfToTChar(a,b,c)
+# else
+# define Tcl_WCharToUtfDString Tcl_UniCharToUtfDString
+# define Tcl_UtfToWCharDString Tcl_UtfToUniCharDString
+# endif
+#ifndef Tcl_Size
+# define Tcl_Size int
+#endif
+#ifndef Tcl_CreateObjCommand2
+# define Tcl_CreateObjCommand2 Tcl_CreateObjCommand
+#endif
+#endif
+
/*
* Declarations for functions defined in this file.
*/
static void AppendSystemError(Tcl_Interp *interp, DWORD error);
-static int BroadcastValue(Tcl_Interp *interp, int objc,
+static int BroadcastValue(Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static DWORD ConvertDWORD(DWORD type, DWORD value);
static void DeleteCmd(void *clientData);
@@ -118,46 +135,22 @@ static int ParseKeyName(Tcl_Interp *interp, char *name,
static DWORD RecursiveDeleteKey(HKEY hStartKey,
const WCHAR * pKeyName, REGSAM mode);
static int RegistryObjCmd(void *clientData,
- Tcl_Interp *interp, int objc,
+ Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[]);
static int SetValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,
Tcl_Obj *valueNameObj, Tcl_Obj *dataObj,
Tcl_Obj *typeObj, REGSAM mode);
-#if (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
-# if TCL_UTF_MAX > 3
-# define Tcl_WCharToUtfDString(a,b,c) Tcl_WinTCharToUtf((TCHAR *)(a),(b)*sizeof(WCHAR),c)
-# define Tcl_UtfToWCharDString(a,b,c) (WCHAR *)Tcl_WinUtfToTChar(a,b,c)
-# else
-# define Tcl_WCharToUtfDString Tcl_UniCharToUtfDString
-# define Tcl_UtfToWCharDString Tcl_UtfToUniCharDString
-# endif
-#endif
-
-static unsigned char *
-getByteArrayFromObj(
- Tcl_Obj *objPtr,
- size_t *lengthPtr
-) {
- int length;
-
- unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, &length);
-#if TCL_MAJOR_VERSION > 8
- if (sizeof(TCL_HASH_TYPE) > sizeof(int)) {
- /* 64-bit and TIP #494 situation: */
- *lengthPtr = *(TCL_HASH_TYPE *) objPtr->internalRep.twoPtrValue.ptr1;
- } else
-#endif
- /* 32-bit or without TIP #494 */
- *lengthPtr = (size_t) (unsigned) length;
- return result;
-}
-
#ifdef __cplusplus
extern "C" {
#endif
DLLEXPORT int Registry_Init(Tcl_Interp *interp);
DLLEXPORT int Registry_Unload(Tcl_Interp *interp, int flags);
+#if TCL_MAJOR_VERSION < 9
+/* With those additional entries, "load tclregistry13.dll" works without 3th argument */
+DLLEXPORT int Tclregistry_Init(Tcl_Interp *interp);
+DLLEXPORT int Tclregistry_Unload(Tcl_Interp *interp, int flags);
+#endif
#ifdef __cplusplus
}
#endif
@@ -188,11 +181,19 @@ Registry_Init(
return TCL_ERROR;
}
- cmd = Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd,
+ cmd = Tcl_CreateObjCommand2(interp, "registry", RegistryObjCmd,
interp, DeleteCmd);
Tcl_SetAssocData(interp, REGISTRY_ASSOC_KEY, NULL, cmd);
- return Tcl_PkgProvideEx(interp, "registry", "1.3.5", NULL);
+ return Tcl_PkgProvideEx(interp, "registry", "1.3.7", NULL);
+}
+#if TCL_MAJOR_VERSION < 9
+int
+Tclregistry_Init(
+ Tcl_Interp *interp)
+{
+ return Registry_Init(interp);
}
+#endif
/*
*----------------------------------------------------------------------
@@ -239,6 +240,15 @@ Registry_Unload(
return TCL_OK;
}
+#if TCL_MAJOR_VERSION < 9
+int
+Tclregistry_Unload(
+ Tcl_Interp *interp,
+ int flags)
+{
+ return Registry_Unload(interp, flags);
+}
+#endif
/*
*----------------------------------------------------------------------
@@ -284,13 +294,13 @@ DeleteCmd(
static int
RegistryObjCmd(
- void *dummy, /* Not used. */
+ void *dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument values. */
{
- int n = 1;
- int index, argc;
+ Tcl_Size n = 1, argc;
+ int index;
REGSAM mode = 0;
const char *errString = NULL;
@@ -377,7 +387,7 @@ RegistryObjCmd(
*/
mode |= KEY_ALL_ACCESS;
- if (OpenKey(interp, objv[n], mode, 1, &key) != TCL_OK) {
+ if (OpenKey(interp, objv[n], mode, REG_CREATE, &key) != TCL_OK) {
return TCL_ERROR;
}
RegCloseKey(key);
@@ -438,13 +448,14 @@ DeleteKey(
DWORD result;
Tcl_DString buf;
REGSAM saveMode = mode;
+ Tcl_Size len;
/*
* Find the parent of the key being deleted and open it.
*/
- keyName = Tcl_GetString(keyNameObj);
- buffer = (char *)Tcl_Alloc(keyNameObj->length + 1);
+ keyName = Tcl_GetStringFromObj(keyNameObj, &len);
+ buffer = (char *)Tcl_Alloc(len + 1);
strcpy(buffer, keyName);
if (ParseKeyName(interp, buffer, &hostName, &rootKey,
@@ -456,7 +467,7 @@ DeleteKey(
if (*keyName == '\0') {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("bad key: cannot delete root keys", -1));
- Tcl_SetErrorCode(interp, "WIN_REG", "DEL_ROOT_KEY", NULL);
+ Tcl_SetErrorCode(interp, "WIN_REG", "DEL_ROOT_KEY", (char *)NULL);
Tcl_Free(buffer);
return TCL_ERROR;
}
@@ -532,6 +543,7 @@ DeleteValue(
char *valueName;
DWORD result;
Tcl_DString ds;
+ Tcl_Size len;
/*
* Attempt to open the key for deletion.
@@ -542,9 +554,9 @@ DeleteValue(
return TCL_ERROR;
}
- valueName = Tcl_GetString(valueNameObj);
+ valueName = Tcl_GetStringFromObj(valueNameObj, &len);
Tcl_DStringInit(&ds);
- Tcl_UtfToWCharDString(valueName, valueNameObj->length, &ds);
+ Tcl_UtfToWCharDString(valueName, len, &ds);
result = RegDeleteValueW(key, (const WCHAR *)Tcl_DStringValue(&ds));
Tcl_DStringFree(&ds);
if (result != ERROR_SUCCESS) {
@@ -685,6 +697,7 @@ GetType(
Tcl_DString ds;
const char *valueName;
const WCHAR *nativeValue;
+ Tcl_Size len;
/*
* Attempt to open the key for reading.
@@ -699,9 +712,9 @@ GetType(
* Get the type of the value.
*/
- valueName = Tcl_GetString(valueNameObj);
+ valueName = Tcl_GetStringFromObj(valueNameObj, &len);
Tcl_DStringInit(&ds);
- nativeValue = Tcl_UtfToWCharDString(valueName, valueNameObj->length, &ds);
+ nativeValue = Tcl_UtfToWCharDString(valueName, len, &ds);
result = RegQueryValueExW(key, nativeValue, NULL, &type,
NULL, NULL);
Tcl_DStringFree(&ds);
@@ -755,8 +768,9 @@ GetValue(
HKEY key;
const char *valueName;
const WCHAR *nativeValue;
- DWORD result, length, type;
+ DWORD result, type, length;
Tcl_DString data, buf;
+ Tcl_Size len;
/*
* Attempt to open the key for reading.
@@ -781,9 +795,9 @@ GetValue(
Tcl_DStringSetLength(&data, TCL_DSTRING_STATIC_SIZE - 1);
length = TCL_DSTRING_STATIC_SIZE/sizeof(WCHAR) - 1;
- valueName = Tcl_GetString(valueNameObj);
+ valueName = Tcl_GetStringFromObj(valueNameObj, &len);
Tcl_DStringInit(&buf);
- nativeValue = Tcl_UtfToWCharDString(valueName, valueNameObj->length, &buf);
+ nativeValue = Tcl_UtfToWCharDString(valueName, len, &buf);
result = RegQueryValueExW(key, nativeValue, NULL, &type,
(BYTE *) Tcl_DStringValue(&data), &length);
@@ -794,8 +808,8 @@ GetValue(
* HKEY_PERFORMANCE_DATA
*/
- length = Tcl_DStringLength(&data) * (2 / sizeof(WCHAR));
- Tcl_DStringSetLength(&data, (int) length * sizeof(WCHAR));
+ length = (DWORD)(Tcl_DStringLength(&data) * (2 / sizeof(WCHAR)));
+ Tcl_DStringSetLength(&data, length * sizeof(WCHAR));
result = RegQueryValueExW(key, nativeValue,
NULL, &type, (BYTE *) Tcl_DStringValue(&data), &length);
}
@@ -840,7 +854,7 @@ GetValue(
Tcl_NewStringObj(Tcl_DStringValue(&buf),
Tcl_DStringLength(&buf)));
- while (*wp++ != 0) {/* empty body */}
+ while (*wp++ != 0); /* empty loop body */
p = (char *) wp;
Tcl_DStringFree(&buf);
}
@@ -856,7 +870,7 @@ GetValue(
*/
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(
- (BYTE *) Tcl_DStringValue(&data), (int) length));
+ (BYTE *) Tcl_DStringValue(&data), length));
}
Tcl_DStringFree(&data);
return result;
@@ -905,7 +919,7 @@ GetValueNames(
resultPtr = Tcl_NewObj();
Tcl_DStringInit(&buffer);
- Tcl_DStringSetLength(&buffer, (int) (MAX_KEY_LENGTH * sizeof(WCHAR)));
+ Tcl_DStringSetLength(&buffer, MAX_KEY_LENGTH * sizeof(WCHAR));
index = 0;
result = TCL_OK;
@@ -924,7 +938,6 @@ GetValueNames(
size = MAX_KEY_LENGTH;
while (RegEnumValueW(key,index, (WCHAR *)Tcl_DStringValue(&buffer),
&size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
-
Tcl_DStringInit(&ds);
Tcl_WCharToUtfDString((const WCHAR *)Tcl_DStringValue(&buffer), size, &ds);
name = Tcl_DStringValue(&ds);
@@ -975,9 +988,10 @@ OpenKey(
char *keyName, *buffer, *hostName;
HKEY rootKey;
DWORD result;
+ Tcl_Size len;
- keyName = Tcl_GetString(keyNameObj);
- buffer = (char *)Tcl_Alloc(keyNameObj->length + 1);
+ keyName = Tcl_GetStringFromObj(keyNameObj, &len);
+ buffer = (char *)Tcl_Alloc(len + 1);
strcpy(buffer, keyName);
result = ParseKeyName(interp, buffer, &hostName, &rootKey, &keyName);
@@ -1133,7 +1147,7 @@ ParseKeyName(
if (!rootName) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad key \"%s\": must start with a valid root", name));
- Tcl_SetErrorCode(interp, "WIN_REG", "NO_ROOT_KEY", NULL);
+ Tcl_SetErrorCode(interp, "WIN_REG", "NO_ROOT_KEY", (char *)NULL);
return TCL_ERROR;
}
@@ -1194,7 +1208,11 @@ RecursiveDeleteKey(
HKEY hKey;
REGSAM saveMode = mode;
static int checkExProc = 0;
- static LONG (* regDeleteKeyExProc) (HKEY, LPCWSTR, REGSAM, DWORD) = (LONG (*) (HKEY, LPCWSTR, REGSAM, DWORD)) NULL;
+ typedef LONG (* regDeleteKeyExProc) (HKEY, LPCWSTR, REGSAM, DWORD);
+ static regDeleteKeyExProc regDeleteKeyEx = (regDeleteKeyExProc) NULL;
+ /* Really RegDeleteKeyExW() but that's not
+ * available on all versions of Windows
+ * supported by Tcl. */
/*
* Do not allow NULL or empty key name.
@@ -1211,7 +1229,7 @@ RecursiveDeleteKey(
}
Tcl_DStringInit(&subkey);
- Tcl_DStringSetLength(&subkey, (int) (MAX_KEY_LENGTH * sizeof(WCHAR)));
+ Tcl_DStringSetLength(&subkey, MAX_KEY_LENGTH * sizeof(WCHAR));
mode = saveMode;
while (result == ERROR_SUCCESS) {
@@ -1234,11 +1252,11 @@ RecursiveDeleteKey(
checkExProc = 1;
handle = GetModuleHandleW(L"ADVAPI32");
- regDeleteKeyExProc = (LONG (*) (HKEY, LPCWSTR, REGSAM, DWORD))
- (void *)GetProcAddress(handle, "RegDeleteKeyExW");
+ regDeleteKeyEx = (regDeleteKeyExProc) (void *)
+ GetProcAddress(handle, "RegDeleteKeyExW");
}
- if (mode && regDeleteKeyExProc) {
- result = regDeleteKeyExProc(startKey, keyName, mode, 0);
+ if (mode && regDeleteKeyEx) {
+ result = regDeleteKeyEx(startKey, keyName, mode, 0);
} else {
result = RegDeleteKeyW(startKey, keyName);
}
@@ -1285,6 +1303,7 @@ SetValue(
HKEY key;
const char *valueName;
Tcl_DString nameBuf;
+ Tcl_Size len;
if (typeObj == NULL) {
type = REG_SZ;
@@ -1296,13 +1315,13 @@ SetValue(
Tcl_ResetResult(interp);
}
mode |= KEY_ALL_ACCESS;
- if (OpenKey(interp, keyNameObj, mode, 1, &key) != TCL_OK) {
+ if (OpenKey(interp, keyNameObj, mode, REG_CREATE, &key) != TCL_OK) {
return TCL_ERROR;
}
- valueName = Tcl_GetString(valueNameObj);
+ valueName = Tcl_GetStringFromObj(valueNameObj, &len);
Tcl_DStringInit(&nameBuf);
- valueName = (char *) Tcl_UtfToWCharDString(valueName, valueNameObj->length, &nameBuf);
+ valueName = (char *) Tcl_UtfToWCharDString(valueName, len, &nameBuf);
if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
int value;
@@ -1318,7 +1337,7 @@ SetValue(
(DWORD) type, (BYTE *) &value, sizeof(DWORD));
} else if (type == REG_MULTI_SZ) {
Tcl_DString data, buf;
- int objc, i;
+ Tcl_Size objc, i;
Tcl_Obj **objv;
if (Tcl_ListObjGetElements(interp, dataObj, &objc, &objv) != TCL_OK) {
@@ -1335,9 +1354,9 @@ SetValue(
Tcl_DStringInit(&data);
for (i = 0; i < objc; i++) {
- const char *bytes = Tcl_GetString(objv[i]);
+ const char *bytes = Tcl_GetStringFromObj(objv[i], &len);
- Tcl_DStringAppend(&data, bytes, objv[i]->length);
+ Tcl_DStringAppend(&data, bytes, len);
/*
* Add a null character to separate this value from the next.
@@ -1356,10 +1375,10 @@ SetValue(
Tcl_DStringFree(&buf);
} else if (type == REG_SZ || type == REG_EXPAND_SZ) {
Tcl_DString buf;
- const char *data = Tcl_GetString(dataObj);
+ const char *data = Tcl_GetStringFromObj(dataObj, &len);
Tcl_DStringInit(&buf);
- data = (char *) Tcl_UtfToWCharDString(data, dataObj->length, &buf);
+ data = (char *) Tcl_UtfToWCharDString(data, len, &buf);
/*
* Include the null in the length, padding if needed for WCHAR.
@@ -1372,13 +1391,13 @@ SetValue(
Tcl_DStringFree(&buf);
} else {
BYTE *data;
- size_t bytelength;
+ Tcl_Size bytelength;
/*
* Store binary data in the registry.
*/
- data = (BYTE *) getByteArrayFromObj(dataObj, &bytelength);
+ data = (BYTE *) Tcl_GetByteArrayFromObj(dataObj, &bytelength);
result = RegSetValueExW(key, (WCHAR *) valueName, 0,
(DWORD) type, data, (DWORD) bytelength);
}
@@ -1415,21 +1434,20 @@ SetValue(
static int
BroadcastValue(
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument values. */
{
LRESULT result;
DWORD_PTR sendResult;
int timeout = 3000;
- size_t len;
+ Tcl_Size len;
const char *str;
Tcl_Obj *objPtr;
WCHAR *wstr;
Tcl_DString ds;
if (objc == 3) {
- str = Tcl_GetString(objv[1]);
- len = objv[1]->length;
+ str = Tcl_GetStringFromObj(objv[1], &len);
if ((len < 2) || (*str != '-') || strncmp(str, "-timeout", len)) {
return TCL_BREAK;
}
@@ -1438,9 +1456,9 @@ BroadcastValue(
}
}
- str = Tcl_GetString(objv[0]);
+ str = Tcl_GetStringFromObj(objv[0], &len);
Tcl_DStringInit(&ds);
- wstr = Tcl_UtfToWCharDString(str, objv[0]->length, &ds);
+ wstr = Tcl_UtfToWCharDString(str, len, &ds);
if (Tcl_DStringLength(&ds) == 0) {
wstr = NULL;
}
@@ -1483,7 +1501,7 @@ AppendSystemError(
Tcl_Interp *interp, /* Current interpreter. */
DWORD error) /* Result code from error. */
{
- int length;
+ Tcl_Size length;
WCHAR *tMsgPtr, **tMsgPtrPtr = &tMsgPtr;
const char *msg;
char id[TCL_INTEGER_SPACE], msgBuf[24 + TCL_INTEGER_SPACE];
@@ -1525,7 +1543,7 @@ AppendSystemError(
}
snprintf(id, sizeof(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);
diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c
index 155312b..48baaa8 100644
--- a/win/tclWinSerial.c
+++ b/win/tclWinSerial.c
@@ -4,7 +4,7 @@
* This file implements the Windows-specific serial port functions, and
* the "serial" channel driver.
*
- * Copyright (c) 1999 by Scriptics Corp.
+ * Copyright © 1999 Scriptics Corp.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -32,16 +32,27 @@ TCL_DECLARE_MUTEX(serialMutex)
/*
* Bit masks used in the flags field of the SerialInfo structure below.
*/
+enum SerialFlags {
+ SERIAL_PENDING = 1 << 0, /* Message is pending in the queue. */
+ 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.
+ */
-/*
- * Bit masks used in the sharedFlags field of the SerialInfo structure below.
- */
+ SERIAL_EOF = 1 << 2, /* Serial has reached EOF. */
+ SERIAL_ERROR = 1 << 4,
-#define SERIAL_EOF (1<<2) /* Serial has reached EOF. */
-#define SERIAL_ERROR (1<<4)
+ /*
+ * Bit masks used for noting whether to drain or discard output on close.
+ * They are disjoint from each other; at most one may be set at a time.
+ */
+
+ SERIAL_CLOSE_DRAIN = 1<<6, /* Drain all output on close. */
+ SERIAL_CLOSE_DISCARD = 1<<7,/* Discard all output on close. */
+ SERIAL_CLOSE_MASK = 3<<6 /* Both two bits above. */
+};
/*
* Default time to block between checking status on the serial port.
@@ -50,13 +61,14 @@ TCL_DECLARE_MUTEX(serialMutex)
#define SERIAL_DEFAULT_BLOCKTIME 10 /* 10 msec */
/*
- * Define Win32 read/write error masks returned by ClearCommError()
+ * Win32 read/write error masks for values returned by ClearCommError()
*/
-
-#define SERIAL_READ_ERRORS \
- (CE_RXOVER | CE_OVERRUN | CE_RXPARITY | CE_FRAME | CE_BREAK)
-#define SERIAL_WRITE_ERRORS \
+enum TclWinCommErrorMasks {
+ SERIAL_READ_ERRORS = /* Errors in the reader side. */
+ (CE_RXOVER | CE_OVERRUN | CE_RXPARITY | CE_FRAME | CE_BREAK),
+ SERIAL_WRITE_ERRORS = /* Errors in the writer side. */
(CE_TXFULL | CE_PTO)
+};
/*
* This structure describes per-instance data for a serial based channel.
@@ -76,7 +88,8 @@ typedef struct SerialInfo {
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
+ unsigned long long lastEventTime;
+ /* Time in milliseconds since last readable
* event. */
/* Next readable event only after blockTime */
DWORD error; /* pending error code returned by
@@ -115,7 +128,7 @@ typedef struct SerialInfo {
* [fconfigure -queue] */
} SerialInfo;
-typedef struct ThreadSpecificData {
+typedef struct {
/*
* The following pointer refers to the head of the list of serials that
* are being watched for file events.
@@ -131,7 +144,7 @@ static Tcl_ThreadDataKey dataKey;
* events are generated.
*/
-typedef struct SerialEvent {
+typedef struct {
Tcl_Event header; /* Information that is standard for all
* events. */
SerialInfo *infoPtr; /* Pointer to serial info structure. Note that
@@ -156,32 +169,30 @@ static COMMTIMEOUTS no_timeout = {
* 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 SerialClose2Proc(ClientData instanceData,
+static int SerialBlockProc(void *instanceData, int mode);
+static void SerialCheckProc(void *clientData, int flags);
+static int SerialCloseProc(void *instanceData,
Tcl_Interp *interp, int flags);
static int SerialEventProc(Tcl_Event *evPtr, int flags);
-static void SerialExitHandler(ClientData clientData);
-static int SerialGetHandleProc(ClientData instanceData,
- int direction, ClientData *handlePtr);
+static void SerialExitHandler(void *clientData);
+static int SerialGetHandleProc(void *instanceData,
+ int direction, void **handlePtr);
static ThreadSpecificData *SerialInit(void);
-static int SerialInputProc(ClientData instanceData, char *buf,
+static int SerialInputProc(void *instanceData, char *buf,
int toRead, int *errorCode);
-static int SerialOutputProc(ClientData instanceData,
+static int SerialOutputProc(void *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,
+static void SerialSetupProc(void *clientData, int flags);
+static void SerialWatchProc(void *instanceData, int mask);
+static void ProcExitHandler(void *clientData);
+static int SerialGetOptionProc(void *instanceData,
Tcl_Interp *interp, const char *optionName,
Tcl_DString *dsPtr);
-static int SerialSetOptionProc(ClientData instanceData,
+static int SerialSetOptionProc(void *instanceData,
Tcl_Interp *interp, const char *optionName,
const char *value);
static DWORD WINAPI SerialWriterThread(LPVOID arg);
-static void SerialThreadActionProc(ClientData instanceData,
+static void SerialThreadActionProc(void *instanceData,
int action);
static int SerialBlockingRead(SerialInfo *infoPtr, LPVOID buf,
DWORD bufSize, LPDWORD lpRead, LPOVERLAPPED osPtr);
@@ -195,23 +206,23 @@ static int SerialBlockingWrite(SerialInfo *infoPtr, LPVOID buf,
*/
static const Tcl_ChannelType serialChannelType = {
- "serial", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
- SerialCloseProc, /* Close proc. */
- SerialInputProc, /* Input proc. */
- SerialOutputProc, /* Output proc. */
+ "serial",
+ TCL_CHANNEL_VERSION_5,
+ NULL, /* Deprecated. */
+ SerialInputProc,
+ SerialOutputProc,
+ NULL, /* Deprecated. */
+ SerialSetOptionProc,
+ SerialGetOptionProc,
+ SerialWatchProc,
+ SerialGetHandleProc,
+ SerialCloseProc,
+ SerialBlockProc,
+ NULL, /* Flush proc. */
+ NULL, /* Bubbled event handler 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. */
- SerialClose2Proc, /* close2proc. */
- SerialBlockProc, /* Set blocking or non-blocking mode.*/
- NULL, /* flush proc. */
- NULL, /* handler proc. */
- NULL, /* wide seek proc */
- SerialThreadActionProc, /* thread action proc */
- NULL /* truncate */
+ SerialThreadActionProc,
+ NULL /* Truncate proc. */
};
/*
@@ -278,7 +289,7 @@ SerialInit(void)
static void
SerialExitHandler(
- ClientData clientData) /* Old window proc */
+ TCL_UNUSED(void *))
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
SerialInfo *infoPtr;
@@ -316,7 +327,7 @@ SerialExitHandler(
static void
ProcExitHandler(
- ClientData clientData) /* Old window proc */
+ TCL_UNUSED(void *))
{
Tcl_MutexLock(&serialMutex);
initialized = 0;
@@ -366,14 +377,15 @@ SerialBlockTime(
*----------------------------------------------------------------------
*/
-static unsigned int
+static unsigned long long
SerialGetMilliseconds(void)
{
Tcl_Time time;
Tcl_GetTime(&time);
- return (time.sec * 1000 + time.usec / 1000);
+ return (unsigned long long)time.sec * 1000
+ + (unsigned long)time.usec / 1000;
}
/*
@@ -393,9 +405,13 @@ SerialGetMilliseconds(void)
*----------------------------------------------------------------------
*/
+#ifdef __cplusplus
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
void
SerialSetupProc(
- ClientData data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
SerialInfo *infoPtr;
@@ -450,7 +466,7 @@ SerialSetupProc(
static void
SerialCheckProc(
- ClientData data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
SerialInfo *infoPtr;
@@ -458,7 +474,7 @@ SerialCheckProc(
int needEvent;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
COMSTAT cStat;
- unsigned int time;
+ unsigned long long time;
if (!(flags & TCL_FILE_EVENTS)) {
return;
@@ -508,8 +524,8 @@ SerialCheckProc(
(infoPtr->error & SERIAL_READ_ERRORS)) {
infoPtr->readable = 1;
time = SerialGetMilliseconds();
- if ((unsigned int) (time - infoPtr->lastEventTime)
- >= (unsigned int) infoPtr->blockTime) {
+ if ((time - infoPtr->lastEventTime)
+ >= (unsigned long long) infoPtr->blockTime) {
needEvent = 1;
infoPtr->lastEventTime = time;
}
@@ -524,7 +540,7 @@ SerialCheckProc(
if (needEvent) {
infoPtr->flags |= SERIAL_PENDING;
- evPtr = (SerialEvent *)ckalloc(sizeof(SerialEvent));
+ evPtr = (SerialEvent *)Tcl_Alloc(sizeof(SerialEvent));
evPtr->header.proc = SerialEventProc;
evPtr->infoPtr = infoPtr;
Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
@@ -550,7 +566,7 @@ SerialCheckProc(
static int
SerialBlockProc(
- ClientData instanceData, /* Instance data for channel. */
+ void *instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
@@ -574,7 +590,7 @@ SerialBlockProc(
/*
*----------------------------------------------------------------------
*
- * SerialCloseProc/SerialClose2Proc --
+ * SerialCloseProc --
*
* Closes a serial based IO channel.
*
@@ -589,15 +605,18 @@ SerialBlockProc(
static int
SerialCloseProc(
- ClientData instanceData, /* Pointer to SerialInfo structure. */
- Tcl_Interp *interp) /* For error reporting. */
+ void *instanceData, /* Pointer to SerialInfo structure. */
+ TCL_UNUSED(Tcl_Interp *),
+ int flags)
{
SerialInfo *serialPtr = (SerialInfo *) instanceData;
- int errorCode, result = 0;
+ int errorCode = 0, result = 0;
SerialInfo *infoPtr, **nextPtrPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- errorCode = 0;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
if (serialPtr->validMask & TCL_READABLE) {
PurgeComm(serialPtr->handle, PURGE_RXABORT | PURGE_RXCLEAR);
@@ -606,8 +625,7 @@ SerialCloseProc(
serialPtr->validMask &= ~TCL_READABLE;
if (serialPtr->writeThread) {
-
- TclPipeThreadStop(&serialPtr->writeTI, serialPtr->writeThread);
+ TclPipeThreadStop(&serialPtr->writeTI, serialPtr->writeThread);
CloseHandle(serialPtr->osWrite.hEvent);
CloseHandle(serialPtr->evWritable);
@@ -631,7 +649,7 @@ SerialCloseProc(
&& (GetStdHandle(STD_OUTPUT_HANDLE) != serialPtr->handle)
&& (GetStdHandle(STD_ERROR_HANDLE) != serialPtr->handle))) {
if (CloseHandle(serialPtr->handle) == FALSE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
errorCode = errno;
}
}
@@ -656,28 +674,16 @@ SerialCloseProc(
*/
if (serialPtr->writeBuf != NULL) {
- ckfree(serialPtr->writeBuf);
+ Tcl_Free(serialPtr->writeBuf);
serialPtr->writeBuf = NULL;
}
- ckfree(serialPtr);
+ Tcl_Free(serialPtr);
if (errorCode == 0) {
return result;
}
return errorCode;
}
-
-static int
-SerialClose2Proc(
- ClientData instanceData, /* Pointer to SerialInfo structure. */
- Tcl_Interp *interp, /* For error reporting. */
- int flags)
-{
- if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) == 0) {
- return SerialCloseProc(instanceData, interp);
- }
- return EINVAL;
-}
/*
*----------------------------------------------------------------------
@@ -794,7 +800,7 @@ SerialBlockingWrite(
LeaveCriticalSection(&infoPtr->csWrite);
if (result == FALSE) {
- int err = GetLastError();
+ DWORD err = GetLastError();
switch (err) {
case ERROR_IO_PENDING:
@@ -853,7 +859,7 @@ SerialBlockingWrite(
static int
SerialInputProc(
- ClientData instanceData, /* Serial state. */
+ void *instanceData, /* Serial state. */
char *buf, /* Where to store data read. */
int bufSize, /* How much space is available in the
* buffer? */
@@ -916,7 +922,7 @@ SerialInputProc(
}
if (bufSize == 0) {
- return bytesRead = 0;
+ return 0;
}
/*
@@ -926,7 +932,7 @@ SerialInputProc(
if (SerialBlockingRead(infoPtr, (LPVOID) buf, (DWORD) bufSize, &bytesRead,
&infoPtr->osRead) == FALSE) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
*errorCode = errno;
return -1;
}
@@ -960,7 +966,7 @@ SerialInputProc(
static int
SerialOutputProc(
- ClientData instanceData, /* Serial state. */
+ void *instanceData, /* Serial state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCode) /* Where to store error code. */
@@ -1008,7 +1014,7 @@ SerialOutputProc(
*/
if (infoPtr->writeError) {
- TclWinConvertError(infoPtr->writeError);
+ Tcl_WinConvertError(infoPtr->writeError);
infoPtr->writeError = 0;
goto error1;
}
@@ -1033,10 +1039,10 @@ SerialOutputProc(
*/
if (infoPtr->writeBuf) {
- ckfree(infoPtr->writeBuf);
+ Tcl_Free(infoPtr->writeBuf);
}
infoPtr->writeBufLen = toWrite;
- infoPtr->writeBuf = (char *)ckalloc(toWrite);
+ infoPtr->writeBuf = (char *)Tcl_Alloc(toWrite);
}
memcpy(infoPtr->writeBuf, buf, toWrite);
infoPtr->toWrite = toWrite;
@@ -1067,7 +1073,7 @@ SerialOutputProc(
return (int) bytesWritten;
writeError:
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
error:
/*
@@ -1190,7 +1196,7 @@ SerialEventProc(
static void
SerialWatchProc(
- ClientData instanceData, /* Serial state. */
+ void *instanceData, /* Serial state. */
int mask) /* What events to watch for, OR-ed combination
* of TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
@@ -1247,13 +1253,13 @@ SerialWatchProc(
static int
SerialGetHandleProc(
- ClientData instanceData, /* The serial state. */
- int direction, /* TCL_READABLE or TCL_WRITABLE */
- ClientData *handlePtr) /* Where to store the handle. */
+ void *instanceData, /* The serial state. */
+ TCL_UNUSED(int) /*direction*/,
+ void **handlePtr) /* Where to store the handle. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
- *handlePtr = (ClientData) infoPtr->handle;
+ *handlePtr = (void *)infoPtr->handle;
return TCL_OK;
}
@@ -1279,7 +1285,7 @@ SerialWriterThread(
LPVOID arg)
{
TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg;
- SerialInfo *infoPtr = NULL; /* access info only after success init/wait */
+ SerialInfo *infoPtr = NULL; /* access info only after success init/wait */
DWORD bytesWritten, toWrite;
char *buf;
OVERLAPPED myWrite; /* Have an own OVERLAPPED in this thread. */
@@ -1292,7 +1298,7 @@ SerialWriterThread(
/* exit */
break;
}
- infoPtr = (SerialInfo *)pipeTI->clientData;
+ infoPtr = (SerialInfo *) pipeTI->clientData;
buf = infoPtr->writeBuf;
toWrite = infoPtr->toWrite;
@@ -1356,7 +1362,25 @@ SerialWriterThread(
Tcl_MutexUnlock(&serialMutex);
}
- /* Worker exit, so inform the main thread or free TI-structure (if owned) */
+ /*
+ * We're about to close, so do any drain or discard required.
+ */
+
+ if (infoPtr) {
+ switch (infoPtr->flags & SERIAL_CLOSE_MASK) {
+ case SERIAL_CLOSE_DRAIN:
+ FlushFileBuffers(infoPtr->handle);
+ break;
+ case SERIAL_CLOSE_DISCARD:
+ PurgeComm(infoPtr->handle, PURGE_TXABORT | PURGE_TXCLEAR);
+ break;
+ }
+ }
+
+ /*
+ * Worker exit, so inform the main thread or free TI-structure (if owned).
+ */
+
TclPipeThreadExit(&pipeTI);
return 0;
@@ -1391,7 +1415,7 @@ TclWinSerialOpen(
* If an open channel is specified, close it
*/
- if ( handle != INVALID_HANDLE_VALUE && CloseHandle(handle) == FALSE) {
+ if (handle != INVALID_HANDLE_VALUE && CloseHandle(handle) == FALSE) {
return INVALID_HANDLE_VALUE;
}
@@ -1435,10 +1459,10 @@ TclWinOpenSerialChannel(
SerialInit();
- infoPtr = (SerialInfo *)ckalloc(sizeof(SerialInfo));
+ infoPtr = (SerialInfo *)Tcl_Alloc(sizeof(SerialInfo));
memset(infoPtr, 0, sizeof(SerialInfo));
- infoPtr->validMask = permissions;
+ infoPtr->validMask = permissions & (TCL_READABLE|TCL_WRITABLE);
infoPtr->handle = handle;
infoPtr->channel = (Tcl_Channel) NULL;
infoPtr->readable = 0;
@@ -1456,12 +1480,10 @@ TclWinOpenSerialChannel(
* are shared between multiple channels (stdin/stdout).
*/
- snprintf(channelName, 16 + TCL_INTEGER_SPACE, "file%" TCL_Z_MODIFIER "x", (size_t) infoPtr);
-
+ TclWinGenerateChannelName(channelName, "file", infoPtr);
infoPtr->channel = Tcl_CreateChannel(&serialChannelType, channelName,
infoPtr, permissions);
-
SetupComm(handle, infoPtr->sysBufRead, infoPtr->sysBufWrite);
PurgeComm(handle,
PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
@@ -1484,17 +1506,10 @@ TclWinOpenSerialChannel(
infoPtr->osWrite.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
infoPtr->evWritable = CreateEventW(NULL, TRUE, TRUE, NULL);
infoPtr->writeThread = CreateThread(NULL, 256, SerialWriterThread,
- TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr,
- infoPtr->evWritable), 0, NULL);
+ TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr), 0, NULL);
}
- /*
- * 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;
}
@@ -1599,22 +1614,20 @@ SerialModemStatusStr(
static int
SerialSetOptionProc(
- ClientData instanceData, /* File state. */
+ void *instanceData, /* Serial 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;
+ SerialInfo *infoPtr = (SerialInfo *) instanceData;
DCB dcb;
BOOL result, flag;
size_t len, vlen;
Tcl_DString ds;
const WCHAR *native;
- int argc;
+ Tcl_Size argc;
const char **argv;
- 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()...
@@ -1624,6 +1637,32 @@ SerialSetOptionProc(
vlen = strlen(value);
/*
+ * Option -closemode drain|discard|default
+ */
+
+ if ((len > 2) && (strncmp(optionName, "-closemode", len) == 0)) {
+ if (strncasecmp(value, "DEFAULT", vlen) == 0) {
+ infoPtr->flags &= ~SERIAL_CLOSE_MASK;
+ } else if (strncasecmp(value, "DRAIN", vlen) == 0) {
+ infoPtr->flags &= ~SERIAL_CLOSE_MASK;
+ infoPtr->flags |= SERIAL_CLOSE_DRAIN;
+ } else if (strncasecmp(value, "DISCARD", vlen) == 0) {
+ infoPtr->flags &= ~SERIAL_CLOSE_MASK;
+ infoPtr->flags |= SERIAL_CLOSE_DISCARD;
+ } else {
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad mode \"%s\" for -closemode: must be"
+ " default, discard, or drain", value));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE",
+ "VALUE", (char *)NULL);
+ }
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+ }
+
+ /*
* Option -mode baud,parity,databits,stopbits
*/
@@ -1631,7 +1670,8 @@ SerialSetOptionProc(
if (!GetCommState(infoPtr->handle, &dcb)) {
goto getStateFailed;
}
- native = (const WCHAR *)Tcl_WinUtfToTChar(value, -1, &ds);
+ Tcl_DStringInit(&ds);
+ native = Tcl_UtfToWCharDString(value, TCL_INDEX_NONE, &ds);
result = BuildCommDCBW(native, &dcb);
Tcl_DStringFree(&ds);
@@ -1640,7 +1680,7 @@ SerialSetOptionProc(
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad value \"%s\" for -mode: should be baud,parity,data,stop",
value));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", (char *)NULL);
}
return TCL_ERROR;
}
@@ -1704,7 +1744,7 @@ SerialSetOptionProc(
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad value \"%s\" for -handshake: must be one of"
" xonxoff, rtscts, dtrdsr or none", value));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "HANDSHAKE", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "HANDSHAKE", (char *)NULL);
}
return TCL_ERROR;
}
@@ -1732,10 +1772,11 @@ SerialSetOptionProc(
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"bad value for -xchar: should be a list of"
- " two elements with each a single character", -1));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "XCHAR", NULL);
+ " two elements with each a single 8-bit character",
+ TCL_INDEX_NONE));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "XCHAR", (char *)NULL);
}
- ckfree(argv);
+ Tcl_Free((void *)argv);
return TCL_ERROR;
}
@@ -1752,21 +1793,21 @@ SerialSetOptionProc(
dcb.XonChar = argv[0][0];
dcb.XoffChar = argv[1][0];
if (argv[0][0] & 0x80 || argv[1][0] & 0x80) {
- int character;
+ Tcl_UniChar character = 0;
int charLen;
- charLen = TclUtfToUCS4(argv[0], &character);
- if ((character & ~0xFF) || argv[0][charLen]) {
+ charLen = TclUtfToUniChar(argv[0], &character);
+ if ((character > 0xFF) || argv[0][charLen]) {
goto badXchar;
}
dcb.XonChar = (char) character;
- charLen = TclUtfToUCS4(argv[1], &character);
- if ((character & ~0xFF) || argv[1][charLen]) {
+ charLen = TclUtfToUniChar(argv[1], &character);
+ if ((character > 0xFF) || argv[1][charLen]) {
goto badXchar;
}
dcb.XoffChar = (char) character;
}
- ckfree(argv);
+ Tcl_Free((void *)argv);
if (!SetCommState(infoPtr->handle, &dcb)) {
goto setStateFailed;
@@ -1779,7 +1820,8 @@ SerialSetOptionProc(
*/
if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) {
- int i, res = TCL_OK;
+ Tcl_Size i;
+ int res = TCL_OK;
if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {
return TCL_ERROR;
@@ -1789,9 +1831,9 @@ SerialSetOptionProc(
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad value \"%s\" for -ttycontrol: should be "
"a list of signal,value pairs", value));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "TTYCONTROL", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "TTYCONTROL", (char *)NULL);
}
- ckfree(argv);
+ Tcl_Free((void *)argv);
return TCL_ERROR;
}
@@ -1805,9 +1847,9 @@ SerialSetOptionProc(
(DWORD) (flag ? SETDTR : CLRDTR))) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "can't set DTR signal", -1));
+ "can't set DTR signal", TCL_INDEX_NONE));
Tcl_SetErrorCode(interp, "TCL", "OPERATION",
- "FCONFIGURE", "TTY_SIGNAL", NULL);
+ "FCONFIGURE", "TTY_SIGNAL", (char *)NULL);
}
res = TCL_ERROR;
break;
@@ -1817,9 +1859,9 @@ SerialSetOptionProc(
(DWORD) (flag ? SETRTS : CLRRTS))) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "can't set RTS signal", -1));
+ "can't set RTS signal", TCL_INDEX_NONE));
Tcl_SetErrorCode(interp, "TCL", "OPERATION",
- "FCONFIGURE", "TTY_SIGNAL", NULL);
+ "FCONFIGURE", "TTY_SIGNAL", (char *)NULL);
}
res = TCL_ERROR;
break;
@@ -1829,9 +1871,9 @@ SerialSetOptionProc(
(DWORD) (flag ? SETBREAK : CLRBREAK))) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "can't set BREAK signal", -1));
+ "can't set BREAK signal", TCL_INDEX_NONE));
Tcl_SetErrorCode(interp, "TCL", "OPERATION",
- "FCONFIGURE", "TTY_SIGNAL", NULL);
+ "FCONFIGURE", "TTY_SIGNAL", (char *)NULL);
}
res = TCL_ERROR;
break;
@@ -1842,14 +1884,14 @@ SerialSetOptionProc(
"bad signal name \"%s\" for -ttycontrol: must be"
" DTR, RTS or BREAK", argv[i]));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "TTY_SIGNAL",
- NULL);
+ (char *)NULL);
}
res = TCL_ERROR;
break;
}
}
- ckfree(argv);
+ Tcl_Free((void *)argv);
return res;
}
@@ -1863,7 +1905,7 @@ SerialSetOptionProc(
* -sysbuffer 4096 or -sysbuffer {64536 4096}
*/
- size_t inSize = (size_t) -1, outSize = (size_t) -1;
+ int inSize = -1, outSize = -1;
if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {
return TCL_ERROR;
@@ -1875,21 +1917,21 @@ SerialSetOptionProc(
inSize = atoi(argv[0]);
outSize = atoi(argv[1]);
}
- ckfree(argv);
+ Tcl_Free((void *)argv);
if ((argc < 1) || (argc > 2) || (inSize <= 0) || (outSize <= 0)) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad value \"%s\" for -sysbuffer: should be "
"a list of one or two integers > 0", value));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "SYS_BUFFER", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "SYS_BUFFER", (char *)NULL);
}
return TCL_ERROR;
}
if (!SetupComm(infoPtr->handle, inSize, outSize)) {
if (interp != NULL) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't setup comm buffers: %s",
Tcl_PosixError(interp)));
@@ -1940,7 +1982,7 @@ SerialSetOptionProc(
tout.ReadTotalTimeoutConstant = msec;
if (!SetCommTimeouts(infoPtr->handle, &tout)) {
if (interp != NULL) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't set comm timeouts: %s",
Tcl_PosixError(interp)));
@@ -1952,11 +1994,12 @@ SerialSetOptionProc(
}
return Tcl_BadChannelOption(interp, optionName,
- "mode handshake pollinterval sysbuffer timeout ttycontrol xchar");
+ "closemode mode handshake pollinterval sysbuffer timeout "
+ "ttycontrol xchar");
getStateFailed:
if (interp != NULL) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't get comm state: %s", Tcl_PosixError(interp)));
}
@@ -1964,7 +2007,7 @@ SerialSetOptionProc(
setStateFailed:
if (interp != NULL) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't set comm state: %s", Tcl_PosixError(interp)));
}
@@ -1994,18 +2037,16 @@ SerialSetOptionProc(
static int
SerialGetOptionProc(
- ClientData instanceData, /* File state. */
+ void *instanceData, /* Serial 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;
+ SerialInfo *infoPtr = (SerialInfo *) instanceData;
DCB dcb;
size_t len;
int valid = 0; /* Flag if valid option parsed. */
- infoPtr = (SerialInfo *) instanceData;
-
if (optionName == NULL) {
len = 0;
} else {
@@ -2013,6 +2054,27 @@ SerialGetOptionProc(
}
/*
+ * Get option -closemode
+ */
+
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-closemode");
+ }
+ if (len==0 || (len>1 && strncmp(optionName, "-closemode", len)==0)) {
+ switch (infoPtr->flags & SERIAL_CLOSE_MASK) {
+ case SERIAL_CLOSE_DRAIN:
+ Tcl_DStringAppendElement(dsPtr, "drain");
+ break;
+ case SERIAL_CLOSE_DISCARD:
+ Tcl_DStringAppendElement(dsPtr, "discard");
+ break;
+ default:
+ Tcl_DStringAppendElement(dsPtr, "default");
+ break;
+ }
+ }
+
+ /*
* Get option -mode
*/
@@ -2026,7 +2088,7 @@ SerialGetOptionProc(
if (!GetCommState(infoPtr->handle, &dcb)) {
if (interp != NULL) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't get comm state: %s", Tcl_PosixError(interp)));
}
@@ -2096,16 +2158,15 @@ SerialGetOptionProc(
if (!GetCommState(infoPtr->handle, &dcb)) {
if (interp != NULL) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't get comm state: %s", Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
- buf[1] = '\0';
- buf[0] = dcb.XonChar;
+ buf[Tcl_UniCharToUtf(UCHAR(dcb.XonChar), buf)] = '\0';
Tcl_DStringAppendElement(dsPtr, buf);
- buf[0] = dcb.XoffChar;
+ buf[Tcl_UniCharToUtf(UCHAR(dcb.XoffChar), buf)] = '\0';
Tcl_DStringAppendElement(dsPtr, buf);
}
if (len == 0) {
@@ -2175,7 +2236,7 @@ SerialGetOptionProc(
if (!GetCommModemStatus(infoPtr->handle, &status)) {
if (interp != NULL) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't get tty status: %s", Tcl_PosixError(interp)));
}
@@ -2189,7 +2250,8 @@ SerialGetOptionProc(
return TCL_OK;
}
return Tcl_BadChannelOption(interp, optionName,
- "mode pollinterval lasterror queue sysbuffer ttystatus xchar");
+ "closemode mode pollinterval lasterror queue sysbuffer ttystatus "
+ "xchar");
}
/*
@@ -2210,7 +2272,7 @@ SerialGetOptionProc(
static void
SerialThreadActionProc(
- ClientData instanceData,
+ void *instanceData,
int action)
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index e077186..2784962 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -3,7 +3,7 @@
*
* This file contains Windows-specific socket related code.
*
- * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright © 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.
@@ -55,22 +55,6 @@
#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.
- */
-
-#undef getservbyname
-#undef getsockopt
-#undef setsockopt
-
-/*
* Helper macros to make parts of this file clearer. The macros do exactly
* what they say on the tin. :-) They also only ever refer to their arguments
* once, and so can be used without regard to side effects.
@@ -78,11 +62,10 @@
#define SET_BITS(var, bits) ((var) |= (bits))
#define CLEAR_BITS(var, bits) ((var) &= ~(bits))
-#define GOT_BITS(var, bits) (((var) & (bits)) != 0)
+#define GOT_BITS(var, bits) (((var) & (bits)) != 0)
/* "sock" + a pointer in hex + \0 */
-#define SOCK_CHAN_LENGTH (16 + TCL_INTEGER_SPACE)
-#define SOCK_TEMPLATE "sock%p"
+#define SOCK_CHAN_LENGTH (16 + TCL_INTEGER_SPACE)
/*
* The following variable is used to tell whether this module has been
@@ -97,12 +80,19 @@ TCL_DECLARE_MUTEX(socketMutex)
/*
* The following defines declare the messages used on socket windows.
*/
+enum TclSocketMessages {
+ SOCKET_MESSAGE = WM_USER+1, /* Sent by OS: something happened. */
+ SOCKET_SELECT = WM_USER+2, /* Adjust select mask. */
+ SOCKET_TERMINATE = WM_USER+3/* Stop worker thread. */
+};
-#define SOCKET_MESSAGE WM_USER+1
-#define SOCKET_SELECT WM_USER+2
-#define SOCKET_TERMINATE WM_USER+3
-#define SELECT TRUE
-#define UNSELECT FALSE
+/*
+ * Operations used with a SOCKET_SELECT message.
+ */
+enum SocketSelectOperations {
+ SELECT = TRUE, /* Add socket to select. */
+ UNSELECT = FALSE /* Remove socket from select. */
+};
/*
* This is needed to comply with the strict aliasing rules of GCC, but it also
@@ -134,9 +124,9 @@ typedef struct TcpFdList {
struct TcpState {
Tcl_Channel channel; /* Channel associated with this socket. */
- struct TcpFdList *sockets; /* Windows SOCKET handle. */
int flags; /* Bit field comprised of the flags described
* below. */
+ struct TcpFdList *sockets; /* Windows SOCKET handle. */
int watchEvents; /* OR'ed combination of FD_READ, FD_WRITE,
* FD_CLOSE, FD_ACCEPT and FD_CONNECT that
* indicate which events are interesting. */
@@ -167,7 +157,7 @@ struct TcpState {
struct addrinfo *myaddrlist;/* Local address. */
struct addrinfo *myaddr; /* Iterator over myaddrlist. */
int connectError; /* Cache status of async socket. */
- int cachedBlocking; /* Cache blocking mode of async socket. */
+ int cachedBlocking; /* Cache blocking mode of async socket. */
volatile int notifierConnectError;
/* Async connect error set by notifier thread.
* This error is still a windows error code.
@@ -181,17 +171,20 @@ struct TcpState {
* structure.
*/
-#define TCP_NONBLOCKING (1<<0) /* Socket with non-blocking I/O */
-#define TCP_ASYNC_CONNECT (1<<1) /* Async connect in progress. */
-#define SOCKET_EOF (1<<2) /* A zero read happened on the
- * socket. */
-#define SOCKET_PENDING (1<<3) /* A message has been sent for this
- * socket */
-#define TCP_ASYNC_PENDING (1<<4) /* TcpConnect was called to
- * process an async connect. This
- * flag indicates that reentry is
- * still pending */
-#define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */
+enum TcpStateFlags {
+ TCP_NONBLOCKING = 1<<0, /* Socket with non-blocking I/O. */
+ TCP_ASYNC_CONNECT = 1<<1, /* Async connect in progress. */
+ SOCKET_EOF = 1<<2, /* A zero read happened on the socket. */
+ SOCKET_PENDING = 1<<3, /* A message has been sent for this socket */
+ TCP_ASYNC_PENDING = 1<<4, /* TcpConnect was called to process an async
+ * connect. This flag indicates that reentry is
+ * still pending. */
+ TCP_ASYNC_FAILED = 1<<5, /* An async connect finally failed. */
+
+ TCP_ASYNC_TEST_MODE = 1<<8 /* Async testing activated. Do not
+ * automatically continue connection
+ * process */
+};
/*
* The following structure is what is added to the Tcl event queue when a
@@ -214,7 +207,10 @@ typedef struct {
#define TCP_BUFFER_SIZE 4096
-
+/*
+ * Per (main) thread data, holding list of things being waited upon and the
+ * various handles to things doing the waiting/notification.
+ */
typedef struct {
HWND hwnd; /* Handle to window for socket messages. */
HANDLE socketThread; /* Thread handling the window */
@@ -224,8 +220,7 @@ typedef struct {
* socketThread has been initialized and has
* started. */
HANDLE socketListLock; /* Win32 Event to lock the socketList */
- TcpState *pendingTcpState;
- /* This socket is opened but not jet in the
+ TcpState *pendingTcpState; /* This socket is opened but not jet in the
* list. This value is also checked by
* the event structure. */
TcpState *socketList; /* Every open socket in this thread has an
@@ -241,27 +236,26 @@ static WNDCLASSW windowClass;
static int TcpConnect(Tcl_Interp *interp,
TcpState *state);
-static void InitSockets(void);
+static void InitSocketWindowClass(void);
static TcpState * NewSocketInfo(SOCKET socket);
static void SocketExitHandler(void *clientData);
static LRESULT CALLBACK SocketProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam);
-static int SocketsEnabled(void);
static void TcpAccept(TcpFdList *fds, SOCKET newSocket, address addr);
static int WaitForConnect(TcpState *statePtr, int *errorCodePtr);
static int WaitForSocketEvent(TcpState *statePtr, int events,
int *errorCodePtr);
-static void AddSocketInfoFd(TcpState *statePtr, SOCKET socket);
+static void AddSocketInfoFd(TcpState *statePtr, SOCKET socket);
static int FindFDInList(TcpState *statePtr, SOCKET socket);
static DWORD WINAPI SocketThread(LPVOID arg);
static void TcpThreadActionProc(void *instanceData,
int action);
+static int TcpCloseProc(void *, Tcl_Interp *);
static Tcl_EventCheckProc SocketCheckProc;
static Tcl_EventProc SocketEventProc;
static Tcl_EventSetupProc SocketSetupProc;
static Tcl_DriverBlockModeProc TcpBlockModeProc;
-static Tcl_DriverCloseProc TcpCloseProc;
static Tcl_DriverClose2Proc TcpClose2Proc;
static Tcl_DriverSetOptionProc TcpSetOptionProc;
static Tcl_DriverGetOptionProc TcpGetOptionProc;
@@ -276,23 +270,23 @@ static Tcl_DriverGetHandleProc TcpGetHandleProc;
*/
static const Tcl_ChannelType tcpChannelType = {
- "tcp", /* Type name. */
- TCL_CHANNEL_VERSION_5, /* v5 channel */
- TcpCloseProc, /* Close proc. */
- TcpInputProc, /* Input proc. */
- TcpOutputProc, /* Output proc. */
+ "tcp",
+ TCL_CHANNEL_VERSION_5,
+ NULL, /* Deprecated. */
+ TcpInputProc,
+ TcpOutputProc,
+ NULL, /* Deprecated. */
+ TcpSetOptionProc,
+ TcpGetOptionProc,
+ TcpWatchProc,
+ TcpGetHandleProc,
+ TcpClose2Proc,
+ TcpBlockModeProc,
+ NULL, /* Flush proc. */
+ NULL, /* Bubbled event handler proc. */
NULL, /* Seek proc. */
- TcpSetOptionProc, /* Set option proc. */
- TcpGetOptionProc, /* Get option proc. */
- TcpWatchProc, /* Initialize notifier. */
- TcpGetHandleProc, /* Get OS handles out of channel. */
- TcpClose2Proc, /* Close2 proc. */
- TcpBlockModeProc, /* Set blocking or non-blocking mode.*/
- NULL, /* flush proc. */
- NULL, /* handler proc. */
- NULL, /* wide seek proc. */
- TcpThreadActionProc, /* thread action proc. */
- NULL /* truncate proc. */
+ TcpThreadActionProc,
+ NULL /* Truncate proc. */
};
/*
@@ -302,21 +296,32 @@ static const Tcl_ChannelType tcpChannelType = {
static TclInitProcessGlobalValueProc InitializeHostName;
static ProcessGlobalValue hostName =
{0, 0, NULL, NULL, InitializeHostName, NULL, NULL};
-
+
/*
- * Simple wrapper round the SendMessage syscall.
+ *----------------------------------------------------------------------
+ *
+ * SendSelectMessage --
+ *
+ * Simple wrapper round the SendMessage syscall with a SOCKET_SELECT
+ * message to add a bit of type safety.
+ *
+ *----------------------------------------------------------------------
*/
-
-#define SendSelectMessage(tsdPtr, message, payload) \
- SendMessageW((tsdPtr)->hwnd, SOCKET_SELECT, \
- (WPARAM) (message), (LPARAM) (payload))
-
+static inline void
+SendSelectMessage(
+ ThreadSpecificData *tsdPtr, /* Reference to this thread's worker. */
+ int operation, /* Whether to add or remove from the mask. */
+ TcpState *payload) /* What socket to add/remove. */
+{
+ SendMessageW(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) operation,
+ (LPARAM) payload);
+}
/*
* Address print debug functions
*/
#if 0
-void
+static inline void
printaddrinfo(
struct addrinfo *ai,
char *prefix)
@@ -325,10 +330,10 @@ printaddrinfo(
getnameinfo(ai->ai_addr, ai->ai_addrlen,
host, sizeof(host), port, sizeof(port),
- NI_NUMERICHOST|NI_NUMERICSERV);
+ NI_NUMERICHOST | NI_NUMERICSERV);
}
-void
+static void
printaddrinfolist(
struct addrinfo *addrlist,
char *prefix)
@@ -358,13 +363,14 @@ printaddrinfolist(
void
InitializeHostName(
char **valuePtr,
- int *lengthPtr,
+ size_t *lengthPtr,
Tcl_Encoding *encodingPtr)
{
WCHAR wbuf[256];
- DWORD length = sizeof(wbuf)/sizeof(WCHAR);
+ DWORD length = sizeof(wbuf) / sizeof(WCHAR);
Tcl_DString ds;
+ Tcl_DStringInit(&ds);
if (GetComputerNameExW(ComputerNamePhysicalDnsFullyQualified, wbuf, &length) != 0) {
/*
* Convert string from WCHAR to utf-8, then change to lowercase,
@@ -372,27 +378,27 @@ InitializeHostName(
*/
Tcl_DString inDs;
- Tcl_UtfToLower(Tcl_WinTCharToUtf((TCHAR *)wbuf, -1, &inDs));
- Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&inDs), -1, &ds);
+ Tcl_DStringInit(&inDs);
+ Tcl_UtfToLower(Tcl_WCharToUtfDString(wbuf, TCL_INDEX_NONE, &inDs));
+ Tcl_UtfToExternalDStringEx(NULL, NULL, Tcl_DStringValue(&inDs),
+ TCL_INDEX_NONE, TCL_ENCODING_PROFILE_TCL8, &ds, NULL);
Tcl_DStringFree(&inDs);
} else {
- Tcl_DStringInit(&ds);
- if (TclpHasSockets(NULL) == TCL_OK) {
- /*
- * The buffer size of 256 is recommended by the MSDN page that
- * documents gethostname() as being always adequate.
- */
+ TclInitSockets();
+ /*
+ * The buffer size of 256 is recommended by the MSDN page that
+ * documents gethostname() as being always adequate.
+ */
- Tcl_DStringInit(&ds);
- Tcl_DStringSetLength(&ds, 256);
- gethostname(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
- Tcl_DStringSetLength(&ds, strlen(Tcl_DStringValue(&ds)));
- }
+ Tcl_DStringInit(&ds);
+ Tcl_DStringSetLength(&ds, 256);
+ gethostname(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
+ Tcl_DStringSetLength(&ds, strlen(Tcl_DStringValue(&ds)));
}
*encodingPtr = Tcl_GetEncoding(NULL, NULL);
*lengthPtr = Tcl_DStringLength(&ds);
- *valuePtr = (char *)ckalloc(*lengthPtr + 1);
+ *valuePtr = (char *)Tcl_Alloc(*lengthPtr + 1);
memcpy(*valuePtr, Tcl_DStringValue(&ds), *lengthPtr + 1);
Tcl_DStringFree(&ds);
}
@@ -424,15 +430,13 @@ Tcl_GetHostName(void)
/*
*----------------------------------------------------------------------
*
- * TclpHasSockets --
+ * TclInitSockets --
*
- * 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.
+ * Initialization of sockets for the thread. Also creates message
+ * handling window class for the process if needed.
*
* Results:
- * Returns TCL_OK if the system supports sockets, or TCL_ERROR with an
- * error in interp (if non-NULL).
+ * Nothing. Panics on failure.
*
* Side effects:
* If not already prepared, initializes the TSD structure and socket
@@ -442,24 +446,62 @@ Tcl_GetHostName(void)
*----------------------------------------------------------------------
*/
-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. */
+void
+TclInitSockets(void)
{
- Tcl_MutexLock(&socketMutex);
- InitSockets();
- Tcl_MutexUnlock(&socketMutex);
+ /* Then Per thread initialization. */
+ DWORD id;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ TclThreadDataKeyGet(&dataKey);
- if (SocketsEnabled()) {
- return TCL_OK;
+ if (tsdPtr != NULL) {
+ return;
}
- if (interp != NULL) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "sockets are not available on this system", -1));
+
+ InitSocketWindowClass();
+
+ /*
+ * OK, this thread has never done anything with sockets before. Construct
+ * a worker thread to handle asynchronous events related to sockets
+ * assigned to _this_ thread.
+ */
+
+ tsdPtr = TCL_TSD_INIT(&dataKey);
+ tsdPtr->pendingTcpState = NULL;
+ tsdPtr->socketList = NULL;
+ tsdPtr->hwnd = NULL;
+ tsdPtr->threadId = Tcl_GetCurrentThread();
+ tsdPtr->readyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ if (tsdPtr->readyEvent == NULL) {
+ goto initFailure;
+ }
+ tsdPtr->socketListLock = CreateEventW(NULL, FALSE, TRUE, NULL);
+ if (tsdPtr->socketListLock == NULL) {
+ goto initFailure;
+ }
+ tsdPtr->socketThread = CreateThread(NULL, 256, SocketThread, tsdPtr, 0,
+ &id);
+ if (tsdPtr->socketThread == NULL) {
+ goto initFailure;
+ }
+
+ 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.
+ */
+
+ WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
+
+ if (tsdPtr->hwnd != NULL) {
+ Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);
+ return;
}
- return TCL_ERROR;
+
+ initFailure:
+ Tcl_Panic("InitSockets failed");
+ return;
}
/*
@@ -484,7 +526,8 @@ TclpHasSockets(
void
TclpFinalizeSockets(void)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ TclThreadDataKeyGet(&dataKey);
/*
* Careful! This is a finalizer!
@@ -503,7 +546,7 @@ TclpFinalizeSockets(void)
* completely cleaned up before we leave this function.
*/
- WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
+ WaitForSingleObject(tsdPtr->socketThread, INFINITE);
tsdPtr->hwnd = NULL;
}
CloseHandle(tsdPtr->socketThread);
@@ -539,7 +582,7 @@ TclpFinalizeSockets(void)
static int
TcpBlockModeProc(
- void *instanceData, /* Socket state. */
+ void *instanceData, /* Socket state. */
int mode) /* The mode to set. Can be one of
* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
@@ -575,8 +618,8 @@ TcpBlockModeProc(
* return any error code.
*
* Results:
- * 0 if the connection has completed, -1 if still in progress or there is
- * an error.
+ * 0 if the connection has completed, -1 if still in progress or there is
+ * an error.
*
* Side effects:
* Processes socket events off the system queue. May process
@@ -593,7 +636,6 @@ WaitForConnect(
{
int result;
int oldMode;
- ThreadSpecificData *tsdPtr;
/*
* Check if an async connect failed already and error reporting is
@@ -614,6 +656,21 @@ WaitForConnect(
}
/*
+ * In socket test mode do not continue with the connect
+ * Exceptions are:
+ * - Call by recv/send and blocking socket
+ * (errorCodePtr != NULL && !GOT_BITS(flags, TCP_NONBLOCKING))
+ * - Call by the event queue (errorCodePtr == NULL)
+ */
+
+ if (GOT_BITS(statePtr->flags, TCP_ASYNC_TEST_MODE)
+ && errorCodePtr != NULL
+ && GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) {
+ *errorCodePtr = EWOULDBLOCK;
+ return -1;
+ }
+
+ /*
* Be sure to disable event servicing so we are truly modal.
*/
@@ -628,7 +685,8 @@ WaitForConnect(
* Get the statePtr lock.
*/
- tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ TclThreadDataKeyGet(&dataKey);
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
/*
@@ -701,11 +759,11 @@ WaitForConnect(
return -1;
}
- /*
- * Free list lock.
- */
+ /*
+ * Free list lock.
+ */
- SetEvent(tsdPtr->socketListLock);
+ SetEvent(tsdPtr->socketListLock);
/*
* Background operation returns with no action as there was no connect
@@ -755,7 +813,7 @@ WaitForConnect(
static int
TcpInputProc(
- void *instanceData, /* Socket state. */
+ void *instanceData, /* Socket state. */
char *buf, /* Where to store data read. */
int bufSize, /* How much space is available in the
* buffer? */
@@ -764,22 +822,12 @@ TcpInputProc(
TcpState *statePtr = (TcpState *)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.
- */
-
- if (!SocketsEnabled()) {
- *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.
*/
@@ -857,8 +905,8 @@ TcpInputProc(
*/
if (GOT_BITS(statePtr->flags, TCP_NONBLOCKING)
- || (error != WSAEWOULDBLOCK)) {
- TclWinConvertError(error);
+ || (error != WSAEWOULDBLOCK)) {
+ Tcl_WinConvertError(error);
*errorCodePtr = Tcl_GetErrno();
bytesRead = -1;
break;
@@ -899,7 +947,7 @@ TcpInputProc(
static int
TcpOutputProc(
- void *instanceData, /* Socket state. */
+ void *instanceData, /* Socket state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCodePtr) /* Where to store error code. */
@@ -907,22 +955,12 @@ TcpOutputProc(
TcpState *statePtr = (TcpState *)instanceData;
int written;
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.
- */
-
- if (!SocketsEnabled()) {
- *errorCodePtr = EFAULT;
- return -1;
- }
-
- /*
* Check if there is an async connect running.
* For blocking sockets terminate connect, otherwise do one step.
* For a non blocking socket return EWOULDBLOCK if connect not terminated
@@ -972,7 +1010,7 @@ TcpOutputProc(
break;
}
} else {
- TclWinConvertError(error);
+ Tcl_WinConvertError(error);
*errorCodePtr = Tcl_GetErrno();
written = -1;
break;
@@ -1014,8 +1052,8 @@ TcpOutputProc(
static int
TcpCloseProc(
- void *instanceData, /* The socket to close. */
- Tcl_Interp *interp) /* Unused. */
+ void *instanceData, /* The socket to close. */
+ TCL_UNUSED(Tcl_Interp *))
{
TcpState *statePtr = (TcpState *)instanceData;
/* TIP #218 */
@@ -1023,35 +1061,27 @@ TcpCloseProc(
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.
+ * 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 (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.
- */
-
- while (statePtr->sockets != NULL) {
- TcpFdList *thisfd = statePtr->sockets;
+ while (statePtr->sockets != NULL) {
+ TcpFdList *thisfd = statePtr->sockets;
- statePtr->sockets = thisfd->next;
- if (closesocket(thisfd->fd) == SOCKET_ERROR) {
- TclWinConvertError((DWORD) WSAGetLastError());
- errorCode = Tcl_GetErrno();
- }
- ckfree(thisfd);
+ statePtr->sockets = thisfd->next;
+ if (closesocket(thisfd->fd) == SOCKET_ERROR) {
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
+ errorCode = Tcl_GetErrno();
}
+ Tcl_Free(thisfd);
}
if (statePtr->addrlist != NULL) {
- freeaddrinfo(statePtr->addrlist);
+ freeaddrinfo(statePtr->addrlist);
}
if (statePtr->myaddrlist != NULL) {
- freeaddrinfo(statePtr->myaddrlist);
+ freeaddrinfo(statePtr->myaddrlist);
}
/*
@@ -1085,7 +1115,7 @@ TcpCloseProc(
* fear of damaging the list.
*/
- ckfree(statePtr);
+ Tcl_Free(statePtr);
return errorCode;
}
@@ -1108,7 +1138,7 @@ TcpCloseProc(
static int
TcpClose2Proc(
- void *instanceData, /* The socket to close. */
+ void *instanceData, /* The socket to close. */
Tcl_Interp *interp, /* For error reporting. */
int flags) /* Flags that indicate which side to close. */
{
@@ -1120,7 +1150,7 @@ TcpClose2Proc(
* Shutdown the OS socket handle.
*/
- if ((flags & (TCL_CLOSE_READ|TCL_CLOSE_WRITE)) == 0) {
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) == 0) {
return TcpCloseProc(instanceData, interp);
}
@@ -1129,12 +1159,14 @@ TcpClose2Proc(
* TCL_WRITABLE so this should never be called for a server socket.
*/
- if ((flags & TCL_CLOSE_READ) && (shutdown(statePtr->sockets->fd, SD_RECEIVE) == SOCKET_ERROR)) {
- TclWinConvertError((DWORD) WSAGetLastError());
+ if ((flags & TCL_CLOSE_READ)
+ && (shutdown(statePtr->sockets->fd, SD_RECEIVE) == SOCKET_ERROR)) {
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
readError = Tcl_GetErrno();
}
- if ((flags & TCL_CLOSE_WRITE) && (shutdown(statePtr->sockets->fd, SD_SEND) == SOCKET_ERROR)) {
- TclWinConvertError((DWORD) WSAGetLastError());
+ if ((flags & TCL_CLOSE_WRITE)
+ && (shutdown(statePtr->sockets->fd, SD_SEND) == SOCKET_ERROR)) {
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
writeError = Tcl_GetErrno();
}
return (readError != 0) ? readError : writeError;
@@ -1158,48 +1190,33 @@ TcpClose2Proc(
static int
TcpSetOptionProc(
- void *instanceData, /* Socket state. */
+ void *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. */
{
-#ifdef TCL_FEATURE_KEEPALIVE_NAGLE
- TcpState *statePtr = instanceData;
+ TcpState *statePtr = (TcpState *)instanceData;
SOCKET sock;
-#endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/
-
- /*
- * 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.
- */
+ size_t len = 0;
- if (!SocketsEnabled()) {
- if (interp) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "winsock is not initialized", -1));
- }
- return TCL_ERROR;
+ if (optionName != NULL) {
+ len = strlen(optionName);
}
-#ifdef TCL_FEATURE_KEEPALIVE_NAGLE
-#error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat statePtr->sockets as single fd or list"
sock = statePtr->sockets->fd;
- if (!strcasecmp(optionName, "-keepalive")) {
- BOOL val = FALSE;
- int boolVar, rtn;
+ if ((len > 1) && (optionName[1] == 'k') &&
+ (strncmp(optionName, "-keepalive", len) == 0)) {
+ BOOL boolVar;
+ int rtn;
if (Tcl_GetBoolean(interp, value, &boolVar) != TCL_OK) {
return TCL_ERROR;
}
- if (boolVar) {
- val = TRUE;
- }
rtn = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
- (const char *) &val, sizeof(BOOL));
+ (const char *) &boolVar, sizeof(boolVar));
if (rtn != 0) {
- TclWinConvertError(WSAGetLastError());
+ Tcl_WinConvertError(WSAGetLastError());
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't set socket option: %s",
@@ -1208,20 +1225,19 @@ TcpSetOptionProc(
return TCL_ERROR;
}
return TCL_OK;
- } else if (!strcasecmp(optionName, "-nagle")) {
- BOOL val = FALSE;
- int boolVar, rtn;
+ }
+ if ((len > 1) && (optionName[1] == 'n') &&
+ (strncmp(optionName, "-nodelay", len) == 0)) {
+ BOOL boolVar;
+ int rtn;
if (Tcl_GetBoolean(interp, value, &boolVar) != TCL_OK) {
return TCL_ERROR;
}
- if (!boolVar) {
- val = TRUE;
- }
rtn = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
- (const char *) &val, sizeof(BOOL));
+ (const char *) &boolVar, sizeof(boolVar));
if (rtn != 0) {
- TclWinConvertError(WSAGetLastError());
+ Tcl_WinConvertError(WSAGetLastError());
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't set socket option: %s",
@@ -1231,11 +1247,7 @@ TcpSetOptionProc(
}
return TCL_OK;
}
-
- return Tcl_BadChannelOption(interp, optionName, "keepalive nagle");
-#else
- return Tcl_BadChannelOption(interp, optionName, "");
-#endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/
+ return Tcl_BadChannelOption(interp, optionName, "keepalive nodelay");
}
/*
@@ -1261,7 +1273,7 @@ TcpSetOptionProc(
static int
TcpGetOptionProc(
- void *instanceData, /* Socket state. */
+ void *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
@@ -1275,20 +1287,9 @@ TcpGetOptionProc(
size_t len = 0;
int reverseDNS = 0;
#define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS"
-
- /*
- * 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_SetObjResult(interp, Tcl_NewStringObj(
- "winsock is not initialized", -1));
- }
- return TCL_ERROR;
- }
+#define HAVE_OPTION(option) \
+ ((len > 1) && (optionName[1] == option[1]) && \
+ (strncmp(optionName, option, len) == 0))
/*
* Go one step in async connect
@@ -1296,15 +1297,17 @@ TcpGetOptionProc(
* If any error is thrown save it as background error to report eventually
* below.
*/
- WaitForConnect(statePtr, NULL);
+
+ if (!GOT_BITS(statePtr->flags, TCP_ASYNC_TEST_MODE)) {
+ WaitForConnect(statePtr, NULL);
+ }
sock = statePtr->sockets->fd;
if (optionName != NULL) {
len = strlen(optionName);
}
- if ((len > 1) && (optionName[1] == 'e') &&
- (strncmp(optionName, "-error", len) == 0)) {
+ if (HAVE_OPTION("-error")) {
/*
* Do not return any errors if async connect is running.
*/
@@ -1319,7 +1322,8 @@ TcpGetOptionProc(
if (statePtr->connectError != 0) {
Tcl_DStringAppend(dsPtr,
- Tcl_ErrnoMsg(statePtr->connectError), -1);
+ Tcl_ErrnoMsg(statePtr->connectError),
+ TCL_INDEX_NONE);
statePtr->connectError = 0;
}
} else {
@@ -1353,20 +1357,20 @@ TcpGetOptionProc(
*/
if (err) {
- TclWinConvertError(err);
- Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1);
+ Tcl_WinConvertError(err);
+ Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()),
+ TCL_INDEX_NONE);
}
}
}
return TCL_OK;
}
- if ((len > 1) && (optionName[1] == 'c') &&
- (strncmp(optionName, "-connecting", len) == 0)) {
+ if (HAVE_OPTION("-connecting")) {
Tcl_DStringAppend(dsPtr,
GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)
- ? "1" : "0", -1);
- return TCL_OK;
+ ? "1" : "0", TCL_INDEX_NONE);
+ return TCL_OK;
}
if (interp != NULL
@@ -1374,8 +1378,7 @@ TcpGetOptionProc(
reverseDNS = NI_NUMERICHOST;
}
- if ((len == 0) || ((len > 1) && (optionName[1] == 'p') &&
- (strncmp(optionName, "-peername", len) == 0))) {
+ if ((len == 0) || HAVE_OPTION("-peername")) {
address peername;
socklen_t size = sizeof(peername);
@@ -1422,7 +1425,7 @@ TcpGetOptionProc(
*/
if (len) {
- TclWinConvertError((DWORD) WSAGetLastError());
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't get peername: %s",
@@ -1433,8 +1436,7 @@ TcpGetOptionProc(
}
}
- if ((len == 0) || ((len > 1) && (optionName[1] == 's') &&
- (strncmp(optionName, "-sockname", len) == 0))) {
+ if ((len == 0) || HAVE_OPTION("-sockname")) {
TcpFdList *fds;
address sockname;
socklen_t size;
@@ -1498,7 +1500,7 @@ TcpGetOptionProc(
Tcl_DStringEndSublist(dsPtr);
} else {
if (interp) {
- TclWinConvertError((DWORD) WSAGetLastError());
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't get sockname: %s", Tcl_PosixError(interp)));
}
@@ -1506,54 +1508,41 @@ TcpGetOptionProc(
}
}
-#ifdef TCL_FEATURE_KEEPALIVE_NAGLE
- if (len == 0 || !strncmp(optionName, "-keepalive", len)) {
+ if ((len == 0) || HAVE_OPTION("-keepalive")) {
int optlen;
BOOL opt = FALSE;
if (len == 0) {
+ sock = statePtr->sockets->fd;
Tcl_DStringAppendElement(dsPtr, "-keepalive");
}
optlen = sizeof(BOOL);
getsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt, &optlen);
- if (opt) {
- Tcl_DStringAppendElement(dsPtr, "1");
- } else {
- Tcl_DStringAppendElement(dsPtr, "0");
- }
+ Tcl_DStringAppendElement(dsPtr, opt ? "1" : "0");
if (len > 0) {
return TCL_OK;
}
}
- if (len == 0 || !strncmp(optionName, "-nagle", len)) {
+ if ((len == 0) || HAVE_OPTION("-nodelay")) {
int optlen;
BOOL opt = FALSE;
if (len == 0) {
- Tcl_DStringAppendElement(dsPtr, "-nagle");
+ sock = statePtr->sockets->fd;
+ Tcl_DStringAppendElement(dsPtr, "-nodelay");
}
optlen = sizeof(BOOL);
getsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, &optlen);
- if (opt) {
- Tcl_DStringAppendElement(dsPtr, "0");
- } else {
- Tcl_DStringAppendElement(dsPtr, "1");
- }
+ Tcl_DStringAppendElement(dsPtr, opt ? "1" : "0");
if (len > 0) {
return TCL_OK;
}
}
-#endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/
if (len > 0) {
-#ifdef TCL_FEATURE_KEEPALIVE_NAGLE
return Tcl_BadChannelOption(interp, optionName,
- "connecting peername sockname keepalive nagle");
-#else
- return Tcl_BadChannelOption(interp, optionName,
- "connecting peername sockname");
-#endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/
+ "connecting keepalive nodelay peername sockname");
}
return TCL_OK;
@@ -1579,7 +1568,7 @@ TcpGetOptionProc(
static void
TcpWatchProc(
- void *instanceData, /* The socket state. */
+ void *instanceData, /* The socket state. */
int mask) /* Events of interest; an OR-ed combination of
* TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
@@ -1633,17 +1622,15 @@ TcpWatchProc(
static int
TcpGetHandleProc(
- void *instanceData, /* The socket state. */
- int direction, /* Not used. */
- void **handlePtr) /* Where to store the handle. */
+ void *instanceData, /* The socket state. */
+ TCL_UNUSED(int) /*direction*/,
+ void **handlePtr) /* Where to store the handle. */
{
TcpState *statePtr = (TcpState *)instanceData;
*handlePtr = INT2PTR(statePtr->sockets->fd);
return TCL_OK;
}
-
-
/*
*----------------------------------------------------------------------
@@ -1659,9 +1646,9 @@ TcpGetHandleProc(
* connect synchronously
*
* Results:
- * TCL_OK, if the socket was successfully connected or an asynchronous
- * connection is in progress. If an error occurs, TCL_ERROR is returned
- * and an error message is left in interp.
+ * TCL_OK, if the socket was successfully connected or an asynchronous
+ * connection is in progress. If an error occurs, TCL_ERROR is returned
+ * and an error message is left in interp.
*
* Side effects:
* Opens a socket.
@@ -1688,16 +1675,17 @@ TcpConnect(
{
DWORD error;
int async_connect = GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT);
- /* We are started with async connect and the
- * connect notification was not yet
- * received. */
+ /* We are started with async connect and the
+ * connect notification was not yet
+ * received. */
int async_callback = GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING);
- /* We were called by the event procedure and
- * continue our loop. */
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
+ /* We were called by the event procedure and
+ * continue our loop. */
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ TclThreadDataKeyGet(&dataKey);
if (async_callback) {
- goto reenter;
+ goto reenter;
}
for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL;
@@ -1714,10 +1702,10 @@ TcpConnect(
continue;
}
- /*
- * Close the socket if it is still open from the last unsuccessful
- * iteration.
- */
+ /*
+ * Close the socket if it is still open from the last unsuccessful
+ * iteration.
+ */
if (statePtr->sockets->fd != INVALID_SOCKET) {
closesocket(statePtr->sockets->fd);
@@ -1750,7 +1738,7 @@ TcpConnect(
*/
if (statePtr->sockets->fd == INVALID_SOCKET) {
- TclWinConvertError((DWORD) WSAGetLastError());
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
continue;
}
@@ -1766,7 +1754,7 @@ TcpConnect(
* Set kernel space buffering
*/
- TclSockMinimumBuffers((void *) statePtr->sockets->fd,
+ TclSockMinimumBuffers((void *)statePtr->sockets->fd,
TCP_BUFFER_SIZE);
/*
@@ -1775,7 +1763,7 @@ TcpConnect(
if (bind(statePtr->sockets->fd, statePtr->myaddr->ai_addr,
statePtr->myaddr->ai_addrlen) == SOCKET_ERROR) {
- TclWinConvertError((DWORD) WSAGetLastError());
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
continue;
}
@@ -1846,7 +1834,7 @@ TcpConnect(
statePtr->addr->ai_addrlen);
error = WSAGetLastError();
- TclWinConvertError(error);
+ Tcl_WinConvertError(error);
if (async_connect && error == WSAEWOULDBLOCK) {
/*
@@ -1878,7 +1866,7 @@ TcpConnect(
* Get signaled connect error.
*/
- TclWinConvertError((DWORD) statePtr->notifierConnectError);
+ Tcl_WinConvertError((DWORD) statePtr->notifierConnectError);
/*
* Clear eventual connect flag.
@@ -2023,35 +2011,23 @@ Tcl_OpenTcpClient(
struct addrinfo *addrlist = NULL, *myaddrlist = NULL;
char channelName[SOCK_CHAN_LENGTH];
- if (TclpHasSockets(interp) != TCL_OK) {
- return NULL;
- }
-
- /*
- * 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;
- }
+ TclInitSockets();
/*
* Do the name lookups for the local and remote addresses.
*/
if (!TclCreateSocketAddress(interp, &addrlist, host, port, 0, &errorMsg)
- || !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1,
- &errorMsg)) {
- if (addrlist != NULL) {
- freeaddrinfo(addrlist);
- }
- if (interp != NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "couldn't open socket: %s", errorMsg));
- }
- return NULL;
+ || !TclCreateSocketAddress(interp, &myaddrlist, myaddr, myport, 1,
+ &errorMsg)) {
+ if (addrlist != NULL) {
+ freeaddrinfo(addrlist);
+ }
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't open socket: %s", errorMsg));
+ }
+ return NULL;
}
statePtr = NewSocketInfo(INVALID_SOCKET);
@@ -2069,17 +2045,16 @@ Tcl_OpenTcpClient(
return NULL;
}
- snprintf(channelName, sizeof(channelName), SOCK_TEMPLATE, statePtr);
-
+ TclWinGenerateChannelName(channelName, "sock", statePtr);
statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
statePtr, (TCL_READABLE | TCL_WRITABLE));
if (TCL_ERROR == Tcl_SetChannelOption(NULL, statePtr->channel,
"-translation", "auto crlf")) {
- Tcl_Close(NULL, statePtr->channel);
+ Tcl_CloseEx(NULL, statePtr->channel, 0);
return NULL;
} else if (TCL_ERROR == Tcl_SetChannelOption(NULL, statePtr->channel,
"-eofchar", "")) {
- Tcl_Close(NULL, statePtr->channel);
+ Tcl_CloseEx(NULL, statePtr->channel, 0);
return NULL;
}
return statePtr->channel;
@@ -2103,17 +2078,12 @@ Tcl_OpenTcpClient(
Tcl_Channel
Tcl_MakeTcpClientChannel(
- void *sock) /* The socket to wrap up into a channel. */
+ void *sock) /* The socket to wrap up into a channel. */
{
- TcpState *statePtr;
- char channelName[SOCK_CHAN_LENGTH];
- ThreadSpecificData *tsdPtr;
+ TclInitSockets();
- if (TclpHasSockets(NULL) != TCL_OK) {
- return NULL;
- }
-
- tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ TclThreadDataKeyGet(&dataKey);
/*
* Set kernel space buffering and non-blocking.
@@ -2121,7 +2091,7 @@ Tcl_MakeTcpClientChannel(
TclSockMinimumBuffers(sock, TCP_BUFFER_SIZE);
- statePtr = NewSocketInfo((SOCKET) sock);
+ TcpState *statePtr = NewSocketInfo((SOCKET) sock);
/*
* Start watching for read/write events on the socket.
@@ -2130,7 +2100,8 @@ Tcl_MakeTcpClientChannel(
statePtr->selectEvents = FD_READ | FD_CLOSE | FD_WRITE;
SendSelectMessage(tsdPtr, SELECT, statePtr);
- snprintf(channelName, sizeof(channelName), SOCK_TEMPLATE, statePtr);
+ char channelName[SOCK_CHAN_LENGTH];
+ TclWinGenerateChannelName(channelName, "sock", statePtr);
statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
statePtr, (TCL_READABLE | TCL_WRITABLE));
Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", "auto crlf");
@@ -2140,7 +2111,7 @@ Tcl_MakeTcpClientChannel(
/*
*----------------------------------------------------------------------
*
- * Tcl_OpenTcpServer --
+ * Tcl_OpenTcpServerEx --
*
* Opens a TCP server socket and creates a channel around it.
*
@@ -2155,10 +2126,13 @@ Tcl_MakeTcpClientChannel(
*/
Tcl_Channel
-Tcl_OpenTcpServer(
+Tcl_OpenTcpServerEx(
Tcl_Interp *interp, /* For error reporting - may be NULL. */
- int port, /* Port number to open. */
+ const char *service, /* Port number to open. */
const char *myHost, /* Name of local host. */
+ unsigned int flags, /* Flags. */
+ int backlog, /* Length of OS listen backlog queue, or -1
+ * for default. */
Tcl_TcpAcceptProc *acceptProc,
/* Callback for accepting connections from new
* clients. */
@@ -2172,25 +2146,19 @@ Tcl_OpenTcpServer(
char channelName[SOCK_CHAN_LENGTH];
u_long flag = 1; /* Indicates nonblocking mode. */
const char *errorMsg = NULL;
+ int optvalue, port;
- if (TclpHasSockets(interp) != TCL_OK) {
- return NULL;
- }
+ TclInitSockets();
/*
- * 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.
+ * Construct the addresses for each end of the socket.
*/
- if (!SocketsEnabled()) {
- return NULL;
+ if (TclSockGetPort(interp, service, "tcp", &port) != TCL_OK) {
+ errorMsg = "invalid port number";
+ goto error;
}
- /*
- * Construct the addresses for each end of the socket.
- */
-
if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1,
&errorMsg)) {
goto error;
@@ -2198,9 +2166,9 @@ Tcl_OpenTcpServer(
for (addrPtr = addrlist; addrPtr != NULL; addrPtr = addrPtr->ai_next) {
sock = socket(addrPtr->ai_family, addrPtr->ai_socktype,
- addrPtr->ai_protocol);
+ addrPtr->ai_protocol);
if (sock == INVALID_SOCKET) {
- TclWinConvertError((DWORD) WSAGetLastError());
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
continue;
}
@@ -2231,9 +2199,18 @@ Tcl_OpenTcpServer(
}
/*
- * 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.
+ * The SO_REUSEADDR option on Windows behaves like SO_REUSEPORT on
+ * unix systems.
+ */
+
+ if (GOT_BITS(flags, TCL_TCPSERVER_REUSEPORT)) {
+ optvalue = 1;
+ (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &optvalue, sizeof(optvalue));
+ }
+
+ /*
+ * Bind to the specified port.
*
* Bind should not be affected by the socket having already been
* set into nonblocking mode. If there is trouble, this is one
@@ -2242,8 +2219,9 @@ Tcl_OpenTcpServer(
if (bind(sock, addrPtr->ai_addr,
addrPtr->ai_addrlen) == SOCKET_ERROR) {
- TclWinConvertError((DWORD) WSAGetLastError());
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
closesocket(sock);
+ sock = INVALID_SOCKET; /* Bug [40b1814b93] */
continue;
}
if (port == 0 && chosenport == 0) {
@@ -2266,9 +2244,13 @@ Tcl_OpenTcpServer(
* different, and there may be differences between TCP/IP stacks).
*/
- if (listen(sock, SOMAXCONN) == SOCKET_ERROR) {
- TclWinConvertError((DWORD) WSAGetLastError());
+ if (backlog < 0) {
+ backlog = SOMAXCONN;
+ }
+ if (listen(sock, backlog) == SOCKET_ERROR) {
+ Tcl_WinConvertError((DWORD) WSAGetLastError());
closesocket(sock);
+ sock = INVALID_SOCKET; /* Bug [40b1814b93] */
continue;
}
@@ -2289,11 +2271,12 @@ Tcl_OpenTcpServer(
}
if (statePtr != NULL) {
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ TclThreadDataKeyGet(&dataKey);
statePtr->acceptProc = acceptProc;
statePtr->acceptProcData = acceptProcData;
- snprintf(channelName, sizeof(channelName), SOCK_TEMPLATE, statePtr);
+ TclWinGenerateChannelName(channelName, "sock", statePtr);
statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
statePtr, 0);
/*
@@ -2310,15 +2293,15 @@ Tcl_OpenTcpServer(
ioctlsocket(sock, (long) FIONBIO, &flag);
SendSelectMessage(tsdPtr, SELECT, statePtr);
if (Tcl_SetChannelOption(interp, statePtr->channel, "-eofchar", "")
- == TCL_ERROR) {
- Tcl_Close(NULL, statePtr->channel);
+ == TCL_ERROR) {
+ Tcl_CloseEx(NULL, statePtr->channel, 0);
return NULL;
}
return statePtr->channel;
}
if (interp != NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't open socket: %s",
(errorMsg ? errorMsg : Tcl_PosixError(interp))));
}
@@ -2347,16 +2330,17 @@ Tcl_OpenTcpServer(
static void
TcpAccept(
- TcpFdList *fds, /* Server socket that accepted newSocket. */
- SOCKET newSocket, /* Newly accepted socket. */
- address addr) /* Address of new socket. */
+ TcpFdList *fds, /* Server socket that accepted newSocket. */
+ SOCKET newSocket, /* Newly accepted socket. */
+ address addr) /* Address of new socket. */
{
TcpState *newInfoPtr;
TcpState *statePtr = fds->statePtr;
int len = sizeof(addr);
char channelName[SOCK_CHAN_LENGTH];
char host[NI_MAXHOST], port[NI_MAXSERV];
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ TclThreadDataKeyGet(&dataKey);
/*
* Win-NT has a misfeature that sockets are inherited in child processes
@@ -2378,17 +2362,17 @@ TcpAccept(
newInfoPtr->selectEvents = (FD_READ | FD_WRITE | FD_CLOSE);
SendSelectMessage(tsdPtr, SELECT, newInfoPtr);
- snprintf(channelName, sizeof(channelName), SOCK_TEMPLATE, newInfoPtr);
+ TclWinGenerateChannelName(channelName, "sock", newInfoPtr);
newInfoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
newInfoPtr, (TCL_READABLE | TCL_WRITABLE));
if (Tcl_SetChannelOption(NULL, newInfoPtr->channel, "-translation",
"auto crlf") == TCL_ERROR) {
- Tcl_Close(NULL, newInfoPtr->channel);
+ Tcl_CloseEx(NULL, newInfoPtr->channel, 0);
return;
}
if (Tcl_SetChannelOption(NULL, newInfoPtr->channel, "-eofchar", "")
== TCL_ERROR) {
- Tcl_Close(NULL, newInfoPtr->channel);
+ Tcl_CloseEx(NULL, newInfoPtr->channel, 0);
return;
}
@@ -2398,37 +2382,36 @@ TcpAccept(
if (statePtr->acceptProc != NULL) {
getnameinfo(&(addr.sa), len, host, sizeof(host), port, sizeof(port),
- NI_NUMERICHOST|NI_NUMERICSERV);
+ NI_NUMERICHOST|NI_NUMERICSERV);
statePtr->acceptProc(statePtr->acceptProcData, newInfoPtr->channel,
- host, atoi(port));
+ host, atoi(port));
}
}
/*
*----------------------------------------------------------------------
*
- * InitSockets --
- *
- * Registers the event window for the socket notifier code.
+ * InitSocketWindowClass --
*
- * Assumes socketMutex is held.
+ * Registers the event window class for the socket notifier code.
+ * Caller must not hold socket mutex lock.
*
* Results:
* None.
*
* Side effects:
- * Register a new window class and creates a
- * window for use in asynchronous socket notification.
+ * Register a new window class.
*
*----------------------------------------------------------------------
*/
static void
-InitSockets(void)
+InitSocketWindowClass(void)
{
- DWORD id;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
-
+ if (initialized) {
+ return;
+ }
+ Tcl_MutexLock(&socketMutex);
if (!initialized) {
initialized = 1;
TclCreateLateExitHandler(SocketExitHandler, NULL);
@@ -2452,102 +2435,21 @@ InitSockets(void)
windowClass.hCursor = NULL;
if (!RegisterClassW(&windowClass)) {
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
goto initFailure;
}
}
-
- /*
- * Check for per-thread initialization.
- */
-
- if (tsdPtr != NULL) {
- return;
- }
-
- /*
- * OK, this thread has never done anything with sockets before. Construct
- * a worker thread to handle asynchronous events related to sockets
- * assigned to _this_ thread.
- */
-
- tsdPtr = TCL_TSD_INIT(&dataKey);
- tsdPtr->pendingTcpState = NULL;
- tsdPtr->socketList = NULL;
- tsdPtr->hwnd = NULL;
- tsdPtr->threadId = Tcl_GetCurrentThread();
- tsdPtr->readyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
- if (tsdPtr->readyEvent == NULL) {
- goto initFailure;
- }
- tsdPtr->socketListLock = CreateEventW(NULL, FALSE, TRUE, NULL);
- if (tsdPtr->socketListLock == NULL) {
- goto initFailure;
- }
- tsdPtr->socketThread = CreateThread(NULL, 256, SocketThread, tsdPtr, 0,
- &id);
- if (tsdPtr->socketThread == NULL) {
- goto initFailure;
- }
-
- 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.
- */
-
- WaitForSingleObject(tsdPtr->readyEvent, INFINITE);
-
- if (tsdPtr->hwnd == NULL) {
- goto initFailure; /* Trouble creating the window. */
- }
-
- Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);
+ Tcl_MutexUnlock(&socketMutex);
return;
initFailure:
- TclpFinalizeSockets();
- initialized = -1;
- return;
+ Tcl_MutexUnlock(&socketMutex); /* Probably pointless before panicing */
+ Tcl_Panic("InitSockets failed");
}
/*
*----------------------------------------------------------------------
*
- * SocketsEnabled --
- *
- * Check that the WinSock was successfully initialized.
- *
- * Warning:
- * This check was useful in times of Windows98 where WinSock may
- * not be available. This is not the case any more.
- * This function may be removed with TCL 9.0
- *
- * Results:
- * 1 if it is.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-SocketsEnabled(void)
-{
- int enabled;
-
- Tcl_MutexLock(&socketMutex);
- enabled = (initialized == 1);
- Tcl_MutexUnlock(&socketMutex);
- return enabled;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
* SocketExitHandler --
*
* Callback invoked during exit clean up to delete the socket
@@ -2564,7 +2466,7 @@ SocketsEnabled(void)
static void
SocketExitHandler(
- void *clientData) /* Not used. */
+ TCL_UNUSED(void *))
{
Tcl_MutexLock(&socketMutex);
@@ -2598,7 +2500,7 @@ SocketExitHandler(
void
SocketSetupProc(
- void *data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
TcpState *statePtr;
@@ -2643,7 +2545,7 @@ SocketSetupProc(
static void
SocketCheckProc(
- void *data, /* Not used. */
+ TCL_UNUSED(void *),
int flags) /* Event flags as passed to Tcl_DoOneEvent. */
{
TcpState *statePtr;
@@ -2665,9 +2567,9 @@ SocketCheckProc(
statePtr = statePtr->nextPtr) {
if (GOT_BITS(statePtr->readyEvents,
statePtr->watchEvents | FD_CONNECT | FD_ACCEPT)
- && !GOT_BITS(statePtr->flags, SOCKET_PENDING)) {
+ && !GOT_BITS(statePtr->flags, SOCKET_PENDING)) {
SET_BITS(statePtr->flags, SOCKET_PENDING);
- evPtr = (SocketEvent *)ckalloc(sizeof(SocketEvent));
+ evPtr = (SocketEvent *)Tcl_Alloc(sizeof(SocketEvent));
evPtr->header.proc = SocketEventProc;
evPtr->socket = statePtr->sockets->fd;
Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
@@ -2733,7 +2635,7 @@ SocketEventProc(
*/
if (!statePtr) {
- SetEvent(tsdPtr->socketListLock);
+ SetEvent(tsdPtr->socketListLock);
return 1;
}
@@ -2942,7 +2844,7 @@ AddSocketInfoFd(
* Add the first FD.
*/
- statePtr->sockets = (TcpFdList *)ckalloc(sizeof(TcpFdList));
+ statePtr->sockets = (TcpFdList *)Tcl_Alloc(sizeof(TcpFdList));
fds = statePtr->sockets;
} else {
/*
@@ -2953,7 +2855,7 @@ AddSocketInfoFd(
fds = fds->next;
}
- fds->next = (TcpFdList *)ckalloc(sizeof(TcpFdList));
+ fds->next = (TcpFdList *)Tcl_Alloc(sizeof(TcpFdList));
fds = fds->next;
}
@@ -2965,8 +2867,7 @@ AddSocketInfoFd(
fds->statePtr = statePtr;
fds->next = NULL;
}
-
-
+
/*
*----------------------------------------------------------------------
*
@@ -2984,9 +2885,10 @@ AddSocketInfoFd(
*/
static TcpState *
-NewSocketInfo(SOCKET socket)
+NewSocketInfo(
+ SOCKET socket)
{
- TcpState *statePtr = (TcpState *)ckalloc(sizeof(TcpState));
+ TcpState *statePtr = (TcpState *)Tcl_Alloc(sizeof(TcpState));
memset(statePtr, 0, sizeof(TcpState));
@@ -3021,15 +2923,15 @@ NewSocketInfo(SOCKET socket)
static int
WaitForSocketEvent(
- TcpState *statePtr, /* Information about this socket. */
+ TcpState *statePtr, /* Information about this socket. */
int events, /* Events to look for. May be one of
- * FD_READ or FD_WRITE.
- */
+ * FD_READ or FD_WRITE. */
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.
@@ -3156,7 +3058,6 @@ SocketThread(
return msg.wParam;
}
-
/*
*----------------------------------------------------------------------
@@ -3349,66 +3250,6 @@ FindFDInList(
/*
*----------------------------------------------------------------------
*
- * TclWinGetSockOpt, et al. --
- *
- * Those functions are historically exported by the stubs table and
- * just use the original system calls now.
- *
- * Warning:
- * Those functions are depreciated and will be removed with TCL 9.0.
- *
- * Results:
- * As defined for each function.
- *
- * Side effects:
- * As defined for each function.
- *
- *----------------------------------------------------------------------
- */
-
-#undef TclWinGetSockOpt
-int
-TclWinGetSockOpt(
- SOCKET s,
- int level,
- int optname,
- char *optval,
- int *optlen)
-{
-
- return getsockopt(s, level, optname, optval, optlen);
-}
-#undef TclWinSetSockOpt
-int
-TclWinSetSockOpt(
- SOCKET s,
- int level,
- int optname,
- const char *optval,
- int optlen)
-{
- return setsockopt(s, level, optname, optval, optlen);
-}
-
-#undef TclpInetNtoa
-char *
-TclpInetNtoa(
- struct in_addr addr)
-{
- return inet_ntoa(addr);
-}
-#undef TclWinGetServByName
-struct servent *
-TclWinGetServByName(
- const char *name,
- const char *proto)
-{
- return getservbyname(name, proto);
-}
-
-/*
- *----------------------------------------------------------------------
- *
* TcpThreadActionProc --
*
* Insert or remove any thread local refs to this channel.
@@ -3437,9 +3278,7 @@ TcpThreadActionProc(
* sockets will not work.
*/
- Tcl_MutexLock(&socketMutex);
- InitSockets();
- Tcl_MutexUnlock(&socketMutex);
+ TclInitSockets();
tsdPtr = TCL_TSD_INIT(&dataKey);
diff --git a/win/tclWinTest.c b/win/tclWinTest.c
index 4e047f6..005fb37 100644
--- a/win/tclWinTest.c
+++ b/win/tclWinTest.c
@@ -3,16 +3,23 @@
*
* Contains commands for platform specific tests on Windows.
*
- * Copyright (c) 1996 Sun Microsystems, Inc.
+ * Copyright © 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.
*/
+#undef BUILD_tcl
+#undef STATIC_BUILD
#ifndef USE_TCL_STUBS
# define USE_TCL_STUBS
#endif
#include "tclInt.h"
+#ifdef TCL_WITH_EXTERNAL_TOMMATH
+# include "tommath.h"
+#else
+# include "tclTomMath.h"
+#endif
/*
* For TestplatformChmod on Windows
@@ -94,7 +101,7 @@ TclplatformtestInit(
static int
TesteventloopCmd(
- void *clientData, /* Not used. */
+ TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -102,10 +109,9 @@ TesteventloopCmd(
static int *framePtr = NULL;/* Pointer to integer on stack frame of
* innermost invocation of the "wait"
* subcommand. */
- (void)clientData;
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ...");
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "done|wait");
return TCL_ERROR;
}
if (strcmp(Tcl_GetString(objv[1]), "done") == 0) {
@@ -171,7 +177,7 @@ TesteventloopCmd(
static int
TestvolumetypeCmd(
- void *clientData, /* Not used. */
+ TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -180,7 +186,6 @@ TestvolumetypeCmd(
int found;
char volType[VOL_BUF_SIZE];
const char *path;
- (void)clientData;
if (objc > 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?name?");
@@ -202,7 +207,7 @@ TestvolumetypeCmd(
if (found == 0) {
Tcl_AppendResult(interp, "could not get volume type for \"",
(path?path:""), "\"", (char *)NULL);
- TclWinConvertError(GetLastError());
+ Tcl_WinConvertError(GetLastError());
return TCL_ERROR;
}
Tcl_AppendResult(interp, volType, (char *)NULL);
@@ -238,7 +243,7 @@ TestvolumetypeCmd(
static int
TestwinclockCmd(
- void *dummy, /* Unused */
+ TCL_UNUSED(void *),
Tcl_Interp* interp, /* Tcl interpreter */
int objc, /* Argument count */
Tcl_Obj *const objv[]) /* Argument vector */
@@ -251,7 +256,6 @@ TestwinclockCmd(
Tcl_Obj *result; /* Result of the command */
LARGE_INTEGER t1, t2;
LARGE_INTEGER p1, p2;
- (void)dummy;
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "");
@@ -272,11 +276,11 @@ TestwinclockCmd(
result = Tcl_NewObj();
Tcl_ListObjAppendElement(interp, result,
- Tcl_NewIntObj((int) (t2.QuadPart / 10000000)));
+ Tcl_NewWideIntObj(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_NewWideIntObj((t2.QuadPart / 10) % 1000000));
+ Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(tclTime.sec));
+ Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(tclTime.usec));
Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(p1.QuadPart));
Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(p2.QuadPart));
@@ -288,13 +292,12 @@ TestwinclockCmd(
static int
TestwinsleepCmd(
- void *clientData, /* Unused */
+ TCL_UNUSED(void *),
Tcl_Interp* interp, /* Tcl interpreter */
int objc, /* Parameter count */
Tcl_Obj *const * objv) /* Parameter vector */
{
int ms;
- (void)clientData;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "ms");
@@ -332,10 +335,10 @@ TestwinsleepCmd(
static int
TestExceptionCmd(
- void *dummy, /* Unused */
- Tcl_Interp* interp, /* Tcl interpreter */
- int objc, /* Argument count */
- Tcl_Obj *const objv[]) /* Argument vector */
+ TCL_UNUSED(void *),
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Argument count */
+ Tcl_Obj *const objv[]) /* Argument vector */
{
static const char *const cmds[] = {
"access_violation", "datatype_misalignment", "array_bounds",
@@ -359,7 +362,6 @@ TestExceptionCmd(
EXCEPTION_GUARD_PAGE, EXCEPTION_INVALID_HANDLE, CONTROL_C_EXIT
};
int cmd;
- (void)dummy;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 0, objv, "<type-of-exception>");
@@ -442,9 +444,9 @@ TestplatformChmod(
res = -1; /* Assume failure */
Tcl_DStringInit(&ds);
- Tcl_UtfToExternalDString(NULL, nativePath, -1, &ds);
+ Tcl_UtfToChar16DString(nativePath, -1, &ds);
- attr = GetFileAttributesA(Tcl_DStringValue(&ds));
+ attr = GetFileAttributesW((WCHAR *)Tcl_DStringValue(&ds));
if (attr == 0xFFFFFFFF) {
goto done; /* Not found */
}
@@ -460,15 +462,15 @@ TestplatformChmod(
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto done;
}
- pTokenUser = (TOKEN_USER *)ckalloc(dw);
+ pTokenUser = (TOKEN_USER *)Tcl_Alloc(dw);
if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dw, &dw)) {
goto done;
}
aceEntry[nSids].sidLen = GetLengthSid(pTokenUser->User.Sid);
- aceEntry[nSids].pSid = (PSID)ckalloc(aceEntry[nSids].sidLen);
+ aceEntry[nSids].pSid = (PSID)Tcl_Alloc(aceEntry[nSids].sidLen);
if (!CopySid(aceEntry[nSids].sidLen, aceEntry[nSids].pSid,
pTokenUser->User.Sid)) {
- ckfree(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */
+ Tcl_Free(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */
goto done;
}
/*
@@ -501,19 +503,19 @@ TestplatformChmod(
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto done;
}
- pTokenGroup = (TOKEN_PRIMARY_GROUP *)ckalloc(dw);
+ pTokenGroup = (TOKEN_PRIMARY_GROUP *)Tcl_Alloc(dw);
if (!GetTokenInformation(hToken, TokenPrimaryGroup, pTokenGroup, dw, &dw)) {
- ckfree(pTokenGroup);
+ Tcl_Free(pTokenGroup);
goto done;
}
aceEntry[nSids].sidLen = GetLengthSid(pTokenGroup->PrimaryGroup);
- aceEntry[nSids].pSid = (PSID)ckalloc(aceEntry[nSids].sidLen);
+ aceEntry[nSids].pSid = (PSID)Tcl_Alloc(aceEntry[nSids].sidLen);
if (!CopySid(aceEntry[nSids].sidLen, aceEntry[nSids].pSid, pTokenGroup->PrimaryGroup)) {
- ckfree(pTokenGroup);
- ckfree(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */
+ Tcl_Free(pTokenGroup);
+ Tcl_Free(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */
goto done;
}
- ckfree(pTokenGroup);
+ Tcl_Free(pTokenGroup);
/* Generate mask for group ACL */
@@ -537,10 +539,10 @@ TestplatformChmod(
goto done;
}
aceEntry[nSids].sidLen = GetLengthSid(pWorldSid);
- aceEntry[nSids].pSid = (PSID)ckalloc(aceEntry[nSids].sidLen);
+ aceEntry[nSids].pSid = (PSID)Tcl_Alloc(aceEntry[nSids].sidLen);
if (!CopySid(aceEntry[nSids].sidLen, aceEntry[nSids].pSid, pWorldSid)) {
LocalFree(pWorldSid);
- ckfree(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */
+ Tcl_Free(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */
goto done;
}
LocalFree(pWorldSid);
@@ -566,9 +568,9 @@ TestplatformChmod(
/* Add in size required for each ACE entry in the ACL */
for (i = 0; i < nSids; ++i) {
newAclSize +=
- TclOffset(ACCESS_ALLOWED_ACE, SidStart) + aceEntry[i].sidLen;
+ offsetof(ACCESS_ALLOWED_ACE, SidStart) + aceEntry[i].sidLen;
}
- newAcl = (PACL)ckalloc(newAclSize);
+ newAcl = (PACL)Tcl_Alloc(newAclSize);
if (!InitializeAcl(newAcl, newAclSize, ACL_REVISION)) {
goto done;
}
@@ -584,7 +586,7 @@ TestplatformChmod(
* to remove inherited ACL (we need to overwrite the default ACL's in this case)
*/
- if (SetNamedSecurityInfoA((LPSTR)Tcl_DStringValue(&ds), SE_FILE_OBJECT,
+ if (SetNamedSecurityInfoW((LPWSTR)Tcl_DStringValue(&ds), SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
NULL, NULL, newAcl, NULL) == ERROR_SUCCESS) {
res = 0;
@@ -592,21 +594,21 @@ TestplatformChmod(
done:
if (pTokenUser) {
- ckfree(pTokenUser);
+ Tcl_Free(pTokenUser);
}
if (hToken) {
CloseHandle(hToken);
}
if (newAcl) {
- ckfree(newAcl);
+ Tcl_Free(newAcl);
}
for (i = 0; i < nSids; ++i) {
- ckfree(aceEntry[i].pSid);
+ Tcl_Free(aceEntry[i].pSid);
}
if (res == 0) {
/* Run normal chmod command */
- res = _chmod(Tcl_DStringValue(&ds), pmode);
+ res = _wchmod((WCHAR*)Tcl_DStringValue(&ds), pmode);
}
Tcl_DStringFree(&ds);
return res;
@@ -633,13 +635,12 @@ TestplatformChmod(
static int
TestchmodCmd(
- void *dummy, /* Not used. */
+ TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Parameter count */
Tcl_Obj *const * objv) /* Parameter vector */
{
int i, mode;
- (void)dummy;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "mode file ?file ...?");
diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c
index 9c99825..13ec5f4 100644
--- a/win/tclWinThrd.c
+++ b/win/tclWinThrd.c
@@ -3,9 +3,9 @@
*
* This file implements the Windows-specific thread operations.
*
- * Copyright (c) 1998 Sun Microsystems, Inc.
- * Copyright (c) 1999 Scriptics Corporation
- * Copyright (c) 2008 George Peter Staplin
+ * Copyright © 1998 Sun Microsystems, Inc.
+ * Copyright © 1999 Scriptics Corporation
+ * Copyright © 2008 George Peter Staplin
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -13,8 +13,6 @@
#include "tclWinInt.h"
-#include <float.h>
-
/* Workaround for mingw versions which don't provide this in float.h */
#ifndef _MCW_EM
# define _MCW_EM 0x0008001F /* Error masks */
@@ -43,7 +41,7 @@ static CRITICAL_SECTION initLock;
* obvious reasons, cannot use any dynamically allocated storage.
*/
-#ifdef TCL_THREADS
+#if TCL_THREADS
static struct Tcl_Mutex_ {
CRITICAL_SECTION crit;
@@ -78,13 +76,13 @@ static CRITICAL_SECTION joinLock;
* The per-thread event and queue pointers.
*/
-#ifdef TCL_THREADS
+#if TCL_THREADS
typedef struct ThreadSpecificData {
- HANDLE condEvent; /* Per-thread condition event */
+ HANDLE condEvent; /* Per-thread condition event */
struct ThreadSpecificData *nextPtr; /* Queue pointers */
struct ThreadSpecificData *prevPtr;
- int flags; /* See flags below */
+ int flags; /* See ThreadStateFlags below */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -92,26 +90,24 @@ static Tcl_ThreadDataKey dataKey;
/*
* State bits for the thread.
- * 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
+enum ThreadStateFlags {
+ WIN_THREAD_UNINIT = 0x0, /* Uninitialized. Must be zero because of the
+ * way ThreadSpecificData is created. */
+ WIN_THREAD_RUNNING = 0x1, /* Running, not waiting. */
+ WIN_THREAD_BLOCKED = 0x2 /* Waiting, or trying to wait. */
+};
/*
* The per condition queue pointers and the Mutex used to serialize access to
* the queue.
*/
-typedef struct WinCondition {
+typedef struct {
CRITICAL_SECTION condLock; /* Lock to serialize queuing on the
* condition. */
- struct ThreadSpecificData *firstPtr; /* Queue pointers */
- struct ThreadSpecificData *lastPtr;
+ ThreadSpecificData *firstPtr; /* Queue pointers */
+ ThreadSpecificData *lastPtr;
} WinCondition;
/*
@@ -119,11 +115,10 @@ typedef struct WinCondition {
*/
#ifdef USE_THREAD_ALLOC
-static int once;
static DWORD tlsKey;
-typedef struct allocMutex {
- Tcl_Mutex tlock;
+typedef struct {
+ Tcl_Mutex tlock;
CRITICAL_SECTION wlock;
} allocMutex;
#endif /* USE_THREAD_ALLOC */
@@ -133,13 +128,13 @@ typedef struct allocMutex {
* to TclWinThreadStart.
*/
-typedef struct WinThread {
- LPTHREAD_START_ROUTINE lpStartAddress; /* Original startup routine */
- LPVOID lpParameter; /* Original startup data */
- unsigned int fpControl; /* Floating point control word from the
+typedef struct {
+ LPTHREAD_START_ROUTINE lpStartAddress;
+ /* Original startup routine */
+ LPVOID lpParameter; /* Original startup data */
+ unsigned int fpControl; /* Floating point control word from the
* main thread */
} WinThread;
-
/*
*----------------------------------------------------------------------
@@ -181,7 +176,7 @@ TclWinThreadStart(
lpOrigStartAddress = winThreadPtr->lpStartAddress;
lpOrigParameter = winThreadPtr->lpParameter;
- ckfree((char *)winThreadPtr);
+ Tcl_Free(winThreadPtr);
return lpOrigStartAddress(lpOrigParameter);
}
@@ -206,15 +201,15 @@ 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. */
+ void *clientData, /* The one argument to Main(). */
+ size_t stackSize, /* Size of stack for the new thread. */
int flags) /* Flags controlling behaviour of the new
* thread. */
{
WinThread *winThreadPtr; /* Per-thread startup info */
HANDLE tHandle;
- winThreadPtr = (WinThread *)ckalloc(sizeof(WinThread));
+ winThreadPtr = (WinThread *)Tcl_Alloc(sizeof(WinThread));
winThreadPtr->lpStartAddress = (LPTHREAD_START_ROUTINE) proc;
winThreadPtr->lpParameter = clientData;
winThreadPtr->fpControl = _controlfp(0, 0);
@@ -224,8 +219,8 @@ TclpThreadCreate(
*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,
+#if defined(_MSC_VER) || defined(__MSVCRT__)
+ tHandle = (HANDLE) _beginthreadex(NULL, (unsigned)stackSize,
(Tcl_ThreadCreateProc*) TclWinThreadStart, winThreadPtr,
0, (unsigned *)idPtr);
#else
@@ -302,7 +297,7 @@ TclpThreadExit(
TclSignalExitThread(Tcl_GetCurrentThread(), status);
LeaveCriticalSection(&joinLock);
-#if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__)
+#if defined(_MSC_VER) || defined(__MSVCRT__)
_endthreadex((unsigned) status);
#else
ExitThread((DWORD) status);
@@ -476,7 +471,7 @@ TclpGlobalUnlock(void)
Tcl_Mutex *
Tcl_GetAllocMutex(void)
{
-#ifdef TCL_THREADS
+#if TCL_THREADS
if (!allocOnce) {
InitializeCriticalSection(&allocLock.crit);
allocOnce = 1;
@@ -518,7 +513,7 @@ TclFinalizeLock(void)
DeleteCriticalSection(&globalLock);
initialized = 0;
-#ifdef TCL_THREADS
+#if TCL_THREADS
if (allocOnce) {
DeleteCriticalSection(&allocLock.crit);
allocOnce = 0;
@@ -534,10 +529,10 @@ TclFinalizeLock(void)
DeleteCriticalSection(&initLock);
}
-#ifdef TCL_THREADS
+#if TCL_THREADS
/* locally used prototype */
-static void FinalizeConditionEvent(ClientData data);
+static void FinalizeConditionEvent(void *data);
/*
*----------------------------------------------------------------------
@@ -570,9 +565,9 @@ Tcl_MutexLock(
*/
if (*mutexPtr == NULL) {
- csPtr = (CRITICAL_SECTION *)ckalloc(sizeof(CRITICAL_SECTION));
+ csPtr = (CRITICAL_SECTION *) Tcl_Alloc(sizeof(CRITICAL_SECTION));
InitializeCriticalSection(csPtr);
- *mutexPtr = (Tcl_Mutex)csPtr;
+ *mutexPtr = (Tcl_Mutex) csPtr;
TclRememberMutex(mutexPtr);
}
TclpGlobalUnlock();
@@ -631,7 +626,7 @@ TclpFinalizeMutex(
if (csPtr != NULL) {
DeleteCriticalSection(csPtr);
- ckfree(csPtr);
+ Tcl_Free(csPtr);
*mutexPtr = NULL;
}
}
@@ -662,7 +657,7 @@ void
Tcl_ConditionWait(
Tcl_Condition *condPtr, /* Really (WinCondition **) */
Tcl_Mutex *mutexPtr, /* Really (CRITICAL_SECTION **) */
- const Tcl_Time *timePtr) /* Timeout on waiting period */
+ const Tcl_Time *timePtr) /* Timeout on waiting period */
{
WinCondition *winCondPtr; /* Per-condition queue head */
CRITICAL_SECTION *csPtr; /* Caller's Mutex, after casting */
@@ -713,7 +708,7 @@ Tcl_ConditionWait(
*/
if (*condPtr == NULL) {
- winCondPtr = (WinCondition *)ckalloc(sizeof(WinCondition));
+ winCondPtr = (WinCondition *)Tcl_Alloc(sizeof(WinCondition));
InitializeCriticalSection(&winCondPtr->condLock);
winCondPtr->firstPtr = NULL;
winCondPtr->lastPtr = NULL;
@@ -727,7 +722,7 @@ Tcl_ConditionWait(
if (timePtr == NULL) {
wtime = INFINITE;
} else {
- wtime = timePtr->sec * 1000 + timePtr->usec / 1000;
+ wtime = (DWORD)timePtr->sec * 1000 + (DWORD)timePtr->usec / 1000;
}
/*
@@ -882,7 +877,7 @@ Tcl_ConditionNotify(
static void
FinalizeConditionEvent(
- ClientData data)
+ void *data)
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *) data;
@@ -924,14 +919,11 @@ TclpFinalizeCondition(
if (winCondPtr != NULL) {
DeleteCriticalSection(&winCondPtr->condLock);
- ckfree(winCondPtr);
+ Tcl_Free(winCondPtr);
*condPtr = NULL;
}
}
-
-
-
/*
* Additions by AOL for specialized thread memory allocator.
*/
@@ -940,9 +932,9 @@ TclpFinalizeCondition(
Tcl_Mutex *
TclpNewAllocMutex(void)
{
- struct allocMutex *lockPtr;
+ allocMutex *lockPtr;
- lockPtr = (struct allocMutex *)malloc(sizeof(struct allocMutex));
+ lockPtr = (allocMutex *)malloc(sizeof(allocMutex));
if (lockPtr == NULL) {
Tcl_Panic("could not allocate lock");
}
@@ -964,24 +956,24 @@ TclpFreeAllocMutex(
free(lockPtr);
}
-void *
-TclpGetAllocCache(void)
+void
+TclpInitAllocCache(void)
{
- void *result;
-
- 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();
- once = 1;
- if (tlsKey == TLS_OUT_OF_INDEXES) {
- Tcl_Panic("could not allocate thread local storage");
- }
+ tlsKey = TlsAlloc();
+ if (tlsKey == TLS_OUT_OF_INDEXES) {
+ Tcl_Panic("could not allocate thread local storage");
}
+}
+void *
+TclpGetAllocCache(void)
+{
+ void *result;
result = TlsGetValue(tlsKey);
if ((result == NULL) && (GetLastError() != NO_ERROR)) {
Tcl_Panic("TlsGetValue failed from TclpGetAllocCache");
@@ -1019,7 +1011,7 @@ TclpFreeAllocCache(
if (!success) {
Tcl_Panic("TlsSetValue failed from TclpFreeAllocCache");
}
- } else if (once) {
+ } else {
/*
* Called by us in TclFinalizeThreadAlloc() during the library
* finalization initiated from Tcl_Finalize()
@@ -1029,19 +1021,16 @@ TclpFreeAllocCache(
if (!success) {
Tcl_Panic("TlsFree failed from TclpFreeAllocCache");
}
- once = 0; /* reset for next time. */
}
-
}
#endif /* USE_THREAD_ALLOC */
-
void *
TclpThreadCreateKey(void)
{
DWORD *key;
- key = (DWORD *)TclpSysAlloc(sizeof *key, 0);
+ key = (DWORD *)TclpSysAlloc(sizeof *key);
if (key == NULL) {
Tcl_Panic("unable to allocate thread key!");
}
diff --git a/win/tclWinTime.c b/win/tclWinTime.c
index 6d04550..c0d2b2e 100644
--- a/win/tclWinTime.c
+++ b/win/tclWinTime.c
@@ -4,7 +4,7 @@
* Contains Windows specific versions of Tcl functions that obtain time
* values from the operating system.
*
- * Copyright 1995-1998 by Sun Microsystems, Inc.
+ * Copyright © 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.
@@ -12,10 +12,6 @@
#include "tclInt.h"
-#define SECSPERDAY (60L * 60L * 24L)
-#define SECSPERYEAR (SECSPERDAY * 365L)
-#define SECSPER4YEAR (SECSPERYEAR * 4L + SECSPERDAY)
-
/*
* Number of samples over which to estimate the performance counter.
*/
@@ -23,41 +19,23 @@
#define SAMPLES 64
/*
- * The following arrays contain the day of year for the last day of each
- * month, where index 1 is January.
- */
-
-static const int normalDays[] = {
- -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364
-};
-
-static const int leapDays[] = {
- -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
-};
-
-typedef struct ThreadSpecificData {
- char tzName[64]; /* Time zone name */
- struct tm tm; /* time information */
-} ThreadSpecificData;
-static Tcl_ThreadDataKey dataKey;
-
-/*
* Data for managing high-resolution timers.
*/
-typedef struct TimeInfo {
+typedef struct {
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. */
- DWORD calibrationInterv; /* Calibration interval in seconds (start 1 sec) */
+ DWORD calibrationInterv; /* Calibration interval in seconds (start 1
+ * sec) */
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
+ 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
@@ -81,9 +59,9 @@ typedef struct TimeInfo {
* Data used in developing the estimate of performance counter frequency
*/
- Tcl_WideUInt fileTimeSample[SAMPLES];
+ unsigned long long fileTimeSample[SAMPLES];
/* Last 64 samples of system time. */
- Tcl_WideInt perfCounterSample[SAMPLES];
+ long long perfCounterSample[SAMPLES];
/* Last 64 samples of performance counter. */
int sampleNo; /* Current sample number. */
} TimeInfo;
@@ -96,12 +74,12 @@ static TimeInfo timeInfo = {
(HANDLE) NULL,
(HANDLE) NULL,
(HANDLE) NULL,
-#ifdef HAVE_CAST_TO_UNION
- (LARGE_INTEGER) (Tcl_WideInt)0,
- (ULARGE_INTEGER) (DWORDLONG)0,
- (LARGE_INTEGER) (Tcl_WideInt)0,
- (LARGE_INTEGER) (Tcl_WideInt)0,
- (LARGE_INTEGER) (Tcl_WideInt)0,
+#if defined(HAVE_CAST_TO_UNION) && !defined(__cplusplus)
+ (LARGE_INTEGER) (long long) 0,
+ (ULARGE_INTEGER) (DWORDLONG) 0,
+ (LARGE_INTEGER) (long long) 0,
+ (LARGE_INTEGER) (long long) 0,
+ (LARGE_INTEGER) (long long) 0,
#else
{{0, 0}},
{{0, 0}},
@@ -125,24 +103,22 @@ static struct {
double microsecsScale; /* Denominator scale between clock / microsecs */
} wideClick = {0, 0, 0.0};
-
/*
* Declarations for functions defined later in this file.
*/
-static struct tm * ComputeGMT(const time_t *tp);
-static void StopCalibration(ClientData clientData);
+static void StopCalibration(void *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 UpdateTimeEachSecond(void);
+static void ResetCounterSamples(unsigned long long fileTime,
+ long long perfCounter, long long perfFreq);
+static long long AccumulateSample(long long perfCounter,
+ unsigned long long fileTime);
static void NativeScaleTime(Tcl_Time* timebuf,
- ClientData clientData);
-static Tcl_WideInt NativeGetMicroseconds(void);
+ void *clientData);
+static long long NativeGetMicroseconds(void);
static void NativeGetTime(Tcl_Time* timebuf,
- ClientData clientData);
+ void *clientData);
/*
* TIP #233 (Virtualized Time): Data for the time hooks, if any.
@@ -150,7 +126,24 @@ static void NativeGetTime(Tcl_Time* timebuf,
Tcl_GetTimeProc *tclGetTimeProcPtr = NativeGetTime;
Tcl_ScaleTimeProc *tclScaleTimeProcPtr = NativeScaleTime;
-ClientData tclTimeClientData = NULL;
+void *tclTimeClientData = NULL;
+
+/*
+ * Inlined version of Tcl_GetTime.
+ */
+
+static inline void
+GetTime(
+ Tcl_Time *timePtr)
+{
+ tclGetTimeProcPtr(timePtr, tclTimeClientData);
+}
+
+static inline int
+IsTimeNative(void)
+{
+ return tclGetTimeProcPtr == NativeGetTime;
+}
/*
*----------------------------------------------------------------------
@@ -169,21 +162,22 @@ ClientData tclTimeClientData = NULL;
*----------------------------------------------------------------------
*/
-unsigned long
+unsigned long long
TclpGetSeconds(void)
{
- Tcl_WideInt usecSincePosixEpoch;
+ long long usecSincePosixEpoch;
- /* Try to use high resolution timer */
- if ( tclGetTimeProcPtr == NativeGetTime
- && (usecSincePosixEpoch = NativeGetMicroseconds())
- ) {
+ /*
+ * Try to use high resolution timer
+ */
+
+ if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) {
return usecSincePosixEpoch / 1000000;
} else {
Tcl_Time t;
- tclGetTimeProcPtr(&t, tclTimeClientData); /* Tcl_GetTime inlined. */
- return t.sec;
+ GetTime(&t);
+ return (unsigned long long)t.sec;
}
}
@@ -206,16 +200,17 @@ TclpGetSeconds(void)
*----------------------------------------------------------------------
*/
-unsigned long
+unsigned long long
TclpGetClicks(void)
{
- Tcl_WideInt usecSincePosixEpoch;
+ long long usecSincePosixEpoch;
- /* Try to use high resolution timer */
- if ( tclGetTimeProcPtr == NativeGetTime
- && (usecSincePosixEpoch = NativeGetMicroseconds())
- ) {
- return (unsigned long)usecSincePosixEpoch;
+ /*
+ * Try to use high resolution timer.
+ */
+
+ if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) {
+ return (Tcl_WideUInt) usecSincePosixEpoch;
} else {
/*
* Use the Tcl_GetTime abstraction to get the time in microseconds, as
@@ -224,8 +219,9 @@ TclpGetClicks(void)
Tcl_Time now; /* Current Tcl time */
- tclGetTimeProcPtr(&now, tclTimeClientData); /* Tcl_GetTime inlined */
- return ((unsigned long)(now.sec)*1000000UL) + (unsigned long)(now.usec);
+ GetTime(&now);
+ return ((unsigned long long)(now.sec)*1000000ULL) +
+ (unsigned long long)(now.usec);
}
}
@@ -248,7 +244,7 @@ TclpGetClicks(void)
*----------------------------------------------------------------------
*/
-Tcl_WideInt
+long long
TclpGetWideClicks(void)
{
LARGE_INTEGER curCounter;
@@ -261,9 +257,10 @@ TclpGetWideClicks(void)
* is consistent across all processors. Therefore, the frequency need
* only be queried upon application initialization.
*/
+
if (QueryPerformanceFrequency(&perfCounterFreq)) {
wideClick.perfCounter = 1;
- wideClick.microsecsScale = 1000000.0 / perfCounterFreq.QuadPart;
+ wideClick.microsecsScale = 1000000.0 / (double)perfCounterFreq.QuadPart;
} else {
/* fallback using microseconds */
wideClick.perfCounter = 0;
@@ -274,14 +271,14 @@ TclpGetWideClicks(void)
}
if (wideClick.perfCounter) {
if (QueryPerformanceCounter(&curCounter)) {
- return (Tcl_WideInt)curCounter.QuadPart;
+ return (long long)curCounter.QuadPart;
}
/* fallback using microseconds */
wideClick.perfCounter = 0;
wideClick.microsecsScale = 1;
return TclpGetMicroseconds();
} else {
- return TclpGetMicroseconds();
+ return TclpGetMicroseconds();
}
}
@@ -295,7 +292,7 @@ TclpGetWideClicks(void)
* and back.
*
* Results:
- * 1 click in microseconds as double.
+ * 1 click in microseconds as double.
*
* Side effects:
* None.
@@ -307,7 +304,7 @@ double
TclpWideClickInMicrosec(void)
{
if (!wideClick.initialized) {
- (void)TclpGetWideClicks(); /* initialize */
+ (void) TclpGetWideClicks(); /* initialize */
}
return wideClick.microsecsScale;
}
@@ -329,26 +326,27 @@ TclpWideClickInMicrosec(void)
*----------------------------------------------------------------------
*/
-Tcl_WideInt
+long long
TclpGetMicroseconds(void)
{
- Tcl_WideInt usecSincePosixEpoch;
+ long long usecSincePosixEpoch;
- /* Try to use high resolution timer */
- if ( tclGetTimeProcPtr == NativeGetTime
- && (usecSincePosixEpoch = NativeGetMicroseconds())
- ) {
+ /*
+ * Try to use high resolution timer.
+ */
+
+ if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) {
return usecSincePosixEpoch;
} else {
/*
- * 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;
- tclGetTimeProcPtr(&now, tclTimeClientData); /* Tcl_GetTime inlined */
- return (((Tcl_WideInt)now.sec) * 1000000) + now.usec;
+ GetTime(&now);
+ return now.sec * 1000000 + now.usec;
}
}
@@ -378,16 +376,17 @@ void
Tcl_GetTime(
Tcl_Time *timePtr) /* Location to store time information. */
{
- Tcl_WideInt usecSincePosixEpoch;
-
- /* Try to use high resolution timer */
- if ( tclGetTimeProcPtr == NativeGetTime
- && (usecSincePosixEpoch = NativeGetMicroseconds())
- ) {
- timePtr->sec = (long) (usecSincePosixEpoch / 1000000);
- timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000);
+ long long usecSincePosixEpoch;
+
+ /*
+ * Try to use high resolution timer.
+ */
+
+ if (IsTimeNative() && (usecSincePosixEpoch = NativeGetMicroseconds())) {
+ timePtr->sec = usecSincePosixEpoch / 1000000;
+ timePtr->usec = (long)(usecSincePosixEpoch % 1000000);
} else {
- tclGetTimeProcPtr(timePtr, tclTimeClientData);
+ GetTime(timePtr);
}
}
@@ -410,8 +409,8 @@ Tcl_GetTime(
static void
NativeScaleTime(
- Tcl_Time *timePtr,
- ClientData clientData)
+ TCL_UNUSED(Tcl_Time *),
+ TCL_UNUSED(void *))
{
/*
* Native scale is 1:1. Nothing is done.
@@ -421,6 +420,96 @@ NativeScaleTime(
/*
*----------------------------------------------------------------------
*
+ * IsPerfCounterAvailable --
+ *
+ * Tests whether the performance counter is available, which is a gnarly
+ * problem on 32-bit systems. Also retrieves the nominal frequency of the
+ * performance counter.
+ *
+ * Results:
+ * 1 if the counter is available, 0 if not.
+ *
+ * Side effects:
+ * Updates fields of the timeInfo global. Make sure you hold the lock
+ * before calling this.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+IsPerfCounterAvailable(void)
+{
+ 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:
+ * - inconsistent results among the processors on multi-processor
+ * systems.
+ * - 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.
+ *
+ * We also assume (perhaps questionably) that the vendors have gotten
+ * their act together on Win64, so bypass all this rubbish on that
+ * platform.
+ */
+
+#if !defined(_WIN64)
+ if (timeInfo.perfCounterAvailable &&
+ /*
+ * The following lines would do an exact match on crystal
+ * frequency:
+ *
+ * timeInfo.nominalFreq.QuadPart != (long long) 1193182 &&
+ * timeInfo.nominalFreq.QuadPart != (long long) 3579545 &&
+ */
+ timeInfo.nominalFreq.QuadPart > (long long) 15000000) {
+ /*
+ * As an exception, if every logical processor on the system is on the
+ * same chip, we use the performance counter anyway, presuming that
+ * everyone's TSC is locked to the same oscillator.
+ */
+
+ SYSTEM_INFO systemInfo;
+ 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 */
+ == (int)systemInfo.dwNumberOfProcessors)) {
+ timeInfo.perfCounterAvailable = TRUE;
+ } else {
+ timeInfo.perfCounterAvailable = FALSE;
+ }
+ }
+#endif /* above code is Win32 only */
+
+ return timeInfo.perfCounterAvailable;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* NativeGetMicroseconds --
*
* Gets the current system time in microseconds since the beginning
@@ -441,18 +530,18 @@ NativeScaleTime(
*----------------------------------------------------------------------
*/
-static inline Tcl_WideInt
+static inline long long
NativeCalc100NsTicks(
ULONGLONG fileTimeLastCall,
LONGLONG perfCounterLastCall,
LONGLONG curCounterFreq,
- LONGLONG curCounter
-) {
+ LONGLONG curCounter)
+{
return fileTimeLastCall +
- ((curCounter - perfCounterLastCall) * 10000000 / curCounterFreq);
+ ((curCounter - perfCounterLastCall) * 10000000 / curCounterFreq);
}
-static Tcl_WideInt
+static long long
NativeGetMicroseconds(void)
{
/*
@@ -468,79 +557,12 @@ NativeGetMicroseconds(void)
timeInfo.posixEpoch.LowPart = 0xD53E8000;
timeInfo.posixEpoch.HighPart = 0x019DB1DE;
- 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:
- * - inconsistent results among the processors on
- * multi-processor systems.
- * - 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.
- *
- * We also assume (perhaps questionably) that the vendors have
- * gotten their act together on Win64, so bypass all this rubbish
- * on that platform.
- */
-
-#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 > 15000000){
- /*
- * As an exception, if every logical processor on the system
- * is on the same chip, we use the performance counter anyway,
- * presuming that everyone's TSC is locked to the same
- * oscillator.
- */
-
- 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)) {
- timeInfo.perfCounterAvailable = TRUE;
- } else {
- 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 (IsPerfCounterAvailable()) {
DWORD id;
InitializeCriticalSection(&timeInfo.cs);
@@ -574,8 +596,8 @@ NativeGetMicroseconds(void)
ULONGLONG fileTimeLastCall;
LONGLONG perfCounterLastCall, curCounterFreq;
- /* Copy with current data of calibration cycle */
-
+ /* Copy with current data of calibration
+ * cycle. */
LARGE_INTEGER curCounter;
/* Current performance counter. */
@@ -584,6 +606,7 @@ NativeGetMicroseconds(void)
/*
* Hold time section locked as short as possible
*/
+
EnterCriticalSection(&timeInfo.cs);
fileTimeLastCall = timeInfo.fileTimeLastCall.QuadPart;
@@ -615,17 +638,21 @@ NativeGetMicroseconds(void)
*/
if (curCounter.QuadPart - perfCounterLastCall <
- 11 * curCounterFreq * timeInfo.calibrationInterv / 10
- ) {
- /* Calibrated file-time is saved from Posix in 100-ns ticks */
+ 11 * curCounterFreq * timeInfo.calibrationInterv / 10) {
+ /*
+ * Calibrated file-time is saved from Posix in 100-ns ticks.
+ */
+
return NativeCalc100NsTicks(fileTimeLastCall,
- perfCounterLastCall, curCounterFreq, curCounter.QuadPart) / 10;
+ perfCounterLastCall, curCounterFreq,
+ curCounter.QuadPart) / 10;
}
}
/*
* High resolution timer is not available.
*/
+
return 0;
}
@@ -649,25 +676,27 @@ NativeGetMicroseconds(void)
static void
NativeGetTime(
Tcl_Time *timePtr,
- ClientData clientData)
+ TCL_UNUSED(void *))
{
- Tcl_WideInt usecSincePosixEpoch;
+ long long usecSincePosixEpoch;
/*
* Try to use high resolution timer.
*/
- if ( (usecSincePosixEpoch = NativeGetMicroseconds()) ) {
- timePtr->sec = (long) (usecSincePosixEpoch / 1000000);
- timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000);
+
+ usecSincePosixEpoch = NativeGetMicroseconds();
+ if (usecSincePosixEpoch) {
+ timePtr->sec = usecSincePosixEpoch / 1000000;
+ timePtr->usec = (long)(usecSincePosixEpoch % 1000000);
} else {
/*
- * High resolution timer is not available. Just use ftime.
- */
+ * High resolution timer is not available. Just use ftime.
+ */
struct _timeb t;
_ftime(&t);
- timePtr->sec = (long)t.time;
+ timePtr->sec = t.time;
timePtr->usec = t.millitm * 1000;
}
}
@@ -694,7 +723,7 @@ void TclWinResetTimerResolution(void);
static void
StopCalibration(
- ClientData unused) /* Client data is unused */
+ TCL_UNUSED(void *))
{
SetEvent(timeInfo.exitEvent);
@@ -711,241 +740,6 @@ StopCalibration(
/*
*----------------------------------------------------------------------
*
- * 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.
- *
- * Results:
- * Returns a static tm structure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-struct tm *
-TclpGetDate(
- const time_t *t,
- int useGMT)
-{
- struct tm *tmPtr;
- time_t time;
-#if defined(_WIN64) || (defined(_USE_64BIT_TIME_T) || (defined(_MSC_VER) && _MSC_VER < 1400))
-# define t2 *t /* no need to cripple time to 32-bit */
-#else
- time_t t2 = *(__time32_t *)t;
-#endif
-
- if (!useGMT) {
-#if defined(_MSC_VER) && (_MSC_VER >= 1900)
-# undef timezone /* prevent conflict with timezone() function */
- long timezone = 0;
-#endif
-
- 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.
- */
-
- /*
- * Hmm, 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 (t2 >= LOCALTIME_VALIDITY_BOUNDARY) {
- return TclpLocaltime(&t2);
- }
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1900)
- _get_timezone(&timezone);
-#endif
-
- time = t2 - 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.
- */
-
- if (t2 < (LONG_MAX - 2*SECSPERDAY) && t2 > (LONG_MIN + 2*SECSPERDAY)) {
- tmPtr = ComputeGMT(&time);
- } else {
- tmPtr = ComputeGMT(&t2);
-
- tzset();
-
- /*
- * Add the bias directly to the tm structure to avoid overflow.
- * Propagate seconds overflow into minutes, hours and days.
- */
-
- time = tmPtr->tm_sec - timezone;
- tmPtr->tm_sec = (int)(time % 60);
- if (tmPtr->tm_sec < 0) {
- tmPtr->tm_sec += 60;
- time -= 60;
- }
-
- time = tmPtr->tm_min + time/60;
- tmPtr->tm_min = (int)(time % 60);
- if (tmPtr->tm_min < 0) {
- tmPtr->tm_min += 60;
- time -= 60;
- }
-
- time = tmPtr->tm_hour + time/60;
- tmPtr->tm_hour = (int)(time % 24);
- if (tmPtr->tm_hour < 0) {
- tmPtr->tm_hour += 24;
- time -= 24;
- }
-
- time /= 24;
- tmPtr->tm_mday += (int)time;
- tmPtr->tm_yday += (int)time;
- tmPtr->tm_wday = (tmPtr->tm_wday + (int)time) % 7;
- }
- } else {
- tmPtr = ComputeGMT(&t2);
- }
- return tmPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * ComputeGMT --
- *
- * 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.
- *
- * Side effects:
- * Updates the values of the static struct tm.
- *
- *----------------------------------------------------------------------
- */
-
-static struct tm *
-ComputeGMT(
- const time_t *tp)
-{
- struct tm *tmPtr;
- long tmp, rem;
- int isLeap;
- const int *days;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
-
- tmPtr = &tsdPtr->tm;
-
- /*
- * Compute the 4 year span containing the specified time.
- */
-
- tmp = (long)(*tp / SECSPER4YEAR);
- rem = (long)(*tp % SECSPER4YEAR);
-
- /*
- * Correct for weird mod semantics so the remainder is always positive.
- */
-
- if (rem < 0) {
- tmp--;
- rem += SECSPER4YEAR;
- }
-
- /*
- * 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;
- isLeap = 0;
- if (rem >= SECSPERYEAR) { /* 1971, etc. */
- tmp++;
- rem -= SECSPERYEAR;
- if (rem >= SECSPERYEAR) { /* 1972, etc. */
- tmp++;
- rem -= SECSPERYEAR;
- if (rem >= SECSPERYEAR + SECSPERDAY) { /* 1973, etc. */
- tmp++;
- rem -= SECSPERYEAR + SECSPERDAY;
- } else {
- isLeap = 1;
- }
- }
- }
- tmPtr->tm_year = tmp;
-
- /*
- * 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.
- */
-
- tmPtr->tm_hour = rem / 3600;
- rem %= 3600;
- tmPtr->tm_min = rem / 60;
- tmPtr->tm_sec = rem % 60;
-
- /*
- * Compute the month and day of month.
- */
-
- 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];
-
- /*
- * Compute day of week. Epoch started on a Thursday.
- */
-
- tmPtr->tm_wday = (long)(*tp / SECSPERDAY) + 4;
- if ((*tp % SECSPERDAY) < 0) {
- tmPtr->tm_wday--;
- }
- tmPtr->tm_wday %= 7;
- if (tmPtr->tm_wday < 0) {
- tmPtr->tm_wday += 7;
- }
-
- return tmPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* CalibrationThread --
*
* Thread that manages calibration of the hi-resolution time derived from
@@ -971,7 +765,7 @@ ComputeGMT(
static DWORD WINAPI
CalibrationThread(
- LPVOID arg)
+ TCL_UNUSED(LPVOID))
{
FILETIME curFileTime;
DWORD waitResult;
@@ -985,7 +779,11 @@ CalibrationThread(
QueryPerformanceFrequency(&timeInfo.curCounterFreq);
timeInfo.fileTimeLastCall.LowPart = curFileTime.dwLowDateTime;
timeInfo.fileTimeLastCall.HighPart = curFileTime.dwHighDateTime;
- /* Calibrated file-time will be saved from Posix in 100-ns ticks */
+
+ /*
+ * Calibrated file-time will be saved from Posix in 100-ns ticks.
+ */
+
timeInfo.fileTimeLastCall.QuadPart -= timeInfo.posixEpoch.QuadPart;
ResetCounterSamples(timeInfo.fileTimeLastCall.QuadPart,
@@ -1049,12 +847,12 @@ UpdateTimeEachSecond(void)
/* File time of the previous calibration */
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
+ long long estFreq; /* Estimated perf counter frequency. */
+ long long vt0; /* Tcl time right now. */
+ long long vt1; /* Tcl time one second from now. */
+ long long tdiff; /* Difference between system clock and Tcl
* time. */
- Tcl_WideInt driftFreq; /* Frequency needed to drift virtual time into
+ long long driftFreq; /* Frequency needed to drift virtual time into
* step over 1 second. */
/*
@@ -1065,12 +863,17 @@ UpdateTimeEachSecond(void)
curFileTime.LowPart = curSysTime.dwLowDateTime;
curFileTime.HighPart = curSysTime.dwHighDateTime;
curFileTime.QuadPart -= timeInfo.posixEpoch.QuadPart;
- /* If calibration still not needed (check for possible time switch) */
- if ( curFileTime.QuadPart > lastFileTime.QuadPart
- && curFileTime.QuadPart < lastFileTime.QuadPart +
- (timeInfo.calibrationInterv * 10000000)
- ) {
- /* again in next one second */
+
+ /*
+ * If calibration still not needed (check for possible time switch)
+ */
+
+ if (curFileTime.QuadPart > lastFileTime.QuadPart && curFileTime.QuadPart <
+ lastFileTime.QuadPart + (timeInfo.calibrationInterv * 10000000)) {
+ /*
+ * Look again in next one second.
+ */
+
return;
}
QueryPerformanceCounter(&curPerfCounter);
@@ -1106,7 +909,7 @@ UpdateTimeEachSecond(void)
*/
estFreq = AccumulateSample(curPerfCounter.QuadPart,
- (Tcl_WideUInt) curFileTime.QuadPart);
+ (unsigned long long) curFileTime.QuadPart);
/*
* We want to adjust things so that time appears to be continuous.
@@ -1126,8 +929,9 @@ UpdateTimeEachSecond(void)
*/
vt0 = NativeCalc100NsTicks(timeInfo.fileTimeLastCall.QuadPart,
- timeInfo.perfCounterLastCall.QuadPart, timeInfo.curCounterFreq.QuadPart,
- curPerfCounter.QuadPart);
+ timeInfo.perfCounterLastCall.QuadPart,
+ timeInfo.curCounterFreq.QuadPart, curPerfCounter.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,
@@ -1136,17 +940,25 @@ UpdateTimeEachSecond(void)
tdiff = vt0 - curFileTime.QuadPart;
if (tdiff > 10000000 || tdiff < -10000000) {
- /* jump to current system time, use curent estimated frequency */
- vt0 = curFileTime.QuadPart;
+ /*
+ * Jump to current system time, use curent estimated frequency.
+ */
+
+ vt0 = curFileTime.QuadPart;
} else {
- /* calculate new frequency and estimate drift to the next second */
+ /*
+ * Calculate new frequency and estimate drift to the next second.
+ */
+
vt1 = 20000000 + curFileTime.QuadPart;
driftFreq = (estFreq * 20000000 / (vt1 - vt0));
+
/*
- * Avoid too large drifts (only half of the current difference),
- * that allows also be more accurate (aspire to the smallest tdiff),
- * so then we can prolong calibration interval by tdiff < 100000
+ * Avoid too large drifts (only half of the current difference), that
+ * allows also be more accurate (aspire to the smallest tdiff), so
+ * then we can prolong calibration interval by tdiff < 100000
*/
+
driftFreq = timeInfo.curCounterFreq.QuadPart +
(driftFreq - timeInfo.curCounterFreq.QuadPart) / 2;
@@ -1154,50 +966,79 @@ UpdateTimeEachSecond(void)
* Average between estimated, 2 current and 5 drifted frequencies,
* (do the soft drifting as possible)
*/
- estFreq = (estFreq + 2 * timeInfo.curCounterFreq.QuadPart + 5 * driftFreq) / 8;
+
+ estFreq = (estFreq + 2 * timeInfo.curCounterFreq.QuadPart +
+ 5 * driftFreq) / 8;
}
- /* Avoid too large discrepancy from nominal frequency */
- if (estFreq > 1003*timeInfo.nominalFreq.QuadPart/1000) {
- estFreq = 1003*timeInfo.nominalFreq.QuadPart/1000;
+ /*
+ * Avoid too large discrepancy from nominal frequency.
+ */
+
+ if (estFreq > 1003 * timeInfo.nominalFreq.QuadPart / 1000) {
+ estFreq = 1003 * timeInfo.nominalFreq.QuadPart / 1000;
vt0 = curFileTime.QuadPart;
- } else if (estFreq < 997*timeInfo.nominalFreq.QuadPart/1000) {
- estFreq = 997*timeInfo.nominalFreq.QuadPart/1000;
+ } else if (estFreq < 997 * timeInfo.nominalFreq.QuadPart / 1000) {
+ estFreq = 997 * timeInfo.nominalFreq.QuadPart / 1000;
vt0 = curFileTime.QuadPart;
} else if (vt0 != curFileTime.QuadPart) {
/*
- * Be sure the clock ticks never backwards (avoid it by negative drifting)
- * just compare native time (in 100-ns) before and hereafter using
- * new calibrated values) and do a small adjustment (short time freeze)
+ * Be sure the clock ticks never backwards (avoid it by negative
+ * drifting). Just compare native time (in 100-ns) before and
+ * hereafter using new calibrated values) and do a small adjustment
+ * (short time freeze).
*/
+
LARGE_INTEGER newPerfCounter;
- Tcl_WideInt nt0, nt1;
+ long long nt0, nt1;
QueryPerformanceCounter(&newPerfCounter);
nt0 = NativeCalc100NsTicks(timeInfo.fileTimeLastCall.QuadPart,
- timeInfo.perfCounterLastCall.QuadPart, timeInfo.curCounterFreq.QuadPart,
- newPerfCounter.QuadPart);
+ timeInfo.perfCounterLastCall.QuadPart,
+ timeInfo.curCounterFreq.QuadPart, newPerfCounter.QuadPart);
nt1 = NativeCalc100NsTicks(vt0,
- curPerfCounter.QuadPart, estFreq,
- newPerfCounter.QuadPart);
- if (nt0 > nt1) { /* drifted backwards, try to compensate with new base */
- /* first adjust with a micro jump (short frozen time is acceptable) */
+ curPerfCounter.QuadPart, estFreq, newPerfCounter.QuadPart);
+ if (nt0 > nt1) {
+ /*
+ * Drifted backwards, try to compensate with new base.
+ *
+ * First adjust with a micro jump (short frozen time is
+ * acceptable).
+ */
+
vt0 += nt0 - nt1;
- /* if drift unavoidable (e. g. we had a time switch), then reset it */
+
+ /*
+ * If drift unavoidable (e. g. we had a time switch), then reset
+ * it.
+ */
+
vt1 = vt0 - curFileTime.QuadPart;
if (vt1 > 10000000 || vt1 < -10000000) {
- /* larger jump resp. shift relative new file-time */
- vt0 = curFileTime.QuadPart;
+ /*
+ * Larger jump resp. shift relative new file-time.
+ */
+
+ vt0 = curFileTime.QuadPart;
}
}
}
- /* In lock commit new values to timeInfo (hold lock as short as possible) */
+ /*
+ * In lock commit new values to timeInfo (hold lock as short as possible)
+ */
+
EnterCriticalSection(&timeInfo.cs);
- /* grow calibration interval up to 10 seconds (if still precise enough) */
+ /*
+ * Grow calibration interval up to 10 seconds (if still precise enough)
+ */
+
if (tdiff < -100000 || tdiff > 100000) {
- /* too long drift - reset calibration interval to 1000 second */
+ /*
+ * Too long drift. Reset calibration interval to 1000 second.
+ */
+
timeInfo.calibrationInterv = 1;
} else if (timeInfo.calibrationInterv < 10) {
timeInfo.calibrationInterv++;
@@ -1231,12 +1072,13 @@ UpdateTimeEachSecond(void)
static void
ResetCounterSamples(
- Tcl_WideUInt fileTime, /* Current file time */
- Tcl_WideInt perfCounter, /* Current performance counter */
- Tcl_WideInt perfFreq) /* Target performance frequency */
+ unsigned long long fileTime,/* Current file time */
+ long long perfCounter, /* Current performance counter */
+ long long 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;
@@ -1271,20 +1113,22 @@ ResetCounterSamples(
* case).
*/
-static Tcl_WideInt
+static long long
AccumulateSample(
- Tcl_WideInt perfCounter,
- Tcl_WideUInt fileTime)
+ long long perfCounter,
+ unsigned long long fileTime)
{
- Tcl_WideUInt workFTSample; /* File time sample being removed from or
+ unsigned long long workFTSample;
+ /* File time sample being removed from or
* added to the circular buffer. */
- Tcl_WideInt workPCSample; /* Performance counter sample being removed
+ long long 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 */
+ unsigned long long lastFTSample;
+ /* Last file time sample recorded */
+ long long lastPCSample; /* Last performance counter sample recorded */
+ long long FTdiff; /* Difference between last FT and current */
+ long long PCdiff; /* Difference between last PC and current */
+ long long estFreq; /* Estimated performance counter frequency */
/*
* Test for jumps and reset the samples if we have one.
@@ -1318,7 +1162,7 @@ AccumulateSample(
estFreq = 10000000 * (perfCounter - workPCSample)
/ (fileTime - workFTSample);
timeInfo.perfCounterSample[timeInfo.sampleNo] = perfCounter;
- timeInfo.fileTimeSample[timeInfo.sampleNo] = fileTime;
+ timeInfo.fileTimeSample[timeInfo.sampleNo] = (long long) fileTime;
/*
* Advance the sample number.
@@ -1335,75 +1179,6 @@ AccumulateSample(
/*
*----------------------------------------------------------------------
*
- * TclpGmtime --
- *
- * Wrapper around the 'gmtime' library function to make it thread safe.
- *
- * Results:
- * Returns a pointer to a 'struct tm' in thread-specific data.
- *
- * Side effects:
- * Invokes gmtime or gmtime_r as appropriate.
- *
- *----------------------------------------------------------------------
- */
-
-struct tm *
-TclpGmtime(
- const time_t *timePtr) /* 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.
- */
-
-#if defined(_WIN64) || defined(_USE_64BIT_TIME_T) || (defined(_MSC_VER) && _MSC_VER < 1400)
- return gmtime(timePtr);
-#else
- return _gmtime32((const __time32_t *)timePtr);
-#endif
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclpLocaltime --
- *
- * Wrapper around the 'localtime' library function to make it thread
- * safe.
- *
- * Results:
- * Returns a pointer to a 'struct tm' in thread-specific data.
- *
- * Side effects:
- * Invokes localtime or localtime_r as appropriate.
- *
- *----------------------------------------------------------------------
- */
-
-struct tm *
-TclpLocaltime(
- const time_t *timePtr) /* 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.
- */
-
-#if defined(_WIN64) || defined(_USE_64BIT_TIME_T) || (defined(_MSC_VER) && _MSC_VER < 1400)
- return localtime(timePtr);
-#else
- return _localtime32((const __time32_t *)timePtr);
-#endif
-}
-
-/*
- *----------------------------------------------------------------------
- *
* Tcl_SetTimeProc --
*
* TIP #233 (Virtualized Time): Registers two handlers for the
@@ -1422,7 +1197,7 @@ void
Tcl_SetTimeProc(
Tcl_GetTimeProc *getProc,
Tcl_ScaleTimeProc *scaleProc,
- ClientData clientData)
+ void *clientData)
{
tclGetTimeProcPtr = getProc;
tclScaleTimeProcPtr = scaleProc;
@@ -1449,7 +1224,7 @@ void
Tcl_QueryTimeProc(
Tcl_GetTimeProc **getProc,
Tcl_ScaleTimeProc **scaleProc,
- ClientData *clientData)
+ void **clientData)
{
if (getProc) {
*getProc = tclGetTimeProcPtr;
diff --git a/win/tclooConfig.sh b/win/tclooConfig.sh
index 2279542..a400b5b 100644
--- a/win/tclooConfig.sh
+++ b/win/tclooConfig.sh
@@ -16,4 +16,4 @@ TCLOO_STUB_LIB_SPEC=""
TCLOO_INCLUDE_SPEC=""
TCLOO_PRIVATE_INCLUDE_SPEC=""
TCLOO_CFLAGS=""
-TCLOO_VERSION=1.1.0
+TCLOO_VERSION=1.3
diff --git a/win/tclsh.exe.manifest.in b/win/tclsh.exe.manifest.in
index 8b06fce..dd8a7c5 100644
--- a/win/tclsh.exe.manifest.in
+++ b/win/tclsh.exe.manifest.in
@@ -28,8 +28,6 @@
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
- <!-- Windows Vista -->
- <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
<asmv3:application>
diff --git a/win/tclsh.rc b/win/tclsh.rc
index 685bebd1..77d2d73 100644
--- a/win/tclsh.rc
+++ b/win/tclsh.rc
@@ -8,12 +8,6 @@
//
// build-up the name suffix that defines the type of build this is.
//
-#if TCL_THREADS
-#define SUFFIX_THREADS "t"
-#else
-#define SUFFIX_THREADS ""
-#endif
-
#if STATIC_BUILD
#define SUFFIX_STATIC "s"
#else
@@ -26,23 +20,23 @@
#define SUFFIX_DEBUG ""
#endif
-#define SUFFIX SUFFIX_THREADS SUFFIX_STATIC SUFFIX_DEBUG
+#define SUFFIX SUFFIX_STATIC SUFFIX_DEBUG
LANGUAGE 0x9, 0x1 /* LANG_ENGLISH, SUBLANG_DEFAULT */
VS_VERSION_INFO VERSIONINFO
- FILEVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
+ FILEVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
PRODUCTVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
- FILEFLAGSMASK 0x3fL
+ FILEFLAGSMASK 0x3fL
#ifdef DEBUG
- FILEFLAGS VS_FF_DEBUG
+ FILEFLAGS VS_FF_DEBUG
#else
- FILEFLAGS 0x0L
+ FILEFLAGS 0x0L
#endif
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_APP
- FILESUBTYPE 0x0L
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
diff --git a/win/tcltest.exe.manifest.in b/win/tcltest.exe.manifest.in
deleted file mode 100644