2

Donc, je travaille sur la traduction de mon application C++ en plusieurs langues. Ce que je suis actuellement en utilisant quelque chose comme:Est-il possible de générer une liste globale de chaînes marquées au moment de la compilation/exécution?

#define TR(x) (lookupTranslatedString(currentLocale(), x)) 
wcout << TR(L"This phrase is in English") << endl; 

Les traductions proviennent d'un fichier CSV qui mappe la chaîne anglaise de la chaîne traduite.

"This phrase is in English","Nasa Tagalog itong pagsabi" 

Ceci est simplifié, mais c'est l'idée de base.

Ma question concerne la génération de la liste des phrases en anglais qui doivent être traduites. J'ai juste besoin du CSV avec toutes les phrases anglaises, et des phrases traduites vides. J'espérais qu'il serait possible de générer cette liste à la compilation ou à l'exécution. À compiletime je pensais quelque chose comme ceci:

#define TR(x) \ 
    #warning x \ 
    (lookupTranslatedString(currentLocale(), x)) 

puis parse peut-être le journal de compilation, ou quelque chose. Cela ne semble pas fonctionner si bien.

Au moment de l'exécution serait également génial. Je pensais juste commencer l'application et avoir une commande cachée qui déverserait le CSV anglais. J'ai vu des méthodes similaires utilisées pour enregistrer des commandes avec une liste centrale, en utilisant des variables globales. Cela peut ressembler à ceci:

class TrString 
{ 
public: 
    static std::set<std::wstring> sEnglishPhrases; 
    TrString(std::wstring english_phrase) { sEnglishPhrases.insert(english_phrase); } 
}; 

#define TR(x) do {static TrString trstr(x);} while(false); (lookupTranslatedString(currentLocale(), x)); 

Je sais qu'il y a deux problèmes avec le code ci-dessus. Je doute qu'il compile, mais plus important encore, afin de générer une liste de toutes les phrases en anglais, je devrais frapper chaque chemin de code avant d'accéder à sEnglishPhrases.

Il semblerait que je finirai par écrire un petit analyseur pour lire tout mon code et rechercher des chaînes TR, ce qui n'est pas si difficile. J'espérais juste en apprendre un peu plus sur le C++, et s'il y avait une meilleure façon de le faire.

Répondre

1

Je pense que vous êtes presque là. Prendre la dernière idée:

class TrString 
{ 
public: 
    static std::set<std::string> sEnglishPhrases; 
    std::string phrase; 
    TrString(const std::string& english_phrase):phrase(english_phrase) 
    { sEnglishPhrases.insert(english_phrase); } 
    friend ostream &operator<<(ostream &stream, const TrString& o); 
}; 

ostream &operator<<(ostream &stream, const TrString& o) 
{ 
    stream << lookupTranslatedString(currentLocale(), o.phrase); 
    return stream; 
} 

#define TR(x) (TrString(x)) 
// ... 
std::cout << TR("This phrase is in English") << std::endl; 

Et comme vous le dites, vous avez besoin d'exécuter le code sur chaque instruction TR(), mais vous pouvez configurer un cadre de test unitaire pour le faire.

Mon alternative serait d'utiliser la classe TrString ci-dessus pour faire des variables statiques pour chaque module:

// unnamed namespace gives static instances 
namespace 
{ 
    TrString InEnglish("This phrase is in English"); 
    // ... 
} 

Maintenant, il vous suffit de créer un lien dans une main() alternative à imprimer TrString :: sEnglishPhrases

+0

On dirait qu'il s'agit de la meilleure solution, c'est-à-dire qu'il n'y a pas de solution vraiment propre.Je suppose que cela a du sens, puisque tout le monde que j'ai vu, de gettext à Qt tout simplement mettre en œuvre un petit analyseur. – tfinniga

2

Vous pouvez simplement créer un script rapide pour analyser le fichier et supprimer ce dont vous avez besoin.

awk '/TR\(L"[^"]*")/ {print}' plop.c 

Si vous avez besoin de quelque chose d'un peu plus complexe, perl est votre ami.

+0

Oui, c'est comme ça que je vais finir par le faire. Je me demandais juste s'il y avait un meilleur moyen. – tfinniga

0

Ce que vous cherchez ressemble beaucoup à ce que fait GNU gettext. En particulier, regardez l'outil xgettext.

Questions connexes