Next: , Previous: , Up: Sources   [Contents][Index]


4.6 キーワードの前の特別なコメント

Cプログラム中の文字列は、しばしばprintfファミリーと呼ばれる関数呼び出しで使用されます。これらで使用される書式指定文字列に関して特筆すべきは、%で始まる書式指定子が含まれていることです。以下のようなコードがあるとしましょう。

printf (gettext ("String `%s' has %d characters\n"), s, strlen (s));

上記の文字列にたいして、以下のようなGermanの翻訳が考えられます:

"%d Zeichen lang ist die Zeichenkette `%s'"

Germanを話せないCプログラマーでも、まずい点があることに気がつくでしょう。文字列中の書式指定子の順序が変更されていますが、printfの引数の順序は変更されません。一番問題なのは、文字列のアドレスが期待されている箇所に、文字列の長さが渡していることです。

翻訳に起因する実行時のエラーを防ぐために、msgfmtは翻訳前の文字列と、翻訳後の文字列に含まれる引数のタイプと数を、静的にチェックすることができます。このチェックを満足しないような場合、msgfmtに‘-c’が指定されていると、msgfmtはエラーを発生させてMOファイルを生成しません。‘msgfmt -c’を使用することにより、エラーを事前に検出して、実行時の問題を防ぐことができます。

Germanの翻訳で上述の単語順が正しい場合は、以下のように記述する必要があります

"%2$d Zeichen lang ist die Zeichenkette `%1$s'"

msgfmtルーチンは、この特別な表記法を認識できます。

プログラムのすべての文字列が書式文字列というわけではないので、.poファイルの中のすべての文字列をmsgfmtがテストする必要はありません。また文字列の中に書式指定子と似た文字列が含まれるが、その文字列がprintfで使われる文字列ではないような場合は、問題が発生します。

そのためxgettextは、それらの書式文字列と思われるメッセージに特別なタグを付与します。このタグ付けは絶対的なルールではなく、発見的なルールです。.poファイルの中のそれらのエントリーには、#,によるコメント行で、c-formatというフラグによりマークされます(PO Filesを参照してください)。

注意深い読者は、まだ問題があると気づくでしょう。発見されたものが間違っている場合です。これは真実であり、そのためにxgettextは、プログラマーが意志決定すべき特別な種類のコメントを認識することができるのです。gettextキーワードと同じ行、またはそれに続く行にxgettext:c-formatという単語を含むコメントを発見すると、xgettextはどのような場合であれ、文字列をc-formatフラグでマークします。この種のコメントは、xgettextが文字列を書式文字列と認識しない場合(テストしてみて実際に認識されない場合)に使う必要があります。gettextキーワードと同じ行にコメントがある場合、翻訳される前にコメントを挿入しなければならないことに注意してください。

このような状況は頻繁に発生します。printf関数にわたされる文字列に書式指定子が含まれない場合もあります。そのようなケースでは通常、fputsを使用するのでしょうが、それでもこのような状況はあり得ます。このような場合、xgettextはそれを書式文字列として認識しませんが、翻訳に書式指定子として認識されるような文字列が含まれていると何が起こるでしょうか? printf関数はパラメーターにアクセスしようとしますが、翻訳前の文字列には何も引数がわたされないため、パラメーターは存在しません。

もちろん他の原因により、xgettextが間違って書式文字列ではない文字列を、書式文字列と認識することがあります。このような場合、msgfmtは多くの警告を出力し、.poファイルへの変換は失敗します。このように間違って書式文字列と認識されるのを防ぐには、上記と同様にxgettext:no-c-formatという文字列を含むコメントを使用します。

文字列がc-formatと間違ってマークされている場合、ユーザーは何が原因なのか調べることができます。--debugオプション使用して、どのように問題を解決するかについては、xgettext Invocationを参照してください。