EN JA
UNIFDEF(1)
UNIFDEF(1) Programmer's Manual UNIFDEF(1)

名称

unifdef, unifdefallコードからプリプロセッサ条件文を取り除く

書式

unifdef [ -bBcdehKkmnsStV][ -Ipath][ -[i]Dsym[ = val]][ -[i]Usym] ... [ -x { 012}][ -M backext][ -o outfile][ infile ...]

unifdefall [ -Ipath] ... file

解説

unifdef ユーティリティは、 cpp(1) のディレクティブの条件文を選択的に処理します。削除するべきであると指定されたディレクティブとあらゆる追加されたテキストの両方をファイルから取り除きます、一方、そうでなければ、ファイルをそのままにします。

unifdef ユーティリティは、 #if, #ifdef, #ifndef, #elif, #else#endif 行に作用します。 unifdef が制御式に対して明確な値を得ることができるコマンド行で指定されたシンボルを満足させる場合にだけ、ディレクティブは、処理されます。結果が偽であるなら、それで制御されるディレクティブと続く行は、削除されます。結果が真であるなら、ディレクティブのみが削除されます。 #ifdef または #ifndef ディレクティブは、制御されたシンボルがコマンド行で指定されてないなら、変更せず通過されます。未知の値があるか、または unifdef が解析できない #if または #elif コントロール式は、変更されずに通過されます。デフォルトで、 unifdef は、定数式がある #if#elif 行を無視します。コマンド行で -k フラグを指定することによって、それらを処理するように指示することができます。

#if#elif 行の式の構文の一般的に使用される次の部分集合を理解しません: 整数定数、コマンド行で定義されたシンボルの整数値、 defined() 演算子、演算子 !, <, >, <=, >=, ==, !=, &&, || と括弧で囲まれた式です。一種の“short circuit” (短絡) 評価は、次の && 演算子のために使用されます: いずれかのオペランドが確実に偽であるなら、たとえ片方のオペランドの値が未知であっても、結果は、偽です。同様に、 || のいずれかのオペランドが確実に真であるなら、結果は、真です。

ほとんどの場合、 unifdef ユーティリティは、オブジェクトのようなマクロ (引数なし) と関数のような引数 (引数あり) を区別できません。マクロが明白に定義されていないか、または -D フラグがコマンド行で定義されるなら、引数は、無視されます。 -U フラグのあるコマンド行でマクロが明白に未定義にされるなら、これは、構文エラーとなるので、なにも引数をつけることはできません。

unifdef ユーティリティは、ディレクティブの 1 つがアクティブでないとき、コメント内であるか、またはバックスラッシュ継続行によって作用されるので、 C に関して本当に必要なことだけ理解します。異常な形式のプリプロセッサディレクティブを見つけて、レイアウトが扱うことができないくらい変であるとき、分かります。

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

オプション

-D sym= val
#if#elif 条件式を評価するとき、使用される与えれられた値にシンボルが定義されることを指定します。

-D sym
シンボルが値 1 に定義されることを指定します。

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

-iD sym[ = val]
-iU sym
C 文字列、コメントと行の継続は、これらのオプションで指定されたシンボルによって制御される #ifdef#ifndef ブロック内で無視されます。

-b
行を削除する代わりに削除された行を空白行に置き換えます。 -B オプションとは互いに排他的です。

-B
削除されたセクションの周りの空白行を圧縮します。 -b オプションとは互いに排他的です。

-c
逆にします、すなわち、削除されたまたは空白とされた行は、保持され、逆もまた同様です。

-d
デバッグメッセージの印刷 (表示) をオンにします。

-e
デフォルトで、 unifdef は、それが 2 行以上の範囲があるプリプロセッサのディレクティブを削除する必要があるなら、例えば、右側の終りでコメントが終っていないような、複数行のコメントがあるなら、エラーを報告します。 -e フラグは、代わりにその行を無視させます。

-h
ヘルプを印刷 (表示) します。

-I path
#include ファイルを検索する追加の場所を unifdefall に指定します。このオプションは、 cpp(1) との互換性のために、そして unifdefall の実装を単純化するために unifdef によって無視されます。

-K
未知のオペランドが結果に影響できないとき、ショートカットする代わりにいずれかのオペランドが未知であるなら、 &&|| 演算子の結果を常に未知のように扱います。このオプションは、 unifdef の古いバージョンとの互換性のためのものです。

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

-m
適切に 1 つ以上の入力ファイルを修正します。

-M backext
適切に入力ファイルを修正して、入力ファイル名に backext を追加することによってオリジナルのファイルのバックアップを保持します。

-n
出力ファイルをコンパイルする時、入力ファイルの行番号に対応したエラーが生成されるように、削除された行に続いて #line ディレクティブを出力に追加します。

-o outfile
単一のファイルを処理するとき、標準出力の代わりにファイル outfile に出力を書き込みます。

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

-S
-s オプションと同様ですが、それぞれのシンボルのネストされた深さも印刷されます。これは、相互依存の定義された/未定義のシンボルの組み合わせの可能性の数を解明するために役に立ちます。

-t
C 文字列、コメントと行継続のための解析を無効にします、それは、平板なテキストのために役に立ちます。これは、 -iD-iU フラグの包括的なバージョンです。

-V
バージョンの詳細を印刷します。

-x { 012}
終了ステータスモードを 0、1 または 2 に設定します。詳細については、下記の 「終了ステータス」 のセクションを参照してください。

unifdef ユーティリティは、 file 引数がないなら、 stdin から入力を取ります。複数の入力ファイルがあるなら、 -m または -M オプションを使用しなければなりません。‘ -’で stdin からの入力、または stdout への出力を指定することができます。

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

終了ステータス

通常の使用法で、 unifdef ユーティリティの終了ステータスは、 -x オプションを使用して設定されたモードに依存します。

終了モードが 0 (デフォルト) であるなら、 unifdef は、出力が正確なコピーであるなら、ステータス 0 で終了し、出力が異なるなら、ステータス 1 で終了します。

終了モードが 1 であるなら、 unifdef は、出力が未変更であるなら、ステータス 1 で終了し、それが異なるなら、ステータス 1 で終了します。

終了モードが 2 であるなら、 unifdef は、両方の場合にステータス 0 で終了します。

すべての終了モードにおいて、 unifdef は、エラーがあるなら、ステータス 2 で終了します。

終了ステータスは、 -h または -V コマンド行オプションが与えられるなら、0 です。

診断

  • 多過ぎるネストレベルを検出します。
  • 不適切な #elif, #else, #endif を検出します。
  • 分かりにくいプリプロセッサ制御行を検出します。
  • 早過ぎる EOF を検出します (もっとも最近の未完了の #if の行番号を表示します)。
  • コメント中の EOF を検出します。

関連項目

cpp(1), diff(1)

歴史

unifdef は、 2.9BSD で登場しました。 ANSI C のサポートは、 FreeBSD 4.7 で追加されました。

作者

オリジナルの実装は、 Dave Yost <Dave@Yost.com>によって書かれました。 Tony Finch <dot@dotat.at>は、 ANSI C をサポートするために、それを書き直しました。

バグ

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

一度に 1 つの行を扱うことは、すべての状況で (コメントまたはバックスラッシュ-改行のために) 2 つ以上の物理的な行に渡って分割されたプリプロセッサのディレクティブを扱うことができないことを意味します。

トライグラフは、認識されません。

ソースファイル中の複数の場所で異なった定義を持つシンボルは、サポートされません。

テキストモードおよび機能無視は、最近の cpp(1) の動作とは、対応していません。

February 21, 2012 FreeBSD