C ++: Como localizar um programa já escrito
-
07-07-2019 - |
Pergunta
Eu quero localizar um programa que eu já escrito .. É bastante grande (cerca de 50k linhas) e, idealmente, eu quero um sistema que permite-me (o programador) para fazer o mínimo de trabalho possível, e sem grandes mudanças no programa -. se possível mesmo nenhum
Eu olhei para gettext () e gostei muito, mas não está claro para mim como isso iria traduzir cordas como estas:
const char *Colors[] = {
{ "Red" },
{ "Blue" },
{ "Yellow" },
....
};
que são MUITO comum em meu programa .. Aqui substituindo "Red" com gettext ( "Red") seria, obviamente, não trabalho.
Então, eu pensei que eu faria algo assim, OutputFunction (gettext (cores [ID])), mas, em seguida, como posso obter uma lista de strings para localizar? Duvido que qualquer programa é inteligente o suficiente para ser capaz de obter "Vermelho", "Azul", "Yellow" do que em uma lista para localizar estaticamente.
Uma vez que é basicamente um servidor que não há necessidade para a capacidade de alterar o idioma sem recompilar (I pode compilá-lo para cada idioma suportado sem qualquer grande problema ou aborrecimento), eu pensei sobre constexpr do C ++ 0x, o que seria perfeito! Ele iria trabalhar em matrizes / etc e eu poderia facilmente obter uma lista de strings para localizar em tempo de compilação .. Pena que não compilador implementado ainda.
Alterar todas as cordas para um ID não é uma opção, pois exigiria uma enorme quantidade de trabalho da minha parte e, especialmente, a criação de um novo id para cada nova seqüência seria chato como o inferno. O mesmo se aplica a conversão de todas as matrizes como o descrito acima para outra coisa.
Assim, todas as idéias? : /
Solução 2
Depois de um monte de brincar com gettext () e xgettext Acho que encontrei uma maneira mim mesmo (onebyone desculpe, mas eu não gostava sua abordagem .. Deve haver centenas de matrizes como essa e eu teria que importar todos deles em main (), que é um monte de extern e um monte de trabalho extra: /)
.De qualquer forma, é assim que eu acho que pode, teoricamente, ser feito (eu ainda não tentei realmente traduzir, mas não vejo por que ele não iria funcionar)
Dois # definir de:
#define _ gettext
#define __(x) x
Em seguida, você usar _ para realmente traduzir e __ às cordas Basta marcar como "a ser traduzido":
const char *Colors[] = {
{ __("Red") },
{ __("Blue") },
{ __("Yellow") },
....
};
void PrintColor(int id) {
cout << _("The color is: ") << _(Colors[id]);
}
Em seguida, você executar:
xgettext -k_ -k__ *.cpp
E você obter o seguinte .po arquivo:
#: 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 ""
Assim, você usa __ (ou qualquer outro nome, realmente não importa) como uma "função fictícia" apenas deixar xgettext sabemos que as necessidades de cordas a ser traduzido, e _ para realmente chamar gettext ().
Se você chamar _ com uma corda, em seguida, a string será marcada a-ser-traduzido, bem como, se você chamá-lo com uma variável, array, qualquer que seja, então ele parece ser simplesmente ignorado por xgettext.
Great! Agora tudo o que tenho a fazer é ir através de 5 trilhões de arquivos e adicionar sublinhados ao redor, como se eu fosse um macaco: /
Outras dicas
Para o seu exemplo específico, eu poderia tentar 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*));
chamadas gettextarray gettext em cada entrada e escreve uma saída. Eu acho que poderia ser implementado apenas como uma chamada para std :: transformar. E você poderia evitar o parâmetro de tamanho com um pouco de malandragem modelo.
Outra opção é chamar gettext no ponto onde qualquer um dos textos de cores está prestes a ser utilizado (exibido, ou anexado a uma corda para exibição). Isso significa mudanças mais código, mas não exige que main () traduz cada conjunto de cordas no programa antes de fazer qualquer coisa que possa usá-los.
Se você não quer fazer o trabalho no principal, você poderia fazê-lo no código que usa as cordas, algo como isto:
if (Colors[0] == 0)
gettextarray(Colors_en, Colors, sizeof(Colors_en) / sizeof(char*));
Ou se o seu aplicativo é multithreaded, considere pthread_once
ou o equivalente na API fio que você usa.