次: , 前: System Functions, 上: Writing C


5.8 国際化

GNUはあるプログラムのメッセージを様々な言語に翻訳するのを容易にするGNU gettextと呼ばれるライブラリを持っている。あらゆるプログラムでこのライブ ラリを使うべきだ。メッセージがプログラムに現れるとき、それらに英語を使い なさい。そして、それらを他の言語に翻訳するための方法をgettextで提供しな さい。

GNU gettextの使用は翻訳が必要かもしれない、それぞれの文字列の周りに gettextマクロの呼び出しを付けることを含む —次のように。

     printf (gettext ("Processing file `%s'..."));

こうすると、GNU gettextが文字列"Processing file `%s'..."を翻訳さ れたバージョンで置き換えられる。

一度プログラムがgettextを使うことになったら、翻訳が必要な新しい文字列を 加えるとき、gettextへの呼び出しを書く地点を作ってください。

あるパッケージでのGNU gettextの使用は、そのパッケージに対してテキス ト領域名を指定することを含む。テキスト領域名はこのパッケージの翻訳を他 のパッケージの翻訳と分離するのに使われる。通常、テキスト領域名はパッケー ジの名前と同じであるべきだ —例えば、GNU file utilityのために `fileutils'が使われる。

gettextが上手く働くようにするために、単語や文の構造に仮定を設けるコード を書かないようにしなさい。文の正確なテキストがデータによって変わるのよう にしたいとき、条件付けられた単語や句を単一の文脈構成に押し込むよりも、そ れぞれ完全な文を含む二つ以上の文字列定数を使いなさい。

これがやるべきではないものの例だ。

     printf ("%d file%s processed", nfiles,
             nfiles != 1 ? "s" : "");

この例の問題は複数形が`s'を加えることで行われると仮定していることだ。も し書式文字列にgettextを適用するなら、次のように、メッセージが異なる単語 を使うことができるが、

     printf (gettext ("%d file%s processed"), nfiles,
             nfiles != 1 ? "s" : "");

複数形が`s'を使うようになお強制されている。これがより良い方法だ。

     printf ((nfiles != 1 ? "%d files processed"
              : "%d file processed"),
             nfiles);

このやり方で、二つの文字列それぞれに独立してgettextを適用できる。

     printf ((nfiles != 1 ? gettext ("%d files processed")
              : gettext ("%d file processed")),
             nfiles);

こうすると、“file”という単語の複数形を作る、いかなる方法でも実現でき、 “processed”に対して、単語が一致しないといけない言語を扱うこともできる。

同じような問題は次のコードで文脈の構造の水準で現れる。

     printf ("#  Implicit rule search has%s been done.\n",
             f->tried_implicit ? "" : " not");

このコードにgettext呼び出しを与えても、すべての言語で正しい結果を 得られるわけではない。なぜなら、いくつかの言語で否定は文中に一つよりもた くさんの場所で単語を加える必要があるからだ。対照的に、gettext呼び 出しの追加は、もしそのコードが次のように始まるなら、簡単に行える。

     printf (f->tried_implicit
             ? "#  Implicit rule search has been done.\n",
             : "#  Implicit rule search has not been done.\n");