visitors 0.5 の出力部分

Vistors 0.5で解析結果を出力(フォーマット)している部分を探ってみた。

C言語はほとんどわからないのにがんばったさ。何で探ったのかというと、解析結果を他のプロ グラムで使いたくてINIファイルの形式で出力したかった。デフォルトのtextやhtmlをこねくり回す労力と比べたら出力フォーマットを追加してやるほうが楽になると思った。

とにかくC言語はわからないけど、なんか「Strategyパターン」みたいなのはわかった。ちょっと「これがハッカーのコードか!?」と関心した。

* 構造体 outputmodule

struct outputmodule {
    void (*print_header)(FILE *fp);
    void (*print_footer)(FILE *fp);
    void (*print_title)(FILE *fp, char *title);
    void (*print_subtitle)(FILE *fp, char *title);
    void (*print_numkey_info)(FILE *fp, char *key, int val);
    void (*print_keykey_entry)(FILE *fp, char *key1, char *key2, int num);
    void (*print_numkey_entry)(FILE *fp, char *key, int val, char *link,
            int num);
    void (*print_numkeybar_entry)(FILE *fp, char *key, int max, int tot,
            int this);
    void (*print_numkeycomparativebar_entry)(FILE *fp, char *key, int tot,
            int this);
    void (*print_bidimentional_map)(FILE *fp, int xlen, int ylen,
            char **xlabel, char **ylabel, int *value);
    void (*print_hline)(FILE *fp);
    void (*print_credits)(FILE *fp);
    void (*print_report_link)(FILE *fp, char *report);
};

* テキスト出力用モジュール

struct outputmodule OutputModuleText = {
    om_text_print_header,
    om_text_print_footer,
    om_text_print_title,
    om_text_print_subtitle,
    om_text_print_numkey_info,
    om_text_print_keykey_entry,
    om_text_print_numkey_entry,
    om_text_print_numkeybar_entry,
    om_text_print_numkeycomparativebar_entry,
    om_text_print_bidimentional_map,
    om_text_print_hline,
    om_text_print_credits,
    om_text_print_report_link,
};

* HTML出力用モジュール

struct outputmodule OutputModuleHtml = {
    om_html_print_header,
    om_html_print_footer,
    om_html_print_title,
    om_html_print_subtitle,
    om_html_print_numkey_info,
    om_html_print_keykey_entry,
    om_html_print_numkey_entry,
    om_html_print_numkeybar_entry,
    om_html_print_numkeycomparativebar_entry,
    om_html_print_bidimentional_map,
    om_html_print_hline,
    om_html_print_credits,
    om_html_print_report_link,
};

この3つがポイント。
main()Output っていう outputmodule 型のポインタに OutputModuleText または OutputModuleHtml を代入してる。

で、実際の出力する部分は Output->print_title とか Output->print_credits ってコードになってる。 Output にどちらが入ってても outputmodule で定義された関数を呼び出せるのだ。すばらしぃ。

で、出力フォーマットの追加部分は OutputModuleText と同じように関数ポインタの実体?を実装すればいいというわけだ。



$Date: 2009-04-15 23:51:04 +0900 (Wed, 15 Apr 2009) $