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

9. 出力の切替え(divert)と逆切替え(undivert)

出力切替え(diversions)は出力を一時的に保存しておく方法です。 m4では好きなときに出力を一時ファイルへ切替え(divert)ておき、 後で再び出力ストリームへと逆切替え(undiverted)することができます。

切り替え先番号は0から数え上げます。切替え先0は通常の出力ストリームです。 同時に存在できる切替え先の数はそれらの記述に費されるメモリの量によって 主に制限を受けます。これはGNU m4が切替え先の情報とそこへの出力を できればメモリに置いておこうとするためです。そして全ての切替え先の分を あわせたもののために使えるメモリ量には制限があります(現在は512Kです)。 この最大値を超えそうになったときは、一番大きな切替え先の内容を入れるために 一時ファイルが作られ、その分のメモリが他の切替え先のために開放されます。 したがって理論上は切替え先の数が利用可能なファイルディスクリプタの数 によって制限されることもありえます。


9.1 出力を切替える(divert)

出力はdivertを使って切替えます。

 
divert(opt number)

numberは使用する切替え先です。 numberを省略したときはゼロとして解釈されます。

divertは展開されると消滅します。

m4への入力がすべて処理されると、 その時点で存在するすべての切替え先が自動的に番号の順で逆切替え(undivert) されて、そこにたまっていたテキストが出力されます。

 
divert(1)
This text is diverted.
divert
⇒
This text is not diverted.
⇒This text is not diverted.
^D
⇒
⇒This text is diverted.

同じ引数でdivertを何回か呼び出すと、 切替え先にある以前のテキストは上書きされずに、 新しいテキストが以前のテキストの後に追加されてゆきます。

存在するはずのない切替え先へ出力を切替えるとそこから後の出力は 単に捨てられます。 よくある不要な出力の例はマクロ定義の後にある改行です。 次はそれらを避ける方法です。

 
divert(-1)
define(`foo', `Macro `foo'.')
define(`bar', `Macro `bar'.')
divert
⇒

これはm4でのプログラミングで広く使われている慣用句のひとつです。


9.2 出力を逆切替え(undivert)する

切替え先に出力されたテキスト(diverted text)は組み込みマクロ undivertを使って明示的に逆切替え(undivert)することができます。

 
undivert(opt number, ...)

このマクロは引数で指定された切替え先を、指定された順に逆切替えして出力します。 引数が与えられなかったときは、すべての切替え先を番号順に逆切替えします。

undivertは展開されると消滅します。

 
divert(1)
This text is diverted.
divert
⇒
This text is not diverted.
⇒This text is not diverted.
undivert(1)
⇒
⇒This text is diverted.
⇒

最後にある2つの空行に注目してください。 最後のものはundivert(1)に続く改行によるもので、 前のものはなんとdivert(1)に続く改行によるものです。 切替え先のテキストはしばしばこのような空行で始まります。

切替え先のテキスト(diverted text)は逆切替え(undiverted)されると、 m4によって再走査されずに、 現在の出力(切替え先)に直接コピーされます。 したがってある切替え先(diversion)へ出力中に、 逆切替え(undivert)しても問題ありません。

逆切替えをすると、その切替え先にあるテキストは破棄されるので 切替え先のテキストを取り出せるのは1回だけです。

 
divert(1)
This text is diverted first.
divert(0)undivert(1)dnl
⇒
⇒This text is diverted first.
undivert(1)
⇒
divert(1)
This text is also diverted but not appended.
divert(0)undivert(1)dnl
⇒
⇒This text is also diverted but not appended.

現在の切替え先(current diversion)を逆切替え(undivert) しようとしても黙殺されます。

GNU m4では名前を指定したファイルを逆切替え(undivert) することができます。数字以外の引数を与えると、その名前をもつファイルの 内容が現在の出力(切替え先)に解釈されずにコピーされます。 これによって組み込みマクロincludeの機能が補完されます(see section 名前を指定してファイルをインクルードする)。 次の例で違いを説明します。ファイル`foo'の内容は`bar'だとします。

 
define(`bar', `BAR')
⇒
undivert(`foo')
⇒bar
⇒
include(`foo')
⇒BAR
⇒

9.3 出力切替え先番号(diversion number)

組み込みマクロdivnumは現在の切替え先(current diversion)の番号に展開されます。

 
divnum
 
Initial divnum
⇒Initial 0
divert(1)
Diversion one: divnum
divert(2)
Diversion two: divnum
divert
⇒
^D
⇒
⇒Diversion one: 1
⇒
⇒Diversion two: 2

逆切替えされて出力されるテキスト自身が切替え先に出力されてしまうのを防ぐため に最後にある引数無しのdivertの呼び出しが必要です。


9.4 出力切替え先のテキストを破棄する

出力を切替えているときは切替え先のテキストが実際に 必要となるかどうかは分からないことがよくあります。 テキストが溜っている切替え先は入力が終りに達した段階で メインの出力ストリームにすべて出力されるので、 切替え先にたまっているテキストを破棄するためのなんらかの手段が必要です。 すべての切替え先のテキストを破棄したいときは m4への入力を`divert(-1)'とそれに続く明示的な`undivert' で終えるのが最も簡単でしょう。

 
divert(1)
Diversion one: divnum
divert(2)
Diversion two: divnum
divert(-1)
undivert
^D

このとき出力はいっさいありません。

特定の切替え先のテキストは次のマクロで消去できます。

 
define(`cleardivert',
`pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')')
⇒

undivertと同じように呼び出しますが、 その効果は引数として与えられた切替え先のテキストを消去することです。 (このマクロにはひどいバグがあります! それを見つけて直せるか挑戦してみてください。)


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

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