1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22: #include <stdio.h>
23: #include <string.h>
24: #include <stdlib.h>
25: #include <time.h>
26:
27: #include <anthy/anthy.h>
28: #include <anthy/convdb.h>
29: #include <config.h>
30:
31:
32: #ifndef SRCDIR
33: # define SRCDIR "."
34: #endif
35:
36: #ifndef TEST_HOME
37: # define TEST_HOME "."
38: #endif
39:
40:
41: #define TESTDATA "test.txt"
42: const char *testdata = SRCDIR "/" TESTDATA;
43:
44:
45: #define EXPDATA "test.exp"
46: const char *expdata = SRCDIR "/" EXPDATA;
47:
48: struct input {
49: char *str;
50: int serial;
51: };
52:
53:
54: struct condition {
55:
56: int serial;
57: int from;
58: int to;
59:
60: int ask;
61: int quiet;
62: int miss_only;
63: int use_utf8;
64: };
65:
66: static int
67: read_file(FILE *fp, struct input *in)
68: {
69: char buf[256];
70: while(fgets(buf, 256, fp)) {
71: switch(buf[0]){
72: case '#':
73: case ':':
74: case '-':
75: break;
76: case '*':
77: if (in->str) {
78: free(in->str);
79: in->str = 0;
80: }
81: buf[strlen(buf)-1] = 0;
82: in->str = strdup(&buf[1]);
83: in->serial ++;
84: return 0;
85: break;
86: }
87: }
88: return -1;
89: }
90:
91: static int
92: check_cond(struct condition *cond, struct input *in)
93: {
94: if (in->serial == cond->serial) {
95: return 1;
96: }
97: if (in->serial <= cond->to && in->serial >= cond->from) {
98: return 1;
99: }
100: return 0;
101: }
102:
103: static void
104: log_print(int lv, const char *msg)
105: {
106: printf("log:%d:%s\n", lv, msg);
107: }
108:
109: static anthy_context_t
110: init_lib(int use_utf8)
111: {
112: anthy_context_t ac;
113:
114: anthy_conf_override("CONFFILE", "../anthy-conf");
115: anthy_conf_override("HOME", TEST_HOME);
116: anthy_conf_override("DIC_FILE", "../mkanthydic/anthy.dic");
117: anthy_set_logger(log_print, 0);
118: if (anthy_init()) {
119: printf("failed to init anthy\n");
120: exit(0);
121: }
122: anthy_set_personality("");
123:
124: ac = anthy_create_context();
125: if (use_utf8) {
126: anthy_context_set_encoding(ac, ANTHY_UTF8_ENCODING);
127: } else {
128: anthy_context_set_encoding(ac, ANTHY_EUC_JP_ENCODING);
129: }
130: return ac;
131: }
132:
133: static void
134: print_usage(void)
135: {
136: printf("Anthy "VERSION"\n"
137: "./anthy [test-id]\n"
138: " For example.\n"
139: " ./anthy 1\n"
140: " ./anthy --to 100\n"
141: " ./anthy --from 10 --to 100\n"
142: " ./anthy --all --print-miss-only --ask\n"
143: " ./anthy --ll 1\n\n");
144: exit(0);
145: }
146:
147: static void
148: parse_args(struct condition *cond, int argc, char **argv)
149: {
150: int i;
151: char *arg;
152: for (i = 1; i < argc; i++) {
153: arg = argv[i];
154: if (!strncmp(arg, "--", 2)) {
155: arg = &arg[2];
156: if (!strcmp(arg, "help") || !strcmp(arg, "version")) {
157: print_usage();
158: }
159: if (!strcmp(arg, "all")) {
160: cond->from = 0;
161: cond->to = 100000000;
162: } else if (!strcmp(arg, "quiet")) {
163: cond->quiet = 1;
164: } else if (!strcmp(arg, "ask") ||
165: !strcmp(arg, "query")) {
166: cond->ask = 1;
167: } else if (!strcmp(arg, "print-miss-only")) {
168: cond->miss_only = 1;
169: } else if (!strcmp(arg, "utf8")) {
170: cond->use_utf8 = 1;
171: }
172:
173: if (i + 1 < argc) {
174: if (!strcmp(arg, "from")){
175: cond->from = atoi(argv[i+1]);
176: i++;
177: }else if (!strcmp(arg, "to")){
178: cond->to = atoi(argv[i+1]);
179: i++;
180: }else if (!strcmp(arg, "ll")) {
181: anthy_set_logger(NULL, atoi(argv[i+1]));
182: i++;
183: }
184: }
185: } else {
186: int num = atoi(arg);
187: if (num) {
188: cond->serial = num;
189: } else {
190: char *buf = alloca(strlen(SRCDIR)+strlen(arg) + 10);
191: sprintf(buf, SRCDIR "/%s.txt", arg);
192: testdata = strdup(buf);
193: }
194: }
195: }
196: }
197:
198: static void
199: print_run_env(void)
200: {
201: time_t t;
202: const char *env;
203: env = getenv("ANTHY_ENABLE_DEBUG_PRINT");
204: if (!env) {
205: env = "";
206: }
207: printf("ANTHY_ENABLE_DEBUG_PRINT=(%s)\n", env);
208: env = getenv("ANTHY_SPLITTER_PRINT");
209: if (!env) {
210: env = "";
211: }
212: printf("ANTHY_SPLITTER_PRINT=(%s)\n", env);
213: printf("SRCDIR=(%s)\n", SRCDIR);
214: t = time(&t);
215: printf(PACKAGE "-" VERSION " %s", ctime(&t));
216: }
217:
218: static void
219: sum_up(struct res_db *db, struct conv_res *cr)
220: {
221: int is_split;
222: struct res_stat *rs;
223: cr->used = 1;
224: db->total ++;
225: if (cr->res_str[0] == '|') {
226: rs = &db->split;
227: is_split = 1;
228: } else {
229: rs = &db->res;
230: is_split = 0;
231: }
232: if (cr->check == CHK_OK) {
233: rs->ok ++;
234: } else if (cr->check == CHK_MISS) {
235: rs->miss ++;
236: } else if (cr->check == CHK_DONTCARE) {
237: rs->dontcare ++;
238: } else {
239: rs->unknown ++;
240: }
241: }
242:
243: static void
244: set_string(struct condition *cond, struct res_db *db,
245: struct input *in, anthy_context_t ac)
246: {
247: struct conv_res *cr1, *cr2;
248: int pr;
249:
250: anthy_set_string(ac, in->str);
251:
252:
253: cr1 = find_conv_res(db, ac, in->str, 1);
254: sum_up(db, cr1);
255:
256: cr2 = find_conv_res(db, ac, in->str, 0);
257: sum_up(db, cr2);
258:
259:
260: pr = 0;
261: if (cond->miss_only) {
262: if (cr1->check == CHK_MISS ||
263: cr2->check == CHK_MISS) {
264: pr = 1;
265: }
266: } else if (!cond->quiet) {
267: pr = 1;
268: }
269:
270: if (pr) {
271: printf("%d:(%s)\n", in->serial, in->str);
272: anthy_print_context(ac);
273: }
274: anthy_reset_context(ac);
275: }
276:
277:
278: static void
279: dump_res(FILE *fp, struct conv_res *r)
280: {
281: fprintf(fp, "%s %s ", r->src_str, r->res_str);
282: if (r->check == CHK_MISS) {
283: fprintf(fp, "X");
284: } else if (r->check == CHK_OK) {
285: fprintf(fp, "OK");
286: } else if (r->check == CHK_DONTCARE) {
287: fprintf(fp, "*");
288: } else {
289: fprintf(fp, "?");
290: }
291: fprintf(fp, "\n");
292: }
293:
294: static void
295: save_db(const char *fn, struct res_db *db)
296: {
297: FILE *fp = fopen(fn, "w");
298: struct conv_res *cr;
299: if (!fp) {
300: printf("failed to open (%s) to write\n", fn);
301: return ;
302: }
303: for (cr = db->res_list.next; cr; cr = cr->next) {
304: dump_res(fp, cr);
305: }
306: }
307:
308: static void
309: ask_results(struct res_db *db)
310: {
311: struct conv_res *cr;
312: for (cr = db->res_list.next; cr; cr = cr->next) {
313: if (cr->check == CHK_UNKNOWN && cr->used == 1) {
314: char buf[256];
315: printf("%s -> %s (y/n/d/q)\n", cr->src_str, cr->res_str);
316: fgets(buf, 256, stdin);
317: if (buf[0] == 'y') {
318: cr->check = CHK_OK;
319: } else if (buf[0] == 'n') {
320: cr->check = CHK_MISS;
321: } else if (buf[0] == 'd') {
322: cr->check = CHK_DONTCARE;
323: } else if (buf[0] == 'q') {
324: return ;
325: }
326: }
327: }
328: }
329:
330: static void
331: show_stat(struct res_db *db)
332: {
333: struct res_stat *rs;
334: int i;
335:
336: printf("%d items\n", db->total);
337: for (i = 0; i < 2; i++) {
338: if (i == 0) {
339: printf("conversion result\n");
340: rs = &db->res;
341: } else {
342: printf("split result\n");
343: rs = &db->split;
344: }
345: printf("ok : %d\n", rs->ok);
346: printf("miss : %d\n", rs->miss);
347: printf("unknown : %d\n", rs->unknown);
348: printf("\n");
349: }
350: }
351:
352: static void
353: init_condition(struct condition *cond)
354: {
355: cond->serial = 0;
356: cond->from = 0;
357: cond->to = 0;
358:
359: cond->quiet = 0;
360: cond->ask = 0;
361: cond->miss_only = 0;
362: cond->use_utf8 = 0;
363: }
364:
365: int
366: main(int argc,char **argv)
367: {
368: anthy_context_t ac;
369: FILE *fp;
370: struct input cur_input;
371: struct res_db *db;
372: struct condition cond;
373:
374: cur_input.serial = 0;
375: cur_input.str = 0;
376: init_condition(&cond);
377:
378: parse_args(&cond, argc, argv);
379: db = create_db();
380: read_db(db, expdata);
381:
382: printf("./test_anthy --help to print usage.\n");
383:
384: print_run_env();
385:
386: fp = fopen(testdata, "r");
387: if (!fp) {
388: printf("failed to open %s.\n", testdata);
389: return 0;
390: }
391:
392: ac = init_lib(cond.use_utf8);
393:
394:
395: while (!read_file(fp, &cur_input)) {
396: if (check_cond(&cond, &cur_input)) {
397: set_string(&cond, db, &cur_input, ac);
398: }
399: }
400:
401: anthy_release_context(ac);
402: anthy_quit();
403:
404: if (cond.ask) {
405:
406: ask_results(db);
407: }
408:
409: show_stat(db);
410: save_db(expdata, db);
411:
412: return 0;
413: }