Определение языково-культурной среды
Определение языково-культурной среды помещается в файлы, к описанию формата которых мы и приступаем. Можно считать, что в подобных файлах, называемых далее файлами определения среды, содержится «исходный текст» определения, поскольку, чтобы возыметь действие, они должны быть обработаны утилитой localedef или эквивалентным средством.
Файл определения среды должен содержать определение одной или нескольких категорий, которое может сводиться к директиве copy (см. далее).
Определение категории состоит из заголовка, тела и хвостовика. Заголовок именует категорию; он должен начинаться с символов LC_. Хвостовик строится из слова END и имени, употребленного в качестве заголовка.
Первому заголовку могут предшествовать строки, переопределяющие символ комментария (по умолчанию – #) и управляющий символ (\).
Тело категории состоит из одной или нескольких строк, содержащих идентификатор и, возможно, следующие за ним операнды. В качестве идентификатора может выступать как ключевое слово, именующее отдельный элемент языково-культурной среды, так и элемент алфавитного сравнения символов. Ключевые слова должны быть уникальными в пределах среды и не начинаться с префикса LC_.
Операндами могут быть символы, элементы сравнения и цепочки символов. Цепочки символов заключаются в двойные кавычки, операнды разделяются точками с запятой и, возможно, пробелами.
Символы и элементы сравнения представляются определенными ниже именами. Кроме того, символы могут обозначаться естественным образом или кодами; правда, при этом определение языково-культурной среды теряет в мобильности.
Имена символов заключаются в угловые скобки (например, <A>, <z> и т.п.). Такая конструкция должна в точности совпадать с именем, определенным в файле отображения символов, который специфицирует опция -f утилиты localedef.
Реализация должна поддерживать по крайней мере один набор символов и соответствующий файл отображения. Любой набор должен включать в себя все элементы из так называемого мобильного набора символов, определяемого стандартом POSIX-2001 (их имена перечислены в пример 13.2).
Файл отображения символов имеет довольно простую структуру. Если отвлечься от несущественных деталей, он должен состоять из директив вида
< имя_символа> <код> <комментарий>
Эти директивы заключаются между строками
Эти директивы заключаются между строками
и
END CHARMAP
Перед строкой CHARMAP может располагаться определение имени набора символов, которое задается директивой
< code_set_name> имя
Фрагмент возможного описания набора символов KOI8-R показан в пример 13.1.
Пример 13.1. Фрагмент файла отображения символов для кодировки KOI8-R. (html, txt)
Опишем теперь формат определения категорий языково-культурной среды.
Категория LC_CTYPE определяет классификацию символов, преобразование регистра и другие атрибуты. К ней относятся следующие ключевые слова: upper (прописные буквы; для POSIX-среды – 26 латинских букв верхнего регистра), lower (строчные буквы), alpha (буквы), digit (цифры), alnum (буквы и цифры), space (пробельные символы; для POSIX-среды в их число, помимо пробела, входят перевод строки, т абуляция и т.п.), cntrl (управляющие символы), punct (знаки пунктуации), graph (печатные символы за исключением пробела), print (печатные символы), xdigit (шестнадцатеричные цифры), blank (для POSIX-среды – пробел и табуляция).
С ключевым словом copy задается имя существующей среды, у которой наследуется определение категории. При наличии данной директивы другие ключевые слова недопустимы.
Ключевое слово charclass позволяет задать имена специфичных для определяемой среды классов символов. Каждый такой класс далее должен быть описан в определении категории LC_CTYPE по образу и подобию перечисленных выше стандартных классов.
Ключевое слово toupper открывает определение отображения малых букв в большие. Операнд этого слова представляет собой пару символов, заключенных в скобки и разделенных запятой. Аналогичным образом устроен элемент tolower.
В пример 13.2 показано определение категории LC_CTYPE для POSIX-среды.
Пример 13.2. Определение категории LC_CTYPE для POSIX-среды. (html, txt)
С ключевым словом copy задается имя существующей среды, у которой наследуется определение категории. При наличии данной директивы другие ключевые слова недопустимы.
Ключевое слово charclass позволяет задать имена специфичных для определяемой среды классов символов. Каждый такой класс далее должен быть описан в определении категории LC_CTYPE по образу и подобию перечисленных выше стандартных классов.
Ключевое слово toupper открывает определение отображения малых букв в большие. Операнд этого слова представляет собой пару символов, заключенных в скобки и разделенных запятой. Аналогичным образом устроен элемент tolower.
В пример 13.2 показано определение категории LC_CTYPE для POSIX-среды.
LC_CTYPE # POSIX-среда, категория LC_CTYPE # "alpha" по определению есть объединение элементов "upper" и "lower" # "alnum" по определению есть объединение элементов "alpha" и "digit" # "print" по определению есть объединение элементов "alnum", "punct" и <space> # "graph" по определению есть объединение элементов "alnum" и "punct" # upper <A>;<B>;<C>;<D>;<E>;<F>;<G>;<H>;<I>;<J>;<K>;\ <L>;<M>;<N>;<O>;<P>;<Q>;<R>;<S>;<T>;<U>;<V>;<W>;\ <X>;<Y>;<Z> # lower <a>;<b>;<c>;<d>;<e>;<f>;<g>;<h>;<i>;<j>;<k>;\ <l>;<m>;<n>;<o>;<p>;<q>;<r>;<s>;<t>;<u>;<v>;<w>;\ <x>;<y>;<z> # digit <zero>;<one>;<two>;<three>;<four>;<five>;\ <six>;<seven>;<eight>;<nine> # space <tab>;<newline>;<vertical-tab>;<form-feed>;\ <carriage-return>;<space> # cntrl <alert>;<backspace>;<tab>;<newline>;\ <vertical-tab>;<form-feed>;<carriage-return>;\ <NUL>;<SOH>;<STX>;<ETX>;<EOT>;<ENQ>;<ACK>;<SO>;\ <SI>;<DLE>;<DC1>;<DC2>;<DC3>;<DC4>;<NAK>;<SYN>;\ <ETB>;<CAN>;<EM>;<SUB>;<ESC>;<IS4>;<IS3>;<IS2>;\ <IS1>;<DEL> # punct <exclamation-mark>;<quotation-mark>;\ <number-sign>;<dollar-sign>;<percent-sign>;\ <ampersand>;<apostrophe>;<left-parenthesis>;\ <right-parenthesis>;<asterisk>;<plus-sign>;\ <comma>;<hyphen>;<period>;<slash>;<colon>;\ <semicolon>;<less-than-sign>;<equals-sign>;\ <greater-than-sign>;<question-mark>;\ <commercial-at>;<left-square-bracket>;\ <backslash>;<right-square-bracket>;\ <circumflex>;<underscore>;<grave-accent>;\ <left-curly-bracket>;<vertical-line>;\ <right-curly-bracket>;<tilde> # xdigit <zero>;<one>;<two>;<three>;<four>;<five>;\ <six>;<seven>;<eight>;<nine>;<A>;<B>;<C>;<D>;\ <E>;<F>;<a>;<b>;<c>;<d>;<e>;<f> # blank <space>;<tab> # toupper (<a>,<A>);(<b>,<B>);(<c>,<C>);(<d>,<D>);\ (<e>,<E>);(<f>,<F>);(<g>,<G>);(<h>,<H>);\ (<i>,<I>);(<j>,<J>);(<k>,<K>);(<l>,<L>);(<m>,<M>);\ (<n>,<N>);(<o>,<O>);(<p>,<P>);(<q>,<Q>);(<r>,<R>);\ (<s>,<S>);(<t>,<T>);(<u>,<U>);(<v>,<V>);(<w>,<W>);\ (<x>,<X>);(<y>,<Y>);(<z>,<Z>) # tolower (<A>,<a>);(<B>,<b>);(<C>,<c>);(<D>,<d>);\ (<E>,<e>);(<F>,<f>);(<G>,<g>);(<H>,<h>);\ (<I>,<i>);(<J>,<j>);(<K>,<k>);(<L>,<l>);\ (<M>,<m>);(<N>,<n>);(<O>,<o>);(<P>,<p>);\( <Q>,<q>);(<R>,<r>);(<S>,<s>);(<T>,<t>);\ <U>,<u>);(<V>,<v>);(<W>,<w>);(<X>,<x>);(\ <Y>,<y>);(<Z>,<z>) END LC_CTYPE
Пример 13.2. Определение категории LC_CTYPE для POSIX-среды.
Категория LC_COLLATE определяет порядок алфавитного сравнения символов для многочисленных служебных программ (sort, uniq и т.д.), регулярных выражений, а также функций strcoll(), strxfrm() и других.
В алфавитном сравнении могут участвовать односимвольные и многосимвольные элементы. Их порядок задается весами, которых у каждого элемента может быть несколько (не более COLL_WEIGHTS_MAX). Первый вес называется основным. Если при сравнении элементов основные веса совпали, используются соответственные пары дополнительных – до тех пор, пока либо не будет обнаружено неравенство, либо не кончатся веса.
Допускается формирование классов эквивалентности – присвоение одного основного веса нескольким элементам сравнения. Поддерживаются также отображения один-ко-многим (один символ отображается в последовательность элементов сравнения).
Разумеется, сравнение цепочек символов начинается с разбиения на элементы сравнения.
Правила алфавитного сравнения и директивы присвоения весов открываются ключевым словом order_start и завершаются директивой order_end. Подразумеваемым правилом является forward – сравнение от начала к концу цепочки. Возможен и противоположный порядок (backward).
После строки order_start элементы сравнения перечисляются в порядке возрастания. После элемента может быть задана последовательность его весов. Веса задаются как относительные, в виде имен других элементов и определяются позицией этих элементов при перечислении. Специальный вес IGNORE означает, что данный элемент следует игнорировать при сравнении цепочек. Многоточие в качестве элемента сравнения обозначает диапазон от предыдущего до последующего элементов. Элемент UNDEFINED представляет все, что не было указано явно.
В POSIX-среде алфавитный порядок совпадает с упорядоченностью символов в кодировке ASCII.
Категория LC_MONETARY определяет формат денежных величин. Входящие в нее элементы именуются аналогично полям приведенной выше структуры lconv.
Например, после ключевого слова currency_symbol задается цепочка символов, обозначающая местные денежные величины. Если ключевое слово данной категории отсутствует в файле определения среды либо его значением является пустая цепочка или -1, значит, соответствующий элемент в языково-культурной среде неспецифицирован.
В POSIX-среде все элементы этой категории остаются неспецифицированными.
В категории LC_NUMERIC, во многом аналогичной LC_MONETARY, определяются правила и обозначения, используемые применительно к числовым данным. Здесь также действует параллель со структурой lconv.
В пример 13.3 показано определение категории LC_NUMERIC для POSIX-среды. Собственно, специфицируется только десятичная точка.
LC_NUMERIC # POSIX-среда, категория LC_NUMERIC # decimal_point "<period>" thousands_sep "" grouping -1 # END LC_NUMERIC
Пример 13.3. Определение категории LC_NUMERIC для POSIX-среды.
Элементы категории LC_TIME определяют интерпретацию спецификаторов преобразований и, тем самым, поведение служебной программы date, а также функций strftime(), strptime() и некоторых других. В число поддерживаемых ключевых слов входят abday (сокращенные названия дней недели, начиная с воскресенья; элемент соответствует спецификатору %a), day (полные названия дней недели, %A), abmon (сокращенные названия месяцев, %b), mon (полные названия месяцев, %B), d_t_fmt (принятое в данной языково-культурной среде представление даты и времени, %c), d_fmt (принятое в данной среде представление даты, %x), t_fmt (принятое в данной среде представление времени, %X).
Особым образом устроен элемент era, определяющий способ отсчета и отображения лет для каждой эры, поддерживаемой языково-культурной средой. Операнд ключевого слова era состоит из цепочек символов, каждая из которых описывает конкретную эру и имеет следующий формат:
направление:смещение:начальная_дата: конечная_дата:имя_эры:формат_эры
Здесь направление – знак плюс или минус, смещение – ближайший к начальной дате номер года, начальная_дата – цепочка вида гггг/мм/дд (год, месяц и число начала эры), конечная_дата – год, месяц и число конца эры либо цепочки «-*» (конечной датой служит начало отсчета времени) или «+*» (конечной датой служит конец отсчета времени), формат_эры – цепочка, используемая при форматировании номеров года в эре.
Отметим, что точка отсчета может быть как самой ранней, так и самой поздней в эре. Примерами служат две христианские эры – после и до Рождества Христова, соответственно.
В пример 13.4 показано определение категории LC_TIME для POSIX-среды.
LC_TIME # POSIX-среда, категория LC_TIME # # Сокращенные названия дней недели (%a) abday "<S><u><n>";"<M><o><n>";"<T><u><e>";\ "<W><e><d>";"<T><h><u>";"<F><r><i>";"<S><a><t>" # # Полные названия дней недели (%A) day "<S><u><n><d><a><y>";\ "<M><o><n><d><a><y>";\ "<T><u><e><s><d><a><y>";\ "<W><e><d><n><e><s><d><a><y>";\ "<T><h><u><r><s><d><a><y>";\ "<F><r><i><d><a>\<y>";\ "<S><a><t><u><r><d><a><y>" # # Сокращенные названия месяцев (%b) abmon "<J><a><n>";"<F><e><b>";"<M><a><r>";\ "<A><p><r>";"<M><a><y>";"<J><u><n>";\ "<J><u><l>";"<A><u><g>";"<S><e><p>";\ "<O><c><t>";"<N><o><v>";"<D><e><c>" # # Полные названия месяцев (%B) mon "<J><a><n><u><a><r><y>"\ "<F><e><b><r><u><a><r><y>";\ "<M><a><r><c><h>";"<A><p><r><i><l>";\ "<M><a><y>";"<J><u><n><e>";\ "<J><u><l><y>";"<A><u><g><u><s><t>";\ "<S><e><p><t><e><m><b><e><r>";\ "<O><c><t><o><b><e><r>";\ "<N><o><v><e><m><b><e><r>";\ "<D><e><c><e><m><b><e><r>" # # Эквивалент AM/PM (%p) "AM";"PM" am_pm "<A><M>";"<P><M>" # # Принятое в POSIX-среде представление даты и времени (%c) # "%a %b %e %H:%M:%S %Y" d_t_fmt "<percent-sign><a><space><percent-sign>\ <b><space><percent-sign><e><space>\ <percent-sign><H><colon><percent-sign>\ <M><colon><percent-sign><S><space>\ <percent-sign><Y>" # # Принятое в POSIX-среде представление даты (%x) "%m/%d/%y" d_fmt "<percent-sign><m><slash><percent-sign><d>\ <slash><percent-sign><y>" # # Принятое в POSIX-среде представление времени (%X) "%H:%M:%S" t_fmt "<percent-sign><H><colon><percent-sign><M>\ <colon><percent-sign><S>" # # Принятое в POSIX-среде 12-часовое представление времени (%r) "%I:%M:%S %p" t_fmt_ampm "<percent-sign><I><colon><percent-sign\ <M><colon><percent-sign><S><space>\ <percent_sign><p>" # END LC_TIME
Пример 13.4. Определение категории LC_TIME для POSIX-среды.
Категория LC_MESSAGES играет весьма ограниченную роль, определяя положительные и отрицательные ответы. Соответственно, она содержит два элемента – yesexpr и noexpr, значениями которых служат расширенные регулярные выражения. Для POSIX-среды данная категория описывается так, как показано в пример 13.5.
LC_MESSAGES # POSIX-среда, категория LC_MESSAGES # yesexpr "<circumflex><left-square-bracket>\ <y><Y><right-square-bracket>" # noexpr "<circumflex><left-square-bracket>\ <n><N><right-square-bracket>" # END LC_MESSAGES
Пример 13.5. Определение категории LC_MESSAGES для POSIX-среды.