确保每个字符串文字都包含在宏中
Posted
技术标签:
【中文标题】确保每个字符串文字都包含在宏中【英文标题】:Ensure every string literal is wrapped inside macro 【发布时间】:2019-02-25 13:53:07 【问题描述】:我想用一个宏来包装我项目中的每个字符串文字。我想确保我的项目中的每个字符串文字都用一个宏包装,并有一些外部工具帮助我找到没有用宏包装的字符串文字的位置。
有什么方法可以使用 Clang 插件来?
我要处理的案例:
#define MY_ASSERT(Y) if(!(Y)) throw Exception(#Y);
#Y 应该被警告为未包装的字符串文字。
"a" "b" "c"
它要求整个东西都在一个宏中,像这样:
MY_STR("a" "b" "c")
我如何使用 Clang 插件来做到这一点,或者一般有其他方法吗?
【问题讨论】:
我想用宏来包装我项目中的每个字符串字面量——我只是好奇:为什么? @Swordfish - 嗯,一个突然想到的原因***.com/questions/15498070/… @Swordfish 我希望能够用各种语言的翻译替换一些字符串。发现用有时会翻译的宏包装每个字符串要容易得多,有时会帮助我们提供项目中需要翻译的已使用字符串的列表。 使用国际化框架??例如 Boost.Locale。 AFAIK 即使你使用 Boost.Locale 你仍然需要调用一个函数,字符串不会神奇地翻译。我希望每个字符串都被翻译,没有例外。 ?? 【参考方案1】:您可以使用 DMS Software Reengineering Toolkit 及其 C++ 前端来做到这一点。
DMS 可以根据 C++ 的显式语法定义读取源代码(在 GCC 和 MS 方言中处理 C++17),构建 AST,应用提供的重写规则来修改树,然后将 AST 漂亮地打印回源代码文本、保留 cmets、文本对齐、数字基数等。
为此,您只需要一条 DMS 规则(详情请参阅DMS Rewrite Rules):
rule wrap_string_in_macro(s:string_literal):primary_expression->primary_expression
= "\s" -> " my_macro_name(\s) ";
非终结符 string_literal 涵盖了各种各样的 C++ 字符串(8bit、ISO、wide、raw、字符串序列……),因此您不必担心它们,这条规则会接他们。但是您的宏可能需要担心这些。因此,您可以编写一组更大的规则,这样您就可以专门化宏调用:
rule wrap_ISO_string_in_macro(s:ISO_STRING_LITERAL):primary_expression->primary_expression
= "\s" -> " my_macro_name_for_ISO_string(\s) ";
rule wrap_ISO_string_in_macro(s:WIDE_STRING_LITERAL):primary_expression->primary_expression
= "\s" -> " my_macro_name_for_wide_string(\s) ";
...
这些规则会提取单个字符串,但这会留下处理字符串序列的问题:
rule wrap_ISO_string_list_in_macro(seq: string_literal_list,s:ISO_STRING_LITERAL):primary_expression->primary_expression
= " \string_literal_list \s" -> " my_macro_name_for_ISO_string_list(\s) ";
...
【讨论】:
开始相信没有人会回答这个问题。非常感谢!我会告诉你这是否有效:)以上是关于确保每个字符串文字都包含在宏中的主要内容,如果未能解决你的问题,请参考以下文章