C API定義を作っている本人も把握していない問題にどう立ち向かうか
...does anyone know of a tool that will parse a C header and tell you all the symbols exported from it (including functions, enums, preprocessor defines)?
まぁ難しいよねぇ
abigail
この検索性最悪のツールがABIの変化を検出するのによく使われる。
- ○ 検出できる
- 関数
- 構造体メンバとレイアウト
- 変数
- × 検出できない
enum
- マクロ
gcc -dM
gccやclangには "定義されたCマクロをダンプする" 機能があるので、これを活用するとヘッダが定義するマクロを抽出できる。
-
git grep -h "#include <" include > dump.h
のようにして、APIヘッダがincludeしているヘッダの集合をダンプする - (
dump.h
からシステムに存在しないヘッダを除去する ) -
gcc -E -dM dump.h | sort > before.h
のようにして、APIヘッダがincludeしているヘッダによって定義されるマクロの一覧を抽出する (これには__unix
のようなシステムが事前定義しているマクロも含まれる) -
gcc -E -dM include/SDL.h | sort > after.h
のようにして、APIヘッダが定義しているマクロを抽出する -
git diff --no-index before.h after.h | grep ^\\+
で追加分を求める
例えば Cygwinで実行すると
いくつかおかしい点がある。
- SDLはCygwinを歴史的事情によりWin32プラットフォームと見做しているため、
WIN32
等がSDLによって定義されている -
_SDL_locale_h
は他のinclude guardマクロの命名規則と異なっている - (既にissueに上がっているように、)
AUDIO_S32MSB
などいくつかのAPIマクロはSDL_
のプレフィックスを持たない
cl.exe /PD
ドキュメントによると /PD
オプションでVisual Studioでも相応のことができるらしい。
/PD
すべてのマクロ定義を出力します。
これで行けるんだろうか。。.hは直接は処理できなさそうなので
cl : Command line warning D9024 : unrecognized source file type 'dump.h', object file assumed
includeだけするソースコードを別途与えることにした。
#include "dump.h"
これで cl /Zc:preprocessor /PD dump.c > beforewin32.h
のようにするとマクロがダンプできた。
pp-trace
Clangには pp-trace
ツールがあるのでもっと賢く実施できる。
clangは大抵のプラットフォームで gcc や cl.exe のエミュレーションを提供しているので、 ↑ のような方法でマクロやプリプロセスの結果をダンプして比較しつつ、clangの pp-trace に掛けるのが確実だろう。
ASTを使う
... Doxygen のようなドキュメントツールはヘッダをパースすることで enum
やその他のAPI要素のリストを出力できる。はず。
また、clangのASTはjson形式でダンプでき、ときどき異常なjsonを出力するのも修正( https://reviews.llvm.org/D108441#change-I7KZj5Lh9yQ8 )されている。