m4 マクロ・プロセッサーの概要

このトピックでは、オペレーティング・システム環境で使用されている、任意のプログラミング言語用のフロントエンド・プロセッサーである、m4 マクロ・プロセッサーについての情報を提供します。

プログラムの先頭で、シンボル名またはシンボリック定数を特殊な文字列として定義することができます。 その後、 m4 マクロ・プロセッサーを使用して、引用符で囲まれていないシンボル名のオカレンスを対応するストリングに置き換えることができます。 あるテキストの文字列を他の文字列に置き換えるだけでなく、m4 マクロ・プロセッサーには以下の機能があります。

  • 演算機能
  • ファイル操作
  • 条件付きマクロ展開
  • 文字列およびサブストリング関数

m4 マクロ・プロセッサーは、トークン と呼ばれる英字と数字の文字列を処理します。 m4 マクロ・プロセッサーは、それぞれの英数字のトークンを読んで、 それがマクロの名前かどうかを判別します。 次に、マクロを定義するテキストでマクロ名を置き換え、 その結果の文字列を元の入力にプッシュし、再スキャンします。 マクロは引数で呼び出せますが、 引数は定義テキストが再スキャンされる前に収集されて、右側の場所に置き換えられます。

m4 マクロ・プロセッサーは、define などの組み込みマクロを提供します。 新規マクロを作成することもできます。 組み込みマクロとユーザー定義マクロの働きは同じです。

m4 マクロ・プロセッサーの使用

m4 マクロ・プロセッサーを使用するには、 次のコマンドを入力します。

m4 [file]

m4 マクロ・プロセッサーは、各引数を順に処理します。 引数がないか、または引数が - (ダッシュ) である場合、m4 マクロ・プロセッサーはその入力ファイルとして標準入力を読み取ります。 m4 マクロ・プロセッサーは、その結果を標準出力に書き込みます。 したがって、後で使用するために出力をファイルにリダイレクトするには、 次のようなコマンドを使用します。

m4 [file] >outputfile

ユーザー定義マクロの作成

マクロ 説明
define (MacroName, Replacement) Replacement の値を持つ新しいマクロ MacroName を定義します。

例えば、プログラムに次のステートメントがあるとします。

define(name, stuff)

m4 マクロ・プロセッサーは、ストリング name を次のように定義します。stuff.プログラム・ファイルに name というストリングがあると、 m4 マクロ・プロセッサーはそれを次のストリングに置き換えます。stuff.このストリングについては以下の条件があります。nameASCII 英数字でなければならず、文字または下線で始まらなければなりません。 このストリングについては以下の条件があります。stuff任意のテキストですが、テキストに括弧が含まれている場合は、左括弧の数が右括弧の数と等しくなければなりません。 テキストを広げるには、 / (スラッシュ) 文字を使用します。stuff複数行にわたっています。

開き括弧 (左括弧) は、ワード define のすぐ後に続けます。 次に例を示します。

define(N, 100)
 . . . 
if (i > N)

定義Nとなる100そして、後の if ステートメントでシンボリック定数 N を使用します。

プログラム中のマクロ・コールは、次の形式です。

name(arg1,arg2, . . . argn)
マクロ名は、英数字以外の文字で囲んだ場合にかぎり認識されます。 次の例では、変数NNN定義されたマクロに関連していないN.
define(N, 100)
 . . . 
if (NNN > 100)

他の名前に関してマクロを定義することができます。 次に例を示します。

define(N, 100)
define(M, N)

両方を定義MおよびNとなる100。後で定義を変更した場合には,N新しい値を割り当てますM価値を保持する100、そうではないN.

m4 マクロ・プロセッサーは、 マクロ名をできるかぎり早くその定義テキストに展開します。 このストリングについては以下の条件があります。N以下のように置き換えられます。100. 次に、ストリングMも以下に置き換えられます。100全体の結果は、最初に以下の入力を使用した場合と同じです。

define(M, 100)

定義の順序は、次のように交換できます。

define(M, N)
define(N, 100)

現在Mストリングとして定義されます。Nということになります。M後で要求された場合、結果は以下の値になります。Nこの時点で (M は次のものに置き換えられるため)Nこれは、以下のように置き換えられます。100).

引用文字の使用

define の引数の展開を遅らせるには、それを引用文字で囲みます。 引数を変更しない場合の引用文字は ` および ' (左右の単一引用符) です。 引用文字によって囲まれたテキストは、いずれもすぐには展開されませんが、 引用文字は除去されます。 引用符付き文字列の値は、引用文字を除去した文字列になります。 次の例を参照してください。

define(N, 100)
define(M, `N')

前後の引用文字Nは、引数が収集されるときに削除されます。 引用文字を使用した結果は、次のように定義されます。MストリングとしてN,not100一般的な規則では、 m4 マクロ・プロセッサーは、何かを評価するたびに、常に 1 レベルの引用文字を除去します。 これは、マクロの外側でも同じです。 単語を作成するにはdefine出力に表示される場合は、次のように引用符文字で単語を入力します。

`define' = 1;

引用文字のもう 1 つの使用例として、再定義があります。N. 再定義するためにはN、次のようにして評価を遅らせます。N引用符で囲みます。 次に例を示します。

define(N, 100)
. . . 
define(`N', 200)

問題が発生するのを防ぐために、マクロの最初の引数を引用します。 例えば、以下のフラグメントは再定義されません。N:

define(N, 100)
. . . 
define(N, 200)

このN2 番目の定義は 100 に置き換えられます。 結果は、次のステートメントと同じです。

define(100, 200)

m4 マクロ・プロセッサーは、 名前を定義できるだけで数字は定義できないので、 このステートメントを無視します。

引用文字の変更

引用文字は普通は ` および ' (左または右の単一引用符) です。 それらの文字が適切ではない場合は、次の組み込みマクロで引用文字を変更できます。

マクロ 説明
changequote (l r ) 左右の引用文字を、l 変数と r 変数で表される文字に変更します。

元の引用文字に復元するには、changequote を次のように引数なしで使用します。

changequote

引数

マクロ処理の最も簡単な形式は、 ある文字列の他の文字列 (固定) 文字列による置き換えです。 ただし、マクロでも引数を使用できるので、 マクロを異なる場所で使用して、異なる結果を得ることができます。 引数をマクロの置換テキスト (その定義の 2 番目の引数) の中のどこで使用するかを示すには、 シンボル $n を使用して、n 番目の引数を示します。 マクロが使用されるとき、m4 マクロ・プロセッサーがシンボルを指示された引数の値で置き換えます。 例えば、次のシンボルがあるとします。

$2

これは、マクロの 2 番目の引数を参照します。 したがって、次のようなマクロを定義したとします。bump形式:

define(bump, $1 = $1 + 1)

m4 マクロ・プロセッサーは、最初の引数を 1ずつ増分するコードを生成します。 このbump(x)ステートメントは x = x + 1 と同等です。

マクロでは、必要なだけの引数を使用することができます。 ただし、 $n 記号を使用してアクセスできる引数は 9 個のみです ($1範囲$9)。 9 番目の引数より後の引数にアクセスするには、 shift マクロを使用します。

マクロ 説明
shift (ParameterList) リストの復元不能な左シフトを実行するために、ParameterList の最初のエレメントを除くすべてを戻します。

このマクロは、最初の引数をドロップし、残りの引数を $n 記号に再割り当てします (2 番目の引数を$1、3 番目の引数$2....... 10 番目の引数$9)。 shift マクロを複数回使用すると、マクロで使用されるすべての引数にアクセスできます。

$0 マクロはマクロの名前を戻します。 提供されていない引数は null 文字列に置き換えられるので、 引数を次のように連結したマクロを定義することができます。

define(cat, $1$2$3$4$5$6$7$8$9)

したがって

cat(x, y, z)

これは次の場合と同じです。

xyz

引数$4範囲$9この例では、対応する引数が指定されていないため、NULL になっています。

m4 マクロ・プロセッサーは、先行する引数で囲まれていないブランク、 タブ、または改行の文字を破棄しますが、他のすべてのホワイト・スペースは保持します。 したがって

define(a, b c)

定義aとなるb c.

引数はコンマで分離します。 コンマで引数が終わらないようにするには、 括弧を使用してコンマの入った引数を囲みます。 次に例を示します。

define(a, (b,c))

この引数は 2 つだけです。 最初の引数は次のとおりです。a2 番目は (b,c)。 コンマまたは単一括弧を使用するには、引用符で囲んでください。

事前定義 m4 マクロの使用

m4 マクロ・プロセッサーは、1 組の事前定義マクロを提供します。 この項では、多数のマクロとその使用法について説明します。

マクロ定義の除去

マクロ 説明
undefine (`MacroName') ユーザー定義マクロまたは組み込みマクロ (`MacroName ') の定義を除去します。

次に例を示します。

undefine(`N')

N の定義を削除する。 undefine マクロを使用して組み込みマクロを除去すると、次のようになります。削除

undefine(`define')

組み込みマクロの定義を再び使用できなくなります。

この場合は、置き換えを防ぐために単一引用符が必須です。

定義済みマクロの検査

マクロ 説明
ifdef (`MacroName', 引数 1, 引数 2) マクロ MacroName が定義済みで、 ゼロに定義されていない場合、Argument1 の値を戻します。 それ以外の場合、Argument2 を戻します。

ifdef マクロでは、3 つの引数を使用することができます。 最初の引数が定義されている場合、 ifdef の値は 2 番目の引数です。 最初の引数が定義されていない場合、 ifdef の値は 3 番目の引数です。 3 番目の引数がない場合、 ifdef の値は NULL になります。

整数演算の使用

m4 マクロ・プロセッサーは、整数のみの演算を行うために、 以下の組み込み関数を用意しています。

マクロ 説明
incr (Number) Number + 1 の値を戻す。
decr (Number) Number - 1 の値を戻す。
eval 算術式を評価する。

したがって、変数を Number 値より 1 大きく定義するには、 次のものを使用します。

define(Number, 100)
define(Number1, `incr(Number)')

これは、Number1現行値より 1 だけ大きい値としてNumber.

eval 関数は、 次の演算子 (優先度に関して降順にリストされている) を使った式を評価することができます。
  • 単項 + および -
  • ** または ^ (累乗)
  • */% (モジュラス)
  • + -
  • == != < <= > >=
  • !(not)
  • & または && (論理 AND)
  • | または | | (論理 OR)

必要に応じて操作をグループ化するには、括弧を使用します。 式のオペランドは、すべて数字でなければなりません。 trueリレーションの数値 ( 例えば、 1 > 0) は 1、falseは 0です。 eval 関数の精度は 32 ビットです。

例えば、次のように定義します。Mとなる2==N+1eval 関数を次のように使用します。

define(N, 3)
define(M, `eval(2==N+1)')

テキストが非常に簡潔でないかぎり、マクロを定義するテキストを引用文字で囲みます。

ファイルの操作

新しいファイルを入力に組み合わせるには、 組み込みの include 関数を使用します。

マクロ 説明
include (File) ファイル File の内容を戻します。

次に例を示します。

include(FileName)

内容を挿入するFileNameinclude コマンドの代わりに使用します。

include マクロで指定されたファイルにアクセスできない場合、 致命的エラーが発生します。 致命的エラーを避けるには、 代替形式の sinclude マクロ (サイレントの組み込み) を使用します。

マクロ 説明
sinclude (File ) ファイル File の内容を戻しますが、File へアクセスできない場合にエラーを報告しません。

sinclude (silent include) マクロはメッセージを書きませんが、 指定されたファイルにアクセスできない場合は継続します。

出力のリダイレクト

m4 マクロ・プロセッサーの出力は、 処理時に一時ファイルに再びリダイレクトし、 収集された材料をコマンドで出力することができます。 m4 マクロ・プロセッサーは、1から9までの9つの一時ファイルを保持します。 組み込みの divert マクロを使用する場合。

マクロ 説明
divert (Number) 出力ストリームを一時ファイル Number に変更します。

m4 マクロ・プロセッサーは、 プログラムからのすべての出力を、divert 関数の後で一時ファイル Number の終わりに書き込みます。 出力をディスプレイ・スクリーンに戻すには、 通常の出力処理を再開する divert 関数か divert(0) 関数のどちらかを使用します。

m4 マクロ・プロセッサーは、すべてのリダイレクトされた出力を、 処理の最後に、 一時ファイルに数値順に書き込みます。 m4 マクロ・プロセッサーは、 出力が 0 から 9 以外の一時ファイルにリダイレクトされると、出力を破棄します。

データをすべての一時ファイルから数値順に戻すには、 組み込みの undivert マクロを使用します。

マクロ 説明
undivert (Number1, Number2... ) 指示された一時ファイルの内容を、現在の一時ファイルに追加します。

選択された一時ファイルを指定された順序で戻すには、 組み込みの undivert マクロを引数付きで使用します。 undivert マクロの使用時に、m4 マクロ・プロセッサーは、 リカバリーされた一時ファイルを破棄し、 リカバリーされたデータをマクロのために検索することはありません。

undivert マクロの値は、方向転換されたテキストではありません。

divnum マクロを使用して、現在使用中の一時ファイルを判別することができます。

マクロ 説明
dinum (分割数) 現在アクティブな一時ファイルの値を戻します。

divert マクロで出力ファイルを変更しない場合、m4 マクロ・プロセッサーは全出力を 0 という名前の一時ファイルに書き込みます。

プログラム内でのシステム・プログラムの使用

組み込まれた syscmd マクロを使用すると、 プログラムから任意のプログラムをオペレーティング・システムで実行することができます。 例えば、次のステートメントは date プログラムを実行します。

syscmd(date)

固有ファイル Nnames の使用

maketemp マクロを使用して、 プログラムから固有ファイル名を作成することができます。

マクロ 説明
maketemp (String...nnnnn...ストリング) 引数文字列内の文字 nnnnn を現在のプロセス ID で置き換えることによって、 固有ファイル名を作成します。

例えば、次のステートメントがあるとします。

maketemp(myfilennnnn)

m4 マクロ・プロセッサーは、以下のストリングを戻します。myfileプロセス ID と連結されます。 この文字列は、一時ファイルの指定に使用します。

条件式の使用

条件式の評価を使えば、マクロ式の処理時間を判別することができます。

説明
ifelse (String1, String2, Argument1, Argument2) String1String2 と一致する場合、Argument1 を戻します。 それ以外の場合は、Argument2 を戻します。

組み込まれた ifelse マクロは、条件テストを行います。 最も簡単な形式では、次のようになります。

ifelse(a, b, c, d)

2 つのストリングを比較するaおよびb.

指定する場合は、aおよびbが同一の場合、組み込みの ifelse マクロは次のストリングを返します。c. これらが同一でない場合は、ストリングを戻します。d例えば、次のようなマクロを定義することができます。compare2 つのストリングを比較して、yes同じものである場合、またはno異なる場合は、以下のようにします。

define(compare, `ifelse($1, $2, yes, no)')

引用文字によって、ifelse マクロの評価が早く行われすぎるのを防止することができます。 4 番目の引数が欠落している場合、空として扱われます。

ifelse マクロでは任意の数の引数を使用でき、 したがって、限定形式のマルチパスの決定能力を提供します。 次に例を示します。

ifelse(a, b, c, d, e, f, g)

このステートメントは、次に示すフラグメントと論理的に同じです。

if(a == b) x = c;
else if(d == e) x = f;
else x = g;
return(x);

最終引数を省略すると、結果は null になります。

ifelse(a, b, c)

次と同一であるcの場合aが次の値に一致するbそれ以外の場合は NULL。

文字列の操作

この項で述べているマクロを使えば、入力文字列を出力文字列に変換することができます。

マクロ 説明
len その引数を構成する文字列のバイト長を戻します。

したがって

len(abcdef)

これは 6 です。

len((a,b))

これは 5 です。

マクロ 説明
DLEN 文字列内の表示可能文字の長さを戻します。

2 バイト・コードで構成される文字は、1 文字として表示されます。 したがって、文字列に何らかの 2 バイトの、 各国文字サポート文字が使われている場合、dlen の結果は len の結果とは異なります。

マクロ 説明
substr (String, Position 長さ) 文字番号 Position から始まり、Length 文字長の String のサブストリングを戻します。

入力を使用すると、substr (s, i, n) は、i 番目の位置 (原点は 0) から始まり、n 文字長の s のサブストリングを戻します。 n を省略すると、文字列の残りの部分が戻されます。 例えば、次の関数を参照してください。

substr(`now is the time',1)

これは、次の文字列を戻します。

ow is the time
マクロ 説明
index (String1 String2) String1 の中の、String2 が始まる文字位置 ( 文字番号 0 から始まる)、 または String1String2 が入っていない場合は -1 を戻します。

組み込まれた substr マクロの場合と同様、 文字列の起点は 0 です。

マクロ 説明
translit (String, Set1, Set2) Set1 の中にある文字を求めて、String を検索します。 見つかった場合は、それらの文字を Set2 の中の対応する文字に変更します (文字変換)。

この一般的形式は、次のようになります。

translit(s, f, t)

変更するs見つかった文字を置き換えることによってf対応する文字によってt。例えば、以下の関数を使用します。

translit(`little', aeiou, 12345)
これは、母音をそれに対応する数字に置き換えて、以下を戻します。
l3ttl2

指定する場合は、tより短いf、エントリーを持たない文字t削除されます。 指定する場合は、tまったく存在しない場合は、以下の文字を使用します。f削除元sそれで

translit(`little', aeiou)
文字列から母音を削除します。little以下を返します。
lttl
マクロ 説明
DNL その後に続くすべての文字を、改行文字まで (これを含む) 削除します。

このマクロは、空の行を除去するために使用します。 例えば、次の関数を参照してください。

define(N, 100)
define(M, 200)
define(L, 300)

この結果、定義の一部でない各行の最後に改行が置かれます。 これらの改行文字は、出力に渡されます。 改行を除去するには、 各行に組み込みの dnl マクロを追加します。

define(N, 100) dnl
define(M, 200) dnl
define(L, 300) dnl

m4 マクロのデバッグ

この項で説明しているマクロを使えば、エラーと処理情報をレポートすることができます。

マクロ 説明
errprint (String) その引数 (String) を標準エラー・ファイルに書き出す

次に例を示します。

errprint (`error')
マクロ 説明
dumpdef (`MacroName'... ) 引数として指定された項目の現在の名前と定義 (`MacroName '...) をダンプする

引数を指定しないと、dumpdef マクロは現在の名前と定義をすべて出力します。 名前を引用符で囲むことを忘れないでください。

その他の m4 マクロ

それぞれの簡単な説明を付けた追加 m4 マクロのリストを、 次に示します。

マクロ 説明
changinfrastructure (l, r ) 左右のコメント文字を l 変数と r 変数で表される文字に変更します。
定義 (MacroName) 引用符で囲まれた MacroName の定義を戻します。
en (ストリング) String 内の文字数を戻します。
m4exit (コード) m4 マクロ・プロセッサーを Code の戻りコードで終了します。
m4wrap (MacroName) m4 マクロ・プロセッサーの終わりにマクロ MacroName を実行します。
popdef (MacroName) MacroName の現在の定義を pushdef マクロによって保管された直前の定義で置き換えます。
pushdef (マクロ名, 置換) MacroName の現在の定義を保管してから、MacroNameReplacement であると定義します。
SYSVAL syscmd マクロを最後に使用したときの戻りコードを取得します。
トレースオフ (MacroList) MacroList 内の任意のマクロのトレースをオフにします。 MacroList が null の場合、すべてのトレースをオフにします。
traceon (MacroName) マクロ MacroName のトレースをオンにします。 MacroName が null の場合、すべてのマクロのトレースをオンにします。