Tcl Source Code

Changes On Branch tip-404
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch tip-404 Excluding Merge-Ins

This is equivalent to a diff from d17e59a33e to 7236bac9ae

2012-09-12
17:08
tip#404 file locale mcset: mc(fl)(m)set check-in: dc1e9e3dea user: oehhar tags: trunk
2012-09-07
17:22
ChangeLog entry added Closed-Leaf check-in: 7236bac9ae user: oehhar tags: tip-404
15:32
Reentrant mcfl(m)set command, test, document mcflset as recommended for message files check-in: 62aa37bb59 user: oehhar tags: tip-404
2012-09-02
07:21
merge trunk check-in: 1ed34b8810 user: dkf tags: dkf-http-cookies
2012-08-30
18:46
Update changes for 8.6b3 check-in: b5c1fbee86 user: dgp tags: trunk
2012-08-29
06:31
proposed solution for [Bug 3562640]: problem loading Thread in 8.5, when compiled for 8.6 check-in: 6b9d54bfeb user: jan.nijtmans tags: bug-3562640
2012-08-28
13:04
merge trunk check-in: 3875099862 user: dgp tags: core-8-6-b3-rc
2012-08-27
17:24
Commit of Harald Oehlmann's TIP 404 patch without TIP 399 pieces and with some added documentation. ... check-in: b7c4598501 user: dkf tags: tip-404
17:12
Followup to [6325d5dbeac6f91d28d6]. dlerror() may return NULL. Fixed the code which wasn't prepared ... check-in: d17e59a33e user: andreask tags: trunk
2012-08-26
08:20
minor: tidy up formatting check-in: 7cbc87061e user: dkf tags: trunk

Changes to ChangeLog.









1
2
3
4
5
6
7








2012-08-25  Donal K. Fellows  <[email protected]>

	* library/msgs/uk.msg: [Bug 3561330]: Use the correct full name of
	March in Ukrainian. Thanks to Mikhail Teterin for reporting.

2012-08-23  Jan Nijtmans  <[email protected]>

>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2012-09-07  Harald Oehlmann  <[email protected]>

	IMPLEMENTATION OF TIP#404.

	* library/msgcat.tcl: [FRQ 3544988]: add commands
	[mcflset] and [mcflmset] to set mc entries with implicit message file
	locale. Package version is now 1.5.0.

2012-08-25  Donal K. Fellows  <[email protected]>

	* library/msgs/uk.msg: [Bug 3561330]: Use the correct full name of
	March in Ukrainian. Thanks to Mikhail Teterin for reporting.

2012-08-23  Jan Nijtmans  <[email protected]>

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
	by looking at [FRQ 1357401] (these are an _internal_ implementation of
	that FRQ).

2012-06-29  Jan Nijtmans  <[email protected]>

	* library/msgcat/msgcat.tcl:   Add tn, ro_MO and ru_MO to msgcat.

2012-06-29  Harald Oehlmann <harald.oe[email protected]>

	* library/msgcat/msgcat.tcl:	[Bug 3536888]: Locale guessing of
	* library/msgcat/pkgIndex.tcl:	msgcat fails on (some) Windows 7. Bump
	* unix/Makefile.in:		to 1.4.5
	* win/Makefile.in:

2012-06-29  Donal K. Fellows  <[email protected]>







|







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
	by looking at [FRQ 1357401] (these are an _internal_ implementation of
	that FRQ).

2012-06-29  Jan Nijtmans  <[email protected]>

	* library/msgcat/msgcat.tcl:   Add tn, ro_MO and ru_MO to msgcat.

2012-06-29  Harald Oehlmann <oehhar@users.sf.net>

	* library/msgcat/msgcat.tcl:	[Bug 3536888]: Locale guessing of
	* library/msgcat/pkgIndex.tcl:	msgcat fails on (some) Windows 7. Bump
	* unix/Makefile.in:		to 1.4.5
	* win/Makefile.in:

2012-06-29  Donal K. Fellows  <[email protected]>

Changes to doc/msgcat.n.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30






31
32
33
34
35
36
37
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
msgcat \- Tcl message catalog
.SH SYNOPSIS
\fBpackage require Tcl 8.5\fR
.sp
\fBpackage require msgcat 1.4.5\fR
.sp
\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
.sp
\fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR?
.sp
\fB::msgcat::mclocale \fR?\fInewLocale\fR?
.sp
\fB::msgcat::mcpreferences\fR
.sp
\fB::msgcat::mcload \fIdirname\fR
.sp
\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
.sp
\fB::msgcat::mcmset \fIlocale src-trans-list\fR






.sp
\fB::msgcat::mcunknown \fIlocale src-string\fR
.BE
.SH DESCRIPTION
.PP
The \fBmsgcat\fR package provides a set of functions
that can be used to manage multi-lingual user interfaces.







|














>
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
msgcat \- Tcl message catalog
.SH SYNOPSIS
\fBpackage require Tcl 8.5\fR
.sp
\fBpackage require msgcat 1.5.0\fR
.sp
\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
.sp
\fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR?
.sp
\fB::msgcat::mclocale \fR?\fInewLocale\fR?
.sp
\fB::msgcat::mcpreferences\fR
.sp
\fB::msgcat::mcload \fIdirname\fR
.sp
\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
.sp
\fB::msgcat::mcmset \fIlocale src-trans-list\fR
.sp
.VS "TIP 404"
\fB::msgcat::mcflset \fIsrc-string \fR?\fItranslate-string\fR?
.sp
\fB::msgcat::mcflmset \fIsrc-trans-list\fR
.VE "TIP 404"
.sp
\fB::msgcat::mcunknown \fIlocale src-string\fR
.BE
.SH DESCRIPTION
.PP
The \fBmsgcat\fR package provides a set of functions
that can be used to manage multi-lingual user interfaces.
126
127
128
129
130
131
132




















133
134
135
136
137
138
139
\fIsrc-trans-list\fR in the specified \fIlocale\fR and the current
namespace.
\fIsrc-trans-list\fR must have an even number of elements and is in
the form {\fIsrc-string translate-string\fR ?\fIsrc-string
translate-string ...\fR?} \fB::msgcat::mcmset\fR can be significantly
faster than multiple invocations of \fB::msgcat::mcset\fR. The function
returns the number of translations set.




















.TP
\fB::msgcat::mcunknown \fIlocale src-string\fR
.
This routine is called by \fB::msgcat::mc\fR in the case when
a translation for \fIsrc-string\fR is not defined in the
current locale.  The default action is to return
\fIsrc-string\fR.  This procedure can be redefined by the







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
\fIsrc-trans-list\fR in the specified \fIlocale\fR and the current
namespace.
\fIsrc-trans-list\fR must have an even number of elements and is in
the form {\fIsrc-string translate-string\fR ?\fIsrc-string
translate-string ...\fR?} \fB::msgcat::mcmset\fR can be significantly
faster than multiple invocations of \fB::msgcat::mcset\fR. The function
returns the number of translations set.
.TP
\fB::msgcat::mcflset \fIsrc-string \fR?\fItranslate-string\fR?
.VS "TIP 404"
Sets the translation for \fIsrc-string\fR to \fItranslate-string\fR in the
current namespace for the locale implied by the name of the message catalog
being loaded via \fB::msgcat::mcload\fR.  If \fItranslate-string\fR is not
specified, \fIsrc-string\fR is used for both.  The function returns
\fItranslate-string\fR.
.VE "TIP 404"
.TP
\fB::msgcat::mcflmset \fIsrc-trans-list\fR
.VS "TIP 404"
Sets the translation for multiple source strings in \fIsrc-trans-list\fR in
the current namespace for the locale implied by the name of the message
catalog being loaded via \fB::msgcat::mcload\fR. \fIsrc-trans-list\fR must
have an even number of elements and is in the form {\fIsrc-string
translate-string\fR ?\fIsrc-string translate-string ...\fR?}
\fB::msgcat::mcflmset\fR can be significantly faster than multiple invocations
of \fB::msgcat::mcflset\fR. The function returns the number of translations set.
.VE "TIP 404"
.TP
\fB::msgcat::mcunknown \fIlocale src-string\fR
.
This routine is called by \fB::msgcat::mc\fR in the case when
a translation for \fIsrc-string\fR is not defined in the
current locale.  The default action is to return
\fIsrc-string\fR.  This procedure can be redefined by the
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
is called
.QW \fBROOT.msg\fR .
This exception is made so as not to
cause peculiar behavior, such as marking the message file as
.QW hidden
on Unix file systems.
.IP [3]
The file contains a series of calls to \fBmcset\fR and
\fBmcmset\fR, setting the necessary translation strings
for the language, likely enclosed in a \fBnamespace eval\fR
so that all source strings are tied to the namespace of
the package. For example, a short \fBes.msg\fR might contain:
.PP
.CS
namespace eval ::mypackage {
    \fB::msgcat::mcset\fR es "Free Beer!" "Cerveza Gracias!"
}
.CE
.SH "RECOMMENDED MESSAGE SETUP FOR PACKAGES"
.PP
If a package is installed into a subdirectory of the
\fBtcl_pkgPath\fR and loaded via \fBpackage require\fR, the
following procedure is recommended.







|
|






|







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
is called
.QW \fBROOT.msg\fR .
This exception is made so as not to
cause peculiar behavior, such as marking the message file as
.QW hidden
on Unix file systems.
.IP [3]
The file contains a series of calls to \fBmcflset\fR and
\fBmcflmset\fR, setting the necessary translation strings
for the language, likely enclosed in a \fBnamespace eval\fR
so that all source strings are tied to the namespace of
the package. For example, a short \fBes.msg\fR might contain:
.PP
.CS
namespace eval ::mypackage {
    \fB::msgcat::mcflset\fR "Free Beer!" "Cerveza Gracias!"
}
.CE
.SH "RECOMMENDED MESSAGE SETUP FOR PACKAGES"
.PP
If a package is installed into a subdirectory of the
\fBtcl_pkgPath\fR and loaded via \fBpackage require\fR, the
following procedure is recommended.

Changes to library/msgcat/msgcat.tcl.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26



27
28
29
30
31
32
33
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tcl 8.5
# When the version number changes, be sure to update the pkgIndex.tcl file,
# and the installation directory in the Makefiles.
package provide msgcat 1.4.5

namespace eval msgcat {
    namespace export mc mcload mclocale mcmax mcmset mcpreferences mcset \
	    mcunknown

    # Records the current locale as passed to mclocale
    variable Locale ""

    # Records the list of locales to search
    variable Loclist {}




    # Records the mapping between source strings and translated strings.  The
    # dict key is of the form "<locale> <namespace> <src>", where locale and
    # namespace should be themselves dict values and the value is
    # the translated string.
    variable Msgs [dict create]








|



|






>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

package require Tcl 8.5
# When the version number changes, be sure to update the pkgIndex.tcl file,
# and the installation directory in the Makefiles.
package provide msgcat 1.5.0

namespace eval msgcat {
    namespace export mc mcload mclocale mcmax mcmset mcpreferences mcset \
	    mcunknown mcflset mcflmset

    # Records the current locale as passed to mclocale
    variable Locale ""

    # Records the list of locales to search
    variable Loclist {}

    # Records the locale of the currently sourced message catalogue file
    variable FileLocale

    # Records the mapping between source strings and translated strings.  The
    # dict key is of the form "<locale> <namespace> <src>", where locale and
    # namespace should be themselves dict values and the value is
    # the translated string.
    variable Msgs [dict create]

273
274
275
276
277
278
279





280
281
282
283
284
285
286
287




288

289



290
291
292
293
294
295
296
# Arguments:
#	langdir		The directory to search.
#
# Results:
#	Returns the number of message catalogs that were loaded.

proc msgcat::mcload {langdir} {





    set x 0
    foreach p [mcpreferences] {
	if { $p eq {} } {
	    set p ROOT
	}
	set langfile [file join $langdir $p.msg]
	if {[file exists $langfile]} {
	    incr x




	    uplevel 1 [list ::source -encoding utf-8 $langfile]

	}



    }
    return $x
}

# msgcat::mcset --
#
#	Set the translation for a given string in a specified locale.







>
>
>
>
>








>
>
>
>

>

>
>
>







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# Arguments:
#	langdir		The directory to search.
#
# Results:
#	Returns the number of message catalogs that were loaded.

proc msgcat::mcload {langdir} {
    variable FileLocale
    # Save the file locale if we are recursively called
    if {[info exists FileLocale]} {
	set nestedFileLocale $FileLocale
    }
    set x 0
    foreach p [mcpreferences] {
	if { $p eq {} } {
	    set p ROOT
	}
	set langfile [file join $langdir $p.msg]
	if {[file exists $langfile]} {
	    incr x
	    set FileLocale [string tolower [file tail [file rootname $langfile]]]
	    if {"root" eq $FileLocale} {
		set FileLocale ""
	    }
	    uplevel 1 [list ::source -encoding utf-8 $langfile]
	    unset FileLocale
	}
    }
    if {[info exists nestedFileLocale]} {
	set FileLocale $nestedFileLocale
    }
    return $x
}

# msgcat::mcset --
#
#	Set the translation for a given string in a specified locale.
313
314
315
316
317
318
319





























320
321
322
323
324
325
326
    set ns [uplevel 1 [list ::namespace current]]

    set locale [string tolower $locale]

    dict set Msgs $locale $ns $src $dest
    return $dest
}






























# msgcat::mcmset --
#
#	Set the translation for multiple strings in a specified locale.
#
# Arguments:
#	locale		The locale to use.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
    set ns [uplevel 1 [list ::namespace current]]

    set locale [string tolower $locale]

    dict set Msgs $locale $ns $src $dest
    return $dest
}

# msgcat::mcflset --
#
#	Set the translation for a given string in the current file locale.
#
# Arguments:
#	src		The source string.
#	dest		(Optional) The translated string.  If omitted,
#			the source string is used.
#
# Results:
#	Returns the new locale.

proc msgcat::mcflset {src {dest ""}} {
    variable FileLocale
    variable Msgs

    if {![info exists FileLocale]} {
	return -code error \
	    "must only be used inside a message catalog loaded with ::msgcat::mcload"
    }
    if {[llength [info level 0]] == 2} { ;# dest not specified
	set dest $src
    }

    set ns [uplevel 1 [list ::namespace current]]
    dict set Msgs $FileLocale $ns $src $dest
    return $dest
}

# msgcat::mcmset --
#
#	Set the translation for multiple strings in a specified locale.
#
# Arguments:
#	locale		The locale to use.
341
342
343
344
345
346
347






















348









349
350
351
352
353
354
355
    set locale [string tolower $locale]
    set ns [uplevel 1 [list ::namespace current]]

    foreach {src dest} $pairs {
	dict set Msgs $locale $ns $src $dest
    }























    return $length









}

# msgcat::mcunknown --
#
#	This routine is called by msgcat::mc if a translation cannot
#	be found for a string.  This routine is intended to be replaced
#	by an application specific routine for error reporting







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
    set locale [string tolower $locale]
    set ns [uplevel 1 [list ::namespace current]]

    foreach {src dest} $pairs {
	dict set Msgs $locale $ns $src $dest
    }

    return [expr {$length / 2}]
}

# msgcat::mcflmset --
#
#	Set the translation for multiple strings in the mc file locale.
#
# Arguments:
#	pairs		One or more src/dest pairs (must be even length)
#
# Results:
#	Returns the number of pairs processed

proc msgcat::mcflmset {pairs} {
    variable FileLocale
    variable Msgs

    if {![info exists FileLocale]} {
	return -code error \
	    "must only be used inside a message catalog loaded with ::msgcat::mcload"
    }
    set length [llength $pairs]
    if {$length % 2} {
	return -code error "bad translation list:\
		should be \"[lindex [info level 0] 0] locale {src dest ...}\""
    }

    set ns [uplevel 1 [list ::namespace current]]
    foreach {src dest} $pairs {
	dict set Msgs $FileLocale $ns $src $dest
    }
    return [expr {$length / 2}]
}

# msgcat::mcunknown --
#
#	This routine is called by msgcat::mc if a translation cannot
#	be found for a string.  This routine is intended to be replaced
#	by an application specific routine for error reporting

Changes to library/msgcat/pkgIndex.tcl.

1
2
if {![package vsatisfies [package provide Tcl] 8.5]} {return}
package ifneeded msgcat 1.4.5 [list source [file join $dir msgcat.tcl]]

|
1
2
if {![package vsatisfies [package provide Tcl] 8.5]} {return}
package ifneeded msgcat 1.5.0 [list source [file join $dir msgcat.tcl]]

Changes to tests/msgcat.test.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# message catalogs for locales foo, foo_BAR, and foo_BAR_baz.

package require Tcl 8.2
if {[catch {package require tcltest 2}]} {
    puts stderr "Skipping tests in [info script].  tcltest 2 required."
    return
}
if {[catch {package require msgcat 1.4.5}]} {
    puts stderr "Skipping tests in [info script].  No msgcat 1.4.5 found to test."
    return
}

namespace eval ::msgcat::test {
    namespace import ::msgcat::*
    namespace import ::tcltest::test
    namespace import ::tcltest::cleanupTests







|
|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# message catalogs for locales foo, foo_BAR, and foo_BAR_baz.

package require Tcl 8.2
if {[catch {package require tcltest 2}]} {
    puts stderr "Skipping tests in [info script].  tcltest 2 required."
    return
}
if {[catch {package require msgcat 1.5.0}]} {
    puts stderr "Skipping tests in [info script].  No msgcat 1.5.0 found to test."
    return
}

namespace eval ::msgcat::test {
    namespace import ::msgcat::*
    namespace import ::tcltest::test
    namespace import ::tcltest::cleanupTests
606
607
608
609
610
611
612








































613
614
615
616
617
618
	variable locale [mclocale]
	mclocale foo
    } -cleanup {
	mclocale $locale
    } -body {
	mc "this is a %s" "good test"
    } -result "this is a good test"









































    cleanupTests
}
namespace delete ::msgcat::test
return








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
	variable locale [mclocale]
	mclocale foo
    } -cleanup {
	mclocale $locale
    } -body {
	mc "this is a %s" "good test"
    } -result "this is a good test"

    # Tests msgcat-8.*: [mcflset]

    set msgdir1 [makeDirectory msgdir1]
    makeFile {::msgcat::mcflset k1 v1} l1.msg $msgdir1

	test msgcat-8.1 {mcflset} -setup {
	    variable locale [mclocale]
	    mclocale l1
	    mcload $msgdir1
	} -cleanup {
	    mclocale $locale
	} -body {
	    mc k1
	} -result v1

    removeFile l1.msg $msgdir1
    removeDirectory msgdir1

    set msgdir2 [makeDirectory msgdir2]
    set msgdir3 [makeDirectory msgdir3]
    makeFile "::msgcat::mcflset k2 v2 ; ::msgcat::mcload [list $msgdir3]"\
	    l2.msg $msgdir2
    makeFile {::msgcat::mcflset k3 v3} l2.msg $msgdir3

	# chained mcload
	test msgcat-8.2 {mcflset} -setup {
	    variable locale [mclocale]
	    mclocale l2
	    mcload $msgdir2
	} -cleanup {
	    mclocale $locale
	} -body {
	    return [mc k2][mc k3]
	} -result v2v3

    removeFile l2.msg $msgdir2
    removeDirectory msgdir2
    removeFile l3.msg $msgdir3
    removeDirectory msgdir3

    cleanupTests
}
namespace delete ::msgcat::test
return