概要
この記事はDoxygenPreviwerのMaking第二弾で、今回はdoxyappとかDoxygenのソースコードをさまよった話を(そして大したところには行きつかなかった話を)書きたいと思います。
やりたかったこと
解決したい問題は前も書きましたがこれですね。
解決策としては:
- Doxygenコメント(DoxygenのSpecial Comment Blocksの中身を簡単にこう呼ぶことにします)の中身を静的解析する
- ソースコード全体ではなく部品だけでドキュメント生成することですばやく確認できるようにする
という選択肢があるでしょう。
Doxygenのプログラムではどのような解析をしているか、解析したデータを横取りして利用することはできないか、その調査のためにDoxygenの中身を調べました。
Doxygenの中身調査
doxygenプログラムの構造
int main(int argc,char **argv)
{
initDoxygen();
readConfiguration(argc,argv);
checkConfiguration();
adjustConfiguration();
parseInput();
generateOutput();
return 0;
}
こんな感じで、InputをparseしてOutputをgenerateします。それぞれの関数の実体はひとまずsrc/doxygen.cppにあります。
src/doxygen.cpp以下、doxygenのプログラム全体はクラスを使ったc++ですがcみたいなstatic関数やグローバル変数の使い方も多いので……処理とデータの流れを追うことは難しいです。
あと、doxygenのコードはdoxygenコメントが少ないです。
どのようにparseしているか?
parseInput()を掘っていくとdoxygenの特殊コマンドを解析しているのはここだろうという部分は見つかります。
Mapper *Mappers::cmdMapper = new Mapper(cmdMap,TRUE);
Mapper *Mappers::htmlTagMapper = new Mapper(htmlTagMap,FALSE);
int Mapper::map(const char *n)
{
QCString name=n;
if (!m_cs) name=name.lower();
int *result;
return !name.isEmpty() && (result=m_map.find(name)) ? *result: 0;
}
CommandMap cmdMap[] =
{
{ "a", CMD_EMPHASIS },
{ "addindex", CMD_ADDINDEX },
{ "anchor", CMD_ANCHOR },
{ "arg", CMD_LI },
:
特殊コマンドの一覧をマップ化し、解析結果を整数で表現しているようです。
parseしたデータはどうなったか?
このデータ構造が垣間見れる個所はたぶんここです:
if (Debug::isFlagSet(Debug::PrintTree))
{
// pretty print the result
PrintDocVisitor *v = new PrintDocVisitor;
root->accept(v);
delete v;
}
デバッグフラグを何とか設定するかコードを書き換えると例えば下記のようなデバッグ表示を見ることができます。
<root>
.<para>
..<simplesect type=note>
...<para>
....hogehogehoge
...</para>
:
このroot->accept(v);
のrootが何かしらのデータを持っていることが推測されます。アクセスの様子からツリーのような構造、データのクラスになっていることがわかります。このデータのクラスはQtのクラスをベースにはしていますが、結局は独自実装なので第三者がパッと見て解析できるような代物でもないです。
というわけでこのデータを利用することは諦めました。
ソースコード単体でのDoxygenドキュメント作成とdoxyapp
データの利用は諦めましたが、ソースコード全体をさまよっているうちに、Doxygenのソースコード一式にはaddonフォルダがあり、中にdoxyappというものがあることに気付きました。
doxyappのbriefはこう書いてあります。
Example of how to use doxygen as part of another GPL applications
(GPLなのがちょっと気になりますが)doxygenをカスタマイズするのに使えそうです。
動かしてみると、Doxyfileなしで動作し、ソースコードを解析してシンボルを取り出しているようでした。
なのでちょっと改造すればDoxyfileなしでDoxygenドキュメントを作成できるようになりました。どう改造したかはソースコードをごらんください。
まとめ
総括して言えるのは、やっぱり他人のコードを見るのは大変だということでした。Doxygenは日々メンテナンスされていますが、あれをいじれるのはすごいと思います。
そしてこの一連の記事のアクセス数も大したことないので、まあ今どきCのためのドキュメントをせっせと作る人もどんどん減ってるんだろうなーと思いました。