Fix memory leak issues
[platform/core/uifw/anthy.git] / src-worddic / ext_ent.c
1 /*
2  * "123" "ABC" ¤Î¤è¤¦¤Ê¼­½ñ¤Ë¤Î¤Ã¤Æ¤Ê¤¤
3  * Ê¸»úÎó¤ËÂФ¹¤ëÌä¹ç¤»¤Î¾ì¹ç¤ÏÁ´¤Æ¤Î¸õÊä¤ò¤³¤³¤ÇÀ¸À®¤¹¤ë
4  * ¾åµ­¤Î¾¤Ë͹ÊØÈÖ¹æ¤Ø¤Î¥¢¥¯¥»¥¹¤â¹Ô¤Ê¤¦
5  *
6  * Copyright (C) 2001-2005 TABATA Yusuke
7  * Copyright (C) 2004-2005 YOSHIDA Yuichi
8  *
9  */
10 /*
11   This library is free software; you can redistribute it and/or
12   modify it under the terms of the GNU Lesser General Public
13   License as published by the Free Software Foundation; either
14   version 2 of the License, or (at your option) any later version.
15
16   This library is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19   Lesser General Public License for more details.
20
21   You should have received a copy of the GNU Lesser General Public
22   License along with this library; if not, write to the Free Software
23   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
24  */
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <anthy/anthy.h> /* for ANTHY_*_ENCODING */
29 #include <anthy/conf.h>
30 #include <anthy/xstr.h>
31 #include <anthy/xchar.h>
32 #include "dic_main.h"
33 #include "dic_ent.h"
34
35 /* ext entry */
36 static struct seq_ent unkseq_ent;/*̤ÃÎʸ»úÎ󤿤Ȥ¨¤Ð±Ñʸ»úÎó¤È¤«*/
37 static struct seq_ent num_ent;/*¿ô»ú¤Ê¤É*/
38 static struct seq_ent sep_ent;/*¥»¥Ñ¥ì¡¼¥¿¤Ê¤É¡£*/
39 /* ext entry¤Îwtype*/
40 static wtype_t wt_num;
41
42 static xchar narrow_wide_tab[]= {WIDE_0, WIDE_1, WIDE_2,
43                                  WIDE_3, WIDE_4, WIDE_5,
44                                  WIDE_6, WIDE_7, WIDE_8, WIDE_9};
45 static int kj_num_tab[]={KJ_0, KJ_1, KJ_2, KJ_3, KJ_4,
46                          KJ_5, KJ_6, KJ_7, KJ_8, KJ_9};
47
48 struct zipcode_line {
49   int nr;
50   xstr **strs;
51 };
52
53 /* ÃÏ̾¤òÄɲ乤ë */
54 static void
55 pushback_place_name(struct zipcode_line *zl, char *pn)
56 {
57   if (pn[0] == '#') {
58     return ;
59   }
60   zl->strs = realloc(zl->strs, sizeof(xstr *) * (zl->nr + 1));
61   zl->strs[zl->nr] = anthy_cstr_to_xstr(pn, ANTHY_EUC_JP_ENCODING);
62   zl->nr++;
63 }
64
65 /* Í¹ÊØÈֹ漭½ñ¤ò¥Ñ¡¼¥¹¤·¤Æ¥¹¥Ú¡¼¥¹¶èÀÚ¤ê¤ò¸¡½Ð¤¹¤ë */
66 static void
67 parse_zipcode_line(struct zipcode_line *zl, char *ln)
68 {
69   char buf[1000];
70   int i = 0;
71   while (*ln) {
72     buf[i] = *ln;
73     if (*ln == '\\') {
74       buf[i] = ln[1];
75       i ++;
76       if (ln[1]) {
77         ln ++;
78       }
79     } else if (*ln == ' ') {
80       buf[i] = 0;
81       i = 0;
82       pushback_place_name(zl, buf);
83     } else {
84       i ++;
85     }
86     /**/
87     ln ++;
88   }
89   buf[i] = 0;
90   pushback_place_name(zl, buf);
91 }
92
93 /* Í¹ÊØÈֹ漭½ñ¤«¤éõ¤¹ */
94 static void
95 search_zipcode_dict(struct zipcode_line *zl, xstr* xs)
96 {
97   FILE *fp;
98   char buf[1000];
99   int len;
100   xstr *temp;
101   char *index;
102
103   zl->nr = 0;
104   zl->strs = NULL;
105   fp = fopen(anthy_conf_get_str("ZIPDICT_EUC"), "r");
106   if (!fp) {
107     return ;
108   }
109   
110   /* È¾³Ñ¡¢Á´³Ñ¤òµÛ¼ý¤¹¤ë */
111   temp = anthy_xstr_wide_num_to_num(xs);
112   index = anthy_xstr_to_cstr(temp, 0);
113   len = strlen(index);
114
115   /* Á´Éôgrep¤¹¤ë */
116   while (fgets(buf, 1000, fp)) {
117     /* 3ʸ»ú¤Î͹ÊØÈֹ椬7ʸ»ú¤Î͹ÊØÈÖ¹æ¤ÎƬ¤Ë¥Þ¥Ã¥Á¤·¤Ê¤¤¤è¤¦¤Ë */
118     if (!strncmp(buf, index, len) && buf[len] == ' ') {
119       /* ²þ¹Ô¤ò¾Ã¤¹ */
120       buf[strlen(buf) - 1] = 0;
121       parse_zipcode_line(zl, &buf[len + 1]);
122     }
123   }
124   anthy_free_xstr(temp);    /* ¥á¥â¥ê¥ê¡¼¥¯¤Î½¤Àµ */
125   free(index);
126   fclose(fp);
127 }
128
129 /* Í¹ÊØÈֹ漭½ñ¤Î¾ðÊó¤ò²òÊü¤¹¤ë */
130 static void
131 free_zipcode_line(struct zipcode_line *zl)
132 {
133   int i;
134   for (i = 0; i < zl->nr; i++) {
135     anthy_free_xstr(zl->strs[i]);
136   }
137   free(zl->strs);
138 }
139
140 static int
141 gen_zipcode(xstr* xs, xstr *dest, int nth)
142 {
143   struct zipcode_line zl;
144
145   /* Í¹ÊØÈֹ漭½ñ¤«¤éÃÏ̾¤òÆɤ߼è¤ë */
146   search_zipcode_dict(&zl, xs);
147
148   /* ¸õÊä¤ò¼èÆÀ¤¹¤ë */
149   if (zl.nr > nth) {
150     dest->len = zl.strs[nth]->len;
151     dest->str = anthy_xstr_dup_str(zl.strs[nth]);
152     free_zipcode_line(&zl);
153     return 0;
154   } else {
155     free_zipcode_line(&zl);
156     return -1;
157   }
158 }
159
160
161
162 /* È¾³Ñ¤Î¿ô»ú¤«¤éÁ´³Ñ¤Î¿ô»ú¤òµá¤á¤ë */
163 static xchar
164 narrow_num_to_wide_num(xchar xc)
165 {
166   if (xc > '9' || xc < '0') {
167     return WIDE_0;
168   }
169   return narrow_wide_tab[(int)(xc - '0')];
170 }
171
172 /* Á´³Ñ¤Î¿ô»ú¤«¤éȾ³Ñ¤Î¿ô»ú¤òµá¤á¤ë */
173 static xchar
174 wide_num_to_narrow_num(xchar xc)
175 {
176   int i;
177   for (i = 0; i < 10; i++) {
178     if (xc == narrow_wide_tab[i]) {
179       return i + '0';
180     }
181   }
182   return '0';
183 }
184 /*
185  * °ì·å¤ÎÀ°¿ô¤ò´Á¿ô»ú¤ËÊÑ´¹¤¹¤ë
186  */
187 static xchar
188 get_kj_num(int n)
189 {
190   if (n > 9 || n < 1) {
191     return KJ_10;
192   }
193   return kj_num_tab[n];
194 }
195
196 /*
197  * 4·åʬ¤ÎÀ°¿ô¤ò´Á»úʸ»úÎó¤È¤·¤Æ¤òÀ¸À®¤¹¤ë
198  */
199 static void
200 compose_num_component(xstr *xs, long long num)
201 {
202   int n[4],i;
203   int a[4] = { 0 , KJ_10, KJ_100, KJ_1000};
204   for (i = 0; i < 4; i++) {
205     n[i] = num-(num/10)*10;
206     num /= 10;
207   }
208   /* 10,100,1000¤Î°Ì */
209   for (i = 3; i > 0; i--) {
210     if (n[i] > 0) {
211       if (n[i] > 1) {
212         anthy_xstrappend(xs, get_kj_num(n[i]));
213       }
214       anthy_xstrappend(xs, a[i]);
215     }
216   }
217   /* 1¤Î°Ì */
218   if (n[0]) {
219     anthy_xstrappend(xs, get_kj_num(n[0]));
220   }
221 }
222
223 /** ´Á¿ô»ú¤Îʸ»úÎó¤òºî¤ë */
224 static int
225 gen_kanji_num(long long num, xstr *dest)
226 {
227   int i;
228   int n[10];
229   if (num < 1 || num >= 10000000000000000LL) {
230     return -1;
231   }
232   /* 4·å¤º¤ÄÇÛÎón¤Ë¤Ä¤á¤ë */
233   for (i = 0; i < 10; i ++) {
234     n[i] = num-(num/10000)*10000;
235     num = num/10000;
236   }
237   /**/
238   dest->len = 0;
239   dest->str = 0;
240   /* µþ¤Î°Ì¤ò¤Ä¤¯¤ë */
241   if (n[3]) {
242     compose_num_component(dest, n[3]);
243     anthy_xstrappend(dest, KJ_1000000000000);
244   }
245   /* ²¯¤Î°Ì¤ò¤Ä¤¯¤ë */
246   if (n[2]) {
247     compose_num_component(dest, n[2]);
248     anthy_xstrappend(dest, KJ_100000000);
249   }
250   /* Ëü¤Î°Ì¤ò¤Ä¤¯¤ë */
251   if (n[1]) {
252     compose_num_component(dest, n[1]);
253     anthy_xstrappend(dest, KJ_10000);
254   }
255   /**/
256   compose_num_component(dest, n[0]);
257   return 0;
258 }
259
260 static int
261 get_nr_zipcode(xstr* xs)
262 {
263   struct zipcode_line zl;
264   int nr = 0;
265   if (xs->len != 3 && xs->len != 7) {
266     return 0;
267   }
268   /* Í¹ÊØÈֹ漭½ñ¤«¤éÃÏ̾¤òÆɤ߼è¤ë */
269   search_zipcode_dict(&zl, xs);
270
271   nr = zl.nr;
272   free_zipcode_line(&zl);
273   return nr;
274 }
275
276 static int
277 get_nr_num_ents(long long num)
278 {
279   if (num > 0 && num < 10000000000000000LL) {
280     if (num > 999) {
281       /* ¥¢¥é¥Ó¥¢¿ô»ú(¤½¤Î¤Þ¤Þ)¡¢¥¢¥é¥Ó¥¢¿ô»ú(Á´³ÑȾ³ÑÀÚÂؤ¨)¡¢
282          ´Á¿ô»ú¡¢3·å¶èÀÚ¤ê(Á´³Ñ¡¢È¾³Ñ) */
283       return 5;
284     } else {
285       /* ¥¢¥é¥Ó¥¢¿ô»ú(¤½¤Î¤Þ¤Þ)¡¢Á´³ÑȾ³ÑÀÚÂؤ¨¡¢´Á¿ô»ú */
286       return 3;
287     }
288   } else {
289     /* ¥¢¥é¥Ó¥¢¿ô»ú(¤½¤Î¤Þ¤Þ)¡¢Á´³ÑȾ³ÑÀÚÂؤ¨ */
290     return 2;
291   }
292 }
293
294
295 /*
296  * ¤¤¤¯¤Ä¤Î¹çÀ®¤Î¥¨¥ó¥È¥ê¡¼¤¬¤¢¤ë¤«
297  */
298 int
299 anthy_get_nr_dic_ents_of_ext_ent(seq_ent_t se, xstr *xs)
300 {
301   if (se == &unkseq_ent) {
302     return 1;
303   }
304   if (anthy_get_xstr_type(xs) & (XCT_NUM|XCT_WIDENUM)) {
305     long long num = anthy_xstrtoll(xs);
306     return get_nr_num_ents(num) + get_nr_zipcode(xs);
307   }
308   return 0;
309 }
310
311 /* Ê¸»úÎó¤ÎÁ´³ÑȾ³Ñ¤ò¸ò´¹¤¹¤ë */
312 static void
313 toggle_wide_narrow(xstr *dest, xstr *src)
314 {
315   int f, i;
316   dest->len = src->len;
317   dest->str = anthy_xstr_dup_str(src);
318   f = anthy_get_xstr_type(src) & XCT_WIDENUM;
319   for (i = 0; i < dest->len; i++) {
320     if (f) {
321       dest->str[i] = wide_num_to_narrow_num(src->str[i]);
322     } else {
323       dest->str[i] = narrow_num_to_wide_num(src->str[i]);
324     }
325   }
326 }
327
328 /* 3·å¤Ë¶èÀڤä¿¿ô»ú¤òÀ¸À®¤¹¤ë */
329 static int
330 gen_separated_num(long long num, xstr *dest, int full)
331 {
332   int width = 0, dot_count;
333   long long tmp;
334   int i, pos;
335
336   if (num < 1000) {
337     return -1;
338   }
339
340   /* ·å¿ô¤ò¿ô¤¨¤ë */
341   for (tmp = num; tmp != 0; tmp /= 10) {
342     width ++;
343   }
344   /* ÅÀ¤Î¿ô */
345   dot_count = (width - 1) / 3;
346   /* ³ÊǼ¤¹¤ë¤Î¤ËɬÍפÊʸ»úÎó¤òÍÑ°Õ¤¹¤ë */
347   dest->len = dot_count + width;
348   dest->str = malloc(sizeof(xchar)*dest->len);
349
350   /* ±¦¤Î·å¤«¤é½ç¤Ë·è¤á¤Æ¤¤¤¯ */
351   for (i = 0, pos = dest->len - 1; i < width; i++, pos --) {
352     int n = num % 10;
353     /* ¥«¥ó¥Þ¤òÄɲà*/
354     if (i > 0 && (i % 3) == 0) {
355       if (full) {
356         dest->str[pos] = WIDE_COMMA;
357       } else {
358         dest->str[pos] = ',';
359       }
360       pos --;
361     }
362     if (full) {
363       /* Á´³Ñ¿ô»ú */
364       dest->str[pos] = narrow_wide_tab[n];
365     } else {
366       /* ASCII¿ô»ú */
367       dest->str[pos] = 48 + n;
368     }
369     num /= 10;
370   }
371   return 0;
372 }
373
374 /*
375  * nth¸Ä¤á¤Î¸õÊä¤ò¼è¤ê½Ð¤¹
376  */
377 int
378 anthy_get_nth_dic_ent_str_of_ext_ent(seq_ent_t se, xstr *xs,
379                                      int nth, xstr *dest)
380 {
381   dest->str = NULL;     /* ÉÔÀµ¤Ê¥á¥â¥ê¥¢¥¯¥»¥¹¤ä¥á¥â¥ê¤Î¿½Å²òÊü¤ò¤¹¤ë¥Ð¥°¤Î½¤Àµ */
382   dest->len = 0;
383   if (nth == 0) {
384     /* ÌµÊÑ´¹Ê¸»úÎó */
385     dest->len = xs->len;
386     dest->str = anthy_xstr_dup_str(xs);
387     return 0;
388   }
389   if (se == &unkseq_ent) {
390     switch(nth) {
391     case 1:
392       /* Á´³Ñ¡¢È¾³Ñ¤Î¥È¥°¥ë */
393       return 0;
394     }
395   }
396   if (anthy_get_xstr_type(xs) & (XCT_NUM|XCT_WIDENUM)) {
397     long long num = anthy_xstrtoll(xs);
398     const int base_ents = get_nr_num_ents(num); /* £³·å͹ÊØÈÖ¹æ¤Ø¤ÎÂбþ */
399     /* ´Á¿ô»ú¡¢¥¢¥é¥Ó¥¢¿ô»ú¡¢Á´³ÑȾ³ÑÀÚÂؤ¨ */
400     switch(nth) {
401     case 1:
402       /* Á´³ÑȾ³Ñ¤òÆþ¤ì´¹¤¨¤¿¤â¤Î */
403       toggle_wide_narrow(dest, xs);
404       return 0;
405     case 2:
406       /* ´Á¿ô»ú */
407       if (!gen_kanji_num(num, dest)) {
408         return 0;
409       }
410       /* break̵¤· */
411     case 3:
412       /* 3·å¤Ç¶èÀڤä¿¿ô»ú */
413       if (!gen_separated_num(num, dest, 0)) {
414         return 0;
415       }
416       /* break̵¤· */
417     case 4:
418       /* 3·å¤Ç¶èÀڤä¿¿ô»ú(Á´³Ñ) */
419       if (!gen_separated_num(num, dest, 1)) {
420         return 0;
421       }
422       /* break̵¤· */
423     default:
424       /* Í¹ÊØÈÖ¹æ */
425       if (base_ents <= nth) {   /* £³·å͹ÊØÈÖ¹æ¤Ø¤ÎÂбþ */
426         if (xs->len == 3 || xs->len == 7) {
427           if (!gen_zipcode(xs, dest, nth - base_ents)) {    /* £³·å͹ÊØÈÖ¹æ¤Ø¤ÎÂбþ */
428             return 0;
429           }
430         }
431       }
432       break;
433     }
434     return -1;
435   }
436   return 0;
437 }
438
439 int
440 anthy_get_ext_seq_ent_indep(struct seq_ent *se)
441 {
442   if (se == &num_ent || se == &unkseq_ent) {
443     return 1;
444   }
445   return 0;
446 }
447
448 /* ³èÍÑ·Á¤òÆÀ¤ë */
449 int
450 anthy_get_ext_seq_ent_ct(struct seq_ent *se, int pos, int ct)
451 {
452   if (anthy_get_ext_seq_ent_pos(se, pos) && ct == CT_NONE) {
453     /* Éʻ줬¹ç¤Ã¤Æ¤¤¤Æ¤«¤Ä̵³èÍѤξì¹ç 
454        (ext_ent¤Ï³èÍѤ·¤Ê¤¤) */
455     return 10;
456   }
457   return 0;
458 }
459
460 /* ÉÊ»ì¤ò¼èÆÀ¤¹¤ë */
461 int
462 anthy_get_ext_seq_ent_pos(struct seq_ent *se, int pos)
463 {
464   /* ext_ent¤Ï̾»ì¤Î¤ß */
465   if (se == &num_ent && pos == POS_NOUN) {
466     return 10;
467   }
468   if ((se == &unkseq_ent) && pos == POS_NOUN) {
469     return 10;
470   }
471   return 0;
472 }
473
474 /*
475  * ¼­½ñ¤Ë¤Î¤Ã¤Æ¤¤¤Ê¤¤¥·¡¼¥±¥ó¥¹¤ò²òÀÏ
476  */
477 seq_ent_t
478 anthy_get_ext_seq_ent_from_xstr(xstr *x, int is_reverse)
479 {
480   int t = anthy_get_xstr_type(x);
481
482   /* ¿ô»ú¤Î¤ß¤Ç¹½À®¤µ¤ì¤Æ¤¤¤ì¤Ð num_ent */
483   if (t & (XCT_NUM | XCT_WIDENUM)) {
484     return &num_ent;
485   }
486   /* ±Ñ¿ô¤Ê¤éunkseq */
487   if (t & XCT_ASCII) {
488     return &unkseq_ent;
489   }
490   if (t & XCT_KATA) {
491     return &unkseq_ent;
492   }
493   if (!is_reverse) {
494     /* µÕÊÑ´¹Ãæ¤Ï´Á»ú¸õÊä¤Ïºî¤é¤Ê¤¤ */
495     if (t & XCT_KANJI) {
496       return &unkseq_ent;
497     }
498   }
499   if (x->len == 1) {
500     /* ¼­½ñ¤Ë¤Î¤Ã¤Æ¤Ê¤¯¤Æ1ʸ»ú¤Ê¤é¥»¥Ñ¥ì¡¼¥¿ */
501     return &sep_ent;
502   }
503   return 0;
504 }
505
506 int
507 anthy_get_nth_dic_ent_wtype_of_ext_ent(xstr *xs, int nth,
508                                        wtype_t *wt)
509 {
510   int type;
511   (void)nth;
512   type = anthy_get_xstr_type(xs);
513   if (type & (XCT_NUM | XCT_WIDENUM)) {
514     *wt = wt_num;
515     return 0;
516   }
517   if (type & XCT_KATA) {
518     *wt = anthy_get_wtype(POS_NOUN, COS_NONE, SCOS_NONE, CC_NONE,
519                           CT_NONE, WF_INDEP);
520     return 0;
521   }
522   return -1;
523 }
524
525 int
526 anthy_get_nth_dic_ent_freq_of_ext_ent(struct seq_ent *se, int nth)
527 {
528   (void)se;
529   (void)nth;
530   return 100;
531 }
532
533 int
534 anthy_get_ext_seq_ent_wtype(struct seq_ent *se, wtype_t w)
535 {
536   if (se == &num_ent) {
537     if (anthy_wtype_include(w, wt_num)) {
538       /* ¿ô»ú¤Î¾ì¹ç */
539       return 10;
540     }
541     return 0;
542   }
543   if (anthy_wtype_get_pos(w) == POS_NOUN &&
544       anthy_wtype_get_cos(w) == COS_NONE &&
545       anthy_wtype_get_scos(w) == SCOS_NONE) {
546     /* Ì¾»ì¡¢ÉûÉÊ»ì¤Ê¤·¡¢Éû¡¹ÉÊ»ì̵¤·¤Ë¥Þ¥Ã¥Á */
547     return 10;
548   }
549   return 0;
550 }
551
552 void
553 anthy_init_ext_ent(void)
554 {
555   /**/
556   unkseq_ent.seq_type = 0;
557   unkseq_ent.nr_dic_ents = 0;
558   num_ent.seq_type = 0;
559   num_ent.nr_dic_ents = 0;
560   sep_ent.seq_type = 0;
561   sep_ent.nr_dic_ents = 0;
562   /**/
563   wt_num = anthy_init_wtype_by_name("¿ô»ì");
564 }