Для упрощения перевода сообщений на различные языки и обеспечения доступа к ним программ, зависящих от пользовательской локали, необходимо хранить сообщения отдельно от программы в форме каталогов сообщений, к которым программа может обращаться во время выполнения. Для решения этой задачи служат средства работы с сообщениями.
Исходные файлы сообщений для приложений создаются программистом и преобразуются в каталоги сообщений. Во время работы приложение может обращаться к этим каталогам и показывать необходимые сообщения. Исходные файлы сообщений можно переводить на другие языки и преобразовывать в каталоги сообщений без изменения и повторной компиляции программы.
Описание Средств работы с сообщениями приведено в следующих разделах:
Средства работы с сообщениями включают команды и функции, которые позволяют программе получать из внешних каталогов и выводить локализованные версии сообщений. Программист должен создать исходный файл сообщений и преобразовать его в каталог сообщений с помощью команды gencat.
Для того чтобы создать исходный файл сообщений, откройте файл в любом текстовом редакторе. Введите идентификационный номер или символьный идентификатор сообщения. Затем введите текст сообщения, как показано в следующем примере:
1 message-text $ (этому сообщению присвоен номер) 2 message-text $ (этому сообщению присвоен номер) OUTMSG message-text $ (у этого сообщения есть символьный \ идентификатор OUTMSG) 4 message-text $ (этому сообщению присвоен номер)
При создании исходных файлов сообщений следуйте приведенным ниже правилам:
также присваивает номера символьным идентификаторам, и номер 3 она бы присвоила идентификатору OUTMSG.
Примечание: Символьные идентификаторы поддерживаются только в Средствах работы с сообщениями. Наличие таких идентификаторов может отрицательно повлиять на переносимость исходных файлов сообщений.
В любое место исходного файла сообщений, за исключением текста сообщения, можно добавить комментарий. После знака доллара ($), обозначающего комментарий, должен присутствовать хотя бы один пробел или символ табуляции. Ниже приведен пример комментария:
$ Это комментарий.
При создании каталогов сообщений из исходных файлов комментарии опускаются.
Комментарии могут помочь программистам в работе с сообщениями, переводчикам - в переводе, а создателям сообщений - в редактировании и регистрации сообщений. Комментарии позволяют помещать в исходные файлы описания переменных, таких как %s, %c и %d. Например, вы можете указать, что переменная обозначает имя пользователя, файла, каталога или значение флага. Комментарии также применяются для обозначения устаревших сообщений.
Для удобства работы комментарии рекомендуется располагать непосредственно после сообщений, к которым они относятся, а не в конце каталога сообщений. Комментарии, относящиеся ко всему набору, следует располагать сразу после директивы $set.
В текст сообщения включаются все символы от пробела, стоящего после идентификатора сообщения, до конца строки. Escape-символ \ (обратная косая черта) означает, что текст сообщения продолжается на следующей строке. Обратная косая черта должна быть последним символом в строке, например:
5 Этот текст относится к сообщению \ номер 5.
Эти две строки определяют одно сообщение:
Этот текст относится к сообщению номер 5.
Примечание: Применение нескольких пробелов после номера или идентификатора сообщения поддерживается только в Средствах работы с сообщениями. Наличие нескольких пробелов может отрицательно повлиять на переносимость исходных файлов сообщений.
Символ обратной косой черты (\)
позволяет вставлять в сообщения специальные символы. Можно использовать
следующие символы:
Директива $quote исходного файла сообщений позволяет определить символ, который будет использоваться в качестве ограничителя текста сообщений. Этот символ должен принадлежать набору ASCII. Формат директивы:
$quote [символ] [комментарий]
Определенный таким образом символ указывается до и после текста сообщения. В приведенном ниже примере директива $quote определяет в качестве ограничителя знак подчеркивания (_), а затем отключает его перед последним сообщением:
$quote _ В качестве ограничителя используется знак подчеркивания $set MSFAC Средства работы с сообщениями - символьные идентификаторы SYM_FORM _Символьные идентификаторы могут включать алфавитно-цифровые \ символы и знаки подчеркивания (\_) \n_ SYM_LEN _Длина символьных идентификаторов может составлять\ до 65 символов \n_ 5 _Символьные и числовые идентификаторы могут применяться совместно \n_ $quote MSG_H Не забудьте включить файл _msg_h_ в программу \n
Последняя директива $quote в предыдущем примере отключает действие знака подчеркивания.
В приведенном ниже примере директива $quote определяет в качестве ограничителя двойные кавычки ("). Ограничитель должен быть первым символом после идентификатора сообщения и пробелов. Любой текст после следующего вхождения ограничителя игнорируется.
$quote " В качестве ограничителя используются двойные кавычки $set 10 Средства работы с сообщениями - сообщения о директиве quote 1 "Директива $quote позволяет задать символ, \ \n ограничивающий текст сообщений" 2 "Для того чтобы использовать символ \"quote\" в сообщении, \n \ поставьте перед ним символ \\ " 3 Для того чтобы использовать символ "quote" в сообщении, \n \ можно указать сообщения без применения ограничителя, т.е. введя \ \n другой символ после ИД сообщения и пробелов $quote 4 Для отключения этого механизма необходимо \n \ ввести директиву $quote без \n\ аргументов
В этом примере показано два способа добавления символа-ограничителя в текст сообщения:
Пример также иллюстрирует следующее:
Каждому набору сообщений необходимо присвоить номер или символьный идентификатор. Директива $set позволяет задать идентификатор набора сообщений:
$set n [комментарий ]
Значение n определяет номер набора и может изменяться от 1 до NL_SETMAX. Вместо номера можно указать символьный идентификатор. В набор включаются все сообщения между текущей и следующей директивами $set. По умолчанию номер набора равен 1. Номера наборов должны следовать в возрастающем порядке, но не обязательно подряд. Пропущенным номерам будут соответствовать пустые наборы. Однако большие пропуски в нумерации наборов приводят к снижению эффективности и скорости работы, как и применение нескольких номеров наборов в каталоге сообщений.
В директиве $set можно также указать комментарий:
$set 10 Сообщения об ошибках связи
$set OUTMSGS Сообщения об ошибках вывода
В AIX многие наборы сообщений носят название MS_PROG, где MS обозначает Message Set (набор сообщений), а PROG соответствует имени программы или утилиты. Например:
$set MS_WC Набор сообщений утилиты wc
$set MS_XLC1 Набор сообщений 1 компилятора C для AIX
$set MS_XLC2 Набор сообщений 2 компилятора C для AIX
Директива $delset позволяет удалить из существующего каталога все сообщения, входящие в указанный набор:
$delset n [комментарий ]
Номер набора определяется значением n должна быть размещена в соответствии с порядком наборов, определенных директивами $set в исходном файле. В директиве $delset можно указать комментарий.
Директива $len позволяет задать максимальную длину выводимого на экран текста сообщений:
$len [ n [ комментарий ] ]
Если значение n не указано, или директива $len отсутствует, длина текста сообщений ограничивается значением NL_TEXTMAX . Длина выводимого текста определяет максимально допустимое число байт в сообщении. Последующие директивы $len переопределяют предыдущие установки. Значение n не может быть больше NL_TEXTMAX.
Старайтесь наиболее точно описать причину ошибки и способы ее устранения. Ниже приведен пример того, как можно улучшить текст сообщения, добавив в него информацию о причине ошибки и способах ее исправления:
Исходное сообщение: Недопустимый аргумент.
Исправленное сообщение: Задайте год в диапазоне от 1 до 9999.
Сообщения, аналогичные приведенному выше: Недопустимый аргумент, вряд ли могут помочь пользователю, в то время как сообщение Укажите в командной строке не более 2 файлов говорит пользователю, что именно он должен исправить. Так, сообщение Слишком длинная строка не несет информации о способе исправления. Гораздо лучше сообщение Длина строки не должна превышать 20 символов.
$ Пример исходного файла сообщений. $ Определить символ-ограничитель. $quote " $set 1 Набор сообщений 1. 1 "Отсутствуют права на чтение указанного файла\n" 2 "Файлы %1$s и %2$s совпадают\n" 3 "Здравствуйте!\n" $ Определить символ-ограничитель $quote ' $set 2 Набор сообщений 2. 1 'fieldef: Невозможно открыть %1$s \n' 2 'Здравствуйте!\n'
$ Пример исходного файла сообщений. $ Определить символ-ограничитель. $quote " $set MS_SET1 Набор сообщений 1. MSG_1 "У указанного файла нет прав на чтение\n" MSG_2 "Файлы %1$s и %2$s совпадают\n" MSG_3 "Добрый день\n" $Define the quote character $quote $set 2 Набор сообщений 2. $EMSG_1 'fieldef: Невозможно открыть %1$s\n' $EMSG_2 'Добрый день!\n'
catgets(cd, 1, 1, "сообщение по умолчанию")
catgets(cd, MS_SET1, MSG_1, "сообщение по умолчанию")
Средства работы с сообщениями включают команды и функции, которые позволяют программе получать из внешних каталогов и выводить локализованные версии сообщений. Программист должен создать исходный файл сообщений и преобразовать его в каталог сообщений. Исходные файлы сообщений можно переводить на другие языки и преобразовывать в каталоги сообщений без изменения и повторной компиляции программы.
Для создания каталога сообщений необходимо обработать исходный файл сообщений с помощью утилиты gencat
средств работы с сообщениями. Эта команда может применяться тремя способами:
для обработки исходного файла сообщений, в котором содержатся номера наборов, идентификаторы сообщений и текст сообщений. Если в исходных файлах применяются символьные идентификаторы, то напрямую обрабатывать их командой gencat нельзя. В следующем примере для создания каталога сообщений применяется исходный файл x.msg:
gencat x.cat x.msg
выполните предварительную обработку исходного файла сообщений, содержащего символьные идентификаторы. Затем полученный файл передается по конвейеру команде gencat
средств работы с сообщениями. Команда mkcatdefs создает файл символьное-имя_msg.h, содержащий директивы #define. Эти директивы задают соответствие между символьными идентификаторами, с одной стороны, и номерами наборов и идентификаторами сообщений, присвоенными командой mkcatdefs, - с другой. Файл СимвольноеИмя_msg.h должен быть включен в программы, в которых используются символьные идентификаторы. Команда mkcatdefs существует только в операционной системе AIX. Следующая команда использует исходный файл x.msg для создания файла заголовка x_msg.h:
mkcatdefs x x.msg
для автоматической обработки исходного файла сообщений, содержащего символьные идентификаторы. Команда runcat вызывает команду mkcatdefs
и передает ее вывод команде gencat
средств работы с сообщениями. Команда runcat существует только в операционной системе AIX. В приведенном ниже примере исходный файл сообщения x.msg используется для создания файла заголовка x_msg.h и построения каталога сообщений X.cat:
runcat x x.msg
Предыдущий пример эквивалентен следующим командам:
mkcatdefs x x.msg | gencat x.cat
Если каталог сообщений, указанный в параметре ФайлКаталога существует, то команда gencat
изменит существующий каталог в соответствии с исходным файлом сообщений. Если такой каталог отсутствует, команда gencat создаст файл каталога с именем, указанным в параметре ФайлКаталога.
Вы можете указать произвольное число исходных файлов. Файлы обрабатываются в указанном порядке. Изменения вносятся каждый раз, когда успешно завершается обработка очередного файла. Если имя исходного файла не указано, команда gencat
будет считывать исходные данные из стандартного ввода.
Размер каталога сообщений может
быть произвольным. Максимальное число наборов в каталоге, сообщений в
каталоге и байт в сообщении определяется следующими макроопределениями,
описанными в файле /usr/include/limits.h:
$ file: hello.msg $set 1 prompts 1 Укажите ваше имя. 2 Здравствуйте, %s \n $ Конец файла hello.msg
Для создания каталога сообщений hello.cat на основе файла hello.msg введите:
gencat hello.cat hello.msg
$ file: hello.msg $quote " $set PROMPTS PLEASE "Введите имя." HELLO "Здравствуйте, %s \n" $ end of file: hello.msg
Ниже приведен текст исходного файла msgerrs.msg с сообщениями об ошибках, на которые можно ссылаться по их символьным идентификаторам:
$ file: msgerrs.msg $quote " $set CAT_ERRORS MAXOPEN "Невозможно открыть каталог сообщений %s \n \ Уже открыто максимально допустимое число каталогов " NOT_EX "Файл %s не является исполняемым \n " $set MSG_ERRORS NOT_FOUND "Сообщение %1$d, набор %2$d, не найдено \n " $ Конец файла msgerrs.msg
Для обработки исходных файлов hello.msg и msgerrs введите:
runcat hello hello.msg runcat msgerrs msgerrs.msg /usr/lib/nls/msg/$LANG/msgerrs.cat
Команда runcat
вызывает команды mkcatdefs и gencat. Первый вызов команды runcat считывает исходный файл hello.msg и использует первый параметр, hello, для создания каталога сообщений hello.cat и файла определений hello_msg.h.
Файл hello_msg.h содержит определения символьных имен для каталога сообщений, наборов и идентификаторов сообщений. Символьным именем каталога hello.cat является MF_HELLO. Это имя создается автоматически командой mkcatdefs
считывает исходный файл сообщений msgerrs.msg и использует первый параметр, msgerrs, для создания файла определений msgerrs_msg.h.
Так как в вызове команды присутствует третий параметр, /usr/lib/nls/msg/$LANG/msgerrs.cat, команда runcat
использует его в качестве имени каталога. Этот параметр является полным путем к файлу каталога, с которым должна работать команда runcat. Символьным именем каталога msgerrs.cat является MF_MSGERRS.
Перечисленные ниже команды
позволяют выводить сообщения вне прикладной программы. Эти команды
существуют только в операционной системе AIX.
dspcat | Выводит сообщения, хранящиеся в указанном каталоге сообщений.
Следующая команда выводит сообщения из каталога x.cat:
dspcat x.cat |
dspmsg | Показывает выбранное сообщение из каталога. Следующая команда
выводит сообщение из каталога x.cat, имеющее
идентификационный номер 1 и номер набора 2:
dspmsg x.cat -s 2 1 Команду dspmsg можно использовать в сценариях оболочки для вывода сообщений из каталога. |
Для использования Средств работы с сообщениями в программе должны присутствовать следующие элементы:
в случае, если применяются символьные идентификаторы, или файлы limits.h и nl_types.h, если символьные идентификаторы не используются.
Для вывода сообщений в Средствах
работы с сообщениями предусмотрены следующие функции:
setlocale | Устанавливает локаль. Укажите переменную среды LC_ALL или LC_MESSAGES в вызове функции setlocale для выбора каталога сообщений в соответствии с установленным в системе языком. |
catopen | Открывает заданный каталог сообщений и возвращает дескриптор каталога, который применяется при чтении сообщений из каталога. |
catgets | Считывает сообщение из каталога после успешного вызова функции catopen. |
printf | Преобразует, форматирует и записывает текст сообщения в стандартный поток вывода (stdout). |
catclose | Закрывает заданный каталог сообщений. |
Следующая программа на языке C (hello) открывает каталог hello.cat с помощью функции catopen, считывает из него сообщения с помощью функции catgets, показывает их с помощью функции printf, а затем закрывает каталог с помощью функции catclose.
/* Программа: Привет */ #include <nl_types.h> #include <locale.h> nl_catd catd; main() { /* инициализация локали */ setlocale (LC_ALL, ""); /* открыть каталог */ catd=catopen("hello.cat",NL_CAT_LOCALE); printf(catgets(catd,1,1,"Здравствуйте!")); catclose(catd); /* закрыть каталог */ exit(0); }
В этом примере функция catopen
обращается к каталогу hello.cat по имени файла. В связи с этим необходимо правильно задать значение переменной среды NLSPATH. Если функция catopen успешно открывает каталог, функция catgets
возвращает указатель на заданное сообщение из каталога hello.cat. Если каталог не существует или заданное сообщение отсутствует, то catgets выводит указанный по умолчанию текст Здравствуйте!
Переменная среды NLSPATH определяет список каталогов файловой системы, в которых будет выполняться поиск каталогов сообщений. Функция catopen для открытия каталога сообщений выполняет поиск в этих каталогах в порядке, заданном переменной. Если функции не удается обнаружить заданный каталог сообщений, она возвращает указанное в программе сообщение по умолчанию. В файле /etc/environment определен список каталогов NLSPATH по умолчанию.
Все функции, отвечающие за чтение сообщений, возвращают заданный в программе текст по умолчанию, если сообщение не удается получить по какой-либо причине. Как правило, в качестве сообщений по умолчанию применяются краткие сообщения без номеров. Пользователи, которые предпочитают работать с сообщениями по умолчанию, могут указать в категории LC_MESSAGES локаль C или сбросить переменную среды NLSPATH. Когда не установлена ни одна из переменных LC_ALL,
категория LC_MESSAGES по умолчанию использует локаль C.
Пользователи, работающие с несколькими языками, могут задать приоритет языков для ввода сообщений. Информация о настройке приоритета языков для всей системы и для отдельных пользователей приведена в описании команды chlang и в разделе "Изменение языковой среды" книги Руководство по управлению системой AIX 5L версии 5.1: Операционная система и устройства, а также в справке по программе SMIT. Для того чтобы задать иерархию языков средствами SMIT, введите команду быстрого доступа
smit mlang
Выберите Изменить / Показать иерархию языков
smit
Выберите Управление языковой средой
Выберите Изменить / Показать иерархию языков
Этот пример состоит из трех частей: исходного файла сообщений, команды, применяемой для создания файла каталога сообщений, и программы, которая использует этот каталог.
$quote " $ В любом каталоге сообщений должен быть определен начальный номер набора. $set MS_SET1 MSG1 "Здравствуйте!\n" MSG2 "Доброе утро!\n" ERRMSG1 "Пример: 1000.220 Чтение файла %s запрещено.\n" $set MS_SET2 MSG3 "Как поживаете?\n"
runcat example example.msg
#include <locale.h> #include <nl_types.h> #include "example_msg.h" /* содержит определения для символьных идентификаторов */ main() { nl_catd catd; int error; (void)setlocale(LC_ALL, ""); catd = catopen(MF_EXAMPLE, NL_CAT_LOCALE); /* ** Получить сообщение 1 из первого набора. */ printf( catgets(catd,MS_SET1,MSG1,"Здравствуйте!\n") ); /* ** Получить сообщение 1 из второго набора. */ printf( catgets(catd, MS_SET2, MSG3,"Как вы поживаете?\n") ); /* ** Выдать сообщение об ошибке. */ printf( catgets(catd, MS_SET1, ERRMSG1,"Пример: 100.220 Чтение файла %s запрещено.\n") , filename); catclose(catd); }
Глава 16, Поддержка национальных языков, Средства работы с сообщениями - Информация для программистов, Создание исходного файла сообщений, Создание каталога сообщений, Список функций поддержки национальных языков.
Изменение языковой среды в книге Руководство по управлению системой AIX 5L версии 5.1: Операционная система и устройства.
Команды chlang, dspcat, dspmsg, gencat, lslpp, mkcatdefs, runcat.
Файл environment.
Функция catclose, catgets, catopen, printf.