1 /*
2  *  $Id: jishosub.c,v 1.3 2001/06/14 18:16:02 ura 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
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 #include <stdio.h>
33 #include "commonhd.h"
34 #include "de_header.h"
35 #include "jdata.h"
36 
37 static int inspect_sd (), get_fst_serial (), inspect_ud ();
38 
39 int
inspect(dic_no,serial,yomi,jd)40 inspect (dic_no, serial, yomi, jd)
41      int dic_no;
42      int serial;
43      w_char *yomi;
44      struct jdata *jd;
45 {
46   struct JT *jtl;
47 
48   if (dic_no >= MAX_DIC || dic_no < 0 || dic_table[dic_no].body == -1)
49     {
50       wnn_errorno = WNN_DICT_NOT_IN_ENV;
51       return (-1);
52     }
53   jtl = (struct JT *) (files[dic_table[dic_no].body].area);
54   if (jtl->syurui == WNN_UD_DICT)
55     {
56       if (inspect_ud (dic_no, serial, yomi, jd) == -1)
57         return (-1);
58 #if     defined(CONVERT_by_STROKE) || defined(CONVERT_with_SiSheng)
59     }
60   else if ((jtl->syurui & 0xff) == WNN_REV_DICT)
61     {
62 #else
63     }
64   else if (jtl->syurui == WNN_REV_DICT)
65     {
66 #endif /* CONVERT_by_STROKE || CONVERT_with_SiSheng */
67       if (inspect_rd (dic_no, serial, yomi, jd) == -1)
68         return (-1);
69     }
70   else
71     {
72       if (inspect_sd (dic_no, serial, yomi, jd) == -1)
73         return (-1);
74     }
75   return (0);
76 }
77 
78 
79 
80 int
get_yomi_from_serial(dic_no,serial,yomi)81 get_yomi_from_serial (dic_no, serial, yomi)
82      int dic_no;
83      int serial;
84      w_char *yomi;
85 {
86   int k;
87   struct jdata jdata;
88   struct JT *jtl;
89 
90   jtl = (struct JT *) (files[dic_table[dic_no].body].area);
91   for (k = 0; k < LENGTHYOMI; k++)
92     {
93       yomi[k] = 0;
94     }
95 
96   if (jtl->syurui == WNN_UD_DICT)
97     {
98       if (inspect_ud (dic_no, serial, yomi, &jdata) == -1)
99         return (-1);
100 #if     defined(CONVERT_by_STROKE) || defined(CONVERT_with_SiSheng)
101     }
102   else if ((jtl->syurui & 0xff) == WNN_REV_DICT)
103     {
104 #else
105     }
106   else if (jtl->syurui == WNN_REV_DICT)
107     {
108 #endif /* CONVERT_by_STROKE || CONVERT_with_SiSheng */
109       if (inspect_rd (dic_no, serial, yomi, &jdata) == -1)
110         return (-1);
111     }
112   else
113     {
114       if (inspect_sd (dic_no, serial, yomi, &jdata) == -1)
115         return (-1);
116     }
117   return (0);
118 }
119 
120 
121 static int
inspect_sd(dic_no,serial,yomi,jd)122 inspect_sd (dic_no, serial, yomi, jd)
123      int dic_no;
124      int serial;
125      w_char *yomi;
126      struct jdata *jd;
127 {
128   int len;
129   struct JT *jtl;
130   struct HJT *hjtl;
131   UCHAR *hontaistart;
132   UCHAR *hopter;
133   int key;
134   int tsize;
135   w_char *charst;
136   w_char *sumst;
137   int *ptrst;
138   int state;
139   int sdiff;
140   int last;
141   int serialst;
142   int kanji1;
143 
144 
145   yomi[0] = 0;
146   jtl = (struct JT *) (files[dic_table[dic_no].body].area);
147   if (dic_table[dic_no].hindo >= 0)
148     hjtl = (struct HJT *) (files[dic_table[dic_no].hindo].area);
149   else
150     hjtl = NULL;
151   hontaistart = jtl->hontai;
152   hopter = hontaistart;
153   if (serial >= jtl->maxserial)
154     {
155       wnn_errorno = WNN_WORD_NO_EXIST;
156       return (-1);
157     }
158   if (jtl->hinsi[serial] == SAKUJO_HINSI)
159     return (-1);
160 
161   for (;;)
162     {
163       switch ((state = *(w_char *) hopter))
164         {
165         case ST_NORMAL:
166         case ST_NOPTER:
167           tsize = *(w_char *) (hopter + 2);
168           serialst = *(int *) (hopter + 4);
169           kanji1 = *(int *) (hopter + 8);
170           charst = (w_char *) (hopter + 12);
171           sumst = ((w_char *) charst + tsize + 2);
172           /* + 2 keeps two zero words */
173           ptrst = (int *) ((w_char *) sumst + tsize);
174           sdiff = serial - *(int *) (hopter + 4);
175 
176           /* May be a little late, but enough */
177           if ((int) sdiff < (int) sumst[tsize - 1])
178             {
179               for (key = 0; key < tsize; key++)
180                 {
181                   if ((int) sdiff < (int) sumst[key])
182                     {
183                       break;
184                     }
185                 }
186               len = Strlen (yomi);
187               yomi[len] = charst[key];
188               yomi[len + 1] = 0;
189 
190               jd->kanji1 = kanji1;
191               jd->kanji2 = serial - serialst;
192               jd->serial = serial;
193               jd->kosuu = 1;
194               jd->jishono = dic_no;
195               jd->jptr = NULL;
196               jd->hinsi = jtl->hinsi + serial;
197               if (hjtl)
198                 {
199                   jd->hindo = hjtl->hindo + serial;
200                   jd->hindo_in = jtl->hindo + serial;
201                 }
202               else
203                 {
204                   jd->hindo = jtl->hindo + serial;
205                   jd->hindo_in = NULL;
206                 }
207               return (0);
208             }
209           else
210             {
211               if (state == ST_NOPTER)
212                 {
213                   wnn_errorno = WNN_WORD_NO_EXIST;
214                   return (-1);
215                 }
216               last = 0;
217               for (key = 0; key < tsize; key++)
218                 {
219                   if (ptrst[key])
220                     {
221                       if (serial < get_fst_serial (hontaistart + ptrst[key], hontaistart))
222                         break;
223                       last = key;
224                     }
225                 }
226               len = Strlen (yomi);
227               yomi[len] = charst[last];
228               yomi[len + 1] = 0;
229               hopter = hontaistart + ptrst[last];
230             }
231           break;
232         case ST_NOENT:
233           tsize = *(w_char *) (hopter + 2);
234           charst = (w_char *) (hopter + 4);
235           ptrst = (int *) AL_INT ((w_char *) charst + tsize);
236           last = 0;
237           for (key = 0; key < tsize; key++)
238             {
239               if (ptrst[key])
240                 {
241                   if (serial < get_fst_serial (hontaistart + ptrst[key], hontaistart))
242                     break;
243                   last = key;
244                 }
245             }
246           len = Strlen (yomi);
247           yomi[len] = charst[last];
248           yomi[len + 1] = 0;
249           hopter = hontaistart + ptrst[last];
250           break;
251         case ST_SMALL:
252           len = Strlen (yomi);
253           yomi[len] = *(w_char *) (hopter + 2);
254           yomi[len + 1] = 0;
255           hopter = hopter + 4;
256           break;
257         default:
258           error1 ("inspect_sd:Error 2\n");
259         }
260     }
261 }
262 
263 static int
get_fst_serial(hopter,hontaistart)264 get_fst_serial (hopter, hontaistart)
265      UCHAR *hontaistart;
266      char *hopter;
267 {
268   int tsize;
269   int k;
270   int *ptrst;
271   w_char *charst;
272 
273   switch (*(w_char *) hopter)
274     {
275     case ST_NORMAL:
276     case ST_NOPTER:
277       return (*(int *) (hopter + 4));
278     case ST_NOENT:
279       tsize = *(w_char *) (hopter + 2);
280       charst = (w_char *) (hopter + 4);
281       ptrst = (int *) AL_INT ((w_char *) charst + tsize);
282       for (k = 0; k < tsize; k++)
283         {
284           if (ptrst[k])
285             {
286               return (get_fst_serial (hontaistart + ptrst[k], hontaistart));
287             }
288         }
289       break;
290     case ST_SMALL:
291       return (get_fst_serial (hopter + 4, hontaistart));
292     default:
293       error1 ("get_fst_serial:Error 1\n");
294     }
295   return (-1);
296 }
297 
298 
299 static int
inspect_ud(dic_no,serial,yomi,jd)300 inspect_ud (dic_no, serial, yomi, jd)
301      int dic_no;
302      int serial;
303      w_char *yomi;
304      struct jdata *jd;
305 {
306   struct JT *jtl;
307   struct HJT *hjtl;
308   struct uind1 *tary;
309   struct uind2 *p;
310   int k;
311   int len;
312 
313   jtl = (struct JT *) (files[dic_table[dic_no].body].area);
314   tary = jtl->table;
315   if (dic_table[dic_no].hindo >= 0)
316     hjtl = (struct HJT *) (files[dic_table[dic_no].hindo].area);
317   else
318     hjtl = NULL;
319 
320   if (serial >= jtl->maxserial)
321     {
322       wnn_errorno = WNN_WORD_NO_EXIST;
323       return (-1);
324     }
325   if (jtl->hinsi[serial] == SAKUJO_HINSI)
326     return (-1);
327 
328   for (k = 0; k < jtl->maxtable; k++)
329     {
330       for (p = ((struct uind2 *) ((tary[k].pter) + jtl->hontai));; p = ((struct uind2 *) ((p->next) + jtl->hontai)))
331         {
332           if ((int) p->serial <= (int) serial && (int) (p->serial + p->kosuu) > (int) serial)
333             goto found_it;
334           if (p->next == ENDPTR)
335             break;
336         }
337     }
338   wnn_errorno = WNN_WORD_NO_EXIST;
339   return (-1);
340 
341 found_it:
342   yomi[0] = tary[k].yomi1 >> 16;
343   yomi[1] = tary[k].yomi1 & 0xffff;
344   if (yomi[1])
345     {
346       yomi[2] = tary[k].yomi2 >> 16;
347       if (yomi[2])
348         {
349           yomi[3] = tary[k].yomi2 & 0xffff;
350         }
351     }
352   len = p->yomi[0];
353   Strncpy (yomi + 4, (p->yomi) + 1, len - 4);
354   yomi[len] = 0;
355 
356   jd->kanji1 = p->kanjipter;
357   jd->kanji2 = serial - p->serial;
358   jd->serial = serial;
359   jd->kosuu = 1;
360   jd->jishono = dic_no;
361   jd->jptr = NULL;
362   jd->hinsi = jtl->hinsi + serial;
363   if (hjtl)
364     {
365       jd->hindo = hjtl->hindo + serial;
366       jd->hindo_in = jtl->hindo + serial;
367     }
368   else
369     {
370       jd->hindo = jtl->hindo + serial;
371       jd->hindo_in = NULL;
372     }
373 
374   return (0);
375 }
376