Pregunta

Quiero localizar un programa que ya escribí. Es bastante grande (casi 50,000 líneas) e idealmente quiero un sistema que me permita (al programador) hacer la menor cantidad de trabajo posible, y sin cambios importantes en el programa - si es posible ninguno en absoluto.

Miré gettext () y me gustó mucho, pero no me queda claro cómo traduciría cadenas como estas:

const char *Colors[] = {
 { "Red" },
 { "Blue" },
 { "Yellow" },
 ....
};

que son MUY comunes en mi programa. Aquí se reemplaza " Rojo " con gettext (" Rojo ") obviamente no funcionaría.

Entonces pensé que haría algo como OutputFunction (gettext (Colors [Id])), pero entonces ¿cómo puedo obtener una lista de cadenas para localizar? Dudo que algún programa sea lo suficientemente inteligente como para poder obtener '' Rojo '', '' Azul '', '' Amarillo '' de eso en una lista para localizar estáticamente.

Dado que es básicamente un servidor, no es necesario cambiar el idioma sin volver a compilar (puedo compilarlo para cada idioma compatible sin ningún problema o molestia importante), pensé en el constexpr de C ++ 0x, que sería ¡Perfecto! Funcionaría en matrices / etc. y obtendría fácilmente una lista de cadenas para localizar en el momento de la compilación. Lástima que ningún compilador lo haya implementado todavía.

Cambiar todas las cadenas a una ID no es una opción, ya que requeriría una gran cantidad de trabajo de mi parte y especialmente crear una nueva identificación para cada nueva cadena sería muy molesto. Lo mismo se aplica a la conversión de todos los arreglos como el anterior a otra cosa.

Entonces, ¿alguna idea? : /

¿Fue útil?

Solución 2

Después de mucho jugar con gettext () y xgettext, creo que encontré una manera (perdón por uno pero no me gustó su enfoque ... Debe haber cientos de matrices como esa y tendría que importar todas de ellos en main (), eso es mucho trabajo externo y mucho trabajo adicional: /).

De todos modos, así es como creo que teóricamente se puede hacer (todavía no he intentado traducir, pero no veo por qué no funcionaría)

Dos # define:

#define _ gettext
#define __(x) x

Luego usa _ para traducir realmente y __ para simplemente marcar cadenas como " para traducir " ;:

const char *Colors[] = {
 { __("Red") },
 { __("Blue") },
 { __("Yellow") },
 ....
};

void PrintColor(int id) {
    cout << _("The color is: ") << _(Colors[id]);
}

Luego ejecutas:

xgettext -k_ -k__ *.cpp

Y obtienes el siguiente archivo .po:

#: test.cpp:2
msgid "Red"
msgstr ""

#: test.cpp:3
msgid "Blue"
msgstr ""

#: test.cpp:4
msgid "Yellow"
msgstr ""

#: test.cpp:9
msgid "The color is: "
msgstr ""

Entonces, usas __ (o cualquier otro nombre, realmente no importa) como una "función ficticia" para dejar que xgettext sepa que la cadena necesita ser traducida y _ para llamar realmente a gettext ().

Si llama a _ con una cadena, la cadena también se marcará como traducida, si la llama con una variable, matriz, lo que sea que parezca simplemente ignorado por xgettext.

¡Genial! Ahora todo lo que tengo que hacer es revisar 5 billones de archivos y agregar guiones bajos, como si fuera un mono: /

Otros consejos

Para su ejemplo específico, podría intentar algo como:

// presumably globals
const char *Colors_en[] = {
 { "Red" },
 { "Blue" },
 { "Yellow" },
 ....
};
const char *Colors[] = {0};

// in main()
gettextarray(Colors_en, Colors, sizeof(Colors_en) / sizeof(char*));

gettextarray llama a gettext en cada entrada y escribe una salida. Creo que podría implementarse solo como una llamada a std :: transform. Y podría evitar el parámetro de tamaño con un poco de truco de plantilla.

Otra opción es llamar a gettext en el punto donde cualquiera de las cadenas de color está a punto de usarse (mostrarse o agregarse a una cadena para su visualización). Eso significa cambiar más código, pero no requiere que main () traduzca cada conjunto de cadenas en el programa antes de hacer cualquier cosa que pueda usarlas.

Si no quieres hacer el trabajo en main, puedes hacerlo en el código que usa las cadenas, algo como esto:

if (Colors[0] == 0)
  gettextarray(Colors_en, Colors, sizeof(Colors_en) / sizeof(char*));

O si su aplicación es multiproceso, considere pthread_once o el equivalente en la API de hilo que utiliza.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top