Что значит "программа правильно написана" ?
Давайте рассмотрим теперь, как писать "правильные" с точки зрения локализации программы. Основное внимание уделим стандартам.
(Но и у стандартов есть свои проблемы. Поэтому - немного ).
"Правильно" написанная программа с использованием POSIX locale не должна зависить от способа кодирования ("") символов. Такая программа не должна быть привязана к 7-ми битности ASCII символов, и должна пользоваться стандартными библиотечными (API) функциями locale : , , isxxx() и / не полагаясь, что Upper=Lower+0x20
и т.д. Конструкции, подобные этой также недопустимы :
if (c >= 'A' && c <= 'Z') { ...
Пользуйтесь :
if (isalpha(c) && isupper(c)) { ... или
if (isascii(c) && isupper(c))
Как правило, национальные алфавиты расположены начиная с кода (codepoint) 0x80, поэтому для совместимости со старыми реализациями locale можно объявить все символы как unsigned char, например ключом компилятора (для gcc -funsigned-char) или явно.
Хорошо написанная программа должна быть польностью 8-бит прозрачна. Например отметка удаленного файла в MS-DOS кодом 0x0E5
- не очень хорошее решение. Еще примеры плохих решений : знаменитая русская буква "Н" в редакторе GoldEd или русская буква "р" в Norton Commander...
Во-вторых, программа должна явно начинаться с вызова (такая форма вызова означает, что всем категориям локализации одновременно будет присвоено значение переменной окружения ). До вызова этой функции (или совсем без него) программа не обращает внимания на LANG= и фунции isalpha()...
работают в локализации POSIX (С) и с набором символов ASCII. То есть, не бывает "никакой" локализации.
ПРИМЕЧАHИЕ: Во FreeBSD можно вылечить некоторые программы, в которых забыт вызов setlocale()
путем задания строки окружения : $ export ENABLE_STARTUP_LOCALE="" тогда setlocale(LC_ALL,"") будет вызываться автоматически при старте программ (без их перекомпиляции). В Linux libc такого нет (пока?) и по умолчанию всегда включено LANG="C" или "POSIX". Однако можно пересобрать Linux libc, указав другое значение по умолчанию. Но следует отметить, что такое решение будет противоречить стандарту, по которому программа стартует в POSIX (до первого вызова setlocale()). |
Для получения locale-зависимой информации следует пользоватся данными структуры lconv, которые можно получить вызовом функции . Для получения детальной информации по категориям локализации (описанным в файле ) можно пользовться функцией . (Эта функция не входит в POSIX, но входит в XPG, и большинство систем ее имеют).
Для сравнения строк символов следует пользоваться функциями и вместо .
Для полной поддержки сообщений на родном языке () весь вывод сообщений пользователю должен происходить c использованием функций NLS и должен быть создан каталог сообщений (message catalog) для данной программы (и данного языка).
А в заключение, неплохо бы иметь man
на разных языках. :-)