M4 括弧つきマクロ
autoconfのm4ライブラリをちょっとのぞいていたら、よくわからないところがあった。
以下は/usr/share/autoconf/m4sugar/m4sugar.m4よりの抜粋。
# m4_include_unique(FILE)
# -----------------------
# Declare that the FILE was loading; and warn if it has already
# been included.
m4_define([m4_include_unique],
[m4_ifdef([m4_include($1)],
[m4_warn([syntax], [file `$1' included several times])])dnl
m4_define([m4_include($1)])])
# m4_include(FILE)
# ----------------
# As the builtin include, but warns against multiple inclusions.
m4_define([m4_include],
[m4_include_unique([$1])dnl
m4_builtin([include], [$1])])
m4_include_uniqueとm4_includeという二つのマクロを定義している。m4_include_uniqueは複数回includeされているかチェックを行い、m4_includeはm4_include_uniqueで複数includeのチェックしてからincludeを行う。# -----------------------
# Declare that the FILE was loading; and warn if it has already
# been included.
m4_define([m4_include_unique],
[m4_ifdef([m4_include($1)],
[m4_warn([syntax], [file `$1' included several times])])dnl
m4_define([m4_include($1)])])
# m4_include(FILE)
# ----------------
# As the builtin include, but warns against multiple inclusions.
m4_define([m4_include],
[m4_include_unique([$1])dnl
m4_builtin([include], [$1])])
m4_include_unique内の2行目と4行目に[m4_include($1)]という記述がある。[]はリテラル文字であり、これら2行は要はm4_include($1)という名前のマクロの存在チェックと定義を行っている。
m4のマニュアルによるとマクロ名に使えるのは、アルファベット、数字、_(アンダースコア) を自由に並べたもののうち、先頭の文字が数字でないものとなっており、"()"は許されていない。普通"("以下は引数とみなされる。 どんな動作なのかその部分だけ抜き出して、テストしてみた。
user@local:~/m4test$ less test2.m4
define(`m4_include_unique', `ifdef(`m4_include($1)', `already defined',
`not defined
define(`m4_include($1)', `include $1')')')
m4_include_unique(`aaa')
m4_include(aaa)
m4_include_unique(`aaa')
ifdef(`m4_include(aaa)', `already defined', `not defined')
このマクロの実行結果は以下のようになる。
define(`m4_include_unique', `ifdef(`m4_include($1)', `already defined',
`not defined
define(`m4_include($1)', `include $1')')')
m4_include_unique(`aaa')
m4_include(aaa)
m4_include_unique(`aaa')
ifdef(`m4_include(aaa)', `already defined', `not defined')
user@local:~/m4test$ m4 test2.m4
not defined
m4_include(aaa)
already defined
already defined
結果からするとdefineやif_defの引数内ではクォートすれば、"()"つきのマクロ名の定義は可能であるようだ。not defined
m4_include(aaa)
already defined
already defined
しかし、定義した後でもm4_include(aaa)がそのまま出力されていることから、マクロとして展開できていない。通常通りm4_includeがマクロ名、aaaが引数と解釈されている。
フラグとしてのみ使うので、展開できないマクロ名を使っているのだと思われる。
0 件のコメント:
コメントを投稿