你怎么能为m4宏文件包含一个ifdef后卫呢?

时间:2011-03-17 23:10:36

标签: m4

对于C头文件,您可以防止多次包含头文件,如:

#ifndef MY_FOO_H
#define MY_FOO_H

[...]

#endif

如何在m4中执行相同的操作,以便对同一文件进行多次include()宏调用只会导致内容被包含一次?

具体来说,我想做一个涉及使用宏changequote的ifdef后卫(我不会用dnl来混淆我的代码):

最初,当我执行以下操作时,多个内容仍然会破坏引号:

changequote_file.m4:

ifdef(my_foo_m4,,define(my_foo_m4,1)
changequote([,])
)

changequote_invocation.m4:

include(changequote_file.m4)
After first include invocation:
[I should not have brackets around me]
`I should have normal m4 quotes around me'
include(changequote_file.m4)
After second include invocation:
[I should not have brackets around me]
`I should have normal m4 quotes around me'

m4 changequote_invocation.m4调用产生:

After first include invocation:
I should not have brackets around me
`I should have normal m4 quotes around me'


After second include invocation:
[I should not have brackets around me]
`I should have normal m4 quotes around me'

2 个答案:

答案 0 :(得分:4)

最直接的方式是cpp版本的几乎字面翻译:

ifdef(`my_foo_m4',,`define(`my_foo_m4',1)dnl
(rest of file here)
')dnl

因此,如果定义了my_foo_m4,则文件将扩展为空,否则将评估其内容。

答案 1 :(得分:1)

我认为你的问题实际上有两个问题: - 怎么做 - 为什么它在我的情况下不起作用。

这样做的方式几乎就像你做的那样,但你需要引用一切

ifdef(`my_foo_m4',,`define(`my_foo_m4',1)
  changequote([,])
')

问题是第二次包含文件时,引用已被更改,因此您理论上应该包含以下文件(您已将引用更改为[]所以所有您现在包含的文件应该使用[]不应该使用它们吗?):

ifdef([my_foo_m4],,[define([my_foo_m4],1)
  changequote([[],])
])

但是因此包含与原始报价相同的文件 youw ifdef在符号`my_foo_m4'上(可能无效)而不是my_foo_m4 和其他位

define(`my_foo_m4',1)
  changequote([,])

没有被引用(不在[]之间),因此无论测试结果如何都被评估,这意味着它使用,调用changequote,即它调用

changequote(,)

禁用引用。