m4是一個通用的巨集處理器,由布萊恩·柯林漢丹尼斯·里奇設計。m4是基於Ritchie早先為AP-3小型機開發的m3巨集處理器擴充的。

使用

m4是POSIX標準中的一部分,所有版本的UNIX下都可用。雖然這種語言可以單獨使用,但大多數人需要m4僅僅是因為GNU autoconf中的「configure」指令碼依賴它。

巨集處理器(或預處理器)一般用作文字替換工具。終端使用者經常會用它來處理要反覆使用的文字模板,典型的是用於編程工具,還會用於文字編輯和文書處理工具。

歷史

巨集處理器開始流行的時候,程式設計師還都在使用組合語言來編程。在早期,程式設計師發現他們的程式中包含了很多重複的代碼,於是他們創造了這種簡單的方法來重用。程式設計師們很快發現它不僅能用於重用整塊代碼,還能為類似的參數替換不同的值。這明確了巨集處理器的使用範圍。

在1977年,Kernighan和Ritchie基於Christopher Strachey的想法開發了m4。一些與眾不同的特徵有:

  • 自由形式的語法(而不是像那些用於處理組合語言的典型巨集處理器一樣使用基於行的語法)
  • 高度的巨集擴充(巨集參數被擴充兩次:掃描時一次、插值時一次)

從一開始,Rational Fortran(RatFor)就使用m4作為它的巨集引擎,而大多數UNIX變種發布時都包含了它。 截止2009年,許多應用仍在使用m4(作為GNU autoconf專案的一部分)。它還出現在sendmail(一個廣泛使用的郵件傳輸代理)的組態過程,以及用於gEDA工具包中生成腳印。

m4大多用於代碼生成,和其他巨集處理器一樣,一旦出了問題會很難除錯。

特性

m4提供如下功能:

  • 語法形式自由,而不是基於行的語法;
  • 高度的巨集擴充(巨集參數在掃描和插值中都會被擴充)
  • 文字替換
  • 參數替換
  • 檔案包含
  • 字串操作
  • 條件判斷
  • 數算運算
  • 系統介面
  • 程式設計師診斷
  • 獨立於電腦程式語言
  • 獨立於自然語言
  • 可程式化

與大部分早先的巨集處理器不同,m4並不面向任何電腦語言或自然語言;但從歷史角度來說,它最初是為支援Fortran的方言Ratfor而開發的。此外,m4還是一種圖靈完備的程式語言。

範例

以下巨集代碼可生成HTML代碼:自動為每個章節編號。

divert(-1)
This `divert' discards this text. Note that I had to quote the `divert'
in the comment so it wouldn't get undiverted.

# In a true comment, I'm free to use words such as divert and other builtin
# m4 macros' names without consequence.

# This starts the count at ONE as the incr is a preincrement.
define(`H2_COUNT', 0)

# The H2_COUNT macro is redefined every time the H2 macro is used.
define(`H2',
        `define(`H2_COUNT', incr(H2_COUNT))<h2>H2_COUNT. $1</h2>')

divert(0)dnl Diversion to 0 means back to normal. dnl macro removes this line.
H2(First Section)
H2(Second Section)
H2(Conclusion)

上述代碼在m4中執行,生成以下結果:

<h2>1. First Section</h2>
<h2>2. Second Section</h2>
<h2>3. Conclusion</h2>

dnl用於刪除前面的空行。

自由軟體版本

GNU實現了一個m4版本;FreeBSD、NetBSD和OpenBSD也提供一個m4語言的獨立實現版本;此外,OpenSolaris的Heirloom專案開發工具中也包含了一個m4語言的自由版本。