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


4.7 翻訳可能文字列の特別なケース

注意深い読者なら、常に翻訳可能な文字列をgettext(または同様のもの)でマークすることはできないことに気づくでしょう。たとえば以下のようなケースです:

{
  static const char *messages[] = {
    "some very meaningful message",
    "and another one"
  };
  const char *string;
  …
  string
    = index > 1 ? "a default message" : messages[index];

  fputs (string);
  …
}

文字列"a default message"にたいするマーク付けは問題ありませんが、配列messagesを初期化する文字列はマークできません。どうすればよいのでしょうか? このような場合は2つのタスクを達成する必要があります。最初にxgettextプログラムが文字列を見つけ出せるように文字列をマークします(xgettext Invocationを参照してください)。次に実行時に文字列を出力する前に、文字列を翻訳するのです。

最初のタスクは、no-opという新しいキーワードを作ることにより達成できます。2番目のタスクは、配列の文字列にたいするすべてのアクセスポイントをマークします。考えられる解決策の1つは、以下のようなものです:

#define gettext_noop(String) String

{
  static const char *messages[] = {
    gettext_noop ("some very meaningful message"),
    gettext_noop ("and another one")
  };
  const char *string;
  …
  string
    = index > 1 ? gettext ("a default message") : gettext (messages[index]);

  fputs (string);
  …
}

どのようなケースでも、fputsに記述された文字列は翻訳されると思ってください。どのようにしてxgettextが、追加のキーワードgettext_noopを認識するかについては、xgettext Invocationを参照してください。

もちろん、これが唯一の解決策という訳ではありません。以下の方法のうちのいずれかを使用することもできます:

#define gettext_noop(String) String

{
  static const char *messages[] = {
    gettext_noop ("some very meaningful message"),
    gettext_noop ("and another one")
  };
  const char *string;
  …
  string
    = index > 1 ? gettext_noop ("a default message") : messages[index];

  fputs (gettext (string));
  …
}

しかしこの方法には欠点があります。プログラマーは文字列"a default message"にもgettext_noopを使うよう留意する必要があります。gettextを使用することにより、予期しない結果となる場合もあります。

利点の1つは、どのようなケースでも出力が翻訳されるようにするために、制御フローを分析する必要がないことです。この分析は一般的に難しいものではありませんが、これにあてはまらないような状況では、2番目の方法を使用することもできます。