1#----------------------------------------------------------------------
2#
3# loadICU,tcl --
4#
5#	Extracts locale strings from a distribution of ICU
6#	(http://oss.software.ibm.com/developerworks/opensource/icu/project/)
7#	and makes Tcl message catalogs for the 'clock' command.
8#
9# Usage:
10#	loadICU.tcl sourceDir destDir
11#
12# Parameters:
13#	sourceDir -- Path name of the 'data' directory of your ICU4C
14#		     distribution.
15#	destDir -- Directory into which the Tcl message catalogs should go.
16#
17# Results:
18#	None.
19#
20# Side effects:
21#	Creates the message catalogs.
22#
23#----------------------------------------------------------------------
24#
25# Copyright (c) 2004 by Kevin B. Kenny.  All rights reserved.
26# See the file "license.terms" for information on usage and redistribution
27# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
28#----------------------------------------------------------------------
29
30# Calculate the Chinese numerals from zero to ninety-nine.
31
32set zhDigits [list {} \u4e00 \u4e8c \u4e09 \u56db \
33		  \u4e94 \u516d \u4e03 \u516b \u4e5d]
34set t 0
35foreach zt $zhDigits {
36    if { $t == 0 } {
37	set zt {}
38    } elseif { $t == 10 } {
39	set zt \u5341
40    } else {
41	append zt \u5341
42    }
43    set d 0
44    foreach zd $zhDigits {
45	if { $t == 0 && $d == 0 } {
46	    set zd \u3007
47	} elseif { $t == 20 && $d != 0 } {
48	    set zt \u5eff
49	} elseif { $t == 30 && $d != 0 } {
50	    set zt \u5345
51	}
52	lappend zhNumbers $zt$zd
53	incr d
54    }
55    incr t 10
56}
57
58# Set format overrides for various locales.
59
60set format(zh,LOCALE_NUMERALS) $zhNumbers
61set format(ja,LOCALE_ERAS) [list \
62				[list -9223372036854775808 \u897f\u66a6 0 ] \
63				[list -3061011600 \u660e\u6cbb 1867] \
64				[list -1812186000 \u5927\u6b63 1911] \
65				[list -1357635600 \u662d\u548c 1925] \
66				[list 600220800 \u5e73\u6210 1988]]
67set format(zh,LOCALE_DATE_FORMAT) "\u516c\u5143%Y\u5e74%B%Od\u65E5"
68set format(ja,LOCALE_DATE_FORMAT) "%EY\u5e74%m\u6708%d\u65E5"
69set format(ko,LOCALE_DATE_FORMAT) "%Y\ub144%B%Od\uc77c"
70set format(zh,LOCALE_TIME_FORMAT) "%OH\u65f6%OM\u5206%OS\u79d2"
71set format(ja,LOCALE_TIME_FORMAT) "%H\u6642%M\u5206%S\u79d2"
72set format(ko,LOCALE_TIME_FORMAT) "%H\uc2dc%M\ubd84%S\ucd08"
73set format(zh,LOCALE_DATE_TIME_FORMAT) "%A %Y\u5e74%B%Od\u65E5%OH\u65f6%OM\u5206%OS\u79d2 %z"
74set format(ja,LOCALE_DATE_TIME_FORMAT) "%EY\u5e74%m\u6708%d\u65E5 (%a) %H\u6642%M\u5206%S\u79d2 %z"
75set format(ko,LOCALE_DATE_TIME_FORMAT) "%A %Y\ub144%B%Od\uc77c%H\uc2dc%M\ubd84%S\ucd08 %z"
76set format(ja,TIME_FORMAT_12) {%P %I:%M:%S}
77
78# The next set of format overrides were obtained from the glibc
79# localization strings.
80
81set format(cs_CZ,DATE_FORMAT) %d.%m.%Y
82set format(cs_CZ,DATE_TIME_FORMAT) {%a %e. %B %Y, %H:%M:%S %z}
83set format(cs_CZ,TIME_FORMAT) %H:%M:%S
84set format(cs_CZ,TIME_FORMAT_12) %I:%M:%S
85set format(da_DK,DATE_FORMAT) %d-%m-%Y
86set format(da_DK,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
87set format(da_DK,TIME_FORMAT) %T
88set format(da_DK,TIME_FORMAT_12) %T
89set format(de_AT,DATE_FORMAT) %Y-%m-%d
90set format(de_AT,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
91set format(de_AT,TIME_FORMAT) %T
92set format(de_AT,TIME_FORMAT_12) %T
93set format(de_BE,DATE_FORMAT) %Y-%m-%d
94set format(de_BE,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
95set format(de_BE,TIME_FORMAT) %T
96set format(de_BE,TIME_FORMAT_12) %T
97set format(de_CH,DATE_FORMAT) %Y-%m-%d
98set format(de_CH,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
99set format(de_CH,TIME_FORMAT) %T
100set format(de_CH,TIME_FORMAT_12) %T
101set format(de_DE,DATE_FORMAT) %Y-%m-%d
102set format(de_DE,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
103set format(de_DE,TIME_FORMAT) %T
104set format(de_DE,TIME_FORMAT_12) %T
105set format(de_LU,DATE_FORMAT) %Y-%m-%d
106set format(de_LU,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
107set format(de_LU,TIME_FORMAT) %T
108set format(de_LU,TIME_FORMAT_12) %T
109set format(en_CA,DATE_FORMAT) %d/%m/%y
110set format(en_CA,DATE_TIME_FORMAT) {%a %d %b %Y %r %z}
111set format(en_CA,TIME_FORMAT) %r
112set format(en_CA,TIME_FORMAT_12) {%I:%M:%S %p}
113set format(en_DK,DATE_FORMAT) %Y-%m-%d
114set format(en_DK,DATE_TIME_FORMAT) {%Y-%m-%dT%T %z}
115set format(en_DK,TIME_FORMAT) %T
116set format(en_DK,TIME_FORMAT_12) %T
117set format(en_GB,DATE_FORMAT) %d/%m/%y
118set format(en_GB,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
119set format(en_GB,TIME_FORMAT) %T
120set format(en_GB,TIME_FORMAT_12) %T
121set format(en_IE,DATE_FORMAT) %d/%m/%y
122set format(en_IE,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
123set format(en_IE,TIME_FORMAT) %T
124set format(en_IE,TIME_FORMAT_12) %T
125set format(en_US,DATE_FORMAT) %m/%d/%y
126set format(en_US,DATE_TIME_FORMAT) {%a %d %b %Y %r %z}
127set format(en_US,TIME_FORMAT) %r
128set format(en_US,TIME_FORMAT_12) {%I:%M:%S %p}
129set format(es_ES,DATE_FORMAT) %d/%m/%y
130set format(es_ES,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
131set format(es_ES,TIME_FORMAT) %T
132set format(es_ES,TIME_FORMAT_12) %T
133set format(et_EE,DATE_FORMAT) %d.%m.%Y
134set format(et_EE,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
135set format(et_EE,TIME_FORMAT) %T
136set format(et_EE,TIME_FORMAT_12) %T
137set format(eu_ES,DATE_FORMAT) {%a, %Yeko %bren %da}
138set format(eu_ES,DATE_TIME_FORMAT) {%y-%m-%d %T %z}
139set format(eu_ES,TIME_FORMAT) %T
140set format(eu_ES,TIME_FORMAT_12) %T
141set format(fi_FI,DATE_FORMAT) %d.%m.%Y
142set format(fi_FI,DATE_TIME_FORMAT) {%a %e %B %Y %T}
143set format(fi_FI,TIME_FORMAT) %T
144set format(fi_FI,TIME_FORMAT_12) %T
145set format(fo_FO,DATE_FORMAT) %d/%m-%Y
146set format(fo_FO,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
147set format(fo_FO,TIME_FORMAT) %T
148set format(fo_FO,TIME_FORMAT_12) %T
149set format(fr_BE,DATE_FORMAT) %d/%m/%y
150set format(fr_BE,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
151set format(fr_BE,TIME_FORMAT) %T
152set format(fr_BE,TIME_FORMAT_12) %T
153set format(fr_CA,DATE_FORMAT) %Y-%m-%d
154set format(fr_CA,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
155set format(fr_CA,TIME_FORMAT) %T
156set format(fr_CA,TIME_FORMAT_12) %T
157set format(fr_CH,DATE_FORMAT) {%d. %m. %y}
158set format(fr_CH,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
159set format(fr_CH,TIME_FORMAT) %T
160set format(fr_CH,TIME_FORMAT_12) %T
161set format(fr_FR,DATE_FORMAT) %d.%m.%Y
162set format(fr_FR,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
163set format(fr_FR,TIME_FORMAT) %T
164set format(fr_FR,TIME_FORMAT_12) %T
165set format(fr_LU,DATE_FORMAT) %d.%m.%Y
166set format(fr_LU,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
167set format(fr_LU,TIME_FORMAT) %T
168set format(fr_LU,TIME_FORMAT_12) %T
169set format(ga_IE,DATE_FORMAT) %d.%m.%y
170set format(ga_IE,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
171set format(ga_IE,TIME_FORMAT) %T
172set format(ga_IE,TIME_FORMAT_12) %T
173set format(gr_GR,DATE_FORMAT) %d/%m/%Y
174set format(gr_GR,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
175set format(gr_GR,TIME_FORMAT) %T
176set format(gr_GR,TIME_FORMAT_12) %T
177set format(hr_HR,DATE_FORMAT) %d.%m.%y
178set format(hr_HR,DATE_TIME_FORMAT) {%a %d %b %Y %T}
179set format(hr_HR,TIME_FORMAT) %T
180set format(hr_HR,TIME_FORMAT_12) %T
181set format(hu_HU,DATE_FORMAT) %Y-%m-%d
182set format(hu_HU,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
183set format(hu_HU,TIME_FORMAT) %T
184set format(hu_HU,TIME_FORMAT_12) %T
185set format(is_IS,DATE_FORMAT) {%a %e.%b %Y}
186set format(is_IS,DATE_TIME_FORMAT) {%a %e.%b %Y, %T %z}
187set format(is_IS,TIME_FORMAT) %T
188set format(is_IS,TIME_FORMAT_12) %T
189set format(it_IT,DATE_FORMAT) %d/%m/%Y
190set format(it_IT,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
191set format(it_IT,TIME_FORMAT) %T
192set format(it_IT,TIME_FORMAT_12) %T
193set format(iw_IL,DATE_FORMAT) %d/%m/%y
194set format(iw_IL,DATE_TIME_FORMAT) {%z %H:%M:%S %Y %b %d %a}
195set format(iw_IL,TIME_FORMAT) %H:%M:%S
196set format(iw_IL,TIME_FORMAT_12) {%I:%M:%S %P}
197set format(kl_GL,DATE_FORMAT) {%d %b %Y}
198set format(kl_GL,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
199set format(kl_GL,TIME_FORMAT) %T
200set format(kl_GL,TIME_FORMAT_12) %T
201set format(lt_LT,DATE_FORMAT) %Y.%m.%d
202set format(lt_LT,DATE_TIME_FORMAT) {%Y m. %B %d d. %T}
203set format(lt_LT,TIME_FORMAT) %T
204set format(lt_LT,TIME_FORMAT_12) %T
205set format(lv_LV,DATE_FORMAT) %Y.%m.%d.
206set format(lv_LV,DATE_TIME_FORMAT) {%A, %Y. gada %e. %B, plkst. %H un %M}
207set format(lv_LV,TIME_FORMAT) %T
208set format(lv_LV,TIME_FORMAT_12) %T
209set format(nl_BE,DATE_FORMAT) %d-%m-%y
210set format(nl_BE,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
211set format(nl_BE,TIME_FORMAT) %T
212set format(nl_BE,TIME_FORMAT_12) %T
213set format(nl_NL,DATE_FORMAT) %d-%m-%y
214set format(nl_NL,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
215set format(nl_NL,TIME_FORMAT) %T
216set format(nl_NL,TIME_FORMAT_12) %T
217set format(no_NO,DATE_FORMAT) %d-%m-%Y
218set format(no_NO,DATE_TIME_FORMAT) {%a %d-%m-%Y %T %z}
219set format(no_NO,TIME_FORMAT) %T
220set format(no_NO,TIME_FORMAT_12) %T
221set format(pl_PL,DATE_FORMAT) %Y-%m-%d
222set format(pl_PL,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
223set format(pl_PL,TIME_FORMAT) %T
224set format(pl_PL,TIME_FORMAT_12) %T
225set format(pt_BR,DATE_FORMAT) %d-%m-%Y
226set format(pt_BR,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
227set format(pt_BR,TIME_FORMAT) %T
228set format(pt_BR,TIME_FORMAT_12) %T
229set format(pt_PT,DATE_FORMAT) %d-%m-%Y
230set format(pt_PT,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
231set format(pt_PT,TIME_FORMAT) %T
232set format(pt_PT,TIME_FORMAT_12) %T
233set format(ro_RO,DATE_FORMAT) %Y-%m-%d
234set format(ro_RO,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
235set format(ro_RO,TIME_FORMAT) %T
236set format(ro_RO,TIME_FORMAT_12) %T
237set format(ru_RU,DATE_FORMAT) %d.%m.%Y
238set format(ru_RU,DATE_TIME_FORMAT) {%a %d %b %Y %T}
239set format(ru_RU,TIME_FORMAT) %T
240set format(ru_RU,TIME_FORMAT_12) %T
241set format(sl_SI,DATE_FORMAT) %d.%m.%Y
242set format(sl_SI,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
243set format(sl_SI,TIME_FORMAT) %T
244set format(sl_SI,TIME_FORMAT_12) %T
245set format(sv_FI,DATE_FORMAT) %Y-%m-%d
246set format(sv_FI,DATE_TIME_FORMAT) {%a %e %b %Y %H.%M.%S}
247set format(sv_FI,TIME_FORMAT) %H.%M.%S
248set format(sv_FI,TIME_FORMAT_12) %H.%M.%S
249set format(sv_SE,DATE_FORMAT) %Y-%m-%d
250set format(sv_SE,DATE_TIME_FORMAT) {%a %e %b %Y %H.%M.%S}
251set format(sv_SE,TIME_FORMAT) %H.%M.%S
252set format(sv_SE,TIME_FORMAT_12) %H.%M.%S
253set format(tr_TR,DATE_FORMAT) %Y-%m-%d
254set format(tr_TR,DATE_TIME_FORMAT) {%a %d %b %Y %T %z}
255set format(tr_TR,TIME_FORMAT) %T
256set format(tr_TR,TIME_FORMAT_12) %T
257
258#----------------------------------------------------------------------
259#
260# handleLocaleFile --
261#
262#	Extracts strings from an ICU locale definition.
263#
264# Parameters:
265#	localeName - Name of the locale (e.g., de_AT_euro)
266#	fileName - Name of the file containing the data
267#	msgFileName - Name of the file containing the Tcl message catalog
268#
269# Results:
270#	None.
271#
272# Side effects:
273#	Writes the Tcl message catalog.
274#
275#----------------------------------------------------------------------
276
277proc handleLocaleFile { localeName fileName msgFileName } {
278    variable format
279
280    # Get the content of the ICU file
281
282    set f [open $fileName r]
283    fconfigure $f -encoding utf-8
284    set data [read $f]
285    close $f
286
287    # Parse the ICU data
288
289    set state {}
290    foreach line [split $data \n] {
291	switch -exact -- $state {
292	    {} {
293
294		# Look for the beginnings of data blocks
295
296		switch -regexp -- $line {
297		    {^[[:space:]]*AmPmMarkers[[:space:]]+[\{]} {
298			set state data
299			set key AmPmMarkers
300		    }
301		    {^[[:space:]]*DateTimePatterns[[:space:]]+[\{]} {
302			set state data
303			set key DateTimePatterns
304		    }
305		    {^[[:space:]]*DayAbbreviations[[:space:]]+[\{]} {
306			set state data
307			set key DayAbbreviations
308		    }
309		    {^[[:space:]]*DayNames[[:space:]]+[\{]} {
310			set state data
311			set key DayNames
312		    }
313		    {^[[:space:]]*Eras[[:space:]]+[\{]} {
314			set state data
315			set key Eras
316		    }
317		    {^[[:space:]]*MonthAbbreviations[[:space:]]+[\{]} {
318			set state data
319			set key MonthAbbreviations
320		    }
321		    {^[[:space:]]*MonthNames[[:space:]]+[\{]} {
322			set state data
323			set key MonthNames
324		    }
325		}
326	    }
327	    data {
328
329
330		# Inside a data block, collect the strings, doing backslash
331		# expansion to pick up the Unicodes
332
333		if { [regexp {"(.*)",} $line -> item] } {
334		    lappend items($key) [subst -nocommands -novariables $item]
335		} elseif { [regexp {^[[:space:]]*[\}][[:space:]]*$} $line] } {
336		    set state {}
337		}
338	    }
339	}
340    }
341
342    # Skip locales that don't change time strings.
343
344    if {![array exists items]} return
345
346    # Write the Tcl message catalog
347
348    set f [open $msgFileName w]
349
350    # Write a header
351
352    puts $f "\# created by $::argv0 -- do not edit"
353    puts $f "namespace eval ::tcl::clock \{"
354
355    # Do ordinary sets of strings (weekday and month names)
356
357    foreach key {
358	DayAbbreviations DayNames MonthAbbreviations MonthNames
359    } tkey {
360	DAYS_OF_WEEK_ABBREV DAYS_OF_WEEK_FULL
361	MONTHS_ABBREV MONTHS_FULL
362    } {
363	if { [info exists items($key)] } {
364	    set itemList $items($key)
365	    set cmd1 "    ::msgcat::mcset "
366	    append cmd1 $localeName " " $tkey " \[list "
367	    foreach item $itemList {
368		append cmd1 \\\n {        } \" [backslashify $item] \"
369	    }
370	    append cmd1 \]
371	    puts $f $cmd1
372	}
373    }
374
375    # Do the eras, B.C.E., and C.E.
376
377    if { [info exists items(Eras)] } {
378	foreach { bce ce } $items(Eras) break
379	set cmd "    ::msgcat::mcset "
380	append cmd $localeName " " BCE " \"" [backslashify $bce] \"
381	puts $f $cmd
382	set cmd "    ::msgcat::mcset "
383	append cmd $localeName " " CE " \"" [backslashify $ce] \"
384	puts $f $cmd
385    }
386
387    # Do the AM and PM markers
388
389    if { [info exists items(AmPmMarkers)] } {
390	foreach { am pm } $items(AmPmMarkers) break
391	set cmd "    ::msgcat::mcset "
392	append cmd $localeName " " AM " \"" [backslashify $am] \"
393	puts $f $cmd
394	set cmd "    ::msgcat::mcset "
395	append cmd $localeName " " PM " \"" [backslashify $pm] \"
396	puts $f $cmd
397    }
398
399    # Do the date/time patterns. First date...
400
401    if { [info exists format($localeName,DATE_FORMAT)]
402	 || [info exists items(DateTimePatterns)] } {
403
404	# Find the shortest date format that includes a 4-digit year.
405
406	if { ![info exists format($localeName,DATE_FORMAT)] } {
407	    for { set i 7 } { $i >= 4 } { incr i -1 } {
408		if { [regexp yyyy [lindex $items(DateTimePatterns) $i]] } {
409		    break
410		}
411	    }
412	    set fmt \
413		[backslashify \
414		     [percentify [lindex $items(DateTimePatterns) $i]]]
415	    set format($localeName,DATE_FORMAT) $fmt
416	}
417
418	# Put it to the message catalog
419
420	set cmd "    ::msgcat::mcset "
421	append cmd $localeName " DATE_FORMAT \"" \
422	    $format($localeName,DATE_FORMAT) "\""
423	puts $f $cmd
424    }
425
426    # Time
427
428    if { [info exists format($localeName,TIME_FORMAT)]
429	 || [info exists items(DateTimePatterns)] } {
430
431	# Find the shortest time pattern that includes the seconds
432
433	if { ![info exists format($localeName,TIME_FORMAT)] } {
434	    for { set i 3 } { $i >= 0 } { incr i -1 } {
435		if { [regexp H [lindex $items(DateTimePatterns) $i]]
436		     && [regexp s [lindex $items(DateTimePatterns) $i]] } {
437		    break
438		}
439	    }
440	    if { $i >= 0 } {
441		set fmt \
442		    [backslashify \
443			 [percentify [lindex $items(DateTimePatterns) $i]]]
444		regsub { %Z} $fmt {} format($localeName,TIME_FORMAT)
445	    }
446	}
447
448	# Put it to the message catalog
449
450	if { [info exists format($localeName,TIME_FORMAT)] } {
451	    set cmd "    ::msgcat::mcset "
452	    append cmd $localeName " TIME_FORMAT \"" \
453		$format($localeName,TIME_FORMAT) "\""
454	    puts $f $cmd
455	}
456    }
457
458    # 12-hour time...
459
460    if { [info exists format($localeName,TIME_FORMAT_12)]
461	 || [info exists items(DateTimePatterns)] } {
462
463	# Shortest patterm with 12-hour time that includes seconds
464
465	if { ![info exists format($localeName,TIME_FORMAT_12)] } {
466	    for { set i 3 } { $i >= 0 } { incr i -1 } {
467		if { [regexp h [lindex $items(DateTimePatterns) $i]]
468		     && [regexp s [lindex $items(DateTimePatterns) $i]] } {
469		    break
470		}
471	    }
472	    if { $i >= 0 } {
473		set fmt \
474		    [backslashify \
475			 [percentify [lindex $items(DateTimePatterns) $i]]]
476		regsub { %Z} $fmt {} format($localeName,TIME_FORMAT_12)
477	    }
478	}
479
480	# Put it to the catalog
481
482	if { [info exists format($localeName,TIME_FORMAT_12)] } {
483	    set cmd "    ::msgcat::mcset "
484	    append cmd $localeName " TIME_FORMAT_12 \"" \
485		$format($localeName,TIME_FORMAT_12) "\""
486	    puts $f $cmd
487	}
488    }
489
490    # Date and time... Prefer 24-hour format to 12-hour format.
491
492    if { ![info exists format($localeName,DATE_TIME_FORMAT)]
493	 && [info exists format($localeName,DATE_FORMAT)]
494	 && [info exists format($localeName,TIME_FORMAT)]} {
495	set format($localeName,DATE_TIME_FORMAT) \
496	    $format($localeName,DATE_FORMAT)
497	append format($localeName,DATE_TIME_FORMAT) \
498	    " " $format($localeName,TIME_FORMAT) " %z"
499    }
500    if { ![info exists format($localeName,DATE_TIME_FORMAT)]
501	 && [info exists format($localeName,DATE_FORMAT)]
502	 && [info exists format($localeName,TIME_FORMAT_12)]} {
503	set format($localeName,DATE_TIME_FORMAT) \
504	    $format($localeName,DATE_FORMAT)
505	append format($localeName,DATE_TIME_FORMAT) \
506	    " " $format($localeName,TIME_FORMAT_12) " %z"
507    }
508
509    # Write date/time format to the file
510
511    if { [info exists format($localeName,DATE_TIME_FORMAT)] } {
512	set cmd "    ::msgcat::mcset "
513	append cmd $localeName " DATE_TIME_FORMAT \"" \
514	    $format($localeName,DATE_TIME_FORMAT) "\""
515	puts $f $cmd
516    }
517
518    # Write the string sets to the file.
519
520    foreach key {
521	LOCALE_NUMERALS LOCALE_DATE_FORMAT LOCALE_TIME_FORMAT
522	LOCALE_DATE_TIME_FORMAT LOCALE_ERAS LOCALE_YEAR_FORMAT
523    } {
524	if { [info exists format($localeName,$key)] } {
525	    set cmd "    ::msgcat::mcset "
526	    append cmd $localeName " " $key " \"" \
527		[backslashify $format($localeName,$key)] "\""
528	    puts $f $cmd
529	}
530    }
531
532    # Footer
533
534    puts $f "\}"
535    close $f
536}
537
538#----------------------------------------------------------------------
539#
540# percentify --
541#
542#	Converts a Java/ICU-style time format to a C/Tcl style one.
543#
544# Parameters:
545#	string -- Format to convert
546#
547# Results:
548#	Returns the converted format.
549#
550# Side effects:
551#	None.
552#
553#----------------------------------------------------------------------
554
555proc percentify { string } {
556    set retval {}
557    foreach { unquoted quoted } [split $string '] {
558	append retval [string map {
559	    EEEE %A MMMM %B yyyy %Y
560	    MMM %b EEE %a
561	    dd %d hh %I HH %H mm %M MM %m ss %S yy %y
562	    a %P d %e h %l H %k M %m z %z
563	} $unquoted]
564	append retval $quoted
565    }
566    return $retval
567}
568
569#----------------------------------------------------------------------
570#
571# backslashify --
572#
573#	Converts a UTF-8 string to a plain ASCII one with escapes.
574#
575# Parameters:
576#	string -- String to convert
577#
578# Results:
579#	Returns the converted string
580#
581# Side effects:
582#	None.
583#
584#----------------------------------------------------------------------
585
586proc backslashify { string } {
587
588    set retval {}
589    foreach char [split $string {}] {
590	scan $char %c ccode
591	if { $ccode >= 0x0020 && $ccode < 0x007f && $char ne "\""
592	     && $char ne "\{" && $char ne "\}" && $char ne "\["
593	     && $char ne "\]" && $char ne "\\" && $char ne "\$" } {
594	    append retval $char
595	} else {
596	    append retval \\u [format %04x $ccode]
597	}
598    }
599    return $retval
600}
601
602#----------------------------------------------------------------------
603#
604# MAIN PROGRAM
605#
606#----------------------------------------------------------------------
607
608# Extract directories from command line
609
610foreach { icudir msgdir } $argv break
611
612# Walk the ICU files and create corresponding Tcl message catalogs
613
614foreach fileName [glob -directory $icudir *.txt] {
615    set n [file rootname [file tail $fileName]]
616    if { [regexp {^[a-z]{2,3}(_[A-Z]{2,3}(_.*)?)?$} $n] } {
617	handleLocaleFile $n $fileName [file join $msgdir [string tolower $n].msg]
618    }
619}
620