1 /*
2  *  $Id: rd_jishoop.c,v 1.4 2003/06/07 02:23:58 hiroo Exp $
3  */
4 
5 /*
6  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7  * This file is part of FreeWnn.
8  *
9  * Copyright Kyoto University Research Institute for Mathematical Sciences
10  *                 1987, 1988, 1989, 1990, 1991, 1992
11  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
12  * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
13  * Copyright FreeWnn Project 1999, 2000, 2003
14  *
15  * Maintainer:  FreeWnn Project   <freewnn@tomo.gr.jp>
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30  */
31 
32 #ifdef HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35 
36 #include <stdio.h>
37 #include "commonhd.h"
38 #include "de_header.h"
39 #include "jdata.h"
40 
41 static void rd_make_space (struct rind1 *, int, struct JT *, int, int);
42 static void rd_remove_space (struct rind1 *, int, struct JT *, int, int);
43 
44 #ifdef  CONVERT_with_SiSheng
45 unsigned int sisheng_int;
46 static char pan_tmp[256];
47 w_char pan_yomi[LENGTHYOMI];
48 #endif
49 
50 int
rd_word_add1(struct JT * jtl,w_char * pyomi,int hinsi,w_char * pkanji,w_char * comment)51 rd_word_add1 (struct JT *jtl,
52 	      w_char *pyomi,	/* normal order (not reversed) */
53 	      int hinsi,
54 	      w_char *pkanji,	/* normal order (not reversed) */
55 	      w_char *comment)
56 {
57   struct rind1 *tary;
58   int key, key0, keye;
59   int serial = jtl->maxserial;
60   w_char *tmp = (w_char *) 0;
61   struct rind2 *ri2;
62   int ind;
63   int which;
64   w_char *csult;
65 
66   w_char yomi[LENGTHYOMI];
67   w_char kanji[LENGTHYOMI];
68 
69 #ifdef  CONVERT_with_SiSheng
70   unsigned int sisheng_int;
71   char pan_tmp[256];
72   w_char pan_yomi[LENGTHYOMI];
73 
74   sisheng_int = 0;
75   biki_sisheng (pyomi, pan_tmp, yomi);
76   sscanf (pan_tmp, "%d", &sisheng_int);
77   Strcpy (kanji, pkanji);
78 #else
79 # ifdef CONVERT_from_TOP
80   Strcpy (yomi, pyomi);
81   Strcpy (kanji, pkanji);
82 # else
83   Sreverse (yomi, pyomi);
84   Sreverse (kanji, pkanji);
85 # endif /* CONVERT_from_TOP */
86 #endif /* CONVERT_with_SiSheng */
87 
88   if ((jtl->bufsize_kanji <= jtl->maxkanji + (Strlen (kanji) + Strlen (comment) + Strlen (yomi) + 3) * sizeof (w_char) + 1)
89       && (ud_realloc_kanji (jtl) == NULL))
90     {
91       return (-1);
92     }
93   if (jtl->bufsize_ri1[D_YOMI] <= jtl->maxri1[D_YOMI] + 2
94      && rd_realloc_ri1 (jtl, D_YOMI) == NULL)
95     {
96       return (-1);
97     }
98   if (jtl->bufsize_ri1[D_KANJI] <= jtl->maxri1[D_KANJI] + 2
99      && rd_realloc_ri1 (jtl, D_KANJI) == NULL)
100     {
101       return (-1);
102     }
103   if (jtl->bufsize_serial <= jtl->maxserial + 4
104      && ud_realloc_serial (jtl) == NULL)
105     {
106       return (-1);
107     }
108 
109   ri2 = jtl->ri2;
110 
111   tary = jtl->ri1[D_YOMI];
112   key = rd_binary_same (tary, yomi, jtl->maxri1[D_YOMI], jtl->ri2, jtl->kanji, D_YOMI);
113   if (key != -1)
114     {                           /*  Entry with same yomi */
115       ind = tary[key].pter;
116       while (1)
117         {
118           w_char kanji1[LENGTHKANJI];
119           w_char comment1[LENGTHKANJI];
120           if (jtl->hinsi[ind] == hinsi)
121             {
122               Get_kanji (ri2[ind].kanjipter + jtl->kanji, yomi, Strlen (yomi), kanji1, NULL, comment1);
123               if (Strcmp (pkanji, kanji1) == 0)
124                 {
125                   /* Same hinsi, same kanji, same yomi */
126                   if (Strcmp (comment, comment1) != 0)
127                     {
128                       /* set_comment */
129                       ri2[ind].kanjipter = jtl->maxkanji;
130                       kanjiadd (jtl, pkanji, pyomi, comment);
131                     }
132                   return (ind);
133                 }
134             }
135           if (ri2[ind].next[D_YOMI] == RD_ENDPTR)
136             break;
137           ind = ri2[ind].next[D_YOMI];
138         }
139     }
140   for (which = 0; which < 2; which++)
141     {
142       csult = (which == 0) ? yomi : kanji;
143       tary = jtl->ri1[which];
144       key = rd_binary1 (tary, csult, jtl->maxri1[which], jtl->ri2, jtl->kanji, which);
145       if (key >= 0)
146         {
147           tmp = KANJI_str (ri2[tary[key].pter].kanjipter + jtl->kanji, which);
148 #ifdef  CONVERT_with_SiSheng
149           tmp = biki_sisheng (tmp, pan_tmp, pan_yomi);
150 #endif
151         }
152       if (key < 0 || Strcmp (csult, tmp))
153         {                       /* No entry with same yomi */
154           key += 1;
155           for (key0 = key - 1; key0 >= 0; key0 = tary[key0].pter1)
156             {
157               tmp = KANJI_str (ri2[tary[key0].pter].kanjipter + jtl->kanji, which);
158 #ifdef  CONVERT_with_SiSheng
159               tmp = biki_sisheng (tmp, pan_tmp, pan_yomi);
160 #endif
161               if (Substr (tmp, csult))
162                 {
163                   break;
164                 }
165             }
166 #ifdef CONVERT_by_STROKE
167           if (jtl->bind != NULL)
168             b_index_add (jtl, pyomi, serial);
169 #endif
170           rd_make_space (tary, key, jtl, jtl->maxri1[which], which);
171           for (keye = key + 1; keye < jtl->maxri1[which]; keye++)
172             {
173               tmp = KANJI_str (ri2[tary[keye].pter].kanjipter + jtl->kanji, which);
174 #ifdef  CONVERT_with_SiSheng
175               tmp = biki_sisheng (tmp, pan_tmp, pan_yomi);
176 #endif
177               if (!Substr (csult, tmp))
178                 break;
179               if (tary[keye].pter1 == key0)
180                 tary[keye].pter1 = key;
181             }
182           tary[key].pter1 = key0;
183           ri2[serial].next[which] = RD_ENDPTR;
184         }
185       else
186         {
187           ri2[serial].next[which] = tary[key].pter;
188         }
189       tary[key].pter = serial;
190     }
191   jtl->maxserial++;
192   jtl->maxri2++;
193   jtl->gosuu++;
194   ri2[serial].kanjipter = jtl->maxkanji;
195   jtl->hinsi[serial] = hinsi;
196   jtl->hindo[serial] = 0;       /* Hindo is set later on upper module */
197 #ifdef  CONVERT_with_SiSheng
198   jtl->sisheng[serial] = sisheng_int;
199 #endif
200   kanjiadd (jtl, pkanji, pyomi, comment);
201   return (serial);
202 }
203 
204 int
rd_word_delete1(struct JT * jtl,struct HJT * hjtl,int serial)205 rd_word_delete1 (struct JT *jtl, struct HJT *hjtl, int serial)
206 {
207   struct rind1 *tary;
208   int ind1;
209   int *pt;
210   w_char *yomi;
211   struct rind2 *ri2;
212   int which;
213 
214   ri2 = jtl->ri2;
215   for (which = 0; which < 2; which++)
216     {
217       tary = jtl->ri1[which];
218       yomi = KANJI_str (ri2[serial].kanjipter + jtl->kanji, which);
219 #ifdef  CONVERT_with_SiSheng
220       yomi = biki_sisheng (yomi, pan_tmp, pan_yomi);
221 #endif
222       ind1 = rd_binary (tary, yomi, jtl->maxri1[which], jtl->ri2, jtl->kanji, which);
223       if (ind1 == -1)
224         {
225           wnn_errorno = WNN_WORD_NO_EXIST;
226           return (-1);
227         }
228       for (pt = &(tary[ind1].pter);; pt = &(jtl->ri2[*pt].next[which]))
229         {
230           if (*pt == serial)
231             {
232               *pt = jtl->ri2[*pt].next[which];
233               break;
234             }
235           if (*pt == RD_ENDPTR)
236             {
237               wnn_errorno = WNN_WORD_NO_EXIST;  /* Must not come here */
238               return (-1);
239             }
240         }
241       if (tary[ind1].pter == RD_ENDPTR)
242         {
243 #ifdef CONVERT_by_STROKE
244           if (jtl->bind != NULL)
245             b_index_delete (jtl, serial);
246 #endif
247           rd_remove_space (tary, ind1, jtl, tary[ind1].pter1, which);
248         }
249     }
250 
251   if (serial == jtl->maxserial - 1)
252     {
253       jtl->maxserial--;
254       jtl->maxri2--;
255       if (hjtl)
256         hjtl->maxserial--;
257     }
258   if ((int) (ri2[serial].kanjipter + *(ri2[serial].kanjipter + jtl->kanji)) >= (int) jtl->maxkanji)
259     {
260       jtl->maxkanji = ri2[serial].kanjipter;
261     }
262   jtl->hinsi[serial] = SAKUJO_HINSI;
263   jtl->gosuu--;
264   return (0);
265 }
266 
267 
268 int
inspect_rd(int dic_no,int serial,w_char * yomi,struct jdata * jd)269 inspect_rd (int dic_no, int serial, w_char *yomi, struct jdata *jd)
270 {
271   struct JT *jtl;
272   struct HJT *hjtl;
273   struct rind2 *p;
274 
275   jtl = (struct JT *) (files[dic_table[dic_no].body].area);
276   if (dic_table[dic_no].hindo >= 0)
277     hjtl = (struct HJT *) (files[dic_table[dic_no].hindo].area);
278   else
279     hjtl = NULL;
280 
281   if (serial >= jtl->maxserial)
282     {
283       wnn_errorno = WNN_WORD_NO_EXIST;
284       return (-1);
285     }
286   if (jtl->hinsi[serial] == SAKUJO_HINSI)
287     return (-1);
288 
289   p = jtl->ri2 + serial;
290   get_kanji_str (jtl->kanji + p->kanjipter, NULL, yomi, NULL);
291 
292   jd->kanji1 = p->kanjipter;
293   jd->kanji2 = 0;
294   jd->serial = serial;
295   jd->kosuu = 1;
296   jd->jishono = dic_no;
297   jd->jptr = NULL;
298   jd->hinsi = jtl->hinsi + serial;
299   if (hjtl)
300     {
301       jd->hindo = hjtl->hindo + serial;
302       jd->hindo_in = jtl->hindo + serial;
303     }
304   else
305     {
306       jd->hindo = jtl->hindo + serial;
307       jd->hindo_in = NULL;
308     }
309 #ifdef  CONVERT_with_SiSheng
310   jd->sisheng = jtl->sisheng + serial;
311 #endif
312   return (0);
313 }
314 
315 static void
rd_make_space(struct rind1 * tary,int key,struct JT * jtl,int end,int which)316 rd_make_space (struct rind1 *tary, int key, struct JT *jtl, int end, int which)
317 {
318   struct rind1 *p, *p1, *pend;
319 
320   pend = tary + key;
321   for (p = tary + end - 1, p1 = tary + end; p >= pend; p--, p1--)
322     {
323       *p1 = *p;                 /* struct no dainyuu! */
324       if (p1->pter1 >= key)
325         p1->pter1++;
326     }
327   jtl->maxri1[which]++;
328 }
329 
330 static void
rd_remove_space(struct rind1 * tary,int key,struct JT * jtl,int newkey,int which)331 rd_remove_space (struct rind1 *tary, int key, struct JT *jtl, int newkey, int which)
332 {
333   struct rind1 *p, *p1, *pend;
334 
335   pend = tary + jtl->maxri1[which];
336   for (p = tary + key + 1, p1 = tary + key; p < pend; p++, p1++)
337     {
338       *p1 = *p;
339       if (p1->pter1 > key)
340         p1->pter1--;
341       else if (p1->pter1 == key)
342         p1->pter1 = newkey;
343     }
344   jtl->maxri1[which]--;
345 }
346 
347