web-dev-qa-db-ja.com

マクロを `m4`の引用符に展開する

_m4_で、マクロを展開してすぐに引用符で囲むことはできますか?つまり、代わりに

_define(HELLO, `Hello!')dnl
define(MACRO, `HELLO')dnl
MACRO
_

_Hello!_に展開すると、たとえば、次のような関数qexpandが欲しいです。

_define(HELLO, `Hello!')dnl
define(MACRO, `HELLO')dnl
qexpand(`MACRO')
_

HELLOに展開されます。ただし、最初の2行の後にMACROを文字列に展開する他の行も同様に機能します。


背景patsubstを使用してマクロの展開に置換を操作したいのですが、たとえば、マクロにコンマを代入します。残念ながら

_define(`MACRO',`x,y,z')dnl
patsubst(`MACRO',`,',`.')
_

文字列MACROで置換が実行されるため、_x,y,z_が生成されます。ただし、マクロの展開にコンマが含まれている場合、バリアント

_define(`MACRO',`x,y,z')dnl
patsubst(MACRO,`,',`.')
_

2行目が最初にpatsubst(x,y,z,`,',`.')に展開され、エラー_Warning: excess arguments to builtin `patsubst' ignored_が発生します。マクロを引用符に拡張する可能性はこれを解決します。

3
k.stm

defn()はあなたのqexpand()関数です。

_define(HELLO, `Hello!')dnl
define(MACRO, `HELLO')dnl
defn(`MACRO')
_

HELLOを出力し、

_define(`MACRO',`x,y,z')dnl
patsubst(defn(`MACRO'),`,',`.')
_

_x.y.z_を出力します。

defn()は、各引数の引用符で囲まれた定義を返します。上記の2番目の例では、これを使用して、引用符で囲まれた文字列_x,y,z_(引用符で囲まれたMACROの値)を取得します。次に、これはpatsubstに渡され、コンマがドットに変更されます。

_m4_ のPOSIX標準では、このマクロについて次のように述べています。

defn

defnマクロの定義テキストは、引数の引用符で囲まれた定義(現在の引用符の文字列を使用)でなければなりません。 defnの直後に_<left-parenthesis>_が続かない場合、動作は指定されていません。

BSD _m4_の場合、defn()マクロ 文書化されています as

defn(name, ...)

各引数の引用符で囲まれた定義を返します。これは、マクロ定義の名前を変更するために使用できます(組み込みマクロの場合でも)。

GNU _m4_ has( _m4_ infoドキュメント )、

組み込み:defn (NAME...)

NAME引用符で囲まれた定義に展開されます。引数が定義済みマクロでない場合、その引数の展開は空です。

NAMEがユーザー定義のマクロである場合、引用された定義は単に引用された拡張テキストです。代わりに、NAMEが1つだけで、それがビルトインである場合、展開はビルトインの内部定義を指す特別なトークンです。このトークンは、define(およびpushdef)の2番目の引数としてのみ意味があり、他のほとんどのコンテキストでは空の文字列にサイレントに変換されます。ビルトインを他のものと組み合わせることはサポートされていません。警告が発行され、組み込みは最終拡張から省略されます。

マクロdefnは、パラメーターでのみ認識されます。

4
Kusalananda