summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authorKevin B Kenny <kennykb@acm.org>2005-05-10 18:33:37 (GMT)
committerKevin B Kenny <kennykb@acm.org>2005-05-10 18:33:37 (GMT)
commit76e3b5eed61a674bce7f9c1e18380842dcff3fbf (patch)
tree2f108341f2c542f48532e6057d79bfa551a4245f /win
parent5b510b75ec4a1d6fb55691bcf55dbf4b0b936624 (diff)
downloadtcl-76e3b5eed61a674bce7f9c1e18380842dcff3fbf.zip
tcl-76e3b5eed61a674bce7f9c1e18380842dcff3fbf.tar.gz
tcl-76e3b5eed61a674bce7f9c1e18380842dcff3fbf.tar.bz2
Merged kennykb-numerics-branch back to the head; TIPs 132 and 232
Diffstat (limited to 'win')
-rw-r--r--win/Makefile.in78
-rw-r--r--win/README.binary2
-rw-r--r--win/configure.in2
-rw-r--r--win/makefile.vc64
-rw-r--r--win/rules.vc2
-rw-r--r--win/tclWin32Dll.c835
-rw-r--r--win/tclWinChan.c2
-rw-r--r--win/tclWinConsole.c2
-rw-r--r--win/tclWinFCmd.c2
-rw-r--r--win/tclWinFile.c2
-rw-r--r--win/tclWinInit.c2
-rw-r--r--win/tclWinNotify.c2
-rw-r--r--win/tclWinPipe.c2
-rw-r--r--win/tclWinSerial.c2
-rw-r--r--win/tclWinSock.c2
-rw-r--r--win/tclWinThrd.c2
-rw-r--r--win/tclWinTime.c2
17 files changed, 535 insertions, 470 deletions
diff --git a/win/Makefile.in b/win/Makefile.in
index ca7b0c2..753681b 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -5,7 +5,7 @@
# "autoconf" program (constructs like "@foo@" will get replaced in the
# actual Makefile.
#
-# RCS: @(#) $Id: Makefile.in,v 1.88 2005/02/24 18:05:43 dgp Exp $
+# RCS: @(#) $Id: Makefile.in,v 1.89 2005/05/10 18:35:29 kennykb Exp $
VERSION = @TCL_VERSION@
@@ -102,6 +102,7 @@ MAN2TCLFLAGS = @MAN2TCLFLAGS@
SRC_DIR = @srcdir@
ROOT_DIR = @srcdir@/..
GENERIC_DIR = @srcdir@/../generic
+TOMMATH_DIR = @srcdir@/../libtommath
WIN_DIR = @srcdir@
COMPAT_DIR = @srcdir@/../compat
@@ -109,6 +110,7 @@ COMPAT_DIR = @srcdir@/../compat
CYGPATH = @CYGPATH@
GENERIC_DIR_NATIVE = $(shell $(CYGPATH) '$(GENERIC_DIR)')
+TOMMATH_DIR_NATIVE = $(shell $(CYGPATH) '$(TOMMATH_DIR)')
WIN_DIR_NATIVE = $(shell $(CYGPATH) '$(WIN_DIR)')
ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)' | sed 's/\\*$$//' )
@@ -156,7 +158,7 @@ MAN2TCL = man2tcl$(EXEEXT)
# makefile to look into these paths when resolving .c to .obj
# dependencies.
-VPATH = $(GENERIC_DIR):$(WIN_DIR):$(COMPAT_DIR)
+VPATH = $(GENERIC_DIR):$(TOMMATH_DIR):$(WIN_DIR):$(COMPAT_DIR)
AR = @AR@
RANLIB = @RANLIB@
@@ -186,14 +188,16 @@ RM = rm -f
COPY = cp
CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} \
--I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \
+-I"${GENERIC_DIR_NATIVE}" -DTCL_TOMMATH -I"${TOMMATH_DIR_NATIVE}" \
+-I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \
${COMPILE_DEBUG_FLAGS}
CC_OBJNAME = @CC_OBJNAME@
CC_EXENAME = @CC_EXENAME@
STUB_CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \
--I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \
+-I"${GENERIC_DIR_NATIVE}" -DTCL_TOMMATH -I"${TOMMATH_DIR_NATIVE}" \
+-I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \
${COMPILE_DEBUG_FLAGS}
TCLTEST_OBJS = \
@@ -263,6 +267,7 @@ GENERIC_OBJS = \
tclResult.$(OBJEXT) \
tclScan.$(OBJEXT) \
tclStringObj.$(OBJEXT) \
+ tclStrToD.$(OBJEXT) \
tclStubInit.$(OBJEXT) \
tclStubLib.$(OBJEXT) \
tclThread.$(OBJEXT) \
@@ -270,11 +275,65 @@ GENERIC_OBJS = \
tclThreadJoin.$(OBJEXT) \
tclThreadStorage.$(OBJEXT) \
tclTimer.$(OBJEXT) \
+ tclTomMathInterface.$(OBJEXT) \
tclTrace.$(OBJEXT) \
tclUtf.$(OBJEXT) \
tclUtil.$(OBJEXT) \
tclVar.$(OBJEXT)
+TOMMATH_OBJS = \
+ bncore.${OBJEXT} \
+ bn_reverse.${OBJEXT} \
+ bn_fast_s_mp_mul_digs.${OBJEXT} \
+ bn_fast_s_mp_sqr.${OBJEXT} \
+ bn_mp_add.${OBJEXT} \
+ bn_mp_add_d.${OBJEXT} \
+ bn_mp_clamp.${OBJEXT} \
+ bn_mp_clear.${OBJEXT} \
+ bn_mp_clear_multi.${OBJEXT} \
+ bn_mp_cmp.${OBJEXT} \
+ bn_mp_cmp_mag.${OBJEXT} \
+ bn_mp_copy.${OBJEXT} \
+ bn_mp_count_bits.${OBJEXT} \
+ bn_mp_div.${OBJEXT} \
+ bn_mp_div_d.${OBJEXT} \
+ bn_mp_div_2.${OBJEXT} \
+ bn_mp_div_2d.${OBJEXT} \
+ bn_mp_div_3.${OBJEXT} \
+ bn_mp_exch.${OBJEXT} \
+ bn_mp_grow.${OBJEXT} \
+ bn_mp_init.${OBJEXT} \
+ bn_mp_init_copy.${OBJEXT} \
+ bn_mp_init_multi.${OBJEXT} \
+ bn_mp_init_set.${OBJEXT} \
+ bn_mp_init_size.${OBJEXT} \
+ bn_mp_karatsuba_mul.${OBJEXT} \
+ bn_mp_karatsuba_sqr.$(OBJEXT) \
+ bn_mp_lshd.${OBJEXT} \
+ bn_mp_mod.${OBJEXT} \
+ bn_mp_mod_2d.${OBJEXT} \
+ bn_mp_mul.${OBJEXT} \
+ bn_mp_mul_2.${OBJEXT} \
+ bn_mp_mul_2d.${OBJEXT} \
+ bn_mp_mul_d.${OBJEXT} \
+ bn_mp_radix_size.${OBJEXT} \
+ bn_mp_radix_smap.${OBJEXT} \
+ bn_mp_read_radix.${OBJEXT} \
+ bn_mp_rshd.${OBJEXT} \
+ bn_mp_set.${OBJEXT} \
+ bn_mp_sqr.${OBJEXT} \
+ bn_mp_sub.${OBJEXT} \
+ bn_mp_sub_d.${OBJEXT} \
+ bn_mp_toom_mul.${OBJEXT} \
+ bn_mp_toom_sqr.${OBJEXT} \
+ bn_mp_toradix_n.${OBJEXT} \
+ bn_mp_zero.${OBJEXT} \
+ bn_s_mp_add.${OBJEXT} \
+ bn_s_mp_mul_digs.${OBJEXT} \
+ bn_s_mp_sqr.${OBJEXT} \
+ bn_s_mp_sub.${OBJEXT}
+
+
WIN_OBJS = \
tclWin32Dll.$(OBJEXT) \
tclWinChan.$(OBJEXT) \
@@ -304,7 +363,7 @@ STUB_OBJS = tclStubLib.$(OBJEXT)
TCLSH_OBJS = tclAppInit.$(OBJEXT)
-TCL_OBJS = ${GENERIC_OBJS} ${WIN_OBJS} ${COMPAT_OBJS}
+TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${COMPAT_OBJS}
TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n]
@@ -471,6 +530,15 @@ gendate:
--no-lines \
$(GENERIC_DIR)/tclGetDate.y
+# The following target generates the file generic/tommath.h.
+# It needs to be run (and the results checked) after updating
+# to a new release of libtommath.
+
+gentommath_h:
+ $(TCL_EXE) "$(ROOT_DIR_NATIVE)\tools\fix_tommath_h.tcl" \
+ "$(TOMMATH_DIR_NATIVE)\tommath.h" \
+ > "$(GENERIC_DIR_NATIVE)\tommath.h"
+
install: all install-binaries install-libraries install-doc
install-binaries: binaries
diff --git a/win/README.binary b/win/README.binary
index 16705d7..e1e8449 100644
--- a/win/README.binary
+++ b/win/README.binary
@@ -1,6 +1,6 @@
Tcl/Tk 8.5 for Windows, Binary Distribution
-RCS: @(#) $Id: README.binary,v 1.39 2004/12/10 23:00:32 dkf Exp $
+RCS: @(#) $Id: README.binary,v 1.40 2005/05/10 18:35:30 kennykb Exp $
1. Introduction
---------------
diff --git a/win/configure.in b/win/configure.in
index df8d707..3e9b6cc 100644
--- a/win/configure.in
+++ b/win/configure.in
@@ -3,7 +3,7 @@
# generate the file "configure", which is run during Tcl installation
# to configure the system for the local environment.
#
-# RCS: @(#) $Id: configure.in,v 1.82 2004/12/10 23:00:33 dkf Exp $
+# RCS: @(#) $Id: configure.in,v 1.83 2005/05/10 18:35:30 kennykb Exp $
AC_INIT(../generic/tcl.h)
AC_PREREQ(2.57)
diff --git a/win/makefile.vc b/win/makefile.vc
index b18d51e..fbcf4a1 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -12,7 +12,7 @@
# Copyright (c) 2001-2004 David Gravereaux.
#
#------------------------------------------------------------------------------
-# RCS: @(#) $Id: makefile.vc,v 1.136 2005/03/08 21:52:35 hobbs Exp $
+# RCS: @(#) $Id: makefile.vc,v 1.137 2005/05/10 18:35:30 kennykb Exp $
#------------------------------------------------------------------------------
# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
@@ -307,6 +307,7 @@ TCLOBJS = \
$(TMP_DIR)\tclResult.obj \
$(TMP_DIR)\tclScan.obj \
$(TMP_DIR)\tclStringObj.obj \
+ $(TMP_DIR)\tclStrToD.obj \
$(TMP_DIR)\tclStubInit.obj \
$(TMP_DIR)\tclStubLib.obj \
$(TMP_DIR)\tclThread.obj \
@@ -314,6 +315,7 @@ TCLOBJS = \
$(TMP_DIR)\tclThreadJoin.obj \
$(TMP_DIR)\tclThreadStorage.obj \
$(TMP_DIR)\tclTimer.obj \
+ $(TMP_DIR)\tclTomMathInterface.obj \
$(TMP_DIR)\tclTrace.obj \
$(TMP_DIR)\tclUtf.obj \
$(TMP_DIR)\tclUtil.obj \
@@ -332,6 +334,56 @@ TCLOBJS = \
$(TMP_DIR)\tclWinSock.obj \
$(TMP_DIR)\tclWinThrd.obj \
$(TMP_DIR)\tclWinTime.obj \
+ $(TMP_DIR)\bncore.obj \
+ $(TMP_DIR)\bn_reverse.obj \
+ $(TMP_DIR)\bn_fast_s_mp_mul_digs.obj \
+ $(TMP_DIR)\bn_fast_s_mp_sqr.obj \
+ $(TMP_DIR)\bn_mp_add.obj \
+ $(TMP_DIR)\bn_mp_add_d.obj \
+ $(TMP_DIR)\bn_mp_clamp.obj \
+ $(TMP_DIR)\bn_mp_clear.obj \
+ $(TMP_DIR)\bn_mp_clear_multi.obj \
+ $(TMP_DIR)\bn_mp_cmp.obj \
+ $(TMP_DIR)\bn_mp_cmp_mag.obj \
+ $(TMP_DIR)\bn_mp_copy.obj \
+ $(TMP_DIR)\bn_mp_count_bits.obj \
+ $(TMP_DIR)\bn_mp_div.obj \
+ $(TMP_DIR)\bn_mp_div_d.obj \
+ $(TMP_DIR)\bn_mp_div_2.obj \
+ $(TMP_DIR)\bn_mp_div_2d.obj \
+ $(TMP_DIR)\bn_mp_div_3.obj \
+ $(TMP_DIR)\bn_mp_exch.obj \
+ $(TMP_DIR)\bn_mp_grow.obj \
+ $(TMP_DIR)\bn_mp_init.obj \
+ $(TMP_DIR)\bn_mp_init_copy.obj \
+ $(TMP_DIR)\bn_mp_init_multi.obj \
+ $(TMP_DIR)\bn_mp_init_set.obj \
+ $(TMP_DIR)\bn_mp_init_size.obj \
+ $(TMP_DIR)\bn_mp_karatsuba_mul.obj \
+ $(TMP_DIR)\bn_mp_karatsuba_sqr.obj \
+ $(TMP_DIR)\bn_mp_lshd.obj \
+ $(TMP_DIR)\bn_mp_mod.obj \
+ $(TMP_DIR)\bn_mp_mod_2d.obj \
+ $(TMP_DIR)\bn_mp_mul.obj \
+ $(TMP_DIR)\bn_mp_mul_2.obj \
+ $(TMP_DIR)\bn_mp_mul_2d.obj \
+ $(TMP_DIR)\bn_mp_mul_d.obj \
+ $(TMP_DIR)\bn_mp_radix_size.obj \
+ $(TMP_DIR)\bn_mp_radix_smap.obj \
+ $(TMP_DIR)\bn_mp_read_radix.obj \
+ $(TMP_DIR)\bn_mp_rshd.obj \
+ $(TMP_DIR)\bn_mp_set.obj \
+ $(TMP_DIR)\bn_mp_sqr.obj \
+ $(TMP_DIR)\bn_mp_sub.obj \
+ $(TMP_DIR)\bn_mp_sub_d.obj \
+ $(TMP_DIR)\bn_mp_toom_mul.obj \
+ $(TMP_DIR)\bn_mp_toom_sqr.obj \
+ $(TMP_DIR)\bn_mp_toradix_n.obj \
+ $(TMP_DIR)\bn_mp_zero.obj \
+ $(TMP_DIR)\bn_s_mp_add.obj \
+ $(TMP_DIR)\bn_s_mp_mul_digs.obj \
+ $(TMP_DIR)\bn_s_mp_sqr.obj \
+ $(TMP_DIR)\bn_s_mp_sub.obj \
!if !$(STATIC_BUILD)
$(TMP_DIR)\tcl.res
!endif
@@ -342,6 +394,7 @@ TCLSTUBOBJS = $(TMP_DIR)\tclStubLib.obj
COMPATDIR = $(ROOT)\compat
DOCDIR = $(ROOT)\doc
GENERICDIR = $(ROOT)\generic
+TOMMATHDIR = $(ROOT)\libtommath
TOOLSDIR = $(ROOT)\tools
WINDIR = $(ROOT)\win
@@ -396,9 +449,9 @@ crt = -MT
!endif
!endif
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(TOMMATHDIR)"
BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(TCL_INCLUDES) \
- -DTCL_PIPE_DLL=\"$(TCLPIPEDLLNAME)\"
+ -DTCL_PIPE_DLL=\"$(TCLPIPEDLLNAME)\" -DTCL_TOMMATH
CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE
TCL_CFLAGS = $(BASE_CFLAGS) $(OPTDEFINES)
STUB_CFLAGS = $(cflags) $(cdebug) $(OPTDEFINES)
@@ -840,6 +893,11 @@ $(GENERICDIR)\regguts.h: $(GENERICDIR)\regcustom.h
$<
<<
+{$(TOMMATHDIR)}.c{$(TMP_DIR)}.obj::
+ $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
+$<
+<<
+
{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
$(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<<
$<
diff --git a/win/rules.vc b/win/rules.vc
index 411a192..d9b498f 100644
--- a/win/rules.vc
+++ b/win/rules.vc
@@ -10,7 +10,7 @@
# Copyright (c) 2001-2003 David Gravereaux.
#
#------------------------------------------------------------------------------
-# RCS: @(#) $Id: rules.vc,v 1.19 2004/06/24 01:29:07 mistachkin Exp $
+# RCS: @(#) $Id: rules.vc,v 1.20 2005/05/10 18:35:36 kennykb Exp $
#------------------------------------------------------------------------------
!ifndef _RULES_VC
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c
index 59746d2..8303af5 100644
--- a/win/tclWin32Dll.c
+++ b/win/tclWin32Dll.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWin32Dll.c,v 1.40 2004/11/01 16:58:37 kennykb Exp $
+ * RCS: @(#) $Id: tclWin32Dll.c,v 1.41 2005/05/10 18:35:37 kennykb Exp $
*/
#include "tclWinInt.h"
@@ -57,26 +57,7 @@ _except_dllmain_detach_handler(
struct _CONTEXT *ContextRecord,
void *DispatcherContext);
-static
-__attribute__ ((cdecl))
-EXCEPTION_DISPOSITION
-_except_checkstackspace_handler(
- struct _EXCEPTION_RECORD *ExceptionRecord,
- void *EstablisherFrame,
- struct _CONTEXT *ContextRecord,
- void *DispatcherContext);
-
-static
-__attribute__((cdecl))
-EXCEPTION_DISPOSITION
-_except_TclWinCPUID_detach_handler(
- struct _EXCEPTION_RECORD *ExceptionRecord,
- void *EstablisherFrame,
- struct _CONTEXT *ContextRecord,
- void *DispatcherContext);
-
-#endif /* HAVE_NO_SEH */
-
+#endif
/*
* VC++ 5.x has no 'cpuid' assembler instruction, so we
@@ -327,7 +308,7 @@ DllMain(hInst, reason, reserved)
"pushl %%ebp" "\n\t"
"pushl %0" "\n\t"
"pushl %%fs:0" "\n\t"
- "movl %%esp, %%fs:0"
+ "movl %%esp, %%fs:0" "\n\t"
:
: "r" (_except_dllmain_detach_handler) );
#else
@@ -549,6 +530,7 @@ TclWinNoBackslash(
int
TclpCheckStackSpace()
{
+
int retval = 0;
/*
@@ -559,123 +541,103 @@ TclpCheckStackSpace()
*/
#ifdef HAVE_NO_SEH
-# ifdef TCL_MEM_DEBUG
__asm__ __volatile__ (
- "movl %%esp, %0" "\n\t"
- "movl %%ebp, %1" "\n\t"
- "movl %%fs:0, %2" "\n\t"
- : "=m"(INITIAL_ESP),
- "=m"(INITIAL_EBP),
- "=r"(INITIAL_HANDLER) );
-# endif /* TCL_MEM_DEBUG */
- __asm__ __volatile__ (
- "pushl %%ebp" "\n\t"
- "pushl %0" "\n\t"
- "pushl %%fs:0" "\n\t"
- "movl %%esp, %%fs:0"
- :
- : "r" (_except_checkstackspace_handler) );
-#else
+ /*
+ * Build an EXCEPTION_REGISTRATION structure on the stack, and
+ * stack it on the list of EXCEPTION_REGISTRATIONs
+ * anchored at the thread information block.
+ * Put the saved EBP at 0x8 and the address of the status
+ * return at 0xc.
+ */
+
+ "leal %[stat], %%edx" "\n\t"
+ "pushl %%edx" "\n\t"
+ "pushl %%ebp" "\n\t"
+ "leal 1f, %%edx" "\n\t"
+ "pushl %%edx" "\n\t"
+ "pushl %%fs:0" "\n\t"
+ "movl %%esp, %%fs:0" "\n\t"
+
+ /*
+ * Attempt a call to _alloca, to determine whether there's
+ * sufficient memory to be had.
+ */
+
+ "movl %[size], %%eax" "\n\t"
+ "pushl %%eax" "\n\t"
+ "call __alloca" "\n\t"
+
+ /*
+ * If 'alloca' succeeds, pull back the address of the
+ * EXCEPTION_REGISTRATION and put a 1 in EAX for status.
+ */
+
+ "movl $1, %%eax" "\n\t"
+ "movl %%fs:0, %%esp" "\n\t"
+ "jmp 2f" "\n"
+
+ /*
+ * Come here on an exception. Retrieve the EXCEPTION_REGISTRATION
+ * from the link in the runtime library's EXCEPTION_REGISTRATION,
+ * and put a 0 in EAX to indicate failure.
+ */
+
+ "1:" "\t"
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl $0, %%eax" "\n\t"
+ "movl 0x8(%%edx), %%esp" "\n"
+
+ /*
+ * Come here whether or not an exception occurred. The stack
+ * pointer points to the EXCEPTION_REGISTRATION, and EAX contains
+ * status. Unstack the EXCEPTION_REGISTRATION and clean up
+ * the stack.
+ */
+
+ "2:" "\t"
+ "pop %%fs:0" "\n\t"
+ "addl $4, %%esp" "\n\t"
+ "pop %%ebp" "\n\t"
+ "pop %%edx" "\n\t"
+ "movl %%eax, 0x0(%%edx)" "\n\t"
+
+ : [stat]"=m"(retval)
+ : [size]"i"(TCL_WIN_STACK_THRESHOLD)
+ : "%eax","%ebx", "%ecx", "%edx", "%esi", "%edi", "memory" );
+
+#else /* !HAVE_NO_SEH */
__try {
-#endif /* HAVE_NO_SEH */
#ifdef HAVE_ALLOCA_GCC_INLINE
- __asm__ __volatile__ (
+ __asm__ __volatile__ (
"movl %0, %%eax" "\n\t"
"call __alloca" "\n\t"
:
: "i"(TCL_WIN_STACK_THRESHOLD)
: "%eax");
#else
- alloca(TCL_WIN_STACK_THRESHOLD);
+ alloca(TCL_WIN_STACK_THRESHOLD);
#endif /* HAVE_ALLOCA_GCC_INLINE */
- retval = 1;
-#ifdef HAVE_NO_SEH
- __asm__ __volatile__ (
- "movl %%fs:0, %%esp" "\n\t"
- "jmp checkstackspace_pop" "\n"
- "checkstackspace_reentry:" "\n\t"
- "movl %%fs:0, %%eax" "\n\t"
- "movl 0x8(%%eax), %%esp" "\n\t"
- "movl 0x8(%%esp), %%ebp" "\n"
- "checkstackspace_pop:" "\n\t"
- "movl (%%esp), %%eax" "\n\t"
- "movl %%eax, %%fs:0" "\n\t"
- "add $12, %%esp" "\n\t"
- :
- :
- : "%eax");
-
-# ifdef TCL_MEM_DEBUG
- __asm__ __volatile__ (
- "movl %%esp, %0" "\n\t"
- "movl %%ebp, %1" "\n\t"
- "movl %%fs:0, %2" "\n\t"
- : "=m"(RESTORED_ESP),
- "=m"(RESTORED_EBP),
- "=r"(RESTORED_HANDLER) );
-
- if (INITIAL_ESP != RESTORED_ESP)
- Tcl_Panic("ESP restored incorrectly");
- if (INITIAL_EBP != RESTORED_EBP)
- Tcl_Panic("EBP restored incorrectly");
- if (INITIAL_HANDLER != RESTORED_HANDLER)
- Tcl_Panic("HANDLER restored incorrectly");
-# endif /* TCL_MEM_DEBUG */
-#else
+ retval = 1;
} __except (EXCEPTION_EXECUTE_HANDLER) {}
#endif /* HAVE_NO_SEH */
-
- /*
- * Avoid using control flow statements in the SEH guarded block!
- */
+
return retval;
}
/*
*----------------------------------------------------------------------
*
- * _except_checkstackspace_handler --
- *
- * SEH exception handler for TclpCheckStackSpace.
- *
- * Results:
- * See TclpCheckStackSpace.
- *
- * Side effects:
- * See TclpCheckStackSpace.
- *
- *----------------------------------------------------------------------
- */
-#ifdef HAVE_NO_SEH
-static
-__attribute__ ((cdecl))
-EXCEPTION_DISPOSITION
-_except_checkstackspace_handler(
- struct _EXCEPTION_RECORD *ExceptionRecord,
- void *EstablisherFrame,
- struct _CONTEXT *ContextRecord,
- void *DispatcherContext)
-{
- __asm__ __volatile__ (
- "jmp checkstackspace_reentry");
- return 0; /* Function does not return */
-}
-#endif /* HAVE_NO_SEH */
-
-/*
- *----------------------------------------------------------------------
- *
* TclWinGetPlatform --
*
- * This is a kludge that allows the test library to get access
- * the internal tclPlatform variable.
+ * This is a kludge that allows the test library to get access
+ * the internal tclPlatform variable.
*
* Results:
- * Returns a pointer to the tclPlatform variable.
+ * Returns a pointer to the tclPlatform variable.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
@@ -691,123 +653,123 @@ TclWinGetPlatform()
*
* TclWinSetInterfaces --
*
- * A helper proc that allows the test library to change the
- * tclWinProcs structure to dispatch to either the wide-character
- * or multi-byte versions of the operating system calls, depending
- * on whether Unicode is the system encoding.
- *
- * As well as this, we can also try to load in some additional
- * procs which may/may not be present depending on the current
- * Windows version (e.g. Win95 will not have the procs below).
+ * A helper proc that allows the test library to change the
+ * tclWinProcs structure to dispatch to either the wide-character
+ * or multi-byte versions of the operating system calls, depending
+ * on whether Unicode is the system encoding.
+ *
+ * As well as this, we can also try to load in some additional
+ * procs which may/may not be present depending on the current
+ * Windows version (e.g. Win95 will not have the procs below).
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*---------------------------------------------------------------------------
*/
void
TclWinSetInterfaces(
- int wide) /* Non-zero to use wide interfaces, 0
- * otherwise. */
+ int wide) /* Non-zero to use wide interfaces, 0
+ * otherwise. */
{
Tcl_FreeEncoding(tclWinTCharEncoding);
if (wide) {
- tclWinProcs = &unicodeProcs;
- tclWinTCharEncoding = Tcl_GetEncoding(NULL, "unicode");
- if (tclWinProcs->getFileAttributesExProc == NULL) {
- HINSTANCE hInstance = LoadLibraryA("kernel32");
- if (hInstance != NULL) {
- tclWinProcs->getFileAttributesExProc =
- (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
- LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExW");
- tclWinProcs->createHardLinkProc =
- (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
- LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
- "CreateHardLinkW");
- tclWinProcs->findFirstFileExProc =
- (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
- LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
- "FindFirstFileExW");
- tclWinProcs->getVolumeNameForVMPProc =
- (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
- DWORD)) GetProcAddress(hInstance,
- "GetVolumeNameForVolumeMountPointW");
- tclWinProcs->getLongPathNameProc =
- (DWORD (WINAPI *)(CONST TCHAR*, TCHAR*,
- DWORD)) GetProcAddress(hInstance,
- "GetLongPathNameW");
- FreeLibrary(hInstance);
- }
- hInstance = LoadLibraryA("advapi32");
- if (hInstance != NULL) {
- tclWinProcs->getFileSecurityProc = (BOOL (WINAPI *)(
- LPCTSTR lpFileName,
- SECURITY_INFORMATION RequestedInformation,
- PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength,
- LPDWORD lpnLengthNeeded)) GetProcAddress(hInstance,
- "GetFileSecurityW");
- tclWinProcs->impersonateSelfProc = (BOOL (WINAPI *) (
- SECURITY_IMPERSONATION_LEVEL ImpersonationLevel))
- GetProcAddress(hInstance, "ImpersonateSelf");
- tclWinProcs->openThreadTokenProc = (BOOL (WINAPI *) (
- HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf,
- PHANDLE TokenHandle)) GetProcAddress(hInstance,
- "OpenThreadToken");
- tclWinProcs->revertToSelfProc = (BOOL (WINAPI *) (void))
- GetProcAddress(hInstance, "RevertToSelf");
- tclWinProcs->mapGenericMaskProc = (VOID (WINAPI *) (
- PDWORD AccessMask, PGENERIC_MAPPING GenericMapping))
- GetProcAddress(hInstance, "MapGenericMask");
- tclWinProcs->accessCheckProc = (BOOL (WINAPI *)(
- PSECURITY_DESCRIPTOR pSecurityDescriptor,
- HANDLE ClientToken, DWORD DesiredAccess,
- PGENERIC_MAPPING GenericMapping,
- PPRIVILEGE_SET PrivilegeSet,
- LPDWORD PrivilegeSetLength,
- LPDWORD GrantedAccess,
- LPBOOL AccessStatus)) GetProcAddress(hInstance,
- "AccessCheck");
- FreeLibrary(hInstance);
- }
- }
+ tclWinProcs = &unicodeProcs;
+ tclWinTCharEncoding = Tcl_GetEncoding(NULL, "unicode");
+ if (tclWinProcs->getFileAttributesExProc == NULL) {
+ HINSTANCE hInstance = LoadLibraryA("kernel32");
+ if (hInstance != NULL) {
+ tclWinProcs->getFileAttributesExProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
+ LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExW");
+ tclWinProcs->createHardLinkProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
+ LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
+ "CreateHardLinkW");
+ tclWinProcs->findFirstFileExProc =
+ (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
+ LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
+ "FindFirstFileExW");
+ tclWinProcs->getVolumeNameForVMPProc =
+ (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
+ DWORD)) GetProcAddress(hInstance,
+ "GetVolumeNameForVolumeMountPointW");
+ tclWinProcs->getLongPathNameProc =
+ (DWORD (WINAPI *)(CONST TCHAR*, TCHAR*,
+ DWORD)) GetProcAddress(hInstance,
+ "GetLongPathNameW");
+ FreeLibrary(hInstance);
+ }
+ hInstance = LoadLibraryA("advapi32");
+ if (hInstance != NULL) {
+ tclWinProcs->getFileSecurityProc = (BOOL (WINAPI *)(
+ LPCTSTR lpFileName,
+ SECURITY_INFORMATION RequestedInformation,
+ PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength,
+ LPDWORD lpnLengthNeeded)) GetProcAddress(hInstance,
+ "GetFileSecurityW");
+ tclWinProcs->impersonateSelfProc = (BOOL (WINAPI *) (
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel))
+ GetProcAddress(hInstance, "ImpersonateSelf");
+ tclWinProcs->openThreadTokenProc = (BOOL (WINAPI *) (
+ HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf,
+ PHANDLE TokenHandle)) GetProcAddress(hInstance,
+ "OpenThreadToken");
+ tclWinProcs->revertToSelfProc = (BOOL (WINAPI *) (void))
+ GetProcAddress(hInstance, "RevertToSelf");
+ tclWinProcs->mapGenericMaskProc = (VOID (WINAPI *) (
+ PDWORD AccessMask, PGENERIC_MAPPING GenericMapping))
+ GetProcAddress(hInstance, "MapGenericMask");
+ tclWinProcs->accessCheckProc = (BOOL (WINAPI *)(
+ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ HANDLE ClientToken, DWORD DesiredAccess,
+ PGENERIC_MAPPING GenericMapping,
+ PPRIVILEGE_SET PrivilegeSet,
+ LPDWORD PrivilegeSetLength,
+ LPDWORD GrantedAccess,
+ LPBOOL AccessStatus)) GetProcAddress(hInstance,
+ "AccessCheck");
+ FreeLibrary(hInstance);
+ }
+ }
} else {
- tclWinProcs = &asciiProcs;
- tclWinTCharEncoding = NULL;
- if (tclWinProcs->getFileAttributesExProc == NULL) {
- HINSTANCE hInstance = LoadLibraryA("kernel32");
- if (hInstance != NULL) {
- tclWinProcs->getFileAttributesExProc =
- (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
- LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExA");
- tclWinProcs->createHardLinkProc =
- (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
- LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
- "CreateHardLinkA");
- tclWinProcs->findFirstFileExProc = NULL;
- tclWinProcs->getLongPathNameProc = NULL;
- /*
- * The 'findFirstFileExProc' function exists on some
- * of 95/98/ME, but it seems not to work as anticipated.
- * Therefore we don't set this function pointer. The
- * relevant code will fall back on a slower approach
- * using the normal findFirstFileProc.
- *
- * (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
- * LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
- * "FindFirstFileExA");
- */
- tclWinProcs->getVolumeNameForVMPProc =
- (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
- DWORD)) GetProcAddress(hInstance,
- "GetVolumeNameForVolumeMountPointA");
- FreeLibrary(hInstance);
- }
- }
+ tclWinProcs = &asciiProcs;
+ tclWinTCharEncoding = NULL;
+ if (tclWinProcs->getFileAttributesExProc == NULL) {
+ HINSTANCE hInstance = LoadLibraryA("kernel32");
+ if (hInstance != NULL) {
+ tclWinProcs->getFileAttributesExProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, GET_FILEEX_INFO_LEVELS,
+ LPVOID)) GetProcAddress(hInstance, "GetFileAttributesExA");
+ tclWinProcs->createHardLinkProc =
+ (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR*,
+ LPSECURITY_ATTRIBUTES)) GetProcAddress(hInstance,
+ "CreateHardLinkA");
+ tclWinProcs->findFirstFileExProc = NULL;
+ tclWinProcs->getLongPathNameProc = NULL;
+ /*
+ * The 'findFirstFileExProc' function exists on some
+ * of 95/98/ME, but it seems not to work as anticipated.
+ * Therefore we don't set this function pointer. The
+ * relevant code will fall back on a slower approach
+ * using the normal findFirstFileProc.
+ *
+ * (HANDLE (WINAPI *)(CONST TCHAR*, UINT,
+ * LPVOID, UINT, LPVOID, DWORD)) GetProcAddress(hInstance,
+ * "FindFirstFileExA");
+ */
+ tclWinProcs->getVolumeNameForVMPProc =
+ (BOOL (WINAPI *)(CONST TCHAR*, TCHAR*,
+ DWORD)) GetProcAddress(hInstance,
+ "GetVolumeNameForVolumeMountPointA");
+ FreeLibrary(hInstance);
+ }
+ }
}
}
@@ -816,9 +778,9 @@ TclWinSetInterfaces(
*
* TclWinResetInterfaceEncodings --
*
- * Called during finalization to free up any encodings we use.
- * The tclWinProcs-> look up table is still ok to use after
- * this call, provided no encoding conversion is required.
+ * Called during finalization to free up any encodings we use.
+ * The tclWinProcs-> look up table is still ok to use after
+ * this call, provided no encoding conversion is required.
*
* We also clean up any memory allocated in our mount point
* map which is used to follow certain kinds of symlinks.
@@ -826,10 +788,10 @@ TclWinSetInterfaces(
* down.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*---------------------------------------------------------------------------
*/
@@ -838,17 +800,17 @@ TclWinResetInterfaceEncodings()
{
MountPointMap *dlIter, *dlIter2;
if (tclWinTCharEncoding != NULL) {
- Tcl_FreeEncoding(tclWinTCharEncoding);
- tclWinTCharEncoding = NULL;
+ Tcl_FreeEncoding(tclWinTCharEncoding);
+ tclWinTCharEncoding = NULL;
}
/* Clean up the mount point map */
Tcl_MutexLock(&mountPointMap);
dlIter = driveLetterLookup;
while (dlIter != NULL) {
- dlIter2 = dlIter->nextPtr;
- ckfree((char*)dlIter->volumeName);
- ckfree((char*)dlIter);
- dlIter = dlIter2;
+ dlIter2 = dlIter->nextPtr;
+ ckfree((char*)dlIter->volumeName);
+ ckfree((char*)dlIter);
+ dlIter = dlIter2;
}
Tcl_MutexUnlock(&mountPointMap);
}
@@ -858,15 +820,15 @@ TclWinResetInterfaceEncodings()
*
* TclWinResetInterfaces --
*
- * Called during finalization to reset us to a safe state for reuse.
- * After this call, it is best not to use the tclWinProcs-> look
- * up table since it is likely to be different to what is expected.
+ * Called during finalization to reset us to a safe state for reuse.
+ * After this call, it is best not to use the tclWinProcs-> look
+ * up table since it is likely to be different to what is expected.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*---------------------------------------------------------------------------
*/
@@ -912,84 +874,84 @@ TclWinDriveLetterForVolMountPoint(CONST WCHAR *mountPoint)
Tcl_MutexLock(&mountPointMap);
dlIter = driveLetterLookup;
while (dlIter != NULL) {
- if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
- /*
- * We need to check whether this information is
- * still valid, since either the user or various
- * programs could have adjusted the mount points on
- * the fly.
- */
- drive[0] = L'A' + (dlIter->driveLetter - 'A');
- /* Try to read the volume mount point and see where it points */
- if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
- (TCHAR*)Target, 55) != 0) {
- if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
- /* Nothing has changed */
- Tcl_MutexUnlock(&mountPointMap);
- return dlIter->driveLetter;
- }
- }
- /*
- * If we reach here, unfortunately, this mount point is
- * no longer valid at all
- */
- if (driveLetterLookup == dlIter) {
- dlPtr2 = dlIter;
- driveLetterLookup = dlIter->nextPtr;
- } else {
- for (dlPtr2 = driveLetterLookup;
- dlPtr2 != NULL; dlPtr2 = dlPtr2->nextPtr) {
- if (dlPtr2->nextPtr == dlIter) {
- dlPtr2->nextPtr = dlIter->nextPtr;
- dlPtr2 = dlIter;
- break;
- }
- }
- }
- /* Now dlPtr2 points to the structure to free */
- ckfree((char*)dlPtr2->volumeName);
- ckfree((char*)dlPtr2);
- /*
- * Restart the loop --- we could try to be clever
- * and continue half way through, but the logic is a
- * bit messy, so it's cleanest just to restart
- */
- dlIter = driveLetterLookup;
- continue;
- }
- dlIter = dlIter->nextPtr;
+ if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
+ /*
+ * We need to check whether this information is
+ * still valid, since either the user or various
+ * programs could have adjusted the mount points on
+ * the fly.
+ */
+ drive[0] = L'A' + (dlIter->driveLetter - 'A');
+ /* Try to read the volume mount point and see where it points */
+ if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
+ (TCHAR*)Target, 55) != 0) {
+ if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
+ /* Nothing has changed */
+ Tcl_MutexUnlock(&mountPointMap);
+ return dlIter->driveLetter;
+ }
+ }
+ /*
+ * If we reach here, unfortunately, this mount point is
+ * no longer valid at all
+ */
+ if (driveLetterLookup == dlIter) {
+ dlPtr2 = dlIter;
+ driveLetterLookup = dlIter->nextPtr;
+ } else {
+ for (dlPtr2 = driveLetterLookup;
+ dlPtr2 != NULL; dlPtr2 = dlPtr2->nextPtr) {
+ if (dlPtr2->nextPtr == dlIter) {
+ dlPtr2->nextPtr = dlIter->nextPtr;
+ dlPtr2 = dlIter;
+ break;
+ }
+ }
+ }
+ /* Now dlPtr2 points to the structure to free */
+ ckfree((char*)dlPtr2->volumeName);
+ ckfree((char*)dlPtr2);
+ /*
+ * Restart the loop --- we could try to be clever
+ * and continue half way through, but the logic is a
+ * bit messy, so it's cleanest just to restart
+ */
+ dlIter = driveLetterLookup;
+ continue;
+ }
+ dlIter = dlIter->nextPtr;
}
/* We couldn't find it, so we must iterate over the letters */
for (drive[0] = L'A'; drive[0] <= L'Z'; drive[0]++) {
- /* Try to read the volume mount point and see where it points */
- if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
- (TCHAR*)Target, 55) != 0) {
- int alreadyStored = 0;
- for (dlIter = driveLetterLookup; dlIter != NULL;
- dlIter = dlIter->nextPtr) {
- if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
- alreadyStored = 1;
- break;
- }
- }
- if (!alreadyStored) {
- dlPtr2 = (MountPointMap*) ckalloc(sizeof(MountPointMap));
- dlPtr2->volumeName = TclNativeDupInternalRep(Target);
- dlPtr2->driveLetter = 'A' + (drive[0] - L'A');
- dlPtr2->nextPtr = driveLetterLookup;
- driveLetterLookup = dlPtr2;
- }
- }
+ /* Try to read the volume mount point and see where it points */
+ if ((*tclWinProcs->getVolumeNameForVMPProc)((TCHAR*)drive,
+ (TCHAR*)Target, 55) != 0) {
+ int alreadyStored = 0;
+ for (dlIter = driveLetterLookup; dlIter != NULL;
+ dlIter = dlIter->nextPtr) {
+ if (wcscmp((WCHAR*)dlIter->volumeName, Target) == 0) {
+ alreadyStored = 1;
+ break;
+ }
+ }
+ if (!alreadyStored) {
+ dlPtr2 = (MountPointMap*) ckalloc(sizeof(MountPointMap));
+ dlPtr2->volumeName = TclNativeDupInternalRep(Target);
+ dlPtr2->driveLetter = 'A' + (drive[0] - L'A');
+ dlPtr2->nextPtr = driveLetterLookup;
+ driveLetterLookup = dlPtr2;
+ }
+ }
}
/* Try again */
for (dlIter = driveLetterLookup; dlIter != NULL;
- dlIter = dlIter->nextPtr) {
- if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
- Tcl_MutexUnlock(&mountPointMap);
- return dlIter->driveLetter;
- }
+ dlIter = dlIter->nextPtr) {
+ if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
+ Tcl_MutexUnlock(&mountPointMap);
+ return dlIter->driveLetter;
+ }
}
/*
* The volume doesn't appear to correspond to a drive letter -- we
@@ -1010,78 +972,78 @@ TclWinDriveLetterForVolMountPoint(CONST WCHAR *mountPoint)
*
* Tcl_WinUtfToTChar, Tcl_WinTCharToUtf --
*
- * Convert between UTF-8 and Unicode when running Windows NT or
- * the current ANSI code page when running Windows 95.
- *
- * On Mac, Unix, and Windows 95, all strings exchanged between Tcl
- * and the OS are "char" oriented. We need only one Tcl_Encoding to
- * convert between UTF-8 and the system's native encoding. We use
- * NULL to represent that encoding.
- *
- * On NT, some strings exchanged between Tcl and the OS are "char"
- * oriented, while others are in Unicode. We need two Tcl_Encoding
- * APIs depending on whether we are targeting a "char" or Unicode
- * interface.
- *
- * Calling Tcl_UtfToExternal() or Tcl_ExternalToUtf() with an
- * encoding of NULL should always used to convert between UTF-8
- * and the system's "char" oriented encoding. The following two
- * functions are used in Windows-specific code to convert between
- * UTF-8 and Unicode strings (NT) or "char" strings(95). This saves
- * you the trouble of writing the following type of fragment over and
- * over:
- *
- * if (running NT) {
- * encoding <- Tcl_GetEncoding("unicode");
- * nativeBuffer <- UtfToExternal(encoding, utfBuffer);
- * Tcl_FreeEncoding(encoding);
- * } else {
- * nativeBuffer <- UtfToExternal(NULL, utfBuffer);
- * }
- *
- * By convention, in Windows a TCHAR is a character in the ANSI code
- * page on Windows 95, a Unicode character on Windows NT. If you
- * plan on targeting a Unicode interfaces when running on NT and a
- * "char" oriented interface while running on 95, these functions
- * should be used. If you plan on targetting the same "char"
- * oriented function on both 95 and NT, use Tcl_UtfToExternal()
- * with an encoding of NULL.
+ * Convert between UTF-8 and Unicode when running Windows NT or
+ * the current ANSI code page when running Windows 95.
+ *
+ * On Mac, Unix, and Windows 95, all strings exchanged between Tcl
+ * and the OS are "char" oriented. We need only one Tcl_Encoding to
+ * convert between UTF-8 and the system's native encoding. We use
+ * NULL to represent that encoding.
+ *
+ * On NT, some strings exchanged between Tcl and the OS are "char"
+ * oriented, while others are in Unicode. We need two Tcl_Encoding
+ * APIs depending on whether we are targeting a "char" or Unicode
+ * interface.
+ *
+ * Calling Tcl_UtfToExternal() or Tcl_ExternalToUtf() with an
+ * encoding of NULL should always used to convert between UTF-8
+ * and the system's "char" oriented encoding. The following two
+ * functions are used in Windows-specific code to convert between
+ * UTF-8 and Unicode strings (NT) or "char" strings(95). This saves
+ * you the trouble of writing the following type of fragment over and
+ * over:
+ *
+ * if (running NT) {
+ * encoding <- Tcl_GetEncoding("unicode");
+ * nativeBuffer <- UtfToExternal(encoding, utfBuffer);
+ * Tcl_FreeEncoding(encoding);
+ * } else {
+ * nativeBuffer <- UtfToExternal(NULL, utfBuffer);
+ * }
+ *
+ * By convention, in Windows a TCHAR is a character in the ANSI code
+ * page on Windows 95, a Unicode character on Windows NT. If you
+ * plan on targeting a Unicode interfaces when running on NT and a
+ * "char" oriented interface while running on 95, these functions
+ * should be used. If you plan on targetting the same "char"
+ * oriented function on both 95 and NT, use Tcl_UtfToExternal()
+ * with an encoding of NULL.
*
* Results:
- * The result is a pointer to the string in the desired target
- * encoding. Storage for the result string is allocated in
- * dsPtr; the caller must call Tcl_DStringFree() when the result
- * is no longer needed.
+ * The result is a pointer to the string in the desired target
+ * encoding. Storage for the result string is allocated in
+ * dsPtr; the caller must call Tcl_DStringFree() when the result
+ * is no longer needed.
*
* Side effects:
- * None.
+ * None.
*
*---------------------------------------------------------------------------
*/
TCHAR *
Tcl_WinUtfToTChar(string, len, dsPtr)
- CONST char *string; /* Source string in UTF-8. */
- int len; /* Source string length in bytes, or < 0 for
- * strlen(). */
- Tcl_DString *dsPtr; /* Uninitialized or free DString in which
- * the converted string is stored. */
+ CONST char *string; /* Source string in UTF-8. */
+ int len; /* Source string length in bytes, or < 0 for
+ * strlen(). */
+ Tcl_DString *dsPtr; /* Uninitialized or free DString in which
+ * the converted string is stored. */
{
return (TCHAR *) Tcl_UtfToExternalDString(tclWinTCharEncoding,
- string, len, dsPtr);
+ string, len, dsPtr);
}
char *
Tcl_WinTCharToUtf(string, len, dsPtr)
- CONST TCHAR *string; /* Source string in Unicode when running
- * NT, ANSI when running 95. */
- int len; /* Source string length in bytes, or < 0 for
- * platform-specific string length. */
- Tcl_DString *dsPtr; /* Uninitialized or free DString in which
- * the converted string is stored. */
+ CONST TCHAR *string; /* Source string in Unicode when running
+ * NT, ANSI when running 95. */
+ int len; /* Source string length in bytes, or < 0 for
+ * platform-specific string length. */
+ Tcl_DString *dsPtr; /* Uninitialized or free DString in which
+ * the converted string is stored. */
{
return Tcl_ExternalToUtfDString(tclWinTCharEncoding,
- (CONST char *) string, len, dsPtr);
+ (CONST char *) string, len, dsPtr);
}
/*
@@ -1089,14 +1051,14 @@ Tcl_WinTCharToUtf(string, len, dsPtr)
*
* TclWinCPUID --
*
- * Get CPU ID information on an Intel box under Windows
+ * Get CPU ID information on an Intel box under Windows
*
* Results:
- * Returns TCL_OK if successful, TCL_ERROR if CPUID is not
- * supported or fails.
+ * Returns TCL_OK if successful, TCL_ERROR if CPUID is not
+ * supported or fails.
*
* Side effects:
- * If successful, stores EAX, EBX, ECX and EDX registers after
+ * If successful, stores EAX, EBX, ECX and EDX registers after
* the CPUID instruction in the four integers designated by 'regsPtr'
*
*----------------------------------------------------------------------
@@ -1104,70 +1066,79 @@ Tcl_WinTCharToUtf(string, len, dsPtr)
int
TclWinCPUID( unsigned int index, /* Which CPUID value to retrieve */
- register unsigned int * regsPtr ) /* Registers after the CPUID */
+ unsigned int * regsPtr ) /* Registers after the CPUID */
{
int status = TCL_ERROR;
-#if defined(__GNUC__)
-
- /* Establish structured exception handling */
+#if defined(__GNUC__) && !defined(_WIN64)
-# ifdef HAVE_NO_SEH
+ /*
+ * Execute the CPUID instruction with the given index, and
+ * store results off 'regPtr'.
+ */
+
__asm__ __volatile__ (
- "pushl %%ebp" "\n\t"
- "pushl %0" "\n\t"
- "pushl %%fs:0" "\n\t"
- "movl %%esp, %%fs:0"
- :
- : "r" (_except_TclWinCPUID_detach_handler) );
-# else
- __try {
-# endif
-
- /*
- * Execute the CPUID instruction with the given index, and
- * store results off 'regPtr'.
- */
-
- __asm__ __volatile__ (
- "movl %4, %%eax" "\n\t"
- "cpuid" "\n\t"
- "movl %%eax, %0" "\n\t"
- "movl %%ebx, %1" "\n\t"
- "movl %%ecx, %2" "\n\t"
- "movl %%edx, %3"
- :
- "=m"(regsPtr[0]),
- "=m"(regsPtr[1]),
- "=m"(regsPtr[2]),
- "=m"(regsPtr[3])
- : "m"(index)
- : "%eax", "%ebx", "%ecx", "%edx" );
- status = TCL_OK;
- /* End the structured exception handler */
-
-# ifndef HAVE_NO_SEH
- } __except( EXCEPTION_EXECUTE_HANDLER ) {
- /* do nothing */
- }
-# else
- __asm __volatile__ (
- "jmp TclWinCPUID_detach_pop" "\n"
- "TclWinCPUID_detach_reentry:" "\n\t"
- "movl %%fs:0, %%eax" "\n\t"
- "movl 0x8(%%eax), %%esp" "\n\t"
- "movl 0x8(%%esp), %%ebp" "\n"
- "TclWinCPUID_detach_pop:" "\n\t"
- "movl (%%esp), %%eax" "\n\t"
- "movl %%eax, %%fs:0" "\n\t"
- "add $12, %%esp" "\n\t"
- :
- :
- : "%eax");
-# endif
+ /*
+ * Build an EXCEPTION_REGISTRATION on the stack. Save
+ * EBP in the EXCEPTION_REGISTRATION's third longword.
+ * Put the address of the status word at 0x0c relative
+ * to the EXCEPTION_REGISTRATION.
+ */
+
+ "movl %[index], %%eax" "\n\t"
+ "leal %[stat], %%edx" "\n\t"
+ "movl %[rptr], %%edi" "\n\t"
+ "pushl %%edx" "\n\t"
+ "pushl %%ebp" "\n\t"
+ "leal 1f, %%edx" "\n\t"
+ "pushl %%edx" "\n\t"
+ "pushl %%fs:0" "\n\t"
+ "movl %%esp, %%fs:0" "\n\t"
+
+ /*
+ * Do the CPUID instruction, and save the results in
+ * the 'regsPtr' area
+ */
+
+ "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"
+ "movl %[ok], %%eax" "\n\t"
+ "jmp 2f" "\n"
+
+ /*
+ * Come here on any exception. Retrieve the EXCEPTION_REGISTRATION
+ * and repair the stack.
+ */
+
+ "1:" "\t"
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl 0x8(%%edx), %%esp" "\n\t"
+ "movl %[error], %%eax" "\n"
+
+ /*
+ * Unstack the EXCEPTION_REGISTRATION, get back the address
+ * of the status word, and store status.
+ */
+
+ "2:" "\t"
+ "pop %%fs:0" "\n\t"
+ "addl $4, %%esp" "\n\t"
+ "pop %%ebp" "\n\t"
+ "pop %%edx" "\n\t"
+ "movl %%eax, 0x0(%%edx)" "\n\t"
+
+ : [stat]"=m"(status)
+ : [index]"m"(index),
+ [rptr]"m"(regsPtr),
+ [ok]"i"(TCL_OK),
+ [error]"i"(TCL_ERROR)
+ : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory" );
#elif defined(_MSC_VER) && !defined(_WIN64)
@@ -1216,36 +1187,4 @@ TclWinCPUID( unsigned int index, /* Which CPUID value to retrieve */
#endif
return status;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * _except_TclWinCPUID_detach_handler --
- *
- * SEH exception handler for TclWinCPUID.
- *
- * Results:
- * See TclWinCPUID.
- *
- * Side effects:
- * See TclWinCPUID.
- *
- *----------------------------------------------------------------------
- */
-
-#if defined( HAVE_NO_SEH )
-static
-__attribute__((cdecl))
-EXCEPTION_DISPOSITION
-_except_TclWinCPUID_detach_handler(
- struct _EXCEPTION_RECORD *ExceptionRecord,
- void *EstablisherFrame,
- struct _CONTEXT *ContextRecord,
- void *DispatcherContext)
-{
- __asm__ __volatile__ (
- "jmp TclWinCPUID_detach_reentry" );
- return 0; /* Function does not return */
-}
-#endif
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index d6ea38c..7cee496 100644
--- a/win/tclWinChan.c
+++ b/win/tclWinChan.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinChan.c,v 1.39 2005/01/27 00:23:32 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclWinChan.c,v 1.40 2005/05/10 18:35:37 kennykb Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c
index 1648ad7..2aa08b3 100644
--- a/win/tclWinConsole.c
+++ b/win/tclWinConsole.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinConsole.c,v 1.13 2005/01/27 00:23:33 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclWinConsole.c,v 1.14 2005/05/10 18:35:37 kennykb Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c
index 249b051..a5df717 100644
--- a/win/tclWinFCmd.c
+++ b/win/tclWinFCmd.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinFCmd.c,v 1.44 2005/02/17 18:34:36 hobbs Exp $
+ * RCS: @(#) $Id: tclWinFCmd.c,v 1.45 2005/05/10 18:35:37 kennykb Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinFile.c b/win/tclWinFile.c
index 9c37ff4..e0ef6b3 100644
--- a/win/tclWinFile.c
+++ b/win/tclWinFile.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinFile.c,v 1.73 2005/03/15 18:07:57 vincentdarley Exp $
+ * RCS: @(#) $Id: tclWinFile.c,v 1.74 2005/05/10 18:35:38 kennykb Exp $
*/
//#define _WIN32_WINNT 0x0500
diff --git a/win/tclWinInit.c b/win/tclWinInit.c
index d8d4fc9..08b3d14 100644
--- a/win/tclWinInit.c
+++ b/win/tclWinInit.c
@@ -7,7 +7,7 @@
* Copyright (c) 1998-1999 by Scriptics Corporation.
* All rights reserved.
*
- * RCS: @(#) $Id: tclWinInit.c,v 1.65 2004/12/04 21:19:19 dgp Exp $
+ * RCS: @(#) $Id: tclWinInit.c,v 1.66 2005/05/10 18:35:39 kennykb Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c
index fb92a7d..5a641c1 100644
--- a/win/tclWinNotify.c
+++ b/win/tclWinNotify.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinNotify.c,v 1.18 2005/04/26 00:45:01 das Exp $
+ * RCS: @(#) $Id: tclWinNotify.c,v 1.19 2005/05/10 18:35:40 kennykb Exp $
*/
#include "tclInt.h"
diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c
index d8a893d..34ed29f 100644
--- a/win/tclWinPipe.c
+++ b/win/tclWinPipe.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinPipe.c,v 1.54 2005/01/27 00:23:34 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclWinPipe.c,v 1.55 2005/05/10 18:35:40 kennykb Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c
index e06fb8e..582f952 100644
--- a/win/tclWinSerial.c
+++ b/win/tclWinSerial.c
@@ -11,7 +11,7 @@
*
* Serial functionality implemented by Rolf.Schroedter@dlr.de
*
- * RCS: @(#) $Id: tclWinSerial.c,v 1.29 2005/01/27 00:23:35 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclWinSerial.c,v 1.30 2005/05/10 18:35:40 kennykb Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index 60c535d..e96eb96 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinSock.c,v 1.45 2005/01/27 00:23:35 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclWinSock.c,v 1.46 2005/05/10 18:35:41 kennykb Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c
index d1f69ba..2b71f62 100644
--- a/win/tclWinThrd.c
+++ b/win/tclWinThrd.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinThrd.c,v 1.36 2005/05/05 17:53:02 kennykb Exp $
+ * RCS: @(#) $Id: tclWinThrd.c,v 1.37 2005/05/10 18:35:42 kennykb Exp $
*/
#include "tclWinInt.h"
diff --git a/win/tclWinTime.c b/win/tclWinTime.c
index 47294df..25f4296 100644
--- a/win/tclWinTime.c
+++ b/win/tclWinTime.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinTime.c,v 1.29 2005/01/21 22:25:35 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclWinTime.c,v 1.30 2005/05/10 18:35:43 kennykb Exp $
*/
#include "tclInt.h"