From d48588c89c7ec24c51b83911d5a5abd6c364b8e3 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 2 Jun 2017 20:08:55 +0000 Subject: Removed public interface to create smart-pointer to dictionaries "dict smartref", common locales catalog rewritten to hold internally onetime referenced merged locales (even as smart-ref). --- generic/tclClock.c | 45 +++++++++++++++++++++++++++++++-------------- generic/tclDate.h | 2 ++ generic/tclDictObj.c | 45 --------------------------------------------- library/clock.tcl | 8 +++----- 4 files changed, 36 insertions(+), 64 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 95b3e36..938e9fc 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -229,6 +229,7 @@ TclClockInit( } data->mcLiterals = NULL; data->mcLitIdxs = NULL; + data->mcMergedCat = NULL; data->LastTZEpoch = 0; data->currentYearCentury = ClockDefaultYearCentury; data->yearOfCenturySwitch = ClockDefaultCenturySwitch; @@ -308,15 +309,17 @@ ClockConfigureClear( Tcl_UnsetObjRef(data->LastSetupTZData); Tcl_UnsetObjRef(data->CurrentLocale); - Tcl_UnsetObjRef(data->CurrentLocaleDict); + data->CurrentLocaleDict = NULL; Tcl_UnsetObjRef(data->LastUnnormUsedLocale); Tcl_UnsetObjRef(data->LastUsedLocale); - Tcl_UnsetObjRef(data->LastUsedLocaleDict); + data->LastUsedLocaleDict = NULL; Tcl_UnsetObjRef(data->lastBase.timezoneObj); Tcl_UnsetObjRef(data->UTC2Local.timezoneObj); Tcl_UnsetObjRef(data->UTC2Local.tzName); Tcl_UnsetObjRef(data->Local2UTC.timezoneObj); + + Tcl_UnsetObjRef(data->mcMergedCat); } /* @@ -474,7 +477,7 @@ ClockGetCurrentLocale( } Tcl_SetObjRef(dataPtr->CurrentLocale, Tcl_GetObjResult(interp)); - Tcl_UnsetObjRef(dataPtr->CurrentLocaleDict); + dataPtr->CurrentLocaleDict = NULL; return dataPtr->CurrentLocale; } @@ -625,30 +628,44 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) if (opts->mcDictObj == NULL) { Tcl_Obj *callargs[2]; - /* get msgcat dictionary - ::tcl::clock::mcget locale */ - callargs[0] = dataPtr->literals[LIT_MCGET]; - callargs[1] = opts->localeObj; - if (Tcl_EvalObjv(opts->interp, 2, callargs, 0) != TCL_OK) { - return NULL; + /* first try to find it own catalog dict */ + if (dataPtr->mcMergedCat == NULL) { + dataPtr->mcMergedCat = Tcl_NewDictObj(); } + Tcl_DictObjGet(NULL, dataPtr->mcMergedCat, + opts->localeObj, &opts->mcDictObj); + + if (opts->mcDictObj == NULL) { + /* get msgcat dictionary - ::tcl::clock::mcget locale */ + callargs[0] = dataPtr->literals[LIT_MCGET]; + callargs[1] = opts->localeObj; - opts->mcDictObj = Tcl_GetObjResult(opts->interp); + if (Tcl_EvalObjv(opts->interp, 2, callargs, 0) != TCL_OK) { + return NULL; + } + + opts->mcDictObj = Tcl_GetObjResult(opts->interp); + Tcl_ResetResult(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); } + + Tcl_DictObjPut(NULL, dataPtr->mcMergedCat, opts->localeObj, + opts->mcDictObj); + if ( opts->localeObj == dataPtr->CurrentLocale ) { - Tcl_SetObjRef(dataPtr->CurrentLocaleDict, opts->mcDictObj); + dataPtr->CurrentLocaleDict = opts->mcDictObj; } else if ( opts->localeObj == dataPtr->LastUsedLocale ) { - Tcl_SetObjRef(dataPtr->LastUsedLocaleDict, opts->mcDictObj); + dataPtr->LastUsedLocaleDict = opts->mcDictObj; } else { Tcl_SetObjRef(dataPtr->LastUsedLocale, opts->localeObj); Tcl_UnsetObjRef(dataPtr->LastUnnormUsedLocale); - Tcl_SetObjRef(dataPtr->LastUsedLocaleDict, opts->mcDictObj); + dataPtr->LastUsedLocaleDict = opts->mcDictObj; } - Tcl_ResetResult(opts->interp); } } @@ -886,7 +903,7 @@ ClockConfigureObjCmd( if (i < objc) { if (dataPtr->CurrentLocale != objv[i]) { Tcl_SetObjRef(dataPtr->CurrentLocale, objv[i]); - Tcl_UnsetObjRef(dataPtr->CurrentLocaleDict); + dataPtr->CurrentLocaleDict = NULL; } } if (i+1 >= objc && dataPtr->CurrentLocale != NULL) { diff --git a/generic/tclDate.h b/generic/tclDate.h index 570a8e4..e2f7d88 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -281,6 +281,8 @@ typedef struct ClockClientData { Tcl_Obj **mcLitIdxs; /* Msgcat object indices prefixed with _IDX_, * used for quick dictionary search */ + Tcl_Obj *mcMergedCat; /* Msgcat collaction contains waek pointers to locale catalogs */ + /* Cache for current clock parameters, imparted via "configure" */ unsigned long LastTZEpoch; int currentYearCentury; diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 593f5a3..115927a 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -51,8 +51,6 @@ static int DictSetCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int DictSizeCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); -static int DictSmartRefCmd(ClientData dummy, Tcl_Interp *interp, - int objc, Tcl_Obj *const *objv); static int DictUnsetCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int DictUpdateCmd(ClientData dummy, Tcl_Interp *interp, @@ -100,7 +98,6 @@ static const EnsembleImplMap implementationMap[] = { {"replace", DictReplaceCmd, NULL, NULL, NULL, 0 }, {"set", DictSetCmd, TclCompileDictSetCmd, NULL, NULL, 0 }, {"size", DictSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 }, - {"smartref",DictSmartRefCmd,NULL, NULL, NULL, 0 }, {"unset", DictUnsetCmd, TclCompileDictUnsetCmd, NULL, NULL, 0 }, {"update", DictUpdateCmd, TclCompileDictUpdateCmd, NULL, NULL, 0 }, {"values", DictValuesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 }, @@ -2015,48 +2012,6 @@ Tcl_DictObjSmartRef( /* *---------------------------------------------------------------------- * - * DictSmartRefCmd -- - * - * This function implements the "dict smartref" Tcl command. - * - * See description of Tcl_DictObjSmartRef for details. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -DictSmartRefCmd( - ClientData dummy, - Tcl_Interp *interp, - int objc, - Tcl_Obj *const *objv) -{ - Tcl_Obj *result; - - if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "dictionary"); - return TCL_ERROR; - } - - result = Tcl_DictObjSmartRef(interp, objv[1]); - if (result == NULL) { - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, result); - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * * DictExistsCmd -- * * This function implements the "dict exists" Tcl command. See the user diff --git a/library/clock.tcl b/library/clock.tcl index 471deff..bc648c5 100644 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -544,8 +544,7 @@ proc mcget {loc} { # try to retrieve now if already available: if {[dict exists $mcMergedCat $loc]} { - set mrgcat [dict get $mcMergedCat $loc] - return [dict smartref $mrgcat] + return [dict get $mcMergedCat $loc] } # get locales list for given locale (de_de -> {de_de de {}}) @@ -581,8 +580,7 @@ proc mcget {loc} { proc mcMerge {locales} { variable mcMergedCat if {[dict exists $mcMergedCat [set loc [lindex $locales 0]]]} { - set mrgcat [dict get $mcMergedCat $loc] - return [dict smartref $mrgcat] + return [dict get $mcMergedCat $loc] } # package msgcat currently does not provide possibility to get whole catalog: upvar ::msgcat::Msgs Msgs @@ -602,7 +600,7 @@ proc mcMerge {locales} { } dict set mcMergedCat $loc $mrgcat # return smart reference (shared dict as object with exact one ref-counter) - return [dict smartref $mrgcat] + return $mrgcat } #---------------------------------------------------------------------- -- cgit v0.12