デバッグコード抽出・続き

コメント(id:pneumaster:20080711:1215715133)でid:fd0さんにunifdefというソフトを教えていただきました.


入っていなかったので,yast --install unifdefでインストール.
id:pneumaster:20080709:1215598038でyast --installの構文間違ってるのか,
# と書きましたが,問題なくインストールできました.

$unifdef -DMACRO file.c

でMACROを定義済みにし,file.c内の#ifdef MACROのブロックが消せます.
逆に#ifndef MACROに対しては,未定義の意味でーUを用います.
こう考えると,#elseに対しても応用が利きますね.
かなり便利です.


というわけで,ちょっとしたコードを書いてみました.
ただ,自分の環境に対して応用してみたので,
一般的じゃないかもしれないです.


まず前提をお話します.
朝方に書いた記事にあるように,gcc -Dオプションでマクロの定義/未定義を操作しますが,
たくさんのソースファイルから作っているので,通常Makefileを使ってます.
このMakefileには次のように書いて,gccにDオプションを与えています.

  (snip)

# DEBUG =
# DEBUG = -DDEBUG_TRACKING_TIME
# DEBUG = -DDEBUG_MESSEAGE -DDEBUG_TRACKING_TIME -DDEBUG_TRACKING
# DEBUG = -DDEBUG_TRACKING_TIME -DDEBUG_DISPLAY_IMGNUM
# DEBUG = -DDEBUG_MESSEAGE -DDEBUG_TRACKING_TIME -DDEBUG_TRACKING -DDEBUG_DISPLAY_IMGNUM -DDEBUG_FUNCTION_TIME
DEBUG = -DDEBUG_MESSEAGE -DDEBUG_TRACKING_TIME -DDEBUG_TRACKING -DDEBUG_DISPLAY_IMGNUM -DDEBUG_FUNCTION_TIME -DDEBUG_DISPLAY_SEARCH_WINDOW

CC = gcc

.c.o:
	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(DEBUG) $<

all: $(TARGET)

clean:

  (snip)

上記の中で「DEBUG = 」で始まる行が-Dオプションです.
分岐をテンプレでいくつか並べておいて,
コメントでスイッチしています.


このマクロをunifdefを呼び出すたびにタイプするのは大変なので,これを解消する目的が一つ.
もう一つは,Makefileと連動させることで,動いているプログラムのソースを吐き出せるようにしてみました.

#!/bin/sh

### unifdef for Makefile
###	Note: must code debug option such the follow statement in Makefile
### 		DEBUG = -Ddebugoption .......
###
makefile="Makefile"

while [ "$#" -gt 0 ]
do
	case $1 in
		-h|--help|-\?)
			echo "  -f Makefile: extract debug option from Makefile"
			echo "  -h         : print this message"
			exit 0
			;;
		-f)
			makefile=$2
			shift
			;;
		*)
			target=$1
			shift
			;;
	esac
	shift
done


if [ -z $target ]; then
	echo "target file not found."
	exit 1
fi

if [ -e $makefile ]; then
	true
else
	echo "$makefile: no such file or directory"
	exit 1
fi


macro=`cat $makefile \
	| egrep '^[^#]*[ \t]*DEBUG[ \t]*=.*$' \
	| LANG=C sed -e 's/^.*DEBUG[ \t]*=[ \t]*\(.*\)/\1/'`
unifdef $macro $target

# 英語は苦手なので触れないでください.
これでMakefile内のDEBUGの部分だけが取り出され,
unifdefの引数に展開されるようにしました.
Makefileのデフォルトは"Makefile"という名前ですが,
"-f"オプションで他のファイルからも取り出せるようになっています.


ただしその中で,上記のMakefileのようなフォーマットで書かれていなければなりません.

  • DEBUGで始まる
  • 次に"="が続く
  • マクロは"-Dマクロ"でその後に続く

こんなフォーマットです.この3つの間はスペースかタブなら許しますし,
行頭にスペースかタブがあっても問題ありません.


unifdef.便利そうです.