Import Tcl 8.6.10
This commit is contained in:
@@ -33,8 +33,6 @@ static int platformId; /* Running under NT, or 95/98? */
|
||||
#define cpuid __asm __emit 0fh __asm __emit 0a2h
|
||||
#endif
|
||||
|
||||
static Tcl_Encoding winTCharEncoding = NULL;
|
||||
|
||||
/*
|
||||
* The following declaration is for the VC++ DLL entry point.
|
||||
*/
|
||||
@@ -49,8 +47,8 @@ BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
|
||||
*/
|
||||
|
||||
typedef struct MountPointMap {
|
||||
const TCHAR *volumeName; /* Native wide string volume name. */
|
||||
TCHAR driveLetter; /* Drive letter corresponding to the volume
|
||||
WCHAR *volumeName; /* Native wide string volume name. */
|
||||
WCHAR driveLetter; /* Drive letter corresponding to the volume
|
||||
* name. */
|
||||
struct MountPointMap *nextPtr;
|
||||
/* Pointer to next structure in list, or
|
||||
@@ -122,6 +120,8 @@ DllMain(
|
||||
DWORD reason, /* Reason this function is being called. */
|
||||
LPVOID reserved) /* Not used. */
|
||||
{
|
||||
(void)reserved;
|
||||
|
||||
switch (reason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hInst);
|
||||
@@ -199,8 +199,6 @@ TclWinInit(
|
||||
if (platformId == VER_PLATFORM_WIN32_WINDOWS) {
|
||||
Tcl_Panic("Windows 9x is not a supported platform");
|
||||
}
|
||||
|
||||
TclWinResetInterfaces();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -266,7 +264,7 @@ TclWinNoBackslash(
|
||||
*
|
||||
* TclpSetInterfaces --
|
||||
*
|
||||
* A helper proc that initializes winTCharEncoding.
|
||||
* A helper proc.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -280,8 +278,6 @@ TclWinNoBackslash(
|
||||
void
|
||||
TclpSetInterfaces(void)
|
||||
{
|
||||
TclWinResetInterfaces();
|
||||
winTCharEncoding = Tcl_GetEncoding(NULL, "unicode");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -309,8 +305,6 @@ TclWinEncodingsCleanup(void)
|
||||
{
|
||||
MountPointMap *dlIter, *dlIter2;
|
||||
|
||||
TclWinResetInterfaces();
|
||||
|
||||
/*
|
||||
* Clean up the mount point map.
|
||||
*/
|
||||
@@ -344,10 +338,6 @@ TclWinEncodingsCleanup(void)
|
||||
void
|
||||
TclWinResetInterfaces(void)
|
||||
{
|
||||
if (winTCharEncoding != NULL) {
|
||||
Tcl_FreeEncoding(winTCharEncoding);
|
||||
winTCharEncoding = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -374,11 +364,11 @@ TclWinResetInterfaces(void)
|
||||
|
||||
char
|
||||
TclWinDriveLetterForVolMountPoint(
|
||||
const TCHAR *mountPoint)
|
||||
const WCHAR *mountPoint)
|
||||
{
|
||||
MountPointMap *dlIter, *dlPtr2;
|
||||
TCHAR Target[55]; /* Target of mount at mount point */
|
||||
TCHAR drive[4] = TEXT("A:\\");
|
||||
WCHAR Target[55]; /* Target of mount at mount point */
|
||||
WCHAR drive[4] = L"A:\\";
|
||||
|
||||
/*
|
||||
* Detect the volume mounted there. Unfortunately, there is no simple way
|
||||
@@ -389,22 +379,22 @@ TclWinDriveLetterForVolMountPoint(
|
||||
Tcl_MutexLock(&mountPointMap);
|
||||
dlIter = driveLetterLookup;
|
||||
while (dlIter != NULL) {
|
||||
if (_tcscmp(dlIter->volumeName, mountPoint) == 0) {
|
||||
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] = (TCHAR) dlIter->driveLetter;
|
||||
drive[0] = (WCHAR) dlIter->driveLetter;
|
||||
|
||||
/*
|
||||
* Try to read the volume mount point and see where it points.
|
||||
*/
|
||||
|
||||
if (GetVolumeNameForVolumeMountPoint(drive,
|
||||
if (GetVolumeNameForVolumeMountPointW(drive,
|
||||
Target, 55) != 0) {
|
||||
if (_tcscmp(dlIter->volumeName, Target) == 0) {
|
||||
if (wcscmp(dlIter->volumeName, Target) == 0) {
|
||||
/*
|
||||
* Nothing has changed.
|
||||
*/
|
||||
@@ -461,13 +451,13 @@ TclWinDriveLetterForVolMountPoint(
|
||||
* Try to read the volume mount point and see where it points.
|
||||
*/
|
||||
|
||||
if (GetVolumeNameForVolumeMountPoint(drive,
|
||||
if (GetVolumeNameForVolumeMountPointW(drive,
|
||||
Target, 55) != 0) {
|
||||
int alreadyStored = 0;
|
||||
|
||||
for (dlIter = driveLetterLookup; dlIter != NULL;
|
||||
dlIter = dlIter->nextPtr) {
|
||||
if (_tcscmp(dlIter->volumeName, Target) == 0) {
|
||||
if (wcscmp(dlIter->volumeName, Target) == 0) {
|
||||
alreadyStored = 1;
|
||||
break;
|
||||
}
|
||||
@@ -488,7 +478,7 @@ TclWinDriveLetterForVolMountPoint(
|
||||
|
||||
for (dlIter = driveLetterLookup; dlIter != NULL;
|
||||
dlIter = dlIter->nextPtr) {
|
||||
if (_tcscmp(dlIter->volumeName, mountPoint) == 0) {
|
||||
if (wcscmp(dlIter->volumeName, mountPoint) == 0) {
|
||||
Tcl_MutexUnlock(&mountPointMap);
|
||||
return (char) dlIter->driveLetter;
|
||||
}
|
||||
@@ -513,39 +503,32 @@ TclWinDriveLetterForVolMountPoint(
|
||||
*
|
||||
* Tcl_WinUtfToTChar, Tcl_WinTCharToUtf --
|
||||
*
|
||||
* Convert between UTF-8 and Unicode when running Windows NT or the
|
||||
* current ANSI code page when running Windows 95.
|
||||
* Convert between UTF-8 and Unicode when running Windows.
|
||||
*
|
||||
* 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 Mac and Unix, 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"
|
||||
* On Windows, 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
|
||||
* 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
|
||||
* Windows-specific code to convert between UTF-8 and Unicode strings.
|
||||
* 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
|
||||
* 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.
|
||||
* By convention, in Windows a WCHAR is a Unicode character. If you plan
|
||||
* on targeting a Unicode interface when running on Windows, these
|
||||
* functions should be used. If you plan on targetting a "char" oriented
|
||||
* function on Windows, use Tcl_UtfToExternal() with an encoding of NULL.
|
||||
*
|
||||
* Results:
|
||||
* The result is a pointer to the string in the desired target encoding.
|
||||
@@ -561,26 +544,128 @@ 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. */
|
||||
{
|
||||
return (TCHAR *) Tcl_UtfToExternalDString(winTCharEncoding,
|
||||
string, len, dsPtr);
|
||||
#if TCL_UTF_MAX > 4
|
||||
Tcl_UniChar ch = 0;
|
||||
TCHAR *w, *wString;
|
||||
const char *p, *end;
|
||||
int oldLength;
|
||||
#endif
|
||||
|
||||
Tcl_DStringInit(dsPtr);
|
||||
if (!string) {
|
||||
return NULL;
|
||||
}
|
||||
#if TCL_UTF_MAX > 4
|
||||
|
||||
if (len < 0) {
|
||||
len = strlen(string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unicode string length in Tcl_UniChars will be <= UTF-8 string length in
|
||||
* bytes.
|
||||
*/
|
||||
|
||||
oldLength = Tcl_DStringLength(dsPtr);
|
||||
|
||||
Tcl_DStringSetLength(dsPtr,
|
||||
oldLength + (int) ((len + 1) * sizeof(TCHAR)));
|
||||
wString = (TCHAR *) (Tcl_DStringValue(dsPtr) + oldLength);
|
||||
|
||||
w = wString;
|
||||
p = string;
|
||||
end = string + len - 4;
|
||||
while (p < end) {
|
||||
p += TclUtfToUniChar(p, &ch);
|
||||
if (ch > 0xFFFF) {
|
||||
*w++ = (WCHAR) (0xD800 + ((ch -= 0x10000) >> 10));
|
||||
*w++ = (WCHAR) (0xDC00 | (ch & 0x3FF));
|
||||
} else {
|
||||
*w++ = ch;
|
||||
}
|
||||
}
|
||||
end += 4;
|
||||
while (p < end) {
|
||||
if (Tcl_UtfCharComplete(p, end-p)) {
|
||||
p += TclUtfToUniChar(p, &ch);
|
||||
} else {
|
||||
ch = UCHAR(*p++);
|
||||
}
|
||||
if (ch > 0xFFFF) {
|
||||
*w++ = (WCHAR) (0xD800 + ((ch -= 0x10000) >> 10));
|
||||
*w++ = (WCHAR) (0xDC00 | (ch & 0x3FF));
|
||||
} else {
|
||||
*w++ = ch;
|
||||
}
|
||||
}
|
||||
*w = '\0';
|
||||
Tcl_DStringSetLength(dsPtr,
|
||||
oldLength + ((char *) w - (char *) wString));
|
||||
|
||||
return wString;
|
||||
#else
|
||||
return (TCHAR *)Tcl_UtfToUniCharDString(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. */
|
||||
{
|
||||
return Tcl_ExternalToUtfDString(winTCharEncoding,
|
||||
(const char *) string, len, dsPtr);
|
||||
#if TCL_UTF_MAX > 4
|
||||
const WCHAR *w, *wEnd;
|
||||
char *p, *result;
|
||||
int oldLength, blen = 1;
|
||||
#endif
|
||||
|
||||
Tcl_DStringInit(dsPtr);
|
||||
if (!string) {
|
||||
return NULL;
|
||||
}
|
||||
if (len < 0) {
|
||||
len = wcslen((WCHAR *)string);
|
||||
} else {
|
||||
len /= 2;
|
||||
}
|
||||
#if TCL_UTF_MAX > 4
|
||||
oldLength = Tcl_DStringLength(dsPtr);
|
||||
Tcl_DStringSetLength(dsPtr, oldLength + (len + 1) * 4);
|
||||
result = Tcl_DStringValue(dsPtr) + oldLength;
|
||||
|
||||
p = result;
|
||||
wEnd = (WCHAR *)string + len;
|
||||
for (w = (WCHAR *)string; w < wEnd; ) {
|
||||
if (!blen && ((*w & 0xFC00) != 0xDC00)) {
|
||||
/* Special case for handling high surrogates. */
|
||||
p += Tcl_UniCharToUtf(-1, p);
|
||||
}
|
||||
blen = Tcl_UniCharToUtf(*w, p);
|
||||
p += blen;
|
||||
if ((*w >= 0xD800) && (blen < 3)) {
|
||||
/* Indication that high surrogate is handled */
|
||||
blen = 0;
|
||||
}
|
||||
w++;
|
||||
}
|
||||
if (!blen) {
|
||||
/* Special case for handling high surrogates. */
|
||||
p += Tcl_UniCharToUtf(-1, p);
|
||||
}
|
||||
Tcl_DStringSetLength(dsPtr, oldLength + (p - result));
|
||||
|
||||
return result;
|
||||
#else
|
||||
return Tcl_UniCharToUtfDString((Tcl_UniChar *)string, len, dsPtr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -610,7 +695,7 @@ TclWinCPUID(
|
||||
|
||||
#if defined(HAVE_INTRIN_H) && defined(_WIN64)
|
||||
|
||||
__cpuid(regsPtr, index);
|
||||
__cpuid((int *)regsPtr, index);
|
||||
status = TCL_OK;
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
Reference in New Issue
Block a user