0

GNU M4 で、渡された空でない ( と等しくない引数) の数を決定する関数を作成しようとしまし`'た。

次のように呼び出し可能であるはずです:

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。マクロの一部を抽象化するいくつかの異なる方法を試した後、あきらめる準備ができています。

4

1 に答える 1

1

上書きしようとするべきではないと思います$@。警告から、$2 を上書きしてもまったく影響がないことがわかります$@。ドキュメントの結合の例では、代わりに次のように 2 番目の引数をシフトアウトしています。

`$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 つの引数の呼び出しを個別にチェックする必要はありません。DRYness が気になる場合は、これを改善する必要があるかもしれません。)

于 2014-12-30T16:13:19.823 に答える