Create devel package not to install header and .pc file in binary
[platform/core/uifw/anthy.git] / src-worddic / word_lookup.c
1 /*
2  * Word Dictionary
3  * ¥Õ¥¡¥¤¥ë¤Î¼­½ñ¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¡¢Â¸ºß¤¹¤ë¥Ç¡¼¥¿¤Ï
4  * ¥­¥ã¥Ã¥·¥å¤µ¤ì¤ë¤Î¤Ç¤³¤³¤Ç¤Ï¸ºß¤·¤Ê¤¤Ã±¸ì¤Î
5  * ¥µ¡¼¥Á¤ò¹â®¤Ë¤¹¤ëɬÍפ¬¤¢¤ë¡£
6  *
7  * anthy_gang_fill_seq_ent()¤¬Ãæ¿´¤È¤Ê¤ë´Ø¿ô¤Ç¤¢¤ë
8  *  »ØÄꤷ¤¿word_dic¤«¤é»ØÄꤷ¤¿Ê¸»úÎó¤ò¥¤¥ó¥Ç¥Ã¥¯¥¹¤È¤·¤Æ¤â¤Ä¥¨¥ó¥È¥ê¤Ë
9  *  ¸ìÈø¤òÉղä·¤Æseq_ent¤ËÄɲ乤ë
10  *
11  * a)¼­½ñ¤Î·Á¼°¤Èb)¼­½ñ¥¢¥¯¥»¥¹¤Î¹â®²½c)¼­½ñ¥Õ¥¡¥¤¥ë¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°
12  *  ¤³¤Î¥½¡¼¥¹Ãæ¤Ç°·¤Ã¤Æ¤ë¤Î¤Ç¤«¤Ê¤êÊ£»¨²½¤·¤Æ¤Þ¤¹¡¥
13  *
14  * Copyright (C) 2000-2007 TABATA Yusuke
15  * Copyright (C) 2005-2006 YOSHIDA Yuichi
16  * Copyright (C) 2001-2002 TAKAI Kosuke
17  *
18  */
19 /*
20   This library is free software; you can redistribute it and/or
21   modify it under the terms of the GNU Lesser General Public
22   License as published by the Free Software Foundation; either
23   version 2 of the License, or (at your option) any later version.
24
25   This library is distributed in the hope that it will be useful,
26   but WITHOUT ANY WARRANTY; without even the implied warranty of
27   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
28   Lesser General Public License for more details.
29
30   You should have received a copy of the GNU Lesser General Public
31   License along with this library; if not, write to the Free Software
32   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
33  */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <ctype.h>
39
40 #include "config.h"
41 #include <anthy/anthy.h>
42 #include <anthy/alloc.h>
43 #include <anthy/dic.h>
44 #include <anthy/word_dic.h>
45 #include <anthy/logger.h>
46 #include <anthy/xstr.h>
47 #include <anthy/diclib.h>
48
49 #include "dic_main.h"
50 #include "dic_ent.h"
51
52 #define NO_WORD -1
53
54 static allocator word_dic_ator;
55
56 struct lookup_context {
57   struct gang_elm **array;
58   int nr;
59   int nth;
60   int is_reverse;
61 };
62
63 /* 1¥Ð¥¤¥ÈÌܤò¸«¤Æ¡¢Ê¸»ú¤¬²¿¥Ð¥¤¥È¤¢¤ë¤«¤òÊÖ¤¹ */
64 static int
65 mb_fragment_len(const char *str)
66 {
67   unsigned char c = *((const unsigned char *)str);
68   if (c < 0x80) {
69     return 1;
70   }
71   if (c < 0xe0) {
72     return 2;
73   }
74   if (c < 0xf0) {
75     return 3;
76   }
77   if (c < 0xf8) {
78     return 4;
79   }
80   if (c < 0xfc) {
81     return 5;
82   }
83   return 6;
84 }
85
86 static int
87 is_printable(char *str)
88 {
89   unsigned char *tmp = (unsigned char *)str;
90   if (*tmp > 31 && *tmp < 127) {
91     return 1;
92   }
93   if (mb_fragment_len(str) > 1) {
94     return 1;
95   }
96   return 0;
97 }
98
99 /* ¼­½ñ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤«¤éxchar¤òºî¤ë */
100 static xchar
101 form_mb_char(const char *str)
102 {
103   xchar xc;
104   anthy_utf8_to_ucs4_xchar(str, &xc);
105   return xc;
106 }
107
108 static int
109 hash(xstr *x)
110 {
111   return anthy_xstr_hash(x)&
112     (YOMI_HASH_ARRAY_SIZE*YOMI_HASH_ARRAY_BITS-1);
113 }
114
115 static int
116 check_hash_ent(struct word_dic *wdic, xstr *xs)
117 {
118   int val = hash(xs);
119   int idx = (val>>YOMI_HASH_ARRAY_SHIFT)&(YOMI_HASH_ARRAY_SIZE-1);
120   int bit = val & ((1<<YOMI_HASH_ARRAY_SHIFT)-1);
121   return wdic->hash_ent[idx] & (1<<bit);
122 }
123
124 static int
125 wtype_str_len(const char *str)
126 {
127   int i;
128   for (i = 0; str[i] && str[i]!= ' '; i++);
129   return i;
130 }
131
132 /* ¼­½ñ¤Î¹ÔÃæ¤ò¥¹¥­¥ã¥ó¤¹¤ë¤¿¤á¤Î¾õÂÖÊÝ»ý */
133 struct wt_stat {
134   wtype_t wt;
135   const char *wt_name;
136   int feature;
137   int freq;
138   int order_bonus;/* ¼­½ñÃæ¤Î½ç½ø¤Ë¤è¤ëÉÑÅ٤Υܡ¼¥Ê¥¹ */
139   int offset;/* Ê¸»úÎóÃæ¤Î¥ª¥Õ¥»¥Ã¥È */
140   const char *line;
141   int encoding;
142 };
143 /*
144  * #XX*123 ¤È¤¤¤¦Cannadic¤Î·Á¼°¤ò¥Ñ¡¼¥º¤¹¤ë
145  *  #XX
146  *  #XX*123
147  *  #XX,x*123
148  */
149 static const char *
150 parse_wtype_str(struct wt_stat *ws)
151 {
152   int len;
153   char *buf;
154   char *freq_part;
155   char *feature_part;
156   const char *wt_name;
157   /* ¥Ð¥Ã¥Õ¥¡¤Ø¥³¥Ô¡¼¤¹¤ë */
158   len = wtype_str_len(&ws->line[ws->offset]);
159   buf = alloca(len + 1);
160   strncpy(buf, &ws->line[ws->offset], len);
161   buf[len] = 0;
162
163   /* ÁÇÀ­(̤»ÈÍÑ) */
164   feature_part = strchr(buf, ',');
165   if (feature_part) {
166     ws->feature = 1;
167   } else {
168     ws->feature = 0;
169   }
170
171   /* ÉÑÅÙ¤òparse¤¹¤ë */
172   freq_part = strchr(buf, '*');
173   if (freq_part) {
174     *freq_part = 0;
175     freq_part ++;
176     ws->freq = atoi(freq_part) * FREQ_RATIO;
177   } else {
178     ws->freq = FREQ_RATIO - 2;
179   }
180
181   /**/
182   wt_name = anthy_type_to_wtype(buf, &ws->wt);
183   if (!wt_name) {
184     ws->wt = anthy_wt_none;
185   }
186   ws->offset += len;
187   return wt_name;
188 }
189
190
191 static int
192 normalize_freq(struct wt_stat* ws)
193 {
194   if (ws->freq < 0) {
195     ws->freq *= -1;
196   }
197   return ws->freq + ws->order_bonus;
198 }
199
200 /* '\\'¤Ë¤è¤ë¥¨¥¹¥±¡¼¥×¤ËÂбþ¤·¤¿¥³¥Ô¡¼ */
201 static void
202 copy_to_buf(char *buf, const char *src, int char_count)
203 {
204   int pos;
205   int i;
206   pos = 0;
207   for (i = 0; i < char_count; i++){
208     if (src[i] == '\\') {
209       if (src[i + 1] == ' ') {
210         i ++;
211       } else if (src[i + 1] == '\\') {
212         i ++;
213       }
214     }
215     buf[pos] = src[i];
216     pos ++;
217   }
218   buf[pos] = 0;
219 }
220
221 /** seq_ent¤Ëdic_ent¤òÄɲ乤ë */
222 static int
223 add_dic_ent(struct seq_ent *seq, struct wt_stat *ws,
224             xstr* yomi, int is_reverse)
225 {
226   int i;
227   /* ¼­½ñ¥Õ¥¡¥¤¥ëÃæ¤Î¥Ð¥¤¥È¿ô */
228   int char_count;
229   char *buf;
230   xstr *xs;
231   int freq;
232   wtype_t w = ws->wt;
233   const char *s = &ws->line[ws->offset];
234
235   /* Ã±¸ì¤Îʸ»ú¿ô¤ò·×»» */
236   for (i = 0, char_count = 0;
237        s[i] && (s[i] != ' ') && (s[i] != '#'); i++) {
238     char_count ++;
239     if (s[i] == '\\') {
240       char_count++;
241       i++;
242     }
243   }
244
245   /* Éʻ줬ÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤¤¤Î¤Ç̵»ë */
246   if (!ws->wt_name) {
247     return char_count;
248   }
249
250   /* freq¤¬Éé¤Ê¤Î¤ÏµÕÊÑ´¹ÍÑ */
251   if (!is_reverse && ws->freq < 0) {
252     return char_count;
253   }
254
255   /* buf¤Ëñ¸ì¤ò¥³¥Ô¡¼ */
256   buf = alloca(char_count+1);
257   copy_to_buf(buf, s, char_count);
258
259   xs = anthy_cstr_to_xstr(buf, ws->encoding);
260
261   /* freq¤¬Àµ¤Ê¤Î¤Ï½çÊÑ´¹ÍÑ */
262   if (is_reverse && ws->freq > 0) {
263     /* ºÆÊÑ´¹¤ÎºÝ¤Ë¡¢ÊÑ´¹ºÑ¤ß¤ÎÉôʬ¤È̤ÊÑ´¹¤ÎÉôʬ¤¬º®¤¸¤Ã¤Æ¤¤¤¿¾ì¹ç¤ËÂбþ¤¹¤ë°Ù¤Ë¡¢
264        Ê¿²¾Ì¾¤Î¤ß¤«¤é¤Ê¤ëÉôʬ¤Ï½ç¼­½ñ¤Ë¤½¤ÎÆɤߤò»ý¤Äñ¸ì¤¬¤¢¤ì¤Ðdic_ent¤òÀ¸À®¤¹¤ë¡£
265     */
266     if (anthy_get_xstr_type(yomi) & XCT_HIRA) {
267       freq = normalize_freq(ws);
268       anthy_mem_dic_push_back_dic_ent(seq, 0, yomi, w,
269                                       ws->wt_name, freq, 0);
270     }      
271     anthy_free_xstr(xs);
272     return char_count;
273   }
274
275   freq = normalize_freq(ws);
276
277   anthy_mem_dic_push_back_dic_ent(seq, 0, xs, w, ws->wt_name, freq, 0);
278   if (anthy_wtype_get_meisi(w)) {
279     /* Ï¢ÍÑ·Á¤¬Ì¾»ì²½¤¹¤ë¤ä¤Ä¤Ï̾»ì²½¤·¤¿¤â¤Î¤âÄɲà*/
280     w = anthy_get_wtype_with_ct(w, CT_MEISIKA);
281     anthy_mem_dic_push_back_dic_ent(seq, 0, xs, w, ws->wt_name, freq, 0);
282   }
283   anthy_free_xstr(xs);
284   return char_count;
285 }
286
287 static int
288 add_compound_ent(struct seq_ent *seq, struct wt_stat *ws,
289                  xstr* yomi,
290                  int is_reverse)
291 {
292   int len = wtype_str_len(&ws->line[ws->offset]);
293   char *buf = alloca(len);
294   xstr *xs;
295   int freq;
296
297   (void)yomi;
298
299   /* freq¤¬Éé¤Ê¤Î¤ÏµÕÊÑ´¹ÍÑ */
300   if (!is_reverse && ws->freq < 0) {
301     /* ÉáÃʤÎÊÑ´¹¤Ç¤ÏÍפé¤Ê¤¤ */
302     return len;
303   }
304
305   /* freq¤¬Àµ¤Ê¤Î¤Ï½çÊÑ´¹ÍÑ */
306   if (is_reverse && ws->freq > 0) {
307
308     /* ºÆÊÑ´¹¤ÎºÝ¤Ë¡¢ÊÑ´¹ºÑ¤ß¤ÎÉôʬ¤È̤ÊÑ´¹¤ÎÉôʬ¤¬º®¤¸¤Ã¤Æ¤¤¤¿¾ì¹ç¤ËÂбþ¤¹¤ë°Ù¤Ë¡¢
309        Ê¿²¾Ì¾¤Î¤ß¤«¤é¤Ê¤ëÉôʬ¤Ï½ç¼­½ñ¤Ë¤½¤ÎÆɤߤò»ý¤Äñ¸ì¤¬¤¢¤ì¤Ðdic_ent¤òÀ¸À®¤¹¤ë¡£
310     */
311     /*
312       yomi¤Ë#_Åù¤òÉղä·¤¿Ê¸»úÎó¤òºî¤ëɬÍפ¬¤¢¤ë
313     if (anthy_get_xstr_type(yomi) & (XCT_HIRA | XCT_KATA)) {
314       freq = normalize_freq(ws);
315       anthy_mem_dic_push_back_compound_ent(seq, xs, ws->wt, freq);
316     }
317     */
318     return len;
319   }
320
321   strncpy(buf, &ws->line[ws->offset + 1], len - 1);
322   buf[len - 1] = 0;
323   xs = anthy_cstr_to_xstr(buf, ws->encoding);
324
325   freq = normalize_freq(ws);
326   anthy_mem_dic_push_back_dic_ent(seq, 1, xs, ws->wt,
327                                   ws->wt_name, freq, 0);
328   anthy_free_xstr(xs);
329
330   return len;
331 }
332
333 static void
334 init_wt_stat(struct wt_stat *ws, char *line)
335 {
336   ws->wt_name = NULL;
337   ws->freq = 0;
338   ws->feature = 0;
339   ws->order_bonus = 0;
340   ws->offset = 0;
341   ws->line = line;
342   ws->encoding = ANTHY_EUC_JP_ENCODING;
343   if (*(ws->line) == 'u') {
344     ws->encoding = ANTHY_UTF8_ENCODING;
345     ws->line ++;
346   }
347 }
348
349 /** ¼­½ñ¤Î¥¨¥ó¥È¥ê¤Î¾ðÊó¤ò¸µ¤Ëseq_ent¤ò¤¦¤á¤ë */
350 static void
351 fill_dic_ent(char *line, struct seq_ent *seq, 
352              xstr* yomi, int is_reverse)
353 {
354   struct wt_stat ws;
355   init_wt_stat(&ws, line);
356
357   while (ws.line[ws.offset]) {
358     if (ws.line[ws.offset] == '#') {
359       if (isalpha(ws.line[ws.offset + 1])) {
360         /* ÉÊ»ì*ÉÑÅÙ */
361         ws.wt_name = parse_wtype_str(&ws);
362         /**/
363         ws.order_bonus = FREQ_RATIO - 1;
364       } else {
365         /* Ê£¹ç¸ì¸õÊä */
366         ws.offset += add_compound_ent(seq, &ws,
367                                       yomi,
368                                       is_reverse);
369       }
370     } else {
371       /* Ã±¸ì */
372       ws.offset += add_dic_ent(seq, &ws, yomi,
373                                is_reverse);
374       if (ws.order_bonus > 0) {
375         ws.order_bonus --;
376       }
377     }
378     if (ws.line[ws.offset] == ' ') {
379       ws.offset++;
380     }
381   }
382 }
383
384 /*
385  * s¤Ë½ñ¤«¤ì¤¿Ê¸»úÎó¤Ë¤è¤Ã¤Æx¤òÊѹ¹¤¹¤ë
386  * ÊÖ¤êÃͤÏÆɤ߿ʤ᤿¥Ð¥¤¥È¿ô
387  */
388 static int
389 mkxstr(char *s, xstr *x)
390 {
391   int i, len;
392   /* s[0]¤Ë¤Ï´¬¤­Ìᤷ¤Îʸ»ú¿ô */
393   x->len -= (s[0] - 1);
394   for (i = 1; is_printable(&s[i]); i ++) {
395     len = mb_fragment_len(&s[i]);
396     if (len > 1) {
397       /* ¥Þ¥ë¥Á¥Ð¥¤¥È */
398       x->str[x->len] = form_mb_char(&s[i]);
399       x->len ++;
400       i += (len - 1);
401     } else {
402       /* 1¥Ð¥¤¥Èʸ»ú */
403       x->str[x->len] = s[i];
404       x->len ++;
405     }
406   } 
407   return i;
408 }
409
410 static int
411 set_next_idx(struct lookup_context *lc)
412 {
413   lc->nth ++;
414   while (lc->nth < lc->nr) {
415     if (lc->array[lc->nth]->tmp.idx != NO_WORD) {
416       return 1;
417     }
418     lc->nth ++;
419   }
420   return 0;
421 }
422
423 /** ¥Ú¡¼¥¸Ãæ¤Îñ¸ì¤Î¾ì½ê¤òÄ´¤Ù¤ë */
424 static void
425 search_words_in_page(struct lookup_context *lc, int page, char *s)
426 {
427   int o = 0;
428   xchar *buf;
429   xstr xs;
430   int nr = 0;
431   /* ¤³¤Î¥Ú¡¼¥¸Ãæ¤Ë¤¢¤ë¤â¤Ã¤È¤âŤ¤Ã±¸ì¤ò³ÊǼ¤·¤¦¤ëŤµ */
432   buf = alloca(sizeof(xchar)*strlen(s)/2);
433   xs.str = buf;
434   xs.len = 0;
435
436   while (*s) {
437     int r;
438     s += mkxstr(s, &xs);
439     r = anthy_xstrcmp(&xs, &lc->array[lc->nth]->xs);
440     if (!r) {
441       lc->array[lc->nth]->tmp.idx = o + page * WORDS_PER_PAGE;
442       nr ++;
443       if (!set_next_idx(lc)) {
444         return ;
445       }
446       /* Æ±¤¸¥Ú¡¼¥¸Æâ¤Ç¼¡¤Îñ¸ì¤òõ¤¹ */
447     }
448     o ++;
449   }
450   if (nr == 0) {
451     /* ¤³¤Î¥Ú¡¼¥¸¤Ç1¸ì¤â¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¤é¡¢¤³¤Îñ¸ì¤Ï̵¤¤ */
452     lc->array[lc->nth]->tmp.idx = NO_WORD;
453     set_next_idx(lc);
454   }
455   /* ¸½ºß¤Îñ¸ì¤Ï¼¡¤Î¸Æ¤Ó½Ð¤·¤Çõ¤¹ */
456 }
457
458 /**/
459 static int
460 compare_page_index(struct word_dic *wdic, const char *key, int page)
461 {
462   char buf[100];
463   char *s = &wdic->page[anthy_dic_ntohl(wdic->page_index[page])];
464   int i;
465   s++;
466   for (i = 0; is_printable(&s[i]);) {
467     int j, l = mb_fragment_len(&s[i]);
468     for (j = 0; j < l; j++) {
469       buf[i+j] = s[i+j];
470     }
471     i += l;
472   }
473   buf[i] = 0;
474   return strcmp(key ,buf);
475 }
476
477 /* ºÆµ¢Åª¤Ë¥Ð¥¤¥Ê¥ê¥µ¡¼¥Á¤ò¤¹¤ë */
478 static int
479 get_page_index_search(struct word_dic *wdic, const char *key, int f, int t)
480 {
481   /* anthy_xstrcmp¤¬-1¤Ç̵¤¯¤Ê¤Ã¤¿¤È¤³¤í¤òõ¤¹ */
482   int c,p;
483   c = (f+t)/2;
484   if (f+1==t) {
485     return c;
486   } else {
487     p = compare_page_index(wdic, key, c);
488     if (p < 0) {
489       return get_page_index_search(wdic, key, f, c);
490     } else {
491       /* c<= <t */
492       return get_page_index_search(wdic, key, c, t);
493     }
494   } 
495 }
496
497 /** key¤ò´Þ¤à²ÄǽÀ­¤Î¤¢¤ë¥Ú¡¼¥¸¤ÎÈÖ¹æ¤òÆÀ¤ë¡¢
498  * ÈÏ°Ï¥Á¥§¥Ã¥¯¤ò¤·¤Æ¥Ð¥¤¥Ê¥ê¥µ¡¼¥Á¤ò¹Ô¤¦get_page_index_search¤ò¸Æ¤Ö
499  */
500 static int
501 get_page_index(struct word_dic *wdic, struct lookup_context *lc)
502 {
503   int page;
504   const char *key = lc->array[lc->nth]->key;
505   /* ºÇ½é¤Î¥Ú¡¼¥¸¤ÎÆɤߤè¤ê¤â¾®¤µ¤¤ */
506   if (compare_page_index(wdic, key, 0) < 0) {
507     return -1;
508   }
509   /* ºÇ¸å¤Î¥Ú¡¼¥¸¤ÎÆɤߤè¤ê¤âÂ礭¤¤¤Î¤Ç¡¢ºÇ¸å¤Î¥Ú¡¼¥¸¤Ë´Þ¤Þ¤ì¤ë²ÄǽÀ­¤¬¤¢¤ë */
510   if (compare_page_index(wdic, key, wdic->nr_pages-1) >= 0) {
511     return wdic->nr_pages-1;
512   }
513   /* ¸¡º÷¤¹¤ë */
514   page = get_page_index_search(wdic, key, 0, wdic->nr_pages);
515   return page;
516 }
517
518 static int
519 get_nr_page(struct word_dic *h)
520 {
521   int i;
522   for (i = 1; anthy_dic_ntohl(h->page_index[i]); i++);
523   return i;
524 }
525
526 static char *
527 get_section(struct word_dic *wdic, int section)
528 {
529   int *p = (int *)wdic->dic_file;
530   int offset = anthy_dic_ntohl(p[section]);
531   return &wdic->dic_file[offset];
532 }
533
534 /** ¼­½ñ¥Õ¥¡¥¤¥ë¤òmmap¤·¤Æ¡¢word_dicÃæ¤Î³Æ¥»¥¯¥·¥ç¥ó¤Î¥Ý¥¤¥ó¥¿¤ò¼èÆÀ¤¹¤ë */
535 static int
536 get_word_dic_sections(struct word_dic *wdic)
537 {
538   wdic->entry_index = (int *)get_section(wdic, 2);
539   wdic->entry = (char *)get_section(wdic, 3);
540   wdic->page = (char *)get_section(wdic, 4);
541   wdic->page_index = (int *)get_section(wdic, 5);
542   wdic->uc_section = (char *)get_section(wdic, 6);
543   wdic->hash_ent = (unsigned char *)get_section(wdic, 7);
544
545   return 0;
546 }
547
548 /** »ØÄꤵ¤ì¤¿Ã±¸ì¤Î¼­½ñÃæ¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÄ´¤Ù¤ë */
549 static void
550 search_yomi_index(struct word_dic *wdic, struct lookup_context *lc)
551 {
552   int p;
553   int page_number;
554
555   /* ¤¹¤Ç¤Ë̵¤¤¤³¤È¤¬Ê¬¤«¤Ã¤Æ¤¤¤ë */
556   if (lc->array[lc->nth]->tmp.idx == NO_WORD) {
557     set_next_idx(lc);
558     return ;
559   }
560
561   p = get_page_index(wdic, lc);
562   if (p == -1) {
563     lc->array[lc->nth]->tmp.idx = NO_WORD;
564     set_next_idx(lc);
565     return ;
566   }
567
568   page_number = anthy_dic_ntohl(wdic->page_index[p]);
569   search_words_in_page(lc, p, &wdic->page[page_number]);
570 }
571
572 static void
573 find_words(struct word_dic *wdic, struct lookup_context *lc)
574 {
575   int i;
576   /* ¸¡º÷Á°¤Ë½üµî */
577   for (i = 0; i < lc->nr; i++) {
578     lc->array[i]->tmp.idx = NO_WORD;
579     if (lc->array[i]->xs.len > 31) {
580       /* 32ʸ»ú°Ê¾åñ¸ì¤Ë¤Ï̤Âбþ */
581       continue;
582     }
583     /* hash¤Ë¤Ê¤¤¤Ê¤é½üµî */
584     if (!check_hash_ent(wdic, &lc->array[i]->xs)) {
585       continue;
586     }
587     /* NO_WORD¤Ç¤Ê¤¤ÃͤòÀßÄꤹ¤ë¤³¤È¤Ç¸¡º÷ÂоݤȤ¹¤ë */
588     lc->array[i]->tmp.idx = 0;
589   }
590   /* ¸¡º÷¤¹¤ë */
591   lc->nth = 0;
592   while (lc->nth < lc->nr) {
593     search_yomi_index(wdic, lc);
594   }
595 }
596
597 static void
598 load_words(struct word_dic *wdic, struct lookup_context *lc)
599 {
600   int i;
601   for (i = 0; i < lc->nr; i++) {
602     int yomi_index;
603     yomi_index = lc->array[i]->tmp.idx;
604     if (yomi_index != NO_WORD) {
605       int entry_index;
606       struct seq_ent *seq;
607       seq = anthy_cache_get_seq_ent(&lc->array[i]->xs,
608                                     lc->is_reverse);
609       entry_index = anthy_dic_ntohl(wdic->entry_index[yomi_index]);
610       fill_dic_ent(&wdic->entry[entry_index],
611                    seq,
612                    &lc->array[i]->xs,
613                    lc->is_reverse);
614       anthy_validate_seq_ent(seq, &lc->array[i]->xs, lc->is_reverse);
615     }
616   }
617 }
618
619 /** word_dic¤«¤éñ¸ì¤ò¸¡º÷¤¹¤ë
620  * ¼­½ñ¥­¥ã¥Ã¥·¥å¤«¤é¸Æ¤Ð¤ì¤ë
621  * (gang lookup¤Ë¤¹¤ë¤³¤È¤ò¸¡Æ¤¤¹¤ë)
622  */
623 void
624 anthy_gang_fill_seq_ent(struct word_dic *wdic,
625                         struct gang_elm **array, int nr,
626                         int is_reverse)
627 {
628   struct lookup_context lc;
629   lc.array = array;
630   lc.nr = nr;
631   lc.is_reverse = is_reverse;
632
633   /* ³Æñ¸ì¤Î¾ì½ê¤òõ¤¹ */
634   find_words(wdic, &lc);
635   /* Ã±¸ì¤Î¾ðÊó¤òÆɤ߹þ¤à */
636   load_words(wdic, &lc);
637 }
638
639 struct word_dic *
640 anthy_create_word_dic(void)
641 {
642   struct word_dic *wdic;
643   char *p;
644
645   wdic = anthy_smalloc(word_dic_ator);
646   memset(wdic, 0, sizeof(*wdic));
647
648   /* ¼­½ñ¥Õ¥¡¥¤¥ë¤ò¥Þ¥Ã¥×¤¹¤ë */
649   wdic->dic_file = anthy_file_dic_get_section("word_dic");
650
651   /* ³Æ¥»¥¯¥·¥ç¥ó¤Î¥Ý¥¤¥ó¥¿¤ò¼èÆÀ¤¹¤ë */
652   if (get_word_dic_sections(wdic) == -1) {
653     anthy_sfree(word_dic_ator, wdic);
654     return 0;
655   }
656   wdic->nr_pages = get_nr_page(wdic);
657
658   /* ÍÑÎã¼­½ñ¤ò¥Þ¥Ã¥×¤¹¤ë */
659   p = wdic->uc_section;
660   return wdic;
661 }
662
663 void
664 anthy_release_word_dic(struct word_dic *wdic)
665 {
666   anthy_sfree(word_dic_ator, wdic);
667 }
668
669 void
670 anthy_init_word_dic(void)
671 {
672   word_dic_ator = anthy_create_allocator(sizeof(struct word_dic), NULL);
673 }