UNIFDEF(1)

名称
unifdef, unifdefall - プリプロセッサ条件行を取り除く

書式
unifdef [-cklst] [ -Ipath -Dsym[=val] -Usym -iDsym[=val] -iUsym] ... [file] unifdefall [-Ipath] ... file

解説
unifdef ユーティリティは cpp(1) の条件ディレクティブ (前処理指令) を選択的に処理します。 ファイルから削除するように特定されたディレクティブとテキストの 両方を削除します。 そうでない場合はファイルをそのままにしておきます。

unifdef ユーティリティは #if, #ifdef, #ifndef, #elif, #else, #endif 行に働きますが、 #if と #elif 行の式文法のよく使われるサブセットしか理解しません。 コマンドラインで定義されたシンボルの整数値や defined() オペレータがコマンドラインで define したり、undefine したシンボルや 演算子!, <, >, <=, >=, ==, !=, &&, || と括弧で囲まれた式を扱うことができます。 より複雑なものはそのまま無傷で通過させます。 #ifdef と #ifndef ディレクティブはシンボルがコマンドラインで指定された場合だけ 処理されます。その他の場合には変更されずに、素通りさせます。 デフォルトでは、定数式を持つ #if と #elif の行は無視しますが、コマンドラインに -k フラグを指定することによりこれらを処理できます。

unifdef ユーティリティにはコメントやシングルクォートやダブルクォートで 囲まれた中で無効にされたディレクティブも理解することができます。 クォートの解析はたいへんシンプルです : 開きクォートが見つかったとき、閉じクォートが見つかるまで (エスケープされたクォートを除いて) すべて無視されます。 もし、バックスラッシュなしの改行が見つかっても 警告しません。

unifdefall シェルスクリプトはファイルから cpp(1) の条件処理ディレクティブをすべて削除することができます。 すべての制御シンボルとその定義 (または未定義) のリストを得るために、 unifdef -s と cpp -dM を使用します。 それからそのファイルを処理するのに適切な引数を付けて unifdef を呼び出します。

利用可能なオプション :
-Dsym[=val]
    定義されるシンボルを指定します。 また、オプションで #if と #elif ディレクティブを操作するためにシンボルに与える値を指定します。

-Usym
    未定義にするシンボルを指定します。 同じシンボルを複数指定した場合には、 最後に指定されたものが有効になります。

-c  -c フラグが指定された場合には、 unifdef の動作は逆にされます。 すなわち、削除されるか空白にされる行を残し、 逆に残すはずだった行を削除します。

-k  定数式を持つ #if と #elif の行を処理します。 デフォルトでは、このような行で制御される部分は変更されずに素通りされます。 なぜなら、これらは典型的には “#if 0” で始まり、未来または過去の開発の概要を記述するコメント的に使用されるからです。 通常のコメントを削除してしまうことが失礼かもしれないのと同様、 これらを削除してしまうのは失礼かもしれません。

-l  削除される行を削除する代わりに空行に置き換えます。

-s  通常の入力ファイルを処理する代わりに、 このオプションは unifdef に unifdef が理解する式に現れたシンボルのリストを生成させます。 それは、 cpp(1) の -dM オプションと協力して unifdef のコマンドラインを生成するのに有用です。

-t  C 言語のコメントとクォートの解釈を禁止します。 通常のテキストファイル等に unifdef を適用する場合に有用です。

-iDsym[=val]
-iUsym
    #ifdef を無視します。C 言語のコードで #ifdef をコメントや作りかけのコードのような C 言語でない部分を区切るために用いている場合は、 unifdef が #ifdef の中のクォートやコメントを解析しないように どのシンボルがその目的で使用されているかを指示する必要があります。 無視するシンボルを指示する方法は -iDsym[=val] や -iUsym で、上記の -Dsym[=val] や -Usym と同様です。

-Ipath
    unifdefall に追加の場所にある #include ファイルを探すように指示します。 cpp(1) との互換性と unifdefall の実装を簡単にするために unifdef はこのオプションは無視します。

unifdef ユーティリティはその出力を stdout にコピーします。 file 引数が指定されなかった場合は stdin から読み込みます。

unifdef ユーティリティは diff(1) の -Dsym オプションとともに使用することができます。

関連項目
cpp(1), diff(1)

診断

不適切な elif, else, endif を検出します。

#ifdef の終了前に EOF を検出した場合、その行番号を出力します。
unifdef ユーティリティは出力が入力と同じになる場合 0、 そうでなければ 1、エラー時には 2 を終了ステータスとして返します。

バグ
構文評価がたいへん限定的です。

ヌル文字を含む入力の場合には正しく動作しません。

歴史
unifdef は 4.3BSD から登場しました。