Skip to content

Commit b4e392a

Browse files
author
jan.nijtmans
committed
Fix [095db8b350]: ::tk::startOfCluster (and friends) only understand ICU locale syntax
2 parents 94b1d0e + 5f719b0 commit b4e392a

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ to the userbase.
5555
- [Aqua: avoid use-after-free during RefocusGrabWindow()](https://core.tcl-lang.org/tk/info/6da885)
5656
- [Aqua: ttk::notebook tabs](https://core.tcl-lang.org/tk/info/cf296a)
5757
- [Fix crash on exit due to faulty asm code in DllMain](https://core.tcl-lang.org/tk/info/44b34c)
58+
- [::tk::startOfCluster (and friends) only understand ICU locale syntax](https://core.tcl-lang.org/tk/info/095db8)
5859

5960
Release Tk 9.0.2 arises from the check-in with tag `core-9-0-2`.
6061

generic/tkIcu.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef int32_t (*fn_icu_following)(void *, int32_t);
3232
typedef int32_t (*fn_icu_previous)(void *);
3333
typedef int32_t (*fn_icu_next)(void *);
3434
typedef void (*fn_icu_setText)(void *, const void *, int32_t, UErrorCodex *);
35+
typedef int32_t (*fn_icu_canonicalize)(const char *, char *, int32_t, UErrorCodex *);
3536

3637
static struct {
3738
size_t nopen;
@@ -43,8 +44,9 @@ static struct {
4344
fn_icu_previous previous;
4445
fn_icu_next next;
4546
fn_icu_setText setText;
47+
fn_icu_canonicalize canonicalize;
4648
} icu_fns = {
47-
0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
49+
0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
4850
};
4951

5052
#define FLAG_WORD 1
@@ -58,6 +60,7 @@ static struct {
5860
#define icu_previous icu_fns.previous
5961
#define icu_next icu_fns.next
6062
#define icu_setText icu_fns.setText
63+
#define icu_canonicalize icu_fns.canonicalize
6164

6265
TCL_DECLARE_MUTEX(icu_mutex);
6366

@@ -76,17 +79,20 @@ startEndOfCmd(
7679
Tcl_Size idx;
7780
int flags = PTR2INT(clientData);
7881
const uint16_t *ustr;
79-
const char *locale = NULL;
82+
char locale[128];
8083

8184
if ((unsigned)(objc - 3) > 1) {
8285
Tcl_WrongNumArgs(interp, 1 , objv, "str start ?locale?");
8386
return TCL_ERROR;
8487
}
88+
locale[0] = '\0';
8589
if (objc > 3) {
86-
locale = Tcl_GetString(objv[3]);
87-
if (!*locale) {
88-
locale = NULL;
90+
if (!TkObjIsEmpty(objv[3]) && icu_canonicalize) {
91+
icu_canonicalize(Tcl_GetString(objv[3]), locale, sizeof(locale), &errorCode);
92+
} else {
93+
strncpy(locale, Tcl_GetString(objv[3]), sizeof(locale));
8994
}
95+
locale[sizeof(locale) - 1] = '\0';
9096
}
9197
Tcl_DStringInit(&ds);
9298
str = Tcl_GetStringFromObj(objv[1], &len);
@@ -99,7 +105,7 @@ startEndOfCmd(
99105
Tcl_SetErrorCode(interp, "TK", "ICU", "INDEX", (char *)NULL);
100106
return TCL_ERROR;
101107
}
102-
it = icu_open((UBreakIteratorTypex)(flags&3), locale,
108+
it = icu_open((UBreakIteratorTypex)(flags&3), locale[0] ? locale : NULL,
103109
NULL, -1, &errorCode);
104110
if (it != NULL) {
105111
errorCode = U_ZERO_ERRORZ;
@@ -298,6 +304,10 @@ Icu_Init(
298304
ICU_SYM(previous);
299305
ICU_SYM(next);
300306
ICU_SYM(setText);
307+
strcpy(symbol, "uloc_canonicalize");
308+
strcat(symbol, icuversion);
309+
icu_fns.canonicalize = (fn_icu_canonicalize)
310+
Tcl_FindSymbol(NULL, icu_fns.lib, symbol);
301311
#undef ICU_SYM
302312
}
303313
}

0 commit comments

Comments
 (0)