1 /*
2  *  $Id: revdic.c,v 1.5 2004/05/21 16:39:32 aono 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, 2002
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 "jslib.h"
35 #include "jh.h"
36 #include "jdata.h"
37 
38 #ifndef min
39 #define min(a, b) ((a > b)? b:a)
40 #define max(a, b) ((a < b)? b:a)
41 #endif
42 
43 /*
44  * rev_ud_hontai(hostart, maxhontai)
45  * rev_ud_table(tary, maxtable)
46  * rev_sd_hontai(hostart)
47  * rev_hinsi(hinsi, maxserial)
48  */
49 
50 static int tmptmp;
51 
52 #define rev_int(x) (tmptmp = *(x), *(x) = ((tmptmp >> 24) & 0xff) |    \
53 		    (((tmptmp >> 16) & 0xff) << 8) |		       \
54 		    (((tmptmp >> 8) & 0xff) << 16) |		       \
55 		    (((tmptmp & 0xff) << 24)))
56 
57 #define rev_short(x) (tmptmp = *(x), *(x) = ((tmptmp >> 8) & 0xff) | \
58 		      ((tmptmp & 0xff) << 8))
59 
60 #define rev_int_org(x) (tmptmp = *(x), *(x) = ((tmptmp >> 24) & 0xff) | \
61 			(((tmptmp >> 16) & 0xff) << 8) |		\
62 			(((tmptmp >> 8) & 0xff) << 16) |		\
63 			((tmptmp & 0xff) << 24), tmptmp)
64 
65 #define rev_short_org(x) (tmptmp = *(x), *(x) = ((tmptmp >> 8) & 0xff) | \
66 			  ((tmptmp & 0xff) << 8), tmptmp)
67 
68 void
rev_ud_hontai(UCHAR * hostart,int maxhontai,int match)69 rev_ud_hontai(UCHAR *hostart,
70 	      int maxhontai,
71 	      int match		/* whether the cpu type match the dictionary */
72 	)
73 {
74 	UCHAR *hoend = hostart + maxhontai;
75 	struct uind2 *hop, *hop1;
76 	int k;
77 	int len;
78 
79 	/* Skip first 4 bytes for some reason. (cf. ujistoud() in atod.c) */
80 	for (hop = (struct uind2 *)((int *) hostart + 1); (UCHAR *) hop < hoend;) {
81 		rev_int(&(hop->next));
82 		rev_int(&(hop->serial));
83 		rev_int(&(hop->kanjipter));
84 		rev_short(&(hop->kosuu));
85 
86 		if (match) {
87 			len = hop->yomi[0];
88 			hop1 = (struct uind2 *)(AL_INT (&(hop->yomi[0]) + 1 + max((len - 4), 0)));
89 			rev_short(&(hop->yomi[0]));
90 			for (k = 0; k < len - 4; k++)
91 				rev_short(&(hop->yomi[k + 1]));
92 			hop = hop1;
93 		} else {
94 			rev_short(&(hop->yomi[0]));
95 			len = hop->yomi[0];
96 			for (k = 0; k < len - 4; k++)
97 				rev_short(&(hop->yomi[k + 1]));
98 			hop = (struct uind2 *)(AL_INT (&(hop->yomi[0]) + 1 + max((len - 4), 0)));
99 		}
100 	}
101 }
102 
103 void
rev_ud_table(struct uind1 * tary,int maxtable,int match)104 rev_ud_table(struct uind1 *tary,
105 	     int maxtable,
106 	     int match)
107 {
108 	int k;
109 
110 	for (k = 0; k < maxtable; k++) {
111 		rev_int(&(tary[k].pter1));
112 		rev_int(&(tary[k].pter));
113 		rev_int(&(tary[k].yomi1));
114 		rev_int(&(tary[k].yomi2));
115 	}
116 }
117 
118 void
rev_hinsi(unsigned short * hinsi,int maxserial,int match)119 rev_hinsi(unsigned short *hinsi,
120 	  int maxserial,
121 	  int match)
122 {
123 	int k;
124 
125 	for (k = 0; k < maxserial; k++)
126 		rev_short(&(hinsi[k]));
127 }
128 
129 /*
130  * first element of each node is syurui,
131  * which is unsigned short less than 0xff.
132  */
133 
134 #define match_machine(x) (*(unsigned short *)(x) & 0xff)
135 
136 void travel_next_nodes ();
137 void rev_sd_node ();
138 
139 void
rev_sd_hontai0(UCHAR * hopter,UCHAR * hostart,int match)140 rev_sd_hontai0(UCHAR *hopter,
141 	       UCHAR *hostart,
142 	       int match)
143 {
144 	if (match) {
145 		travel_next_nodes(hopter, hostart, match);
146 		rev_sd_node(hopter, hostart, match);
147 	} else {
148 		rev_sd_node(hopter, hostart, match);
149 		travel_next_nodes(hopter, hostart, match);
150 	}
151 }
152 
153 void
rev_sd_hontai(UCHAR * hostart,int match)154 rev_sd_hontai(UCHAR *hostart,
155 	      int match)
156 {
157 	rev_sd_hontai0(hostart, hostart, match);
158 }
159 
160 void
travel_next_nodes(UCHAR * hopter,UCHAR * hostart,int match)161 travel_next_nodes(UCHAR *hopter,
162 		  UCHAR *hostart,
163 		  int match)
164 {
165 	int k;
166 	int tsize;
167 	w_char *charst;
168 	w_char *sumst;
169 	int *ptrst;
170 
171 	switch (*(unsigned short *)hopter) {
172 	case ST_NORMAL:
173 		tsize = *(w_char *)(hopter + 2);
174 		charst = (w_char *)(hopter + 12);
175 		sumst = ((w_char *)charst + tsize + 2);  /* + 2 keeps two zero words */
176 		ptrst = (int *)((w_char *)sumst + tsize);
177 
178 		for (k = 0; k < tsize; k++) {
179 			if (ptrst[k] != ENDPTR)
180 				rev_sd_hontai0(hostart + ptrst[k], hostart, match);
181 		}
182 		break;
183 
184 	case ST_NOPTER:
185 		break;
186 	case ST_NOENT:
187 		tsize = *(w_char *)(hopter + 2);
188 		charst = (w_char *)(hopter + 4);
189 		ptrst = (int *)AL_INT((w_char *)charst + tsize);
190 
191 		for (k = 0; k < tsize; k++)
192 			rev_sd_hontai0(hostart + ptrst[k], hostart, match);
193 		break;
194 	case ST_SMALL:
195 		rev_sd_hontai0(hopter + 4, hostart, match);
196 		break;
197 	}
198 }
199 
200 #define rev_if_short(x) (match? rev_short_org(x): rev_short(x))
201 #define rev_if_int(x) (match? rev_int_org(x): rev_int(x))
202 
203 void
rev_sd_node(UCHAR * hopter,UCHAR * hostart,int match)204 rev_sd_node(UCHAR *hopter,
205 	    UCHAR *hostart,
206 	    int match)
207 {
208 	/* whether current state of dict matches the cpu type of the machine */
209 	int k;
210 	int tsize;
211 	w_char *charst;
212 	w_char *sumst;
213 	int *ptrst;
214 	int state;
215 
216 	state = rev_if_short((unsigned short *) hopter);
217 
218 	switch (state) {
219 	case ST_NORMAL:
220 	case ST_NOPTER:
221 		tsize = rev_if_short((w_char *)(hopter + 2));
222 		rev_int((int *)(hopter + 4));
223 		rev_int((int *)(hopter + 8));
224 		charst = (w_char *)(hopter + 12);
225 		sumst = ((w_char *)charst + tsize + 2);  /* + 2 keeps two zero words */
226 		ptrst = (int *)((w_char *)sumst + tsize);
227 
228 		for (k = 0; k < tsize; k++) {
229 			rev_short(charst + k);
230 			rev_short(sumst + k);
231 		}
232 
233 		if (state == ST_NORMAL) {
234 			for (k = 0; k < tsize; k++)
235 				rev_int (ptrst + k);
236 		}
237 		break;
238 
239 	case ST_NOENT:
240 		tsize = rev_if_short((w_char *)(hopter + 2));
241 		charst = (w_char *)(hopter + 4);
242 		ptrst = (int *)AL_INT((w_char *)charst + tsize);
243 
244 		for (k = 0; k < tsize; k++) {
245 			rev_short(charst + k);
246 			rev_int(ptrst + k);
247 		}
248 		break;
249 
250 	case ST_SMALL:
251 		rev_short((unsigned short *)(hopter + 2));
252 		break;
253 	}
254 }
255 
256 int
little_endian()257 little_endian()
258 {
259 	int a = 1;
260 #ifdef BYTE_SWAP
261 	return (1);
262 #else
263 	return (*(char *) &a == 1);
264 #endif
265 }
266 
267 void
rev_rd_rind1(struct rind1 * ri1,int maxri1,int match)268 rev_rd_rind1(struct rind1 *ri1,
269 	     int maxri1,
270 	     int match)
271 {
272 	int k;
273 
274 	for (k = 0; k < maxri1; k++) {
275 		rev_int(&(ri1[k].pter1));
276 		rev_int(&(ri1[k].pter));
277 	}
278 }
279 
280 void
rev_rd_rind2(struct rind2 * ri2,int maxri2,int match)281 rev_rd_rind2(struct rind2 *ri2,
282 	     int maxri2,
283 	     int match)
284 {
285 	int k;
286 
287 	for (k = 0; k < maxri2; k++) {
288 		rev_int(&(ri2[k].kanjipter));
289 		rev_int(&(ri2[k].next[D_YOMI]));
290 		rev_int(&(ri2[k].next[D_KANJI]));
291 	}
292 }
293 
294 void rev_w_char ();
295 
296 void
rev_kanji(UCHAR * kpter,int maxk,int match)297 rev_kanji(UCHAR *kpter,
298 	  int maxk,
299 	  int match)
300 {
301 	UCHAR *kend = kpter + maxk;
302 
303 	while (kpter < kend && *kpter) {
304 		rev_w_char((w_char *)(kpter + 2), *kpter / 2 - 1);
305 		kpter += *kpter;
306 	}
307 }
308 
309 void
rev_w_char(w_char * p,int maxp)310 rev_w_char(w_char *p,
311 	   int maxp)
312 {
313 	for (; maxp > 0; maxp--) {
314 		rev_short(p);
315 		p++;
316 	}
317 }
318 
319 /*
320  *  Change the byte-order of dictionary except for the header area.
321  *  Header and hindo area don't depend on byte-order.
322  *  If match is nonzero, the dict-type matches CPU type before conversion.
323  */
324 
325 int
revdic(struct JT * jtl,int match)326 revdic(struct JT *jtl,
327        int match)
328 {
329 	extern int rev_ud(), rev_rd(), rev_sd();
330 	int syurui = jtl->syurui;
331 
332 	syurui = jtl->syurui & 0xff;
333 
334 	if (syurui == WNN_UD_DICT) {
335 		if (rev_ud (jtl, match) == -1)
336 			return (-1);
337 	} else if (syurui == WNN_REV_DICT) {
338 		if (rev_rd (jtl, match) == -1)
339 			return (-1);
340 	} else {
341 		if (rev_sd (jtl, match) == -1)
342 			return (-1);
343 	}
344 
345 	return (0);
346 }
347 
348 void rev_common ();
349 
350 int
rev_ud(struct JT * jtl,int match)351 rev_ud(struct JT *jtl,
352        int match)
353 {
354 	rev_common(jtl, match);
355 	rev_ud_hontai(jtl->hontai, jtl->maxhontai, match);
356 	rev_ud_table(jtl->table, jtl->maxtable, match);
357 
358 	return (0);
359 }
360 
361 int
rev_sd(struct JT * jtl,int match)362 rev_sd(struct JT *jtl,
363        int match)
364 {
365 	rev_common(jtl, match);
366 	rev_sd_hontai(jtl->hontai, match);
367 	return (0);
368 }
369 
370 int
rev_rd(struct JT * jtl,int match)371 rev_rd(struct JT *jtl,
372        int match)
373 {
374 	rev_common(jtl, match);
375 	rev_rd_rind1(jtl->ri1[D_YOMI], jtl->maxri1[D_YOMI], match);
376 	rev_rd_rind1(jtl->ri1[D_KANJI], jtl->maxri1[D_KANJI], match);
377 	rev_rd_rind2(jtl->ri2, jtl->maxri2, match);
378 	return (0);
379 }
380 
381 void
rev_common(struct JT * jtl,int match)382 rev_common(struct JT *jtl,
383 	   int match)
384 {
385 	if (jtl->hinsi)
386 		rev_hinsi(jtl->hinsi, jtl->maxserial, match);
387 	if (jtl->kanji)
388 		rev_kanji(jtl->kanji, jtl->maxkanji, match);
389 	if (jtl->comment)
390 		rev_w_char(jtl->comment, jtl->maxcomment);
391 	if (jtl->hinsi_list)
392 		rev_w_char(jtl->hinsi_list, jtl->maxhinsi_list);
393 }
394 
395 /* rev_short is called from atod.c.... kanapiiii */
396 void
rev_short_fun(w_char * sp)397 rev_short_fun(w_char *sp)
398 {
399 	rev_short (sp);
400 }
401