Emacs для начинающих

       

Локализация и POSIX.


    Если мы говорим о файле, то в идеологии POSIX, - это просто плоская последовательность байтов. Внутреннее содержимое не стандартизовано никак. Поэтому невозможно определить, какую информацию содержит файл, а если он содержит текстовую информацию -- в какой она кодировке. То же самое можно сказать о потоках : stdin/stdout

-- это потоки байтов (кодов). Кодировка (т.е. соответствие символ-код (CES)) полностью потеряна и нигде не указывается. И POSIX

вовсе не гарантирует, что CES (кодировка) stdin

будет совпадать с текущей локализацией, заданной через LANG=.

    Точно тактая же ситуация с терминальным : кодировка терминала совершенно неизвестна приложению.

   К сожалению, в стандарте POSIX

поддержка Charset не имеет полностью идеологически стройной и ясной концепции. Понятие Charset существует только для locale API и тех функций, которые зависят от locale.

    Более того, в "чистом" POSIX

вообще невозможно

узнать (получить) имя Charset после вызова . Единственный способ, узнать Charset текущей locale

- это воспользоваться не-POSIX функцией XPG

(но определенной в Single UNIXSVID

и Unix98) : (определена в файле ). Тогда текущий Сharset можно получить так :



#include <locale.h> #include <langinfo.h>

... setlocale(LC_ALL,""); printf ("Current charset = %s\n",nl_langinfo(CODESET));

     Надо ли говорить, что некоторые UNIX

(например ) не имеют этих XPG-extensions и не имеют функции как таковой вообще. (Что очень странно, поскольку в том же POSIX определена утилита c keyword-ом codeset которая "как-то" это имя определяет...) Например, популярная система до сих пор не имеет функции (как впрочем не имеет и утилиты , увы !).

    Еще один способ определения текущего Charset-а - это разбор

переменной окружения . По стандарту POSIX переменная LANG=

задается в форме LANG=language_TERRITORY.Codeset. Например, переменная


(управляющая поведением подсистемы )может иметь "подстановки" :

%L

The value of the LC_MESSAGES category.

%l

The language element from the LC_MESSAGES category.

%t

The territory element from the LC_MESSAGES category.

%c

The codeset element from the LC_MESSAGES category.

    Таким образом, если задать LANG="ru_RU.KOI8-R", то мы получим :

%L

= "ru_RU.KOI8-R"

%l

= "ru"

%t

= "RU"

%c

= "KOI8-R"

    Исходные тексты этих функций открыты и широко доступны.

    Таким образом, установив LANG=ru_RU.KOI8-R

мы получим сообщения на русском языке в кодировке KOI8-R, а установив LANG=ru_RU.ISO_8859-5

- в кодировке ISO. На некоторых системах точно так же работает переменная MANPATH=.

    К сожалению, поле Charset - опционально и по стандарту можно использовать сокращенную форму : LANG=ru_RU или даже LANG=ru. (См. ключ -f ). Поэтому, если ваша система это поддерживает, задавайте максимально длинное имя для LANG=

, указывая Charset. (получить список можно по ). К сожалению, само тоже может различаться.

    Довольно значительное число ошибок происходит из за того, что в языке С

определен тип переменных char (хотя точнее было бы назвать его : byte). Это во-первых, жестко привязывает нас к 8-ми битным кодировкам. А во-вторых, кодировка не определена. Поэтому, если мы задаем строку (массив char), в которой употребляются символы не ASCII (с кодами >128) : char string[]="Проверка"; -- результат совершенно непредсказуем и непереносим. Еще больше проблем вызывает идея .

    Также вызывает удивление существование (и синтаксическая корректность) типов signed / unsigned char (что такое "отрицательный" символ? Вот unsigned short int

-- понятно)... Если вы планируете работу вашей программы в многоязычном окружении, неплохо бы предусмотреть атрибут Сharset у любой строки символов char *. Или полностью переходить на UNICODE (wchar_t) в качестве внутренней кодировки.

Содержание ""

Last change : 02-11-1999



Содержание раздела