diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2021-03-24 16:08:15 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2021-03-24 16:08:15 (GMT) |
commit | a820220b3d4be7f09e9eb56fa090642f316bf3fb (patch) | |
tree | 2b32739d41f5970b16ba31fffd44a398dee08481 /generic/tkIcu.c | |
parent | d6d676512fab10d31a6fc83012b29505d11a3a89 (diff) | |
download | tk-a820220b3d4be7f09e9eb56fa090642f316bf3fb.zip tk-a820220b3d4be7f09e9eb56fa090642f316bf3fb.tar.gz tk-a820220b3d4be7f09e9eb56fa090642f316bf3fb.tar.bz2 |
::tk::startOfCluster/::tk::endOfCluster are now giving the correct result on ICU 68 (or ICU 64 on XQuarz)
Diffstat (limited to 'generic/tkIcu.c')
-rw-r--r-- | generic/tkIcu.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/generic/tkIcu.c b/generic/tkIcu.c index 8fdd8df..fc112c5 100644 --- a/generic/tkIcu.c +++ b/generic/tkIcu.c @@ -36,6 +36,7 @@ typedef void *(*fn_icu_open)(UBreakIteratorTypex, const char *, typedef void (*fn_icu_close)(void *); typedef int32_t (*fn_icu_preceding)(void *, int32_t); typedef int32_t (*fn_icu_following)(void *, int32_t); +typedef void (*fn_icu_setText)(void *, const void *, int32_t, UErrorCodex *); static struct { int nopen; @@ -44,8 +45,9 @@ static struct { fn_icu_close close; fn_icu_preceding preceding; fn_icu_following following; + fn_icu_setText setText; } icu_fns = { - 0, NULL, NULL, NULL, NULL, NULL + 0, NULL, NULL, NULL, NULL, NULL, NULL }; #define FLAG_WORD 1 @@ -55,6 +57,7 @@ static struct { #define icu_close icu_fns.close #define icu_preceding icu_fns.preceding #define icu_following icu_fns.following +#define icu_setText icu_fns.setText TCL_DECLARE_MUTEX(icu_mutex); @@ -68,7 +71,7 @@ startEndOfCmd( Tcl_DString ds; TkSizeT len; const char *str; - UErrorCodex errorCode; + UErrorCodex errorCode = U_ZERO_ERRORZ; void *it; TkSizeT idx; int flags = PTR2INT(clientData); @@ -79,20 +82,30 @@ startEndOfCmd( } Tcl_DStringInit(&ds); str = Tcl_GetStringFromObj(objv[1], &len); - Tcl_UtfToChar16DString(str, len, &ds); - if (TkGetIntForIndex(objv[2], Tcl_DStringLength(&ds)/2-1, 1, &idx) != TCL_OK) { + Tcl_UtfToUniCharDString(str, len, &ds); + if (TkGetIntForIndex(objv[2], Tcl_DStringLength(&ds)/2-1, 0, &idx) != TCL_OK) { Tcl_DStringFree(&ds); Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", Tcl_GetString(objv[2]))); Tcl_SetErrorCode(interp, "TK", "ICU", "INDEX", NULL); return TCL_ERROR; } - it = icu_open((UBreakIteratorTypex)(PTR2INT(clientData)&3), "C", - (const uint16_t *)Tcl_DStringValue(&ds), -1, &errorCode); + it = icu_open((UBreakIteratorTypex)(PTR2INT(clientData)&3), NULL, + NULL, -1, &errorCode); + if (it != NULL) { + errorCode = U_ZERO_ERRORZ; + icu_setText(it, (const uint16_t *)Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)/2, &errorCode); + } + if (it == NULL || errorCode != U_ZERO_ERRORZ) { + Tcl_DStringFree(&ds); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("cannot open ICU iterator, errocode: %d", (int)errorCode)); + Tcl_SetErrorCode(interp, "TK", "ICU", "CANNOTOPEN", NULL); + return TCL_ERROR; + } if (flags & FLAG_FOLLOWING) { idx = icu_following(it, idx); } else { - idx = icu_preceding(it, idx); + idx = icu_preceding(it, idx + 1); } Tcl_SetObjResult(interp, TkNewIndexObj(idx)); icu_close(it); @@ -100,6 +113,13 @@ startEndOfCmd( return TCL_OK; } +#ifdef MAC_OSX_TCL +/* Hack, since homebrew doesn't have ICU 68 yet */ +#define ICU_VERSION "64" +#else +#define ICU_VERSION "68" +#endif + void Icu_Init( Tcl_Interp *interp) @@ -111,14 +131,14 @@ Icu_Init( Tcl_Obj *nameobj; static const char *iculibs[] = { #if defined(_WIN32) - "cygicuuc68.dll", - "icuuc68.dll", + "cygicuuc" ICU_VERSION ".dll", + "icuuc" ICU_VERSION ".dll", #elif defined(__CYGWIN__) - "cygicuuc68.dll", + "cygicuuc" ICU_VERSION ".dll", #elif defined(MAC_OSX_TCL) - "libicuuc68.dylib", + "libicuuc." ICU_VERSION ".dylib", #else - "libicuuc.so.68", + "libicuuc.so." ICU_VERSION "", #endif NULL }; @@ -144,11 +164,12 @@ Icu_Init( if (icu_fns.lib != NULL) { #define ICU_SYM(name) \ icu_fns.name = (fn_icu_ ## name) \ - Tcl_FindSymbol(NULL, icu_fns.lib, "ubrk_" #name "_68") + Tcl_FindSymbol(NULL, icu_fns.lib, "ubrk_" #name "_" ICU_VERSION) ICU_SYM(open); ICU_SYM(close); ICU_SYM(preceding); ICU_SYM(following); + ICU_SYM(setText); #undef ICU_SYM } } |