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