"Le %2$s %1$s te regarde d'un aire interrogateur.\n"
(Даже этот перевод не совершенен: артикль «Le» имеет род. Подготовка программы к переводу трудная задача!)
13.3.6. Тестирование переводов в персональном каталоге
Коллекция сообщений в программе называется списком сообщений (message catalog). Этот термин применяется также к каждому из переводов сообщений на другой язык. Когда программа установлена, каждый перевод также устанавливается в стандартное место, где
gettext
может во время исполнения найти нужный перевод.
Может оказаться полезным разместить переводы не в стандартном, а в другом каталоге, особенно для тестирования программы. Особенно на больших системах, у обычного пользователя может не быть необходимых разрешений для установки файлов в системные каталоги. Функция
bindtextdomain
дает
gettext
альтернативное место для поиска переводов:
#include <libintl.h> /* GLIBC */
char *bindtextdomain(const char *domainname,
const char *dirname);
Полезные каталоги включают '
.
' для текущего каталога и
/tmp
. Может оказаться удобным также получить каталог из переменной окружения, подобно этому:
char *td_dir;
setlocale(LC_ALL, "");
textdomain("killerapp");
if ((td_dir = getenv("KILLERAPP_TD_DIR")) != NULL)
bindtextdomain("killerapp", td_dir);
bindtextdomain
должна быть вызвана до вызовов любой из функций из семейства
gettext
. Мы увидим пример ее использования в разделе 13.3.8 «Создание переводов»
13.3.7. Подготовка интернационализированных программ
К настоящему моменту мы рассмотрели все компоненты, из которых состоит интернационализированная программа. Данный раздел подводит итоги.
1. Включите в свое приложение заголовочный файл
gettext.h
, добавьте определения для макросов
_
и
N_
в заголовочный файл, который включается во все ваши исходные файлы на С. Не забудьте определить именованную константу
ENABLE_NLS
.
2. Вызовите соответствующим образом
setlocale
. Проще всего вызвать '
setlocale(LC_ALL, "")
', но иногда приложению может потребоваться быть более разборчивым в отношении используемых категорий локали.
3. Выберите для приложения текстовый домен и установите его с помощью
textdomain
.
4. При тестировании свяжите текстовый домен с определенным каталогом при помощи
bindtextdomain
.
5. Используйте соответствующим образом
strfmon
,
strftime
и флаг
'
. Если нужна другая информация о локали, используйте
nl_langinfo
, особенно в сочетании с
strftime
.
6. Пометьте все строки, которые должны быть переведены, соответствующими
вызовами
_
или
N_
.
Хотя некоторые не следует так помечать. Например, если вы используете
getopt_long
(см. раздел 2.1.2 «Длинные опции GNU»), вы, вероятно, не захотите, чтобы имена длинных опций были помечены для перевода. Не требуют перевода и простые форматирующие строки наподобие "
%d %d\n
", также как отладочные сообщения.
7. В нужных местах используйте
ngettext
(или ее варианты) для значений, которые могут быть 1 или больше 1.
8. Упростите жизнь для своих переводчиков, используя строки с полными предложениями вместо замены слов с помощью
%s
и
?:
. Например:
if (/* возникла ошибка */) { /* ВЕРНО */
/* Использовать несколько строк для упрощения перевода. */
Как только что показано, хорошей мыслью является включение комментария, сообщающего о намеренном использовании нескольких строк, чтобы упростить перевод сообщений.
13.3.8. Создание переводов
После интернационализации программы необходимо подготовить переводы. Это осуществляется с помощью нескольких инструментов уровня оболочки. Мы начнем с интернационализированной версии
ch06-echodate.c
из раздела 6.1.4 «Преобразование разложенного времени в