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 と同じように関数ポインタの実体?を実装すればいいというわけだ。