背景

背景

背景

我面临以下问题:我坚持m4_include([some/file.m4])在我的configure.ac 文件中使用,其中some/file.m4 然后包含libtoolize 工作所需的模式,如“AC_INIT”和“LT_INIT”。换句话说,我需要 m4 对 configure.ac 进行预处理,然后 libtoollize 将其提供给 sed 来查找这些模式。

我不想生成configure.ac(如果我可以避免的话)。 libtoolize 提供的唯一可以帮助我的钩子是它们查找环境变量 SED 并在找到时使用它而不是 /bin/sed 。

我编写了一个 shell 脚本来分析 sed 参数并将它们传递给真正的 sed。不幸的是,libtoolize 连接 m4local.ac 和 configure.ac 并在某个时刻将其提供给 $SED,因此查找名为“configure.ac”的输入文件失败。尽管如此,在分析传递给 $SED 的参数之后,我可以连接所有输入文件和/或标准输入,因为最终它必须通过从流(标准输入)读取来工作。

剩下的问题

因此,我面临的问题如下:

我的脚本必须从 stdin 读取并写入 stdout,直到遇到类似的行,m4_include([cwm4/configure_ac_top.m4])然后它应该吞下并插入 cwm4/configure_ac_top.m4 的内容,不需要其他 m4 预处理,只需包含即可。事实上,由于 sed 还用于无数其他小事情,因此进行除 m4_include 之外的任何其他预处理都是非常危险的。但是我也需要它是递归的:如果包含的文件包含一行,m4_sinclude([lt_init.m4])那么也需要包含该文件。

我在这个网站上发现了多个问题及其答案,询问如何将一个文件插入另一个文件,但是要插入的文件的文件名是已知的(不是从原始文件中读取的),它不是递归的并且在很多情况下,它不是从标准输入读取(而是从第一个已知的文件名称读取)。

答案1

最后我用m4解决了这个问题。为了使任何可能在这项工作中抛出的“sed”命令,m4 不应该这样做任何事物除了处理 m4_include() 宏之外,尽管一旦这样做,它可能会假设我们实际上正在处理 m4 输入并执行更多操作,例如删除引号,当然还有递归包含等,这是可以的。

因此,我所做的就是用一些魔术字符串 (xyzzy) 替换输入流中所有出现的“m4_”,通过m4_changequote(,)在开头插入 a 将引号更改为无,并将结果通过管道传输到 m4。这保证了 m4 绝对不会对输入执行任何操作。但是,我希望它能够处理m4_include,因此在将其通过管道传输到 m4 之前,我将其替换xyzzyinclude([\1])m4_changequote([,])m4_include([\1])m4_changequote(,)使 m4 使用正确的引用来处理包含的文件。最后, m4 -Psed 再次处理 的输出,将魔术字符串替换回“m4_”。

magic="xyzzy"
cat first.txt | /bin/sed "s/m4_/$magic/g;s/$magic""include(\[\([^]]*\)\])/m4_changequote([,])m4_include(\1)m4_changequote(,)/g;1s/^/m4_changequote(,)/" | m4 -P - | sed "s/$magic/m4_/g"

请注意,魔术字符串的限制是:它不能包含(子字符串)m4_,它不能以下划线或 4_ 开头,也不能以 m 或 m4 结尾。它也不应该以与其开头相同的字符结尾。最后,如果它出现在输入流中,则在将其替换为“m4_”时不应损害脚本的目的。

有以下输入:

A1 m4_dnl Nothing should be changed.
A2 m4___file__
m4_include([second.txt])
A4 m4___line__
A5 [` Unmatched quoting: no problem.

This is second.txt, an m4 file.
The wizard said xyzzy,
and nothing happened.

使用“xyzzy”的“神奇”字符串,我们得到结果:

A1 m4_dnl Nothing should be changed.
A2 m4___file__
This is second.txt, an m4 file.
The wizard said m4_,
and nothing happened.

A4 m4___line__
A5 [` Unmatched quoting: no problem.

对于 libtoolize 来说,使用使用 m4_include 的configure.ac,这就足够了。有关完整的 SED 脚本,请参阅https://github.com/CarloWood/cwm4/blob/master/scripts/SED.sh

编辑:事实证明这还不够;我还必须将 m4 替换为 hackhttps://github.com/CarloWood/cwm4/blob/master/scripts/M4.sh

相关内容