Как работает 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, glibc2.1)

    В старой, последней 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 (/usr/share/locale/). Для 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

    Теперь вопрос, откуда взять данные файлы ? ;-) См. Русификация RedHat 5.2 или POSIX locale FreeBSD 2.x или Как установить 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"


Last change : 14-03-2000