аналог gettext в fpc

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Аватара пользователя
bormant
постоялец
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Сообщение bormant »

alex_alex_alex1,
Будет ли падать при таком варианте вызова?

Код: Выделить всё

uses dynlibs;

const
  LC_ALL = 6;
  BASH_MSG = '%s: command not found';

function SetLocale(Context: Integer; Locale: PChar): PChar; cdecl; external name 'setlocale';

type
  TDGetText = function(Domain, MsgId: PChar): PChar; cdecl;

var
  DGetText: TDGetText;
  LibGT: TLibHandle;

begin
  { локаль приложения }
  SetLocale(LC_ALL, '');

  { получаем адрес DGetText }
  LibGT := SafeLoadLibrary('libgettextlib.so');
  if NilHandle = LibGT then begin WriteLn('Error: SafeLoadLibrary()'); exit; end;
  pointer(DGetText) := GetProcedureAddress(LibGT, 'dgettext');

  { получаем перевод(ы) }
  if nil <> DGetText
  then WriteLn(DGetText('bash', BASH_MSG))
  else WriteLn('Error: GetProcedureAddress()');

  { освобождаем библиотеку }
  UnloadLibrary(LibGT);
end.


Полученное от DGetText() нужно скопировать куда-то в родную строку для дальнейшего использования, либо продолжать использовать как ообычный указатель PChar (благо совместим), ибо
man dgettext писал(а):RETURN VALUE
... The resulting string is statically allocated and must not be modified or freed. ...
alex_alex_alex1
постоялец
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

Сообщение alex_alex_alex1 »

bormant писал(а):Будет ли падать при таком варианте вызова?

так работает

Найдено рабочее решение: оказалось несложно и правильнее пропатчить модуль gnugettext, чтобы он переводил .mo-файлы, которые не только в utf8:
http://code.google.com/p/xroot/source/b ... ettext.pas
http://code.google.com/p/xroot/source/b ... ext_fpc.pp

Код: Выделить всё

    Result:=mofile.gettext(msgid,found);
    //переводим в кодировку, которая используется в .mo-файле
    if found then if mofile.mo_code='KOI8-R' then
                      Result:=KOI8TOUTF8(Result);

Модуля lconvencoding в mseide+msegui нет, но есть в lazarus, поэтому просто берутся из него необходимые функции перевода из одной кодировки в другую.

Очень хорошо, что в поднятой теме уже 2 рабочих решения.
Аватара пользователя
bormant
постоялец
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Сообщение bormant »

Вот, уже ближе. Осталось только учесть, что у пользователя может быть не UTF-8 локаль и переводить нужно в неё, а не в UTF-8. Так, у кириллического письма легко может оказаться koi8-r, koi8-u, cp1251, iso-8859-5, cp866 (рус./укр.), mik, cp855 (Болгария) и т.д.
alex_alex_alex1
постоялец
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

Сообщение alex_alex_alex1 »

А зачем если у mseide+msegui всё в unicode?

> - in msegui I did not find functions: KOI8TOUTF8, ISO_8859_1TOUTF8,
> ISO_8859_2TOUTF8 and other from lconvencoding (lazarus).

Martin Schreiber пишет мне ответ:
"MSEgui uses internally UnicodeString (utf-16) instead of utf-8 like Lazarus.
For GUI string variables you should always use "msestring" which is mapped to
UnicodeString. The conversion from/to the 8bit system encoding to/from
UnicodeString utf-16 is done automatically by the unicodestringmanager and
iconv on Linux or system functions on Windows. So there probably is no need
to explicitely convert encodings. Please don't forget to compile MSEgui
programs with -Fcutf8 in order FPC can build the correct Unicode string
constants. You probably can ask debi12345 on freepascal.ru for details"
Аватара пользователя
bormant
постоялец
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Сообщение bormant »

alex_alex_alex1 писал(а):А зачем если у mseide+msegui всё в unicode?
...
"MSEgui uses internally

Это MSEgui использует, а bash/su/sudo/что-то-ещё не использует...

man 3 gettext говорит, что gettext()/dgettext()/dcgettext() возвращают строку в кодировке приложения:
RETURN VALUE
If a translation was found in one of the specified catalogs, it is converted to the locale's codeset and returned.
поэтому

Код: Выделить всё

LANG=ru_RU.UTF-8 bash abracadabra
bash: abracadabra: Нет такого файла или каталога
ответит в кодировке UTF-8, а

Код: Выделить всё

LANG=ru_RU.CP1251 bash abracadabra 
ответит то же самое, но в кодировке CP1251, в чём легко убедиться (пример для локали utf-8):

Код: Выделить всё

LANG=ru_RU.CP1251 bash abracadabra 2>&1 | iconv -f CP1251 -t UTF-8
bash: abracadabra: Нет такого файла или каталога
alex_alex_alex1
постоялец
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

Сообщение alex_alex_alex1 »

018.jpeg
У xroot своя консоль (tterminal), и bash отвечает в ней, я проверил
termfo.term.execprog('export LANG=ru_RU.CP1251; export LANGUAGE=ru_RU.CP1251:ru; export; su --login -p -c "'+command_str.value+'"');
bash отвечает в кодировке CP1251, но до лампочки, работает всё нормально.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Ответить