For the Programmer

PostgreSQL 7.3.4 Documentation
Prev | Chapter 10. Native Language Support | Next

# 10.2. For the Programmer

This section describes how to support native language support in a program or library that is part of the PostgreSQL distribution. Currently, it only applies to C programs.

Adding NLS support to a program

1. Insert this code into the start-up sequence of the program:

       #ifdef ENABLE_NLS
       #include <locale.h>
       #endif

       ...

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

   (The progname can actually be chosen freely.)

2. Wherever a message that is a candidate for translation is found, a call to `gettext()` needs to be inserted. E.g.,

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

   would be changed to

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

   (`gettext` is defined as a no-op if no NLS is configured.)

   This may tend to add a lot of clutter. One common shortcut is to

       #define _(x) gettext((x))

   Another solution is feasible if the program does much of its communication through one or a few functions, such as `elog()` in the backend. Then you make this function call `gettext` internally on all input values.

3. Add a file `nls.mk` in the directory with the program sources. This file will be read as a makefile. The following variable assignments need to be made here:

   CATALOG_NAME

     The program name, as provided in the `textdomain()` call.

   AVAIL_LANGUAGES

     List of provided translations -- empty in the beginning.

   GETTEXT_FILES

     List of files that contain translatable strings, i.e., those marked with `gettext` or an alternative solution. Eventually, this will include nearly all source files of the program. If this list gets too long you can make the first "file" be a + and the second word be a file that contains one file name per line.

   GETTEXT_TRIGGERS

     The tools that generate message catalogs for the translators to work on need to know what function calls contain translatable strings. By default, only `gettext()` calls are known. If you used `_` or other identifiers you need to list them here. If the translatable string is not the first argument, the item needs to be of the form func:2 (for the second argument).

The build system will automatically take care of building and installing the message catalogs.

To ease the translation of messages, here are some guidelines:

- Do not construct sentences at run-time out of laziness, like

      printf("Files where %s.\n", flag ? "copied" : "removed");

  The word order within the sentence may be different in other languages.

- For similar reasons, this won't work:

      printf("copied %d file%s", n, n!=1 ? "s" : "");

  because it assumes how the plural is formed. If you figured you could solve it like this

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

  then be disappointed. Some languages have more than two forms, with some peculiar rules. We may have a solution for this in the future, but for now this is best avoided altogether. You could write:

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

- If you want to communicate something to the translator, such as about how a message is intended to line up with other output, precede the occurrence of the string with a comment that starts with translator, e.g.,

      /* translator: This message is not what it seems to be. */

  These comments are copied to the message catalog files so that the translators can see them.

Prev | Home | Next
Native Language Support | Up | The CVS Repository