Applied fPIE, pie compier option
[platform/core/uifw/anthy.git] / src-worddic / mem_dic.c
1 /*
2  * mem_dic ¼­½ñ¤Î¥­¥ã¥Ã¥·¥å¤ò¹Ô¤¦
3  *
4  * ¥­¥ã¥Ã¥·¥å¤ÏÆɤߤÎʸ»úÎó¤ÈµÕÊÑ´¹ÍѤ«¤Î¥Õ¥é¥°(is_reverse)¤Î
5  * Æó¤Ä¤ò¥­¡¼¤È¤·¤ÆÁàºî¤µ¤ì¤ë¡£
6  *
7  * Copyright (C) 2000-2007 TABATA Yusuke
8  */
9 /*
10   This library is free software; you can redistribute it and/or
11   modify it under the terms of the GNU Lesser General Public
12   License as published by the Free Software Foundation; either
13   version 2 of the License, or (at your option) any later version.
14
15   This library is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18   Lesser General Public License for more details.
19
20   You should have received a copy of the GNU Lesser General Public
21   License along with this library; if not, write to the Free Software
22   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
23  */
24 #include <stdlib.h>
25
26 #include <anthy/alloc.h>
27 #include "dic_main.h"
28 #include "mem_dic.h"
29
30 static allocator mem_dic_ator;
31
32 static void
33 dic_ent_dtor(void *p)
34 {
35   struct dic_ent *de = p;
36   if (de->str.str) {
37     free(de->str.str);
38   }
39 }
40
41 static void
42 seq_ent_dtor(void *p)
43 {
44   struct seq_ent *seq = p;
45   int i;
46   /**/
47   for (i = 0; i < seq->nr_dic_ents; i++) {
48     anthy_sfree(seq->md->dic_ent_allocator, seq->dic_ents[i]);
49   }
50   if (seq->nr_dic_ents) {
51     free(seq->dic_ents);
52   }
53   /**/
54   free(seq->str.str);
55 }
56
57 static void
58 mem_dic_dtor(void *p)
59 {
60   struct mem_dic * md = p;
61   anthy_free_allocator(md->seq_ent_allocator);
62   anthy_free_allocator(md->dic_ent_allocator);
63 }
64
65 /** xstr¤ËÂбþ¤¹¤ëseq_ent¤ò³ÎÊݤ¹¤ë */
66 static struct seq_ent *
67 alloc_seq_ent_by_xstr(struct mem_dic * md, xstr *x, int is_reverse)
68 {
69   struct seq_ent *se;
70   se = (struct seq_ent *)anthy_smalloc(md->seq_ent_allocator);
71   if (is_reverse) {
72     se->seq_type = ST_REVERSE;
73   } else {
74     se->seq_type = ST_NONE;
75   }
76   se->md = md;
77   se->str.len = x->len;
78   /**/
79   se->nr_dic_ents = 0;
80   se->dic_ents = NULL;
81   /**/
82   se->nr_compound_ents = 0;
83
84   se->str.str = anthy_xstr_dup_str(x);
85   return se;
86 }
87
88 /* ¥Ï¥Ã¥·¥å´Ø¿ô¡£¤È¤ê¤¢¤¨¤º¤Æ¤­¤È¡¼ */
89 static int
90 hash_function(xstr *xs)
91 {
92   if (xs->len) {
93     return xs->str[0]% HASH_SIZE;
94   }
95   return 0;
96 }
97
98 /** xstr¤ËÂбþ¤¹¤ëseq_ent¤òÊÖ¤¹ */
99 struct seq_ent *
100 anthy_mem_dic_alloc_seq_ent_by_xstr(struct mem_dic * md, xstr *xs,
101                                     int is_reverse)
102 {
103   struct seq_ent *se;
104   int h;
105   /* ¥­¥ã¥Ã¥·¥å¤Ë¤¢¤ì¤Ð¤½¤ì¤òÊÖ¤¹ */
106   se = anthy_mem_dic_find_seq_ent_by_xstr(md, xs, is_reverse);
107   if (se) {
108     return se;
109   }
110   /* ¥­¥ã¥Ã¥·¥å¤Ë¤Ï̵¤¤¤Î¤Çºî¤ë */
111   se = alloc_seq_ent_by_xstr(md, xs, is_reverse);
112
113   /* mem_dicÃæ¤Ë¤Ä¤Ê¤° */
114   h = hash_function(xs);
115   se->next = md->seq_ent_hash[h];
116   md->seq_ent_hash[h] = se;
117
118   return se;
119 }
120
121 static int
122 compare_seq_ent(struct seq_ent *seq, xstr *xs, int is_reverse)
123 {
124   /* ¤Þ¤º¡¢¤É¤Á¤é¤«¤¬µÕÊÑ´¹ÍѤΥ¨¥ó¥È¥ê¤«¤ò¥Á¥§¥Ã¥¯ */
125   if (seq->seq_type & ST_REVERSE) {
126     if (!is_reverse) {
127       return 1;
128     }
129   } else {
130     if (is_reverse) {
131       return 1;
132     }
133   }
134   /* ¼¡¤Ëʸ»úÎó¤ÎÈæ³Ó */
135   return anthy_xstrcmp(&seq->str, xs);
136 }
137
138 /*** mem_dic¤ÎÃ椫¤éʸ»úÎó¤ËÂбþ¤¹¤ëseq_ent*¤ò¼èÆÀ¤¹¤ë
139  * */
140 struct seq_ent *
141 anthy_mem_dic_find_seq_ent_by_xstr(struct mem_dic * md, xstr *xs,
142                                    int is_reverse)
143 {
144   struct seq_ent *sn;
145   int h;
146   h = hash_function(xs);
147   for (sn = md->seq_ent_hash[h]; sn; sn = sn->next) {
148     if (!compare_seq_ent(sn, xs, is_reverse)){
149       return sn;
150     }
151   }
152   return 0;
153 }
154
155 void
156 anthy_mem_dic_release_seq_ent(struct mem_dic * md, xstr *xs, int is_reverse)
157 {
158   struct seq_ent *sn;
159   struct seq_ent **sn_prev_p;
160   int h;
161
162   h = hash_function(xs);
163   sn_prev_p = &md->seq_ent_hash[h];
164   for (sn = md->seq_ent_hash[h]; sn; sn = sn->next) {
165     if (!compare_seq_ent(sn, xs, is_reverse)){
166       *sn_prev_p = sn->next;
167       anthy_sfree(md->seq_ent_allocator, sn);
168       return;
169     } else {
170       sn_prev_p = &sn->next;
171     }
172   }
173 }
174
175 /** seq_ent¤Ëdic_ent¤òÄɲ乤ë */
176 void
177 anthy_mem_dic_push_back_dic_ent(struct seq_ent *se, int is_compound,
178                                 xstr *xs, wtype_t wt,
179                                 const char *wt_name, int freq, int feature)
180 {
181   struct dic_ent *de;
182   de = anthy_smalloc(se->md->dic_ent_allocator);
183   de->type = wt;
184   de->wt_name = wt_name;
185   de->freq = freq;
186   de->feature = feature;
187   de->order = 0;
188   de->is_compound = is_compound;
189   de->str.len = xs->len;
190   de->str.str = anthy_xstr_dup_str(xs);
191
192   if (is_compound) {
193     se->nr_compound_ents ++;
194   }
195
196   /* order¤ò·×»»¤¹¤ë */
197   if (se->nr_dic_ents > 0) {
198     struct dic_ent *prev_de = se->dic_ents[se->nr_dic_ents-1];
199     if (anthy_wtype_equal(prev_de->type, de->type) &&
200         prev_de->freq > de->freq) {
201       de->order = prev_de->order + 1;
202     }
203   }
204
205   /* ÇÛÎó¤ËÄɲ乤ë */
206   se->nr_dic_ents ++;
207   se->dic_ents = realloc(se->dic_ents,
208                          sizeof(struct dic_ent *)*se->nr_dic_ents);
209   se->dic_ents[se->nr_dic_ents-1] = de;
210 }
211
212 struct mem_dic *
213 anthy_create_mem_dic(void)
214 {
215   int i;
216   struct mem_dic *md;
217
218   md = anthy_smalloc(mem_dic_ator);
219   for (i = 0; i < HASH_SIZE; i++) {
220     md->seq_ent_hash[i] = NULL;
221   }
222   
223   md->seq_ent_allocator = 
224     anthy_create_allocator(sizeof(struct seq_ent),
225                            seq_ent_dtor);
226   md->dic_ent_allocator =
227     anthy_create_allocator(sizeof(struct dic_ent),
228                            dic_ent_dtor);
229
230   return md;
231 }
232
233 void
234 anthy_release_mem_dic(struct mem_dic * d)
235 {
236   anthy_sfree(mem_dic_ator, d);
237 }
238
239 void
240 anthy_init_mem_dic(void)
241 {
242   mem_dic_ator = anthy_create_allocator(sizeof(struct mem_dic),
243                                         mem_dic_dtor);
244 }
245
246 void
247 anthy_quit_mem_dic(void)
248 {
249   anthy_free_allocator(mem_dic_ator);
250 }