是否可以在编译时/运行时生成标记字符串的全局列表?

时间:2009-09-02 18:11:19

标签: c++ static localization internationalization c-preprocessor

所以,我正在努力将我的C ++应用程序翻译成多种语言。我目前正在使用的是:

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

翻译来自CSV文件,该文件将英文字符串映射到翻译后的字符串。

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

这是简化的,但这是基本的想法。

我的问题是关于生成需要翻译的英语短语列表。我只需要包含所有英语短语和空白翻译短语的CSV。我希望可以在编译时或运行时生成此列表。在编译时我正在考虑这样的事情:

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

然后可能会解析编译日志或其他东西。这似乎不太好用。

在运行时也会很棒。我正在考虑启动应用程序并使用隐藏的命令来转储英文CSV。我已经看到类似的方法用于使用全局变量向中央列表注册命令。它可能看起来像这样:

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 ));

我知道上面的代码存在两个问题。我怀疑它是否编译,但更重要的是,为了生成所有英语短语的列表,我需要在访问sEnglishPhrases之前点击每个代码路径。

看起来我最终会编写一个小的解析器来读取我的所有代码并查找TR字符串,这并不是那么难。我只是希望学习更多关于C ++的知识,如果有更好的方法可以做到这一点。

3 个答案:

答案 0 :(得分:2)

您可以构建一个快速脚本来解析文件并删除所需内容。

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

如果你需要稍微复杂的东西,那么perl就是你的朋友。

答案 1 :(得分:1)

我想你差不多了。采取最后的想法:

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;

正如您所说,您确实需要在每个TR()语句上运行代码,但您可以配置单元测试框架来执行此操作。

我的另一种方法是使用上面的TrString类为每个模块创建静态变量:

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

现在你只需要链接另一个main()来打印掉TrString :: sEnglishPhrases

答案 2 :(得分:0)

您正在寻找的内容与GNU gettext的内容非常相似。请特别注意xgettext工具。