From d02ab64fa21f394ed414f13f1670cf3661fae3a7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 4 Dec 2019 12:53:25 +0000 Subject: Use the right encoding when converting (Unicode) messages regarding socket errors on Windows. Some code cleanup in win/tclWinfile.c. --- generic/tclIOSock.c | 2 +- win/tclWinFile.c | 69 +++++++++++++++++++++++++---------------------------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index 8a1e3e6..6413960 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -11,7 +11,7 @@ #include "tclInt.h" -#if defined(_WIN32) && defined(UNICODE) +#if defined(_WIN32) /* On Windows, we need to do proper Unicode->UTF-8 conversion. */ typedef struct ThreadSpecificData { diff --git a/win/tclWinFile.c b/win/tclWinFile.c index e050862..752aa0c 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -169,7 +169,7 @@ static int NativeWriteReparse(const WCHAR *LinkDirectory, REPARSE_DATA_BUFFER *buffer); static int NativeMatchType(int isDrive, DWORD attr, const WCHAR *nativeName, Tcl_GlobTypeData *types); -static int WinIsDrive(const char *name, int nameLen); +static int WinIsDrive(const char *name, size_t nameLen); static int WinIsReserved(const char *path); static Tcl_Obj * WinReadLink(const WCHAR *LinkSource); static Tcl_Obj * WinReadLinkDirectory(const WCHAR *LinkDirectory); @@ -395,11 +395,11 @@ WinSymLinkDirectory( */ for (loop = nativeTarget; *loop != 0; loop++) { - if (*loop == L'/') { - *loop = L'\\'; + if (*loop == '/') { + *loop = '\\'; } } - if ((nativeTarget[len-1] == L'\\') && (nativeTarget[len-2] != L':')) { + if ((nativeTarget[len-1] == '\\') && (nativeTarget[len-2] != ':')) { nativeTarget[len-1] = 0; } @@ -572,8 +572,7 @@ WinReadLinkDirectory( */ offset = 0; -#if 1 - if (reparseBuffer->MountPointReparseBuffer.PathBuffer[0] == L'\\') { + if (reparseBuffer->MountPointReparseBuffer.PathBuffer[0] == '\\') { /* * Check whether this is a mounted volume. */ @@ -587,7 +586,7 @@ WinReadLinkDirectory( * to fix here. It doesn't seem very well documented. */ - reparseBuffer->MountPointReparseBuffer.PathBuffer[1]=L'\\'; + reparseBuffer->MountPointReparseBuffer.PathBuffer[1] = '\\'; /* * Check if a corresponding drive letter exists, and use that @@ -634,11 +633,10 @@ WinReadLinkDirectory( offset = 4; } } -#endif /* UNICODE */ Tcl_WinTCharToUtf((TCHAR *) reparseBuffer->MountPointReparseBuffer.PathBuffer, - (int) reparseBuffer->MountPointReparseBuffer + reparseBuffer->MountPointReparseBuffer .SubstituteNameLength, &ds); copy = Tcl_DStringValue(&ds)+offset; @@ -810,13 +808,13 @@ tclWinDebugPanic( { #define TCL_MAX_WARN_LEN 1024 va_list argList; - char buf[TCL_MAX_WARN_LEN * TCL_UTF_MAX]; + char buf[TCL_MAX_WARN_LEN * 3]; WCHAR msgString[TCL_MAX_WARN_LEN]; va_start(argList, format); vsnprintf(buf, sizeof(buf), format, argList); - msgString[TCL_MAX_WARN_LEN-1] = L'\0'; + msgString[TCL_MAX_WARN_LEN-1] = '\0'; MultiByteToWideChar(CP_UTF8, 0, buf, -1, msgString, TCL_MAX_WARN_LEN); /* @@ -824,7 +822,7 @@ tclWinDebugPanic( * and cause possible oversized window error. */ - if (msgString[TCL_MAX_WARN_LEN-1] != L'\0') { + if (msgString[TCL_MAX_WARN_LEN-1] != '\0') { memcpy(msgString + (TCL_MAX_WARN_LEN - 5), L" ...", 5 * sizeof(WCHAR)); } if (IsDebuggerPresent()) { @@ -869,7 +867,7 @@ TclpFindExecutable( * ignore. */ { WCHAR wName[MAX_PATH]; - char name[MAX_PATH * TCL_UTF_MAX]; + char name[MAX_PATH * 3]; /* * Under Windows we ignore argv0, and return the path for the file used to @@ -1174,7 +1172,7 @@ TclpMatchInDirectory( static int WinIsDrive( const char *name, /* Name (UTF-8) */ - int len) /* Length of name */ + size_t len) /* Length of name */ { int remove = 0; @@ -1471,14 +1469,12 @@ TclpGetUserHome( } Tcl_DStringFree(&ds); } else { - Tcl_DStringInit(&ds); wName = (WCHAR *)Tcl_WinUtfToTChar(domain + 1, -1, &ds); rc = NetGetDCName(NULL, wName, (LPBYTE *) &wDomain); Tcl_DStringFree(&ds); nameLen = domain - name; } if (rc == 0) { - Tcl_DStringInit(&ds); wName = (WCHAR *)Tcl_WinUtfToTChar(name, nameLen, &ds); while (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) &uiPtr) != 0) { /* @@ -1505,7 +1501,7 @@ TclpGetUserHome( DWORD i, size = MAX_PATH; wHomeDir = uiPtr->usri1_home_dir; - if ((wHomeDir != NULL) && (wHomeDir[0] != L'\0')) { + if ((wHomeDir != NULL) && (wHomeDir[0] != '\0')) { size = lstrlenW(wHomeDir); Tcl_WinTCharToUtf((TCHAR *)wHomeDir, size*sizeof(WCHAR), bufferPtr); } else { @@ -1522,7 +1518,7 @@ TclpGetUserHome( result = Tcl_DStringValue(bufferPtr); /* - * Be sure we returns normalized path + * Be sure we return normalized path */ for (i = 0; i < size; ++i) { @@ -1691,7 +1687,6 @@ NativeAccess( * what permissions the OS has set for a file. */ -#if 1 { SECURITY_DESCRIPTOR *sdPtr = NULL; unsigned long size; @@ -1854,7 +1849,6 @@ NativeAccess( } } -#endif /* !UNICODE */ return 0; } @@ -1887,11 +1881,11 @@ NativeIsExec( } path += len-3; - if ((wcsicmp(path, L"exe") == 0) - || (wcsicmp(path, L"com") == 0) - || (wcsicmp(path, L"cmd") == 0) - || (wcsicmp(path, L"cmd") == 0) - || (wcsicmp(path, L"bat") == 0)) { + if ((_wcsicmp(path, L"exe") == 0) + || (_wcsicmp(path, L"com") == 0) + || (_wcsicmp(path, L"cmd") == 0) + || (_wcsicmp(path, L"cmd") == 0) + || (_wcsicmp(path, L"bat") == 0)) { return 1; } return 0; @@ -2205,7 +2199,7 @@ NativeDev( p = strchr(p + 1, '\\'); if (p == NULL) { /* - * Add terminating backslash to fullpath or GetVolumeInformationW() + * Add terminating backslash to fullpath or GetVolumeInformation() * won't work. */ @@ -2538,8 +2532,9 @@ TclpFilesystemPathType( int TclpObjNormalizePath( Tcl_Interp *interp, - Tcl_Obj *pathPtr, - int nextCheckpoint) + Tcl_Obj *pathPtr, /* An unshared object containing the path to + * normalize */ + int nextCheckpoint) /* offset to start at in pathPtr */ { char *lastValidPathEnd = NULL; Tcl_DString dsNorm; /* This will hold the normalized string. */ @@ -2586,8 +2581,8 @@ TclpObjNormalizePath( for (i=0 ; i= L'a') { - wc -= (L'a' - L'A'); + if (wc >= 'a') { + wc -= ('a' - 'A'); ((WCHAR *) nativePath)[i] = wc; } } @@ -2677,8 +2672,8 @@ TclpObjNormalizePath( if (isDrive) { WCHAR drive = ((WCHAR *) nativePath)[0]; - if (drive >= L'a') { - drive -= (L'a' - L'A'); + if (drive >= 'a') { + drive -= ('a' - 'A'); ((WCHAR *) nativePath)[0] = drive; } Tcl_DStringAppend(&dsNorm, (const char *)nativePath, @@ -2709,7 +2704,7 @@ TclpObjNormalizePath( Tcl_DStringAppend(&dsNorm, ((const char *)nativePath) + Tcl_DStringLength(&ds) - (dotLen * sizeof(WCHAR)), - (int)(dotLen * sizeof(WCHAR))); + dotLen * sizeof(WCHAR)); } else { /* * Normal path. @@ -2775,8 +2770,8 @@ TclpObjNormalizePath( * We have to make the drive letter uppercase. */ - if (wpath[0] >= L'a') { - wpath[0] -= (L'a' - L'A'); + if (wpath[0] >= 'a') { + wpath[0] -= ('a' - 'A'); } Tcl_DStringAppend(&dsNorm, (const char *) wpath, wpathlen * sizeof(WCHAR)); @@ -3021,7 +3016,7 @@ TclpNativeToNormalized( * The nativePath representation. * * Side effects: - * Memory will be allocated. The path may need to be normalized. + * Memory will be allocated. The path might be normalized. * *--------------------------------------------------------------------------- */ @@ -3073,7 +3068,7 @@ TclNativeCreateNativeRep( str = Tcl_GetString(validPathPtr); len = validPathPtr->length; - if (strlen(str) != (unsigned int) len) { + if (strlen(str) != len) { /* * String contains NUL-bytes. This is invalid. */ -- cgit v0.12 From 0acc700234e4684a44765c0fccb621c71f1dc93f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 4 Dec 2019 12:54:39 +0000 Subject: Add builds using TCL_UTF_MAX=4 on Windows. Not officially supported, but used by Androwish. Also alphabetise some options in win/makefile.vc and win/rules.vc --- .travis.yml | 50 +++++++++++++++++++++++++++++++++++++++++--------- win/makefile.vc | 37 ++++++++++++++++++++----------------- win/rules.vc | 15 ++++++++++++--- 3 files changed, 73 insertions(+), 29 deletions(-) diff --git a/.travis.yml b/.travis.yml index 30a7bf0..9fa6f1f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -175,7 +175,7 @@ matrix: - gcc-multilib env: - BUILD_DIR=win - - CFGOPT="--host=i686-w64-mingw32" + - CFGOPT=--host=i686-w64-mingw32 script: *crosstest # Test on Windows with MSVC native - name: "Windows/MSVC/Shared" @@ -189,8 +189,17 @@ matrix: - cd ${BUILD_DIR} install: [] script: - - cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=msvcrt -f makefile.vc all tcltest' - - cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=msvcrt -f makefile.vc test' + - cmd.exe /C 'vcvarsall.bat x64 && nmake -f makefile.vc all tcltest' + - cmd.exe /C 'vcvarsall.bat x64 && nmake -f makefile.vc test' + - name: "Windows/MSVC/Shared: UTF_MAX=4" + os: windows + compiler: cl + env: *vcenv + before_install: *vcpreinst + install: [] + script: + - cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=utfmax -f makefile.vc all tcltest' + - cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=utfmax -f makefile.vc test' - name: "Windows/MSVC/Static" os: windows compiler: cl @@ -207,8 +216,8 @@ matrix: before_install: *vcpreinst install: [] script: - - cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=symbols,msvcrt -f makefile.vc all tcltest' - - cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=symbols,msvcrt -f makefile.vc test' + - cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=symbols -f makefile.vc all tcltest' + - cmd.exe /C 'vcvarsall.bat x64 && nmake OPTS=symbols -f makefile.vc test' # Test on Windows with MSVC native (32-bit) - name: "Windows/MSVC-x86/Shared" os: windows @@ -217,8 +226,17 @@ matrix: before_install: *vcpreinst install: [] script: - - cmd.exe /C 'vcvarsall.bat x86 && nmake OPTS=msvcrt -f makefile.vc all tcltest' - - cmd.exe /C 'vcvarsall.bat x86 && nmake OPTS=msvcrt -f makefile.vc test' + - cmd.exe /C 'vcvarsall.bat x86 && nmake -f makefile.vc all tcltest' + - cmd.exe /C 'vcvarsall.bat x86 && nmake -f makefile.vc test' + - name: "Windows/MSVC-x86/Shared: UTF_MAX=4" + os: windows + compiler: cl + env: *vcenv + before_install: *vcpreinst + install: [] + script: + - cmd.exe /C 'vcvarsall.bat x86 && nmake OPTS=utfmax -f makefile.vc all tcltest' + - cmd.exe /C 'vcvarsall.bat x86 && nmake OPTS=utfmax -f makefile.vc test' - name: "Windows/MSVC-x86/Static" os: windows compiler: cl @@ -235,8 +253,8 @@ matrix: before_install: *vcpreinst install: [] script: - - cmd.exe /C 'vcvarsall.bat x86 && nmake OPTS=symbols,msvcrt -f makefile.vc all tcltest' - - cmd.exe /C 'vcvarsall.bat x86 && nmake OPTS=symbols,msvcrt -f makefile.vc test' + - cmd.exe /C 'vcvarsall.bat x86 && nmake OPTS=symbols -f makefile.vc all tcltest' + - cmd.exe /C 'vcvarsall.bat x86 && nmake OPTS=symbols -f makefile.vc test' # Test on Windows with GCC native - name: "Windows/GCC/Shared" os: windows @@ -247,6 +265,13 @@ matrix: before_install: &makepreinst - choco install make - cd ${BUILD_DIR} + - name: "Windows/GCC/Shared: UTF_MAX=4" + os: windows + compiler: gcc + env: + - BUILD_DIR=win + - CFGOPT="--enable-64bit CFLAGS=-DTCL_UTF_MAX=4" + before_install: *makepreinst - name: "Windows/GCC/Static" os: windows compiler: gcc @@ -268,6 +293,13 @@ matrix: env: - BUILD_DIR=win before_install: *makepreinst + - name: "Windows/GCC-x86/Shared: UTF_MAX=4" + os: windows + compiler: gcc + env: + - BUILD_DIR=win + - CFGOPT="CFLAGS=-DTCL_UTF_MAX=4" + before_install: *makepreinst - name: "Windows/GCC-x86/Static" os: windows compiler: gcc diff --git a/win/makefile.vc b/win/makefile.vc index 26f7da3..e337569 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -52,29 +52,32 @@ # turn on the 64-bit compiler, if your SDK has it. # # Basic macros and options usable on the commandline (see rules.vc for more info): -# OPTS=msvcrt,static,staticpkg,symbols,nothreads,profile,unchecked,time64bit,none +# OPTS=msvcrt,nothreads,pdbs,profile,static,staticpkg,symbols,thrdalloc,time64bit,unchecked,utfmax,none # Sets special options for the core. The default is for none. # Any combination of the above may be used (comma separated). # 'none' will over-ride everything to nothing. # -# msvcrt = Affects the static option only to switch it from -# using libcmt(d) as the C runtime [by default] to -# msvcrt(d). This is useful for static embedding -# support. -# static = Builds a static library of the core instead of a -# dll. The shell will be static (and large), as well. -# staticpkg= Affects the static option only to switch -# tclshXX.exe to have the dde and reg extension linked -# inside it. -# nothreads = Turns off full multithreading support (default on). +# msvcrt = Affects the static option only to switch it from +# using libcmt(d) as the C runtime [by default] to +# msvcrt(d). This is useful for static embedding +# support. +# nothreads = Turns off full multithreading support (default on). +# pbds = Produce separate debug symbol files. +# profile = Adds profiling hooks. Map file is assumed. +# static = Builds a static library of the core instead of a +# dll. The shell will be static (and large), as well. +# staticpkg = Affects the static option only to switch +# tclshXX.exe to have the dde and reg extension linked +# inside it. +# symbols = Adds symbols for step debugging. # thrdalloc = Use the thread allocator (shared global free pool). -# symbols = Adds symbols for step debugging. -# profile = Adds profiling hooks. Map file is assumed. -# unchecked = Allows a symbols build to not use the debug -# enabled runtime (msvcrt.dll not msvcrtd.dll -# or libcmt.lib not libcmtd.lib). # time64bit = Forces a build using 64-bit time_t for 32-bit build -# (CRT library should support this). +# (CRT library should support this). +# unchecked = Allows a symbols build to not use the debug +# enabled runtime (msvcrt.dll not msvcrtd.dll +# or libcmt.lib not libcmtd.lib). +# utfmax = Forces a build allowing 4-byte UTF-8 sequences +# internally. # # STATS=compdbg,memdbg,none # Sets optional memory and bytecode compiler debugging code added diff --git a/win/rules.vc b/win/rules.vc index 8050ed3..c0deb2a 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -686,6 +686,7 @@ LINKERFLAGS = $(LINKERFLAGS) -ltcg # configuration (ignored for Tcl itself) # _USE_64BIT_TIME_T - forces a build using 64-bit time_t for 32-bit build # (CRT library should support this) +# TCL_UTF_MAX=4 - forces a build allowing 4-byte UTF-8 sequences internally. # Further, LINKERFLAGS are modified based on above. # Default values for all the above @@ -750,7 +751,7 @@ TCL_USE_STATIC_PACKAGES = 0 TCL_THREADS = 0 USE_THREAD_ALLOC= 0 !else -TCL_THREADS = 1 +TCL_THREADS = 1 USE_THREAD_ALLOC= 1 !endif @@ -759,6 +760,11 @@ USE_THREAD_ALLOC= 1 _USE_64BIT_TIME_T = 1 !endif +!if [nmakehlp -f $(OPTS) "utfmax"] +!message *** Force allowing 4-byte UTF-8 sequences internally +TCL_UTF_MAX = 4 +!endif + # Yes, it's weird that the "symbols" option controls DEBUG and # the "pdbs" option controls SYMBOLS. That's historical. !if [nmakehlp -f $(OPTS) "symbols"] @@ -1346,11 +1352,14 @@ OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_PROFILED OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_DO64BIT !endif !if $(VCVERSION) < 1300 -OPTDEFINES = $(OPTDEFINES) /DNO_STRTOI64 +OPTDEFINES = $(OPTDEFINES) /DNO_STRTOI64=1 !endif !if "$(_USE_64BIT_TIME_T)" == "1" -OPTDEFINES = $(OPTDEFINES) /D_USE_64BIT_TIME_T +OPTDEFINES = $(OPTDEFINES) /D_USE_64BIT_TIME_T=1 +!endif +!if "$(TCL_UTF_MAX)" == "4" +OPTDEFINES = $(OPTDEFINES) /DTCL_UTF_MAX=4 !endif # _ATL_XP_TARGETING - Newer SDK's need this to build for XP -- cgit v0.12