在GNU M4中,我一直在尝试编写一个函数来确定传递给它的非空(不等于`'
的args)。
它应该像这样可以调用:
ne_nargs(0, `1', `')
# 1
ne_nargs(0, `')
# 0
ne_nargs(0, `1')
# 1
请注意,第一个参数应始终为0
。
这是我到目前为止的代码:
define(`ne_nargs', `ifelse(`$#', `1`, $1,
`ifelse(`$2', `', `pushdef(`$2', $1)ne_nargs(shift($@))',
`pushdef(`$2', incr($1))ne_nargs(shift($@))')')')
这里是伪代码:
if (number_of_args == 1); then
return first_arg; // which is `0` by default.
else if (second_arg == ''); then
second_arg = first_arg;
return ne_nargs(shift(all_args));
else
second_arg = (++first_arg);
return ne_nargs(shift(all_args));
ne_nargs(`0', `', `1', `i', `', `l')
# what I get
m4:test.m4:8: empty string treated as 0 in builtin `incr'
m4:test.m4:8: empty string treated as 0 in builtin `incr'
1
# what I expect
3
我无法弄清楚我在ne_nargs
的定义中做错了什么,在尝试了几种不同的方法来抽象部分宏之后,我就准备好了放弃。
答案 0 :(得分:1)
我认为你不应该试图覆盖$@
;你可以从警告中看到,覆盖$ 2肯定不会影响$@
。文档中的join example改为将第二个参数移出:
`$0(`$1', shift(shift($@)))'
以下是有效的:
define(`ne_nargs', `ifelse(`$#', `2', `ifelse(`$2', `', `$1', incr(`$1'))',
`ifelse(`$2', `', `$0(`$1', shift(shift($@)))',
`$0(incr($1), shift(shift($@)))')')')
ne_nargs(`0', `', `1', `i', `', `l')
(我不知道清理递归调用的好方法,因此不必独立检查2参数调用,因此如果您担心干燥,可能需要改进。)