次のページ
前のページ
目次へ
1996年9月 Locales mini-HOWTO
Peeter Joot, joot@ecf.toronto.edu 著
松田 員幸 <kazm@ca2.so-net.or.jp> 訳
v1.3, 6 June 1996.
このドキュメントでは、Linux マシンで locale を使用するための設定方法に
ついて説明します。 [ 訳注:locale は「ロケール」とも「ロカール」とも表
記されることがあります。どちらでも間違いではないのですが、ここでは
locale と英語のままで表記します。]
1. はじめに
これは、私が localedef をインストールし、locale をコンパイルして試して
みるためにしなければならなかったことを説明してるだけです。私はただ楽し
みとしてやってみましたが、おそらくちゃんと試すことに興味がある人もいる
でしょう。一度設定すれば、自分が選択した locale で、NLS を利用できるア
プリケーションを使えるようになるでしょう。しばらくすれば locale サポー
トは標準配布の一部となり、この mini-HOWTO のほとんどは無用の長物となる
でしょう。[ 訳注:現時点では Linux のライブラリは日本語の扱える locale
をサポートしていないようです。だからこのドキュメントの翻訳を読む人に
とって、この情報はきっと役に立たないでしょう。]
2. とりあえず "locale" とは何でしょう?
locale は、プログラムにハードコーディングすべきでない、言語や文化に特
有のいくつかのものを隠蔽します。
自分のコンピュータに複数の locale がインストールされているなら、下記の
環境変数によって locale を考慮するプログラムのふるまいを選択できます。
デフォルトの locale は C あるいは POSIX で、これは libc の中にハードコ
ーディングされています。
LANG
これは locale を設定しますが、他の LC_xxxx という環境変数によっ
て上書きされます。
LC_COLLATE
並べかえ(ソート)の順番です。
LC_CTYPE
文字定義、大文字、小文字など。これらは toupper、tolower、
islower、isdigit のような関数で用いられます。 [訳注:man 3
isalpha 参照のこと。]
LC_MONETARY
期待される形式で貨幣単位をフォーマットするのに必要な情報を含みま
す。それは千の区切り文字、小数点区切り文字、通貨記号を意味するも
のやその位置を定義します。
LC_NUMERIC
期待される千、小数点区切り文字、数字集合です。
LC_TIME
時刻、日付を指定する方法です。これは曜日、短縮形/非短縮形での月
のようなものです。
LC_MESSAGES
特に言うことはありません。
LC_ALL
これは locale を設定し、他の LC_xxxx 環境変数に上書きされます。
いくつかの他の locale を示します。他にもたくさんあります。
en_CA
English Canadian.
en_US
US English.
de_DE
Germany's German.
fr_FR
France's French.
[訳注:日本語関係は ja,ja_JP,ja_JP.eucJP,ja_JP.SJIS,ja_JP.JIS7 等]
あなたがプログラムを書いていて、国際的に利用されることを望むなら、
locale を使うべきです。そのもっとも大きな理由は、誰もがあなたと同じ文
字セットやコードページを使おうとしているわけではないということです。
プログラムの中で以下のようなことをしないように。
/* check for alphabetic characters */
if ( (( c >= 'a') && ( c <= 'z' )) ||
(( c >= 'A') && ( c <= 'Z' )) ) { ... }
もしこんなプログラムを書くなら、そのプログラムは、/user/file/... は
ASCII で、ASCII 以外のなにものでもないことを仮定しており、ユーザの
locale のコードページ定義を尊重していません。例えば、ドイツ語環境では
a-ウムラウトのような文字で始まります。代わりに、isalpha() のような
locale 依存関数を用いるべきです。もしプログラムがはっきりと US-ASCII
アルファベットだけを使うことを要求している場合も、isalpha() 関数を用い
ますが、その場合は、setlocale(LC_CTYPE,"C") を実行し、LANG、
LC_CTYPE、LC_ALL 環境変数を "C" に設定しなければなりません。
locale を使えば非常に融通が効き、プログラマは ASCII ベースの C プログ
ラムを書くときにしていたかもしれないある種の仮定ができなくなります。
たとえば、文字のコード位置を仮定することはできません。'A' のコード位置
を 0x41 ではなく 0xC1 に定義する charmap ファイルを作ることを何ものも
止めることはできません。これは実際にメインフレームで用いられる IBM コ
ードページ 37 で、'A' のコード位置マッピングです。一方前者は、 US-
ASCII、iso8859-x などで用いられています。
基本的な考えは、異なる人々が異なる言語を話し、異なる並べかえ順を想定
し、異なるコードページを用い、異なる国に住んでいることです。locale と
locale に依存するプログラムはそれを尊重し、それに応じた扱いをするよう
に意図されています。そうするのに格別の努力はいりませんし、プログラムを
書くときにちょっと気分を変えるだけでよいのです。
3. ノート
o 自分のマシンで locale を設定するためには、いくつかのものをアップグ
レードする必要があります。ftp.tu-clausthal.de:/pub/linux/SLT/nls に
locale と localedef の a.out 版が(nlsutils-0.5.tar.gzという名前で)
あるようです。で、ELF システムを持っていないか、ELF が欲しくないな
ら、これを使うことができます。たぶんどこか他のところで nlsutils
パッケージのコピーがあるでしょう。しかし、私はそれを見つけていませ
ん [ 訳注:国内にはないようですが、debian パッケージには .deb の形
で入っているようです ] 。私は locale と localedef のスタンドアロン
版を聞いたことがありませんが、対応する libc をインストールしなけれ
ばならないことは考慮にいれておいて下さい。ですからこの HOWTO の大部
分は 私が libc とそのファミリーをアップグレードするためにしなければ
ならなかったことの記録でしかありません。もしあなたが libc をインス
トールするなら、私がしたように ELF システムを走らせ、locale をセッ
トアップするときに ELF に移行する必要があります。
o 私が行なったシステム移行の内容は、a.out から ELF への移行ですべきこ
とと同じです。ELF に移行していないか、Linux の再インストールで ELF
に移行しているなら、sunsite のミラーから最新の ELF HOWTO をもってき
てください。これはすばらしいガイドで、libc、ld.so、などの ELF シス
テムへの移行をインストールするためのガイダンスでもあります。
o 何をインストールするにしても、適当なリリースノートや README などの
ファイルを読んでください。もし、ここで私が書いたことを誤解したり、
(そうでないことを願うけど)私がここで書いたことを実行することであな
たのシステムをぐちゃぐちゃにしてしまっても、どうか私を責めないで下
さい。 [ 訳注:そして、できれば翻訳者も責めないでください。 ]
o 新しい libc や ld.so のインストールを間違えると、ブートできないシス
テムにしてしまうことがあります。ブードディスクをつくっておくべき
で、消えてしまうと取り返しのつかない重要なデータは必ずバックアップ
しておくように。
4. 必要なもの
2、3のものをいろいろな場所からダウンロードする必要があります。ここに
ある locale ソースファイルを除くすべてのものは sunsite.unc.edu、
tsx-11.mit.edu、なるべくならこれらのサイトのミラーから得ることができま
す。 [ 訳注:国内では sunsite.sut.ac.jp,ftp.sra.co.jp など。 locale 関
係以外では ftp.kuis.kyoto-u.ac.jp も使えます。どうせなら kernel を
2.0.x にしてしまってもっと新しいライブラリを使ったほうがよいでしょ
う。linux-2.0.x/Documentation/Changes を参照のこと。 ]
o locale と charmap のソース --- localedef を使ってコンパイルするもの
です。
o libc-5.2.18.bin.tar.gz --- c と math ライブラリに対する ELF 共有ラ
イブラリです。
o libc-5.2.18.tar.gz --- ELF 共有ライブラリのソースコードです。
localedef コンパイルするのにこれが必要です。
o make-3.74.tar.gz --- dirent のバグを修正するためのパッチを合体する
ためにコンパイルする必要があります。
o release.libc-5.2.18 --- これらのリリースノートには make を作成する
ためのパッチがあります。
o ld.so-1.7.12+ --- ダイナミック・リンカです。
o ELF gcc-2.7.2+ --- コンパイルに必要です。
o ELF kernel 1.1.92+, or ELF kernel 1.3.40+ --- コンパイルに必要で
す。
o binutils 2.6.0.2+ --- コンパイルに必要です。
locale のソースを入手できるサイトはたぶんたくさんあります。私が知って
いる範囲では次のサイトで locale と charmap のソースを入手できます。
dkuug.dk:/i18n/WG15-collection/locales
<ftp://dkuug.dk/i18n/WG15-collection/locales>
dkuug.dk:/i18n/WG15-collection/charmaps
<ftp://dkuug.dk/i18n/WG15-collection/charmaps>
-- [ 訳注:日本語の locale は XFree86 にも入っています。 ] --
5. 全てのものをインストールする
これは全てをインストールするためのものです。私はすでにこれを行なう前に
インストールした ELF システム(コンパイラ、カーネルなど...)を持っていま
す。
1. まず、binutils パッケージをインストールしました。
tar xzf binutils-2.6.0.2.bin.tar.gz -C /
2. 次にダイナミック・リンカをインストールしました:
tar zxf ld.so-1.7.12.tar.gz -C /usr/src
cd /usr/src/ld.so-1.7.12
sh instldso.sh
3. 次に libc バイナリをインストールしました。詳しい手順は
libc-5.2.18 のリリースノートを参照してください。
rm -f /usr/lib/libc.so /usr/lib/libm.so
rm -f /usr/include/iolibio.h /usr/include/iostdio.h
rm -f /usr/include/ld_so_config.h /usr/include/localeinfo.h
rm -rf /usr/include/netinet /usr/include/net /usr/include/pthread
tar -xzf libc-5.2.18.bin.tar.gz -C /
4. 新しい共有ライブラリを認識させるために ldconfig を実行する必
要があります。
ldconfig -v
5. libc には make やいくつかのプログラムを壊すバグがあります。私
は次のように make を再構築し、インストールしました: [ 訳注:
新しい libc で使える make-3.74 のバイナリもあります ]
tar zxf make-3.74.tar.gz -C /usr/src
cd /usr/src/make-3.74
patch < /whereever_you_put_it/release.libc-5.2.18
configure --prefix=/usr
sh build.sh
../make install
cd ..
rm -rf make-3.74
6. さあ、これで localedef をコンパイル、インストールできます。
mkdir /usr/src/libc
tar zxf libc-5.2.18.tar.gz -C /usr/src/libc
cd /usr/src/libc
cd include
ln -s /usr/src/linux/include/asm .
ln -s /usr/src/linux/include/linux .
cd ../libc
../configure
# 私はこの2回の make が必要なことかどうかは自信がありませ
# んが、安全のためにやっているだけです。
make clean ; make depend
cd locale
make programs
mv localedef /usr/local/bin
mv locale /usr/local/bin
7. localedef がそれらを見つけるところに charmap を置いて下さい。
これは charmap.tar として dkuug.dk ftp サイトからダウンロード
できる、 charmap と locale ソースを用います。
tar xf charmaps.tar -C /tmp
mkdir /usr/share/nls
mkdir /usr/share/nls/charmap
mkdir /usr/share/locale
mv /tmp/charmaps/* /usr/share/nls/charmap
rm -rf /tmp/charmaps
tar xf locales.tar -C /usr/share # 好きなところに置いてください
#
# locale ソースのいくつかは `copy' を使い、これは他の
# locale に依存します。私は以下のコマンドを作成するための
# makefile を grep、cut、sed を使って作成しました。これは
# /usr/share/locale ディレクトリにある全ての locale オブ
# ジェクトを作成します。
#
localedef -ci locales/en_DK -f ISO_8859-1:1987 en_DK
localedef -ci locales/sv_SE -f ISO_8859-1:1987 sv_SE
localedef -ci locales/fi_FI -f ISO_8859-1:1987 fi_FI
localedef -ci locales/sv_FI -f ISO_8859-1:1987 sv_FI
localedef -ci locales/ro_RO -f ISO_8859-1:1987 ro_RO
localedef -ci locales/pt_PT -f ISO_8859-1:1987 pt_PT
localedef -ci locales/no_NO -f ISO_8859-1:1987 no_NO
localedef -ci locales/nl_NL -f ISO_8859-1:1987 nl_NL
localedef -ci locales/fr_BE -f ISO_8859-1:1987 fr_BE
localedef -ci locales/nl_BE -f ISO_8859-1:1987 nl_BE
localedef -ci locales/da_DK -f ISO_8859-1:1987 da_DK
localedef -ci locales/kl_GL -f ISO_8859-1:1987 kl_GL
localedef -ci locales/it_IT -f ISO_8859-1:1987 it_IT
localedef -ci locales/is_IS -f ISO_8859-1:1987 is_IS
localedef -ci locales/fr_LU -f ISO_8859-1:1987 fr_LU
localedef -ci locales/fr_FR -f ISO_8859-1:1987 fr_FR
localedef -ci locales/de_DE -f ISO_8859-1:1987 de_DE
localedef -ci locales/de_CH -f ISO_8859-1:1987 de_CH
localedef -ci locales/fr_CH -f ISO_8859-1:1987 fr_CH
localedef -ci locales/en_CA -f ISO_8859-1:1987 en_CA
localedef -ci locales/fr_CA -f ISO_8859-1:1987 fr_CA
localedef -ci locales/fo_FO -f ISO_8859-1:1987 fo_FO
localedef -ci locales/et_EE -f ISO_8859-1:1987 et_EE
localedef -ci locales/es_ES -f ISO_8859-1:1987 es_ES
localedef -ci locales/en_US -f ISO_8859-1:1987 en_US
localedef -ci locales/en_GB -f ISO_8859-1:1987 en_GB
localedef -ci locales/en_IE -f ISO_8859-1:1987 en_IE
localedef -ci locales/de_LU -f ISO_8859-1:1987 de_LU
localedef -ci locales/de_BE -f ISO_8859-1:1987 de_BE
localedef -ci locales/de_AT -f ISO_8859-1:1987 de_AT
localedef -ci locales/sl_SI -f ISO_8859-2:1987 sl_SI
localedef -ci locales/ru_RU -f ISO_8859-5:1988 ru_RU
localedef -ci locales/pl_PL -f ISO_8859-2:1987 pl_PL
localedef -ci locales/lv_LV -f BALTIC lv_LV
localedef -ci locales/lt_LT -f BALTIC lt_LT
localedef -ci locales/iw_IL -f ISO_8859-8:1988 iw_IL
localedef -ci locales/hu_HU -f ISO_8859-2:1987 hu_HU
localedef -ci locales/hr_HR -f ISO_8859-4:1988 hr_HR
localedef -ci locales/gr_GR -f ISO_8859-7:1987 gr_GR
6. さあ、どうだ
すべて済めば、作成された locale を使うことができるでしょう。以下は単純
な例題プログラムです。
/* test.c : a simple test to see if the locales can be loaded, and
* used */
#include <locale.h>
#include <stdio.h>
#include <time.h>
main(){
time_t t;
struct tm * _t;
char buf[256];
time(&t);
_t = gmtime(&t);
setlocale(LC_TIME,"");
strftime(buf,256,"%c",_t);
printf("%s\n",buf);
}
現在の locale 環境変数設定がどうなっているかを locale プログラムを使っ
て見ることができます。
$ # compile the simple test program above, and run it with
$ # some different locale settings
$ gcc -s -o Test test.c
$ # see what the current locale is :
$ locale
LANG=POSIX
LC_COLLATE="POSIX"
LC_CTYPE="POSIX"
LC_MONETARY="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_MESSAGES="POSIX"
LC_ALL=
$ # Ho, hum... we're using the boring C locale
$ # let's change to English Canadian:
$ export LC_TIME=en_CA
$ Test
Sat 23 Mar 1996 07:51:49 PM
$ # let's try French Canadian:
$ export LC_TIME=fr_CA
$ Test
sam 23 mar 1996 19:55:27
7. catopen のバグ修正
locale をインストールすると、Linux libc の catopen コマンドにあるバグ
(仕様か?)が修正されます。メッセージ・カタログを使うプログラムを作成
し、ドイツ語カタログを作り、それを /home/peeter/catalogs/de_DE におく
としましょう。
以下のことを de_DE locale をインストールしないで行なってみてください:
export LC_MESSAGES=de_DE
export NLSPATH=/home/peeter/catalogs/%L/%N.cat:$NLSPATH
ドイツ語のメッセージ・カタログがオープンできず、catgets コールのデフォ
ルトのメッセージが使われます。
これは catopen が正しいメッセージ・カテゴリを得るために setlocale コー
ルを実行し、環境変数が設定されていても setlocale が失敗する理由です。
それで catopen は NLSPATH の全ての "%L" に "C" を代入してメッセージ・
カタログをロードしようとします。
locale をインストールしなくてもメッセージ・カタログを用いることはでき
ますが、以下のように NLSPATH の "%L" 部分をはっきりと設定する必要があ
るでしょう:
export NLSPATH=/home/peeter/catalogs/de_DE/%N.cat:$NLSPATH
しかし、これは locale カテゴリ環境変数の全ての目的をくじけさせてしまい
ます。
8. Q & A
このセクションは FAQ に成長するかもしれませんが、本当はまだそうではあ
りません。
8.1. msgcat の質問
私は LINUX のユーザで、以下のテストプログラムを書きました:
--------------------------------------------------------------------
#include <stdio.h>
#include <locale.h>
#include <features.h>
#include <nl_types.h>
main(int argc, char ** argv)
{
nl_catd catd;
setlocale(LC_MESSAGES, "");
catd = catopen("msg", MCLoadBySet);
fprintf(stderr,catgets(catd, 1, 1, "locale message fail\n"));
catclose(catd);
}
--------------------------------------------------------------------
$ msg.m
$set 1
1 locale message pass\n
--------------------------------------------------------------------
もし catopen("/etc/locale/msg.cat",MCLoadBySet); のように catopen で絶
対パスを使えば、正しい結果が得られます。しかし、上の例のようにすると
catopen は -1 を返します(失敗します)。
8.2. msgcat の答え
この質問については前のセクションがある程度答になっていますが、もう少し
付け加えておきます。
メッセージをカタログに置くのに適切な場所はたくさんあります。(メッセー
ジ・カタログの場所を設定する) NLSPATH 環境変数が明示的に設定されていな
くても、libc の中で次のように定義されてます:
$ strings /lib/libc.so.5.2.18 | grep locale | grep %L
/etc/locale/%L/%N.cat:/usr/lib/locale/%L/%N.cat:/usr
/lib/locale/%N/%L:/usr/share/locale/%L/%N.cat:/usr/
local/share/locale/%L/%N.cat
これができたら次のうちの1つをやってみてください:
$ export LC_MESSAGES=en_CA
$ export LC_ALL=en_CA
$ export LANG=en_CA
メッセージ・カタログが次のどれかにコピーされているなら、上記の NLSPATH
と指定された環境で、catopen("msg", MCLoadBySet); はうまく動くでしょ
う。
/etc/locale/en_CA/msg.cat
/usr/lib/locale/en_CA/msg.cat
/usr/lib/locale/msg/en_CA
/usr/share/locale/en_CA/msg.cat
/usr/local/share/locale/en_CA/msg.cat
しかし、もし en_CA locale がインストールされていなければ、setlocale は
失敗するためにうまくいかず、catopen ルーチンで (en_CAではなく) "C" が
"%L" に代入されるでしょう。
9. フィナーレ
以上です。願わくばこのガイドがあなたの助けとなって欲しいと思います。
locale 依存のプログラムを書くために、さらなる情報を探すことができる場
所はおそらくたくさんあるでしょう。libc の info ページに情報がいくつか
ありますし、man ページはいつでも見ることができます。ちょっとWWWページ
を漁れば、たくさんの情報を見つけることができるでしょう。国際化プログラ
ミングに対する良い情報源を見つけたら、お知らせ下さい。そうすればそれら
をこの HOWTO に反映することができます。
次のページ
前のページ
目次へ