Ejemplo completo de C++ i18n gettext() "hola mundo"
linux internationalization (3)
Estoy buscando un ejemplo completo de i18n gettext()
hello world. Comencé un script basado en Un tutorial sobre soporte de idioma nativo usando GNU gettext por G. Mohanty. Estoy usando Linux y G ++.
Código:
cat >hellogt.cxx <<EOF
// hellogt.cxx
#include <libintl.h>
#include <locale.h>
#include <iostream>
#include <cstdlib>
int main (){
char* cwd = getenv("PWD");
std::cout << "getenv(PWD): " << (cwd?cwd:"NULL") << std::endl;
char* l = getenv("LANG");
std::cout << "getenv(LANG): " << (l?l:"NULL") << std::endl;
char* s = setlocale(LC_ALL, "");
std::cout << "setlocale(): " << (s?s:"NULL") << std::endl;
std::cout << "bindtextdomain(): " << bindtextdomain("hellogt", cwd) << std::endl;
std::cout << "textdomain(): " << textdomain( "hellogt") << std::endl;
std::cout << gettext("hello, world!") << std::endl;
}
EOF
g++ -ohellogt hellogt.cxx
xgettext -d hellogt -o hellogt.pot hellogt.cxx
msginit --no-translator -l es_MX -o hellogt_spanish.po -i hellogt.pot
sed --in-place hellogt_spanish.po --expression=''/#: /,$ s/""/"hola mundo"/''
sed --in-place hellogt_spanish.po --expression=''s/PACKAGE VERSION/hellogt 1.0/''
mkdir -p ./es_MX/LC_MESSAGES
msgfmt -c -v -o ./es_MX/LC_MESSAGES/hellogt.mo hellogt_spanish.po
export LANG=es_MX
ls -l $PWD/es_MX/LC_MESSAGES/hellogt.mo
./hellogt
strace -e trace=open ./hellogt
El programa compila, el texto se extrae, el archivo en español se crea, se modifica y se crea un binario, pero hellogt aún muestra el inglés. La traza no muestra evidencia de buscar en el directorio de trabajo actual para es_MX ni ninguna referencia al directorio LC_MESSAGES.
Aquí hay una descripción de gettext del Proyecto Fedora. Es fácil de seguir. Pero está en C.
http://fedoraproject.org/wiki/How_to_do_I18N_through_gettext
Su problema es que hellogt.mo
está en la ubicación incorrecta; su programa no lo está abriendo. Puedes decir esto usando strace
para rastrear syscalls open
:
strace -e trace=open ./hellogt
...
open("/tmp/.//es_MX/LC_MESSAGES/hellogt.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/tmp/.//es/LC_MESSAGES/hellogt.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
Puede afectar el lugar donde Gettext busca los catálogos de mensajes con la variable de entorno LOCPATH
, pero si lo mueve a donde Gettext intenta cargarlo desde su trabajo de ejemplo:
mkdir -p es/LC_MESSAGES
cp hellogt.mo es/LC_MESSAGES
./hellogt
hola mundo
cat >hellogt.cxx <<EOF
// hellogt.cxx
#include <libintl.h>
#include <locale.h>
#include <iostream>
int main (){
setlocale(LC_ALL, "");
bindtextdomain("hellogt", ".");
textdomain( "hellogt");
std::cout << gettext("hello, world!") << std::endl;
}
EOF
g++ -o hellogt hellogt.cxx
xgettext --package-name hellogt --package-version 1.2 --default-domain hellogt --output hellogt.pot hellogt.cxx
msginit --no-translator --locale es_MX --output-file hellogt_spanish.po --input hellogt.pot
sed --in-place hellogt_spanish.po --expression=''/"hello, world!"/,/#: / s/""/"hola mundo"/''
mkdir --parents ./es_MX.utf8/LC_MESSAGES
msgfmt --check --verbose --output-file ./es_MX.utf8/LC_MESSAGES/hellogt.mo hellogt_spanish.po
LANGUAGE=es_MX.utf8 ./hellogt
Aquí está una descripción de los archivos creados por el anterior:
hellogt.cxx C++ source file
hellogt Executable image
hellogt.pot Extracted text from C++ source file (portable object template)
hellogt_spanish.po Modified text for Spanish with translations added (using sed)
es_MX.utf8/
LC_MESSAGES/
hellogt.mo Binary translated text for Spanish used at run-time