Disable zipcode dictionary
[platform/core/uifw/anthy.git] / src-util / rkhelper.c
1 /*
2  * ¥í¡¼¥Þ»ú¤«¤éÊ¿²¾Ì¾¡ÊÀµ³Î¤Ë¤Ï¥­¡¼¤ÎÎ󤫤éʸ»ú¡Ë¤Îɽ(rk_map)¤Î
3  * ¥«¥¹¥¿¥Þ¥¤¥º¤ò´ÉÍý¤¹¤ë
4  *
5  * Copyright (C) 2001-2002 UGAWA Tomoharu
6  * Copyright (C) 2002 Tabata Yusuke
7  *
8  * Funded by IPA̤Ƨ¥½¥Õ¥È¥¦¥§¥¢ÁϤ»ö¶È 2001
9  */
10
11 #include <string.h>
12 #include <stdlib.h>
13 #include "rkconv.h"
14 #include "rkhelper.h"
15
16 static const char* rk_default_symbol[128] = {
17   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
18   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
19   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
20   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
21   "¡¡", "¡ª", "¡É", "¡ô", "¡ð", "¡ó", "¡õ", "¡Ç", 
22   "¡Ê", "¡Ë", "¡ö", "¡Ü", "¡¢", "¡¼", "¡£", "¡¿",
23   "£°", "£±", "£²", "£³", "£´", "£µ", "£¶", "£·",
24   "£¸", "£¹", "¡§", "¡¨", "¡ã", "¡á", "¡ä", "¡©",
25
26   "¡÷", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
27   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
28   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
29   NULL, NULL, NULL, "¡Ö", "¡À", "¡×", "¡°", "¡²",
30   "¡Æ", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
31   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
32   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
33   NULL, NULL, NULL, "¡Ð", "¡Ã", "¡Ñ", "¡Á", NULL
34 };
35
36 struct rk_conf_ent {
37   char *lhs;
38   char *rhs;
39   struct rk_conf_ent *next;
40 };
41
42 struct rk_option {
43   int enable_default;
44   char toggle; /* ±Ñ¿ô¤È¤Î°ì»þŪ¤ÊÀÚÂؤ¨¤Ë»È¤¦¥·¥ó¥Ü¥ë */
45   /*
46    * ÇÛÎó¤Ï¤½¤ì¤¾¤ì¥ê¥¹¥È¤ÎÀèƬ¤Ë¤Ê¤ë
47    * ¥ê¥¹¥È¤ÎÀèƬ¤Ï°ìʸ»ú¤Î¥¨¥ó¥È¥ê¤¬Æþ¤ë
48    */
49   struct rk_conf_ent hiragana_symbol[128]; /* ¤Ò¤é¤¬¤Ê¤È¤ÎÂбþ */
50   struct rk_conf_ent katakana_symbol[128]; /* ¥«¥¿¥«¥Ê¤È¤ÎÂбþ */
51   struct rk_conf_ent hankaku_kana_symbol[128]; /* ¥«¥¿¥«¥Ê¤È¤ÎÂбþ */
52 };
53
54 #include "rkmap.h"
55
56 struct rk_option *
57 anthy_input_create_rk_option()
58 {
59   struct rk_option *opt;
60   int i;
61
62   opt = malloc(sizeof(struct rk_option));
63   opt->enable_default = 1;
64   opt->toggle = '/';
65   for (i = 0; i < 128; i++) {
66     opt->hiragana_symbol[i].rhs = NULL;
67     opt->hiragana_symbol[i].lhs = NULL;
68     opt->hiragana_symbol[i].next = NULL;
69     opt->katakana_symbol[i].rhs = NULL;
70     opt->katakana_symbol[i].lhs = NULL;
71     opt->katakana_symbol[i].next = NULL;
72     opt->hankaku_kana_symbol[i].rhs = NULL;
73     opt->hankaku_kana_symbol[i].lhs = NULL;
74     opt->hankaku_kana_symbol[i].next = NULL;
75   }
76   return opt;
77 }
78
79 int
80 anthy_input_free_rk_option(struct rk_option *opt)
81 {
82   int err;
83
84   err = anthy_input_do_clear_rk_option(opt, 1);
85   free(opt);
86
87   return err;
88 }
89
90 static struct rk_conf_ent *
91 find_rk_conf_ent(struct rk_option *opt, int map,
92                  const char *key, int force)
93 {
94   int c = key[0];
95   struct rk_conf_ent *tab = NULL;
96   struct rk_conf_ent *sym = NULL;
97
98   if (c == 0) {
99     return NULL;
100   }
101
102   if (map == RKMAP_HIRAGANA) {
103     tab = opt->hiragana_symbol;
104   }
105   if (map == RKMAP_KATAKANA) {
106     tab = opt->katakana_symbol;
107   }
108   if (map == RKMAP_HANKAKU_KANA) {
109     tab = opt->hankaku_kana_symbol;
110   }
111   if (!tab) {
112     return NULL;
113   }
114   if (strlen(key) == 1) {
115     sym = &tab[c];
116   } else {
117     /* 2ʸ»ú°Ê¾å */
118     for (sym = tab[c].next; sym; sym = sym->next) {
119       if (!strcmp(sym->lhs, key)) {
120         break;
121       }
122     }
123   }
124   if (!sym && force) {
125     /* ¥á¥â¥ê³ÎÊݤ·¤Æ¤Ä¤Ê¤° */
126     sym = malloc(sizeof(struct rk_conf_ent));
127     sym->rhs = NULL;
128     sym->lhs = NULL;
129     sym->next = tab[c].next;
130     tab[c].next = sym;
131   }
132   if (sym && !sym->lhs) {
133     sym->lhs = strdup(key);
134   }
135   return sym;
136 }
137
138 /*
139  * opt Êѹ¹ÂоݤÎoption
140  * map RKMAP_*
141  * from ÊÑ´¹¤â¤È¤Îʸ»ú
142  * to ÊÑ´¹Àè¤Îʸ»úÎó
143  * follow follow½¸¹ç
144  */
145 int
146 anthy_input_do_edit_rk_option(struct rk_option* opt, int map, 
147                               const char* from, const char* to, const char *follow)
148 {
149   struct rk_conf_ent *tab;
150   (void)follow;
151
152   tab = find_rk_conf_ent(opt, map, from, 1);
153   if (!tab) {
154     return -1;
155   }
156
157   if (tab->rhs) {
158     free(tab->rhs);
159   }
160   if (to == NULL) {
161     tab->rhs = NULL;
162   } else {
163     tab->rhs = strdup(to);
164   }
165   return 0;
166 }
167
168 static void
169 free_rk_conf_ent(struct rk_conf_ent *e)
170 {
171   if (e->lhs) {
172     free(e->lhs);
173     e->lhs = NULL;
174   }
175   if (e->rhs) {
176     free(e->rhs);
177     e->rhs = NULL;
178   }
179   e->next = NULL;
180 }
181
182 int
183 anthy_input_do_clear_rk_option(struct rk_option* opt,
184                                int use_default)
185 {
186   int i;
187
188   opt->enable_default = use_default;
189   for (i = 0; i < 128; i++) {
190     /* ³Æʸ»ú¤ËÂФ·¤Æ */
191     struct rk_conf_ent *tab, *tmp;
192     /* ¤Ò¤é¤¬¤Ê¤Î¥ê¥¹¥È¤ò²òÊü */
193     for (tab = opt->hiragana_symbol[i].next; tab;) {
194       tmp = tab;
195       tab = tab->next;
196       free_rk_conf_ent(tmp);
197       free(tmp);
198     }
199     /* ¥«¥¿¥«¥Ê¤Î¥ê¥¹¥È¤ò²òÊü */
200     for (tab = opt->katakana_symbol[i].next; tab;) {
201       tmp = tab;
202       tab = tab->next;
203       free_rk_conf_ent(tmp);
204       free(tmp);
205     }
206     /* ÀèƬ¤Î°ìʸ»ú¤Î¥¨¥ó¥È¥ê¤â˺¤ì¤º¤Ë²òÊü */
207     free_rk_conf_ent(&opt->katakana_symbol[i]);
208     free_rk_conf_ent(&opt->hiragana_symbol[i]);
209   }
210   return 0;
211 }
212
213 int
214 anthy_input_do_edit_toggle_option(struct rk_option* opt,
215                                   char toggle)
216 {
217   opt->toggle = toggle;
218   return 0;
219 }
220
221 static void
222 rkrule_set(struct rk_rule* r,
223            const char* lhs, const char* rhs, const char* follow)
224 {
225   r->lhs = lhs;
226   r->rhs = rhs;
227   r->follow = follow;
228 }
229
230 struct rk_map*
231 make_rkmap_ascii(struct rk_option* opt)
232 {
233   struct rk_rule var_part[130];
234   struct rk_rule* complete_rules;
235   struct rk_map* map;
236   struct rk_rule* p;
237   char work[2*128];
238   char* w;
239   int c;
240   
241   (void)opt;
242   p = var_part;
243   w = work;
244   for (c = 0; c < 128; c++) {
245     if (rk_default_symbol[c]) {
246       w[0] = c;
247       w[1] = '\0';
248       rkrule_set(p++, w, w, NULL);
249       w += 2;
250     }
251   }
252   p->lhs = NULL;
253
254   complete_rules = rk_merge_rules(rk_rule_alphabet, var_part);
255   map = rk_map_create(complete_rules);
256   rk_rules_free(complete_rules);
257
258   return map;
259 }
260
261 struct rk_map*
262 make_rkmap_wascii(struct rk_option* opt)
263 {
264   (void)opt;
265   return rk_map_create(rk_rule_walphabet);
266 }
267
268 struct rk_map*
269 make_rkmap_shiftascii(struct rk_option* opt)
270 {
271   struct rk_rule var_part[130];
272   struct rk_rule* complete_rules;
273   struct rk_map* map;
274   struct rk_rule* p;
275   char work[2*128 + 3];
276   char* w;
277   int c;
278   int toggle_char = opt->toggle;
279   
280   p = var_part;
281   w = work;
282   for (c = 0; c < 128; c++) {
283     if (rk_default_symbol[c]) {
284       if (c == toggle_char) {
285         /* ¥È¥°¥ë¤¹¤ëʸ»ú¤Î¾ì¹ç */
286         w[0] = c;
287         w[1] = '\0';
288         rkrule_set(p++, w, "\xff" "o", NULL);
289         w[2] = c;
290         w[3] = c;
291         w[4] = '\0';
292         rkrule_set(p++, w + 2, w, NULL);
293         w += 5; 
294       } else {
295         /* ÉáÄ̤Îʸ»ú¤Î¾ì¹ç */
296         w[0] = c;
297         w[1] = '\0';
298         rkrule_set(p++, w, w, NULL);
299         w += 2;
300       }
301     }
302   }
303   p->lhs = NULL;
304
305   complete_rules = rk_merge_rules(rk_rule_alphabet, var_part);
306   map = rk_map_create(complete_rules);
307   rk_rules_free(complete_rules);
308
309   return map;
310 }
311
312 static int
313 count_rk_rule_ent(struct rk_option *opt, int map_no)
314 {
315   int i , c;
316   struct rk_conf_ent *head;
317   struct rk_conf_ent *ent;
318
319   if (map_no == RKMAP_HIRAGANA) {
320     head = opt->hiragana_symbol;
321   } else if (map_no == RKMAP_HANKAKU_KANA) {
322     head = opt->katakana_symbol;
323   } else {
324     head = opt->hankaku_kana_symbol;
325   }
326
327   c = 128;
328   for (i = 0; i < 128; i++) {
329     for (ent = head[i].next; ent; ent = ent->next) {
330       if (ent->lhs) {
331         c++;
332       }
333     }
334   }
335   return c;
336 }
337
338 /*
339  * ¥Ç¥Õ¥©¥ë¥È¤Î¥ë¡¼¥ë¤È¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿¥ë¡¼¥ë¤ò¥Þ¡¼¥¸¤·¤Æ
340  * rk_map¤òºî¤ë¡£
341  */
342 static struct rk_map*
343 make_rkmap_hirakata(const struct rk_rule* rule,
344                     struct rk_option *opt, int map_no)
345 {
346   struct rk_conf_ent *tab;
347   struct rk_rule* rk_var_part;
348   struct rk_rule* complete_rules;
349   struct rk_rule* p;
350   struct rk_map* map;
351   int toggle = opt->toggle;
352   char *work;
353   char* w;
354   int c;
355   int nr_rule;
356   char buf[2];
357
358   nr_rule = count_rk_rule_ent(opt, map_no);
359
360   rk_var_part = alloca(sizeof(struct rk_rule) *(nr_rule + 2));
361   work = alloca(2*128 + 8);
362   p = rk_var_part;
363   w = work;
364
365   /* °ìʸ»ú¤Î¤â¤Î¤òrk_var_part¤Ë½ñ¤­¹þ¤ó¤Ç¤¤¤¯ */
366   /* ¥È¥°¥ë¤Î¾ì¹ç */
367   buf[0] = toggle;
368   buf[1] = 0;
369   w[0] = toggle;
370   w[1] = '\0';
371   w[2] = '\xff';
372   w[3] = '0' + RKMAP_SHIFT_ASCII;
373   w[4] = '\0';
374   rkrule_set(p++, w, w + 2, NULL);
375   w[5] = toggle;
376   w[6] = toggle;
377   w[7] = '\0';
378   tab = find_rk_conf_ent(opt, map_no, buf, 0);
379   if (tab && tab->rhs) {
380     rkrule_set(p++, w + 5, tab->rhs, NULL);
381   } else {
382     rkrule_set(p++, w + 5, rk_default_symbol[toggle], NULL);
383   }
384   w += 8;
385   /* ¥È¥°¥ë°Ê³° */
386   for (c = 0; c < 128; c++) {
387     if (c != toggle) {
388       buf[0] = c;
389       buf[1] = 0;
390       /* °ìʸ»ú¤Î¤â¤Î */
391       w[0] = c;
392       w[1] = '\0';
393       tab = find_rk_conf_ent(opt, map_no, buf, 0);
394       if (tab && tab->rhs) {
395         /* ¥«¥¹¥¿¥Þ¥¤¥ººÑ¤Î¤¬¤¢¤ë */
396         rkrule_set(p++, w, tab->rhs, NULL);
397       } else if (rk_default_symbol[c]) {
398         /* µ­¹æ¤Ê¤É */
399         rkrule_set(p++, w, rk_default_symbol[c], NULL);
400       }
401       w += 2;
402       /* Æóʸ»ú°Ê¾å¤Î¤â¤Î */
403       if (tab) {
404         for (tab = tab->next; tab; tab = tab->next) {
405           rkrule_set(p++, tab->lhs, tab->rhs, NULL);
406         }
407       }
408     }
409   }
410   p->lhs = NULL;
411
412   if (opt->enable_default) {
413     complete_rules = rk_merge_rules(rule, rk_var_part);
414     map = rk_map_create(complete_rules);
415     rk_rules_free(complete_rules);
416   } else {
417     map = rk_map_create(rk_var_part);
418   }
419
420   return map;
421 }
422
423 struct rk_map*
424 make_rkmap_hiragana(struct rk_option* opt)
425 {
426   return make_rkmap_hirakata(rk_rule_hiragana,
427                              opt, RKMAP_HIRAGANA);
428 }
429
430 struct rk_map*
431 make_rkmap_katakana(struct rk_option* opt)
432 {
433   return make_rkmap_hirakata(rk_rule_katakana,
434                              opt, RKMAP_KATAKANA);
435 }
436
437 struct rk_map *
438 make_rkmap_hankaku_kana(struct rk_option *opt)
439 {
440   return make_rkmap_hirakata(rk_rule_hankaku_kana,
441                              opt, RKMAP_HANKAKU_KANA);
442 }