如何从boost :: wave获取完整的,扩展的,字符串化的宏?

时间:2015-12-25 06:53:46

标签: c++ boost c-preprocessor

我有一个包含以下内容的文件:

#define str(s) s
#define xstr(s) #s
#define foo 4
#define first str(foo)
#define second xstr(foo)

当我将其传递给boost :: wave时,macromap包含以下内容:

first=str(foo)
foo=4
second=xstr(foo)
str(s)=#s
xstr(s)=str(s)

如何让宏完全展开,以便:

first="foo"
second=4

我认为boost :: wave支持宏重新扫描和查找。我有什么遗漏,或者我是否需要对处理挂钩做些什么才能实现扩展?我的意思是,我可以编写代码来下降树,但如果我在没有重要的东西的情况下不做这项工作,那肯定会很好。

1 个答案:

答案 0 :(得分:0)

从上午开始的线索很重要。无论何时都可以定义和定义宏,因此它只是相关的使用实例。

这比我预期的要容易得多。如果我在头文件中有这样的东西:

#define str(s) #s
#define xstr(s) str(s)
...
#define MAJORVER 1
#define MINORVER 0
#define MAJORBUILD 0
#define MINORBUILD 1
#define FULLBUILDSTRING xstr(MAJORVER) "." \
                        xstr(MINORVER) "." \
                        xstr(MAJORBUILD) "." \
                        xstr(MINORBUILD)

FULLBUILDSTRING宏将评估为声明的字符串。但是,如果我有一些代码直接使用宏,例如在

static char const full_build_string[] = FULLBUILDSTRING;

当Wave处理它时,它将评估以下内容:

static char const full_build_string = "1" "." "0" "." "0" "." "1";

如果您需要在处理完成后查看宏的定义方式,您可以随时执行以下操作(这取自Wave驱动程序代码):

auto end = ctx.macro_names_end();
for (auto it = ctx.macro_names_begin(); it != end; ++it) {
   typedef std::vector<context_type::token_type> parameters_type;
   bool has_pars = false;
   bool predef = false;
   context_type::position_type pos;
   parameters_type pars;
   context_type::token_sequence_type def;
   if (ctx.get_macro_definition(*it, has_pars, predef, pos, pars, def)) {
      // if has_pars is true, you can iterate through pars to see 
      // parameters for function macros
      // iterate through def to see the macro definition
   }
}

当然,宏以非扩展形式存储。

(当然,如果你写了一个答案,我会接受它)