54.2. 对于程序员

54.2.1. Mechanics

本节描述了如何在 PostgreSQL 发行版中的程序或库中实现本地语言支持。当前,它仅适用于 C 程序。

为程序添加 NLS 支持

  • 将此代码插入程序的启动序列:
#ifdef ENABLE_NLS
#include <locale.h>
#endif

...

#ifdef ENABLE_NLS
setlocale(LC_ALL, "");
bindtextdomain("progname", LOCALEDIR);
textdomain("progname");
#endif

(* progname *实际上可以自由选择.)

  • 无论在哪里找到可以翻译的邮件,都需要插入对gettext()的调用。例如。:
fprintf(stderr, "panic level %d\n", lvl);

将更改为:

fprintf(stderr, gettext("panic level %d\n"), lvl);

(如果未配置 NLS 支持,则gettext被定义为无操作.)

这往往会增加很多混乱。一种常见的快捷方式是使用:

#define _(x) gettext(x)

如果程序通过一个或几个功能(例如,后端中的ereport())进行大量通信,则另一种解决方案是可行的。然后,在所有 Importing 字符串上内部使此函数调用gettext

  • 在包含程序源的目录中添加文件nls.mk。该文件将作为 makefile 读取。在此需要进行以下变量分配:

  • CATALOG_NAME

    • textdomain()调用中提供的程序名称。
  • AVAIL_LANGUAGES

    • 提供的翻译列表-最初为空。
  • GETTEXT_FILES

    • 包含可翻译字符串(即标有gettext或其他解决方案的字符串)的文件列表。最终,这将包括该程序的几乎所有源文件。如果此列表过长,则可以使第一个“文件”为+,第二个单词为每行包含一个文件名的文件。
  • GETTEXT_TRIGGERS

    • 生成消息目录以供翻译人员使用的工具需要知道哪些函数调用包含可翻译的字符串。默认情况下,只有gettext()个电话是已知的。如果您使用了_或其他标识符,则需要在此处列出。如果可翻译字符串不是第一个参数,则该项目的格式必须为func:2(对于第二个参数)。如果您具有支持复数消息的函数,则该项应看起来像func:1,2(标识单数和复数消息参数)。

构建系统将自动负责构建和安装消息目录。

54 .2.2. 信息撰写准则

这是编写易于翻译的消息的一些准则。

  • 不要在运行时构造句子,例如:
printf("Files were %s.\n", flag ? "copied" : "removed");

句子中的单词 Sequences 在其他语言中可能有所不同。同样,即使您记得在每个片段上调用gettext(),这些片段也可能无法分别翻译。最好复制一些代码,以使每个要翻译的消息都是一个连贯的整体。在运行时,仅数字,文件名和类似的运行时变量应插入到消息文本中。

  • 出于类似的原因,这将不起作用:
printf("copied %d file%s", n, n!=1 ? "s" : "");

因为它假设如何形成复数。如果您认为可以解决此问题,请执行以下操作:

if (n==1)
    printf("copied 1 file");
else
    printf("copied %d files", n):

然后就失望了。有些语言有两种以上的形式,并有一些特殊的规则。通常最好设计一条消息来完全避免出现此问题,例如:

printf("number of copied files: %d", n);

如果您真的想构造一个适当的多元消息,可以对此进行支持,但是这有点尴尬。在ereport()中生成主要或详细错误消息时,您可以编写如下内容:

errmsg_plural("copied %d file",
              "copied %d files",
              n,
              n)

第一个参数是适合英语单数形式的格式字符串,第二个参数是适合英语复数形式的格式字符串,第三个参数是确定使用哪种复数形式的整数控制值。照常按照格式字符串对后续参数进行格式化。 (通常,复数控制值也将是要格式化的值之一,因此必须将其写入两次.)在英语中,* n 是否为 1 或 1 无关紧要,但是在其他语言中,可以有很多不同的复数形式。译者将这两种英语形式视为一个整体,并有机会提供多个替代字符串,并且根据 n *的运行时值来选择适当的替代字符串。

如果您需要将不直接发送到errmsgerrdetail报告的消息复数,则必须使用基础函数ngettext。请参阅 gettext 文档。

  • 如果您想与翻译交流一些信息,例如有关一条消息如何与其他输出对齐的信息,请在出现该字符串之前加上以translator开头的 Comments,例如:
/* translator: This message is not what it seems to be. */

这些 Comments 将复制到消息目录文件中,以便翻译人员可以看到它们。