diff options
| -rw-r--r-- | generic/tclEnv.c | 70 | ||||
| -rw-r--r-- | tests/cmdAH.test | 4 | ||||
| -rwxr-xr-x | unix/configure | 117 | ||||
| -rw-r--r-- | unix/tcl.m4 | 25 | ||||
| -rw-r--r-- | unix/tclConfig.h.in | 6 | ||||
| -rw-r--r-- | win/Makefile.in | 10 | ||||
| -rw-r--r-- | win/tclWinInit.c | 3 |
7 files changed, 200 insertions, 35 deletions
diff --git a/generic/tclEnv.c b/generic/tclEnv.c index 608ebf6..8b73b21 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -19,20 +19,20 @@ TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */ #if defined(_WIN32) # define tenviron _wenviron -# define tenviron2utfdstr(string, len, dsPtr) (Tcl_DStringInit(dsPtr), \ - (char *)Tcl_Char16ToUtfDString((const unsigned short *)(string), ((((len) + 2) >> 1) - 1), (dsPtr))) -# define utf2tenvirondstr(string, len, dsPtr) (Tcl_DStringInit(dsPtr), \ - (const WCHAR *)Tcl_UtfToChar16DString((string), (len), (dsPtr))) +# define tenviron2utfdstr(str, dsPtr) (Tcl_DStringInit(dsPtr), \ + (char *)Tcl_Char16ToUtfDString((const unsigned short *)(str), -1, (dsPtr))) +# define utf2tenvirondstr(str, dsPtr) (Tcl_DStringInit(dsPtr), \ + (const WCHAR *)Tcl_UtfToChar16DString((str), -1, (dsPtr))) # define techar WCHAR # ifdef USE_PUTENV # define putenv(env) _wputenv((const wchar_t *)env) # endif #else # define tenviron environ -# define tenviron2utfdstr(tenvstr, len, dstr) \ - Tcl_ExternalToUtfDString(NULL, tenvstr, len, dstr) -# define utf2tenvirondstr(str, len, dstr) \ - Tcl_UtfToExternalDString(NULL, str, len, dstr) +# define tenviron2utfdstr(str, dsPtr) \ + Tcl_ExternalToUtfDString(NULL, str, -1, dsPtr) +# define utf2tenvirondstr(str, dsPtr) \ + Tcl_UtfToExternalDString(NULL, str, -1, dsPtr) # define techar char #endif @@ -42,7 +42,7 @@ size_t TclEnvEpoch = 0; /* Epoch of the tcl environment * (if changed with tcl-env). */ static struct { - size_t cacheSize; /* Number of env strings in cache. */ + Tcl_Size cacheSize; /* Number of env strings in cache. */ char **cache; /* Array containing all of the environment * strings that Tcl has allocated. */ #ifndef USE_PUTENV @@ -159,7 +159,11 @@ TclSetupEnv( const char *p1; char *p2; - p1 = tenviron2utfdstr(tenviron[i], -1, &envString); + p1 = tenviron2utfdstr(tenviron[i], &envString); + if (p1 == NULL) { + /* Ignore what cannot be decoded (should not happen) */ + continue; + } p2 = (char *)strchr(p1, '='); if (p2 == NULL) { /* @@ -301,9 +305,9 @@ TclSetEnv( * interpreters. */ - oldEnv = tenviron2utfdstr(tenviron[index], -1, &envString); - if (strcmp(value, oldEnv + (length + 1)) == 0) { - Tcl_DStringFree(&envString); + oldEnv = tenviron2utfdstr(tenviron[index], &envString); + if (oldEnv == NULL || strcmp(value, oldEnv + (length + 1)) == 0) { + Tcl_DStringFree(&envString); /* OK even if oldEnv is NULL */ Tcl_MutexUnlock(&envMutex); return; } @@ -324,7 +328,13 @@ TclSetEnv( memcpy(p, name, nameLength); p[nameLength] = '='; memcpy(p+nameLength+1, value, valueLength+1); - p2 = utf2tenvirondstr(p, -1, &envString); + p2 = utf2tenvirondstr(p, &envString); + if (p2 == NULL) { + /* No way to signal error from here :-( but should not happen */ + Tcl_Free(p); + Tcl_MutexUnlock(&envMutex); + return; + } /* * Copy the native string to heap memory. @@ -502,7 +512,11 @@ TclUnsetEnv( string[length] = '\0'; #endif /* _WIN32 */ - utf2tenvirondstr(string, -1, &envString); + if (utf2tenvirondstr(string, &envString) == NULL) { + /* Should not happen except memory alloc fail. */ + Tcl_MutexUnlock(&envMutex); + return; + } string = (char *)Tcl_Realloc(string, Tcl_DStringLength(&envString) + tNTL); memcpy(string, Tcl_DStringValue(&envString), Tcl_DStringLength(&envString) + tNTL); @@ -577,17 +591,19 @@ TclGetEnv( if (index != -1) { Tcl_DString envStr; - result = tenviron2utfdstr(tenviron[index], -1, &envStr); - result += length; - if (*result == '=') { - result++; - Tcl_DStringInit(valuePtr); - Tcl_DStringAppend(valuePtr, result, -1); - result = Tcl_DStringValue(valuePtr); - } else { - result = NULL; + result = tenviron2utfdstr(tenviron[index], &envStr); + if (result) { + result += length; + if (*result == '=') { + result++; + Tcl_DStringInit(valuePtr); + Tcl_DStringAppend(valuePtr, result, -1); + result = Tcl_DStringValue(valuePtr); + } else { + result = NULL; + } + Tcl_DStringFree(&envStr); } - Tcl_DStringFree(&envStr); } Tcl_MutexUnlock(&envMutex); return result; @@ -703,7 +719,7 @@ ReplaceString( const char *oldStr, /* Old environment string. */ char *newStr) /* New environment string. */ { - size_t i; + Tcl_Size i; /* * Check to see if the old value was allocated by Tcl. If so, it needs to @@ -782,7 +798,7 @@ TclFinalizeEnvironment(void) if (env.cache) { #ifdef PURIFY - size_t i; + Tcl_Size i; for (i = 0; i < env.cacheSize; i++) { Tcl_Free(env.cache[i]); } diff --git a/tests/cmdAH.test b/tests/cmdAH.test index 555c70f..ad5a67d 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -1710,6 +1710,8 @@ test cmdAH-24.14.1 { test cmdAH-24.20.1 {Tcl_FileObjCmd: atime 64-bit time_t, bug [4718b41c56]} -setup { set filename [makeFile "" foo.text] } -body { + # This test may fail if your system does not have a 64-bit time_t. + # That is to be expected and is not a problem with Tcl. list [file atime $filename 3155760000] [file atime $filename] } -cleanup { removeFile $filename @@ -1717,6 +1719,8 @@ test cmdAH-24.20.1 {Tcl_FileObjCmd: atime 64-bit time_t, bug [4718b41c56]} -setu test cmdAH-24.20.2 {Tcl_FileObjCmd: mtime 64-bit time_t, bug [4718b41c56]} -setup { set filename [makeFile "" foo.text] } -body { + # This test may fail if your system does not have a 64-bit time_t. + # That is to be expected and is not a problem with Tcl. list [file mtime $filename 3155760000] [file mtime $filename] } -cleanup { file delete -force $filename diff --git a/unix/configure b/unix/configure index a3102b8..66af4ce 100755 --- a/unix/configure +++ b/unix/configure @@ -7492,6 +7492,56 @@ printf "%s\n" "#define _ISOC99_SOURCE 1" >>confdefs.h fi + if test ${tcl_cv_flag__file_offset_bits+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/stat.h> +int +main (void) +{ +switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; } + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + tcl_cv_flag__file_offset_bits=no +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include <sys/stat.h> +int +main (void) +{ +switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; } + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + tcl_cv_flag__file_offset_bits=yes +else $as_nop + tcl_cv_flag__file_offset_bits=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + if test "x${tcl_cv_flag__file_offset_bits}" = "xyes" ; then + +printf "%s\n" "#define _FILE_OFFSET_BITS 64" >>confdefs.h + + tcl_flags="$tcl_flags _FILE_OFFSET_BITS" + fi + + if test ${tcl_cv_flag__largefile64_source+y} then : printf %s "(cached) " >&6 @@ -7592,6 +7642,73 @@ printf "%s\n" "yes" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } # Now check for auxiliary declarations + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 64-bit time_t" >&5 +printf %s "checking for 64-bit time_t... " >&6; } +if test ${tcl_cv_time_t_64+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +int +main (void) +{ +switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;} + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + tcl_cv_time_t_64=yes +else $as_nop + tcl_cv_time_t_64=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_time_t_64" >&5 +printf "%s\n" "$tcl_cv_time_t_64" >&6; } + if test "x${tcl_cv_time_t_64}" = "xno" ; then + # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64 + # which SC_TCL_EARLY_FLAGS has defined if necessary. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if _TIME_BITS=64 enables 64-bit time_t" >&5 +printf %s "checking if _TIME_BITS=64 enables 64-bit time_t... " >&6; } +if test ${tcl_cv__time_bits+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _TIME_BITS 64 +#include <sys/types.h> +int +main (void) +{ +switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;} + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + tcl_cv__time_bits=yes +else $as_nop + tcl_cv__time_bits=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv__time_bits" >&5 +printf "%s\n" "$tcl_cv__time_bits" >&6; } + if test "x${tcl_cv__time_bits}" = "xyes" ; then + +printf "%s\n" "#define _TIME_BITS 64" >>confdefs.h + + fi + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5 printf %s "checking for struct dirent64... " >&6; } if test ${tcl_cv_struct_dirent64+y} diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 9dc39f2..beaac7e 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2294,6 +2294,7 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [ # # Might define the following vars: # _ISOC99_SOURCE +# _FILE_OFFSET_BITS # _LARGEFILE64_SOURCE # #-------------------------------------------------------------------- @@ -2301,12 +2302,12 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [ AC_DEFUN([SC_TCL_EARLY_FLAG],[ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]), AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])], - [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ 1 + [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ ]m4_default([$4],[1])[ ]$2]], [[$3]])], [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)])) if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then - AC_DEFINE($1, 1, [Add the ]$1[ flag when building]) + AC_DEFINE($1, m4_default([$4],[1]), [Add the ]$1[ flag when building]) tcl_flags="$tcl_flags $1" fi ]) @@ -2316,6 +2317,8 @@ AC_DEFUN([SC_TCL_EARLY_FLAGS],[ tcl_flags="" SC_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>], [char *p = (char *)strtoll; char *q = (char *)strtoull;]) + SC_TCL_EARLY_FLAG(_FILE_OFFSET_BITS,[#include <sys/stat.h>], + [switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }],64) SC_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>], [struct stat64 buf; int i = stat64("/", &buf);]) if test "x${tcl_flags}" = "x" ; then @@ -2340,6 +2343,7 @@ AC_DEFUN([SC_TCL_EARLY_FLAGS],[ # HAVE_STRUCT_DIRENT64, HAVE_DIR64 # HAVE_STRUCT_STAT64 # HAVE_TYPE_OFF64_T +# _TIME_BITS # #-------------------------------------------------------------------- @@ -2359,6 +2363,23 @@ AC_DEFUN([SC_TCL_64BIT_FLAGS], [ else AC_MSG_RESULT([no]) # Now check for auxiliary declarations + AC_CACHE_CHECK([for 64-bit time_t], tcl_cv_time_t_64,[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]], + [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])], + [tcl_cv_time_t_64=yes],[tcl_cv_time_t_64=no])]) + if test "x${tcl_cv_time_t_64}" = "xno" ; then + # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64 + # which SC_TCL_EARLY_FLAGS has defined if necessary. + AC_CACHE_CHECK([if _TIME_BITS=64 enables 64-bit time_t], tcl_cv__time_bits,[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define _TIME_BITS 64 +#include <sys/types.h>]], + [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])], + [tcl_cv__time_bits=yes],[tcl_cv__time_bits=no])]) + if test "x${tcl_cv__time_bits}" = "xyes" ; then + AC_DEFINE(_TIME_BITS, 64, [_TIME_BITS=64 enables 64-bit time_t.]) + fi + fi + AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> #include <dirent.h>]], [[struct dirent64 p;]])], diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in index fe2c6d9..a1b59df 100644 --- a/unix/tclConfig.h.in +++ b/unix/tclConfig.h.in @@ -471,6 +471,9 @@ /* Are Darwin SUSv3 extensions available? */ #undef _DARWIN_C_SOURCE +/* Add the _FILE_OFFSET_BITS flag when building */ +#undef _FILE_OFFSET_BITS + /* Add the _ISOC99_SOURCE flag when building */ #undef _ISOC99_SOURCE @@ -489,6 +492,9 @@ /* Do we want the thread-safe OS API? */ #undef _THREAD_SAFE +/* _TIME_BITS=64 enables 64-bit time_t. */ +#undef _TIME_BITS + /* Do we want to use the XOPEN network library? */ #undef _XOPEN_SOURCE diff --git a/win/Makefile.in b/win/Makefile.in index 04ae08f..e648d3f 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -627,10 +627,14 @@ ${ZLIB_DLL_FILE}: ${TCL_STUB_LIB_FILE} # use pre-built libtommath.dll ${TOMMATH_DLL_FILE}: ${TCL_STUB_LIB_FILE} - @if test "@TOMMATH_LIBS@set" != "${TOMMATH_DIR_NATIVE}/win32/tommath.libset" ; then \ - $(COPY) $(TOMMATH_DIR)/win64/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \ - else \ + @if test "@TOMMATH_LIBS@set" = "${TOMMATH_DIR_NATIVE}/win64-arm/tommath.libset" ; then \ + $(COPY) $(TOMMATH_DIR)/win64-arm/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \ + elif test "@TOMMATH_LIBS@set" = "${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.aset" ; then \ + $(COPY) $(TOMMATH_DIR)/win64-arm/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \ + elif test "@TOMMATH_LIBS@set" = "${TOMMATH_DIR_NATIVE}/win32/tommath.libset" ; then \ $(COPY) $(TOMMATH_DIR)/win32/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \ + else \ + $(COPY) $(TOMMATH_DIR)/win64/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \ fi; # Add the object extension to the implicit rules. By default .obj is not diff --git a/win/tclWinInit.c b/win/tclWinInit.c index 510b6df..d682006 100644 --- a/win/tclWinInit.c +++ b/win/tclWinInit.c @@ -566,9 +566,6 @@ TclpSetVariables( *---------------------------------------------------------------------- */ -# define tenviron2utfdstr(string, len, dsPtr) \ - (char *)Tcl_Char16ToUtfDString((const unsigned short *)(string), ((((len) + 2) >> 1) - 1), (dsPtr)) - Tcl_Size TclpFindVariable( const char *name, /* Name of desired environment variable |
