デバッグコード抽出

デバッグやちょっとしたテスト用に、
ifdef/endifでマクロを書いておいて、
必要な部分をgccの-Dオプションでコンパイルしたりしますよね。


例えばこんな感じ?
# すごい無駄なコードだけれど。。。

int 
main()
{
#ifdef OPENSUSE
        puts("geeko");
#else
        puts("tux");
#endif /* OPENSUSE */
        return 0;
}
$ gcc -DOPENSUSE src.c
$ ./a.out
geeko
$ gcc src.c
$ ./a.out
tux


わたしは、ひとつの関数ができるだけ短く、シンプルになるように
努めて書いているつもりなのですが、
上のデバッグコードをいくつも入れていたら、
結局のところ本末転倒に。。。


gccで、コンパイル対象の部分を抽出してくれると嬉しいのですが、
見つからなかったので書いてみました。perlで。
正規表現の本のサンプルコードを多少試した程度なので、
perlの基本も何もできてないかもしれません。
こうするべき、だというところがあったらご指摘ください。

#!/usr/bin/perl -w

while ($input = <>) {
        chop($input);
        if ($input =~ m/^(\s)*#ifdef(\s)*(.*)$/) {
                push @stack, $3;
        }
        if ($#stack + 1 == 0) {
                $text .= $input . "\n";
        }
        if ($input =~ m/^(\s)*#endif.*$/) {
                pop @stack;
        }
}
print $text;


一応、2時間くらいでここまで書いてみた。
使い方は

$ perl script.pl src.c

です。src.c内で、ifdefブロックを消去した後のコードを標準出力に表示します。


次に変更していく箇所

  1. 特定のマクロに対するifdefブロック消去
  2. コマンドラインからのマクロ入力


後者は<>で書いているところを$ARGV[0]を使ってやるのかな。
open()使わないとならないのかしら。
できれば<>っぽい表現で短く書きたいと思っています。


また、消去するマクロ名は$ARGV[1]から入力させるのがいいのかな。
もっといい設計があるのでしょうか。