LINUX.ORG.RU

C: локализация POSIX-way


0

0

Сразу скажу, что пишу кроссплатформенную программу, и не у нее, а у систем, в которых она используется есть проблема: перед запуском невозможно выставить для нее переменные среды.

Теперь про локализацию: я так понимаю, что необходимо использовать функции catopen, catclose и catgets (gettext не стандарт для всех систем, кроме Solaris и Linux). Есть несколько вопросов по применению POSIX-функций (я конечно могу опытным путем проверить их в Linux и HP-UX, но это не полный перечень платформ, которые хотелось бы поддерживать, вразумительной документации не нашел):
1. POSIX не определяет, где хранить каталоги (cat-файлы), т.е. catopen конечно читает NLSPATH, но, например, в Slackware Linux ни переменной NLSPATH, ни одного .cat файла я не обнаружил. Вопрос: куда программа по make install должна их забросить и что должна передавать в качестве первого параметра catopen?
2. Правильно ли будет (оч. хочется) сделать массив указателей типа char * и при старте программы заполнить его указателями через catgets? Ведь catgets с номером сообщения мало информативен для кода, да и обременяет программу каждый раз по catgets делать поиск (пусть даже по индексу) в каталоге.
3. К п.2 выше, живут ли значения catgets после очередного вызова catgets? Согласно man из HP-UX и Linux - живут.
4. Согласно man на catgets, сказано, что если catopen не нашел каталога (вернул -1), то будут использоваться значения по-умолчанию для C/POSIX. Правильно ли я понимаю, что через NLSPATH всегда должна быть доступна директория en (или какая? en_US? en_GB???) с локализацией на английском?

P.S. Гуглил, яндексил, читал стандарт, всё весьма противоречиво, кстати, очень ругают *BSD системы :-\

★★★★★

gettext не стандарт, конечно, но практически на все системы портирован

1. Если NLSPATH не определена, то используется путь по умолчанию. Для *NIX это обычно что-то типа /usr/share/locale, но можно ведь при вызове catopen и полный путь указать

2. ИМХО так и задумано

3. Не очень понял о чём, но не стал бы на это полагаться. В SUSv3 написано, что "catgets() function need not be reentrant", а это значит, что реализация может использовать буфер изменяемый при каждом очередном вызове.

4. Если catopen вернул ошибку, то catgets будет возвращать значения по умолчанию (т.е. свой четвёртый аргумент). Наличие каталогов C, en ,т.о. не является необходимым

zwon
()

Могу лишь сказать, что Fluxbox устанавливает свои *.cat файлы в /usr/share/fluxbox/nls/ Можешь кстати заглянуть в его сырцы, авось чего полезное откопаешь (смотри в src/FbTk/I18n.{cc,hh})

php-coder ★★★★★
()
Ответ на: комментарий от zwon

> gettext не стандарт, конечно, но практически на все системы портирован

Да, но именно портирован, а не присутствует из коробки :-(

> 1. Если NLSPATH не определена, то используется путь по умолчанию. Для *NIX это обычно что-то типа /usr/share/locale, но можно ведь при вызове catopen и полный путь указать.

Да, это в доке сказано. Только программе по make install создавать /usr/share/nls на системах где его нет (допустим они /usr/share/locale используют)? Я вообще тогда смысла не вижу в этих cat*, потому что сейчас программа читает текстовый файл, где номер строки - индекс и еще потому, что программе придется даже полное имя локали читать.

> 2. ИМХО так и задумано > 3. Не очень понял о чём, но не стал бы на это полагаться. В SUSv3 написано, что "catgets() function need not be reentrant", а это значит, что реализация может использовать буфер изменяемый при каждом очередном вызове.

Вы правильно меня поняли в п.3, но ваши ответы на п.2,3 противоречивы, спасибо за цитату из SUS, буду использовать strdup (если вообще решусь на этот, sorry, cat*бред).

> 4. Если catopen вернул ошибку, то catgets будет возвращать значения по умолчанию (т.е. свой четвёртый аргумент). Наличие каталогов C, en ,т.о. не является необходимым. Проморгал, блин :-)

Спасибо огромное, наверное откажусь от помощи POSIX в вопросе локализации, текущие функции, читающие строки из текстового файла и портабельные и удобные и быстрые, в отличие от ...

saper ★★★★★
() автор топика
Ответ на: комментарий от saper

> Да, но именно портирован, а не присутствует из коробки :-(

Некоторые распространяют gettext вместе со своим кодом, на случай если в системе этой библиотеки нет

> Только программе по make install создавать /usr/share/nls на системах где его нет?

Тут на разных системах по разному, в любом случае.

> ваши ответы на п.2,3 противоречивы

Да, я ошибся, подумал про массив строк, а не указателей

> наверное откажусь от помощи POSIX в вопросе локализации

возможно свои функции использовать проще и эффективнее, но если посторонние люди будут выполнять локализацию на другие языки, то им прийдётся с этими функциями разбираться.

zwon
()
Ответ на: комментарий от zwon

> если посторонние люди будут выполнять локализацию на другие языки, то им прийдётся с этими функциями разбираться

Видимо не придется, придется им взять файл английской локализации и построчно его перевести. Всё :-) Тем более, что на словакский, немецкий, итальянский и чешский мне так и переводили :)

saper ★★★★★
() автор топика
Ответ на: комментарий от zwon

Меня больше интересовала автозагрузка файла локализации в зависимости от локали, т.е. чтобы это самому не делать.

Как файлы локализации размещать и обрабатывать, если перевод для en_* у меня пока один... И я не знаю, будет ли перевод различаться для: en_US, en_CA, en_AU, en_GB, т.е. мне или:
1. en.ISO8859-1 сделать для всех этих языков (программа будет смотреть только на en и набор символов).
2. или полные en_US.ISO8859-1 (оригинал), en_GB.ISO8859-1 (симв. ссылка на en_US.ISO8859-1).

saper ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.