diff options
Diffstat (limited to 'generic/tkIcu.c')
-rw-r--r-- | generic/tkIcu.c | 89 |
1 files changed, 83 insertions, 6 deletions
diff --git a/generic/tkIcu.c b/generic/tkIcu.c index 23ccbaa..8fdd8df 100644 --- a/generic/tkIcu.c +++ b/generic/tkIcu.c @@ -11,6 +11,13 @@ */ #include "tkInt.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif /* * Runtime linking of libicu. @@ -41,6 +48,9 @@ static struct { 0, NULL, NULL, NULL, NULL, NULL }; +#define FLAG_WORD 1 +#define FLAG_FOLLOWING 4 + #define icu_open icu_fns.open #define icu_close icu_fns.close #define icu_preceding icu_fns.preceding @@ -48,19 +58,77 @@ static struct { TCL_DECLARE_MUTEX(icu_mutex); -int +static int +startEndOfCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + Tcl_DString ds; + TkSizeT len; + const char *str; + UErrorCodex errorCode; + void *it; + TkSizeT idx; + int flags = PTR2INT(clientData); + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1 , objv, "str start"); + return TCL_ERROR; + } + 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_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); + if (flags & FLAG_FOLLOWING) { + idx = icu_following(it, idx); + } else { + idx = icu_preceding(it, idx); + } + Tcl_SetObjResult(interp, TkNewIndexObj(idx)); + icu_close(it); + Tcl_DStringFree(&ds); + return TCL_OK; +} + +void Icu_Init( Tcl_Interp *interp) { Tcl_MutexLock(&icu_mutex); + if (icu_fns.nopen == 0) { int i = 0; Tcl_Obj *nameobj; static const char *iculibs[] = { - "libicuuc68.so", +#if defined(_WIN32) + "cygicuuc68.dll", + "icuuc68.dll", +#elif defined(__CYGWIN__) + "cygicuuc68.dll", +#elif defined(MAC_OSX_TCL) + "libicuuc68.dylib", +#else + "libicuuc.so.68", +#endif NULL }; +#if defined(_WIN32) && !defined(STATIC_BUILD) + if (!tclStubsPtr->tcl_CreateFileHandler) { + /* Not running on Cygwin, so don't try to load the cygwin icu dll */ + i++; + } +#endif while (iculibs[i] != NULL) { Tcl_ResetResult(interp); nameobj = Tcl_NewStringObj(iculibs[i], -1); @@ -76,7 +144,7 @@ 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 "_86") + Tcl_FindSymbol(NULL, icu_fns.lib, "ubrk_" #name "_68") ICU_SYM(open); ICU_SYM(close); ICU_SYM(preceding); @@ -87,9 +155,18 @@ Icu_Init( icu_fns.nopen++; Tcl_MutexUnlock(&icu_mutex); - //Tcl_CreateObjCommand(interp, "::tk::endOfCluster", endOfClusterCmd, - // interp, NULL); - return TCL_OK; + if (icu_fns.lib != NULL) { + Tcl_CreateObjCommand(interp, "::tk::startOfCluster", startEndOfCmd, + INT2PTR(0), NULL); + Tcl_CreateObjCommand(interp, "::tk::startOfNextWord", startEndOfCmd, + INT2PTR(FLAG_WORD|FLAG_FOLLOWING), NULL); + Tcl_CreateObjCommand(interp, "::tk::startOfPreviousWord", startEndOfCmd, + INT2PTR(FLAG_WORD), NULL); + Tcl_CreateObjCommand(interp, "::tk::endOfCluster", startEndOfCmd, + INT2PTR(FLAG_FOLLOWING), NULL); + Tcl_CreateObjCommand(interp, "::tk::endOfWord", startEndOfCmd, + INT2PTR(FLAG_WORD|FLAG_FOLLOWING), NULL); + } } /* |