Cプログラムのヘッダーおよびソースファイルから関数定義部を抽出する
表題の方法を調べたのでメモしておく。なお、C++のクラスや構造体からのメンバー関数の抽出などはとりあえず考えていない。
中核をなす処理は関数定義部の抽出で、これにはctagsを使う。ただし、ctagsは関数定義部が複数行に分割されている時には最初の1行しか抽出できない。そこで事前にclang-formatで関数をフォーマットして関数定義部を1行にしてしまう。
ヘッダー部分を1行に整形する
clang-formatを使うと簡単にC/C++プログラムを整形できる。整形の方法として多様なオプションが用意されているが、今回は関数定義部のみ抽出すればいいので、それに見合った整形をする。要するに途中で折り返しが起きないよう、1行の長さを長くしてしまえばいい。
--styl
e引数のColumnLimit:
によって指定できる。ColumnLimit:
は':'の後ろに空白が必要であることに注意。
clang-format foo.h --style="{ColumnLimit: 9999}" > bar.h
結果を標準出力ではなくファイルに出力しているのは後述のctagsの制限による。
関数定義部の抽出
ctagsは本来エディタ向けのツールで、ソースコードからインデックス情報を取り出すためのものである。これに-x
オプションを与えると、結果をテキストにしてくれる。--c++-kinds=pf
は、static
および非static
な関数の双方を抽出するよう指示している。
なお、ctagsはソースコードを標準入力から受け取ることはできない。
ctags -x --c++-kinds=pf bar.h
ただ、これだけだと不要な情報が含まれる。具体的には
- 関数定義部に続く関数本体などが同じ行にあると、そのまま出力される。
- 関数プロトタイプの
;
が出力される。 - インデックスのための情報が出力される。
そこで、以下のパイプラインで不要な情報を削除している。
まず、{
以降行末までと、;
以降行末までをsedで削除する。
sed s/{.*$// | sed s/\;.*$//
次に、インデックス情報である最初の4つのフィールドをawkで空欄にする。
awk '{$1="";$2="";$3="";$4="";print $0}'
最後に、inline
,static
といった不要なキーワードをsedで削除する。
sed s/static// | sed s/inline//
これらを合わせて一つにすると、以下の通りになる。
ctags -x --c++-kinds=pf bar.h | sed s/{.*$// | sed s/\;.*$// | awk '{$1="";$2="";$3="";$4="";print $0}'| sed s/static// | sed s/inline//