Debugging

m4 宏使用可變數量的選項卡來排列一列

  • December 22, 2014

這是我到目前為止的宏:

define(`debug_macro', `
#ifndef $1_DEBUG
#define $1_DEBUG'forloop(`i',`1',eval(5-(len($1)/4+ifelse(eval(len($1)%4 == 0)), `0', `1')),`   ')dnl`0
#endif

')

_DEBUG目標是在和字元之間放置正確數量的製表符,0以便它們全部對齊。可能缺少括號或引號,但希望你能明白我要去哪裡。

我正在使用 Xcode 並將我的選項卡設置為 4。以下是我為適應這種情況所做的更改:

divert(`-1')
# forloop(var, from, to, stmt)
define(`forloop',
`pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
define(`_forloop',
`$4`'ifelse($1, `$3', ,
`define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
divert`'dnl
changecom()dnl
define(`debug_macro', `
#ifndef $1_DEBUG
#define $1_DEBUG`'forloop(`i', `1', ifelse(eval(len($1) >= 16), 1, 1, eval(5-(len($1)/4+ifelse(eval(len($1)%4 > 1), 0, `0', `1')))),`   ')0
#endif

')
changecom()dnl

因為我在我的系統上找不到“forloop.m4”,所以我只包含了它。除以 4 輪,所以我添加了檢查餘數何時大於 1。我還更改了單個製表符的空格執行。

對於感興趣的人,我使用這個宏來定義我用來打開應用程序不同區域的調試的常量。該文件被檢入 git。然後有一個個人文件,未簽入,如下所示:

//#define NETWORK_DEBUG  1

在包含上述文件之前,該文件包含在 myapp.pch 文件中。這樣,每個程序員都可以隨意打開或關閉自己的調試區域。

縮進最簡單的方法是使用空格,而不是製表符。尤其是非標準寬度的標籤(只要標籤有標準寬度,它是 8)。

使用製表符縮進的第二種最簡單的方法是生成一個帶有空格的文件並呼叫unexpand以製表符替換空格。

話雖如此,您可以在 m4 中做到這一點,但您必須更加熟悉它。逐步建立你的表達方式:讓一件作品開始工作,然後繼續下一件作品。

forloop不是標準的 m4 宏。我認為您的意思是forloopGNU m4 手冊中介紹的宏。這是 GNU m4 附帶的範常式式碼(手冊並沒有說得很清楚);要在您的程式碼中使用它,您需要明確地包含它。發行版可能會或可能不會發布它,因此您最好將其與您的程式碼一起發布。

您的程式碼中有幾個語法問題。

  • 您已將呼叫留在forloop任何引號之外,因此在評估時define對其進行評估,而不是在評估時debug_macro進行評估。
  • ifelse宏不會單獨根據第一個參數的值進行選擇,而是比較它的前兩個參數——它更像是一個 case 宏:呼叫應該是ifelse(…, 0, 0, 1)or ifelse(… == 0, 1, 0, 1)
  • #開始評論。M4 在評論後忽略所有內容。在定義宏時更改註釋分隔符。debug_macro

只要參數不太長,以下程式碼就可以工作:

include(`/usr/share/doc/m4/examples/forloop.m4')dnl
changecom()dnl
define(`debug_macro', `
#ifndef $1_DEBUG
#define $1_DEBUG`'forloop(`i',`1',eval(5-(len($1)/4+ifelse(eval(len($1)%4), 0, `0', `1'))),`    ')0
#endif

')dnl
changecom('#')dnl

使用導致最大循環索引變為 0 或更小的參數,循環執行大約 2 32次(m4 使用 32 位模運算)。在這種情況下,您需要進行額外的測試。這是在參數太長時插入單個選項卡的程式碼。

include(`/usr/share/doc/m4/examples/forloop.m4')dnl
changecom()dnl
define(`debug_macro', `
#ifndef $1_DEBUG
#define $1_DEBUG`'forloop(`i', `1', ifelse(eval(len($1) >= 16), 1, 1, eval(5-(len($1)/4+ifelse(eval(len($1)%4), 0, `0', `1')))),`       ')0
#endif

')dnl
changecom('#')dnl

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