diff options
author | sebres <sebres@users.sourceforge.net> | 2017-01-10 22:28:25 (GMT) |
---|---|---|
committer | sebres <sebres@users.sourceforge.net> | 2017-01-10 22:28:25 (GMT) |
commit | 5afae758b98de2da47b30d6aa4b40a5d5a604fbc (patch) | |
tree | 9bea9e914a912fb419e1f480d397197c4362a28a /generic/tclClock.c | |
parent | 7b6cd1089c2d3a6eeb8f12b106af40c18017c8f3 (diff) | |
download | tcl-5afae758b98de2da47b30d6aa4b40a5d5a604fbc.zip tcl-5afae758b98de2da47b30d6aa4b40a5d5a604fbc.tar.gz tcl-5afae758b98de2da47b30d6aa4b40a5d5a604fbc.tar.bz2 |
improve LocalizeFormat, internal caching of localized formats inside msgcat for locale and format objects
smart reference introduced in dict (smart pointer with 0 object reference but increase dict-reference, provide changeable locale dict)
Diffstat (limited to 'generic/tclClock.c')
-rw-r--r-- | generic/tclClock.c | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c index 166a4b3..e066812 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -60,6 +60,7 @@ typedef enum ClockLiteral { LIT_GETSYSTEMTIMEZONE, LIT_SETUPTIMEZONE, LIT_MCGET, LIT_TCL_CLOCK, + LIT_LOCALIZE_FORMAT, #if 0 LIT_FREESCAN, #endif @@ -82,7 +83,8 @@ static const char *const Literals[] = { "::tcl::clock::TZData", "::tcl::clock::GetSystemTimeZone", "::tcl::clock::SetupTimeZone", - "::msgcat::mcget", "::tcl::clock" + "::msgcat::mcget", "::tcl::clock", + "::tcl::clock::LocalizeFormat" #if 0 "::tcl::clock::FreeScan" #endif @@ -487,7 +489,6 @@ MODULE_SCOPE Tcl_Obj * ClockMCDict(ClockFmtScnCmdArgs *opts) { ClockClientData *dataPtr = opts->clientData; - Tcl_Obj *callargs[3]; /* if dict not yet retrieved */ if (opts->mcDictObj == NULL) { @@ -518,6 +519,7 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) } if (opts->mcDictObj == NULL) { + Tcl_Obj *callargs[3]; /* get msgcat dictionary - ::msgcat::mcget ::tcl::clock locale */ callargs[0] = dataPtr->literals[LIT_MCGET]; callargs[1] = dataPtr->literals[LIT_TCL_CLOCK]; @@ -528,6 +530,11 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) } opts->mcDictObj = Tcl_GetObjResult(opts->interp); + /* be sure that object reference not increases (dict changeable) */ + if (opts->mcDictObj->refCount > 0) { + /* smart reference (shared dict as object with no ref-counter) */ + opts->mcDictObj = Tcl_DictObjSmartRef(opts->interp, opts->mcDictObj); + } if ( opts->localeObj == dataPtr->CurrentLocale ) { Tcl_SetObjRef(dataPtr->CurrentLocaleDict, opts->mcDictObj); } else { @@ -535,6 +542,7 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) Tcl_UnsetObjRef(dataPtr->LastUnnormUsedLocale); Tcl_SetObjRef(dataPtr->LastUsedLocaleDict, opts->mcDictObj); } + Tcl_ResetResult(opts->interp); } } @@ -626,6 +634,56 @@ ClockMCGetListIdxDict( return valObj; } +MODULE_SCOPE Tcl_Obj * +ClockLocalizeFormat( + ClockFmtScnCmdArgs *opts) +{ + ClockClientData *dataPtr = opts->clientData; + Tcl_Obj *valObj, *keyObj; + + keyObj = ClockFrmObjGetLocFmtKey(opts->interp, opts->formatObj); + + if (opts->mcDictObj == NULL) { + ClockMCDict(opts); + if (opts->mcDictObj == NULL) + return NULL; + } + + /* try to find in cache within mc-catalog */ + if (Tcl_DictObjGet(NULL, opts->mcDictObj, + keyObj, &valObj) != TCL_OK) { + return NULL; + } + if (valObj == NULL) { + Tcl_Obj *callargs[4]; + /* call LocalizeFormat locale format fmtkey */ + callargs[0] = dataPtr->literals[LIT_LOCALIZE_FORMAT]; + callargs[1] = opts->localeObj; + callargs[2] = opts->formatObj; + callargs[3] = keyObj; + Tcl_IncrRefCount(keyObj); + if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK + ) { + Tcl_DecrRefCount(keyObj); + return NULL; + } + + valObj = Tcl_GetObjResult(opts->interp); + + if (Tcl_DictObjPut(opts->interp, opts->mcDictObj, + keyObj, valObj) != TCL_OK + ) { + Tcl_DecrRefCount(keyObj); + return NULL; + } + + Tcl_DecrRefCount(keyObj); + Tcl_ResetResult(opts->interp); + } + + return (opts->formatObj = valObj); +} + /* *---------------------------------------------------------------------- */ @@ -2936,7 +2994,7 @@ ClockScanObjCmd( #endif else { /* Use compiled version of Scan - */ - + ret = ClockScan(clientData, interp, info, objv[1], &opts); } |