Initial commit
This commit is contained in:
1472
ruby/lib/tcltk/tcl8/8.4/http-2.7.9.tm
Normal file
1472
ruby/lib/tcltk/tcl8/8.4/http-2.7.9.tm
Normal file
File diff suppressed because it is too large
Load Diff
387
ruby/lib/tcltk/tcl8/8.4/platform-1.0.10.tm
Normal file
387
ruby/lib/tcltk/tcl8/8.4/platform-1.0.10.tm
Normal file
@@ -0,0 +1,387 @@
|
||||
# -*- tcl -*-
|
||||
# ### ### ### ######### ######### #########
|
||||
## Overview
|
||||
|
||||
# Heuristics to assemble a platform identifier from publicly available
|
||||
# information. The identifier describes the platform of the currently
|
||||
# running tcl shell. This is a mixture of the runtime environment and
|
||||
# of build-time properties of the executable itself.
|
||||
#
|
||||
# Examples:
|
||||
# <1> A tcl shell executing on a x86_64 processor, but having a
|
||||
# wordsize of 4 was compiled for the x86 environment, i.e. 32
|
||||
# bit, and loaded packages have to match that, and not the
|
||||
# actual cpu.
|
||||
#
|
||||
# <2> The hp/solaris 32/64 bit builds of the core cannot be
|
||||
# distinguished by looking at tcl_platform. As packages have to
|
||||
# match the 32/64 information we have to look in more places. In
|
||||
# this case we inspect the executable itself (magic numbers,
|
||||
# i.e. fileutil::magic::filetype).
|
||||
#
|
||||
# The basic information used comes out of the 'os' and 'machine'
|
||||
# entries of the 'tcl_platform' array. A number of general and
|
||||
# os/machine specific transformation are applied to get a canonical
|
||||
# result.
|
||||
#
|
||||
# General
|
||||
# Only the first element of 'os' is used - we don't care whether we
|
||||
# are on "Windows NT" or "Windows XP" or whatever.
|
||||
#
|
||||
# Machine specific
|
||||
# % arm* -> arm
|
||||
# % sun4* -> sparc
|
||||
# % intel -> ix86
|
||||
# % i*86* -> ix86
|
||||
# % Power* -> powerpc
|
||||
# % x86_64 + wordSize 4 => x86 code
|
||||
#
|
||||
# OS specific
|
||||
# % AIX are always powerpc machines
|
||||
# % HP-UX 9000/800 etc means parisc
|
||||
# % linux has to take glibc version into account
|
||||
# % sunos -> solaris, and keep version number
|
||||
#
|
||||
# NOTE: A platform like linux glibc 2.3, which can use glibc 2.2 stuff
|
||||
# has to provide all possible allowed platform identifiers when
|
||||
# searching search. Ditto a solaris 2.8 platform can use solaris 2.6
|
||||
# packages. Etc. This is handled by the other procedure, see below.
|
||||
|
||||
# ### ### ### ######### ######### #########
|
||||
## Requirements
|
||||
|
||||
namespace eval ::platform {}
|
||||
|
||||
# ### ### ### ######### ######### #########
|
||||
## Implementation
|
||||
|
||||
# -- platform::generic
|
||||
#
|
||||
# Assembles an identifier for the generic platform. It leaves out
|
||||
# details like kernel version, libc version, etc.
|
||||
|
||||
proc ::platform::generic {} {
|
||||
global tcl_platform
|
||||
|
||||
set plat [string tolower [lindex $tcl_platform(os) 0]]
|
||||
set cpu $tcl_platform(machine)
|
||||
|
||||
switch -glob -- $cpu {
|
||||
sun4* {
|
||||
set cpu sparc
|
||||
}
|
||||
intel -
|
||||
i*86* {
|
||||
set cpu ix86
|
||||
}
|
||||
x86_64 {
|
||||
if {$tcl_platform(wordSize) == 4} {
|
||||
# See Example <1> at the top of this file.
|
||||
set cpu ix86
|
||||
}
|
||||
}
|
||||
"Power*" {
|
||||
set cpu powerpc
|
||||
}
|
||||
"arm*" {
|
||||
set cpu arm
|
||||
}
|
||||
ia64 {
|
||||
if {$tcl_platform(wordSize) == 4} {
|
||||
append cpu _32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch -- $plat {
|
||||
windows {
|
||||
set plat win32
|
||||
if {$cpu eq "amd64"} {
|
||||
# Do not check wordSize, win32-x64 is an IL32P64 platform.
|
||||
set cpu x86_64
|
||||
}
|
||||
}
|
||||
sunos {
|
||||
set plat solaris
|
||||
if {[string match "ix86" $cpu]} {
|
||||
if {$tcl_platform(wordSize) == 8} {
|
||||
set cpu x86_64
|
||||
}
|
||||
} elseif {![string match "ia64*" $cpu]} {
|
||||
# sparc
|
||||
if {$tcl_platform(wordSize) == 8} {
|
||||
append cpu 64
|
||||
}
|
||||
}
|
||||
}
|
||||
darwin {
|
||||
set plat macosx
|
||||
# Correctly identify the cpu when running as a 64bit
|
||||
# process on a machine with a 32bit kernel
|
||||
if {$cpu eq "ix86"} {
|
||||
if {$tcl_platform(wordSize) == 8} {
|
||||
set cpu x86_64
|
||||
}
|
||||
}
|
||||
}
|
||||
aix {
|
||||
set cpu powerpc
|
||||
if {$tcl_platform(wordSize) == 8} {
|
||||
append cpu 64
|
||||
}
|
||||
}
|
||||
hp-ux {
|
||||
set plat hpux
|
||||
if {![string match "ia64*" $cpu]} {
|
||||
set cpu parisc
|
||||
if {$tcl_platform(wordSize) == 8} {
|
||||
append cpu 64
|
||||
}
|
||||
}
|
||||
}
|
||||
osf1 {
|
||||
set plat tru64
|
||||
}
|
||||
}
|
||||
|
||||
return "${plat}-${cpu}"
|
||||
}
|
||||
|
||||
# -- platform::identify
|
||||
#
|
||||
# Assembles an identifier for the exact platform, by extending the
|
||||
# generic identifier. I.e. it adds in details like kernel version,
|
||||
# libc version, etc., if they are relevant for the loading of
|
||||
# packages on the platform.
|
||||
|
||||
proc ::platform::identify {} {
|
||||
global tcl_platform
|
||||
|
||||
set id [generic]
|
||||
regexp {^([^-]+)-([^-]+)$} $id -> plat cpu
|
||||
|
||||
switch -- $plat {
|
||||
solaris {
|
||||
regsub {^5} $tcl_platform(osVersion) 2 text
|
||||
append plat $text
|
||||
return "${plat}-${cpu}"
|
||||
}
|
||||
macosx {
|
||||
set major [lindex [split $tcl_platform(osVersion) .] 0]
|
||||
if {$major > 8} {
|
||||
incr major -4
|
||||
append plat 10.$major
|
||||
return "${plat}-${cpu}"
|
||||
}
|
||||
}
|
||||
linux {
|
||||
# Look for the libc*.so and determine its version
|
||||
# (libc5/6, libc6 further glibc 2.X)
|
||||
|
||||
set v unknown
|
||||
|
||||
# Determine in which directory to look. /lib, or /lib64.
|
||||
# For that we use the tcl_platform(wordSize).
|
||||
#
|
||||
# We could use the 'cpu' info, per the equivalence below,
|
||||
# that however would be restricted to intel. And this may
|
||||
# be a arm, mips, etc. system. The wordsize is more
|
||||
# fundamental.
|
||||
#
|
||||
# ix86 <=> (wordSize == 4) <=> 32 bit ==> /lib
|
||||
# x86_64 <=> (wordSize == 8) <=> 64 bit ==> /lib64
|
||||
#
|
||||
# Do not look into /lib64 even if present, if the cpu
|
||||
# doesn't fit.
|
||||
|
||||
# TODO: Determine the prefixes (i386, x86_64, ...) for
|
||||
# other cpus. The path after the generic one is utterly
|
||||
# specific to intel right now. Ok, on Ubuntu, possibly
|
||||
# other Debian systems we may apparently be able to query
|
||||
# the necessary CPU code. If we can't we simply use the
|
||||
# hardwired fallback.
|
||||
|
||||
switch -exact -- $tcl_platform(wordSize) {
|
||||
4 {
|
||||
lappend bases /lib
|
||||
if {[catch {
|
||||
exec dpkg-architecture -qDEB_HOST_MULTIARCH
|
||||
} res]} {
|
||||
lappend bases /lib/i386-linux-gnu
|
||||
} else {
|
||||
# dpkg-arch returns the full tripled, not just cpu.
|
||||
lappend bases /lib/$res
|
||||
}
|
||||
}
|
||||
8 {
|
||||
lappend bases /lib64
|
||||
if {[catch {
|
||||
exec dpkg-architecture -qDEB_HOST_MULTIARCH
|
||||
} res]} {
|
||||
lappend bases /lib/x86_64-linux-gnu
|
||||
} else {
|
||||
# dpkg-arch returns the full tripled, not just cpu.
|
||||
lappend bases /lib/$res
|
||||
}
|
||||
}
|
||||
default {
|
||||
return -code error "Bad wordSize $tcl_platform(wordSize), expected 4 or 8"
|
||||
}
|
||||
}
|
||||
|
||||
foreach base $bases {
|
||||
if {[LibcVersion $base -> v]} break
|
||||
}
|
||||
|
||||
append plat -$v
|
||||
return "${plat}-${cpu}"
|
||||
}
|
||||
}
|
||||
|
||||
return $id
|
||||
}
|
||||
|
||||
proc ::platform::LibcVersion {base _->_ vv} {
|
||||
upvar 1 $vv v
|
||||
set libclist [lsort [glob -nocomplain -directory $base libc*]]
|
||||
|
||||
if {![llength $libclist]} { return 0 }
|
||||
|
||||
set libc [lindex $libclist 0]
|
||||
|
||||
# Try executing the library first. This should suceed
|
||||
# for a glibc library, and return the version
|
||||
# information.
|
||||
|
||||
if {![catch {
|
||||
set vdata [lindex [split [exec $libc] \n] 0]
|
||||
}]} {
|
||||
regexp {([0-9]+(\.[0-9]+)*)} $vdata -> v
|
||||
foreach {major minor} [split $v .] break
|
||||
set v glibc${major}.${minor}
|
||||
return 1
|
||||
} else {
|
||||
# We had trouble executing the library. We are now
|
||||
# inspecting its name to determine the version
|
||||
# number. This code by Larry McVoy.
|
||||
|
||||
if {[regexp -- {libc-([0-9]+)\.([0-9]+)} $libc -> major minor]} {
|
||||
set v glibc${major}.${minor}
|
||||
return 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
# -- platform::patterns
|
||||
#
|
||||
# Given an exact platform identifier, i.e. _not_ the generic
|
||||
# identifier it assembles a list of exact platform identifier
|
||||
# describing platform which should be compatible with the
|
||||
# input.
|
||||
#
|
||||
# I.e. packages for all platforms in the result list should be
|
||||
# loadable on the specified platform.
|
||||
|
||||
# << Should we add the generic identifier to the list as well ? In
|
||||
# general it is not compatible I believe. So better not. In many
|
||||
# cases the exact identifier is identical to the generic one
|
||||
# anyway.
|
||||
# >>
|
||||
|
||||
proc ::platform::patterns {id} {
|
||||
set res [list $id]
|
||||
if {$id eq "tcl"} {return $res}
|
||||
|
||||
switch -glob -- $id {
|
||||
solaris*-* {
|
||||
if {[regexp {solaris([^-]*)-(.*)} $id -> v cpu]} {
|
||||
if {$v eq ""} {return $id}
|
||||
foreach {major minor} [split $v .] break
|
||||
incr minor -1
|
||||
for {set j $minor} {$j >= 6} {incr j -1} {
|
||||
lappend res solaris${major}.${j}-${cpu}
|
||||
}
|
||||
}
|
||||
}
|
||||
linux*-* {
|
||||
if {[regexp {linux-glibc([^-]*)-(.*)} $id -> v cpu]} {
|
||||
foreach {major minor} [split $v .] break
|
||||
incr minor -1
|
||||
for {set j $minor} {$j >= 0} {incr j -1} {
|
||||
lappend res linux-glibc${major}.${j}-${cpu}
|
||||
}
|
||||
}
|
||||
}
|
||||
macosx*-* {
|
||||
# 10.5+
|
||||
if {[regexp {macosx([^-]*)-(.*)} $id -> v cpu]} {
|
||||
|
||||
switch -exact -- $cpu {
|
||||
ix86 -
|
||||
x86_64 { set alt i386-x86_64 }
|
||||
default { set alt {} }
|
||||
}
|
||||
|
||||
if {$v ne ""} {
|
||||
foreach {major minor} [split $v .] break
|
||||
|
||||
# Add 10.5 to 10.minor to patterns.
|
||||
set res {}
|
||||
for {set j $minor} {$j >= 5} {incr j -1} {
|
||||
lappend res macosx${major}.${j}-${cpu}
|
||||
lappend res macosx${major}.${j}-universal
|
||||
if {$alt ne {}} {
|
||||
lappend res macosx${major}.${j}-$alt
|
||||
}
|
||||
}
|
||||
|
||||
# Add unversioned patterns for 10.3/10.4 builds.
|
||||
lappend res macosx-${cpu}
|
||||
lappend res macosx-universal
|
||||
if {$alt ne {}} {
|
||||
lappend res macosx-$alt
|
||||
}
|
||||
} else {
|
||||
lappend res macosx-universal
|
||||
if {$alt ne {}} {
|
||||
lappend res macosx-$alt
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lappend res macosx-universal
|
||||
}
|
||||
}
|
||||
macosx-powerpc {
|
||||
lappend res macosx-universal
|
||||
}
|
||||
macosx-x86_64 -
|
||||
macosx-ix86 {
|
||||
lappend res macosx-universal macosx-i386-x86_64
|
||||
}
|
||||
}
|
||||
lappend res tcl ; # Pure tcl packages are always compatible.
|
||||
return $res
|
||||
}
|
||||
|
||||
|
||||
# ### ### ### ######### ######### #########
|
||||
## Ready
|
||||
|
||||
package provide platform 1.0.10
|
||||
|
||||
# ### ### ### ######### ######### #########
|
||||
## Demo application
|
||||
|
||||
if {[info exists argv0] && ($argv0 eq [info script])} {
|
||||
puts ====================================
|
||||
parray tcl_platform
|
||||
puts ====================================
|
||||
puts Generic\ identification:\ [::platform::generic]
|
||||
puts Exact\ identification:\ \ \ [::platform::identify]
|
||||
puts ====================================
|
||||
puts Search\ patterns:
|
||||
puts *\ [join [::platform::patterns [::platform::identify]] \n*\ ]
|
||||
puts ====================================
|
||||
exit 0
|
||||
}
|
||||
241
ruby/lib/tcltk/tcl8/8.4/platform/shell-1.1.4.tm
Normal file
241
ruby/lib/tcltk/tcl8/8.4/platform/shell-1.1.4.tm
Normal file
@@ -0,0 +1,241 @@
|
||||
|
||||
# -*- tcl -*-
|
||||
# ### ### ### ######### ######### #########
|
||||
## Overview
|
||||
|
||||
# Higher-level commands which invoke the functionality of this package
|
||||
# for an arbitrary tcl shell (tclsh, wish, ...). This is required by a
|
||||
# repository as while the tcl shell executing packages uses the same
|
||||
# platform in general as a repository application there can be
|
||||
# differences in detail (i.e. 32/64 bit builds).
|
||||
|
||||
# ### ### ### ######### ######### #########
|
||||
## Requirements
|
||||
|
||||
package require platform
|
||||
namespace eval ::platform::shell {}
|
||||
|
||||
# ### ### ### ######### ######### #########
|
||||
## Implementation
|
||||
|
||||
# -- platform::shell::generic
|
||||
|
||||
proc ::platform::shell::generic {shell} {
|
||||
# Argument is the path to a tcl shell.
|
||||
|
||||
CHECK $shell
|
||||
LOCATE base out
|
||||
|
||||
set code {}
|
||||
# Forget any pre-existing platform package, it might be in
|
||||
# conflict with this one.
|
||||
lappend code {package forget platform}
|
||||
# Inject our platform package
|
||||
lappend code [list source $base]
|
||||
# Query and print the architecture
|
||||
lappend code {puts [platform::generic]}
|
||||
# And done
|
||||
lappend code {exit 0}
|
||||
|
||||
set arch [RUN $shell [join $code \n]]
|
||||
|
||||
if {$out} {file delete -force $base}
|
||||
return $arch
|
||||
}
|
||||
|
||||
# -- platform::shell::identify
|
||||
|
||||
proc ::platform::shell::identify {shell} {
|
||||
# Argument is the path to a tcl shell.
|
||||
|
||||
CHECK $shell
|
||||
LOCATE base out
|
||||
|
||||
set code {}
|
||||
# Forget any pre-existing platform package, it might be in
|
||||
# conflict with this one.
|
||||
lappend code {package forget platform}
|
||||
# Inject our platform package
|
||||
lappend code [list source $base]
|
||||
# Query and print the architecture
|
||||
lappend code {puts [platform::identify]}
|
||||
# And done
|
||||
lappend code {exit 0}
|
||||
|
||||
set arch [RUN $shell [join $code \n]]
|
||||
|
||||
if {$out} {file delete -force $base}
|
||||
return $arch
|
||||
}
|
||||
|
||||
# -- platform::shell::platform
|
||||
|
||||
proc ::platform::shell::platform {shell} {
|
||||
# Argument is the path to a tcl shell.
|
||||
|
||||
CHECK $shell
|
||||
|
||||
set code {}
|
||||
lappend code {puts $tcl_platform(platform)}
|
||||
lappend code {exit 0}
|
||||
|
||||
return [RUN $shell [join $code \n]]
|
||||
}
|
||||
|
||||
# ### ### ### ######### ######### #########
|
||||
## Internal helper commands.
|
||||
|
||||
proc ::platform::shell::CHECK {shell} {
|
||||
if {![file exists $shell]} {
|
||||
return -code error "Shell \"$shell\" does not exist"
|
||||
}
|
||||
if {![file executable $shell]} {
|
||||
return -code error "Shell \"$shell\" is not executable (permissions)"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
proc ::platform::shell::LOCATE {bv ov} {
|
||||
upvar 1 $bv base $ov out
|
||||
|
||||
# Locate the platform package for injection into the specified
|
||||
# shell. We are using package management to find it, whereever it
|
||||
# is, instead of using hardwired relative paths. This allows us to
|
||||
# install the two packages as TMs without breaking the code
|
||||
# here. If the found package is wrapped we copy the code somewhere
|
||||
# where the spawned shell will be able to read it.
|
||||
|
||||
# This code is brittle, it needs has to adapt to whatever changes
|
||||
# are made to the TM code, i.e. the provide statement generated by
|
||||
# tm.tcl
|
||||
|
||||
set pl [package ifneeded platform [package require platform]]
|
||||
set base [lindex $pl end]
|
||||
|
||||
set out 0
|
||||
if {[lindex [file system $base]] ne "native"} {
|
||||
set temp [TEMP]
|
||||
file copy -force $base $temp
|
||||
set base $temp
|
||||
set out 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
proc ::platform::shell::RUN {shell code} {
|
||||
set c [TEMP]
|
||||
set cc [open $c w]
|
||||
puts $cc $code
|
||||
close $cc
|
||||
|
||||
set e [TEMP]
|
||||
|
||||
set code [catch {
|
||||
exec $shell $c 2> $e
|
||||
} res]
|
||||
|
||||
file delete $c
|
||||
|
||||
if {$code} {
|
||||
append res \n[read [set chan [open $e r]]][close $chan]
|
||||
file delete $e
|
||||
return -code error "Shell \"$shell\" is not executable ($res)"
|
||||
}
|
||||
|
||||
file delete $e
|
||||
return $res
|
||||
}
|
||||
|
||||
proc ::platform::shell::TEMP {} {
|
||||
set prefix platform
|
||||
|
||||
# This code is copied out of Tcllib's fileutil package.
|
||||
# (TempFile/tempfile)
|
||||
|
||||
set tmpdir [DIR]
|
||||
|
||||
set chars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
set nrand_chars 10
|
||||
set maxtries 10
|
||||
set access [list RDWR CREAT EXCL TRUNC]
|
||||
set permission 0600
|
||||
set channel ""
|
||||
set checked_dir_writable 0
|
||||
set mypid [pid]
|
||||
for {set i 0} {$i < $maxtries} {incr i} {
|
||||
set newname $prefix
|
||||
for {set j 0} {$j < $nrand_chars} {incr j} {
|
||||
append newname [string index $chars \
|
||||
[expr {int(rand()*62)}]]
|
||||
}
|
||||
set newname [file join $tmpdir $newname]
|
||||
if {[file exists $newname]} {
|
||||
after 1
|
||||
} else {
|
||||
if {[catch {open $newname $access $permission} channel]} {
|
||||
if {!$checked_dir_writable} {
|
||||
set dirname [file dirname $newname]
|
||||
if {![file writable $dirname]} {
|
||||
return -code error "Directory $dirname is not writable"
|
||||
}
|
||||
set checked_dir_writable 1
|
||||
}
|
||||
} else {
|
||||
# Success
|
||||
close $channel
|
||||
return [file normalize $newname]
|
||||
}
|
||||
}
|
||||
}
|
||||
if {$channel != ""} {
|
||||
return -code error "Failed to open a temporary file: $channel"
|
||||
} else {
|
||||
return -code error "Failed to find an unused temporary file name"
|
||||
}
|
||||
}
|
||||
|
||||
proc ::platform::shell::DIR {} {
|
||||
# This code is copied out of Tcllib's fileutil package.
|
||||
# (TempDir/tempdir)
|
||||
|
||||
global tcl_platform env
|
||||
|
||||
set attempdirs [list]
|
||||
|
||||
foreach tmp {TMPDIR TEMP TMP} {
|
||||
if { [info exists env($tmp)] } {
|
||||
lappend attempdirs $env($tmp)
|
||||
}
|
||||
}
|
||||
|
||||
switch $tcl_platform(platform) {
|
||||
windows {
|
||||
lappend attempdirs "C:\\TEMP" "C:\\TMP" "\\TEMP" "\\TMP"
|
||||
}
|
||||
macintosh {
|
||||
set tmpdir $env(TRASH_FOLDER) ;# a better place?
|
||||
}
|
||||
default {
|
||||
lappend attempdirs \
|
||||
[file join / tmp] \
|
||||
[file join / var tmp] \
|
||||
[file join / usr tmp]
|
||||
}
|
||||
}
|
||||
|
||||
lappend attempdirs [pwd]
|
||||
|
||||
foreach tmp $attempdirs {
|
||||
if { [file isdirectory $tmp] && [file writable $tmp] } {
|
||||
return [file normalize $tmp]
|
||||
}
|
||||
}
|
||||
|
||||
# Fail if nothing worked.
|
||||
return -code error "Unable to determine a proper directory for temporary files"
|
||||
}
|
||||
|
||||
# ### ### ### ######### ######### #########
|
||||
## Ready
|
||||
|
||||
package provide platform::shell 1.1.4
|
||||
527
ruby/lib/tcltk/tcl8/8.5/msgcat-1.4.5.tm
Normal file
527
ruby/lib/tcltk/tcl8/8.5/msgcat-1.4.5.tm
Normal file
@@ -0,0 +1,527 @@
|
||||
# msgcat.tcl --
|
||||
#
|
||||
# This file defines various procedures which implement a
|
||||
# message catalog facility for Tcl programs. It should be
|
||||
# loaded with the command "package require msgcat".
|
||||
#
|
||||
# Copyright (c) 1998-2000 by Ajuba Solutions.
|
||||
# Copyright (c) 1998 by Mark Harrison.
|
||||
#
|
||||
# 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]
|
||||
|
||||
# Map of language codes used in Windows registry to those of ISO-639
|
||||
if {[info sharedlibextension] eq ".dll"} {
|
||||
variable WinRegToISO639 [dict create {*}{
|
||||
01 ar 0401 ar_SA 0801 ar_IQ 0c01 ar_EG 1001 ar_LY 1401 ar_DZ
|
||||
1801 ar_MA 1c01 ar_TN 2001 ar_OM 2401 ar_YE 2801 ar_SY
|
||||
2c01 ar_JO 3001 ar_LB 3401 ar_KW 3801 ar_AE 3c01 ar_BH
|
||||
4001 ar_QA
|
||||
02 bg 0402 bg_BG
|
||||
03 ca 0403 ca_ES
|
||||
04 zh 0404 zh_TW 0804 zh_CN 0c04 zh_HK 1004 zh_SG 1404 zh_MO
|
||||
05 cs 0405 cs_CZ
|
||||
06 da 0406 da_DK
|
||||
07 de 0407 de_DE 0807 de_CH 0c07 de_AT 1007 de_LU 1407 de_LI
|
||||
08 el 0408 el_GR
|
||||
09 en 0409 en_US 0809 en_GB 0c09 en_AU 1009 en_CA 1409 en_NZ
|
||||
1809 en_IE 1c09 en_ZA 2009 en_JM 2409 en_GD 2809 en_BZ
|
||||
2c09 en_TT 3009 en_ZW 3409 en_PH
|
||||
0a es 040a es_ES 080a es_MX 0c0a es_ES@modern 100a es_GT 140a es_CR
|
||||
180a es_PA 1c0a es_DO 200a es_VE 240a es_CO 280a es_PE
|
||||
2c0a es_AR 300a es_EC 340a es_CL 380a es_UY 3c0a es_PY
|
||||
400a es_BO 440a es_SV 480a es_HN 4c0a es_NI 500a es_PR
|
||||
0b fi 040b fi_FI
|
||||
0c fr 040c fr_FR 080c fr_BE 0c0c fr_CA 100c fr_CH 140c fr_LU
|
||||
180c fr_MC
|
||||
0d he 040d he_IL
|
||||
0e hu 040e hu_HU
|
||||
0f is 040f is_IS
|
||||
10 it 0410 it_IT 0810 it_CH
|
||||
11 ja 0411 ja_JP
|
||||
12 ko 0412 ko_KR
|
||||
13 nl 0413 nl_NL 0813 nl_BE
|
||||
14 no 0414 no_NO 0814 nn_NO
|
||||
15 pl 0415 pl_PL
|
||||
16 pt 0416 pt_BR 0816 pt_PT
|
||||
17 rm 0417 rm_CH
|
||||
18 ro 0418 ro_RO 0818 ro_MO
|
||||
19 ru 0819 ru_MO
|
||||
1a hr 041a hr_HR 081a sr_YU 0c1a sr_YU@cyrillic
|
||||
1b sk 041b sk_SK
|
||||
1c sq 041c sq_AL
|
||||
1d sv 041d sv_SE 081d sv_FI
|
||||
1e th 041e th_TH
|
||||
1f tr 041f tr_TR
|
||||
20 ur 0420 ur_PK 0820 ur_IN
|
||||
21 id 0421 id_ID
|
||||
22 uk 0422 uk_UA
|
||||
23 be 0423 be_BY
|
||||
24 sl 0424 sl_SI
|
||||
25 et 0425 et_EE
|
||||
26 lv 0426 lv_LV
|
||||
27 lt 0427 lt_LT
|
||||
28 tg 0428 tg_TJ
|
||||
29 fa 0429 fa_IR
|
||||
2a vi 042a vi_VN
|
||||
2b hy 042b hy_AM
|
||||
2c az 042c az_AZ@latin 082c az_AZ@cyrillic
|
||||
2d eu
|
||||
2e wen 042e wen_DE
|
||||
2f mk 042f mk_MK
|
||||
30 bnt 0430 bnt_TZ
|
||||
31 ts 0431 ts_ZA
|
||||
32 tn
|
||||
33 ven 0433 ven_ZA
|
||||
34 xh 0434 xh_ZA
|
||||
35 zu 0435 zu_ZA
|
||||
36 af 0436 af_ZA
|
||||
37 ka 0437 ka_GE
|
||||
38 fo 0438 fo_FO
|
||||
39 hi 0439 hi_IN
|
||||
3a mt 043a mt_MT
|
||||
3b se 043b se_NO
|
||||
043c gd_UK 083c ga_IE
|
||||
3d yi 043d yi_IL
|
||||
3e ms 043e ms_MY 083e ms_BN
|
||||
3f kk 043f kk_KZ
|
||||
40 ky 0440 ky_KG
|
||||
41 sw 0441 sw_KE
|
||||
42 tk 0442 tk_TM
|
||||
43 uz 0443 uz_UZ@latin 0843 uz_UZ@cyrillic
|
||||
44 tt 0444 tt_RU
|
||||
45 bn 0445 bn_IN
|
||||
46 pa 0446 pa_IN
|
||||
47 gu 0447 gu_IN
|
||||
48 or 0448 or_IN
|
||||
49 ta
|
||||
4a te 044a te_IN
|
||||
4b kn 044b kn_IN
|
||||
4c ml 044c ml_IN
|
||||
4d as 044d as_IN
|
||||
4e mr 044e mr_IN
|
||||
4f sa 044f sa_IN
|
||||
50 mn
|
||||
51 bo 0451 bo_CN
|
||||
52 cy 0452 cy_GB
|
||||
53 km 0453 km_KH
|
||||
54 lo 0454 lo_LA
|
||||
55 my 0455 my_MM
|
||||
56 gl 0456 gl_ES
|
||||
57 kok 0457 kok_IN
|
||||
58 mni 0458 mni_IN
|
||||
59 sd
|
||||
5a syr 045a syr_TR
|
||||
5b si 045b si_LK
|
||||
5c chr 045c chr_US
|
||||
5d iu 045d iu_CA
|
||||
5e am 045e am_ET
|
||||
5f ber 045f ber_MA
|
||||
60 ks 0460 ks_PK 0860 ks_IN
|
||||
61 ne 0461 ne_NP 0861 ne_IN
|
||||
62 fy 0462 fy_NL
|
||||
63 ps
|
||||
64 tl 0464 tl_PH
|
||||
65 div 0465 div_MV
|
||||
66 bin 0466 bin_NG
|
||||
67 ful 0467 ful_NG
|
||||
68 ha 0468 ha_NG
|
||||
69 nic 0469 nic_NG
|
||||
6a yo 046a yo_NG
|
||||
70 ibo 0470 ibo_NG
|
||||
71 kau 0471 kau_NG
|
||||
72 om 0472 om_ET
|
||||
73 ti 0473 ti_ET
|
||||
74 gn 0474 gn_PY
|
||||
75 cpe 0475 cpe_US
|
||||
76 la 0476 la_VA
|
||||
77 so 0477 so_SO
|
||||
78 sit 0478 sit_CN
|
||||
79 pap 0479 pap_AN
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
# msgcat::mc --
|
||||
#
|
||||
# Find the translation for the given string based on the current
|
||||
# locale setting. Check the local namespace first, then look in each
|
||||
# parent namespace until the source is found. If additional args are
|
||||
# specified, use the format command to work them into the traslated
|
||||
# string.
|
||||
#
|
||||
# Arguments:
|
||||
# src The string to translate.
|
||||
# args Args to pass to the format command
|
||||
#
|
||||
# Results:
|
||||
# Returns the translated string. Propagates errors thrown by the
|
||||
# format command.
|
||||
|
||||
proc msgcat::mc {src args} {
|
||||
# Check for the src in each namespace starting from the local and
|
||||
# ending in the global.
|
||||
|
||||
variable Msgs
|
||||
variable Loclist
|
||||
variable Locale
|
||||
|
||||
set ns [uplevel 1 [list ::namespace current]]
|
||||
|
||||
while {$ns != ""} {
|
||||
foreach loc $Loclist {
|
||||
if {[dict exists $Msgs $loc $ns $src]} {
|
||||
if {[llength $args] == 0} {
|
||||
return [dict get $Msgs $loc $ns $src]
|
||||
} else {
|
||||
return [format [dict get $Msgs $loc $ns $src] {*}$args]
|
||||
}
|
||||
}
|
||||
}
|
||||
set ns [namespace parent $ns]
|
||||
}
|
||||
# we have not found the translation
|
||||
return [uplevel 1 [list [namespace origin mcunknown] \
|
||||
$Locale $src {*}$args]]
|
||||
}
|
||||
|
||||
# msgcat::mclocale --
|
||||
#
|
||||
# Query or set the current locale.
|
||||
#
|
||||
# Arguments:
|
||||
# newLocale (Optional) The new locale string. Locale strings
|
||||
# should be composed of one or more sublocale parts
|
||||
# separated by underscores (e.g. en_US).
|
||||
#
|
||||
# Results:
|
||||
# Returns the current locale.
|
||||
|
||||
proc msgcat::mclocale {args} {
|
||||
variable Loclist
|
||||
variable Locale
|
||||
set len [llength $args]
|
||||
|
||||
if {$len > 1} {
|
||||
return -code error "wrong # args: should be\
|
||||
\"[lindex [info level 0] 0] ?newLocale?\""
|
||||
}
|
||||
|
||||
if {$len == 1} {
|
||||
set newLocale [lindex $args 0]
|
||||
if {$newLocale ne [file tail $newLocale]} {
|
||||
return -code error "invalid newLocale value \"$newLocale\":\
|
||||
could be path to unsafe code."
|
||||
}
|
||||
set Locale [string tolower $newLocale]
|
||||
set Loclist {}
|
||||
set word ""
|
||||
foreach part [split $Locale _] {
|
||||
set word [string trim "${word}_${part}" _]
|
||||
if {$word ne [lindex $Loclist 0]} {
|
||||
set Loclist [linsert $Loclist 0 $word]
|
||||
}
|
||||
}
|
||||
lappend Loclist {}
|
||||
set Locale [lindex $Loclist 0]
|
||||
}
|
||||
return $Locale
|
||||
}
|
||||
|
||||
# msgcat::mcpreferences --
|
||||
#
|
||||
# Fetch the list of locales used to look up strings, ordered from
|
||||
# most preferred to least preferred.
|
||||
#
|
||||
# Arguments:
|
||||
# None.
|
||||
#
|
||||
# Results:
|
||||
# Returns an ordered list of the locales preferred by the user.
|
||||
|
||||
proc msgcat::mcpreferences {} {
|
||||
variable Loclist
|
||||
return $Loclist
|
||||
}
|
||||
|
||||
# msgcat::mcload --
|
||||
#
|
||||
# Attempt to load message catalogs for each locale in the
|
||||
# preference list from the specified directory.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Arguments:
|
||||
# locale The locale to use.
|
||||
# src The source string.
|
||||
# dest (Optional) The translated string. If omitted,
|
||||
# the source string is used.
|
||||
#
|
||||
# Results:
|
||||
# Returns the new locale.
|
||||
|
||||
proc msgcat::mcset {locale src {dest ""}} {
|
||||
variable Msgs
|
||||
if {[llength [info level 0]] == 3} { ;# dest not specified
|
||||
set dest $src
|
||||
}
|
||||
|
||||
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.
|
||||
# pairs One or more src/dest pairs (must be even length)
|
||||
#
|
||||
# Results:
|
||||
# Returns the number of pairs processed
|
||||
|
||||
proc msgcat::mcmset {locale pairs } {
|
||||
variable Msgs
|
||||
|
||||
set length [llength $pairs]
|
||||
if {$length % 2} {
|
||||
return -code error "bad translation list:\
|
||||
should be \"[lindex [info level 0] 0] locale {src dest ...}\""
|
||||
}
|
||||
|
||||
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
|
||||
# purposes. The default behavior is to return the source string.
|
||||
# If additional args are specified, the format command will be used
|
||||
# to work them into the traslated string.
|
||||
#
|
||||
# Arguments:
|
||||
# locale The current locale.
|
||||
# src The string to be translated.
|
||||
# args Args to pass to the format command
|
||||
#
|
||||
# Results:
|
||||
# Returns the translated value.
|
||||
|
||||
proc msgcat::mcunknown {locale src args} {
|
||||
if {[llength $args]} {
|
||||
return [format $src {*}$args]
|
||||
} else {
|
||||
return $src
|
||||
}
|
||||
}
|
||||
|
||||
# msgcat::mcmax --
|
||||
#
|
||||
# Calculates the maximum length of the translated strings of the given
|
||||
# list.
|
||||
#
|
||||
# Arguments:
|
||||
# args strings to translate.
|
||||
#
|
||||
# Results:
|
||||
# Returns the length of the longest translated string.
|
||||
|
||||
proc msgcat::mcmax {args} {
|
||||
set max 0
|
||||
foreach string $args {
|
||||
set translated [uplevel 1 [list [namespace origin mc] $string]]
|
||||
set len [string length $translated]
|
||||
if {$len>$max} {
|
||||
set max $len
|
||||
}
|
||||
}
|
||||
return $max
|
||||
}
|
||||
|
||||
# Convert the locale values stored in environment variables to a form
|
||||
# suitable for passing to [mclocale]
|
||||
proc msgcat::ConvertLocale {value} {
|
||||
# Assume $value is of form: $language[_$territory][.$codeset][@modifier]
|
||||
# Convert to form: $language[_$territory][_$modifier]
|
||||
#
|
||||
# Comment out expanded RE version -- bugs alleged
|
||||
# regexp -expanded {
|
||||
# ^ # Match all the way to the beginning
|
||||
# ([^_.@]*) # Match "lanugage"; ends with _, ., or @
|
||||
# (_([^.@]*))? # Match (optional) "territory"; starts with _
|
||||
# ([.]([^@]*))? # Match (optional) "codeset"; starts with .
|
||||
# (@(.*))? # Match (optional) "modifier"; starts with @
|
||||
# $ # Match all the way to the end
|
||||
# } $value -> language _ territory _ codeset _ modifier
|
||||
if {![regexp {^([^_.@]+)(_([^.@]*))?([.]([^@]*))?(@(.*))?$} $value \
|
||||
-> language _ territory _ codeset _ modifier]} {
|
||||
return -code error "invalid locale '$value': empty language part"
|
||||
}
|
||||
set ret $language
|
||||
if {[string length $territory]} {
|
||||
append ret _$territory
|
||||
}
|
||||
if {[string length $modifier]} {
|
||||
append ret _$modifier
|
||||
}
|
||||
return $ret
|
||||
}
|
||||
|
||||
# Initialize the default locale
|
||||
proc msgcat::Init {} {
|
||||
global env
|
||||
|
||||
#
|
||||
# set default locale, try to get from environment
|
||||
#
|
||||
foreach varName {LC_ALL LC_MESSAGES LANG} {
|
||||
if {[info exists env($varName)] && ("" ne $env($varName))} {
|
||||
if {![catch {
|
||||
mclocale [ConvertLocale $env($varName)]
|
||||
}]} {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
#
|
||||
# On Darwin, fallback to current CFLocale identifier if available.
|
||||
#
|
||||
if {[info exists ::tcl::mac::locale] && $::tcl::mac::locale ne ""} {
|
||||
if {![catch {
|
||||
mclocale [ConvertLocale $::tcl::mac::locale]
|
||||
}]} {
|
||||
return
|
||||
}
|
||||
}
|
||||
#
|
||||
# The rest of this routine is special processing for Windows or
|
||||
# Cygwin. All other platforms, get out now.
|
||||
#
|
||||
if {([info sharedlibextension] ne ".dll")
|
||||
|| [catch {package require registry}]} {
|
||||
mclocale C
|
||||
return
|
||||
}
|
||||
#
|
||||
# On Windows or Cygwin, try to set locale depending on registry
|
||||
# settings, or fall back on locale of "C".
|
||||
#
|
||||
|
||||
# First check registry value LocalName present from Windows Vista
|
||||
# which contains the local string as RFC5646, composed of:
|
||||
# [a-z]{2,3} : language
|
||||
# -[a-z]{4} : script (optional, translated by table Latn->latin)
|
||||
# -[a-z]{2}|[0-9]{3} : territory (optional, numerical region codes not used)
|
||||
# (-.*)* : variant, extension, private use (optional, not used)
|
||||
# Those are translated to local strings.
|
||||
# Examples: de-CH -> de_ch, sr-Latn-CS -> sr_cs@latin, es-419 -> es
|
||||
#
|
||||
set key {HKEY_CURRENT_USER\Control Panel\International}
|
||||
if {([registry values $key "LocaleName"] ne "")
|
||||
&& [regexp {^([a-z]{2,3})(?:-([a-z]{4}))?(?:-([a-z]{2}))?(?:-.+)?$}\
|
||||
[string tolower [registry get $key "LocaleName"]] match locale\
|
||||
script territory]} {
|
||||
if {"" ne $territory} {
|
||||
append locale _ $territory
|
||||
}
|
||||
set modifierDict [dict create latn latin cyrl cyrillic]
|
||||
if {[dict exists $modifierDict $script]} {
|
||||
append locale @ [dict get $modifierDict $script]
|
||||
}
|
||||
if {![catch {
|
||||
mclocale [ConvertLocale $locale]
|
||||
}]} {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# then check key locale which contains a numerical language ID
|
||||
if {[catch {
|
||||
set locale [registry get $key "locale"]
|
||||
}]} {
|
||||
mclocale C
|
||||
return
|
||||
}
|
||||
#
|
||||
# Keep trying to match against smaller and smaller suffixes
|
||||
# of the registry value, since the latter hexadigits appear
|
||||
# to determine general language and earlier hexadigits determine
|
||||
# more precise information, such as territory. For example,
|
||||
# 0409 - English - United States
|
||||
# 0809 - English - United Kingdom
|
||||
# Add more translations to the WinRegToISO639 array above.
|
||||
#
|
||||
variable WinRegToISO639
|
||||
set locale [string tolower $locale]
|
||||
while {[string length $locale]} {
|
||||
if {![catch {
|
||||
mclocale [ConvertLocale [dict get $WinRegToISO639 $locale]]
|
||||
}]} {
|
||||
return
|
||||
}
|
||||
set locale [string range $locale 1 end]
|
||||
}
|
||||
#
|
||||
# No translation known. Fall back on "C" locale
|
||||
#
|
||||
mclocale C
|
||||
}
|
||||
msgcat::Init
|
||||
3412
ruby/lib/tcltk/tcl8/8.5/tcltest-2.3.4.tm
Normal file
3412
ruby/lib/tcltk/tcl8/8.5/tcltest-2.3.4.tm
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user