GNU cflow vs パブリックドメイン cflow
今まで cflow を過小評価していた。あらかじめ
$ for i in *.c; do cflow $i > $i.cflow; done
としておいて :grep 関数名 *.cflow とすればクロスリファレンスにもなるし、vim のキー入力のように関数呼び出しが深いソースを読むときは超役に立つ。相互に呼びあってるのでなければ図示化しなくても十分見やすいし。
しかし GNU cflow は関数定義の検出にけっこう漏れがある。特に vim のソースとは相性が悪いのか、ui.c に cflow をかけてみると30/68 ≒ 44% もの関数が抜けてしまう。
なので、FreeBSD ports にも入っていたパブリックドメイン版を使ってみた。
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/cflow-2.0.tar.gz
普通に make してもコンパイルが通らないので FreeBSD ports の patch-ab をあてる。
http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/cflow/files/
そしてテストとして
$ cflow prcc.c
をやってみると何も出力されない。
__asm__ や __attribute__ などが使われているとだめなので patch-ac と同じように cpp に
-D__attribute__(x)= -D__asm__(x)=
をつけることで対処。
patch-ac で __asm__ に対応していないのは、FreeBSD のヘッダでは __asm__ がほとんど使われていないからかもしれない。
パブリックドメイン版 cflow は cpp を呼び出すため、次のメリット・デメリットがある。
- プリプロセッサディレクティブによりコンパイルされないコードを除外できる
- コンパイル時と同じ -I -D オプションを指定しなければならない
- 関数形のマクロが展開されてしまい、コールグラフに出力されない
場合によっては cpp を通さずに
prcc hoge.c | prcg
とした方がいいかもしれない。
ui.c にパブリックドメイン版 cflow をかけてみたところ、なぜか ui_write() だけが抜けていた。