Projects/Localization
Contents
Overview
The purpose of this project is to add infrastructure for localization of user interface messages in the krb5 tree, using gettext.
Design
Basic infrastructure
Configuration logic will be added to build with localization support if <libintl.h> is available on the system. The system library -lintl will be used if libc does not define dgettext().
Macros will be added to k5-platform.h to define _() and N_(), and to null out calls to bindtextdomain(), setlocale(), and dgettext() when krb5 is built without localization support.
Strings in the tree which should be translated will be marked up with _(), which will be defined to dgettext("mit-krb5", string) when built with localization support. Strings which will be translated later will be marked up with N_().
krb5int_lib_init() will be extended to call bindtextdomain() for the mit-krb5 textdomain.
Build infrastructure will be added to run xgettext to extract marked strings from C source files into a pot file, and to convert po files into mo files and install them. A placeholder en_US.po file with no translations will be used to make the build infrastructure work until there are actual translations to ship.
Programs in the tree such as kinit will call setlocale(LC_MESSAGES, "") at startup. For now we will not use LC_ALL to avoid possible unwanted impacts on the processing of protocol data using ctype.h macros or similar functions.
The test framework will be modified to set the locale to C to ensure that it sees the expected (untranslated) output.
com_err library
There are several versions of the com_err library. MIT krb5 is typically built either with its own internal version of com_err, or with the system com_err which typically comes from e2fsprogs. The following changes will be made to the internal krb5 com_err and have also been submitted to the e2fsprogs maintainer for its version of com_err:
- compile_et defines N_() to a no-op and marks up error message strings with it.
- If compile_et is passed the --textdomain option, it stores the text domain as a string at the end of the error table, before the null terminator.
- If compile_et is also passed the --localedir option, it stores it in the error table after the text domain.
- If an error table has a text domain, error_message() will call dgettext on the text domain and error string.
- If an error table also has a locale directory, add_error_table() will call bindtextdomain on the text domain and locale direcetory.
We will use the --textdomain option, but not the --localedir option. If we build against a system com_err with no support for compile_et --textdomain, we will translate com_err results in krb5int_get_error(), which should reach most uses.
Markup
A pass will be made over the source tree looking for strings, each of which is analyzed to determine if it is a string presented to the user on stdout or stderr or a log file. If so, it will be marked for translating. Messages sent over a network protocol will not be marked for translation, as we generally do not know the locale of the client (nor does gettext provide easy way to localize messages for different clients in different locales). A few messages will be skipped for now because they are part of tables, and translating them would disturb table alignment.
Relevant Mailing List Threads
http://mailman.mit.edu/pipermail/krbdev/2011-May/010011.html