summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
Diffstat (limited to 'win')
-rw-r--r--win/Makefile.in46
-rwxr-xr-xwin/buildall.vc.bat41
-rwxr-xr-xwin/configure23
-rw-r--r--win/configure.in12
-rw-r--r--win/makefile.vc4
-rw-r--r--win/nmakehlp.c19
-rw-r--r--win/rules.vc26
-rw-r--r--win/tclAppInit.c30
-rw-r--r--win/tclWinChan.c16
-rw-r--r--win/tclWinDde.c123
-rw-r--r--win/tclWinFCmd.c20
-rw-r--r--win/tclWinFile.c14
-rw-r--r--win/tclWinLoad.c34
-rw-r--r--win/tclWinPipe.c37
-rw-r--r--win/tclWinPort.h5
-rw-r--r--win/tclWinReg.c81
-rw-r--r--win/tclWinSerial.c143
-rw-r--r--win/tclWinSock.c374
-rw-r--r--win/tclooConfig.sh2
19 files changed, 557 insertions, 493 deletions
diff --git a/win/Makefile.in b/win/Makefile.in
index 84dcaf7..fad1f09 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -90,7 +90,7 @@ COMPILE_DEBUG_FLAGS =
SRC_DIR = @srcdir@
ROOT_DIR = @srcdir@/..
-TOP_DIR = $(shell cd @srcdir@/..; pwd)
+TOP_DIR = $(shell cd @srcdir@/..; pwd -P)
GENERIC_DIR = $(TOP_DIR)/generic
TOMMATH_DIR = $(TOP_DIR)/libtommath
WIN_DIR = $(TOP_DIR)/win
@@ -112,7 +112,7 @@ ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)' | sed 's!\\!/!g')
# Fully qualify library path so that `make test`
# does not depend on the current directory.
-LIBRARY_DIR1 = $(shell cd '$(ROOT_DIR_NATIVE)/library' ; pwd)
+LIBRARY_DIR1 = $(shell cd '$(ROOT_DIR_NATIVE)/library' ; pwd -P)
LIBRARY_DIR = $(shell $(CYGPATH) '$(LIBRARY_DIR1)' | sed 's!\\!/!g')
DLLSUFFIX = @DLLSUFFIX@
LIBSUFFIX = @LIBSUFFIX@
@@ -439,12 +439,6 @@ ${TCL_LIB_FILE}: ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS}
@MAKE_LIB@ ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS}
@POST_MAKE_LIB@
-# assume GNU make
-
-# To enable concurrent parallel make of tcl<x>.dll and tcl<x>.lib, the tcl<x>.dll
-# targets have to depend on tcl<x>.lib, this ensures that linking of tcl<x>.dll
-# does not execute concurrently with the renaming and recompiling of tcl<x>.lib
-
${DDE_DLL_FILE}: ${DDE_OBJS} ${TCL_STUB_LIB_FILE}
@MAKE_DLL@ ${DDE_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
@@ -456,8 +450,12 @@ ${TEST_DLL_FILE}: ${TCLTEST_OBJS} ${TCL_STUB_LIB_FILE}
@MAKE_DLL@ ${TCLTEST_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS)
# use pre-built zlib1.dll
-${ZLIB_DLL_FILE}: $(ZLIB_DIR)/win32/${ZLIB_DLL_FILE}
- @$(COPY) $(ZLIB_DIR)/win32/${ZLIB_DLL_FILE} ${ZLIB_DLL_FILE}
+${ZLIB_DLL_FILE}: ${TCL_STUB_LIB_FILE}
+ @if test "@ZLIB_LIBS@set" == "${ZLIB_DIR}/win64/zdll.libset" ; then \
+ $(COPY) $(ZLIB_DIR)/win64/${ZLIB_DLL_FILE} ${ZLIB_DLL_FILE}; \
+ else \
+ $(COPY) $(ZLIB_DIR)/win32/${ZLIB_DLL_FILE} ${ZLIB_DLL_FILE}; \
+ fi;
# Add the object extension to the implicit rules. By default .obj is not
# automatically added.
@@ -540,9 +538,9 @@ gendate:
# run (and the results checked) after updating to a new release of libtommath.
gentommath_h:
- $(TCL_EXE) "$(ROOT_DIR_NATIVE)\tools\fix_tommath_h.tcl" \
- "$(TOMMATH_DIR_NATIVE)\tommath.h" \
- > "$(GENERIC_DIR_NATIVE)\tclTomMath.h"
+ $(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
@@ -643,8 +641,8 @@ install-libraries: libraries install-tzdata install-msgs
do \
$(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \
done;
- @echo "Installing package msgcat 1.4.5 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.4.5.tm;
+ @echo "Installing package msgcat 1.5.0 as a Tcl Module";
+ @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.5.0.tm;
@echo "Installing package tcltest 2.3.4 as a Tcl Module";
@$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.3.4.tm;
@echo "Installing package platform 1.0.10 as a Tcl Module";
@@ -697,14 +695,14 @@ test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE)
TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \
-load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \
- package ifneeded dde 1.4.0b1 [list load [file normalize ${DDE_DLL_FILE}] dde]; \
+ package ifneeded dde 1.4.0b2 [list load [file normalize ${DDE_DLL_FILE}] dde]; \
package ifneeded registry 1.3.0 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32)
# Useful target to launch a built tclsh with the proper path,...
runtest: binaries $(TCLSH) $(TEST_DLL_FILE)
@TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
./$(TCLSH) $(TESTFLAGS) -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \
- package ifneeded dde 1.4.0b1 [list load [file normalize ${DDE_DLL_FILE}] dde]; \
+ package ifneeded dde 1.4.0b2 [list load [file normalize ${DDE_DLL_FILE}] dde]; \
package ifneeded registry 1.3.0 [list load [file normalize ${REG_DLL_FILE}] registry]" $(SCRIPT)
# This target can be used to run tclsh from the build directory via
@@ -744,7 +742,7 @@ PKG_CFG_ARGS = @PKG_CFG_ARGS@
PKG_DIR = ./pkgs
packages:
- @builddir=`pwd`; \
+ @builddir=`pwd -P`; \
for i in $(PKGS_DIR)/*; do \
if [ -d $$i ] ; then \
if [ -x $$i/configure ] ; then \
@@ -752,7 +750,7 @@ packages:
mkdir -p $(PKG_DIR)/$$pkg; \
if [ ! -f $(PKG_DIR)/$$pkg/Makefile ]; then \
( cd $(PKG_DIR)/$$pkg; \
- echo "Configuring package '$$i' wd = `pwd`"; \
+ echo "Configuring package '$$i' wd = `pwd -P`"; \
$$i/configure --with-tcl=$(PWD) --with-tclinclude=$(GENERIC_DIR) $(PKG_CFG_ARGS) --enable-shared --enable-threads; ) \
fi ; \
echo "Building package '$$pkg'"; \
@@ -763,7 +761,7 @@ packages:
cd $$builddir
install-packages: packages
- @builddir=`pwd`; \
+ @builddir=`pwd -P`; \
for i in $(PKGS_DIR)/*; do \
if [ -d $$i ]; then \
pkg=`basename $$i`; \
@@ -776,20 +774,20 @@ install-packages: packages
cd $$builddir
test-packages: tcltest packages
- @builddir=`pwd`; \
+ @builddir=`pwd -P`; \
for i in $(PKGS_DIR)/*; do \
if [ -d $$i ]; then \
pkg=`basename $$i`; \
if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \
echo "Testing package '$$pkg'"; \
- ( cd $(PKG_DIR)/$$pkg; $(MAKE) "LD_LIBRARY_PATH=$$builddir:${LD_LIBRARY_PATH}" "TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" "TCLLIBPATH=$$builddir/pkgs" test "TCLSH_PROG=$$builddir/tcltest"; ) \
+ ( cd $(PKG_DIR)/$$pkg; $(MAKE) "LD_LIBRARY_PATH=$$builddir:${LD_LIBRARY_PATH}" "TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" "TCLLIBPATH=$$builddir/pkgs" test "TCLSH_PROG=$$builddir/${TCLSH}"; ) \
fi; \
fi; \
done; \
cd $$builddir
clean-packages:
- @builddir=`pwd`; \
+ @builddir=`pwd -P`; \
for i in $(PKGS_DIR)/*; do \
if [ -d $$i ]; then \
pkg=`basename $$i`; \
@@ -801,7 +799,7 @@ clean-packages:
cd $$builddir
distclean-packages:
- @builddir=`pwd`; \
+ @builddir=`pwd -P`; \
for i in $(PKGS_DIR)/*; do \
if [ -d $$i ]; then \
pkg=`basename $$i`; \
diff --git a/win/buildall.vc.bat b/win/buildall.vc.bat
index c33aefd..e4f0a30 100755
--- a/win/buildall.vc.bat
+++ b/win/buildall.vc.bat
@@ -1,4 +1,5 @@
@echo off
+
:: This is an example batchfile for building everything. Please
:: edit this (or make your own) for your needs and wants using
:: the instructions for calling makefile.vc found in makefile.vc
@@ -26,10 +27,11 @@ cd > nul
:: path or have already run vcvars32.bat. Testing these envars proves
:: cl.exe and friends are in your path.
::
-if defined VCINSTALLDIR (goto :startBuilding)
-if defined MSDRVDIR (goto :startBuilding)
-if defined MSVCDIR (goto :startBuilding)
-if defined MSSDK (goto :startBuilding)
+if defined VCINSTALLDIR (goto :startBuilding)
+if defined MSDEVDIR (goto :startBuilding)
+if defined MSVCDIR (goto :startBuilding)
+if defined MSSDK (goto :startBuilding)
+if defined WINDOWSSDKDIR (goto :startBuilding)
:: We need to run the development environment batch script that comes
:: with developer studio (v4,5,6,7,etc...) All have it. This path
@@ -62,42 +64,13 @@ if not %SYMBOLS%.==. set OPTS=symbols
nmake -nologo -f makefile.vc release htmlhelp OPTS=%OPTS% %1
if errorlevel 1 goto error
-:: Build the static core, dlls and shell.
-::
-set OPTS=static
-if not %SYMBOLS%.==. set OPTS=symbols,static
-nmake -nologo -f makefile.vc release OPTS=%OPTS% %1
-if errorlevel 1 goto error
-
-:: Build the special static libraries that use the dynamic runtime.
+:: Build the static core and shell.
::
set OPTS=static,msvcrt
if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt
-nmake -nologo -f makefile.vc core dlls OPTS=%OPTS% %1
-if errorlevel 1 goto error
-
-:: Build the core and shell for thread support.
-::
-set OPTS=threads
-if not %SYMBOLS%.==. set OPTS=symbols,threads
nmake -nologo -f makefile.vc shell OPTS=%OPTS% %1
if errorlevel 1 goto error
-:: Build a static, thread support core library with a shell.
-::
-set OPTS=static,threads
-if not %SYMBOLS%.==. set OPTS=symbols,static,threads
-nmake -nologo -f makefile.vc shell OPTS=%OPTS% %1
-if errorlevel 1 goto error
-
-:: Build the special static libraries that use the dynamic runtime,
-:: but now with thread support.
-::
-set OPTS=static,msvcrt,threads
-if not %SYMBOLS%.==. set OPTS=symbols,static,msvcrt,threads
-nmake -nologo -f makefile.vc core dlls OPTS=%OPTS% %1
-if errorlevel 1 goto error
-
set OPTS=
set SYMBOLS=
goto end
diff --git a/win/configure b/win/configure
index f5a23fe..0258898 100755
--- a/win/configure
+++ b/win/configure
@@ -1311,7 +1311,7 @@ SHELL=/bin/sh
TCL_VERSION=8.6
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL="b2"
+TCL_PATCH_LEVEL="b3"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
TCL_DDE_VERSION=1.4
@@ -4344,12 +4344,6 @@ esac
# as we just assume that the platform hasn't got a usable z.lib
#------------------------------------------------------------------------
-if test "$do64bit" = "yes"; then
-
- tcl_ok=no
-
-else
-
if test "${enable_shared+set}" = "set"; then
enableval="$enable_shared"
@@ -4361,14 +4355,21 @@ else
fi
-
-fi
-
if test "$tcl_ok" = "yes"; then
ZLIB_DLL_FILE=\${ZLIB_DLL_FILE}
- ZLIB_LIBS=\${ZLIB_DIR}/win32/zdll.lib
+ if test "$do64bit" = "yes"; then
+
+ ZLIB_LIBS=\${ZLIB_DIR}/win64/zdll.lib
+
+
+else
+
+ ZLIB_LIBS=\${ZLIB_DIR}/win32/zdll.lib
+
+
+fi
else
diff --git a/win/configure.in b/win/configure.in
index d17f815..0426bb1 100644
--- a/win/configure.in
+++ b/win/configure.in
@@ -14,7 +14,7 @@ SHELL=/bin/sh
TCL_VERSION=8.6
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL="b2"
+TCL_PATCH_LEVEL="b3"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
TCL_DDE_VERSION=1.4
@@ -120,19 +120,19 @@ esac
# as we just assume that the platform hasn't got a usable z.lib
#------------------------------------------------------------------------
-AS_IF([test "$do64bit" = "yes"], [
- tcl_ok=no
-], [
AS_IF([test "${enable_shared+set}" = "set"], [
enableval="$enable_shared"
tcl_ok=$enableval
], [
tcl_ok=yes
])
-])
AS_IF([test "$tcl_ok" = "yes"], [
AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}])
- AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win32/zdll.lib])
+ AS_IF([test "$do64bit" = "yes"], [
+ AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win64/zdll.lib])
+ ], [
+ AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win32/zdll.lib])
+ ])
], [
AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])
AC_DEFINE_UNQUOTED(NO_VIZ, 1)
diff --git a/win/makefile.vc b/win/makefile.vc
index ba5b710..d097e26 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -578,13 +578,13 @@ test-core: setup $(TCLTEST) dlls $(CAT32)
set TCL_LIBRARY=$(ROOT:\=/)/library
!if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE"
$(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile <<
- package ifneeded dde 1.4.0b1 [list load "$(TCLDDELIB:\=/)" dde]
+ package ifneeded dde 1.4.0b2 [list load "$(TCLDDELIB:\=/)" dde]
package ifneeded registry 1.3.0 [list load "$(TCLREGLIB:\=/)" registry]
<<
!else
@echo Please wait while the tests are collected...
$(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << > tests.log
- package ifneeded dde 1.4.0b1 "$(TCLDDELIB:\=/)" dde]
+ package ifneeded dde 1.4.0b2 "$(TCLDDELIB:\=/)" dde]
package ifneeded registry 1.3.0 "$(TCLREGLIB:\=/)" registry]
<<
type tests.log | more
diff --git a/win/nmakehlp.c b/win/nmakehlp.c
index 2868857..b1a1517 100644
--- a/win/nmakehlp.c
+++ b/win/nmakehlp.c
@@ -47,7 +47,7 @@ static int CheckForLinkerFeature(const char *option);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
-static const char *GetVersionFromFile(const char *filename, const char *match);
+static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);
/* globals */
@@ -153,7 +153,7 @@ main(
&dwWritten, NULL);
return 0;
}
- printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
+ printf("%s\n", GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0'));
return 0;
case 'Q':
if (argc != 3) {
@@ -479,7 +479,8 @@ IsIn(
static const char *
GetVersionFromFile(
const char *filename,
- const char *match)
+ const char *match,
+ int numdots)
{
size_t cbBuffer = 100;
static char szBuffer[100];
@@ -497,9 +498,10 @@ GetVersionFromFile(
p = strstr(szBuffer, match);
if (p != NULL) {
/*
- * Skip to first digit.
+ * Skip to first digit after the match.
*/
+ p += strlen(match);
while (*p && !isdigit(*p)) {
++p;
}
@@ -509,7 +511,8 @@ GetVersionFromFile(
*/
q = p;
- while (*q && (isalnum(*q) || *q == '.')) {
+ while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q)
+ && (!strchr("ab", q[-1])) || --numdots))) {
++q;
}
@@ -628,11 +631,11 @@ SubstituteFile(
}
}
#endif
-
+
/*
* Run the substitutions over each line of the input
*/
-
+
while (fgets(szBuffer, cbBuffer, fp) != NULL) {
list_item_t *p = NULL;
for (p = substPtr; p != NULL; p = p->nextPtr) {
@@ -652,7 +655,7 @@ SubstituteFile(
}
printf(szBuffer);
}
-
+
list_free(&substPtr);
}
fclose(fp);
diff --git a/win/rules.vc b/win/rules.vc
index f09e2ea..1513198 100644
--- a/win/rules.vc
+++ b/win/rules.vc
@@ -218,7 +218,7 @@ DEBUG = 0
SYMBOLS = 0
PROFILE = 0
PGO = 0
-MSVCRT = 0
+MSVCRT = 1
LOIMPACT = 0
TCL_USE_STATIC_PACKAGES = 0
USE_THREAD_ALLOC = 1
@@ -234,9 +234,13 @@ STATIC_BUILD = 0
!message *** Doing msvcrt
MSVCRT = 1
!else
+!if !$(STATIC_BUILD)
+MSVCRT = 1
+!else
MSVCRT = 0
!endif
-!if [nmakehlp -f $(OPTS) "staticpkg"]
+!endif
+!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
!message *** Doing staticpkg
TCL_USE_STATIC_PACKAGES = 1
!else
@@ -245,6 +249,7 @@ TCL_USE_STATIC_PACKAGES = 0
!if [nmakehlp -f $(OPTS) "nothreads"]
!message *** Compile explicitly for non-threaded tcl
TCL_THREADS = 0
+USE_THREAD_ALLOC= 0
!else
TCL_THREADS = 1
USE_THREAD_ALLOC= 1
@@ -298,15 +303,6 @@ UNCHECKED = 0
!endif
!endif
-
-!if !$(STATIC_BUILD)
-# Make sure we don't build overly fat DLLs.
-MSVCRT = 1
-# We shouldn't statically put the extensions inside the shell when dynamic.
-TCL_USE_STATIC_PACKAGES = 0
-!endif
-
-
#----------------------------------------------------------
# Figure-out how to name our intermediate and output directories.
# We wouldn't want different builds to use the same .obj files
@@ -348,10 +344,8 @@ TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
TMP_DIRFULL = $(TMP_DIRFULL:Static=)
SUFX = $(SUFX:s=)
EXT = dll
-!if $(MSVCRT)
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX = $(SUFX:x=)
-!endif
!else
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
EXT = lib
@@ -583,12 +577,6 @@ Failed to find tcl.h. The TCLDIR macro does not appear correct.
TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
-!if $(TCL_VERSION) < 81
-TCL_DOES_STUBS = 0
-!else
-TCL_DOES_STUBS = 1
-!endif
-
!if $(TCLINSTALL)
TCLSH = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
!if !exist($(TCLSH)) && $(TCL_THREADS)
diff --git a/win/tclAppInit.c b/win/tclAppInit.c
index d6da500..56f45a0 100644
--- a/win/tclAppInit.c
+++ b/win/tclAppInit.c
@@ -109,9 +109,9 @@ _tmain(
* Forward slashes substituted for backslashes.
*/
- for (p = argv[0]; *p != TEXT('\0'); p++) {
- if (*p == TEXT('\\')) {
- *p = TEXT('/');
+ for (p = argv[0]; *p != '\0'; p++) {
+ if (*p == '\\') {
+ *p = '/';
}
}
@@ -242,13 +242,13 @@ setargv(
*/
size = 2;
- for (p = cmdLine; *p != TEXT('\0'); p++) {
- if ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */
+ for (p = cmdLine; *p != '\0'; p++) {
+ if ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */
size++;
- while ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */
+ while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */
p++;
}
- if (*p == TEXT('\0')) {
+ if (*p == '\0') {
break;
}
}
@@ -267,10 +267,10 @@ setargv(
p = cmdLine;
for (argc = 0; argc < size; argc++) {
argv[argc] = arg = argSpace;
- while ((*p == TEXT(' ')) || (*p == TEXT('\t'))) { /* INTL: ISO space. */
+ while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */
p++;
}
- if (*p == TEXT('\0')) {
+ if (*p == '\0') {
break;
}
@@ -278,14 +278,14 @@ setargv(
slashes = 0;
while (1) {
copy = 1;
- while (*p == TEXT('\\')) {
+ while (*p == '\\') {
slashes++;
p++;
}
- if (*p == TEXT('"')) {
+ if (*p == '"') {
if ((slashes & 1) == 0) {
copy = 0;
- if ((inquote) && (p[1] == TEXT('"'))) {
+ if ((inquote) && (p[1] == '"')) {
p++;
copy = 1;
} else {
@@ -296,13 +296,13 @@ setargv(
}
while (slashes) {
- *arg = TEXT('\\');
+ *arg = '\\';
arg++;
slashes--;
}
- if ((*p == TEXT('\0')) || (!inquote &&
- ((*p == TEXT(' ')) || (*p == TEXT('\t'))))) { /* INTL: ISO space. */
+ if ((*p == '\0') || (!inquote &&
+ ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
break;
}
if (copy != 0) {
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index 517aa20..52b9e32 100644
--- a/win/tclWinChan.c
+++ b/win/tclWinChan.c
@@ -940,8 +940,9 @@ TclpOpenFileChannel(
}
TclWinConvertError(err);
if (interp != (Tcl_Interp *) NULL) {
- Tcl_AppendResult(interp, "couldn't open \"", TclGetString(pathPtr),
- "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't open \"%s\": %s",
+ TclGetString(pathPtr), Tcl_PosixError(interp)));
}
return NULL;
}
@@ -959,9 +960,9 @@ TclpOpenFileChannel(
if (handle == INVALID_HANDLE_VALUE) {
TclWinConvertError(GetLastError());
if (interp != (Tcl_Interp *) NULL) {
- Tcl_AppendResult(interp, "couldn't reopen serial \"",
- TclGetString(pathPtr), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't reopen serial \"%s\": %s",
+ TclGetString(pathPtr), Tcl_PosixError(interp)));
}
return NULL;
}
@@ -995,8 +996,9 @@ TclpOpenFileChannel(
*/
channel = NULL;
- Tcl_AppendResult(interp, "couldn't open \"", TclGetString(pathPtr),
- "\": bad file type", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't open \"%s\": bad file type",
+ TclGetString(pathPtr)));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "CHANNEL", "BAD_TYPE",
NULL);
break;
diff --git a/win/tclWinDde.c b/win/tclWinDde.c
index 4d6e31b..f5c0484 100644
--- a/win/tclWinDde.c
+++ b/win/tclWinDde.c
@@ -26,6 +26,12 @@
# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c)
#endif
+#if !defined(NDEBUG)
+ /* test POKE server Implemented for debug mode only */
+# undef CBF_FAIL_POKES
+# define CBF_FAIL_POKES 0
+#endif
+
/*
* TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the Dde_Init
* declaration is in the source file itself, which is only accessed when we
@@ -90,7 +96,7 @@ static DWORD ddeInstance; /* The application instance handle given to us
* by DdeInitialize. */
static int ddeIsServer = 0;
-#define TCL_DDE_VERSION "1.4.0b1"
+#define TCL_DDE_VERSION "1.4.0b2"
#define TCL_DDE_PACKAGE_NAME "dde"
#define TCL_DDE_SERVICE_NAME TEXT("TclEval")
#define TCL_DDE_EXECUTE_RESULT TEXT("$TCLEVAL$EXECUTE$RESULT")
@@ -157,7 +163,8 @@ Dde_Init(
#ifdef UNICODE
if (TclWinGetPlatformId() < VER_PLATFORM_WIN32_NT) {
- Tcl_AppendResult(interp, "Win32s and Windows 9x are not supported platforms", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "Win32s and Windows 9x are not supported platforms", -1));
return TCL_ERROR;
}
#endif
@@ -749,7 +756,7 @@ DdeServerProc(
} else {
returnString = (char *)
Tcl_GetUnicodeFromObj(convPtr->returnPackagePtr, &len);
- len = 2 * len + 1;
+ len = sizeof(TCHAR) * len + 1;
}
ddeReturn = DdeCreateDataHandle(ddeInstance, (BYTE *)returnString,
(DWORD) len+1, 0, ddeItem, uFmt, 0);
@@ -770,7 +777,7 @@ DdeServerProc(
} else {
returnString = (char *) Tcl_GetUnicodeFromObj(
variableObjPtr, &len);
- len = 2 * len + 1;
+ len = sizeof(TCHAR) * len + 1;
}
ddeReturn = DdeCreateDataHandle(ddeInstance,
(BYTE *)returnString, (DWORD) len+1, 0, ddeItem,
@@ -785,6 +792,53 @@ DdeServerProc(
}
return ddeReturn;
+#if !CBF_FAIL_POKES
+ case XTYP_POKE:
+ /*
+ * This is a poke for a Tcl variable, only implemented in
+ * debug/UNICODE mode.
+ */
+ ddeReturn = DDE_FNOTPROCESSED;
+
+ if ((uFmt != CF_TEXT) && (uFmt != CF_UNICODETEXT)) {
+ return ddeReturn;
+ }
+
+ for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
+ && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
+ /*
+ * Empty loop body.
+ */
+ }
+
+ if (convPtr && !Tcl_IsSafe(convPtr->riPtr->interp)) {
+ Tcl_DString ds;
+ Tcl_Obj *variableObjPtr;
+
+ len = DdeQueryString(ddeInstance, ddeItem, NULL, 0, CP_WINUNICODE);
+ Tcl_DStringInit(&dString);
+ Tcl_DStringSetLength(&dString, (len + 1) * sizeof(TCHAR) - 1);
+ utilString = (TCHAR *) Tcl_DStringValue(&dString);
+ DdeQueryString(ddeInstance, ddeItem, utilString, (DWORD) len + 1,
+ CP_WINUNICODE);
+ Tcl_WinTCharToUtf(utilString, -1, &ds);
+ utilString = (TCHAR *) DdeAccessData(hData, &dlen);
+ if (uFmt == CF_TEXT) {
+ variableObjPtr = Tcl_NewStringObj((char *)utilString, -1);
+ } else {
+ variableObjPtr = Tcl_NewUnicodeObj(utilString, -1);
+ }
+
+ Tcl_SetVar2Ex(convPtr->riPtr->interp, Tcl_DStringValue(&ds), NULL,
+ variableObjPtr, TCL_GLOBAL_ONLY);
+
+ Tcl_DStringFree(&ds);
+ Tcl_DStringFree(&dString);
+ ddeReturn = (HDDEDATA) DDE_FACK;
+ }
+ return ddeReturn;
+
+#endif
case XTYP_EXECUTE: {
/*
* Execute this script. The results will be saved into a list object
@@ -947,8 +1001,12 @@ MakeDdeConnection(
if (ddeConv == (HCONV) NULL) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "no registered server named \"",
- name, "\"", NULL);
+ Tcl_DString dString;
+
+ Tcl_WinTCharToUtf(name, -1, &dString);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "no registered server named \"%s\"", Tcl_DStringValue(&dString)));
+ Tcl_DStringFree(&dString);
Tcl_SetErrorCode(interp, "TCL", "DDE", "NO_SERVER", NULL);
}
return TCL_ERROR;
@@ -1424,7 +1482,11 @@ DdeObjCmd(
serviceName = DdeSetServerName(interp, serviceName, flags,
handlerPtr);
if (serviceName != NULL) {
+#ifdef UNICODE
Tcl_SetObjResult(interp, Tcl_NewUnicodeObj((Tcl_UniChar *) serviceName, -1));
+#else
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(serviceName, -1));
+#endif
} else {
Tcl_ResetResult(interp);
}
@@ -1432,15 +1494,15 @@ DdeObjCmd(
case DDE_EXECUTE: {
int dataLength;
- const char *dataString;
+ const Tcl_UniChar *dataString;
if (flags & DDE_FLAG_BINARY) {
- dataString = (const char *)
+ dataString = (const Tcl_UniChar *)
Tcl_GetByteArrayFromObj(objv[firstArg + 2], &dataLength);
} else {
dataString =
- Tcl_GetStringFromObj(objv[firstArg + 2], &dataLength);
- dataLength += 1;
+ Tcl_GetUnicodeFromObj(objv[firstArg + 2], &dataLength);
+ dataLength = (dataLength + 1) * sizeof(Tcl_UniChar);
}
if (dataLength <= 0) {
@@ -1461,15 +1523,15 @@ DdeObjCmd(
}
ddeData = DdeCreateDataHandle(ddeInstance, (BYTE *) dataString,
- (DWORD) dataLength, 0, 0, CF_TEXT, 0);
+ (DWORD) dataLength, 0, 0, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, 0);
if (ddeData != NULL) {
if (flags & DDE_FLAG_ASYNC) {
DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0,
- CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
+ (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
DdeAbandonTransaction(ddeInstance, hConv, ddeResult);
} else {
ddeReturn = DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF,
- hConv, 0, CF_TEXT, XTYP_EXECUTE, 30000, NULL);
+ hConv, 0, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_EXECUTE, 30000, NULL);
if (ddeReturn == 0) {
SetDdeError(interp);
result = TCL_ERROR;
@@ -1511,22 +1573,23 @@ DdeObjCmd(
CP_WINUNICODE);
if (ddeItem != NULL) {
ddeData = DdeClientTransaction(NULL, 0, hConv, ddeItem,
- CF_TEXT, XTYP_REQUEST, 5000, NULL);
+ (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_REQUEST, 5000, NULL);
if (ddeData == NULL) {
SetDdeError(interp);
result = TCL_ERROR;
} else {
DWORD tmp;
- const char *dataString = (const char *) DdeAccessData(ddeData, &tmp);
+ const Tcl_UniChar *dataString = (const Tcl_UniChar *) DdeAccessData(ddeData, &tmp);
if (flags & DDE_FLAG_BINARY) {
returnObjPtr =
Tcl_NewByteArrayObj((BYTE *) dataString, (int) tmp);
} else {
- if (tmp && !dataString[tmp-1]) {
+ tmp >>= 1;
+ if (tmp && !dataString[(tmp-1)]) {
--tmp;
}
- returnObjPtr = Tcl_NewStringObj(dataString,
+ returnObjPtr = Tcl_NewUnicodeObj(dataString,
(int) tmp);
}
DdeUnaccessData(ddeData);
@@ -1563,8 +1626,8 @@ DdeObjCmd(
Tcl_GetByteArrayFromObj(objv[firstArg + 3], &length);
} else {
dataString = (BYTE *)
- Tcl_GetStringFromObj(objv[firstArg + 3], &length);
- length += 1;
+ Tcl_GetUnicodeFromObj(objv[firstArg + 3], &length);
+ length = 2 * length + 1;
}
hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
@@ -1579,7 +1642,7 @@ DdeObjCmd(
CP_WINUNICODE);
if (ddeItem != NULL) {
ddeData = DdeClientTransaction(dataString, (DWORD) length,
- hConv, ddeItem, CF_TEXT, XTYP_POKE, 5000, NULL);
+ hConv, ddeItem, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_POKE, 5000, NULL);
if (ddeData == NULL) {
SetDdeError(interp);
result = TCL_ERROR;
@@ -1722,24 +1785,24 @@ DdeObjCmd(
}
objPtr = Tcl_ConcatObj(objc, objv);
- string = Tcl_GetStringFromObj(objPtr, &length);
+ string = (const char *) Tcl_GetUnicodeFromObj(objPtr, &length);
ddeItemData = DdeCreateDataHandle(ddeInstance,
- (BYTE *) string, (DWORD) length+1, 0, 0, CF_TEXT, 0);
+ (BYTE *) string, (DWORD) 2*length+2, 0, 0, CF_UNICODETEXT, 0);
if (flags & DDE_FLAG_ASYNC) {
ddeData = DdeClientTransaction((LPBYTE) ddeItemData,
0xFFFFFFFF, hConv, 0,
- CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
+ CF_UNICODETEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
DdeAbandonTransaction(ddeInstance, hConv, ddeResult);
} else {
ddeData = DdeClientTransaction((LPBYTE) ddeItemData,
0xFFFFFFFF, hConv, 0,
- CF_TEXT, XTYP_EXECUTE, 30000, NULL);
+ CF_UNICODETEXT, XTYP_EXECUTE, 30000, NULL);
if (ddeData != 0) {
ddeCookie = DdeCreateStringHandle(ddeInstance,
TCL_DDE_EXECUTE_RESULT, CP_WINUNICODE);
ddeData = DdeClientTransaction(NULL, 0, hConv, ddeCookie,
- CF_TEXT, XTYP_REQUEST, 30000, NULL);
+ CF_UNICODETEXT, XTYP_REQUEST, 30000, NULL);
}
}
@@ -1753,6 +1816,7 @@ DdeObjCmd(
if (!(flags & DDE_FLAG_ASYNC)) {
Tcl_Obj *resultPtr;
+ Tcl_UniChar *ddeDataString;
/*
* The return handle has a two or four element list in it. The
@@ -1765,10 +1829,11 @@ DdeObjCmd(
resultPtr = Tcl_NewObj();
length = DdeGetData(ddeData, NULL, 0, 0);
- Tcl_SetObjLength(resultPtr, (length + 1) * sizeof(TCHAR) - 1);
- string = Tcl_GetString(resultPtr);
- DdeGetData(ddeData, (BYTE *) string, (DWORD) length, 0);
- Tcl_SetObjLength(resultPtr, (int) strlen(string));
+ ddeDataString = ckalloc(length);
+ DdeGetData(ddeData, (BYTE *) ddeDataString, (DWORD) length, 0);
+ length = (length >> 1) - 1;
+ resultPtr = Tcl_NewUnicodeObj(ddeDataString, length);
+ ckfree(ddeDataString);
if (Tcl_ListObjIndex(NULL, resultPtr, 0, &objPtr) != TCL_OK) {
Tcl_DecrRefCount(resultPtr);
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c
index 77a5b82..ac88861 100644
--- a/win/tclWinFCmd.c
+++ b/win/tclWinFCmd.c
@@ -1530,8 +1530,8 @@ StatError(
* error. */
{
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "could not read \"", TclGetString(fileName),
- "\": ", Tcl_PosixError(interp), (char *) NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s",
+ TclGetString(fileName), Tcl_PosixError(interp)));
}
/*
@@ -1649,9 +1649,9 @@ ConvertFileNameFormat(
if (splitPath == NULL || pathc == 0) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "could not read \"",
- Tcl_GetString(fileName), "\": no such file or directory",
- (char *) NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "could not read \"%s\": no such file or directory",
+ Tcl_GetString(fileName)));
errno = ENOENT;
Tcl_PosixError(interp);
}
@@ -1738,11 +1738,11 @@ ConvertFileNameFormat(
}
nativeName = data.cAlternateFileName;
if (longShort) {
- if (data.cFileName[0] != TEXT('\0')) {
+ if (data.cFileName[0] != '\0') {
nativeName = data.cFileName;
}
} else {
- if (data.cAlternateFileName[0] == TEXT('\0')) {
+ if (data.cAlternateFileName[0] == '\0') {
nativeName = (TCHAR *) data.cFileName;
}
}
@@ -1941,9 +1941,9 @@ CannotSetAttribute(
Tcl_Obj *fileName, /* The name of the file. */
Tcl_Obj *attributePtr) /* The new value of the attribute. */
{
- Tcl_AppendResult(interp, "cannot set attribute \"",
- tclpFileAttrStrings[objIndex], "\" for file \"",
- Tcl_GetString(fileName), "\": attribute is readonly", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "cannot set attribute \"%s\" for file \"%s\": attribute is readonly",
+ tclpFileAttrStrings[objIndex], Tcl_GetString(fileName)));
errno = EINVAL;
Tcl_PosixError(interp);
return TCL_ERROR;
diff --git a/win/tclWinFile.c b/win/tclWinFile.c
index 1f56060..a1189f5 100644
--- a/win/tclWinFile.c
+++ b/win/tclWinFile.c
@@ -1048,10 +1048,9 @@ TclpMatchInDirectory(
TclWinConvertError(err);
if (interp != NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "couldn't read directory \"",
- Tcl_DStringValue(&dsOrig), "\": ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't read directory \"%s\": %s",
+ Tcl_DStringValue(&dsOrig), Tcl_PosixError(interp)));
}
Tcl_DStringFree(&dsOrig);
return TCL_ERROR;
@@ -1785,7 +1784,7 @@ NativeIsExec(
return 0;
}
- if (path[len-4] != TEXT('.')) {
+ if (path[len-4] != '.') {
return 0;
}
@@ -1866,8 +1865,9 @@ TclpGetCwd(
if (GetCurrentDirectory(MAX_PATH, buffer) == 0) {
TclWinConvertError(GetLastError());
if (interp != NULL) {
- Tcl_AppendResult(interp, "error getting working directory name: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "error getting working directory name: %s",
+ Tcl_PosixError(interp)));
}
return NULL;
}
diff --git a/win/tclWinLoad.c b/win/tclWinLoad.c
index b59ccba..6294086 100644
--- a/win/tclWinLoad.c
+++ b/win/tclWinLoad.c
@@ -91,9 +91,8 @@ TclpDlopen(
if (hInstance == NULL) {
DWORD lastError = GetLastError();
-
- Tcl_AppendResult(interp, "couldn't load library \"",
- Tcl_GetString(pathPtr), "\": ", NULL);
+ Tcl_Obj *errMsg = Tcl_ObjPrintf("couldn't load library \"%s\": ",
+ Tcl_GetString(pathPtr));
/*
* Check for possible DLL errors. This doesn't work quite right,
@@ -109,29 +108,30 @@ TclpDlopen(
case ERROR_DLL_NOT_FOUND:
Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_NOT_FOUND", NULL);
notFoundMsg:
- Tcl_AppendResult(interp, "this library or a dependent library"
- " could not be found in library path", NULL);
+ Tcl_AppendToObj(errMsg, "this library or a dependent library"
+ " could not be found in library path", -1);
break;
case ERROR_PROC_NOT_FOUND:
Tcl_SetErrorCode(interp, "WIN_LOAD", "PROC_NOT_FOUND", NULL);
- Tcl_AppendResult(interp, "A function specified in the import"
- " table could not be resolved by the system. Windows"
- " is not telling which one, I'm sorry.", NULL);
+ 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);
break;
case ERROR_INVALID_DLL:
Tcl_SetErrorCode(interp, "WIN_LOAD", "INVALID_DLL", NULL);
- Tcl_AppendResult(interp, "this library or a dependent library"
- " is damaged", NULL);
+ Tcl_AppendToObj(errMsg, "this library or a dependent library"
+ " is damaged", -1);
break;
case ERROR_DLL_INIT_FAILED:
Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_INIT_FAILED", NULL);
- Tcl_AppendResult(interp, "the library initialization"
- " routine failed", NULL);
+ Tcl_AppendToObj(errMsg, "the library initialization"
+ " routine failed", -1);
break;
default:
TclWinConvertError(lastError);
- Tcl_AppendResult(interp, Tcl_PosixError(interp), NULL);
+ Tcl_AppendToObj(errMsg, Tcl_PosixError(interp), -1);
}
+ Tcl_SetObjResult(interp, errMsg);
return TCL_ERROR;
}
@@ -190,7 +190,8 @@ FindSymbol(
Tcl_DStringFree(&ds);
}
if (proc == NULL && interp != NULL) {
- Tcl_AppendResult(interp, "cannot find symbol \"", symbol, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "cannot find symbol \"%s\"", symbol));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol, NULL);
}
return proc;
@@ -286,8 +287,9 @@ TclpTempFileNameForLibrary(
Tcl_MutexLock(&dllDirectoryNameMutex);
if (dllDirectoryName == NULL) {
if (InitDLLDirectoryName() == TCL_ERROR) {
- Tcl_AppendResult(interp, "couldn't create temporary directory: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't create temporary directory: %s",
+ Tcl_PosixError(interp)));
Tcl_MutexUnlock(&dllDirectoryNameMutex);
return NULL;
}
diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c
index db462f8..36ae58a 100644
--- a/win/tclWinPipe.c
+++ b/win/tclWinPipe.c
@@ -1030,8 +1030,9 @@ TclpCreateProcess(
}
if (startInfo.hStdInput == INVALID_HANDLE_VALUE) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "couldn't duplicate input handle: ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't duplicate input handle: %s",
+ Tcl_PosixError(interp)));
goto end;
}
@@ -1065,8 +1066,9 @@ TclpCreateProcess(
}
if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "couldn't duplicate output handle: ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't duplicate output handle: %s",
+ Tcl_PosixError(interp)));
goto end;
}
@@ -1084,8 +1086,9 @@ TclpCreateProcess(
}
if (startInfo.hStdError == INVALID_HANDLE_VALUE) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "couldn't duplicate error handle: ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't duplicate error handle: %s",
+ Tcl_PosixError(interp)));
goto end;
}
@@ -1129,9 +1132,9 @@ TclpCreateProcess(
}
if (applType == APPL_DOS) {
- Tcl_AppendResult(interp,
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
"DOS application process not supported on this platform",
- (char *) NULL);
+ -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "DOS_APP",
NULL);
goto end;
@@ -1158,12 +1161,12 @@ TclpCreateProcess(
BuildCommandLine(execPath, argc, argv, &cmdLine);
- if (CreateProcess(NULL,
- (TCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE,
- (DWORD) createFlags, NULL, NULL, &startInfo, &procInfo) == 0) {
+ if (CreateProcess(NULL, (TCHAR *) Tcl_DStringValue(&cmdLine),
+ NULL, NULL, TRUE, (DWORD) createFlags, NULL, NULL, &startInfo,
+ &procInfo) == 0) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "couldn't execute \"", argv[0],
- "\": ", Tcl_PosixError(interp), (char *) NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s",
+ argv[0], Tcl_PosixError(interp)));
goto end;
}
@@ -1409,8 +1412,8 @@ ApplicationType(
if (applType == APPL_NONE) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "couldn't execute \"", originalName,
- "\": ", Tcl_PosixError(interp), (char *) NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s",
+ originalName, Tcl_PosixError(interp)));
return APPL_NONE;
}
@@ -1673,8 +1676,8 @@ Tcl_CreatePipe(
if (!CreatePipe(&readHandle, &writeHandle, &sec, 0)) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "pipe creation failed: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "pipe creation failed: %s", Tcl_PosixError(interp)));
return TCL_ERROR;
}
diff --git a/win/tclWinPort.h b/win/tclWinPort.h
index c262671..48f7894 100644
--- a/win/tclWinPort.h
+++ b/win/tclWinPort.h
@@ -14,8 +14,8 @@
#ifndef _TCLWINPORT
#define _TCLWINPORT
-#ifndef _WIN64
-/* See [Bug 2935503]: file mtime sets wrong time */
+#if !defined(_WIN64) && defined(BUILD_tcl)
+/* See [Bug 3354324]: file mtime sets wrong time */
# define _USE_32BIT_TIME_T
#endif
@@ -538,7 +538,6 @@ typedef DWORD_PTR * PDWORD_PTR;
#define getservbyname TclWinGetServByName
#define getsockopt TclWinGetSockOpt
-#define ntohs TclWinNToHS
#define setsockopt TclWinSetSockOpt
/* This type is not defined in the Windows headers */
#define socklen_t int
diff --git a/win/tclWinReg.c b/win/tclWinReg.c
index 9c08b0c..6ac5caf 100644
--- a/win/tclWinReg.c
+++ b/win/tclWinReg.c
@@ -15,6 +15,7 @@
#undef STATIC_BUILD
#undef USE_TCL_STUBS
#define USE_TCL_STUBS
+
#include "tclInt.h"
#ifdef _MSC_VER
# pragma comment (lib, "advapi32.lib")
@@ -23,20 +24,20 @@
#ifndef UNICODE
# undef Tcl_WinTCharToUtf
-# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c)
+# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c)
# undef Tcl_WinUtfToTChar
-# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c)
-#endif
+# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c)
+#endif /* !UNICODE */
/*
* Ensure that we can say which registry is being accessed.
*/
#ifndef KEY_WOW64_64KEY
-#define KEY_WOW64_64KEY (0x0100)
+# define KEY_WOW64_64KEY (0x0100)
#endif
#ifndef KEY_WOW64_32KEY
-#define KEY_WOW64_32KEY (0x0200)
+# define KEY_WOW64_32KEY (0x0200)
#endif
/*
@@ -44,7 +45,7 @@
*/
#ifndef MAX_KEY_LENGTH
-#define MAX_KEY_LENGTH 256
+# define MAX_KEY_LENGTH 256
#endif
/*
@@ -57,14 +58,6 @@
#define TCL_STORAGE_CLASS DLLEXPORT
/*
- * The maximum length of a sub-key name.
- */
-
-#ifndef MAX_KEY_LENGTH
-#define MAX_KEY_LENGTH 256
-#endif
-
-/*
* The following macros convert between different endian ints.
*/
@@ -172,7 +165,7 @@ Registry_Init(
{
Tcl_Command cmd;
- if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
+ if (Tcl_InitStubs(interp, "8.5", 0) == NULL) {
return TCL_ERROR;
}
@@ -534,9 +527,9 @@ DeleteValue(
result = RegDeleteValue(key, (const TCHAR *)Tcl_DStringValue(&ds));
Tcl_DStringFree(&ds);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to delete value \"",
- Tcl_GetString(valueNameObj), "\" from key \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unable to delete value \"%s\" from key \"%s\": ",
+ Tcl_GetString(valueNameObj), Tcl_GetString(keyNameObj)));
AppendSystemError(interp, result);
result = TCL_ERROR;
} else {
@@ -574,7 +567,8 @@ GetKeyNames(
{
const char *pattern; /* Pattern being matched against subkeys */
HKEY key; /* Handle to the key being examined */
- TCHAR buffer[MAX_KEY_LENGTH]; /* Buffer to hold the subkey name */
+ TCHAR buffer[MAX_KEY_LENGTH];
+ /* Buffer to hold the subkey name */
DWORD bufSize; /* Size of the buffer */
DWORD index; /* Position of the current subkey */
char *name; /* Subkey name */
@@ -610,9 +604,9 @@ GetKeyNames(
if (result == ERROR_NO_MORE_ITEMS) {
result = TCL_OK;
} else {
- Tcl_SetObjResult(interp, Tcl_NewObj());
- Tcl_AppendResult(interp, "unable to enumerate subkeys of \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unable to enumerate subkeys of \"%s\": ",
+ Tcl_GetString(keyNameObj)));
AppendSystemError(interp, result);
result = TCL_ERROR;
}
@@ -693,9 +687,9 @@ GetType(
RegCloseKey(key);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to get type of value \"",
- Tcl_GetString(valueNameObj), "\" from key \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unable to get type of value \"%s\" from key \"%s\": ",
+ Tcl_GetString(valueNameObj), Tcl_GetString(keyNameObj)));
AppendSystemError(interp, result);
return TCL_ERROR;
}
@@ -787,9 +781,9 @@ GetValue(
Tcl_DStringFree(&buf);
RegCloseKey(key);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to get value \"",
- Tcl_GetString(valueNameObj), "\" from key \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unable to get value \"%s\" from key \"%s\": ",
+ Tcl_GetString(valueNameObj), Tcl_GetString(keyNameObj)));
AppendSystemError(interp, result);
Tcl_DStringFree(&data);
return TCL_ERROR;
@@ -816,16 +810,16 @@ GetValue(
* we get bogus data.
*/
- while ((p < end)
- && (*((Tcl_UniChar *) p)) != 0) {
+ while ((p < end) && *((Tcl_UniChar *) p) != 0) {
Tcl_UniChar *up;
+
Tcl_WinTCharToUtf((TCHAR *) p, -1, &buf);
Tcl_ListObjAppendElement(interp, resultPtr,
Tcl_NewStringObj(Tcl_DStringValue(&buf),
Tcl_DStringLength(&buf)));
up = (Tcl_UniChar *) p;
- while (*up++ != 0) {}
+ while (*up++ != 0) {/* empty body */}
p = (char *) up;
Tcl_DStringFree(&buf);
}
@@ -1110,8 +1104,8 @@ ParseKeyName(
rootName = name;
}
if (!rootName) {
- Tcl_AppendResult(interp, "bad key \"", name,
- "\": must start with a valid root", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad key \"%s\": must start with a valid root", name));
Tcl_SetErrorCode(interp, "WIN_REG", "NO_ROOT_KEY", NULL);
return TCL_ERROR;
}
@@ -1225,8 +1219,8 @@ RecursiveDeleteKey(
}
break;
} else if (result == ERROR_SUCCESS) {
- result = RecursiveDeleteKey(hKey, (const TCHAR *) Tcl_DStringValue(&subkey),
- mode);
+ result = RecursiveDeleteKey(hKey,
+ (const TCHAR *) Tcl_DStringValue(&subkey), mode);
}
}
Tcl_DStringFree(&subkey);
@@ -1293,8 +1287,8 @@ SetValue(
return TCL_ERROR;
}
- value = ConvertDWORD((DWORD)type, (DWORD)value);
- result = RegSetValueEx(key, (TCHAR *)valueName, 0,
+ value = ConvertDWORD((DWORD) type, (DWORD) value);
+ result = RegSetValueEx(key, (TCHAR *) valueName, 0,
(DWORD) type, (BYTE *) &value, sizeof(DWORD));
} else if (type == REG_MULTI_SZ) {
Tcl_DString data, buf;
@@ -1328,7 +1322,7 @@ SetValue(
Tcl_WinUtfToTChar(Tcl_DStringValue(&data), Tcl_DStringLength(&data)+1,
&buf);
- result = RegSetValueEx(key, (TCHAR *)valueName, 0,
+ result = RegSetValueEx(key, (TCHAR *) valueName, 0,
(DWORD) type, (BYTE *) Tcl_DStringValue(&buf),
(DWORD) Tcl_DStringLength(&buf));
Tcl_DStringFree(&data);
@@ -1337,7 +1331,7 @@ SetValue(
Tcl_DString buf;
const char *data = Tcl_GetStringFromObj(dataObj, &length);
- data = (char *)Tcl_WinUtfToTChar(data, length, &buf);
+ data = (char *) Tcl_WinUtfToTChar(data, length, &buf);
/*
* Include the null in the length, padding if needed for Unicode.
@@ -1346,7 +1340,7 @@ SetValue(
Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf)+1);
length = Tcl_DStringLength(&buf) + 1;
- result = RegSetValueEx(key, (TCHAR *)valueName, 0,
+ result = RegSetValueEx(key, (TCHAR *) valueName, 0,
(DWORD) type, (BYTE *) data, (DWORD) length);
Tcl_DStringFree(&buf);
} else {
@@ -1357,7 +1351,7 @@ SetValue(
*/
data = (BYTE *) Tcl_GetByteArrayFromObj(dataObj, &length);
- result = RegSetValueEx(key, (TCHAR *)valueName, 0,
+ result = RegSetValueEx(key, (TCHAR *) valueName, 0,
(DWORD) type, data, (DWORD) length);
}
@@ -1528,14 +1522,15 @@ ConvertDWORD(
DWORD type, /* Either REG_DWORD or REG_DWORD_BIG_ENDIAN */
DWORD value) /* The value to be converted. */
{
- DWORD order = 1;
+ const DWORD order = 1;
DWORD localType;
/*
* Check to see if the low bit is in the first byte.
*/
- localType = (*((char *) &order) == 1) ? REG_DWORD : REG_DWORD_BIG_ENDIAN;
+ localType = (*((const char *) &order) == 1)
+ ? REG_DWORD : REG_DWORD_BIG_ENDIAN;
return (type != localType) ? (DWORD) SWAPLONG(value) : value;
}
diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c
index 58a9eb4..9e9d1af 100644
--- a/win/tclWinSerial.c
+++ b/win/tclWinSerial.c
@@ -1673,12 +1673,7 @@ SerialSetOptionProc(
if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) {
if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't get comm state: ",
- Tcl_PosixError(interp), NULL);
- }
- return TCL_ERROR;
+ goto getStateFailed;
}
native = Tcl_WinUtfToTChar(value, -1, &ds);
result = BuildCommDCB(native, &dcb);
@@ -1686,8 +1681,9 @@ SerialSetOptionProc(
if (result == FALSE) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value \"", value,
- "\" for -mode: should be baud,parity,data,stop", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad value \"%s\" for -mode: should be baud,parity,data,stop",
+ value));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", NULL);
}
return TCL_ERROR;
@@ -1703,12 +1699,7 @@ SerialSetOptionProc(
dcb.fAbortOnError = FALSE;
if (!SetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't set comm state: ",
- Tcl_PosixError(interp), NULL);
- }
- return TCL_ERROR;
+ goto setStateFailed;
}
return TCL_OK;
}
@@ -1719,12 +1710,7 @@ SerialSetOptionProc(
if ((len > 1) && (strncmp(optionName, "-handshake", len) == 0)) {
if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't get comm state: ",
- Tcl_PosixError(interp), NULL);
- }
- return TCL_ERROR;
+ goto getStateFailed;
}
/*
@@ -1759,21 +1745,16 @@ SerialSetOptionProc(
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
} else {
if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value \"", value,
- "\" for -handshake: must be one of xonxoff, rtscts, "
- "dtrdsr or none", NULL);
+ 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);
}
return TCL_ERROR;
}
if (!SetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't set comm state: ",
- Tcl_PosixError(interp), NULL);
- }
- return TCL_ERROR;
+ goto setStateFailed;
}
return TCL_OK;
}
@@ -1784,12 +1765,7 @@ SerialSetOptionProc(
if ((len > 1) && (strncmp(optionName, "-xchar", len) == 0)) {
if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't get comm state: ",
- Tcl_PosixError(interp), NULL);
- }
- return TCL_ERROR;
+ goto getStateFailed;
}
if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {
@@ -1798,9 +1774,9 @@ SerialSetOptionProc(
if (argc != 2) {
badXchar:
if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value for -xchar: should be "
- "a list of two elements with each a single character",
- NULL);
+ 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);
}
ckfree(argv);
@@ -1837,12 +1813,7 @@ SerialSetOptionProc(
ckfree(argv);
if (!SetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't set comm state: ",
- Tcl_PosixError(interp), NULL);
- }
- return TCL_ERROR;
+ goto setStateFailed;
}
return TCL_OK;
}
@@ -1859,9 +1830,9 @@ SerialSetOptionProc(
}
if ((argc % 2) == 1) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value \"", value,
- "\" for -ttycontrol: should be a list of "
- "signal,value pairs", NULL);
+ 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);
}
ckfree(argv);
@@ -1877,7 +1848,8 @@ SerialSetOptionProc(
if (!EscapeCommFunction(infoPtr->handle,
(DWORD) (flag ? SETDTR : CLRDTR))) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "can't set DTR signal", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can't set DTR signal", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION",
"FCONFIGURE", "TTY_SIGNAL", NULL);
}
@@ -1888,7 +1860,8 @@ SerialSetOptionProc(
if (!EscapeCommFunction(infoPtr->handle,
(DWORD) (flag ? SETRTS : CLRRTS))) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "can't set RTS signal", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can't set RTS signal", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION",
"FCONFIGURE", "TTY_SIGNAL", NULL);
}
@@ -1899,7 +1872,8 @@ SerialSetOptionProc(
if (!EscapeCommFunction(infoPtr->handle,
(DWORD) (flag ? SETBREAK : CLRBREAK))) {
if (interp != NULL) {
- Tcl_AppendResult(interp,"can't set BREAK signal",NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "can't set BREAK signal", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION",
"FCONFIGURE", "TTY_SIGNAL", NULL);
}
@@ -1908,9 +1882,9 @@ SerialSetOptionProc(
}
} else {
if (interp != NULL) {
- Tcl_AppendResult(interp, "bad signal name \"", argv[i],
- "\" for -ttycontrol: must be DTR, RTS or BREAK",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad signal name \"%s\" for -ttycontrol: must be"
+ " DTR, RTS or BREAK", argv[i]));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "TTY_SIGNAL",
NULL);
}
@@ -1949,9 +1923,9 @@ SerialSetOptionProc(
if ((argc < 1) || (argc > 2) || (inSize <= 0) || (outSize <= 0)) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "bad value \"", value,
- "\" for -sysbuffer: should be a list of one or two "
- "integers > 0", NULL);
+ 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);
}
return TCL_ERROR;
@@ -1960,8 +1934,9 @@ SerialSetOptionProc(
if (!SetupComm(infoPtr->handle, inSize, outSize)) {
if (interp != NULL) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't setup comm buffers: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't setup comm buffers: %s",
+ Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -1974,22 +1949,12 @@ SerialSetOptionProc(
*/
if (!GetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't get comm state: ",
- Tcl_PosixError(interp), NULL);
- }
- return TCL_ERROR;
+ goto getStateFailed;
}
dcb.XonLim = (WORD) (infoPtr->sysBufRead*1/2);
dcb.XoffLim = (WORD) (infoPtr->sysBufRead*1/4);
if (!SetCommState(infoPtr->handle, &dcb)) {
- if (interp != NULL) {
- TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't set comm state: ",
- Tcl_PosixError(interp), NULL);
- }
- return TCL_ERROR;
+ goto setStateFailed;
}
return TCL_OK;
}
@@ -2020,8 +1985,9 @@ SerialSetOptionProc(
if (!SetCommTimeouts(infoPtr->handle, &tout)) {
if (interp != NULL) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't set comm timeouts: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't set comm timeouts: %s",
+ Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -2031,6 +1997,22 @@ SerialSetOptionProc(
return Tcl_BadChannelOption(interp, optionName,
"mode handshake pollinterval sysbuffer timeout ttycontrol xchar");
+
+ getStateFailed:
+ if (interp != NULL) {
+ TclWinConvertError(GetLastError());
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't get comm state: %s", Tcl_PosixError(interp)));
+ }
+ return TCL_ERROR;
+
+ setStateFailed:
+ if (interp != NULL) {
+ TclWinConvertError(GetLastError());
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't set comm state: %s", Tcl_PosixError(interp)));
+ }
+ return TCL_ERROR;
}
/*
@@ -2089,8 +2071,8 @@ SerialGetOptionProc(
if (!GetCommState(infoPtr->handle, &dcb)) {
if (interp != NULL) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't get comm state: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't get comm state: %s", Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -2159,8 +2141,8 @@ SerialGetOptionProc(
if (!GetCommState(infoPtr->handle, &dcb)) {
if (interp != NULL) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't get comm state: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't get comm state: %s", Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -2237,8 +2219,8 @@ SerialGetOptionProc(
if (!GetCommModemStatus(infoPtr->handle, &status)) {
if (interp != NULL) {
TclWinConvertError(GetLastError());
- Tcl_AppendResult(interp, "can't get tty status: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't get tty status: %s", Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -2248,10 +2230,9 @@ SerialGetOptionProc(
if (valid) {
return TCL_OK;
- } else {
- return Tcl_BadChannelOption(interp, optionName,
- "mode pollinterval lasterror queue sysbuffer ttystatus xchar");
}
+ return Tcl_BadChannelOption(interp, optionName,
+ "mode pollinterval lasterror queue sysbuffer ttystatus xchar");
}
/*
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index 97b10a3..1a74354 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -72,7 +72,6 @@
#undef getservbyname
#undef getsockopt
-#undef ntohs
#undef setsockopt
/*
@@ -163,7 +162,7 @@ struct SocketInfo {
* socket event occurs.
*/
-typedef struct SocketEvent {
+typedef struct {
Tcl_Event header; /* Information that is standard for all
* events. */
SOCKET socket; /* Socket descriptor that is ready. Used to
@@ -191,7 +190,7 @@ typedef struct SocketEvent {
#define SOCKET_PENDING (1<<3) /* A message has been sent for this
* socket */
-typedef struct ThreadSpecificData {
+typedef struct {
HWND hwnd; /* Handle to window for socket messages. */
HANDLE socketThread; /* Thread handling the window */
Tcl_ThreadId threadId; /* Parent thread. */
@@ -220,7 +219,7 @@ static void SocketExitHandler(ClientData clientData);
static LRESULT CALLBACK SocketProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam);
static int SocketsEnabled(void);
-static void TcpAccept(TcpFdList *fds);
+static void TcpAccept(TcpFdList *fds, SOCKET newSocket, address addr);
static int WaitForSocketEvent(SocketInfo *infoPtr, int events,
int *errorCodePtr);
static DWORD WINAPI SocketThread(LPVOID arg);
@@ -558,8 +557,8 @@ TclpHasSockets(
return TCL_OK;
}
if (interp != NULL) {
- Tcl_AppendResult(interp, "sockets are not available on this system",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "sockets are not available on this system", -1));
}
return TCL_ERROR;
}
@@ -692,6 +691,9 @@ SocketEventProc(
int mask = 0, events;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
TcpFdList *fds;
+ SOCKET newSocket;
+ address addr;
+ int len;
if (!(flags & TCL_FILE_EVENTS)) {
return 0;
@@ -708,13 +710,13 @@ SocketEventProc(
break;
}
}
- SetEvent(tsdPtr->socketListLock);
/*
* Discard events that have gone stale.
*/
if (!infoPtr) {
+ SetEvent(tsdPtr->socketListLock);
return 1;
}
@@ -726,11 +728,65 @@ SocketEventProc(
if (infoPtr->readyEvents & FD_ACCEPT) {
for (fds = infoPtr->sockets; fds != NULL; fds = fds->next) {
- TcpAccept(fds);
+
+ /*
+ * Accept the incoming connection request.
+ */
+ len = sizeof(address);
+
+ newSocket = accept(fds->fd, &(addr.sa), &len);
+
+ /* On Tcl server sockets with multiple OS fds we loop over the fds trying
+ * an accept() on each, so we expect INVALID_SOCKET. There are also other
+ * network stack conditions that can result in FD_ACCEPT but a subsequent
+ * failure on accept() by the time we get around to it.
+ * Access to sockets (acceptEventCount, readyEvents) in socketList
+ * is still protected by the lock (prevents reintroduction of
+ * SF Tcl Bug 3056775.
+ */
+
+ if (newSocket == INVALID_SOCKET) {
+ /* int err = WSAGetLastError(); */
+ continue;
+ }
+
+ /*
+ * It is possible that more than one FD_ACCEPT has been sent, so an extra
+ * count must be kept. Decrement the count, and reset the readyEvent bit
+ * if the count is no longer > 0.
+ */
+ infoPtr->acceptEventCount--;
+
+ if (infoPtr->acceptEventCount <= 0) {
+ infoPtr->readyEvents &= ~(FD_ACCEPT);
+ }
+
+ SetEvent(tsdPtr->socketListLock);
+
+ /* Caution: TcpAccept() has the side-effect of evaluating the server
+ * accept script (via AcceptCallbackProc() in tclIOCmd.c), which can
+ * close the server socket and invalidate infoPtr and fds.
+ * If TcpAccept() accepts a socket we must return immediately and let
+ * SocketCheckProc queue additional FD_ACCEPT events.
+ */
+ TcpAccept(fds, newSocket, addr);
+ return 1;
}
+
+ /* Loop terminated with no sockets accepted; clear the ready mask so
+ * we can detect the next connection request. Note that connection
+ * requests are level triggered, so if there is a request already
+ * pending, a new event will be generated.
+ */
+ infoPtr->acceptEventCount = 0;
+ infoPtr->readyEvents &= ~(FD_ACCEPT);
+
+ SetEvent(tsdPtr->socketListLock);
return 1;
}
+ SetEvent(tsdPtr->socketListLock);
+
/*
* Mask off unwanted events and compute the read/write mask so we can
* notify the channel.
@@ -872,9 +928,15 @@ TcpCloseProc(
* background.
*/
- if (closesocket(infoPtr->sockets->fd) == SOCKET_ERROR) {
- TclWinConvertError((DWORD) WSAGetLastError());
- errorCode = Tcl_GetErrno();
+ while ( infoPtr->sockets != NULL ) {
+ TcpFdList *thisfd = infoPtr->sockets;
+ infoPtr->sockets = thisfd->next;
+
+ if (closesocket(thisfd->fd) == SOCKET_ERROR) {
+ TclWinConvertError((DWORD) WSAGetLastError());
+ errorCode = Tcl_GetErrno();
+ }
+ ckfree(thisfd);
}
}
@@ -928,12 +990,14 @@ TcpClose2Proc(
break;
default:
if (interp) {
- Tcl_AppendResult(interp,
- "Socket close2proc called bidirectionally", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "Socket close2proc called bidirectionally", -1));
}
return TCL_ERROR;
}
+ /* single fd operation: Tcl_OpenTcpServer() does not set TCL_READABLE or
+ * TCL_WRITABLE so this should never be called for a server socket. */
if (shutdown(infoPtr->sockets->fd, sd) == SOCKET_ERROR) {
TclWinConvertError((DWORD) WSAGetLastError());
errorCode = Tcl_GetErrno();
@@ -945,6 +1009,51 @@ TcpClose2Proc(
/*
*----------------------------------------------------------------------
*
+ * AddSocketInfoFd --
+ *
+ * This function adds a SOCKET file descriptor to the 'sockets' linked
+ * list of a SocketInfo structure.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None, except for allocation of memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AddSocketInfoFd(
+ SocketInfo *infoPtr,
+ SOCKET socket)
+{
+ TcpFdList *fds = infoPtr->sockets;
+
+ if ( fds == NULL ) {
+ /* Add the first FD */
+ infoPtr->sockets = ckalloc(sizeof(TcpFdList));
+ fds = infoPtr->sockets;
+ } else {
+ /* Find end of list and append FD */
+ while ( fds->next != NULL ) {
+ fds = fds->next;
+ }
+
+ fds->next = ckalloc(sizeof(TcpFdList));
+ fds = fds->next;
+ }
+
+ /* Populate new FD */
+ fds->fd = socket;
+ fds->infoPtr = infoPtr;
+ fds->next = NULL;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
* NewSocketInfo --
*
* This function allocates and initializes a new SocketInfo structure.
@@ -963,14 +1072,10 @@ NewSocketInfo(
SOCKET socket)
{
SocketInfo *infoPtr = ckalloc(sizeof(SocketInfo));
- TcpFdList *fds = ckalloc(sizeof(TcpFdList));
- fds->fd = socket;
- fds->next = NULL;
- fds->infoPtr = infoPtr;
/* ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); */
infoPtr->channel = 0;
- infoPtr->sockets = fds;
+ infoPtr->sockets = NULL;
infoPtr->flags = 0;
infoPtr->watchEvents = 0;
infoPtr->readyEvents = 0;
@@ -988,6 +1093,8 @@ NewSocketInfo(
infoPtr->nextPtr = NULL;
+ AddSocketInfoFd(infoPtr, socket);
+
return infoPtr;
}
@@ -1057,7 +1164,6 @@ CreateSocket(
}
if (server) {
- TcpFdList *fds = NULL, *newfds;
for (addrPtr = addrlist; addrPtr != NULL; addrPtr = addrPtr->ai_next) {
sock = socket(addrPtr->ai_family, SOCK_STREAM, 0);
@@ -1140,7 +1246,6 @@ CreateSocket(
*/
infoPtr = NewSocketInfo(sock);
- fds = infoPtr->sockets;
/*
* Set up the select mask for connection request events.
@@ -1150,13 +1255,7 @@ CreateSocket(
infoPtr->watchEvents |= FD_ACCEPT;
} else {
- newfds = ckalloc(sizeof(TcpFdList));
- memset(newfds, (int) 0, sizeof(TcpFdList));
- newfds->fd = sock;
- newfds->infoPtr = infoPtr;
- newfds->next = NULL;
- fds->next = newfds;
- fds = newfds;
+ AddSocketInfoFd( infoPtr, sock );
}
}
} else {
@@ -1280,12 +1379,9 @@ CreateSocket(
}
if (interp != NULL) {
- Tcl_AppendResult(interp, "couldn't open socket: ", NULL);
- if (errorMsg == NULL) {
- Tcl_AppendResult(interp, Tcl_PosixError(interp), NULL);
- } else {
- Tcl_AppendResult(interp, errorMsg, NULL);
- }
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't open socket: %s",
+ (errorMsg ? errorMsg : Tcl_PosixError(interp))));
}
if (sock != INVALID_SOCKET) {
@@ -1537,8 +1633,9 @@ Tcl_OpenTcpServer(
*
* TcpAccept --
*
- * Accept a TCP socket connection. This is called by SocketEventProc and
- * it in turns calls the registered accept function.
+ * Creates a channel for a newly accepted socket connection. This is
+ * called by SocketEventProc and it in turns calls the registered
+ * accept function.
*
* Results:
* None.
@@ -1551,60 +1648,18 @@ Tcl_OpenTcpServer(
static void
TcpAccept(
- TcpFdList *fds) /* Socket to accept. */
+ TcpFdList *fds, /* Server socket that accepted newSocket. */
+ SOCKET newSocket, /* Newly accepted socket. */
+ address addr) /* Address of new socket. */
{
- SOCKET newSocket;
SocketInfo *newInfoPtr;
SocketInfo *infoPtr = fds->infoPtr;
- SOCKADDR_IN addr;
- int len;
+ int len = sizeof(addr);
char channelName[16 + TCL_INTEGER_SPACE];
+ char host[NI_MAXHOST], port[NI_MAXSERV];
ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
/*
- * Accept the incoming connection request.
- */
-
- len = sizeof(SOCKADDR_IN);
-
- newSocket = accept(fds->fd, (SOCKADDR *) &addr, &len);
-
- /*
- * Protect access to sockets (acceptEventCount, readyEvents) in socketList
- * by the lock. Fix for SF Tcl Bug 3056775.
- */
-
- WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
-
- /*
- * Clear the ready mask so we can detect the next connection request. Note
- * that connection requests are level triggered, so if there is a request
- * already pending, a new event will be generated.
- */
-
- if (newSocket == INVALID_SOCKET) {
- infoPtr->acceptEventCount = 0;
- infoPtr->readyEvents &= ~(FD_ACCEPT);
-
- SetEvent(tsdPtr->socketListLock);
- return;
- }
-
- /*
- * It is possible that more than one FD_ACCEPT has been sent, so an extra
- * count must be kept. Decrement the count, and reset the readyEvent bit
- * if the count is no longer > 0.
- */
-
- infoPtr->acceptEventCount--;
-
- if (infoPtr->acceptEventCount <= 0) {
- infoPtr->readyEvents &= ~(FD_ACCEPT);
- }
-
- SetEvent(tsdPtr->socketListLock);
-
- /*
* Win-NT has a misfeature that sockets are inherited in child processes
* by default. Turn off the inherit bit.
*/
@@ -1644,8 +1699,10 @@ TcpAccept(
*/
if (infoPtr->acceptProc != NULL) {
+ getnameinfo(&(addr.sa), len, host, sizeof(host), port, sizeof(port),
+ NI_NUMERICHOST|NI_NUMERICSERV);
infoPtr->acceptProc(infoPtr->acceptProcData, newInfoPtr->channel,
- inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+ host, atoi(port));
}
}
@@ -1720,6 +1777,7 @@ TcpInputProc(
while (1) {
SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
(WPARAM) UNSELECT, (LPARAM) infoPtr);
+ /* single fd operation: this proc is only called for a connected socket. */
bytesRead = recv(infoPtr->sockets->fd, buf, toRead, 0);
infoPtr->readyEvents &= ~(FD_READ);
@@ -1840,6 +1898,7 @@ TcpOutputProc(
SendMessage(tsdPtr->hwnd, SOCKET_SELECT,
(WPARAM) UNSELECT, (LPARAM) infoPtr);
+ /* single fd operation: this proc is only called for a connected socket. */
bytesWritten = send(infoPtr->sockets->fd, buf, toWrite, 0);
if (bytesWritten != SOCKET_ERROR) {
/*
@@ -1929,12 +1988,14 @@ TcpSetOptionProc(
if (!SocketsEnabled()) {
if (interp) {
- Tcl_AppendResult(interp, "winsock is not initialized", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "winsock is not initialized", -1));
}
return TCL_ERROR;
}
#ifdef TCL_FEATURE_KEEPALIVE_NAGLE
+ #error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat infoPtr->sockets as single fd or list"
sock = infoPtr->sockets->fd;
if (!strcasecmp(optionName, "-keepalive")) {
@@ -1952,8 +2013,9 @@ TcpSetOptionProc(
if (rtn != 0) {
TclWinConvertError(WSAGetLastError());
if (interp) {
- Tcl_AppendResult(interp, "couldn't set socket option: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't set socket option: %s",
+ Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -1973,8 +2035,9 @@ TcpSetOptionProc(
if (rtn != 0) {
TclWinConvertError(WSAGetLastError());
if (interp) {
- Tcl_AppendResult(interp, "couldn't set socket option: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "couldn't set socket option: %s",
+ Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -2032,7 +2095,8 @@ TcpGetOptionProc(
if (!SocketsEnabled()) {
if (interp) {
- Tcl_AppendResult(interp, "winsock is not initialized", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "winsock is not initialized", -1));
}
return TCL_ERROR;
}
@@ -2099,8 +2163,9 @@ TcpGetOptionProc(
if (len) {
TclWinConvertError((DWORD) WSAGetLastError());
if (interp) {
- Tcl_AppendResult(interp, "can't get peername: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't get peername: %s",
+ Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -2164,8 +2229,8 @@ TcpGetOptionProc(
} else {
if (interp) {
TclWinConvertError((DWORD) WSAGetLastError());
- Tcl_AppendResult(interp, "can't get sockname: ",
- Tcl_PosixError(interp), NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't get sockname: %s", Tcl_PosixError(interp)));
}
return TCL_ERROR;
}
@@ -2398,6 +2463,7 @@ SocketProc(
int event, error;
SOCKET socket;
SocketInfo *infoPtr;
+ TcpFdList *fds = NULL;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
#ifdef _WIN64
GetWindowLongPtr(hwnd, GWLP_USERDATA);
@@ -2442,58 +2508,60 @@ SocketProc(
WaitForSingleObject(tsdPtr->socketListLock, INFINITE);
for (infoPtr = tsdPtr->socketList; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
- if (infoPtr->sockets->fd == socket) {
- /*
- * Update the socket state.
- *
- * A count of FD_ACCEPTS is stored, so if an FD_CLOSE event
- * happens, then clear the FD_ACCEPT count. Otherwise,
- * increment the count if the current event is an FD_ACCEPT.
- */
-
- if (event & FD_CLOSE) {
- infoPtr->acceptEventCount = 0;
- infoPtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT);
- } else if (event & FD_ACCEPT) {
- infoPtr->acceptEventCount++;
- }
-
- if (event & FD_CONNECT) {
+ for (fds = infoPtr->sockets; fds != NULL; fds = fds->next) {
+ if (fds->fd == socket) {
/*
- * The socket is now connected, clear the async connect
- * flag.
+ * Update the socket state.
+ *
+ * A count of FD_ACCEPTS is stored, so if an FD_CLOSE event
+ * happens, then clear the FD_ACCEPT count. Otherwise,
+ * increment the count if the current event is an FD_ACCEPT.
*/
- infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
+ if (event & FD_CLOSE) {
+ infoPtr->acceptEventCount = 0;
+ infoPtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT);
+ } else if (event & FD_ACCEPT) {
+ infoPtr->acceptEventCount++;
+ }
+
+ if (event & FD_CONNECT) {
+ /*
+ * The socket is now connected, clear the async connect
+ * flag.
+ */
- /*
- * Remember any error that occurred so we can report
- * connection failures.
- */
+ infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
+
+ /*
+ * Remember any error that occurred so we can report
+ * connection failures.
+ */
- if (error != ERROR_SUCCESS) {
- TclWinConvertError((DWORD) error);
- infoPtr->lastError = Tcl_GetErrno();
+ if (error != ERROR_SUCCESS) {
+ TclWinConvertError((DWORD) error);
+ infoPtr->lastError = Tcl_GetErrno();
+ }
}
- }
- if (infoPtr->flags & SOCKET_ASYNC_CONNECT) {
- infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
- if (error != ERROR_SUCCESS) {
- TclWinConvertError((DWORD) error);
- infoPtr->lastError = Tcl_GetErrno();
+ if (infoPtr->flags & SOCKET_ASYNC_CONNECT) {
+ infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
+ if (error != ERROR_SUCCESS) {
+ TclWinConvertError((DWORD) error);
+ infoPtr->lastError = Tcl_GetErrno();
+ }
+ infoPtr->readyEvents |= FD_WRITE;
}
- infoPtr->readyEvents |= FD_WRITE;
- }
- infoPtr->readyEvents |= event;
+ infoPtr->readyEvents |= event;
- /*
- * Wake up the Main Thread.
- */
+ /*
+ * Wake up the Main Thread.
+ */
- SetEvent(tsdPtr->readyEvent);
- Tcl_ThreadAlert(tsdPtr->threadId);
- break;
+ SetEvent(tsdPtr->readyEvent);
+ Tcl_ThreadAlert(tsdPtr->threadId);
+ break;
+ }
}
}
SetEvent(tsdPtr->socketListLock);
@@ -2501,15 +2569,18 @@ SocketProc(
case SOCKET_SELECT:
infoPtr = (SocketInfo *) lParam;
- if (wParam == SELECT) {
- WSAAsyncSelect(infoPtr->sockets->fd, hwnd,
- SOCKET_MESSAGE, infoPtr->selectEvents);
- } else {
- /*
- * Clear the selection mask
- */
+ for (fds = infoPtr->sockets; fds != NULL; fds = fds->next) {
+ infoPtr = (SocketInfo *) lParam;
+ if (wParam == SELECT) {
+ WSAAsyncSelect(fds->fd, hwnd,
+ SOCKET_MESSAGE, infoPtr->selectEvents);
+ } else {
+ /*
+ * Clear the selection mask
+ */
- WSAAsyncSelect(infoPtr->sockets->fd, hwnd, 0, 0);
+ WSAAsyncSelect(fds->fd, hwnd, 0, 0);
+ }
}
break;
@@ -2664,23 +2735,6 @@ TclWinSetSockOpt(
return setsockopt(s, level, optname, optval, optlen);
}
-unsigned short
-TclWinNToHS(
- unsigned short netshort)
-{
- /*
- * Check that WinSock is initialized; do not call it if not, to prevent
- * system crashes. This can happen at exit time if the exit handler for
- * WinSock ran before other exit handlers that want to use sockets.
- */
-
- if (!SocketsEnabled()) {
- return (unsigned short) -1;
- }
-
- return ntohs(netshort);
-}
-
char *
TclpInetNtoa(
struct in_addr addr)
diff --git a/win/tclooConfig.sh b/win/tclooConfig.sh
index 68de106..dce540a 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=-DUSE_TCLOO_STUBS
-TCLOO_VERSION=0.6.3
+TCLOO_VERSION=0.7