Skip to content

Commit

Permalink
Handle Tcl_UtfToUniChar/Tcl_UniCharToUtf correctly as well
Browse files Browse the repository at this point in the history
  • Loading branch information
jan.nijtmans committed Mar 14, 2024
1 parent fa083c8 commit a4b5a1d
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 27 deletions.
17 changes: 6 additions & 11 deletions generic/tkInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,23 @@
#endif

#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 7)
# define Tcl_WCharToUtfDString ((char * (*)(const WCHAR *, int len, Tcl_DString *))Tcl_UniCharToUtfDString)
# define Tcl_UtfToWCharDString ((WCHAR * (*)(const char *, int len, Tcl_DString *))Tcl_UtfToUniCharDString)
# define Tcl_WCharToUtfDString ((char * (*)(const WCHAR *, int, Tcl_DString *))Tcl_UniCharToUtfDString)
# define Tcl_UtfToWCharDString ((WCHAR * (*)(const char *, int, Tcl_DString *))Tcl_UtfToUniCharDString)
# define Tcl_Char16ToUtfDString Tcl_UniCharToUtfDString
# define Tcl_UtfToChar16DString Tcl_UtfToUniCharDString
# define TCL_COMBINE 0
#endif

/* Make available UTF-32 versions of the API, even though we compile with TCL_UTF_MAX=3 */
#if TCL_MAJOR_VERSION > 8
# define TkUtfToUniChar (tclStubsPtr->tcl_UtfToUniChar) /* 646 */
# define TkUniCharToUtf (tclStubsPtr->tcl_UniCharToUtf) /* 324 (without TCL_COMBINE) */
# define TkNumUtfChars (tclStubsPtr->tcl_NumUtfChars) /* 669 */
# define TkGetCharLength (tclStubsPtr->tcl_GetCharLength) /* 670 */
# define TkUtfAtIndex (tclStubsPtr->tcl_UtfAtIndex) /* 671 */
#else
MODULE_SCOPE Tcl_Size TkUtfToUniChar(const char *, int *);
MODULE_SCOPE Tcl_Size TkUniCharToUtf(int, char *);
# define TkNumUtfChars (((&tclStubsPtr->tcl_PkgProvideEx)[631]) ? \
((Tcl_Size (*)(const char *, Tcl_Size))(void *)((&tclStubsPtr->tcl_PkgProvideEx)[669])) \
: (tclStubsPtr->tcl_NumUtfChars) /* 312 */)
Expand Down Expand Up @@ -1394,15 +1398,6 @@ MODULE_SCOPE void TkpCopyRegion(TkRegion dst, TkRegion src);
# define c_class class
#endif

/* Tcl 8.6 has a different definition of Tcl_UniChar than other Tcl versions for TCL_UTF_MAX > 3 */
#if TCL_UTF_MAX > (3 + (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 6))
# define TkUtfToUniChar(src, ch) (size_t)(((int (*)(const char *, int *))Tcl_UtfToUniChar)(src, ch))
# define TkUniCharToUtf(ch, src) (size_t)(((int (*)(int, char *))Tcl_UniCharToUtf)(ch, src))
#else
MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *);
MODULE_SCOPE size_t TkUniCharToUtf(int, char *);
#endif

#if defined(_WIN32) && !defined(STATIC_BUILD) && TCL_MAJOR_VERSION < 9
# define tcl_CreateFileHandler reserved9
#endif
Expand Down
20 changes: 9 additions & 11 deletions generic/tkUtil.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,8 +1246,7 @@ Tk_SendVirtualEvent(
Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}

/* Tcl 8.6 has a different definition of Tcl_UniChar than other Tcl versions for TCL_UTF_MAX > 3 */
#if TCL_UTF_MAX <= (3 + (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 6))
#if TCL_MAJOR_VERSION < 9
/*
*---------------------------------------------------------------------------
*
Expand All @@ -1267,20 +1266,19 @@ Tk_SendVirtualEvent(
*---------------------------------------------------------------------------
*/

size_t
Tcl_Size
TkUtfToUniChar(
const char *src, /* The UTF-8 string. */
int *chPtr) /* Filled with the Unicode value represented by
* the UTF-8 string. */
{
Tcl_UniChar uniChar = 0;

size_t len = Tcl_UtfToUniChar(src, &uniChar);
Tcl_Size len = Tcl_UtfToUniChar(src, &uniChar);
if ((uniChar & 0xFC00) == 0xD800) {
Tcl_UniChar low = uniChar;
/* This can only happen if sizeof(Tcl_UniChar)== 2 and src points
* to a character > U+FFFF */
size_t len2 = Tcl_UtfToUniChar(src+len, &low);
/* This can only happen if src points to a character > U+FFFF */
Tcl_Size len2 = Tcl_UtfToUniChar(src+len, &low);
if ((low & 0xFC00) == 0xDC00) {
*chPtr = (((uniChar & 0x3FF) << 10) | (low & 0x3FF)) + 0x10000;
return len + len2;
Expand Down Expand Up @@ -1309,12 +1307,12 @@ TkUtfToUniChar(
*---------------------------------------------------------------------------
*/

size_t TkUniCharToUtf(int ch, char *buf)
Tcl_Size TkUniCharToUtf(int ch, char *buf)
{
if ((unsigned)(ch - 0x10000) <= 0xFFFFF) {
/* Spit out a 4-byte UTF-8 character or 2 x 3-byte UTF-8 characters, depending on Tcl
* version and/or TCL_UTF_MAX build value */
int len = Tcl_UniCharToUtf(0xD800 | ((ch - 0x10000) >> 10), buf);
/* Spit out a 4-byte UTF-8 character (Tcl 8.7+) or
* 2 x 3-byte UTF-8 characters (Tcl 8.6) */
Tcl_Size len = Tcl_UniCharToUtf(0xD800 | ((ch - 0x10000) >> 10), buf);
return len + Tcl_UniCharToUtf(0xDC00 | (ch & 0x7FF), buf + len);
}
return Tcl_UniCharToUtf(ch, buf);
Expand Down
3 changes: 0 additions & 3 deletions generic/tkWindow.c
Original file line number Diff line number Diff line change
Expand Up @@ -1028,9 +1028,6 @@ TkCreateMainWindow(
#ifdef STATIC_BUILD
".static"
#endif
#if TCL_UTF_MAX <= (3 + (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 6))
".utf-16"
#endif
#if defined(_WIN32)
".win32"
#endif
Expand Down
4 changes: 2 additions & 2 deletions macosx/tkMacOSXPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,8 +532,8 @@ VISIBILITY_HIDDEN
* NSString class does not provide a constructor which accepts a CESU-8 encoded
* byte sequence as initial data. So we add a new class which does provide
* such a constructor. It also has a DString property which is a DString whose
* string pointer is a byte sequence encoding the NSString with the current Tk
* encoding, namely UTF-8 if TCL_UTF_MAX >= 4 or CESU-8 if TCL_UTF_MAX = 3.
* string pointer is a byte sequence encoding the NSString with the current Tcl
* internal encoding, namely UTF-8 for Tcl8.7+ or CESU-8 otherwise.
*
*---------------------------------------------------------------------------
*/
Expand Down

0 comments on commit a4b5a1d

Please sign in to comment.