元の質問
私が望むのは、標準の C プリプロセッサではなく、どこか (おそらく -DNAME1 および -UNAME2 オプションを介したコマンド ライン) から受け入れられるバリエーションであり、どのマクロが定義されているかの仕様であり、デッドを排除します。コード。
いくつかの例を使用すると、私が求めていることを理解しやすくなる場合があります。
#ifdef NAME1
#define ALBUQUERQUE "ambidextrous"
#else
#define PHANTASMAGORIA "ghostly"
#endif
コマンドが「-DNAME1」で実行された場合、出力は次のようになります。
#define ALBUQUERQUE "ambidextrous"
コマンドが「-UNAME1」で実行された場合、出力は次のようになります。
#define PHANTASMAGORIA "ghostly"
どちらのオプションも指定せずにコマンドを実行すると、出力は入力と同じになります。
これは単純なケースです。コードがより複雑なケースも処理できることを願っています。
現実世界の単純な例で説明するには:
#ifdef USE_VOID
#ifdef PLATFORM1
#define VOID void
#else
#undef VOID
typedef void VOID;
#endif /* PLATFORM1 */
typedef void * VOIDPTR;
#else
typedef mint VOID;
typedef char * VOIDPTR;
#endif /* USE_VOID */
コマンドを実行して出力を取得したい-DUSE_VOID -UPLATFORM1
:
#undef VOID
typedef void VOID;
typedef void * VOIDPTR;
もう一つの例:
#ifndef DOUBLEPAD
#if (defined NT) || (defined OLDUNIX)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
-UOLDUNIX
理想的には、実行して出力を取得したいと思います。
#ifndef DOUBLEPAD
#if (defined NT)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
これは私の運を後押ししているかもしれません!
動機: 多数の条件付きコードを含む大規模で古いコード ベース。条件の多くは適用されなくなりました。たとえば、OLDUNIX プラットフォームは製造されなくなり、サポートも終了したため、コード内でこれを参照する必要はありません。他の条件は常に true です。たとえば、条件付きコンパイルを使用して機能が追加されるため、単一バージョンのコードを、機能が利用できない古いバージョンのソフトウェアと利用できる新しいバージョンの両方に使用できます (多かれ少なかれ)。最終的に、機能のない古いバージョンはサポートされなくなります - すべてが機能を使用します - そのため、機能が存在するかどうかの条件を削除し、「機能が存在しない場合」のコードも削除する必要があります。私'
(ツールの非常に賢いバージョンは、#include
'd ファイルを読み取って、コマンド ラインで -D または -U によって指定された制御マクロがそれらのファイルで定義されているかどうかを判断する場合があります。ただし、それが何をするにしても、疑似プリプロセッサはマクロを展開したり、ファイルを逐語的にインクルードしたりしてはなりません. 出力は、入力コードと同様のソースである必要がありますが、通常は入力コードよりも単純でなければなりません.)
現状報告(1年後)
1年間使用した後、選択した回答が推奨する「 sunifdef 」に非常に満足しています。それはまだ間違いを犯していませんし、そうなるとは思っていません。私がそれについて持っている唯一の疑問は文体です。次のような入力が与えられた場合:
#if (defined(A) && defined(B)) || defined(C) || (defined(D) && defined(E))
'-UC' (C は定義されていません) を指定して実行すると、出力は次のようになります。
#if defined(A) && defined(B) || defined(D) && defined(E)
「&&」は「||」よりも強く結合するため、これは技術的には正しいのですが、混乱への公然たる招待状です。元のように、「&&」条件のセットを括弧で囲むことをお勧めします。
#if (defined(A) && defined(B)) || (defined(D) && defined(E))
ただし、私が使用しなければならないコードの一部が不明瞭であることを考えると、それが最大のつまらないものであるということは、強力な賛辞です。それは私にとって貴重なツールです。
ザ・ニュー・キッド・オン・ザ・ブロック
上記の情報に含まれる URL を確認したところ、(予測どおり) 「sunifdef」の後継であるCoanという新しいプログラムがあることがわかりました。これは SourceForge で入手でき、2010 年 1 月から利用できます。私はそれを調べます...今年後半、または来年、あるいはいつか、またはまったく報告しないでしょう。