summaryrefslogtreecommitdiffstats
path: root/library/clock.tcl
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2017-05-31 09:19:21 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2017-05-31 09:19:21 (GMT)
commit85d70230296a50fa8805dca4b6a7281746759c7a (patch)
tree59e94c5c206dc93a5e6ba9c3fd901a94e9bf52fd /library/clock.tcl
parentcef09a18ae9b1a55404db45ade312b06880c0f65 (diff)
parent91189c426903448dfa31ba4983c5d3035cb351a5 (diff)
downloadtcl-85d70230296a50fa8805dca4b6a7281746759c7a.zip
tcl-85d70230296a50fa8805dca4b6a7281746759c7a.tar.gz
tcl-85d70230296a50fa8805dca4b6a7281746759c7a.tar.bz2
merge core-8-6-branch (except: the "timerate" command and the clock performance-tests are kept)
Diffstat (limited to 'library/clock.tcl')
-rw-r--r--library/clock.tcl112
1 files changed, 99 insertions, 13 deletions
diff --git a/library/clock.tcl b/library/clock.tcl
index 94d2341..471deff 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]
}
- msgcat::mcget ::tcl::clock $locale {*}$args
+
+ # 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]
+ }
+ }
+ dict set mcMergedCat $loc $mrgcat
+ # return smart reference (shared dict as object with exact one ref-counter)
+ return [dict smartref $mrgcat]
}
#----------------------------------------------------------------------
@@ -741,7 +826,7 @@ proc ::tcl::clock::LoadWindowsDateTimeFormats { locale } {
proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } {
variable LocaleFormats
-
+
if { $fmtkey eq {} } { set fmtkey FMT_$format }
if { [catch {
set locfmt [dict get $LocaleFormats $locale $fmtkey]
@@ -751,10 +836,10 @@ proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } {
if { [catch {
set mlst [dict get $LocaleFormats $locale MLST]
}] } {
-
+
# message catalog dictionary:
set mcd [mcget $locale]
-
+
# Handle locale-dependent format groups by mapping them out of the format
# string. Note that the order of the [string map] operations is
# significant because later formats can refer to later ones; for example
@@ -779,7 +864,7 @@ proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } {
dict set LocaleFormats $locale MLST $mlst
}
- # translate copy of format (don't use format object here, because otherwise
+ # translate copy of format (don't use format object here, because otherwise
# it can lose its internal representation (string map - convert to unicode)
set locfmt [string map $mlst [string range " $format" 1 end]]
@@ -787,10 +872,10 @@ proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } {
dict set LocaleFormats $locale $fmtkey $locfmt
}
- # Save original format as long as possible, because of internal
+ # Save original format as long as possible, because of internal
# representation (performance).
# Note that in this case such format will be never localized (also
- # using another locales). To prevent this return a duplicate (but
+ # using another locales). To prevent this return a duplicate (but
# it may be slower).
if {$locfmt eq $format} {
set locfmt $format
@@ -849,7 +934,7 @@ proc ::tcl::clock::GetSystemTimeZone {} {
if { [dict exists $TimeZoneBad $timezone] } {
set timezone :localtime
}
-
+
# tell backend - current system timezone:
configure -system-tz $timezone
@@ -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 {}