Библиотека сайта rus-linux.net
Как работает locale ? (пример Linux)
/* Несколько устаревшие сведения на 1 Dec1998*/
Для операцонной системы Linux имеют хождение одновременно множество версий Linux libc, с различной степенью поддержки locale. Hиже приведен краткий обзор версий Linux libc.
Исторически, Linux libc ведет свое происхождение от free библиотеки GNU libc (glibc), которая в своей последней стабильной версии ( GNU libc 1.0.9 ) не имела поддержки других locale кроме "C" и соответственно не имела возможности их менять. Эта библиотека дала рождение ветке Linux libc 4.x.x и 5.x.x которая постоянно совершенствовалась, переписывалась и кроме других полезных возможностей постепенно приобрела и средства locale.
... glibc1 libc-4 a.out libc libc-5 original ELF libc libc-6 GNU libc (glibc2)
В старой, последней a.out (не-ELF) библиотеке, Linux libc 4.7.5 была возможность переключаться на другие значения locale, но только на заданные в процессе компиляции библиотеки. Для автоматической генерции *.c файлов с описаниями параметров локализации применялись специальные утилиты (реализация Nikolay Saukh ) /* Сильно похоже на старые SCO UNIX */.
В ELF версии Linux libc 5.0.9 (получившей довольно широкое распространение в дистрибутивах Slackware 2.x, RedHat и Caldera 1.x с ядром Linux 1.2.13-ELF) появилась возможность задавать любые значения локализации.
Hо сначало надо немного обратится к реализации locale в современной библиотеке Linux libc.
Напомним, что интернационализация -- это дизайн (способ проектирования) программного обеспечения, при котором КОД не зависит от национальных особенностей. При таком подходе : локализация -- это процесс изготовления особых "объектов локализации", в которых сосредоточены языково-зависимые данные. Эти данные разбиты на функциональные группы : категории локализации.
Как мы выяснили ранее, различным категориям локализации могут быть присвоены различные значения и причем в разное время - разные. Естественно предположить, что они как-то куда-то динамически загружаются. И действительно, вызов setlocale(LC_XXXXX,"ru_SU.KOI8-R") будет пытаться открыть файл "/usr/share/locale/ru_SU.KOI8-R/LC_XXXXX" и считать его внутрь структуры в run-time части libc. Это все происходит совершенно прозрачно для пользователя.
Имя файла для считывания конструируется динамически :
/usr/share/locale/ru_RU.KOI8-R/LC_XXXXX
/usr/share/locale/ | это константа, определяющая каталог в котором хранится база локализации. Различно для различных операционных систем. Для Linux смотри LFSSND. Для Intractive UNIX: /lib/locale. Вообще-то IMHO должно использоваться _PATH_LOCALE из <paths.h> |
ru_RU.KOI8-R/ | подкаталог в базе докализации, где "ru_RU.KOI8-R" - значение локализации. |
LC_XXXXX | файл данных для загрузки в run-time libc для категории локализации LC_XXXXX. Этот файл называется "объект локализации". |
Если задана категория локализации LC_ALL, считываются все файлы из /usr/share/locale/ru_RU.KOI8-R/* и если там найдутся файлы, имена которых совпадают с именами (LC_ - locale categories) категорий локализации (LC_CTYPE, LC_COLLATE, e.t.c.) -- то они загружаются. Для остальных категорий остается значение по умолчанию : "C".
Таким образом, при правильной
установке локализации, должны существовать
следующие каталоги: (пример)
$ ls /usr/share/locale/*
C
POSIX
ru_RU.KOI8-R
en_DK.ISO-8859-1
...
* ПРИМЕЧАHИЕ: В полном POSIX.2 точно тот же
результат даст утилита locale:
$ locale -a
C
POSIX
ru_RU.KOI8-R
en_DK.ISO-8859-1
...
Также должны существовать файлы
("объекты локализации") : (пример)
$ ls /usr/share/locale/ru_RU.KOI8-R/*
LC_CTYPE
LC_COLLATE
LC_MONETARY
LC_NUMERIC
LC_TIME
Теперь вопрос, откуда вять данные файлы ? ;-) См. Как установить locale .
В упомянутой выше версии Linux libc 5.0.9 подсистема locale работала именно так, однако не было утилит для создания загружаемых "объектов локализации". Те утилиты, которые входили в ее состав, генерировали объекты только для 4.4 BSD lite libc (почему ?).
Рабочие утилиты localedef и locale, появились начиная с версии Linux libc 5.1.X. А начиная с 5.2.1X - в Linux libc уже есть все необходимое для работы с locale в соответствии с POSIX.2 . См. здесь.
В широко распространенных дистрибутивах RedHat Linux 4.1 и 4.2 применяется библиотека Linux libc 5.3.12 (ELF) содержащая вполне работоспособную систему locale. Однако, к сожалению, в дистрибутив RedHat не входили файлы "объекты локализации" для русского языка ru_RU.KOI8-R.
Однако GNU libc также развивалась и появилась версия GNU libc 2.0 поддерживающая locale по стандарту POSIX 1996. Она была портирована для Linux и вскоре появились дистрибутивы, использующие GNU libc 2.0.x вместо Linux libc. Например, в состав дистрибутива RedHat Linux 5.2 (Apollo) (на glibc 2.0.7) входят все необходимые утилиты и "объекты локализации" - ru_RU (в ISO8859-5) и ru_SU (KOI8-R). Хотя, без проблем там не обошлось.
В библиотеке Linux libc 5.4.x, многое взявшей от GNU libc 2.0.x реализована следующая версия кода, locale 2, и объекты локализации (файлы) от версий Linux libc 5.0.x - 5.3.Х уже не годятся. Однако, благодаря унификации POSIX 1996, эти файлы можно легко получить из текстового описания локализации и файла описания набора символов (Character Set Definition File).
В настоящее время развитие библиотеки Linux libc остановлено (на версии ~5.4.38), и общее направление развития --> слияние и переход на библиотеку glibc2. Но из за того, что существут огромное количество приложений, работающих с Linux libc, приходится иметь в системе две версии библиотеки : Linux libc, называемую libc5 (например, версии 5.3.12) и GNU libc (например, glibc версии 2.1), называемую libc6.
Содержание "Locale AS IT IS"