Help us understand the problem. What is going on with this article?

DoxyfileなしでDoxygenドキュメント作成とdoxyapp

More than 1 year has passed since last update.

概要

この記事はDoxygenPreviwerのMaking第二弾で、今回はdoxyappとかDoxygenのソースコードをさまよった話を(そして大したところには行きつかなかった話を)書きたいと思います。

やりたかったこと

解決したい問題は前も書きましたがこれですね。

解決策としては:

  1. Doxygenコメント(DoxygenのSpecial Comment Blocksの中身を簡単にこう呼ぶことにします)の中身を静的解析する
  2. ソースコード全体ではなく部品だけでドキュメント生成することですばやく確認できるようにする

という選択肢があるでしょう。
Doxygenのプログラムではどのような解析をしているか、解析したデータを横取りして利用することはできないか、その調査のためにDoxygenの中身を調べました。

Doxygenの中身調査

doxygenプログラムの構造

src/main.cpp
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の特殊コマンドを解析しているのはここだろうという部分は見つかります。

src/cmdMapper.cpp
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;
}
src/cmdMapper.cpp
CommandMap cmdMap[] =
{
  { "a",             CMD_EMPHASIS },
  { "addindex",      CMD_ADDINDEX },
  { "anchor",        CMD_ANCHOR },
  { "arg",           CMD_LI },
:

特殊コマンドの一覧をマップ化し、解析結果を整数で表現しているようです。

parseしたデータはどうなったか?

このデータ構造が垣間見れる個所はたぶんここです:

src/docparser.cpp
  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のためのドキュメントをせっせと作る人もどんどん減ってるんだろうなーと思いました。

hakua-doublemoon
横浜の外周部で組み込み装置のファームウェア開発やってます。RTOSのカーネル・ネットワーク関連からはじまりゴリゴリのHW依存のアプリケーション作ったりQtでGUI作ったり、LabVIEWでの画像処理とかもしてます。Ruby/RailsやRustが好きですがそれは本職とはあんまり関係ない。
https://pawoo.net/web/accounts/586636
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした