summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/Encoding.34
-rw-r--r--generic/tclStubInit.c34
-rw-r--r--unix/tclUnixPort.h4
-rw-r--r--win/tclWin32Dll.c55
4 files changed, 78 insertions, 19 deletions
diff --git a/doc/Encoding.3 b/doc/Encoding.3
index 81ef508..79fca0f 100644
--- a/doc/Encoding.3
+++ b/doc/Encoding.3
@@ -260,10 +260,6 @@ Windows-only convenience
functions for converting between UTF-8 and Windows strings
based on the TCHAR type which is by convention
a Unicode character on Windows NT.
-These functions are essentially wrappers around
-\fBTcl_UtfToExternalDString\fR and
-\fBTcl_ExternalToUtfDString\fR that convert to and from the
-Unicode encoding.
.PP
\fBTcl_GetEncodingName\fR is roughly the inverse of \fBTcl_GetEncoding\fR.
Given an \fIencoding\fR, the return value is the \fIname\fR argument that
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index d26b67c..10ca66b 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -54,7 +54,9 @@
# define TclWinFlushDirtyChannels doNothing
# define TclWinResetInterfaces doNothing
+#if TCL_UTF_MAX < 4
static Tcl_Encoding winTCharEncoding;
+#endif
static int
TclpIsAtty(int fd)
@@ -66,7 +68,7 @@ void *TclWinGetTclInstance()
{
void *hInstance = NULL;
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- (const char *)&winTCharEncoding, &hInstance);
+ (const char *)&TclpIsAtty, &hInstance);
return hInstance;
}
@@ -102,11 +104,24 @@ Tcl_WinUtfToTChar(
int len,
Tcl_DString *dsPtr)
{
+#if TCL_UTF_MAX > 3
+ WCHAR *wp;
+ int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0);
+
+ Tcl_DStringInit(dsPtr);
+ Tcl_DStringSetLength(dsPtr, 2*size+2);
+ wp = (WCHAR *)Tcl_DStringValue(dsPtr);
+ MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1);
+ Tcl_DStringSetLength(dsPtr, 2*size);
+ wp[size] = 0;
+ return (char *)wp;
+#else
if (!winTCharEncoding) {
winTCharEncoding = Tcl_GetEncoding(0, "unicode");
}
return Tcl_UtfToExternalDString(winTCharEncoding,
string, len, dsPtr);
+#endif
}
char *
@@ -115,11 +130,28 @@ Tcl_WinTCharToUtf(
int len,
Tcl_DString *dsPtr)
{
+#if TCL_UTF_MAX > 3
+ char *p;
+ int size;
+
+ if (len > 0) {
+ len /= 2;
+ }
+ size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL);
+ Tcl_DStringInit(dsPtr);
+ Tcl_DStringSetLength(dsPtr, size+1);
+ p = (char *)Tcl_DStringValue(dsPtr);
+ WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL);
+ Tcl_DStringSetLength(dsPtr, size);
+ p[size] = 0;
+ return p;
+#else
if (!winTCharEncoding) {
winTCharEncoding = Tcl_GetEncoding(0, "unicode");
}
return Tcl_ExternalToUtfDString(winTCharEncoding,
string, len, dsPtr);
+#endif
}
#if defined(TCL_WIDE_INT_IS_LONG)
diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h
index d464f05..86f1dd0 100644
--- a/unix/tclUnixPort.h
+++ b/unix/tclUnixPort.h
@@ -87,8 +87,8 @@ typedef off_t Tcl_SeekOffset;
typedef unsigned short WCHAR;
__declspec(dllimport) extern __stdcall int GetModuleHandleExW(unsigned int, const char *, void *);
__declspec(dllimport) extern __stdcall int GetModuleFileNameW(void *, const char *, int);
- __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const char *, int,
- const char *, int, const char *, const char *);
+ __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const void *, int,
+ char *, int, const char *, void *);
__declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int, const char *, int,
WCHAR *, int);
__declspec(dllimport) extern __stdcall void OutputDebugStringW(const WCHAR *);
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c
index 95b8193..bc28032 100644
--- a/win/tclWin32Dll.c
+++ b/win/tclWin32Dll.c
@@ -32,7 +32,9 @@ static HINSTANCE hInstance; /* HINSTANCE of this DLL. */
#define cpuid __asm __emit 0fh __asm __emit 0a2h
#endif
+#if TCL_UTF_MAX < 4
static Tcl_Encoding winTCharEncoding = NULL;
+#endif
/*
* The following declaration is for the VC++ DLL entry point.
@@ -234,7 +236,7 @@ TclWinNoBackslash(
*
* TclpSetInterfaces --
*
- * A helper proc that initializes winTCharEncoding.
+ * A helper proc.
*
* Results:
* None.
@@ -248,8 +250,10 @@ TclWinNoBackslash(
void
TclpSetInterfaces(void)
{
+#if TCL_UTF_MAX < 4
TclWinResetInterfaces();
winTCharEncoding = Tcl_GetEncoding(NULL, "unicode");
+#endif
}
/*
@@ -312,10 +316,12 @@ TclWinEncodingsCleanup(void)
void
TclWinResetInterfaces(void)
{
+#if TCL_UTF_MAX < 4
if (winTCharEncoding != NULL) {
Tcl_FreeEncoding(winTCharEncoding);
winTCharEncoding = NULL;
}
+#endif
}
/*
@@ -500,13 +506,9 @@ TclWinDriveLetterForVolMountPoint(
* (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);
- * }
+ * encoding <- Tcl_GetEncoding("unicode");
+ * nativeBuffer <- UtfToExternal(encoding, utfBuffer);
+ * Tcl_FreeEncoding(encoding);
*
* 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
@@ -529,26 +531,55 @@ TclWinDriveLetterForVolMountPoint(
TCHAR *
Tcl_WinUtfToTChar(
const char *string, /* Source string in UTF-8. */
- int len, /* Source string length in bytes, or < 0 for
+ int len, /* Source string length in bytes, or -1 for
* strlen(). */
Tcl_DString *dsPtr) /* Uninitialized or free DString in which the
* converted string is stored. */
{
+#if TCL_UTF_MAX > 3
+ TCHAR *wp;
+ int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0);
+
+ Tcl_DStringInit(dsPtr);
+ Tcl_DStringSetLength(dsPtr, 2*size+2);
+ wp = (TCHAR *)Tcl_DStringValue(dsPtr);
+ MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1);
+ Tcl_DStringSetLength(dsPtr, 2*size);
+ wp[size] = 0;
+ return wp;
+#else
return (TCHAR *) Tcl_UtfToExternalDString(winTCharEncoding,
string, len, dsPtr);
+#endif
}
char *
Tcl_WinTCharToUtf(
- const TCHAR *string, /* Source string in Unicode when running NT,
- * ANSI when running 95. */
- int len, /* Source string length in bytes, or < 0 for
+ const TCHAR *string, /* Source string in Unicode. */
+ int len, /* Source string length in bytes, or -1 for
* platform-specific string length. */
Tcl_DString *dsPtr) /* Uninitialized or free DString in which the
* converted string is stored. */
{
+#if TCL_UTF_MAX > 3
+ char *p;
+ int size;
+
+ if (len > 0) {
+ len /= 2;
+ }
+ size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL);
+ Tcl_DStringInit(dsPtr);
+ Tcl_DStringSetLength(dsPtr, size+1);
+ p = (char *)Tcl_DStringValue(dsPtr);
+ WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL);
+ Tcl_DStringSetLength(dsPtr, size);
+ p[size] = 0;
+ return p;
+#else
return Tcl_ExternalToUtfDString(winTCharEncoding,
(const char *) string, len, dsPtr);
+#endif
}
/*