web-dev-qa-db-ja.com

可変数のタブを使用して列を並べるm4マクロ

これは私がこれまでに持っているマクロです:

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ファイルに含まれています。そうすれば、各プログラマーは自分のデバッグ領域を好きなようにオンまたはオフにすることができます。

2
MyTallest

何かをインデントする最も簡単な方法は、タブではなくスペースを使用することです。特に、標準外の幅のタブではありません(タブには標準の幅があるため、8です)。

タブで何かをインデントする2番目に簡単な方法は、スペースを含むファイルを生成し、 unexpand を呼び出してスペースをタブに置き換えることです。

そうは言っても、m4でそれを行うことはできますが、もっとよく理解する必要があります。式を段階的に作成します。1つのピースを機能させてから、次のピースに進みます。

forloopは標準のm4マクロではありません。 GNU m4マニュアルに示されているforloopマクロ を意味していると思います。これはGNU m4に付属するサンプルコードです(マニュアルではこれを明確に説明していません)。コードで使用するには、明示的に含める必要があります。ディストリビューションでは出荷される場合とされない場合があるため、コードと一緒に配布することをお勧めします。

コードにはいくつかの構文上の問題があります。

  • forloopへの呼び出しを引用符の外に残したため、_debug_macro_が評価されるときではなく、defineが評価されるときに評価されます。
  • ifelseマクロは、最初の引数の値だけに基づいて選択するのではなく、最初の2つの引数を比較します。これは、よりケースマクロです。呼び出しはifelse(…, 0, 0, 1)または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
_