Pentru a putea vota, modifica pagini sau abona la modificările unei pagini trebuie să fiți autentificați. Cu această ocazie scăpați și de acest mesaj deranjant.

Localizarea în Visual C: Diferență între versiuni

De la l10n.ro
Salt la: navigare, căutare
(Gettext)
(Cum convertesc dintr-un string în altul)
 
(Nu s-au afișat 15 versiuni intermediare efectuate de alți 2 utilizatori)
Linia 1: Linia 1:
[[Category:Programming]]
 
 
 
== Introducere ==
 
== Introducere ==
Am in mentenanţă o aplicaţie MFC veche de 7 ani şi de curând am putut să renunţ la suportul pentru Win9x şi am început trecerea aplicaţiei la Unicode.  
+
Am în mentenanţă o aplicaţie MFC, veche de 7 ani şi de curând am putut să renunţ la suportul pentru Win9x şi am început trecerea aplicaţiei la Unicode.  
  
Acum pot sa recomand oricui vrea sa internationalizeze/localizeze să folosească libraria gettext din urmatoarele motive:
+
Acum pot recomand oricui vrea, să internaţionalizeze/localizeze, să folosească librăria gettext din următoarele motive:
 
* mentenanţa fişierelor de localizare este incomparabil mai uşoară
 
* mentenanţa fişierelor de localizare este incomparabil mai uşoară
 
* există orice fel de unelte de localizare pentru fişiere gettext (.PO)
 
* există orice fel de unelte de localizare pentru fişiere gettext (.PO)
 
* poate fi folosită şi în aplicaţii comerciale (este LGPL)
 
* poate fi folosită şi în aplicaţii comerciale (este LGPL)
  
== Faza 1 - trecerea la unicode... fără a renuţa la versiunea veche! ==
+
== Trecerea aplicației la Unicode ==
Unii o pot considera inutila dar experienta mea spune ca merita sa renunti la Win9x si sa treci la unicode.  
+
Unii o pot considera inutilă, dar experienţa mea spune că merită să renunţi la Win9x și să treci la Unicode. Cel puțin, scapi de problema codepage-urilor.
 +
 
 +
Începeţi prin a înlocui tipurile de date și apelurile la funcții cu următoarele alternative, care de fapt sunt toate macro-uri, care se compilează diferit, în funcție de target. Această fază nu vă va 'strica' aplicaţia şi veţi putea să faceţi build-uri separate.
  
Incepeti prin a inlocui tipurile de date si accesele la functii cu urmatoarele. Aceasta faza nu vă va 'strica' aplicaţia şi veţi putea să faceţi build-uri separate.
+
Nu uitați să faceți un branch separat înainte de a începe, s-ar putea să dureze de 3X mai mult decât credeți, acum depinde de când și de cine a fost scrisă aplicația inițial.
  
 
<pre>
 
<pre>
char   _TCHAR
+
char       _TCHAR
 
LPSTR      LPTSTR
 
LPSTR      LPTSTR
 
LPCSTR      LPCTSTR
 
LPCSTR      LPCTSTR
Linia 30: Linia 30:
 
sscanf      _stscanf
 
sscanf      _stscanf
 
wsprintf    _tcs
 
wsprintf    _tcs
atoi   _tstoi
+
atoi       _tstoi
itoa   itot
+
itoa       _itot_s
sscanf   _stscanf
+
sscanf     _stscanf
 
vsprintf    _vstprintf
 
vsprintf    _vstprintf
fopen   _tfopen
+
fopen       _tfopen
 
fputs      _fputs
 
fputs      _fputs
fclose   _tfclose
+
fclose     _tfclose
 
</pre>
 
</pre>
  
 
<source lang="c">
 
<source lang="c">
/* Cum Bill cam uită să ducă treaba la bun sfârşit a uitat de (w)sprintf aşa că adăugaţi şi asta într-un H*/
+
/* Cum Bill cam uită să ducă treaba la bun sfârşit, a uitat de (w)sprintf aşa că adăugaţi şi asta într-un H*/
 
#ifdef UNICODE
 
#ifdef UNICODE
 
#define _tsprintf wsprintf
 
#define _tsprintf wsprintf
Linia 51: Linia 51:
  
 
=== Ceva mai puţin evident despre ..prinf(...) ===
 
=== Ceva mai puţin evident despre ..prinf(...) ===
funcţiile din gama printf pot primi ca parametrii atât char, w_char cât şi t_char aşa că **trebuie** ajutate să-şi dea sema ce primesc
+
Funcţiile din gama printf, pot primi ca parametrii atât char, w_char cât şi t_char aşa că **trebuie** ajutate să-şi dea seama ce primesc
 
<pre>
 
<pre>
 
Apel                  build unicode          build ne-unicode        alias
 
Apel                  build unicode          build ne-unicode        alias
Linia 61: Linia 61:
 
</pre>
 
</pre>
  
== Cum convertesc dintr-un string in altul ==
+
== Cum convertesc dintr-un string în altul ==
Puteti folosi niste macrocomenzi gen:
+
Puteți folosi niște macrocomenzi gen:
 +
 
 
<pre>
 
<pre>
W2A
+
W2A(...) și CW2A(...)
CA2T - const ANSI to TCHAR
+
A2T(...) și CA2T(...)
 +
T2A(...) și CT2A(...)
 
</pre>
 
</pre>
Nu uitati ca întorc un buffer static deci trebuie copiaţi valoarea dacă nu o folosiţi imediat.
+
 
 +
* C - constant
 +
* W - Wide
 +
* T - TCHAR (Adica W în unicode și A în rest)
 +
* A - ASCII
 +
 
 +
Nu uitați că ''nu le puteți folosi oricum'', deoarece fac niște hack-uri cam nasoale. Dacă vreți le folosiți citiți '''neapărat''' înainte
 +
* http://codexpert.ro/forum/viewtopic.php?f=23&t=149&p=650&hilit=CW2A#p650
 +
* http://codexpert.ro/forum/viewtopic.php?f=14&t=416&p=2426&hilit=ct2a#p2426
  
 
== Gettext ==
 
== Gettext ==
Linia 94: Linia 104:
 
=== ... ===
 
=== ... ===
  
Descarcati:
+
Descărcaţi:
 
* <tt>gettext-runtime</tt> (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/gettext)
 
* <tt>gettext-runtime</tt> (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/gettext)
 
* <tt>libiconv</tt> (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/libiconv)
 
* <tt>libiconv</tt> (ex: ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/libiconv)
  
Ar trebui sa stiti ca implicit gettext intoarce textele in UTF-8 ceea ce este foarte bine, mai putin pentru Windows care foloseste in modul Unicode (UTF16-LE), asa ca trebuie sa le convertiti la runtime (oricum e suficient de rapida conversia).
+
Ar trebui să ştiţi că, implicit, gettext întoarce textele în UTF-8, ceea ce este foarte bine, mai puţin pentru Windows, care foloseşte în modul Unicode (UTF16-LE), aşa că trebuie le convertiţi la runtime (oricum e suficient de rapidă conversia).
  
 
<source lang="cpp">
 
<source lang="cpp">
Linia 111: Linia 121:
  
 
== Extragerea textelor ==
 
== Extragerea textelor ==
Extragerea textelor din fisierele .C si .CPP este extrem de usoara folosing <tt>xgettext</tt>, dar cand veti ajunge la fisierele <tt>.RC</tt> o sa descoperiti ca nu sunt suportate. Din fericire dupa multe incercari nereusite am gasit singur o solutie simpla
+
Extragerea textelor din fişierele .C si .CPP este extrem de uşoară, folosind <tt>xgettext</tt>, dar când veţi ajunge la fişierele <tt>.RC</tt>, o să descoperiţi că nu sunt suportate. Din fericire, după multe încercări nereuşite, am găsit singur o soluţie simplă
  
 
<source lang="bash">xgettext --from-code=UTF-8 --add-comments --omit-header --no-location \
 
<source lang="bash">xgettext --from-code=UTF-8 --add-comments --omit-header --no-location \
Linia 118: Linia 128:
 
</source>
 
</source>
  
Sau pe scurt: intrucat sintaxa Tcl e destul de compatibila cu cea din .RC, folosind keyword-urile respective obtinei un parser de .RC in xgettext. Cool?... o sa trimit si un mail ca sa modifice sa recunoasca fisierele rc direct.
+
Sau pe scurt: întrucât sintaxa Tcl e destul de compatibilă cu cea din .RC, folosind keyword-urile respective, obţineţi un parser de .RC în xgettext. Cool?... o trimit şi un mail ca modifice să recunoască fişierele rc direct.
 +
 
  
[[Category:Tutorial]]
 
  
== Legături ==
+
== [[Legături|Legături]] ==
 
* http://www.gnu.org/software/gettext/ - de citit cu atenţie
 
* http://www.gnu.org/software/gettext/ - de citit cu atenţie
* http://taossa.com/index.php/2007/01/09/string-theory-for-windows/ - cum se lucreaza cu siruri in windows
+
* http://taossa.com/index.php/2007/01/09/string-theory-for-windows/ - cum se lucrează cu şiruri în Windows
  
 
--[[User:Admin|sorin]]
 
--[[User:Admin|sorin]]
 +
 +
[[Categorie:Tutorial]]
 +
[[Categorie:Programare]]

Versiunea curentă din 22 noiembrie 2009 07:07

Introducere

Am în mentenanţă o aplicaţie MFC, veche de 7 ani şi de curând am putut să renunţ la suportul pentru Win9x şi am început trecerea aplicaţiei la Unicode.

Acum pot să recomand oricui vrea, să internaţionalizeze/localizeze, să folosească librăria gettext din următoarele motive:

  • mentenanţa fişierelor de localizare este incomparabil mai uşoară
  • există orice fel de unelte de localizare pentru fişiere gettext (.PO)
  • poate fi folosită şi în aplicaţii comerciale (este LGPL)

Trecerea aplicației la Unicode

Unii o pot considera inutilă, dar experienţa mea spune că merită să renunţi la Win9x și să treci la Unicode. Cel puțin, scapi de problema codepage-urilor.

Începeţi prin a înlocui tipurile de date și apelurile la funcții cu următoarele alternative, care de fapt sunt toate macro-uri, care se compilează diferit, în funcție de target. Această fază nu vă va 'strica' aplicaţia şi veţi putea să faceţi build-uri separate.

Nu uitați să faceți un branch separat înainte de a începe, s-ar putea să dureze de 3X mai mult decât credeți, acum depinde de când și de cine a fost scrisă aplicația inițial.

char        _TCHAR
LPSTR       LPTSTR
LPCSTR      LPCTSTR

strlen      _tcslen
strcpy      _tcscpy 
strcmp      _tcscmp
strncmp     _tcsmcmp
stricmp     _tcsicmp
strchr      _tcschr
strncmp     _tcsncmp
sprintf     _tsprintf /* Vezi mai jos */
strstr      _tcsstr
sscanf      _stscanf
wsprintf    _tcs
atoi        _tstoi
itoa        _itot_s
sscanf      _stscanf
vsprintf    _vstprintf
fopen       _tfopen
fputs       _fputs
fclose      _tfclose
/* Cum Bill cam uită să ducă treaba la bun sfârşit, a uitat de (w)sprintf aşa că adăugaţi şi asta într-un H*/
#ifdef UNICODE
#define _tsprintf wsprintf
#define tstring wstring
#else
#define _tsprintf sprintf
#define tstring string
#endif

Ceva mai puţin evident despre ..prinf(...)

Funcţiile din gama printf, pot primi ca parametrii atât char, w_char cât şi t_char aşa că **trebuie** ajutate să-şi dea seama ce primesc

Apel                  build unicode          build ne-unicode        alias
--------------------------------------------------------------------------------
sprintf "%s"          LPWSTR                 LPSTR                   normal
sprintf "%S"          LPSTR          LPWSTR                  inverse  
sprintf "%hs"         LPSTR                  LPSTR                   single-byte
sprintf "&ls"         LPWSTR                 LPWSTR                  double-byte

Cum convertesc dintr-un string în altul

Puteți folosi niște macrocomenzi gen:

W2A(...) și CW2A(...)
A2T(...) și CA2T(...)
T2A(...) și CT2A(...)
  • C - constant
  • W - Wide
  • T - TCHAR (Adica W în unicode și A în rest)
  • A - ASCII

Nu uitați că nu le puteți folosi oricum, deoarece fac niște hack-uri cam nasoale. Dacă vreți să le folosiți citiți neapărat înainte

Gettext

Gettext functions and comments

// Translators: This is a text that is going to be used by translators in order to translate the next term corectly.
print(_("Code"));

// This is how we MUST use printf syntax in order to be able to translate corectly the programs.
// This syntax permits the changing the order of the parameters.
printf("'%2$d' us tge 2th parameter and '%1$s' is the first one.", param1, param2);

// SYntax
// _(...) este doar un macro care se expandeaza la gettext(...)
// dgettext
// dcgettext
char * ngettext (const char *msgid_singular, const char *msgid2_plural, unsigned long int n); // For plural
char * dngettext (const char *domain, const char *msgid1_singular, const char *msgid2_plural, unsigned long int n); // 
char * dcngettext (const char *domain, const char *msgid1, const char *msgid2, unsigned long int n, int category); //
// Formatting with positions
fprintf "%2$d %1$d" // (POSIX but not C 99)
// printf, vfprintf, sprintf, vsprintf, fwprintf, wprintf, swprintf, vswprintf

...

Descărcaţi:

Ar trebui să ştiţi că, implicit, gettext întoarce textele în UTF-8, ceea ce este foarte bine, mai puţin pentru Windows, care foloseşte în modul Unicode (UTF16-LE), aşa că trebuie să le convertiţi la runtime (oricum e suficient de rapidă conversia).

#include "../contrib/gettext-runtime/include/libintl.h"

CString strDomain=CString(textdomain("myproject")); // if you put "" will default to "messages"
CString strBinded = CString(bindtextdomain("myproject","d:\\dev\\pbxtools\\src\\debug\\locale\\")); // put you path here

// later
AfxMessageBox(_("Hello World!"), (UINT)MB_OK, (UINT)0);

Extragerea textelor

Extragerea textelor din fişierele .C si .CPP este extrem de uşoară, folosind xgettext, dar când veţi ajunge la fişierele .RC, o să descoperiţi că nu sunt suportate. Din fericire, după multe încercări nereuşite, am găsit singur o soluţie simplă

xgettext --from-code=UTF-8 --add-comments --omit-header --no-location \
--keyword=MENUITEM --keyword=LTEXT --keyword=DEFPUSHBUTTON --keyword=PUSHBUTTON --keyword=CAPTION \
--language=Tcl -o resources.po project.rc

Sau pe scurt: întrucât sintaxa Tcl e destul de compatibilă cu cea din .RC, folosind keyword-urile respective, obţineţi un parser de .RC în xgettext. Cool?... o să trimit şi un mail ca să modifice să recunoască fişierele rc direct.


Legături

--sorin