| The Russian Electronic Developer Magazine | |
| Русский электронный журнал разработчика | |
Замечание 1. Меня очень сильно удивил тот факт, что никто не кричит на всех углах о русификации IBM AIX, и тем не менее оказалось, что она вполне правильно "говорит" по-русски (впрочем, как на доброй сотне других и всё это в одном дистрибутиве).Оказывается, уже давно существуют стандарты Posix на поддержку языков. OS/2 не исключение, поддержка языков (после некоторого момента :-) является одной из сильных сторон этой ОС. В руководстве пользователя по VisualAge C++ (в моем случае это v3.0) есть целая глава "Making Your Program International" (делайте Ваши программы интернациональными).
Базовым понятием в языковой поддержке является "locale" ("локаль"), которая включает в себя поддержку кодовых страниц и наборов символов; сортировки и сравнения строк, классификации символов (знаки пунктуации, цифры и т.п.); поддержку перевода на нижний/верхний регистр; формат даты и времени; форматы чисел. Соответственно, в своей программе Вы можете использовать как отдельные элементы (например, только форматы представления денег) локализации, так и все вместе. Что самое удобное, так это то, что эта поддержка абсолютно прозрачна и не требует специальной модификации программ. Такие функции, как strcmp, tolower, ispunct при смене языка работают как должно (практически все функции работы со строками и символами правильно обрабатывают русские символы).
Как задать "locale"? Необходимо в начале программы вызвать функцию setlocale (LC_ALL,""); -- такой вызов установит locale в соответствии с установленной в системе (переменная LANG) для всех аспектов языка; setlocale(LC_ALL,"RU_RU"); - такой вызов установит locale - "русский".
Первый параметр задаёт "область действия" locale (например LC_TIME - только для представления времени, LC_COLLATE - только для сравнения строк). Второй параметр - имя "locale" (Вы уже догадались, зачем на загрузочном диске OS/2 находятся каталоги LANGUAGE\LOCALE, IBMI18N\LOCALE). И всё... Согласитесь, что это совсем немного, если теперь в зависимости от установленной "locale" можно воспользоваться данными соответствующими данному языку из русурсов?
Замечание 2. При необходимости достаточно просто можно описать и создать новую "locale", скомпилировать её, положить в один из каталогов, описанных в переменной LOCPATH, и пользоваться.
#includeДанный пример получает значение переменной окружения LANG, если она не задана, то выбирается русская, затем устанавливается "locale" программы, и, последнее, программа получает имя кодовой страницы.#include #include ... char *pclocale; char pcLocale[32]; // get LANG environment variable if ( (pclocale=getenv("LANG")) == NULL ) pclocale = "RU_RU";// Default is Russian ! setlocale ( LC_ALL, pclocale ); strcpy ( pcLocale, nl_langinfo(CODESET) ); // setup PC codepage for ... // name translation
Кроме вышеописанного, данный интерфейс позволяет производить и перекодировку символов из одной кодовой страницы в другую. Это избавляет от необходимости иметь массу файлов с таблицами перекодировки для каждой из программ, нуждающихся в этом. Ниже приведен пример, который производит перекодировку из 866 в 1251 и обратно.
char pcLocale [32] = "IBM-866";
char psionLocale [32] = "IBM-1251";
iconv_t cd_2psion;
iconv_t cd_2pc;
... // initialization, open translation tables
cd_2psion = iconv_open ( psionLocale, pcLocale );
cd_2pc = iconv_open ( pcLocale, psionLocale );
...
char *toPsiName ( char fname[] )
{
unsigned int ilen, olen;
char *ibuf, *obuf;
CHAR buf [_MAX_PS_PATH];
olen = ilen = strlen(fname)+1;
obuf = (char *)&buf;
ibuf = (char *)fname;
strcpy ( buf, fname );
if ( cd_2psion != (iconv_t)(-1) )
iconv ( cd_2psion, &ibuf, &ilen, &obuf, &olen );
strcpy ( fname, buf );
return ( fname );
}
char *toOsName ( char fname[] )
{
unsigned int ilen, olen;
char *ibuf, *obuf;
char buf [_MAX_PS_PATH];
olen = ilen = strlen(fname)+1;
obuf = (char *)&buf;
ibuf = (char *)fname;
strcpy ( buf, fname );
if ( cd_2pc != (iconv_t)(-1) )
iconv ( cd_2pc, &ibuf, &ilen, &obuf, &olen );
strcpy ( fname, buf );
return ( fname );
}
К сожалению, несмотря на декларированную в документации VisualAge
целостность языковой поддержки, не обошлось без ложки дёгтя. Все
необходимые DLL-ли и таблицы перекодировки находятся только в каталогах
\IBMCPP\LOCALE\ICONV и \IBMCPP\LOCALE\UCONVTAB, и, соответственно, не
включены в дистрибутив OS/2. Если нужно, чтобы Ваши программы производили
перекодировку, то необходимо позаботится, чтобы эти каталоги попали в
один из каталогов, указанных в переменной LOCPATH. Причём действительно
необходимым является весь каталог ICONV, а из каталога UCONVTAB Вас будут
интересовать только используемые Вами таблицы перекодировки.
Замечание 3. Пользователи Warp 3, 4 должны еще скопировать подкаталоги RU_RU, EN_US (или другие для нужных языков).
Андрей А. ПородькоP.S. Используя данную технику была создана небольшая программа-перекодировщик для сервисов TCP/IP. Желающие могут взять ее здесь и покопаться.
Интересные ссылки:
Комментариев к странице: 0 | Добавить комментарий
Редактор: Дмитрий Бан
Оформление: Евгений Кулешов