1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45: #include <string.h>
46: #include <stdlib.h>
47: #include <stdio.h>
48:
49: #include <anthy/dic.h>
50: #include <anthy/splitter.h>
51: #include <anthy/conf.h>
52: #include <anthy/ordering.h>
53: #include <anthy/logger.h>
54: #include <anthy/record.h>
55: #include <anthy/anthy.h>
56: #include <anthy/record.h>
57: #include <anthy/xchar.h>
58: #include "main.h"
59: #include "config.h"
60:
61:
62:
63: static int is_init_ok;
64:
65: static int default_encoding;
66:
67: static char *history_file;
68:
69:
70: int
71: anthy_init(void)
72: {
73: char *hfn;
74: if (is_init_ok) {
75:
76: return 0;
77: }
78:
79:
80: if (anthy_init_dic()) {
81: anthy_log(0, "Failed to initialize dictionary.\n");
82: return -1;
83: }
84:
85: if (anthy_init_splitter()) {
86: anthy_log(0, "Failed to init splitter.\n");
87: return -1;
88: }
89: anthy_init_contexts();
90: anthy_init_personality();
91: anthy_infosort_init();
92: anthy_relation_init();
93:
94:
95: default_encoding = ANTHY_EUC_JP_ENCODING;
96: is_init_ok = 1;
97: history_file = NULL;
98: hfn = getenv("ANTHY_HISTORY_FILE");
99: if (hfn) {
100: history_file = strdup(hfn);
101: }
102:
103:
104: return 0;
105: }
106:
107:
108: void
109: anthy_quit(void)
110: {
111: if (!is_init_ok) {
112: return ;
113: }
114: anthy_quit_contexts();
115: anthy_quit_personality();
116: anthy_quit_splitter();
117:
118: anthy_quit_dic();
119:
120: is_init_ok = 0;
121:
122: if (history_file) {
123: free(history_file);
124: }
125: history_file = NULL;
126: }
127:
128:
129: void
130: anthy_conf_override(const char *var, const char *val)
131: {
132: anthy_do_conf_override(var, val);
133: }
134:
135:
136: int
137: anthy_set_personality(const char *id)
138: {
139: return anthy_do_set_personality(id);
140: }
141:
142:
143: struct anthy_context *
144: anthy_create_context(void)
145: {
146: if (!is_init_ok) {
147: return 0;
148: }
149: return anthy_do_create_context(default_encoding);
150: }
151:
152:
153: void
154: anthy_reset_context(struct anthy_context *ac)
155: {
156: anthy_do_reset_context(ac);
157: }
158:
159:
160: void
161: anthy_release_context(struct anthy_context *ac)
162: {
163: anthy_do_release_context(ac);
164: }
165:
166:
167:
168:
169: static int
170: need_reconvert(struct anthy_context *ac, xstr *xs)
171: {
172: int i;
173:
174: if (ac->reconversion_mode == ANTHY_RECONVERT_ALWAYS) {
175: return 1;
176: }
177: if (ac->reconversion_mode == ANTHY_RECONVERT_DISABLE) {
178: return 0;
179: }
180:
181: for (i = 0; i < xs->len; ++i) {
182: xchar xc = xs->str[i];
183: int type = anthy_get_xchar_type(xc);
184:
185:
186:
187:
188:
189: if (!(type & (XCT_HIRA | XCT_SYMBOL | XCT_NUM |
190: XCT_WIDENUM | XCT_OPEN | XCT_CLOSE |
191: XCT_ASCII)) &&
192: xc != KK_VU) {
193: return 1;
194: }
195: }
196: return 0;
197: }
198:
199:
200:
201: int
202: anthy_set_string(struct anthy_context *ac, const char *s)
203: {
204: xstr *xs;
205: int retval;
206:
207: if (!ac) {
208: return -1;
209: }
210:
211:
212: anthy_do_reset_context(ac);
213:
214:
215: if (!ac->dic_session) {
216: ac->dic_session = anthy_dic_create_session();
217: if (!ac->dic_session) {
218: return -1;
219: }
220: }
221:
222: anthy_dic_activate_session(ac->dic_session);
223:
224: anthy_reload_record();
225:
226: xs = anthy_cstr_to_xstr(s, ac->encoding);
227:
228: if (!need_reconvert(ac, xs)) {
229:
230: retval = anthy_do_context_set_str(ac, xs, 0);
231: } else {
232:
233: struct anthy_conv_stat stat;
234: struct seg_ent *seg;
235: int i;
236: xstr* hira_xs;
237:
238: retval = anthy_do_context_set_str(ac, xs, 1);
239:
240:
241: anthy_get_stat(ac, &stat);
242: hira_xs = NULL;
243: for (i = 0; i < stat.nr_segment; ++i) {
244: seg = anthy_get_nth_segment(&ac->seg_list, i);
245: hira_xs = anthy_xstrcat(hira_xs, &seg->cands[0]->str);
246: }
247:
248: anthy_release_segment_list(ac);
249: retval = anthy_do_context_set_str(ac, hira_xs, 0);
250: anthy_free_xstr(hira_xs);
251: }
252:
253: anthy_free_xstr(xs);
254: return retval;
255: }
256:
257:
258: void
259: anthy_resize_segment(struct anthy_context *ac, int nth, int resize)
260: {
261: anthy_dic_activate_session(ac->dic_session);
262: anthy_do_resize_segment(ac, nth, resize);
263: }
264:
265:
266: int
267: anthy_get_stat(struct anthy_context *ac, struct anthy_conv_stat *s)
268: {
269: s->nr_segment = ac->seg_list.nr_segments;
270: return 0;
271: }
272:
273:
274: int
275: anthy_get_segment_stat(struct anthy_context *ac, int n,
276: struct anthy_segment_stat *s)
277: {
278: struct seg_ent *seg;
279: seg = anthy_get_nth_segment(&ac->seg_list, n);
280: if (seg) {
281: s->nr_candidate = seg->nr_cands;
282: s->seg_len = seg->str.len;
283: return 0;
284: }
285: return -1;
286: }
287:
288: static int
289: get_special_candidate_index(int nth, struct seg_ent *seg)
290: {
291: int i;
292: int mask = XCT_NONE;
293: if (nth >= 0) {
294: return nth;
295: }
296: if (nth == NTH_UNCONVERTED_CANDIDATE ||
297: nth == NTH_HALFKANA_CANDIDATE) {
298: return nth;
299: }
300: if (nth == NTH_KATAKANA_CANDIDATE) {
301: mask = XCT_KATA;
302: } else if (nth == NTH_HIRAGANA_CANDIDATE) {
303: mask = XCT_HIRA;
304: }
305: for (i = 0; i < seg->nr_cands; i++) {
306: if (anthy_get_xstr_type(&seg->cands[i]->str) & mask) {
307: return i;
308: }
309: }
310: return NTH_UNCONVERTED_CANDIDATE;
311: }
312:
313:
314: int
315: anthy_get_segment(struct anthy_context *ac, int nth_seg,
316: int nth_cand, char *buf, int buflen)
317: {
318: struct seg_ent *seg;
319: char *p;
320: int len;
321:
322:
323: if (nth_seg < 0 || nth_seg >= ac->seg_list.nr_segments) {
324: return -1;
325: }
326: seg = anthy_get_nth_segment(&ac->seg_list, nth_seg);
327:
328:
329: p = NULL;
330: if (nth_cand < 0) {
331: nth_cand = get_special_candidate_index(nth_cand, seg);
332: }
333: if (nth_cand == NTH_HALFKANA_CANDIDATE) {
334: xstr *xs = anthy_xstr_hira_to_half_kata(&seg->str);
335: p = anthy_xstr_to_cstr(xs, ac->encoding);
336: anthy_free_xstr(xs);
337: } else if (nth_cand == NTH_UNCONVERTED_CANDIDATE) {
338:
339: p = anthy_xstr_to_cstr(&seg->str, ac->encoding);
340: } else if (nth_cand >= 0 && nth_cand < seg->nr_cands) {
341: p = anthy_xstr_to_cstr(&seg->cands[nth_cand]->str, ac->encoding);
342: }
343: if (!p) {
344: return -1;
345: }
346:
347:
348: len = strlen(p);
349: if (!buf) {
350: free(p);
351: return len;
352: }
353: if (len + 1 > buflen) {
354:
355: free(p);
356: return -1;
357: }
358: strcpy(buf, p);
359: free(p);
360: return len;
361: }
362:
363:
364: static int
365: commit_all_segment_p(struct anthy_context *ac)
366: {
367: int i;
368: struct seg_ent *se;
369: for (i = 0; i < ac->seg_list.nr_segments; i++) {
370: se = anthy_get_nth_segment(&ac->seg_list, i);
371: if (se->committed < 0) {
372: return 0;
373: }
374: }
375: return 1;
376: }
377:
378:
379: int
380: anthy_commit_segment(struct anthy_context *ac, int s, int c)
381: {
382: struct seg_ent *seg;
383: if (!ac->str.str) {
384: return -1;
385: }
386: if (s < 0 || s >= ac->seg_list.nr_segments) {
387: return -1;
388: }
389: if (commit_all_segment_p(ac)) {
390:
391: return -1;
392: }
393:
394: anthy_dic_activate_session(ac->dic_session);
395: seg = anthy_get_nth_segment(&ac->seg_list, s);
396: if (c < 0) {
397: c = get_special_candidate_index(c, seg);
398: }
399: if (c == NTH_UNCONVERTED_CANDIDATE) {
400:
401:
402:
403: int i;
404: for (i = 0; i < seg->nr_cands; i++) {
405: if (!anthy_xstrcmp(&seg->str, &seg->cands[i]->str)) {
406: c = i;
407: }
408: }
409: }
410: if (c < 0 || c >= seg->nr_cands) {
411: return -1;
412: }
413: seg->committed = c;
414:
415: if (commit_all_segment_p(ac)) {
416:
417: anthy_proc_commit(&ac->seg_list, &ac->split_info);
418:
419: anthy_save_history(history_file, ac);
420: }
421: return 0;
422: }
423:
424:
425: int
426: anthy_set_prediction_string(struct anthy_context *ac, const char* s)
427: {
428: int retval;
429: xstr *xs;
430:
431: anthy_dic_activate_session(ac->dic_session);
432:
433: anthy_reload_record();
434:
435:
436: xs = anthy_cstr_to_xstr(s, ac->encoding);
437:
438: retval = anthy_do_set_prediction_str(ac, xs);
439:
440: anthy_free_xstr(xs);
441:
442: return retval;
443: }
444:
445:
446: int
447: anthy_get_prediction_stat(struct anthy_context *ac, struct anthy_prediction_stat * ps)
448: {
449: ps->nr_prediction = ac->prediction.nr_prediction;
450: return 0;
451: }
452:
453:
454: int
455: anthy_get_prediction(struct anthy_context *ac, int nth, char* buf, int buflen)
456: {
457: struct prediction_cache* prediction = &ac->prediction;
458: int nr_prediction = prediction->nr_prediction;
459: char* p;
460: int len;
461:
462: if (nth < 0 || nr_prediction <= nth) {
463: return -1;
464: }
465:
466: p = anthy_xstr_to_cstr(prediction->predictions[nth].str, ac->encoding);
467:
468:
469: len = strlen(p);
470: if (!buf) {
471: free(p);
472: return len;
473: }
474: if (len + 1 > buflen) {
475: free(p);
476: return -1;
477: } else {
478: strcpy(buf, p);
479: free(p);
480: return len;
481: }
482: }
483:
484:
485:
486: int
487: anthy_commit_prediction(struct anthy_context *ac, int nth)
488: {
489: struct prediction_cache* pc = &ac->prediction;
490: if (nth < 0 || nth >= pc->nr_prediction) {
491: return -1;
492: }
493: anthy_do_commit_prediction(pc->predictions[nth].src_str,
494: pc->predictions[nth].str);
495: return 0;
496: }
497:
498:
499: void
500: anthy_print_context(struct anthy_context *ac)
501: {
502: anthy_do_print_context(ac, default_encoding);
503: }
504:
505:
506:
507:
508: const char *
509: anthy_get_version_string (void)
510: {
511: #ifdef VERSION
512: return VERSION;
513: #else
514: return "(unknown)";
515: #endif
516: }
517:
518:
519: int
520: anthy_context_set_encoding(struct anthy_context *ac, int encoding)
521: {
522: if (!ac) {
523: return ANTHY_EUC_JP_ENCODING;
524: }
525: if (encoding == ANTHY_UTF8_ENCODING ||
526: encoding == ANTHY_EUC_JP_ENCODING) {
527: ac->encoding = encoding;
528: }
529: return ac->encoding;
530: }
531:
532:
533: int
534: anthy_set_reconversion_mode(anthy_context_t ac, int mode)
535: {
536: if (!ac) {
537: return ANTHY_RECONVERT_AUTO;
538: }
539: if (mode == ANTHY_RECONVERT_AUTO ||
540: mode == ANTHY_RECONVERT_DISABLE ||
541: mode == ANTHY_RECONVERT_ALWAYS) {
542: ac->reconversion_mode = mode;
543: }
544: return ac->reconversion_mode;
545: }