使用m4预处理器一次检查多个条件

时间:2015-09-15 16:00:54

标签: preprocessor m4

有没有m4语法等同于这个C预处理器?

#if defined A || defined B
do something
#endif

1 个答案:

答案 0 :(得分:1)

简短的回答是否定的。

答案很长:

检查是否定义了宏

define(`defined', `ifelse($1()$1, `$1()$1', ``0'', ``1'')')

ifelse(eval(defined(`A') || defined(`B')),
       1,
       ``At least one is defined'',
       ``Neither are defined'')

没有合理的方法来检查m4中定义的宏,所以你不得不求助于上面的黑客攻击。

工作原理

ifelse检查两个字符串是否相等。在defined宏中,我将$1中的宏扩展了两次(一次为$1(),一次为$1)。我将它与$1()$1作为字符串进行比较,因此如果它不扩展则会比较true。以两种不同方式指定宏的原因是因为A可以定义为``A''``A()'',否则在使用此方法检查是否定义时会导致漏报

然后我使用defined中的eval宏将||逻辑放在最前面。

注意事项

  • 如果您已在文档中使用defined一词,则可能需要为宏指定一个不同的名称。
  • defined无法在定义的宏上运行,以扩展为不引用的句法标记,如(,)。< / LI>
  • 如果要检查的宏是无限递归的,defined检查也将永远不会返回。 (基本上,要意识到像这样的黑客仍在实际执行宏。)

虽然最后2点有一些你期望从任何ifelse检查宏的东西,但是从一个声称检查是否定义了另一个宏的宏来预期它可能并不直观。

更好的方法

我宁愿建议您首先使用某个默认值定义变量,并且只是避免检查是否已定义它的问题。

这样做容易得多:

# Define this right off the bat:
define(`A', ``0'')

# Maybe later this line will come up...
# Quotes around the A are mandatory
define(`A', ``1'')

# Then soon after that, you can check:
ifelse(A, `0', , ``hey, A is nonzero!'')