9.2. 给程序员 #
本节描述如何在属于 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))
如果该程序的大部分通信都是通过一个或少数几个函数完成的,例如后端中的
elog(),另一种可行的解决办法是让这个函数在内部对所有输入值调用gettext。在包含程序源码的目录中添加一个文件
nls.mk。这个文件将作为 makefile 读取。这里需要进行下列变量赋值:- CATALOG_NAME
程序名,如
textdomain()调用中所提供的那样。- AVAIL_LANGUAGES
已有翻译的列表——开始时为空。
- GETTEXT_FILES
包含可翻译字符串的文件的列表,即那些用
gettext或替代方案标记的文件。最终,这将包括该程序几乎所有源文件。如果这个列表太长,可以让第一个“文件”是+,第二个词是一个每行包含一个文件名的文件。- GETTEXT_TRIGGERS
为翻译者生成消息目录的工具需要知道哪些函数调用包含可翻译字符串。默认情况下只有
gettext()调用是已知的。如果你用了_或其他标识符,需要在此列出它们。如果可翻译字符串不是第一个参数,条目的形式应为func:2(表示第二个参数)。
构建系统会自动处理消息目录的构建和安装。
为了便于翻译消息,这里有一些指导原则:
不要因为偷懒而像下面这样在运行时拼接句子:
printf("Files where %s.\n", flag ? "copied" : "removed");句子中的词序在其他语言里可能不同。
出于类似的原因,这样也不行:
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);如果你想向译者传达一些信息,比如消息打算如何与其他输出对齐,可以在字符串出现的位置前面加一条以
translator开头的注释,例如:/* translator: This message is not what it seems to be. */
这些注释会被复制到消息目录文件中,这样翻译者就能看到它们。