Литмир - Электронная Библиотека
A
A

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 (/* <i>возникла ошибка</i> */) { /* ВЕРНО */

 /* Использовать несколько строк для упрощения перевода. */

 if (input_type == INPUT_FILE)

  fprintf(stderr, _(&quot;%s: cannot read file: %s\n&quot;),

   argv[0], strerror(errno));

 else

  fprintf(stderr, _(&quot;%s: cannot read pipe: %s\n&quot;),

   argv[0], strerror(errno));

Это лучше, чем

if (/* <i>возникла ошибка</i> */) { /* НЕВЕРНО */

 fprintf(stderr, _(&quot;%s: cannot read %s: %s\n&quot;), argv[0],

 input_type == INPUT_FILE ? _(&quot;file&quot;) : _(&quot;pipe&quot;),

 strerror(errno));

}

Как только что показано, хорошей мыслью является включение комментария, сообщающего о намеренном использовании нескольких строк, чтобы упростить перевод сообщений.

13.3.8. Создание переводов

После интернационализации программы необходимо подготовить переводы. Это осуществляется с помощью нескольких инструментов уровня оболочки. Мы начнем с интернационализированной версии

ch06-echodate.c
из раздела 6.1.4 «Преобразование разложенного времени в
time_t
»:

/* ch13-echodate.c --- демонстрация переводов */

#include &lt;stdio.h&gt;

#include &lt;time.h&gt;

#include &lt;locale.h&gt;

#define ENABLE_NLS 1

#include &quot;gettext.h&quot;

#define _(msgid) gettext(msgid)

#define N_(msgid) msgid

int main (void) {

 struct tm tm;

 time_t then;

 setlocale(LC_ALL, &quot;&quot;);

 bindtextdomain(&quot;echodate&quot;, &quot;.&quot;);

 textdomain(&quot;echodate&quot;);

 printf(&quot;%s&quot;, _(&quot;Enter a Date/time as YYYY/MM/DD HH:MM:SS : &quot;));

 scanf(&quot;%d/%d/%d %d:%d:%d&quot;,

  &amp;tm.tm_year, &amp;tm.tm_mon, &amp;tm.tm_mday,

  &amp;tm.tm_hour, &amp;tm.tm_min, &amp;tm.tm_sec);

 /* Проверка ошибок для краткости опущена. */

 tm.tm_year -= 1900;

 tm.tm_mon -= 1;

 tm.tm_isdst = -1; /* О летнем времени ничего не известно */

 then = mktime(&amp;tm);

 printf(_(&quot;Got: %s&quot;), ctime(&amp;then));

 exit(0);

}

Мы намеренно использовали

&quot;gettext.h&quot;
, а не
&lt;gettext.h&gt;
. Если наше приложение поставляется с отдельной копией библиотеки
gettext
, тогда
&quot;gettext.h&quot;
найдет ее, избежав использования системной копии. С другой стороны, если имеется лишь системная копия, она будет найдена, если локальной копии нет. Общеизвестно, что ситуация усложнена фактом наличия на системах Solaris библиотеки
gettext
, которая не имеет всех возможностей версии GNU.

201
{"b":"576259","o":1}