仕様文書を抽出する


という訳で、インライン函数をやめると、函数の仕様はhoge.cppを見れば すべて足りる、という状況にまた1歩近づく訳です。

開発中は、その函数がどう実装されているか、も見たくなることが多いので、 hoge.cppを直接参照します。 でも、ここから函数の中身(実装)を取り除いて適当に整形すれば、 ほかの人にも見せられる仕様文書、まあ函数のリファレンスですな、 それを作ることができます。

という訳で、それを実際に作るスクリプトを紹介。 これは、

        &mk_specs("hoge.cpp", "hoge.html");

という具合に呼び出すと、hoge.cpp から必要部分を集めて、 hoge.htmlに出力します。普通はソースファイルがいくつもあるでしょうから、 *.cppすべてについて*.htmlを生成することになります。


# ---------------------------------------------------------------------
sub mk_specs {
        local($cpp, $htmlName) = @_;
        open(FILE, $cpp) || die "Can't open $cpp\n";
        open(OUT, "> $htmlName") || die "Can't open $htmlName\n";
        print OUT "<HTML>\n";
        print OUT "<HEAD>\n<TITLE>$cpp</TITLE>\n</HEAD>\n";
        print OUT "<BODY>\n<H1>$cpp</H1>\n<HR>\n";
        print OUT "<PRE>\n";
        $write = 1;
        while (<FILE>) {
                chop;
                if (/^#/) {
                        $write = 0;
                }
                next if /^\s*$/;
                next if /^static/;
                if ($write) {
                        if (/^{/) {                             # (B)
                                $write = 0;
                                next;
                        }
                        s/&/&amp;/g;
                        s/</&lt;/g;
                        s/>/&gt;/g;
                        print OUT "$_\n";
                        if (/\)\s*:/) {                         # (C)
                                $write = 0;
                                next;
                        }
                }
                else {
                        if ((m:^/\*===:) || (m:^/\*---:)) {     # (A)
                                $write = 1;
                                print OUT "\n$_\n";
                        }
                }
        }
        print OUT "</PRE>\n";
        print OUT "<HR>\n<A HREF=\"index.html\">back to index</A>\n";
        print OUT "</BODY>\n";
        print OUT "</HTML>\n";
        close(FILE);
        close(OUT);
}

一応註釈。 C++とのつきあい方(2)で書いたように、 publicやprotectedの函数は/*=====/*-----のような 水平線がついていて、目立つようになっています。 private函数はこの仕様文書には載せません。 という訳で、この水平線が現れたら抽出を始めます(A)。 函数の機能の説明、引数の意味などはその後ろに書いてあります。

函数の実体が始まるところは行頭が{になっています。 これが現れたら抽出をやめます(B)。

構築子の場合、{の前に初期化並びが現れますが、これは抽出をやめようと いうことで、(C)があります。このパターンは、構築子が

        Hoge::Hoge(
                int             munya) :
                        Munya(munya)
        {
                ...
        }

という形になっていることを前提にしています。

ここに示したのは骨組みだけなので、キーワードを強調する (s/\bchar\b/<STRONG>char</STRONG>/g;)とかは 適宜追加して使ってください。 HTMLで出力するのは、実はこういう細工がいろいろできるからなのです。 ついでに目次なんかも生成するようにすればいいですね。