[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

8. M4でのプログラミング

Autoconfは,二つのレイヤーのトップに書かれています.それは,純粋なM4プロ グラムで便利なマクロを提供しているM4sugarと,シェルスクリプトの生 成に専念するマクロを提供するM4shです.

このバージョンのAutoconfでは,二つのレイヤーはまだ実験段階で,そのインター フェースは将来変更される可能性があります.実際問題,文章化されてい ないものは使用しないでください


8.1 M4の引用符

既存のマクロの最も一般的な問題は,不適当な引用符です.このセクションでは, Autoconfのユーザは飛ばすことができますが,マクロを書く人は読む必要 があり,最初にAutoconfで採択された引用符を利用する方法を正当化し,最後 に経験則を述べます.前者を理解すると後者で役立ちます.


8.1.1 アクティブな文字

適切な引用符の重要性を完全に理解するため,最初にAutoconfでの特殊な文字が 何かを知る必要があります.`#'はマクロ展開が実行されない内部コメント の導入で,`,'は引数のセパレータ,`['と`]'はそれらの引用符, そして最後は,(M4が対の一致を試みる)`('と`)'です.

マクロ呼び出しの微妙な状況を理解するために,最初に明らかな失敗を紹介しな ければならないでしょう.以下で"明確にされ"ていて,実生活でも見つかるで しょうが,それらは通常ごまかしです.

ハッシュと改行まで実行することで導入されるコメントは,トップレベルへの不 明瞭なトークンです.アクティブな文字はそうではなくなり,マクロの展開もあ りません.

 
# define([def], ine)
⇒# define([def], ine)

マクロの展開があるごとに,引用符も展開されます.すなわち,第一レベルの引 用符は削除されます.

 
int tab[10];
⇒int tab10;
[int tab[10];]
⇒int tab[10];

これを覚えていなければ,読者は絶望しながらもマクロのarrayを使用し てみるでしょう.

 
define([array], [int tab[10];])
array
⇒int tab10;
[array]
⇒array

期待する結果を正しく出力するにはどうすれば良いでしょうか (3)


8.1.2 一つのマクロの呼び出し

さて,アクティブな文字と以下の単に最初の引数を返す小さなマクロを用いたマ クロで,対話的に進めていきましょう.

 
define([car], [$1])

上記の二組の引用符はdefineの引数の一部ではありません.そうではな く,defineの引数の検索が試みられるときに,それらはトップレベルで 理解されます.そのため,それは以下のように書くことと等価です.

 
define(car, $1)

しかし,`configure.ac'が不必要な引用符を避けることは受け入れてもか まいませんが,より強固で,完全な形式を提案する必要もあるAutoconfマクロに とっては悪い慣習です.

トップレベルでは,二つの可能性があります.引用符で囲む,または囲まないで の二つです.

 
car(foo, bar, baz)
⇒foo
[car(foo, bar, baz)]
⇒car(foo, bar, baz)

特殊文字に注目してみましょう.

 
car(#)
error-->EOF in argument list

閉じカッコはコメント内に隠れてしまいます.引用符を推測することで,トップ レベルでは以下のように理解します.

 
car([#)]

適切な引用符は,もちろんこの問題を修正します.

 
car([#])
⇒#

読者は,以下の例の方が理解しやすいかもしれません.

 
car(foo, bar)
⇒foo
car([foo, bar])
⇒foo, bar
car((foo, bar))
⇒(foo, bar)
car([(foo], [bar)])
⇒(foo
car([], [])
⇒
car([[]], [[]])
⇒[]

これを覚えていると,マクロがマクロを呼び出し,マクロがマクロを呼び出し …となっているような状況も調査することが可能です.


8.1.3 引用符と入れ子状のマクロ

これ以降の例では,以下のマクロを使用しています.

 
define([car], [$1])
define([active], [ACT, IVE])
define([array], [int tab[10]])

追加の埋め込まれたマクロ呼び出しは,それぞれ興味深い引用符について,その 他の可能性を導き出します.

 
car(active)
⇒ACT
car([active])
⇒ACT, IVE
car([[active]])
⇒active

最初の状況では,トップレベルではcarの引数を探し,`active' が 見つかります.M4はマクロを適用する前のその引数と等価なので, `active'は展開され,結果として以下のようになります.

 
car(ACT, IVE)
⇒ACT

二番目の状況では,トップレベルはcarの最初で唯一の引数として `active'を与えるので,結果として以下のようになります.

 
active
⇒ACT, IVE

すなわち,マクロが呼び出された後で,引数が評価されます.三番目の 状況では,carは`[active]'を受けとり,結果として以下のように なります.

 
[active]
⇒active

上記で見たものと同じですね.

より現実的な例を適用して,上記の例に与えてみましょう.

 
car(int tab[10];)
⇒int tab10;
car([int tab[10];])
⇒int tab10;
car([[int tab[10];]])
⇒int tab[10];

う〜ん? 最初の状況は簡単に理解できますが,なぜ二番目が間違っていて,三 番目は正しいのでしょうか?それを理解するために,M4がマクロを展開した後, 結果として生じるテキストがすぐにマクロを展開に従って引用符が取り除かれる ことを知っておく必要があります.これは,引用符の削除が二回行なわれること を意味します -- 最初に引数としてcarマクロに渡されるとき,二回目 はcarマクロが最初の引数を展開するときです.

Autoconfマクロcarの作者として,ユーザがcarの引数を二重の引 用符にする必要があることは間違っていると考えるようにし,マクロを修 正してください.引用符で囲まれているcarに対して,それを qarと呼ぶことにしましょう.

 
define([qar], [[$1]])

そして,qarが適切に修正されていることを調査してみます.

 
qar([int tab[10];])
⇒int tab[10];

あぁ!そうした方が良さそうですね.

しかし,自分が行なったことに注意してください.現在その引数はリテラル文字 列ですが,引数を展開した結果をユーザが使用したい場合,引用符で囲ま れていないマクロを使用する必要があります.

 
qar(active)
⇒ACT

carを用いて行なっていたことを再生成したい状況を考えます.

 
car([active])
⇒ACT, IVE

まだ駄目ですね.cppマクロの組を生成するマクロを使用したい状況を考 えてみましょう.

 
define([my_includes], [#include <stdio.h>])
car([my_includes])
⇒#include <stdio.h>
qar(my_includes)
error-->EOF in argument list

このマクロqarは,引数を二重に引用符で囲むので,ユーザはマクロの呼 び出しを引用符で囲まないままにしておくよう強制されるので,それは危険です. カンマとその他のアクティブなシンボルは,マクロに渡される前にM4で解釈され, それはユーザが期待している手法ではないことが多いものです.また, qarは,他のマクロとは異なる動作をするので,Autoconfでは避けるべき 例外になります.


8.1.4 changequoteの弊害

特に夜も遅くなると,適切な引用符をバイパスする誘惑が大きくなることも多い ものです.そして,経験豊富なAutoconfのハッカーの多くは,最終的に暗黒の力 に支配され,最終兵器を持ち出します.それはchangequoteです.

M4組み込みのchangequoteは,言語の構文を必要に応じて調整することを 可能にするプリミティブの組に属しています.例えば,M4では引用符としてデフォ ルトで``'と`''を使用しますが,シェルプログラムの文脈(そして, ほとんどの実際のプログラミング言語)では,それは利用可能なものの中での最 悪の選択です.シェルコードでの(`'this''と``that`' のような)文 字列とバッククオートされた式と,通常のプログラミング言語で使用される (`'0''のような)リテラル文字のため,多くの対にならない``'と `''が存在します.そのような文脈での厳密なM4の引用符が(変更)不可能な 場合は,悪夢になります.そのような文脈でM4を役立たせるため,それを設計し た人は別の引用符の組の選択を可能にするchangequoteを装備しました. M4sugar,M4sh,Autoconf,そしてAutotestでは,すべてのものが`['と `]'の使用を選択しています.それらが滅多に使用されない文字という理由 だけでなく,対にならないことも滅多に無い文字という理由もあります

構文形式がコメントだということを指定するため(M4がHTMLページを生成するた めに使用されるとき,`changecom(<!--, -->)'が一般的だと分かるでしょ う)のchangecomと,それ以外の構文の詳細を変更するための changewordchangesyntax(n番目の引数を示す,デフォルトで `$'となっている文字や,引数の周りを囲むカッコなど)のような,それ以 外のマジックプリミティブもあります.

これらのプリミティブは,特定の分野に対してM4がより役に立つようにするため, 本当に意味があるものです.それらはコマンドラインオプションのように考える べきです.それらは,`--quotes',`--comments', `--words',そして--syntaxのようなものです.それにもかかわ らず,M4ライブラリ自身が含まれる(追加のオプションが必要無い)ように,M4の 組み込みとして実装されています.

そこに問題があります....


問題は,M4スクリプトの途中で,その初期化を目的としてそれを使用するときに 発生します.これは,あまり注意していない場合,甚大な影響があるはずです. 実行の途中で言語を変更しているようなものです.構文の変更とそれか らの復帰が十分でないことが多いものです.その間でマクロの呼び出しを行なっ た場合,現在の構文はおそらくマクロを実装していないので,これらのマクロは 失われることになります.


8.1.5 四文字表記

Autoconfマクロを書いているとき,標準的なAutoconfの引用符の規則で表現する ことが難しい,特殊な文字を生成する必要が生じるかもしれません.例えば, `['以外の全ての文字に一致する正規表現`[^[]'を出力する必要があ るかもしれません.この表現は,対称ではないカッコを含んでいるので,M4 マ クロの中に簡単に書き込むことはできません.

以下の四文字表記(quadrigraph)の一つを使用することで,この問題を解 決することが可能です.

` @<:@'

`['

` @:>@'

`]'

` @S|@'

`$'

` @%:@'

`#'

` @&t@'

何にも展開されません.

四文字表記は,m4が実行された後,変換処理の終りの段階で置換され るので,M4の引用符の邪魔になりません.例えば,文字列`[^@<:@]' は, その引用符で囲まれている状態に依存せず,出力では`[^[]'として現れま す.

空の四文字表記を使用することも可能です.

`@&t@'の名前はPaul Eggertの提案です.

私は,`@&t@'の語呂合わせに称賛を与えるべきでしょう.`&'は私 自身の発明ですが,`t'はSteve Bourne(Bourneシェルで有名です)によって 書かれたALGOL68Cコンパイラのソースコードが由来となっていて,そこで は空の文字列を示すために`mt'を使用しています.Cでは,それは以下のよ うなものになるでしょう.

 
char const mt[] = "";

しかし,ソースコードは当然Algol 68で書かれています.

彼が`mt'を得た場所を,私は知りません.それは独自の発明かもしれませ んし,当時のケンブリッジ大学のコンピュータ研究所で,一般的な語呂合わせだっ たのかもしれません.


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 section 四文字表記.

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

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


8.2 autom4teの呼び出し

Autoconf自身のものに加え,M4sugar,M4sh,そしてAutotestを含めた Autoconfスイートは,M4にかなり依存しています.使い方が異なるこれらはす べて,m4の上のレイヤーに集約したいという共通の要求を具体化し ました.それはautom4te(4)です.

autom4teは,m4のようなプリプロセッサです.それは Autoconfのようなツールで使用するために設計された,M4の拡張をサポートして います.


8.2.1 autom4teの呼び出し

コマンドライン引数は,M4のものをモデルにしています.

 
autom4te options files

ここでのfilesは,直接m4に渡すものです.正規の展開に加え, それは四文字表記(see section 四文字表記)と,出力の現在の行の `__oline__'の置換を処理します.それは,filesに対して拡張され た構文もサポートしています.

` file.m4f'

このファイルは,M4を固めたファイルです.以前のファイルはすべて無視 されることに注意してください.正当性については,オプション `--melt'を参照してください.

` file?'

ライブラリパスで見つかった場合,fileは展開に含められ,それ以外では, 異常終了を発生する代わりに無視されます.


もちろん,それはAutoconfの一般的のオプションのサブセットをサポートしてい ます.

` --help'
` -h'

コマンドラインオプションの概要を出力し,終了します.

` --version'
` -V'

Autoconfのバージョンナンバーを出力し,終了します.

` --verbose'
` -v'

処理しているステップを報告します.

` --debug'
` -d'

一時的なファイルを削除せず,さらに冗長になります.

` --include=dir'
` -I dir'

入力ファイルをdirでも探します.複数回の呼び出しは累積されます.

` --output=file'
` -o file'

(スクリプトやトレースの)出力をfileに保存します.ファイル`-' は標準出力を意味します.


m4の拡張として,それらは以下のオプションが含まれます.

` --warnings=category'
` -W category'

(実際にはカンマで分けられたリストになっている)categoryに関連する警 告を報告します.カテゴリの包括的なリストは,マクロAC_DIAGNOSE の See section メッセージの報告. 以下の特殊な値が含まれます.

` all'

すべての警告を報告します.

` none'

何も報告しません.

` error'

警告をエラーとして扱います.

` no-category'

categoryに分類される警告を利用不可能にします.

`syntax'に関する警告は,デフォルトで利用可能で,カテゴリのカンマで 分離されたリストの環境変数WARNINGSは尊重されます. autom4te -W categoryは,実際に悪いことを実行したかのよう に動作します.

 
autom4te --warnings=syntax,$WARNINGS,category

autom4teのデフォルトとWARNINGSを利用不可能にしたいけれ ども,(例えば)時代遅れの構成物に関する警告は利用可能にしたい場合, `-W none,obsolete'を使用するべきでしょう.

autom4teはエラーのバックトレースを表示しますが,警告は表示しま せん.警告も表示したい場合,`-W error'を渡してください.例えば以 下のような`configure.ac'を考えます.

 
AC_DEFUN([INNER],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([exit (0)])])])

AC_DEFUN([OUTER],
[INNER])

AC_INIT
OUTER

以下のようになるでしょう.

 
$ autom4te -l autoconf -Wcross
configure.ac:8: warning: AC_RUN_IFELSE called without default \
to allow cross compiling
$ autom4te -l autoconf -Wcross,error -f
configure.ac:8: error: AC_RUN_IFELSE called without default \
to allow cross compiling
acgeneral.m4:3044: AC_RUN_IFELSE is expanded from...
configure.ac:2: INNER is expanded from...
configure.ac:5: OUTER is expanded from...
configure.ac:8: the top level
` --melt'
` -m'

固められたファイルを使用しません.すべての引数file.m4ffile.m4で置換されます.これは,ファイルが固められているとき だけに実行されるマクロ,通常はm4_defineの追跡で役に立ちます.例え ば以下のように実行します.

 
autom4te --melt 1.m4 2.m4f 3.m4 4.m4f input.m4

これは以下を実行したのと等価です.

 
m4 1.m4 2.m4 3.m4 4.m4 input.m4

一方,以下を実行した場合を考えます.

 
autom4te 1.m4 2.m4f 3.m4 4.m4f input.m4

これは以下と等価です.

 
m4 --reload-state=4.m4f input.m4
` --freeze'
` -f'

固まった状態のファイルを生成します.autom4teの固め方は,M4より 厳密です.警告を生成させたり,空の行(空白行は空の行ではありません) とコメント(`#'で始まります)以外の出力を生成してはいけません. m4とは異なり,このオプションは以下のように引数をとらないことに 注意してください.

 
autom4te 1.m4 2.m4 3.m4 --freeze --output=3.m4f

これは以下に対応します.

 
m4 1.m4 2.m4 3.m4 --freeze-state=3.m4f
` --mode=octal-mode'
` -m octal-mode'

octal-modeにトレース出力以外のモードを設定します.デフォルトは `0666'です.


それ以外のm4上の追加機能として,autom4teがその結果を キャッシュするというものがあります.GNU M4は,標準出力を生成す ると同時にトレースすることが可能です.トレースはGNUビルドシス テムで重点的に使用されています.autoheaderは, `config.h.in'をビルドするために,autoreconfは,使用されて いるGNUビルドシステムの構成要素を決定するために, automakeは`configure.ac'をパースするため等として使用して います.m4の長い実行結果を保存するために,通常の展開を実行して いる間,トレースはキャッシュされます(5).このキャッシュ(実際には複数あ る) は,ディレクトリ`autom4te.cache'に保存されます.いつでも 削除して大丈夫です(特に,理由があればautom4teはそれが捨 てられてしまったと考えます).

` --cache=directory'
` -C directory'

結果をキャッシュするディレクトリの名前を指定します.空の値を渡すことで キャッシュが利用不可能になります.グローバルキャッシュがサポートされると きまで,相対パスで渡してください.

` --no-cache'

結果をキャッシュしません.

` --force'
` -f'

キャッシュが使用されている場合,時代遅れだと考えません(しかし,それはい ずれにせよ更新されます).


トレースはGNUビルドシステムに重きをおいて実装されているので, autom4teは,M4と比較して高度なトレース機能を提供していて,キャッ シュを利用する手助けとなります.

` --trace=macro[:format]'
` -t macro[:format]'

formatによって,macroの呼び出しをトレースします.複数の `--trace'引数は,いくつかのマクロリストを使用するために使用可能で す.単一マクロに対する複数の`--trace'引数は累積されません.その代 わりに,必要な長さのformatにすべきです.

formatは,必要なときは改行を用いていて,特殊なエスケープコードをも 用いている通常の文字列です.デフォルトは`$f:$l:$n:$%'です.以下の特 殊なエスケープ文字が使用可能です.

` $$'

文字`$'.

` $f'

macroが呼び出されているファイル名.

` $l'

macroが呼び出されている行番号.

` $d'

macro呼び出しの深さ.これはM4の技術的な詳細で,特に知りたいとは思 わないでしょう.

` $n'

macroの名前.

` $num'

macro呼び出しのnum番目の引数.

` $@'
` $sep@'
` ${separator}@'

文字sepまたは文字列separatorで分離されている,マクロに渡され ているすべての引数(デフォルトは`,').それぞれの引数は引用符で囲まれ ています.すなわち,角カッコの組で囲まれています.

` $*'
` $sep*'
` ${separator}*'

上と同じですが,引数は引用符で囲まれていません.

` $%'
` $sep%'
` ${separator}%'

上と同じですが,引数は引用符で囲まれておらず,引数内部のすべての改行文字 は取り除かれていて,そして,デフォルトの分離子は`:'です.

エスケープの`$%'は,(`separator'に改行を書き込まない限り)一行 のトレース出力を生成しますが,`$@'と`$*'はそうではありません.

トレースの使用例はSee section configureを作成するためautoconfを使用する.

` --preselect=macro'
` -p macro'

macroのトレースをキャッシュしますが,キャッシュを利用可能にしませ ん.これは特に,将来のCPUサイクルを無駄にしないために重要です.例えば呼 び出し時に,m4の実行でトレースする必要が無いように, autoconfautoheaderautomakeautoreconfなどがトレースするすべてのマクロを前もって選択します. キャッシュは十分です.これは結果として非常に高速になります.


最後に,autom4teAutom4teライブラリ(Autom4te libraries) の概念を導入します.それらは,強力ですが非常にシンプルな機能から成り立っ ています.コマンドライン引数の組み合わせの組です.

` --language=language'
` -l =language'

languageをAutom4teライブラリで使用します.現在の言語は以下のものが 含まれています.

M4sugar

M4sugar出力を作成します.

M4sh

M4shの実行可能なシェルスクリプトを作成します.

Autotest

Autotestの実行可能なテストスイートを作成します.

Autoconf

Autoconfの実行可能なコンフィグレーションスクリプトを作成します.

Autoconf-without-aclocal-m4

`aclocal.m4'を読み込まずに,Autoconfの実行可能なコンフィグレーショ ンスクリプトを作成します.

` --prepend-include=dir'
` -B dir'

検索パスにディレクトリdirを前置します.これは,サードパーティーの マクロの前に,言語指定ファイルを含めるために使用します.

例として,Autoconfがデフォルトの場所`/usr/local'にインストールされ ている場合,`autom4te -l m4sugar foo.m4'を実行することは, `autom4te --prepend-include /usr/local/share/autoconf m4sugar/m4sugar.m4f --warning syntax foo.m4'を実行することと厳密に等価と なります.再帰的な展開も適用します.`autom4te --language m4sh foo.m4'を実行することは,`autom4te --language M4sugar m4sugar/m4sh.m4f foo.m4'と同じで,すなわち,`autom4te --prepend-include /usr/local/share/autoconf m4sugar/m4sugar.m4f m4sugar/m4sh.m4f --mode 777 foo.m4'と同じになります.言語の定義は, `autom4te.cfg'に保存されます.


8.2.2 autom4teのカスタマイズ

`~/.autom4te.cfg' (すなわち,ユーザのホームディレクトリにあるとき) と,`./.autom4te.cfg' (すなわち,autom4teが実行されるディ レクトリにあるとき)で,autom4teをカスタマイズすることが可能で す.順番として,最初に`autom4te.cfg'を読み込み,そして `~/.autom4te.cfg',そして`./.autom4te.cfg',そして最後にコマン ドライン引数を読み込みます.

これらのテキストファイルでは,コメントは#ではじまり,空の行は無視 されます.カスタマイズは,言語ごとを基本に実行され, `begin-language: "language"'と`end-language: "language"'の組みで囲まれます.

言語のカスタマイズとは,現在の言語の定義にオプションを追加すること (see section autom4teの呼び出し)を意味します.オプションと一般的な引数は, `args: arguments'で始まります.argumentsを引用符で囲む ことによって伝統的なシェルの構文を使用してもかまいません.

例として,Autoconfのキャッシュ(`autom4te.cache')を大域的に利用不可 能にするため,以下の行を`~/.autom4te.cfg'に含めます.

## ------------------ ##
## User Preferences.  ##
## ------------------ ##

begin-language: "Autoconf"
args: --no-cache
end-language: "Autoconf"

8.3 M4sugarでのプログラミング

M4自身は非常に小さいけれど十分な,汎用マクロの組を提供しています. M4sugarは,追加の一般的なマクロを導入しています.その名前は,Lars J. Aas によってつくり出されました:"Readability And Greater Understanding Stands 4 M4sugar".


8.3.1 M4マクロの再定義

いくつか例外がありますが,全てのM4ネイティブなマクロは,`m4_'疑似名 前空間に移動されていて,例えば,M4sugarではdefinem4_defineに名前を変えるなどのようになっています.

M4マクロには再定義されているものもあり,ネイティブな同義語とわずかに互換 性がなくなっています.

Macro: dnl

このマクロは,もともとの名前を維持しています.m4_dnlは定義されて いません.

Macro: m4_defn (macro)

M4組み込みのものと比較して,このマクロは,macroが定義されていない 場合は失敗します.m4_undefineを参照してください.

Macro: m4_exit (exit-status)

このマクロはm4exitに対応します.

Macro: m4_if (comment)
Macro: m4_if (string-1, string-2, equal, [not-equal])
Macro: m4_if (string-1, string-2, equal, …)

このマクロはifelseに対応します.

Macro: m4_undefine (macro)

M4組み込みのものとは異なり,このマクロはmacroが定義されていない場 合は失敗します.以下のように使用してください.

 
m4_ifdef([macro], [m4_undefine([macro])])

それで,組み込みのものの動作に復旧します.

Macro: m4_bpatsubst (string, regexp, [replacement])

このマクロはpatsubstに対応します.m4_patsubstの名前は, epatsubstで拡張した正規表現の構文を提供する,GNU M4の最 上位のM4shの将来のバージョンに対して残されています.

Macro: m4_popdef (macro)

M4組み込みのものとは異なり,このマクロはmacroが定義されていない場 合は失敗します.m4_undefineを参照してください.

Macro: m4_bregexp (string, regexp, [replacement])

このマクロはregexpに対応しています.m4_regexpの名前は, eregexpで拡張した正規表現の構文を提供する,GNU M4の最上 位のM4shの将来のバージョンに対して残されています.

Macro: m4_wrap (text)

このマクロはm4wrapに対応しています.

二つの連続して呼び出されるm4_wrapが,そのままトークンとして渡され るという予期しない結果となる危険が無いように,textを`[]' で終 えることが推奨されます.

 
m4_define([foo], [Foo])
m4_define([bar], [Bar])
m4_define([foobar], [FOOBAR])
m4_wrap([bar])
m4_wrap([foo])
⇒FOOBAR

8.3.2 マクロの評価

以下のマクロは,引用符のレベルを追加したり削除したりすることで,評価の順 序全体を制御するものです.それらは,ハードコアなM4プログラマに対して意味 があります.

Macro: m4_dquote (arg1, …)

引用符で囲まれたリストを引用符で囲んだ引数を返します.

Macro: m4_quote (arg1, …)

単一の要素として引数を返し,すなわち,一つの引用符の組でそれらを囲みます.

以下の例は,(i)これらの例を使用していない,(ii)m4_quoteを使用して いる,(iii)m4_dquoteを使用している,といったそれぞれの間の差を強 調することを目的としています.

 
$ cat example.m4
# Overquote, so that quotes are visible.
m4_define([show], [$[]1 = [$1], $[]@ = [$@]])
m4_divert(0)dnl
show(a, b)
show(m4_quote(a, b))
show(m4_dquote(a, b))
$ autom4te -l m4sugar example.m4
$1 = a, $@ = [a],[b]
$1 = a,b, $@ = [a,b]
$1 = [a],[b], $@ = [[a],[b]]

8.3.3 禁止されているパターン

M4sugar提供の目的は,怪しげはパターン,つまり出力に現れるべきではないトー クンを記述しているパターンを定義するためです.例えば,Autoconf `configure'スクリプトに`AC_DEFINE'や`dnl'のようなトークン が含められている場合,おそらく何か問題が発生するでしょう(通常は,余分な 引用符のためにマクロが評価されていないためです).

M4sugarは,`^m4_'と`^dnl$'に一致する全てのトークンを禁止します.

Macro: m4_pattern_forbid (pattern)

出力で見つかる必要のあるpatternにマッチするトークンを宣言しません. コメントは調査されません.これは,例えば,`#include'より後に展開さ れないまま残っているマクロがある場合に問題になるはずです.現在,Autoconf コミュニティでは合意がとおらず,コメント内で指名されているマクロを有効に すべきだと考えている人もいるからです(`#'のコメントは出力を説明する べきで,`dnl'コメントのように入力を説明するのではないため,このドキュ メントの著者には意味がありません).

もちろん,これらの一般的な規則の例外に遭遇する可能性もあり,例えば, `$m4_flags'を参照する必要があるかもしれません.

Macro: m4_pattern_allow (pattern)

patternに一致している全てのトークンが可能で,それには m4_pattern_forbidパターンに一致しているものも含まれます.


8.4 M4shでのプログラミング

M4shは,"mash"と発音し,移植性の高いBourneシェルスクリプトを生成するこ とが狙いです.この名前はLars J. Aasが発明し,Webster's Revised Unabridged Dictionary (1913)にメモがあります.

Mash \Mash\, n. [Akin to G. meisch, maisch, meische, maische, mash, wash, and prob. to AS. miscian to mix. See "Mix".]

  1. 混合成分の塊を,こう解や圧搾でパルプ状に軟らかくして絞った....

  2. 動物に与える粉餌やぬかと水を混ぜたもの.

  3. 混乱.トラブル. [Obs.] -Beau. & Fl.

今しばらくは,広範囲の使用に十分なほど熟していません.

M4shは,実験してみると残念ながら移植性が無い,一般的なシェルの構成に対す る移植性の高い代替物を提供しています.

Macro: AS_DIRNAME (pathname)

POSIXで要求されるアルゴリズムを使用しながら,pathname の ディレクトリ部分を返します.これが返すものと,それがdirnameコ マンドより移植性が高い理由の詳細は,See section 通常のツールの制限.

Macro: AS_IF (test, [RUN-IF-TRUE], [RUN-IF-FALSE])

シェルコードtestを実行します.TESTがゼロのステータスで終了し た場合,シェルコードのRUN-IF-TRUEを実行し,それ以外ではシェルコー ドのRUN-IF-FALSEを実行し,RUN-IF-TRUERUN-IF-FALSEが 空の場合は何もしません.

Macro: AS_MKDIR_P (filename)

間に入る必要なディレクトリを含め,ディレクトリfilenameを作成します. これは`mkdir -p filename'と等価ですが,`-p'オプション が無い古いバージョンのmkdirに移植性を持たせます.

Macro: AS_SET_CATFILE (var, dir, file)

シェル変数vardir/fileに設定しますが,一般的に最適な ものにします(dirfileが`.'のときはfileは絶対パス になるなどです).

c=================================================== Writing Autoconf Macros.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Akihiro Sagawa on June, 15 2005 using texi2html 1.70.