summaryrefslogtreecommitdiffstats
path: root/library
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2017-01-10 22:28:25 (GMT)
committersebres <sebres@users.sourceforge.net>2017-01-10 22:28:25 (GMT)
commit5afae758b98de2da47b30d6aa4b40a5d5a604fbc (patch)
tree9bea9e914a912fb419e1f480d397197c4362a28a /library
parent7b6cd1089c2d3a6eeb8f12b106af40c18017c8f3 (diff)
downloadtcl-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 'library')
-rwxr-xr-xlibrary/clock.tcl83
-rw-r--r--library/init.tcl2
-rw-r--r--library/msgcat/msgcat.tcl3
3 files changed, 57 insertions, 31 deletions
diff --git a/library/clock.tcl b/library/clock.tcl
index b4632b1..4173174 100755
--- a/library/clock.tcl
+++ b/library/clock.tcl
@@ -629,6 +629,8 @@ proc ::tcl::clock::Initialize {} {
# Caches
+ variable LocaleFormats {}; # Dictionary with localized formats
+
variable LocaleNumeralCache {}; # Dictionary whose keys are locale
# names and whose values are pairs
# comprising regexes matching numerals
@@ -2323,38 +2325,59 @@ proc ::tcl::clock::LoadWindowsDateTimeFormats { locale } {
#
#----------------------------------------------------------------------
-proc ::tcl::clock::LocalizeFormat { locale format } {
+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]
+ }] } {
- # message catalog key to cache this format
- set key FORMAT_$format
+ # get map list cached or build it:
+ if { [catch {
+ set mlst [dict get $LocaleFormats $locale MLST]
+ }] } {
+
+ # message catalog dictionary:
+ set mcd [::msgcat::mcget ::tcl::clock $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
+ # %c can refer to %X, which in turn can refer to %T.
+
+ set mlst {
+ %% %%
+ %D %m/%d/%Y
+ %+ {%a %b %e %H:%M:%S %Z %Y}
+ }
+ lappend mlst %EY [string map $mlst [dict get $mcd LOCALE_YEAR_FORMAT]]
+ lappend mlst %T [string map $mlst [dict get $mcd TIME_FORMAT_24_SECS]]
+ lappend mlst %R [string map $mlst [dict get $mcd TIME_FORMAT_24]]
+ lappend mlst %r [string map $mlst [dict get $mcd TIME_FORMAT_12]]
+ lappend mlst %X [string map $mlst [dict get $mcd TIME_FORMAT]]
+ lappend mlst %EX [string map $mlst [dict get $mcd LOCALE_TIME_FORMAT]]
+ lappend mlst %x [string map $mlst [dict get $mcd DATE_FORMAT]]
+ lappend mlst %Ex [string map $mlst [dict get $mcd LOCALE_DATE_FORMAT]]
+ lappend mlst %c [string map $mlst [dict get $mcd DATE_TIME_FORMAT]]
+ lappend mlst %Ec [string map $mlst [dict get $mcd LOCALE_DATE_TIME_FORMAT]]
+
+ dict set LocaleFormats $locale MLST $mlst
+ }
- if { [::msgcat::mcexists -exactlocale -exactnamespace $key] } {
- return [mc $key]
- }
- # 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
- # %c can refer to %X, which in turn can refer to %T.
-
- set list {
- %% %%
- %D %m/%d/%Y
- %+ {%a %b %e %H:%M:%S %Z %Y}
+ # translate:
+ set locfmt [string map $mlst $format]
+
+ # Save original format as long as possible, because of internal representation (performance)
+ if {$locfmt eq $format} {
+ set locfmt $format
+ }
+
+ # cache it:
+ dict set LocaleFormats $locale $fmtkey $locfmt
}
- lappend list %EY [string map $list [mc LOCALE_YEAR_FORMAT]]
- lappend list %T [string map $list [mc TIME_FORMAT_24_SECS]]
- lappend list %R [string map $list [mc TIME_FORMAT_24]]
- lappend list %r [string map $list [mc TIME_FORMAT_12]]
- lappend list %X [string map $list [mc TIME_FORMAT]]
- lappend list %EX [string map $list [mc LOCALE_TIME_FORMAT]]
- lappend list %x [string map $list [mc DATE_FORMAT]]
- lappend list %Ex [string map $list [mc LOCALE_DATE_FORMAT]]
- lappend list %c [string map $list [mc DATE_TIME_FORMAT]]
- lappend list %Ec [string map $list [mc LOCALE_DATE_TIME_FORMAT]]
- set format [string map $list $format]
-
- ::msgcat::mcset $locale $key $format
- return $format
+
+ return $locfmt
}
#----------------------------------------------------------------------
@@ -4437,6 +4460,7 @@ proc ::tcl::clock::ChangeCurrentLocale {args} {
proc ::tcl::clock::ClearCaches {} {
variable FormatProc
+ variable LocaleFormats
variable LocaleNumeralCache
variable TimeZoneBad
@@ -4451,6 +4475,7 @@ proc ::tcl::clock::ClearCaches {} {
}
unset -nocomplain FormatProc
+ set LocaleFormats {}
set LocaleNumeralCache {}
set TimeZoneBad {}
InitTZData
diff --git a/library/init.tcl b/library/init.tcl
index 06a9459..ef0a84a 100644
--- a/library/init.tcl
+++ b/library/init.tcl
@@ -178,7 +178,7 @@ if {[interp issafe]} {
# Auto-loading stubs for 'clock.tcl'
- foreach cmd {add format SetupTimeZone GetSystemTimeZone __org_scan} {
+ foreach cmd {add format LocalizeFormat SetupTimeZone GetSystemTimeZone __org_scan} {
proc ::tcl::clock::$cmd args {
variable TclLibDir
source -encoding utf-8 [file join $TclLibDir clock.tcl]
diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl
index 3fd2cdb..a25f6c8 100644
--- a/library/msgcat/msgcat.tcl
+++ b/library/msgcat/msgcat.tcl
@@ -947,7 +947,8 @@ proc msgcat::Merge {ns locales} {
}
}
dict set Merged $ns $loc $mrgcat
- return $mrgcat
+ # return smart reference (shared dict as object with exact one ref-counter)
+ return [dict smartref $mrgcat]
}
# msgcat::Invoke --