注意: このセクションはまだ作成中です!
以下の図は、ソースファイルがDoxygenによってどのように処理されるかを示しています。
以下のセクションでは、上記のステップについてより詳細に説明します。
プロジェクトの設定を制御する設定ファイルが解析され、設定はシングルトンクラス Config
(src/config.h
内) に格納されます。パーサー自体は flex
を使用して記述されており、src/config.l
にあります。このパーサーは Doxywizard でも直接使用されるため、別のライブラリにまとめられています。
各設定オプションには、String
、List
、Enum
、Int
、または Bool
の5つの可能なタイプのうちの1つがあります。これらのオプションの値は、グローバル関数 Config_getXXX()
(XXX
はオプションのタイプ) を介して利用できます。これらの関数の引数は、設定ファイルに表示されるオプションの名前の文字列です。たとえば、Config_getBool(GENERATE_TESTLIST)
は、設定ファイルでテストリストが有効になっている場合に TRUE
であるブール値への参照を返します。
src/doxygen.cpp
内の関数 readConfiguration()
は、コマンドラインオプションを読み取り、その後設定パーサーを呼び出します。
設定ファイルで言及されている入力ファイルは、(デフォルトで)Cプリプロセッサに(利用可能な場合はユーザー定義のフィルターを通してパイプされた後)渡されます。
プリプロセッサの動作方法は、標準的なCプリプロセッサとは多少異なります。デフォルトでは、すべてのマクロを展開するように設定できますが、マクロ展開は行いません。一般的な使用法は、ユーザーが指定したマクロのセットのみを展開することです。これは、たとえば関数パラメータの型にマクロ名を表示できるようにするためです。
もう1つの違いは、プリプロセッサは #include
を検出した場合にコードを解析しますが、実際にはインクルードしないことです({ ... } ブロック内にある #include
は例外です)。この標準からの逸脱の背後にある理由は、同じ関数/クラスの複数の定義をDoxygenのパーサーに渡すのを防ぐためです。たとえば、すべてのソースファイルが共通のヘッダーファイルをインクルードする場合、クラスと型の定義(およびそれらのドキュメント)は各翻訳単位に存在することになります。
プリプロセッサは flex
を使用して記述されており、src/pre.l
にあります。条件ブロック (#if
) の場合、定数式の評価が必要です。このために、yacc
ベースのパーサーが使用されており、src/constexp.y
および src/constexp.l
にあります。
プリプロセッサは、src/pre.h
で宣言されている関数 preprocessFile()
を使用してファイルごとに呼び出され、プリプロセスされた結果を文字バッファに追加します。文字バッファの形式は次のとおりです。
0x06 file name 1 0x06 preprocessed contents of file 1 ... 0x06 file name n 0x06 preprocessed contents of file n
プリプロセスされた入力バッファは、言語パーサーに渡されます。これは、flex
を使用した大きなステートマシンとして実装されています。これは、ファイル src/scanner.l
にあります。すべての言語(C/C++/Java/IDL)に対して1つのパーサーがあります。状態変数 insideIDL
および insideJava
は、言語固有の選択のために一部の場所で使用されます。
パーサーのタスクは、入力バッファをエントリのツリー(基本的には抽象構文木)に変換することです。エントリは src/entry.h
で定義されており、構造化されていない情報のblobです。最も重要なフィールドは section
であり、エントリに含まれる情報の種類を指定します。
将来のバージョンでの改善の可能性
このステップは、抽出されたクラス、ファイル、名前空間、変数、関数、パッケージ、ページ、およびグループの辞書を構築する多くの小さなステップで構成されています。辞書の構築に加えて、このステップ中に、抽出されたエンティティ間の関係(継承関係など)が計算されます。
各ステップには、言語解析中に構築されたエントリのツリーを操作する関数が src/doxygen.cpp
で定義されています。詳細については、parseInput()
の「情報の収集」部分を参照してください。
このステップの結果は、src/doxygen.h
で定義されている Doxygen "名前空間" にある多数の辞書です。これらの辞書のほとんどの要素は、クラス Definition
から派生しています。たとえば、クラス MemberDef
は、メンバーに関するすべての情報を保持します。このようなクラスのインスタンスは、ファイル (クラス FileDef
)、クラス (クラス ClassDef
)、名前空間 (クラス NamespaceDef
)、グループ (クラス GroupDef
)、または Java パッケージ (クラス PackageDef
) の一部になることができます。
設定ファイルでタグファイルが指定されている場合、これらは src/tagreader.cpp
にある SAX ベースの XML パーサーによって解析されます。タグファイルの解析結果は、エントリツリーへの Entry
オブジェクトの挿入です。フィールド Entry::tagInfo
は、エントリを外部としてマークするために使用され、タグファイルに関する情報を保持します。
特別なコメントブロックは、ドキュメント化するエンティティに文字列として格納されます。簡単な説明のための文字列と、詳細な説明のための文字列があります。ドキュメントパーサーはこれらの文字列を読み取り、その中に見つかったコマンドを実行します(これはドキュメントを解析する2回目のパスです)。結果は出力ジェネレーターに直接書き込まれます。
パーサーは C++ で記述されており、src/docparser.cpp
にあります。パーサーによって消費されるトークンは、src/doctokenizer.l
から来ています。コメントブロックで見つかったコードフラグメントは、ソースパーサーに渡されます。
ドキュメントパーサーのメインエントリポイントは、src/docparser.h
で宣言されている validatingParseDoc()
です。特別なコマンドを含む単純なテキストの場合、validatingParseText()
が使用されます。
ソースブラウジングが有効になっている場合、またはコードフラグメントがドキュメント内で検出された場合、ソースパーサーが呼び出されます。
コードパーサーは、解析するソースコードをドキュメント化されたエンティティと相互参照しようとします。また、ソースの構文強調表示も行います。出力は出力ジェネレーターに直接書き込まれます。
コードパーサーのメインエントリポイントは、src/code.h
で宣言されている parseCode()
です。
データが収集され、相互参照された後、Doxygen はさまざまな形式で出力を生成します。このために、抽象クラス OutputGenerator
によって提供されるメソッドを使用します。複数の形式で同時に出力を生成するために、代わりに OutputList
のメソッドが呼び出されます。このクラスは、具体的な出力ジェネレーターのリストを保持しており、呼び出された各メソッドはリスト内のすべてのジェネレーターに委譲されます。
具体的な出力ジェネレーターごとに出力に書き込まれる内容にわずかな逸脱を許容するために、特定のジェネレーターを一時的に無効にすることができます。OutputList クラスには、このためのさまざまな disable()
および enable()
メソッドが含まれています。メソッド OutputList::pushGeneratorState()
および OutputList::popGeneratorState()
は、有効/無効になっている出力ジェネレーターのセットをスタックに一時的に保存するために使用されます。
XML は、収集されたデータ構造から直接生成されます。将来的には、XML は中間言語 (IL) として使用される予定です。出力ジェネレーターは、この IL を開始点として使用して、特定の出力形式を生成します。IL を持つことの利点は、さまざまな言語で記述されたさまざまな独立して開発されたツールが、XML 出力から情報を抽出できることです。考えられるツールは次のとおりです。
Doxygen は多くの flex
コードを使用しているため、flex
がどのように動作するか(これについては man
ページを読む必要があります)と、flex
が入力の一部を解析するときに何をしているかを理解することが重要です。幸いなことに、flex
を -d
オプションで使用すると、どのルールが一致したかが出力されます。これにより、特定の入力フラグメントに対して何が起こっているかを非常に簡単に追跡できます。
特定の flex
ファイルのデバッグ情報を切り替えるのを容易にするために、Makefile:
の正しい行から -d
を自動的に追加または削除する次の perl
スクリプトを作成しました。
#!/usr/bin/perl $file = shift @ARGV; print "Toggle debugging mode for $file\n"; if (!-e "../src/${file}.l") { print STDERR "Error: file ../src/${file}.l does not exist!\n"; exit 1; } system("touch ../src/${file}.l"); unless (rename "src/CMakeFiles/doxymain.dir/build.make","src/CMakeFiles/doxymain.dir/build.make.old") { print STDERR "Error: cannot rename src/CMakeFiles/doxymain.dir/build.make!\n"; exit 1; } if (open(F,"<src/CMakeFiles/doxymain.dir/build.make.old")) { unless (open(G,">src/CMakeFiles/doxymain.dir/build.make")) { print STDERR "Error: opening file build.make for writing\n"; exit 1; } print "Processing build.make...\n"; while (<F>) { if ( s/flex \$\(LEX_FLAGS\) -d(.*) ${file}.l/flex \$(LEX_FLAGS)$1 ${file}.l/ ) { print "Disabling debug info for $file\n"; } elsif ( s/flex \$\(LEX_FLAGS\)(.*) ${file}.l$/flex \$(LEX_FLAGS) -d$1 ${file}.l/ ) { print "Enabling debug info for $file.l\n"; } print G "$_"; } close F; unlink "src/CMakeFiles/doxymain.dir/build.make.old"; } else { print STDERR "Warning file src/CMakeFiles/doxymain.dir/build.make does not exist!\n"; } # touch the file $now = time; utime $now, $now, $file;
flex
コードからルールマッチング/デバッグ情報を取得するもう1つの方法は、make
で LEX_FLAGS
を設定することです (make LEX_FLAGS=-d
)。
デフォルトでは、Doxygen のデバッグバージョン (つまり、CMake
設定 -DCMAKE_BUILD_TYPE=Debug
で作成された実行可能ファイル) は、すべての flex codefile
に対して flex
デバッグ情報を自動的に持ちます。
-d lex
を付けて Doxygen を実行すると、どの flex codefile
が使用されているかに関する情報が得られることに注意してください。flex デバッグオプションでコンパイルされた flex パーサーの情報を見るには、Doxygen を実行するときに -d lex:<flex codefile>
を指定する必要があります。
lex 解析に関する情報は stderr
に出力され、他のデバッグ出力は -d stderr
を使用しない限り、デフォルトで stdout
に出力されることに注意してください。
Doxygen には、コードの整合性などをテストするために利用できる小さなテストセットがあります。テストは、コマンド make tests
で実行できます。1つまたは少数のテストのみが必要な場合は、テストを実行するときに変数 TEST_FLAGS
を設定できます。たとえば、make TEST_FLAGS="--id 5" tests
または複数のテストの場合は make TEST_FLAGS="--id 5 --id 7" tests
です。すべての可能性のあるオプションについては、コマンド make TEST_FLAGS="--help" tests
を実行してください。TEST_FLAGS
を環境変数として指定することもできます (Visual Studio プロジェクトを介したテストにも対応)。たとえば、setenv TEST_FLAGS "--id 5 --id 7"
と make tests
です。
フォーラムなどを介して、標準の Doxygen 設定ファイルの設定とは異なる設定を伝達する必要がある場合、Doxygen コマンドを -x
オプションと設定ファイルの名前 (デフォルトは Doxyfile
) を付けて実行できます。出力は、デフォルト設定ではない設定のリストになります (Doxyfile
形式)。または、-x_noenv
も可能で、これは -x
オプションと同じですが、環境変数と CMake
タイプ置換変数を置き換えない点が異なります。
インデックスに戻る。