前: Quadrigraphs, 上: M4 Quotation


8.1.6 引用符の経験則

終りに引用符の経験則を述べます.

カッコの組ごとに引用符の組

特にマクロ定義では,多過ぎる引用符もだめ,少な過ぎる引用符も駄目です.カッ コを使用する必要があるマクロ(通常Cのプログラム文や正規表現の中)では,適 切に引数を引用符で囲んでください!

以下のような断片を用いたAutoconfプログラムを読むことはよくあります.

     AC_TRY_LINK(
     changequote(<<, >>)dnl
     <<#include <time.h>
     #ifndef tzname /* For SGI.  */
     extern char *tzname[]; /* RS6000 and others reject char **tzname.  */
     #endif>>,
     changequote([, ])dnl
     [atoi (*tzname);], ac_cv_var_tzname=yes, ac_cv_var_tzname=no)

それは,AC_TRY_LINKすでに二重に引用符で囲まれているので, 全く無駄になり,実際は以下のようにするだけで十分です.

     AC_TRY_LINK(
     [#include <time.h>
     #ifndef tzname /* For SGI.  */
     extern char *tzname[]; /* RS6000 and others reject char **tzname.  */
     #endif],
                 [atoi (*tzname);],
                 [ac_cv_var_tzname=yes],
                 [ac_cv_var_tzname=no])

M4に親しんでいる読者は,M4が引数をまとめる(collect)ときに `changequote(<<, >>)'と`<<' `>>'の両方を飲み込むので,こ れら二つの例が厳密に等価であることに注意してください.これらの引用符は引 数の一部ではありません!

単純にしてみると,上記の例は以下のようになります.

     changequote(<<, >>)dnl
     <<[]>>
     changequote([, ])dnl

その代わりに単純に以下のようにします.

     [[]]

引数を(規則で)二重に引用符で囲まないマクロを用いると,二重の引用は(危険 な)文字列になります.

     AC_LINK_IFELSE([AC_LANG_PROGRAM(
     [[#include <time.h>
     #ifndef tzname /* For SGI.  */
     extern char *tzname[]; /* RS6000 and others reject char **tzname.  */
     #endif]],
                                     [atoi (*tzname);])],
                    [ac_cv_var_tzname=yes],
                    [ac_cv_var_tzname=no])

引用符が十分でない状況で望みがなくなった場合どうすればいいかということに ついては,See Quadrigraphs.

新たに書かれたマクロを用いてconfigureスクリプトを作成するとき, マクロにより多くの引用符を加える必要があるかどうかの調査は,気を付けて吟 味してください.一つ以上の単語がM4の出力に現れない場合,より多くの引用符 が必要になります.迷ったときは引用符です.

しかし,引用符のレイヤーが多過ぎる可能性もあります.この場合は,結果とし て得られるconfigureスクリプトは,展開されていないマクロが含ま れているでしょう.autoconfプログラムは,`grep AC_ configure'を行なうことでこの問題を調査します.