аналог gettext в fpc

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

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

аналог gettext в fpc

Сообщение alex_alex_alex1 » 18.03.2012 15:43:56

Задача узнать как переведены строки в том или ином приложении.
Есть в linux консольная утилита gettext:
Код: Выделить всё
$ gettext bash '%s: command not found'; echo
%s: команда не найдена

она позволяет узнать как у приложения переведены строки, например, у bash фраза "command not found" переведена "команда не найдена"
как написать тоже самое на fpc без вызова gettext (чем проще тем лучше)?
Последний раз редактировалось alex_alex_alex1 19.03.2012 10:52:49, всего редактировалось 1 раз.
alex_alex_alex1
постоялец
 
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

Re: аналог gettext в fpc

Сообщение Сквозняк » 19.03.2012 06:45:43

Из паскаля можно вызывать комманды системы функцией FpSystem, очень полезная функция - можно стрельнуть на линуксовом форуме комманду баша, там заведут пластинку на тему "читай маны, учи баш..." но комманду в результате дадут. Но выхлоп консоли FpSystem не возвращает. Переделал стандартную демку которая идёт в html документации. Работает, я сам в шоке :)
Код: Выделить всё
{ Program to demonstrate the Popen function. }

uses BaseUnix,Unix;

var f : text;
    i : longint;
    s : ansistring;

begin
assign (f,'test21a');
rewrite (f);
s:='gettext bash '+#39+'%s: command not found'+#39+';'; //загоняем в переменную текст: gettext bash '%s: command not found';
popen (f,s,'W');
if fpgeterrno<>0 then
     writeln ('error from POpen : errno : ', fpgeterrno);
writeln('Сейчас будет распечатан выхлоп комманды, если таковой имеется');
writeln (f);
erase (f)
end.
Сквозняк
энтузиаст
 
Сообщения: 1126
Зарегистрирован: 29.06.2006 22:08:32

Re: аналог gettext в fpc

Сообщение alex_alex_alex1 » 19.03.2012 10:35:39

FpSystem и POpen - не вариант, знаю я и то и то, но вы так и продолжаете использовать gettext, а надо написать аналог gettext, а не вызывать его.
alex_alex_alex1
постоялец
 
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

Re: аналог gettext в fpc

Сообщение zub » 19.03.2012 10:53:29

Аналог gettext для работы с mo файлами в fpc есть - \ppsrc\packages\fcl-base\src\gettext.pp
В лазаре добавляется возможность работы с po файлами - \lcl\translations.pas
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: аналог gettext в fpc

Сообщение alex_alex_alex1 » 19.03.2012 10:57:23

Как мне кажется эту задачу можно решить теоретически так: каким-то образом задействовать возможности fpc по работе с .mo-файлами, ведь он же умеет переводить с языка на язык.
/usr/share/locale/ЛОКАЛЬ/LC_MESSAGES/bash.mo - здесь и есть перевод, надо только его вытащить.

Добавлено спустя 1 минуту 42 секунды:
zub писал(а):Аналог gettext для работы с mo файлами в fpc есть - \ppsrc\packages\fcl-base\src\gettext.pp

копал его, но что-то никак, подскажите, если не затруднит, пару строк кода как делать надо.
alex_alex_alex1
постоялец
 
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

Re: аналог gettext в fpc

Сообщение zub » 19.03.2012 11:25:26

http://wiki.lazarus.freepascal.org/Tran ... rograms/ru
описана локализация программ на основе po, для mo думаю аналогично. Там перевод "изнутри" программы, сразу "целыми юнитами".
Но можно работать и с отдельными фразами, надо только найти и загрузить нужный po\mo и использовать методы перевода отдельных фраз
Код: Выделить всё
  TMOFile = class
    ....
    function Translate(AOrig: PChar; ALen: Integer; AHash: LongWord): String;
    function Translate(AOrig: String; AHash: LongWord): String;
    function Translate(AOrig: String): String;
    ....
  end;

Код: Выделить всё
  TPOFile = class
    ....
    function Translate(const Identifier, OriginalValue: String): String;
    ....
  end;
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: аналог gettext в fpc

Сообщение alex_alex_alex1 » 19.03.2012 11:58:44

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

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  gettext;

type

  { TForm1 }

  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

resourcestring
  mes='Password:';

var
  Form1: TForm1;
  Lang, FallbackLang: string;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Text:=mes;
end;

initialization

gettext.GetLanguageIDs(Lang, FallbackLang);
If FileExists('/usr/share/locale/'+FallbackLang+'/LC_MESSAGES/coreutils.mo') then
                                                     gettext.TranslateResourceStrings('/usr/share/locale/'+FallbackLang+'/LC_MESSAGES/coreutils.mo');

end.     

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

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, gettext;

type

  { TForm1 }

  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  mof: TMOFile;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var
  str,file_mo:string;
  Lang, FallbackLang: string;
begin
   gettext.GetLanguageIDs(Lang, FallbackLang);
   file_mo:= '/usr/share/locale/'+FallbackLang+'/LC_MESSAGES/coreutils.mo';
   str:='Password:';
   mof := TMOFile.Create(file_mo);
   str:=mof.Translate(str);
   memo1.Text:=str;
   mof.Free;
end;

end.       

Всё бы хорошо, но некоторые .mo-файлы переводятся таким образом кракозябрами, чего-то не то с кодировкой.
alex_alex_alex1
постоялец
 
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

Re: аналог gettext в fpc

Сообщение alex_alex_alex1 » 21.03.2012 09:05:06

По ходу надо использовать модуль gnugettext чтобы использовать dgettext из него из-за проблем с кодировкой.
Здесь http://sourceforge.net/projects/lazarus ... dxgettext/ лежит старый вариант gnugettext.
У кого есть новый вариант gnugettext и gnugettext_fpc_pp?
alex_alex_alex1
постоялец
 
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

Re: аналог gettext в fpc

Сообщение Alexx2000 » 21.03.2012 09:37:37

alex_alex_alex1 писал(а):Всё бы хорошо, но некоторые .mo-файлы переводятся таким образом кракозябрами, чего-то не то с кодировкой.

Возможно они в кодировке KOI8-R, попробуйте добавить перекодировку из KOI8-R в UTF-8 (модуль LConvEncoding, функция KOI8ToUTF8)
Аватара пользователя
Alexx2000
постоялец
 
Сообщения: 489
Зарегистрирован: 25.10.2006 00:22:07
Откуда: Мытищи

Re: аналог gettext в fpc

Сообщение zub » 21.03.2012 11:39:17

Я так и непонял смысл задачи. Использовать чужие файлы локализации? Это неправильно, надо создать и использовать свои
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: аналог gettext в fpc

Сообщение bormant » 21.03.2012 12:11:24

zub,
насколько я понял, задача узнать, каков будет ответ команды в текущей локали по известному ответу в LANG=C или LANG=en.

Для динамической линковки с gettextlib.so всё довольно просто:
Код: Выделить всё
const
  LC_ALL = 6;

function SetLocale(Context: Integer; Locale: PChar): PChar; cdecl; external name 'setlocale';
function DGetText(Domain, MsgId: PChar): PChar; cdecl; external name 'dgettext';
{$linklib gettextlib}

const
  BASH_MSG="%s: command not found";
begin
  SetLocale(LC_ALL, '');
  WriteLn(DGetText('bash', BASH_MSG));
end.
Аватара пользователя
bormant
постоялец
 
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Re: аналог gettext в fpc

Сообщение alex_alex_alex1 » 21.03.2012 19:18:50

В простейшем коде на fpc алгоритм bormant работает, но в проекте на lazarus или mseide+msegui начитается конфликт модулей и этой либы, вплоть до того, что шрифты не нравятся ни один - в итоге проект может и собраться, но при выполнении начинается конфликт.

Необходимость знать как отвечает в консоль та или иная команда возникла в проекте xroot: http://code.google.com/p/xroot/
На данный момент перевод .mo-файлов работает если они в utf-8, но если кодировка .mo-файла другая, то возникают кракозябры.

Добавлено спустя 10 минут 57 секунд:
Код: Выделить всё
./xroot
Fontconfig warning: no <cachedir> elements found. Check configuration.
Fontconfig warning: adding <cachedir>/var/cache/fontconfig</cachedir>
Fontconfig warning: adding <cachedir>~/.fontconfig</cachedir>
* Пароль:
* неправильный пароль
* %s: command not found
* %s: Authentication failure

Использование утилиты xroot:
xroot "команда" + параметры
Параметры: auto_su_first, auto_sudo_first, auto_su_sudo, debug, help
"команда" может быть "команда+параметры"

An unhandled exception occurred at $080E0A7C :
egdi : Invalid font twidgetfont stf_default.
  $080E0A7C  GDIERROR,  line 1610 of /opt/xroot/trunk/msegui/lib/common/graphics/msegraphutils.pas
  $080E0B9B  GDIERROR,  line 1625 of /opt/xroot/trunk/msegui/lib/common/graphics/msegraphutils.pas
  $080CFE40  TCANVAS__ERROR,  line 2968 of /opt/xroot/trunk/msegui/lib/common/graphics/msegraphics.pas
  $080CE511  TFONT__CREATEHANDLE,  line 2284 of /opt/xroot/trunk/msegui/lib/common/graphics/msegraphics.pas
  $080CE600  TFONT__GETHANDLE,  line 2313 of /opt/xroot/trunk/msegui/lib/common/graphics/msegraphics.pas
  $080CE647  TFONT__GETDATAPO,  line 2323 of /opt/xroot/trunk/msegui/lib/common/graphics/msegraphics.pas
  $080CE721  TFONT__GETLINEHEIGHT,  line 2361 of /opt/xroot/trunk/msegui/lib/common/graphics/msegraphics.pas
  $0807F48E  TWIDGET__UPDATEFONTHEIGHT,  line 11325 of /opt/xroot/trunk/msegui/lib/common/kernel/msegui.pas
  $0807F20C  TWIDGET__FONTCHANGED,  line 11267 of /opt/xroot/trunk/msegui/lib/common/kernel/msegui.pas
  $081C09B1  TCUSTOMEDIT__FONTCHANGED,  line 1316 of /opt/xroot/trunk/msegui/lib/common/editwidgets/mseedit.pas
  $08225684  TCUSTOMTEXTEDIT__FONTCHANGED,  line 576 of /opt/xroot/trunk/msegui/lib/common/editwidgets/msetextedit.pas
  $0807F63F  TWIDGET__PARENTFONTCHANGED,  line 11370 of /opt/xroot/trunk/msegui/lib/common/kernel/msegui.pas
  $08075859  TWIDGET__LOADED,  line 7302 of /opt/xroot/trunk/msegui/lib/common/kernel/msegui.pas
  $080AB76E
  $080E957A  LOADMSEMODULE,  line 2637 of /opt/xroot/trunk/msegui/lib/common/kernel/mseclasses.pas
  $0808E755  TCUSTOMMSEFORM__CREATE,  line 792 of /opt/xroot/trunk/msegui/lib/common/widgets/mseforms.pas
  $08091163  TMSEFORM__CREATE,  line 1792 of /opt/xroot/trunk/msegui/lib/common/widgets/mseforms.pas
alex_alex_alex1
постоялец
 
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

Re: аналог gettext в fpc

Сообщение zub » 21.03.2012 19:41:16

>>На данный момент перевод .mo-файлов работает если они в utf-8, но если кодировка .mo-файла другая, то возникают кракозябры.
в шапке po указывается кодировка в которой он сохранен, в мо думаю тоже должна
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: аналог gettext в fpc

Сообщение Sergei I. Gorelkin » 21.03.2012 21:00:25

В .mo вся шапка отдается как "перевод" пустой строки.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: аналог gettext в fpc

Сообщение alex_alex_alex1 » 21.03.2012 21:30:58

Проверил на дефолтном проекте в mseide - всё работает, но не работает если использовать хоть какие-нибудь компоненты.
Код: Выделить всё
unit main;
{$ifdef FPC}{$mode objfpc}{$h+}{$endif}
interface
uses
mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui,
msegraphics,msegraphutils,mseevent,mseclasses,mseforms;
const
  LC_ALL = 6;
  BASH_MSG='%s: command not found';
function SetLocale(Context: Integer; Locale: PChar): PChar; cdecl; external name 'setlocale';
function DGetText(Domain, MsgId: PChar): PChar; cdecl; external name 'dgettext';
{$linklib gettextlib}

type
tmainfo = class(tmainform)
end;
var
mainfo: tmainfo;
implementation
uses
main_mfm;

initialization
   SetLocale(LC_ALL, '');
  WriteLn(DGetText('bash', BASH_MSG));
end.


Воспроизвести просто: если в дефолтном проекте (код чуть выше в этом сообщении) положить на форму любой компонент, то возникает проблема с шрифтами, без компонентов если голая форма, то работает. Стоит только написать {$linklib gettextlib} как проект собирается, но падает, ругаясь на шрифты: egdi : Invalid font twidgetfont...
alex_alex_alex1
постоялец
 
Сообщения: 207
Зарегистрирован: 15.10.2010 14:08:50

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5

Рейтинг@Mail.ru