Книга: Linux программирование в примерах

13.3.4.1. Переносимые программы: "gettext.h"

13.3.4.1. Переносимые программы: "gettext.h"

Здесь мы предполагаем, что вы хотите написать программу, которая может использоваться вместе с библиотекой GNU gettext на любой системе Unix, а не только GNU/Linux. Следующий раздел описывает, что сделать для программ только для GNU/Linux.

Пометка строк включает два шага. Первый заключается в использовании вспомогательного заголовка gettext.h, который поставляется с дистрибутивом GNU gettext. Этот файл обрабатывает несколько проблем переносимости и компиляции, упрощая использование gettext() в ваших собственных программах:

#define ENABLELNLS 1 /* ENABLE_NLS должен быть true, чтобы gettext() работала */
#include "gettext.h" /* Вместо <libintl.h> */

Если макрос ENABLE_NLS не определен[146] или установлен в ноль, gettext.h развертывает вызовы gettext() в первый аргумент. Это делает возможным перенос кода, использующего gettext(), на системы, в которых не установлены ни GNU gettext, ни собственная их версия. Помимо прочего, этот заголовочный файл определяет следующий макрос:

/* Вызов псевдофункции, который служит в качестве маркера для
   автоматического извлечения сообщений, но не осуществляющий вызов
   gettext(). Перевод времени исполнения осуществляется в другом
   месте кода. Аргумент String должен быть символической строкой.
   Сцепленные строки и другие строковые выражения не будут работать.
   Разворачивание макроса не параметризовано, так что он подходит для
   инициализации статических переменных 'char[]' или 'const char[]'. */
#define gettext_noop(String) String

Комментарий самодостаточен. С помощью этого макроса мы можем теперь перейти ко второму шагу. Мы перепишем код следующим образом:

#define ENABLE_NLS 1
#include "gettext.h"
static char copyrights[] =
 gettext_noop("Copyright 2004, Jane Programmern"
 "Permission is granted ...n"
 /* ... Здесь куча легальностей */
 "So there.");
void copyright(void) {
 printf("%sn", gettext(copyrights));
}

Обратите внимание, что мы сделали два изменения. Во-первых, copyrights теперь является одной длинной строкой, созданной с использованием возможности конкатенации строк стандартного C. Эта простая строка затем включена в вызов gettext_noop(). Нам нужна одна строка, чтобы легальности могли быть переведены в виде одного элемента

Второе изменение заключается в непосредственном выводе перевода в виде одной строки в copyright().

К этому времени вы, возможно, думаете: «Вот здорово, набирать каждый раз 'gettext(...)' довольно неприятно». Ну, вы правы. Это не только создает лишнюю работу по набиванию, но также и затрудняет чтение исходного кода. Соответственно, когда вы используете заголовочный файл gettext.h, руководство GNU gettext рекомендует включить два других макроса с именами _() и N_() следующим образом:

#define ENABLE_NLS 1
#include "gettext.h"
#define _(msgid) gettext(msgid)
#define N_(msgid) msgid

Такой подход снижает накладные расходы по использованию gettext() всего лишь тремя дополнительными символами для переводимой строковой константы и всего лишь четырьмя символами для статических строк:

#include <stdio.h>
#define ENABLE_NLS 1
#include "gettext.h"
#define _(msgid) gettext(msgid)
#define N_(msgid) msgid
...
static char copyrights[] =
 N_("Copyright 2004, Jane Programmern"
 "Permission is granted ...n"
 /* ... Здесь куча легальностей */
 "So there.");
void copyright(void) {
 printf("%sn", gettext(copyrights));
}
int main(void) {
 setlocale(LC_ALL, ""); /* gettext.h gets <locale.h> for us too */
 printf("%sn", _("hello, world"));
 copyright();
 exit(0);
}

Эти макросы скромны, и на практике все GNU программы, использующие GNU gettext, следуют этому соглашению. Если вы собираетесь использовать GNU gettext, вам тоже нужно следовать этому соглашению.

Оглавление книги


Генерация: 2.191. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз