"Русификация" REXX
Автор: Тимур Козимиров
Источник: RDM/2
Дата: 25.02.1999
При работе с REXX в OS/2 я постоянно сталкиваюсь с двумя проблемами. Часто надо преобразовать какой-либо текст из 866 кодовой страницы в KOI8 и наоборот. Средствами REXX такое можно сделать, но приходится городить примерно подобные конструкции:
Table866 = 'стучу все буковки из таблицы 866'
Table878 = 'аналогично, но для KOI8-R'
trn_str = TRANSLATE(source_str, Table878, Table866)
Кроме того, очень часто надо преобразовать строку в верхний регистр. Функция UPPER здесь не помощница - там только первая половина таблицы переводится (равно как и в любом другом языке или системе программирования). Опять приходится прибегать к набору таблиц перевода и функции TRANSLATE. Неудобно...
Вот я и решил создать две функции, использующие вызовы OS/2 API WinCpTranslateString и WinUpper соответственно для этих задач. В поставке Virtual Pascal 1.1 for OS/2 есть пример написания собственных DLL-ей для использования в REXX. Часовой эксперимент увенчался успехом и я могу теперь предложить вам этот набор - rxcpage.zip. Распакуйте его, там три файла - исходник библиотеки на Паскале, сама DLL и пример программы на REXX, использующей мои функции.
Внутри DLL содержатся описания трех функций:
- RxCpLoadFuncs - для загрузки функций в память
- RxCpTranslate - для перевода строки из одной кодировки в другую (можно использовать любую кодировку, которая упоминается в каталоге \LANGUAGE\CODEPAGE - там их около сотни).
- RxUpCase - для перевода строки в верхний регистр в соответствии с текущей кодировкой
Ну вот, собственно говоря, и все... Ах да! Чуть не забыл... Если вы хотите использовать эти функции в разных программах, то просто киньте RXCPAGE.DLL в какой-нибудь из каталогов, перечисленных в LIBPATH (гуру - простите, но может кто-то этого не знает). Пишите мне, если есть какие-либо вопросы.
Теперь о том как это все делалось... В каталоге \VP10\EXAMPLES\REXX есть пример REXXEXT.PAS. В принципе, там все понятно и без подробных объяснений, для меня, правда, остался невыясненным вопрос как поступать с пропущенными параметрами в середине вызова - может кто и подскажет попозже. В общем так... Для создания библиотеки необходимо подключить модуль Os2Rexx - там содержатся описания структур передачи данных и функция регистрации экспортируемых функций. Не забудьте указать директиву $CDecl+
- чтобы все функции имели формат вызова C-style
. Заголовок всех экспортируемых функций должен быть одинаковым (за исключением названия, конечно). Все что та или иная функция будет возвращать сохраняется в структуре типа RxString
- не забудьте указывать длину возвращаемого значения в этой же структуре.
По сути дела, при написании своей DLL-ки, я просто скопировал этот файл в другой и кое-что там переименовал. Ключевым моментом является собственно использование API'шных функций WinCpTranslateString и WinUpper (импортируемых в модуле Os2PmApi). У меня они используются без всяких дополнительных проверок, но есть и кое-какие грабли. Так например, функция WinCpTranslateString присваивает символам получаемой строки, которых нет в кодировке, в которую надо перевести, код 255 - это может привести к возможным осложнениям (так, например в 1251 буква "я" имеет тоже этот код - благодарите создателя за это).
Вот как теперь выглядит перекодировка на REXX:
/* Small REXX using the REXX functions defined in the RXCPAGE.DLL */
call RxFuncAdd 'RxCpLoadFuncs', 'RXCPAGE', 'RxCpLoadFuncs'
call RxCpLoadFuncs
/* RxCpTranslate(source, cpage_source, cpage_dest)
returns "source" string converted from one codepage (cpage_source) to another (cpage_dest)
You can use codepages from C:\LANGUAGE\CODEPAGE directory */
say RxCpTranslate('This is a test... Это тест...', "866", "1251")
say RxCpTranslate('This is a test... Это тест...', 866, 878)
/* RxUpCase(source) returns "source" string in upper case using current codepage - replacement for UPPER function */
say RxUpCase('Hello! Привет!')
Exit
В заключение хочу сказать, что создание модулей расширения REXX является относительно несложным делом и доступно, в принципе, даже неквалифицированным программистам (себя я отношу именно к ним).