diff options
Diffstat (limited to 'test/main.c')
-rwxr-xr-x | test/main.c | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/test/main.c b/test/main.c new file mode 100755 index 0000000..5ba1450 --- /dev/null +++ b/test/main.c @@ -0,0 +1,413 @@ +/* ライブラリの関数呼び出しのテスト + * + * デフォルトでは、test.txtから1行ずつ読み込んで変換を行う。 + * 変換前の文字列と変換を行った結果をtest.expから探し、 + * 変換結果が合っているかをカウントして最後に出力する。 + * + * ./anthy --from 1 --to 10 のように実行するとtest.txtの最初の10個の + * 行の変換テストが行われます。 + * + * --askオプションを付けて実行すると、結果が合っているかの判断を + * 設定するモードになるので、表示された結果に対する判断を + * 標準入力から'y', 'n', 'd', 'q'で入力してください。 + * 'd' dont care, 'q' quit + * 判断できない場合はその他の文字を入力してください。 + * + * Copyright (C) 2000-2006 TABATA Yusuke + * Copyright (C) 2004-2006 YOSHIDA Yuichi + * Copyright (C) 2001-2002 TAKAI Kosuke + * + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> + +#include <anthy/anthy.h> +#include <anthy/convdb.h> +#include <config.h> + +/* Makefile の $(srcdir) (静的データファイルの基準ディレクトリ) */ +#ifndef SRCDIR +# define SRCDIR "." +#endif +/* ビルド時のカレントディレクトリ (ここに .anthy を作る) */ +#ifndef TEST_HOME +# define TEST_HOME "." /* FIXME: 実際は相対パスだと誤動作する */ +#endif + +/* テストデータとなる変換前の文字列 */ +#define TESTDATA "test.txt" +const char *testdata = SRCDIR "/" TESTDATA; + +/* 変換後の文字列が妥当かどうかをチェックするためのデータ */ +#define EXPDATA "test.exp" +const char *expdata = SRCDIR "/" EXPDATA; + +struct input { + char *str; + int serial; +}; + +/* テストを行う条件 */ +struct condition { + /* conversion condition */ + int serial; + int from; + int to; + /* operation */ + int ask; + int quiet; + int miss_only; + int use_utf8; +}; + +static int +read_file(FILE *fp, struct input *in) +{ + char buf[256]; + while(fgets(buf, 256, fp)) { + switch(buf[0]){ + case '#': + case ':': + case '-': + break; + case '*': + if (in->str) { + free(in->str); + in->str = 0; + } + buf[strlen(buf)-1] = 0; + in->str = strdup(&buf[1]); + in->serial ++; + return 0; + break; + } + } + return -1; +} + +static int +check_cond(struct condition *cond, struct input *in) +{ + if (in->serial == cond->serial) { + return 1; + } + if (in->serial <= cond->to && in->serial >= cond->from) { + return 1; + } + return 0; +} + +static void +log_print(int lv, const char *msg) +{ + printf("log:%d:%s\n", lv, msg); +} + +static anthy_context_t +init_lib(int use_utf8) +{ + anthy_context_t ac; + /* 既にインストールされているファイルの影響を受けないようにする */ + anthy_conf_override("CONFFILE", "../anthy-conf"); + anthy_conf_override("HOME", TEST_HOME); + anthy_conf_override("DIC_FILE", "../mkanthydic/anthy.dic"); + anthy_set_logger(log_print, 0); + if (anthy_init()) { + printf("failed to init anthy\n"); + exit(0); + } + anthy_set_personality(""); + + ac = anthy_create_context(); + if (use_utf8) { + anthy_context_set_encoding(ac, ANTHY_UTF8_ENCODING); + } else { + anthy_context_set_encoding(ac, ANTHY_EUC_JP_ENCODING); + } + return ac; +} + +static void +print_usage(void) +{ + printf("Anthy "VERSION"\n" + "./anthy [test-id]\n" + " For example.\n" + " ./anthy 1\n" + " ./anthy --to 100\n" + " ./anthy --from 10 --to 100\n" + " ./anthy --all --print-miss-only --ask\n" + " ./anthy --ll 1\n\n"); + exit(0); +} + +static void +parse_args(struct condition *cond, int argc, char **argv) +{ + int i; + char *arg; + for (i = 1; i < argc; i++) { + arg = argv[i]; + if (!strncmp(arg, "--", 2)) { + arg = &arg[2]; + if (!strcmp(arg, "help") || !strcmp(arg, "version")) { + print_usage(); + } + if (!strcmp(arg, "all")) { + cond->from = 0; + cond->to = 100000000; + } else if (!strcmp(arg, "quiet")) { + cond->quiet = 1; + } else if (!strcmp(arg, "ask") || + !strcmp(arg, "query")) { + cond->ask = 1; + } else if (!strcmp(arg, "print-miss-only")) { + cond->miss_only = 1; + } else if (!strcmp(arg, "utf8")) { + cond->use_utf8 = 1; + } + + if (i + 1 < argc) { + if (!strcmp(arg, "from")){ + cond->from = atoi(argv[i+1]); + i++; + }else if (!strcmp(arg, "to")){ + cond->to = atoi(argv[i+1]); + i++; + }else if (!strcmp(arg, "ll")) { + anthy_set_logger(NULL, atoi(argv[i+1])); + i++; + } + } + } else { + int num = atoi(arg); + if (num) { + cond->serial = num; + } else { + char *buf = alloca(strlen(SRCDIR)+strlen(arg) + 10); + sprintf(buf, SRCDIR "/%s.txt", arg); + testdata = strdup(buf); + } + } + } +} + +static void +print_run_env(void) +{ + time_t t; + const char *env; + env = getenv("ANTHY_ENABLE_DEBUG_PRINT"); + if (!env) { + env = ""; + } + printf("ANTHY_ENABLE_DEBUG_PRINT=(%s)\n", env); + env = getenv("ANTHY_SPLITTER_PRINT"); + if (!env) { + env = ""; + } + printf("ANTHY_SPLITTER_PRINT=(%s)\n", env); + printf("SRCDIR=(%s)\n", SRCDIR); + t = time(&t); + printf(PACKAGE "-" VERSION " %s", ctime(&t)); +} + +static void +sum_up(struct res_db *db, struct conv_res *cr) +{ + int is_split; + struct res_stat *rs; + cr->used = 1; + db->total ++; + if (cr->res_str[0] == '|') { + rs = &db->split; + is_split = 1; + } else { + rs = &db->res; + is_split = 0; + } + if (cr->check == CHK_OK) { + rs->ok ++; + } else if (cr->check == CHK_MISS) { + rs->miss ++; + } else if (cr->check == CHK_DONTCARE) { + rs->dontcare ++; + } else { + rs->unknown ++; + } +} + +static void +set_string(struct condition *cond, struct res_db *db, + struct input *in, anthy_context_t ac) +{ + struct conv_res *cr1, *cr2; + int pr; + + anthy_set_string(ac, in->str); + + /* result */ + cr1 = find_conv_res(db, ac, in->str, 1); + sum_up(db, cr1); + /* split */ + cr2 = find_conv_res(db, ac, in->str, 0); + sum_up(db, cr2); + + /**/ + pr = 0; + if (cond->miss_only) { + if (cr1->check == CHK_MISS || + cr2->check == CHK_MISS) { + pr = 1; + } + } else if (!cond->quiet) { + pr = 1; + } + + if (pr) { + printf("%d:(%s)\n", in->serial, in->str); + anthy_print_context(ac); + } + anthy_reset_context(ac); +} + + +static void +dump_res(FILE *fp, struct conv_res *r) +{ + fprintf(fp, "%s %s ", r->src_str, r->res_str); + if (r->check == CHK_MISS) { + fprintf(fp, "X"); + } else if (r->check == CHK_OK) { + fprintf(fp, "OK"); + } else if (r->check == CHK_DONTCARE) { + fprintf(fp, "*"); + } else { + fprintf(fp, "?"); + } + fprintf(fp, "\n"); +} + +static void +save_db(const char *fn, struct res_db *db) +{ + FILE *fp = fopen(fn, "w"); + struct conv_res *cr; + if (!fp) { + printf("failed to open (%s) to write\n", fn); + return ; + } + for (cr = db->res_list.next; cr; cr = cr->next) { + dump_res(fp, cr); + } +} + +static void +ask_results(struct res_db *db) +{ + struct conv_res *cr; + for (cr = db->res_list.next; cr; cr = cr->next) { + if (cr->check == CHK_UNKNOWN && cr->used == 1) { + char buf[256]; + printf("%s -> %s (y/n/d/q)\n", cr->src_str, cr->res_str); + fgets(buf, 256, stdin); + if (buf[0] == 'y') { + cr->check = CHK_OK; + } else if (buf[0] == 'n') { + cr->check = CHK_MISS; + } else if (buf[0] == 'd') { + cr->check = CHK_DONTCARE; + } else if (buf[0] == 'q') { + return ; + } + } + } +} + +static void +show_stat(struct res_db *db) +{ + struct res_stat *rs; + int i; + /**/ + printf("%d items\n", db->total); + for (i = 0; i < 2; i++) { + if (i == 0) { + printf("conversion result\n"); + rs = &db->res; + } else { + printf("split result\n"); + rs = &db->split; + } + printf("ok : %d\n", rs->ok); + printf("miss : %d\n", rs->miss); + printf("unknown : %d\n", rs->unknown); + printf("\n"); + } +} + +static void +init_condition(struct condition *cond) +{ + cond->serial = 0; + cond->from = 0; + cond->to = 0; + /**/ + cond->quiet = 0; + cond->ask = 0; + cond->miss_only = 0; + cond->use_utf8 = 0; +} + +int +main(int argc,char **argv) +{ + anthy_context_t ac; + FILE *fp; + struct input cur_input; + struct res_db *db; + struct condition cond; + + cur_input.serial = 0; + cur_input.str = 0; + init_condition(&cond); + + parse_args(&cond, argc, argv); + db = create_db(); + read_db(db, expdata); + + printf("./test_anthy --help to print usage.\n"); + + print_run_env(); + + fp = fopen(testdata, "r"); + if (!fp) { + printf("failed to open %s.\n", testdata); + return 0; + } + + ac = init_lib(cond.use_utf8); + + /* ファイルを読んでいくループ */ + while (!read_file(fp, &cur_input)) { + if (check_cond(&cond, &cur_input)) { + set_string(&cond, db, &cur_input, ac); + } + } + + anthy_release_context(ac); + anthy_quit(); + + if (cond.ask) { + /* ユーザに聞く */ + ask_results(db); + } + + show_stat(db); + save_db(expdata, db); + + return 0; +} |