X/Open 方式では、翻訳メッセージは「メッセージカタログ」と呼ばれるファイルに格納されます。メッセージカタログファイルは 1 つ以上のセットに分かれ、それぞれのセットの中には 1 つ以上の翻訳メッセージがメッセージ ID と共に存在します。アプリケーションは、オリジナルのメッセージに対して、メッセージカタログファイル、セット ID、メッセージ ID を指定して翻訳メッセージを使用します。
メッセージ処理の手順は次のとおりです。
翻訳したいメッセージに印を付け、そのメッセージが属する集合を指定します。
印をつける操作は、メッセージ文字列を catgets(3C) インタフェースで囲むことで行います。その際に、翻訳メッセージを格納するカタログファイル、セット ID、インデックス ID をあらかじめ決めておきます。catgets() では、「メッセージカタログ記述子」を介してカタログファイルを利用するため、catopen(3C) インタフェースで取得しておきます。
nl_catd hook; hook= catopen("catalog", 0) fprintf(stdout, catgets(hook, SET_1, ID_1, "Defaults:"));
翻訳したいメッセージをソースコードから抽出し、オリジナルメッセージだけのファイルを作ります。
メッセージカタログファイルの中身を作成します。各メッセージはメッセージ ID を持ち、セット ID と共に管理されます。アプリケーションからは、これらの ID だけで利用されるので、オリジナルメッセージと別の ID にならないように注意が必要です。
sun% cat my_message.orig $set 1 my_message set $ 1 Here's the 1st message.¥n $ 2 Here's the 2nd message from %s.¥n
手順 2 で作成したファイルに翻訳したメッセージを追加し、アプリケーションが参照できる形式に変換します。
カタログファイルの変換は gencat コマンドを使用します。gencat コマンドが処理できるファイル形式については gencat(1) のマニュアルページを参照してください。
sun% cp my_message.orig my_message.ja sun% vi my_message.ja sun% cat my_message.ja $set 1 my_message set $ 1 Here's the 1st message.¥n 1 これは第 1 のメッセージです。¥n $ 2 Here's the 2nd message from %s.¥n 2 これは %s からの第 2 のメッセージです。¥n sun% gencat my_catalogue.cat my_message.ja
変換したファイルを一定の場所に置き、アプリケーションがパス名とファイル名から翻訳メッセージのあるファイルを特定し、参照できるようにプログラムを変更します。
ここで、カタログファイルを利用するには、catopen() でメッセージカタログ記述子を取得する必要があります。不要になった記述子は catopen() インタフェースを介して解放できます。
catopen() でカタログファイルを利用するには、カタログファイル名を絶対パス名で指定する方法と、NLSPATH 環境変数とデフォルトパスを利用した相対パス名で指定する方法があります。詳細は catopen(3C)のマニュアルページを参照してください。
なお、これらの API を使用する場合は、nl_types.h ヘッダーファイルを取り込み、処理の最初の段階で setlocale を呼び出し、動作ロケールを適切に設定する必要があります。
sun% cat my_message.c #include <stdio.h> #include <locale.h> #include <nl_types.h> #include <errno.h> #define MY_CATALOGUE "my_catalogue.cat" #define SAMPLE_SET 1 #define SAMPLE_MES_IND 1 int main(int argc, char *argv[]) { int retval; nl_catd hook; setlocale(LC_ALL, ""); hook = catopen(MY_CATALOGUE, 0); if (hook == (nl_catd)-1) { perror("catopen()"); exit(-1); } fprintf(stdout, catgets(hook, SAMPLE_SET, SAMPLE_MES_IND, "Here's the 1st message.¥n")); fprintf(stdout, catgets(hook, SAMPLE_SET, (SAMPLE_MES_IND + 1), "Here's the 2nd message from %s.¥n"), argv[0]); errno = 0; retval = catclose(hook); if (retval != 0) { perror("catclose()"); exit(-1); } return (0); } sun% mkdir -p /usr/tmp/C /usr/tmp/ja sun% cp my_catalogue.cat /usr/tmp/ja sun% setenv NLSPATH /usr/tmp/%L/%N sun% cc -o my_message my_message.c sun% env LANG=C ./my_message Here's the 2nd message from ./my_message. sun% ./my_message これは第 1 のメッセージです。 これは ./my_message からの第 2 のメッセージです。