Next: , Previous: System Functions, Up: Writing C


5.8 Internationalization

GNU has a library called GNU gettext that makes it easy to translate the messages in a program into various languages. You should use this library in every program. Use English for the messages as they appear in the program, and let gettext provide the way to translate them into other languages.

Using GNU gettext involves putting a call to the gettext macro around each string that might need translation—like this:

     printf (gettext ("Processing file `%s'..."));

This permits GNU gettext to replace the string "Processing file `%s'..." with a translated version.

Once a program uses gettext, please make a point of writing calls to gettext when you add new strings that call for translation.

Using GNU gettext in a package involves specifying a text domain name for the package. The text domain name is used to separate the translations for this package from the translations for other packages. Normally, the text domain name should be the same as the name of the package—for example, ‘fileutils’ for the GNU file utilities.

To enable gettext to work well, avoid writing code that makes assumptions about the structure of words or sentences. When you want the precise text of a sentence to vary depending on the data, use two or more alternative string constants each containing a complete sentences, rather than inserting conditionalized words or phrases into a single sentence framework.

Here is an example of what not to do:

     printf ("%d file%s processed", nfiles,
             nfiles != 1 ? "s" : "");

The problem with that example is that it assumes that plurals are made by adding `s'. If you apply gettext to the format string, like this,

     printf (gettext ("%d file%s processed"), nfiles,
             nfiles != 1 ? "s" : "");

the message can use different words, but it will still be forced to use `s' for the plural. Here is a better way:

     printf ((nfiles != 1 ? "%d files processed"
              : "%d file processed"),
             nfiles);

This way, you can apply gettext to each of the two strings independently:

     printf ((nfiles != 1 ? gettext ("%d files processed")
              : gettext ("%d file processed")),
             nfiles);

This can be any method of forming the plural of the word for “file”, and also handles languages that require agreement in the word for “processed”.

A similar problem appears at the level of sentence structure with this code:

     printf ("#  Implicit rule search has%s been done.\n",
             f->tried_implicit ? "" : " not");

Adding gettext calls to this code cannot give correct results for all languages, because negation in some languages requires adding words at more than one place in the sentence. By contrast, adding gettext calls does the job straightfowardly if the code starts out like this:

     printf (f->tried_implicit
             ? "#  Implicit rule search has been done.\n",
             : "#  Implicit rule search has not been done.\n");