From 15cfba832c9f08a08f59acbaa8ed97383634359e Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 30 May 2017 16:41:48 +0000 Subject: [msgcat] revert changes of "msgcat" to previous state before clock-speedup, move this functionality to "clock.tcl"; additionally avoids the usage of catch (uses pair "dict exists/dict get" instead of). --- library/clock.tcl | 98 +++++++++++++++++++++++++++++++++--- library/msgcat/msgcat.tcl | 125 ++-------------------------------------------- tests/msgcat.test | 2 +- 3 files changed, 98 insertions(+), 127 deletions(-) diff --git a/library/clock.tcl b/library/clock.tcl index 94d2341..1f3c669 100644 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -506,18 +506,103 @@ proc ::tcl::clock::Initialize {} { variable FormatProc; # Array mapping format group # and locale to the name of a procedure # that renders the given format + + variable mcLocales [dict create]; # Dictionary with loaded locales + variable mcMergedCat [dict create]; # Dictionary with merged locale catalogs } ::tcl::clock::Initialize #---------------------------------------------------------------------- -proc mcget {locale args} { - switch -- $locale system { - set locale [GetSystemLocale] +# mcget -- +# +# Return the merged translation catalog for the ::tcl::clock namespace +# Searching of catalog is similar to "msgcat::mc". +# +# Contrary to "msgcat::mc" may additionally load a package catalog +# on demand. +# +# Arguments: +# loc The locale used for translation. +# +# Results: +# Returns the dictionary object as whole catalog of the package/locale. +# +proc mcget {loc} { + variable mcMergedCat + switch -- $loc system { + set loc [GetSystemLocale] } current { - set locale [mclocale] + set loc [mclocale] + } + if {$loc eq {C}} { + set loclist [msgcat::PackagePreferences ::tcl::clock] + set loc [lindex $loclist 0] + } else { + set loc [string tolower $loc] + } + + # try to retrieve now if already available: + if {[dict exists $mcMergedCat $loc]} { + set mrgcat [dict get $mcMergedCat $loc] + return [dict smartref $mrgcat] + } + + # get locales list for given locale (de_de -> {de_de de {}}) + variable mcLocales + if {[dict exists $mcLocales $loc]} { + set loclist [dict get $mcLocales $loc] + } else { + # save current locale: + set prevloc [mclocale] + # lazy load catalog on demand (set it will load the catalog) + mcpackagelocale set $loc + set loclist [msgcat::GetPreferences $loc] + dict set $mcLocales $loc $loclist + # restore: + if {$prevloc ne $loc} { + mcpackagelocale set $prevloc + } + } + # get whole catalog: + mcMerge $loclist +} + +# mcMerge -- +# +# Merge message catalog dictionaries to one dictionary. +# +# Arguments: +# locales List of locales to merge. +# +# Results: +# Returns the (weak pointer) to merged dictionary of message catalog. +# +proc mcMerge {locales} { + variable mcMergedCat + if {[dict exists $mcMergedCat [set loc [lindex $locales 0]]]} { + set mrgcat [dict get $mcMergedCat $loc] + return [dict smartref $mrgcat] + } + # package msgcat currently does not provide possibility to get whole catalog: + upvar ::msgcat::Msgs Msgs + set ns ::tcl::clock + # Merge sequential locales (in reverse order, e. g. {} -> en -> en_en): + if {[llength $locales] > 1} { + set mrgcat [mcMerge [lrange $locales 1 end]] + if {[dict exists $Msgs $ns $loc]} { + set mrgcat [dict merge $mrgcat [dict get $Msgs $ns $loc]] + } + } else { + if {[dict exists $Msgs $ns $loc]} { + set mrgcat [dict get $Msgs $ns $loc] + } else { + set mrgcat [dict create] + } } - msgcat::mcget ::tcl::clock $locale {*}$args + dict set mcMergedCat $loc $mrgcat + # return smart reference (shared dict as object with exact one ref-counter) + return [dict smartref $mrgcat] } #---------------------------------------------------------------------- @@ -2004,13 +2089,14 @@ proc ::tcl::clock::ClearCaches {} { variable FormatProc variable LocaleFormats variable LocaleNumeralCache + variable mcMergedCat variable TimeZoneBad # tell backend - should invalidate: configure -clear # clear msgcat cache: - msgcat::ClearCaches ::tcl::clock + set mcMergedCat [dict create] foreach p [info procs [namespace current]::scanproc'*] { rename $p {} diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index f9f57db..928474d 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -225,65 +225,6 @@ proc msgcat::mc {src args} { } } -# msgcat::mcget -- -# -# Return the translation for the given string based on the given -# locale setting or the whole dictionary object of the package/locale. -# Searching of catalog is similar to "msgcat::mc". -# -# Contrary to "msgcat::mc" may additionally load a package catalog -# on demand. -# -# Arguments: -# ns The package namespace (as catalog selector). -# loc The locale used for translation. -# {src} The string to translate. -# {args} Args to pass to the format command -# -# Results: -# Returns the translated string. Propagates errors thrown by the -# format command. - -proc msgcat::mcget {ns loc args} { - if {$loc eq {C}} { - set loclist [PackagePreferences $ns] - set loc [lindex $loclist 0] - } else { - set loc [string tolower $loc] - variable PackageConfig - # get locales list for given locale (de_de -> {de_de de {}}) - if {[catch { - set loclist [dict get $PackageConfig locales $ns $loc] - }]} { - # lazy load catalog on demand - mcpackagelocale load $loc $ns - set loclist [dict get $PackageConfig locales $ns $loc] - } - } - if {![llength $args]} { - # get whole catalog: - return [msgcat::Merge $ns $loclist] - } - set src [lindex $args 0] - # search translation for each locale (regarding parent namespaces) - for {set nscur $ns} {$nscur != ""} {set nscur [namespace parent $nscur]} { - foreach loc $loclist { - set msgs [mcget $nscur $loc] - if {![catch { set val [dict get $msgs $src] }]} { - if {[llength $args] == 1} { - return $val - } - return [format $val {*}[lrange $args 1 end]] - } - } - } - # no translation : - if {[llength $args] == 1} { - return $src - } - return [format $src {*}[lrange $args 1 end]] -} - # msgcat::mcexists -- # # Check if a catalog item is set or if mc would invoke mcunknown. @@ -474,10 +415,6 @@ proc msgcat::mcloadedlocales {subcommand} { # items, if the former locale was the default locale. # Returns the normalized set locale. # The default locale is taken, if locale is not given. -# load -# Load a package locale without set it (lazy loading from mcget). -# Returns the normalized set locale. -# The default locale is taken, if locale is not given. # get # Get the locale valid for this package. # isset @@ -505,7 +442,7 @@ proc msgcat::mcloadedlocales {subcommand} { # Results: # Empty string, if not stated differently for the subcommand -proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { +proc msgcat::mcpackagelocale {subcommand {locale ""}} { # todo: implement using an ensemble variable Loclist variable LoadedLocales @@ -525,9 +462,7 @@ proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { } set locale [string tolower $locale] } - if {$ns eq ""} { - set ns [uplevel 1 {::namespace current}] - } + set ns [uplevel 1 {::namespace current}] switch -exact -- $subcommand { get { return [lindex [PackagePreferences $ns] 0] } @@ -535,7 +470,7 @@ proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { loaded { return [PackageLocales $ns] } present { return [expr {$locale in [PackageLocales $ns]} ]} isset { return [dict exists $PackageConfig loclist $ns] } - set - load { # set a package locale or add a package locale + set { # set a package locale or add a package locale # Copy the default locale if no package locale set so far if {![dict exists $PackageConfig loclist $ns]} { @@ -545,21 +480,17 @@ proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { # Check if changed set loclist [dict get $PackageConfig loclist $ns] - if {[llength [info level 0]] == 2 || $locale eq [lindex $loclist 0] } { + if {! [info exists locale] || $locale eq [lindex $loclist 0] } { return [lindex $loclist 0] } # Change loclist set loclist [GetPreferences $locale] set locale [lindex $loclist 0] - if {$subcommand eq {set}} { - # set loclist - dict set PackageConfig loclist $ns $loclist - } + dict set PackageConfig loclist $ns $loclist # load eventual missing locales set loadedLocales [dict get $PackageConfig loadedlocales $ns] - dict set PackageConfig locales $ns $locale $loclist if {$locale in $loadedLocales} { return $locale } set loadLocales [ListComplement $loadedLocales $loclist] dict set PackageConfig loadedlocales $ns\ @@ -590,7 +521,6 @@ proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { [dict get $PackageConfig loadedlocales $ns] $LoadedLocales] dict unset PackageConfig loadedlocales $ns dict unset PackageConfig loclist $ns - dict unset PackageConfig locales $ns # unset keys not in global loaded locales if {[dict exists $Msgs $ns]} { @@ -917,47 +847,6 @@ proc msgcat::Load {ns locales {callbackonly 0}} { return $x } -# msgcat::Merge -- -# -# Merge message catalog dictionaries to one dictionary. -# -# Arguments: -# ns Namespace (equal package) to load the message catalog. -# locales List of locales to merge. -# -# Results: -# Returns the merged dictionary of message catalogs. -proc msgcat::Merge {ns locales} { - variable Merged - if {![catch { - set mrgcat [dict get $Merged $ns [set loc [lindex $locales 0]]] - }]} { - return $mrgcat - } - variable Msgs - # Merge sequential locales (in reverse order, e. g. {} -> en -> en_en): - if {[llength $locales] > 1} { - set mrgcat [msgcat::Merge $ns [lrange $locales 1 end]] - catch { - set mrgcat [dict merge $mrgcat [dict get $Msgs $ns $loc]] - } - } else { - if {[catch { - set mrgcat [dict get $Msgs $ns $loc] - }]} { - set mrgcat [dict create] - } - } - dict set Merged $ns $loc $mrgcat - # return smart reference (shared dict as object with exact one ref-counter) - return [dict smartref $mrgcat] -} - -proc msgcat::ClearCaches {ns} { - variable Merged - dict unset Merged $ns -} - # msgcat::Invoke -- # # Invoke a set of registered callbacks. @@ -1030,7 +919,6 @@ proc msgcat::Invoke {index arglist {ns ""} {resultname ""} {failerror 0}} { proc msgcat::mcset {locale src {dest ""}} { variable Msgs - variable Merged if {[llength [info level 0]] == 3} { ;# dest not specified set dest $src } @@ -1040,7 +928,6 @@ proc msgcat::mcset {locale src {dest ""}} { set locale [string tolower $locale] dict set Msgs $ns $locale $src $dest - dict unset Merged $ns return $dest } @@ -1080,7 +967,6 @@ proc msgcat::mcflset {src {dest ""}} { proc msgcat::mcmset {locale pairs} { variable Msgs - variable Merged set length [llength $pairs] if {$length % 2} { @@ -1094,7 +980,6 @@ proc msgcat::mcmset {locale pairs} { foreach {src dest} $pairs { dict set Msgs $ns $locale $src $dest } - dict unset Merged $ns return [expr {$length / 2}] } diff --git a/tests/msgcat.test b/tests/msgcat.test index 584e420..1c3ce58 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -811,7 +811,7 @@ namespace eval ::msgcat::test { test msgcat-12.1 {mcpackagelocale no subcommand} -body { mcpackagelocale } -returnCodes 1\ - -result {wrong # args: should be "mcpackagelocale subcommand ?locale? ?ns?"} + -result {wrong # args: should be "mcpackagelocale subcommand ?locale?"} test msgcat-12.2 {mclpackagelocale wrong subcommand} -body { mcpackagelocale junk -- cgit v0.12