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

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

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

下記3つの構造体がポイント。

構造体 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,
};

main()Output という outputmodule 型のポインタに OutputModuleText または OutputModuleHtml を代入してる。

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

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



最終更新日: 2015年05月16日(土)

Back to top