M4

將宏擴展為 m4 中的引號

  • February 24, 2019

m4中,是否可以擴展宏並立即將其放在引號中?也就是說,而不是

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

擴展到Hello!,我希望有一些功能qexpand,例如,這樣

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

擴展到HELLO. 但是,當然,前兩行之後的任何其他行擴展MACRO為字元串也可以。


背景。我想使用 對宏的擴展進行替換patsubst,比如在其中替換逗號。很遺憾

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

產生x,y,z,因為替換是在字元串上執行的MACRO。但如果宏的擴展包含逗號,則變體

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

有第二行首先展開patsubst(x,y,z,,’,.'),給出錯誤Warning: excess arguments to builtin patsubst’ ignored`。將宏擴展為引號的可能性將解決此問題。

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()返回其每個參數的引用定義。在上面的第二個範例中,我們使用它來獲取帶引號的字元串x,y,z( 的帶引號的值MACRO)。然後將其移交給patsubst它將逗號更改為點的。

POSIX 標準對m4這個宏有這樣的說法:

defn

宏的定義文本defn應為其參數的引用定義(使用目前引用字元串)。如果 defn 後面沒有緊跟 a ,則行為未指定<left-parenthesis>

對於 BSD m4defn()被記錄

defn(name, ...)

返回每個參數的引用定義。這可用於重命名宏定義(即使是內置宏)。

GNUm4有(在m4 info文件中),

內置:defn (NAME...)

擴展到每個的引用定義NAME。如果參數不是已定義的宏,則該參數的擴展為空。

如果NAME是使用者定義的宏,則引用的定義只是引用的擴展文本。相反,如果只有一個NAME 並且它是內置的,則擴展是一個特殊的標記,它指向內置的內部定義。此標記僅作為define(and pushdef) 的第二個參數有意義,並且在大多數其他上下文中被靜默轉換為空字元串。不支持將內置函式與其他任何內容結合使用;發出警告,並從最終擴展中省略內置函式。

defn只能通過參數辨識。

引用自:https://unix.stackexchange.com/questions/501134