2007年4月7日土曜日

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を行う。
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')
このマクロの実行結果は以下のようになる。
user@local:~/m4test$ m4 test2.m4

not defined

m4_include(aaa)
already defined
already defined
結果からするとdefineやif_defの引数内ではクォートすれば、"()"つきのマクロ名の定義は可能であるようだ。
しかし、定義した後でもm4_include(aaa)がそのまま出力されていることから、マクロとして展開できていない。通常通りm4_includeがマクロ名、aaaが引数と解釈されている。
フラグとしてのみ使うので、展開できないマクロ名を使っているのだと思われる。

■ 参考資料

GNU macro processor: GNU macro processor

0 件のコメント: