Mercurial > kinput2.yaz
comparison lib/Xsj3clib/table.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children | 7353de876e93 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 #ifndef lint | |
2 static char *rcsid = "$Id: table.c,v 2.3 1993/09/21 09:42:45 nao Exp $"; | |
3 #endif | |
4 /* | |
5 * Copyright 1991 Sony Corporation | |
6 * | |
7 * Permission to use, copy, modify, distribute, and sell this software and its | |
8 * documentation for any purpose is hereby granted without fee, provided that | |
9 * the above copyright notice appear in all copies and that both that | |
10 * copyright notice and this permission notice appear in supporting | |
11 * documentation, and that the name of Sony not be used in advertising or | |
12 * publicity pertaining to distribution of the software without specific, | |
13 * written prior permission. Sony makes no representations about the | |
14 * suitability of this software for any purpose. It is provided "as is" | |
15 * without express or implied warranty. | |
16 * | |
17 * SONY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL | |
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SONY | |
19 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
23 */ | |
24 /* | |
25 * Author: Naoshi Suzuki, SONY Corporation. (nao@sm.sony.co.jp) | |
26 */ | |
27 | |
28 #include <stdio.h> | |
29 #include <ctype.h> | |
30 #include "common.h" | |
31 #include "sj3ctype.h" | |
32 #include "util.h" | |
33 | |
34 extern Xsj3cCVServerIF serverIF[SERVER_NUM]; | |
35 extern Xsj3cSymbol _Xsj3cSymbolInit(); | |
36 extern Xsj3cHinsi _Xsj3cHinsiInit(); | |
37 | |
38 Xsj3cRKTable *_Xsj3cRKInit(); | |
39 Xsj3cHKTable *_Xsj3cHKInit(); | |
40 Xsj3cZHTable *_Xsj3cZHInit(); | |
41 unsigned char *_Xsj3cSetPlosive(); | |
42 unsigned char *_Xsj3cSetDouble(); | |
43 void Xsj3cInitializeTables(); | |
44 | |
45 int _Xsj3cmINtowOUT(); | |
46 int _Xsj3cReadAscii(); | |
47 wchar *_Xsj3cStoreWchar(); | |
48 | |
49 static Xsj3cRKTable *_Xsj3cAllocRKTable(); | |
50 static Xsj3cHKTable *_Xsj3cAllocHKTable(); | |
51 static Xsj3cZHTable *_Xsj3cAllocZHTable(); | |
52 | |
53 static unsigned char *_Xsj3cStoreChar(); | |
54 | |
55 static int _Xsj3cmINtomPS(); | |
56 | |
57 static int _Xsj3cReadRK(); | |
58 static int _Xsj3cReadHK(); | |
59 static int _Xsj3cReadZH(); | |
60 | |
61 static unsigned char *chnowp = NULL, *chmaxp = NULL; | |
62 static wchar *wnowp = NULL, *wmaxp = NULL; | |
63 | |
64 static Xsj3cRKTable *rktable[2] = {NULL, NULL}; | |
65 static Xsj3cHKTable *hktable[2] = {NULL, NULL}; | |
66 static Xsj3cZHTable *zhtable[2] = {NULL, NULL}; | |
67 static unsigned char *plosive[2] = {NULL, NULL}; | |
68 static unsigned char *rkdouble[2] = {NULL, NULL}; | |
69 | |
70 static Xsj3cRKTable *rknowtp = NULL, *rkmaxtp = NULL; | |
71 static Xsj3cHKTable *hknowtp = NULL, *hkmaxtp = NULL; | |
72 static Xsj3cZHTable *zhnowtp = NULL, *zhmaxtp = NULL; | |
73 | |
74 static unsigned char * | |
75 _Xsj3cStoreChar(ch, len) | |
76 unsigned char *ch; | |
77 int len; | |
78 { | |
79 register unsigned char *chp; | |
80 | |
81 if (chnowp == NULL || chnowp + len > chmaxp) { | |
82 chp = (unsigned char *)malloc(BUFSIZ); | |
83 if (chp == NULL) | |
84 return (NULL); | |
85 chnowp = chp; | |
86 chmaxp = chnowp + (BUFSIZ/sizeof(unsigned char)); | |
87 strcpy (chp, ch); | |
88 chnowp += len; | |
89 return (chp); | |
90 } else { | |
91 chp = chnowp; | |
92 strcpy (chp, ch); | |
93 chnowp += len; | |
94 return (chp); | |
95 } | |
96 } | |
97 | |
98 wchar * | |
99 _Xsj3cStoreWchar(wch, len) | |
100 wchar *wch; | |
101 int len; | |
102 { | |
103 register wchar *wp; | |
104 | |
105 if (wnowp == NULL || wnowp + len > wmaxp) { | |
106 wp = (wchar *)malloc(BUFSIZ); | |
107 if (wp == NULL) | |
108 return (NULL); | |
109 wnowp = wp; | |
110 wmaxp = wnowp + (BUFSIZ/sizeof(wchar)); | |
111 (void)_Xsj3cWcpy (wp, wch); | |
112 wnowp += len; | |
113 return (wp); | |
114 } else { | |
115 wp = wnowp; | |
116 (void)_Xsj3cWcpy (wp, wch); | |
117 wnowp += len; | |
118 return (wp); | |
119 } | |
120 } | |
121 | |
122 static int | |
123 _Xsj3cmINtomPS(buf, file, src, dest) | |
124 Xsj3cBuf buf; | |
125 char *file; | |
126 register unsigned char *src, *dest; | |
127 { | |
128 register unsigned char c; | |
129 register wchar s, (*conv)(); | |
130 register int i = 0, kanji = OFF, kana = OFF; | |
131 | |
132 conv = CodeConvFunc[in_lang][serverIF[buf->server].lang]; | |
133 while ((*src != '\t' && *src != '\n' | |
134 && *src != ' ' && *src != '#')||(kanji || kana)) { | |
135 c = *src++; | |
136 switch (c) { | |
137 case ESC: | |
138 c = *src++; | |
139 if (c == '$') { | |
140 c = *src++; | |
141 i++; | |
142 if (c == 'B' || c == '@') { | |
143 kanji++; | |
144 i++; | |
145 } else | |
146 goto badcode; | |
147 } else if (c == '(') { | |
148 c = *src++; | |
149 i++; | |
150 if (c == 'J' || c == 'B' || c == 'H') { | |
151 kanji = OFF; | |
152 i++; | |
153 } else if (c == '$' && *src == 'B') { | |
154 src++; | |
155 kanji++; | |
156 i++; | |
157 } else | |
158 goto badcode; | |
159 } else if (c == '&' && !strcmp("@\033$B", src)) { | |
160 src += 4; | |
161 i += 5; | |
162 kanji++; | |
163 } else | |
164 goto badcode; | |
165 break; | |
166 case SI: | |
167 kana = OFF; | |
168 break; | |
169 case SO: | |
170 kana++; | |
171 break; | |
172 case '\\': | |
173 if (!kanji & !kana) { | |
174 *dest++ = *src++; | |
175 i++; | |
176 break; | |
177 } | |
178 default: | |
179 if (kanji) { | |
180 s = (c << 8) + (*src++ & 0x7f); | |
181 s = conv(s); | |
182 *dest++ = (s >> 8) & 0xff; | |
183 *dest++ = s & 0xff; | |
184 i++; | |
185 } else if (iskan1(c, in_lang) && iskan2(*src, in_lang)) { | |
186 if (conv) { | |
187 s = (c << 8) + (*src++ & 0xff); | |
188 s = conv(s); | |
189 *dest++ = (s >> 8) & 0xff; | |
190 *dest++ = s & 0xff; | |
191 } else { | |
192 *dest++ = c; | |
193 *dest++ = *src++; | |
194 } | |
195 i++; | |
196 } else if (iskana(c)) { | |
197 if (in_lang == JP_SJIS || in_lang == JP_JIS8) | |
198 *dest++ = c; | |
199 else if (in_lang == JP_EUC && iseuckana(c) && iskana2(*src)) { | |
200 *dest++ = *src++; | |
201 i++; | |
202 } else | |
203 goto badcode; | |
204 } else if (iseuckana(c) && iskana2(*src)) { | |
205 if (in_lang == JP_EUC) | |
206 *dest++ = *src++; | |
207 else | |
208 goto badcode; | |
209 i++; | |
210 } else if (kana) { | |
211 *dest++ = (c | MSB); | |
212 } else if (isascii(c)) { | |
213 *dest++ = c; | |
214 } else { | |
215 badcode: | |
216 Xsj3cError("There is bad code %s in %s",_Xsj3cXtoa(c),file); | |
217 } | |
218 break; | |
219 } | |
220 i++; | |
221 } | |
222 *dest = '\0'; | |
223 return (i); | |
224 } | |
225 | |
226 int | |
227 _Xsj3cReadAscii(file, src, dest) | |
228 char *file; | |
229 register unsigned char *src, *dest; | |
230 { | |
231 register int i = 0, kana = OFF; | |
232 | |
233 while ((*src != '\t' && *src != ' ' | |
234 && *src != '\0' && *src != '\n' && *src != '#')|| kana) { | |
235 if (kana) { | |
236 *dest++ = (*src++ | MSB); | |
237 } if (*src == '\\') { | |
238 src++; | |
239 i++; | |
240 *dest++ = *src++; | |
241 } else if (isascii(*src)) { | |
242 *dest++ = *src++; | |
243 } else if (isdakuten(*src)) { | |
244 *dest++ = *src++; | |
245 } else if (iseuckana(*src) && isdakuten(*(src + 1))) { | |
246 src++; | |
247 i++; | |
248 *dest++ = *src++; | |
249 } else if (*src == SO) { | |
250 src++; | |
251 kana++; | |
252 } else if (*src == SI) { | |
253 src++; | |
254 kana = OFF; | |
255 } else { | |
256 int n = *src; | |
257 Xsj3cError("There is bad code %s in %s",_Xsj3cXtoa(n),file); | |
258 } | |
259 i++; | |
260 } | |
261 *dest = '\0'; | |
262 return (i); | |
263 } | |
264 | |
265 int | |
266 _Xsj3cmINtowOUT(file, src, dest, len) | |
267 char *file; | |
268 register unsigned char *src; | |
269 register wchar *dest; | |
270 register int *len; | |
271 { | |
272 register unsigned char c; | |
273 register int i = 0, kanji = OFF, kana = OFF; | |
274 register wchar (*conv)(); | |
275 | |
276 *len = 0; | |
277 conv = CodeConvFunc[in_lang][out_lang]; | |
278 while ((*src != '\t' && *src != ' ' && *src != '\0' | |
279 && *src != '\n' && *src != '#')||(kanji || kana)) { | |
280 c = *src++; | |
281 switch (c) { | |
282 case ESC: | |
283 c = *src++; | |
284 if (c == '$') { | |
285 c = *src++; | |
286 i++; | |
287 if (c == 'B' || c == '@') { | |
288 kanji++; | |
289 i++; | |
290 } else | |
291 goto badcode; | |
292 } else if (c == '(') { | |
293 c = *src++; | |
294 i++; | |
295 if (c == 'J' || c == 'B' || c == 'H') { | |
296 kanji = OFF; | |
297 i++; | |
298 } else if (c == '$' && *src == 'B') { | |
299 src++; | |
300 kanji++; | |
301 i++; | |
302 } else | |
303 goto badcode; | |
304 } else if (c == '&' && !strcmp("@\033$B", src)) { | |
305 src += 4; | |
306 i += 5; | |
307 kanji++; | |
308 } else | |
309 goto badcode; | |
310 break; | |
311 case SI: | |
312 kana = OFF; | |
313 break; | |
314 case SO: | |
315 kana++; | |
316 break; | |
317 case '\\': | |
318 if (!kanji && !kana) { | |
319 *dest++ = *src++; | |
320 i++; | |
321 break; | |
322 } | |
323 default: | |
324 if (kanji || (iskan1(c, in_lang) && iskan2(*src, in_lang))) { | |
325 if (conv) | |
326 *dest++ = conv((c << 8) + (*src++ & 0xff)); | |
327 else | |
328 *dest++ = (c << 8) + (*src++ & 0xff); | |
329 i++; | |
330 } else if (iskana(c)) { | |
331 if (in_lang == JP_SJIS || in_lang == JP_JIS8) | |
332 *dest++ = c; | |
333 else if (in_lang == JP_EUC && iseuckana(c) && iskana2(*src)) { | |
334 *dest++ = *src++; | |
335 i++; | |
336 } else | |
337 goto badcode; | |
338 } else if (iseuckana(c) && iskana2(*src)) { | |
339 if (in_lang == JP_EUC) | |
340 *dest++ = *src++; | |
341 else | |
342 goto badcode; | |
343 i++; | |
344 } else if (kana) { | |
345 *dest++ = (c | MSB); | |
346 } else if (isascii(c)) { | |
347 *dest++ = c; | |
348 } else { | |
349 badcode: | |
350 Xsj3cError("There is bad code %s in %s",_Xsj3cXtoa(c),file); | |
351 } | |
352 (*len)++; | |
353 break; | |
354 } | |
355 i++; | |
356 } | |
357 *dest = '\0'; | |
358 return (i); | |
359 } | |
360 | |
361 /* | |
362 * Xsj3cInitializeTables() | |
363 * Read definition files and initialize conversion tables. | |
364 */ | |
365 void | |
366 Xsj3cInitializeTables(buf, home, sjrk, sjhk, sjzh, sjsb) | |
367 Xsj3cBuf buf; | |
368 char *home; | |
369 char *sjrk, *sjhk, *sjzh, *sjsb; | |
370 { | |
371 buf->rktable = _Xsj3cRKInit(buf, sjrk, home); | |
372 buf->hktable = _Xsj3cHKInit(buf, sjhk, home); | |
373 buf->zhtable = _Xsj3cZHInit(buf, sjzh, home); | |
374 buf->symbol = _Xsj3cSymbolInit(sjsb, home); | |
375 buf->plosive = _Xsj3cSetPlosive(buf); | |
376 buf->rkdouble = _Xsj3cSetDouble(buf); | |
377 buf->hinsi = _Xsj3cHinsiInit(buf); | |
378 } | |
379 | |
380 /* | |
381 * _Xsj3cRKInit() | |
382 * Decide sjrk file to read, then read it and make table for roman-kana | |
383 * conversion table. | |
384 */ | |
385 Xsj3cRKTable * | |
386 _Xsj3cRKInit(buf, sjrk, home) | |
387 Xsj3cBuf buf; | |
388 char *sjrk; | |
389 char *home; | |
390 { | |
391 extern char *getenv(); | |
392 register char *p; | |
393 char rkfile[BUFSIZ]; | |
394 int value, error; | |
395 | |
396 if (rktable[serverIF[buf->server].lang]) | |
397 return (rktable[serverIF[buf->server].lang]); | |
398 | |
399 if (sjrk) { | |
400 if ((value = _Xsj3cReadRK(buf, sjrk, &error)) > 0 ) | |
401 Xsj3cError("can't open sjrk file %s", sjrk); | |
402 else if (value < 0) | |
403 Xsj3cError("read failed line %s sjrk file %s", | |
404 _Xsj3cItoa(error), sjrk); | |
405 } else { | |
406 rkfile[0] = '\0'; | |
407 if ((p = getenv("SJRK")) && *p != '\0') { | |
408 if (*p != '/') { | |
409 if (home) | |
410 strcpy(rkfile, home); | |
411 strcat(rkfile, "/"); | |
412 } | |
413 strcat(rkfile, p); | |
414 } else if (home) { | |
415 strcpy(rkfile, home); | |
416 strcat(rkfile, "/.sjrk"); | |
417 } else { | |
418 strcpy(rkfile, SJ3DEFPATH); | |
419 strcat(rkfile, DEF_SJRK_FILE); | |
420 } | |
421 if ((value = _Xsj3cReadRK(buf, rkfile, &error)) > 0 ) { | |
422 strcpy(rkfile, SJ3DEFPATH); | |
423 strcat(rkfile, DEF_SJRK_FILE); | |
424 if ((value = _Xsj3cReadRK(buf, rkfile, &error)) > 0 ) { | |
425 Xsj3cError("can't open sjrk file %s", rkfile); | |
426 } else if (value < 0) { | |
427 Xsj3cError("read failed line %s sjrk file %s", | |
428 _Xsj3cItoa(error), rkfile); | |
429 } | |
430 } else if (value < 0) { | |
431 Xsj3cError("read failed line %s sjrk file %s", | |
432 _Xsj3cItoa(error), rkfile); | |
433 } | |
434 } | |
435 return (rktable[serverIF[buf->server].lang]); | |
436 } | |
437 | |
438 #define RKTBMAX (BUFSIZ/sizeof(Xsj3cRKTable)) | |
439 | |
440 static Xsj3cRKTable * | |
441 _Xsj3cAllocRKTable() | |
442 { | |
443 register Xsj3cRKTable *rktp; | |
444 | |
445 if (rknowtp == NULL || rknowtp > rkmaxtp) { | |
446 rktp = (Xsj3cRKTable *)malloc(sizeof(Xsj3cRKTable) * RKTBMAX); | |
447 if (rktp == NULL) | |
448 return (NULL); | |
449 rknowtp = rktp; | |
450 rkmaxtp = rknowtp + RKTBMAX - 1; | |
451 rknowtp++; | |
452 } else { | |
453 rktp = rknowtp; | |
454 rknowtp++; | |
455 } | |
456 rktp->roma = NULL; | |
457 rktp->yomi = NULL; | |
458 rktp->str = NULL; | |
459 rktp->rlen = 0; | |
460 rktp->ylen = 0; | |
461 rktp->next = NULL; | |
462 return (rktp); | |
463 } | |
464 | |
465 /* | |
466 * _Xsj3cReadRK() | |
467 * Read sjrk file like a format sj3's roman-kana conversion file, | |
468 * and make conversion table. | |
469 * But this routine distinguishes upper-case and lower-case. | |
470 * It's a big difference. | |
471 */ | |
472 static int | |
473 _Xsj3cReadRK(buf, file, error) | |
474 Xsj3cBuf buf; | |
475 register char *file; | |
476 register int *error; | |
477 { | |
478 register FILE *fp; | |
479 unsigned char line[256]; | |
480 unsigned char *p; | |
481 unsigned char roma[RBUFSIZ], yomi[YBUFSIZ], str[RBUFSIZ]; | |
482 register int begin = 0, rlen, ylen; | |
483 register Xsj3cRKTable *rktp, *rktq, *rktr; | |
484 | |
485 if ((fp = fopen(file, "r")) == NULL) | |
486 return (OPEN_FAILED); | |
487 | |
488 *error = 1; | |
489 rktp = rktable[serverIF[buf->server].lang] = _Xsj3cAllocRKTable(); | |
490 while (fgets(line, sizeof(line), fp) != NULL) { | |
491 p = line; | |
492 while (*p != '\n' && *p != '#') { | |
493 p += _Xsj3cReadAscii(file, p, roma); | |
494 CHECK_END(p); | |
495 SKIP(p); | |
496 p += _Xsj3cmINtomPS(buf, file, p, yomi); | |
497 SKIP(p); | |
498 p += _Xsj3cReadAscii(file, p, str); | |
499 if (roma[0] == '\0' || yomi[0] == '\0') | |
500 break; | |
501 if (begin++) { | |
502 rktr = _Xsj3cAllocRKTable(); | |
503 if (!rktr) { | |
504 Xsj3cWarning("can't allocate roman-kana conversion table"); | |
505 return (ALLOC_FAILED); | |
506 } | |
507 rktp = rktq->next = rktr; | |
508 } | |
509 rktp->roma = _Xsj3cStoreChar(roma, (rlen = strlen(roma)) + 1); | |
510 rktp->yomi = _Xsj3cStoreChar(yomi, (ylen = strlen(yomi)) + 1); | |
511 rktp->str = _Xsj3cStoreChar(str, strlen(str) + 1); | |
512 if (!rktp->roma || !rktp->yomi || !rktp->str) { | |
513 Xsj3cWarning("can't allocate roman-kana conversion table"); | |
514 return(ALLOC_FAILED); | |
515 } | |
516 rktp->rlen = rlen; | |
517 rktp->ylen = ylen; | |
518 rktq = rktp; | |
519 } | |
520 (*error)++; | |
521 } | |
522 rktp->next = NULL; | |
523 fclose(fp); | |
524 return (OK); | |
525 } | |
526 | |
527 /* | |
528 * _Xsj3cHKInit() | |
529 * Decide sjhk file to read, then read it and make hiragana-katakana | |
530 * conversion table. | |
531 */ | |
532 Xsj3cHKTable * | |
533 _Xsj3cHKInit(buf, sjhk, home) | |
534 Xsj3cBuf buf; | |
535 char *sjhk; | |
536 char *home; | |
537 { | |
538 extern char *getenv(); | |
539 register char *p; | |
540 char hkfile[BUFSIZ]; | |
541 int value, error; | |
542 | |
543 if (hktable[serverIF[buf->server].lang]) | |
544 return (hktable[serverIF[buf->server].lang]); | |
545 | |
546 if (sjhk) { | |
547 if ((value = _Xsj3cReadHK(buf, sjhk, &error)) > 0 ) | |
548 Xsj3cError("can't open sjhk file %s", sjhk); | |
549 else if (value < 0) | |
550 Xsj3cError("read failed line %s sjhk file %s", | |
551 _Xsj3cItoa(error), sjhk); | |
552 } else { | |
553 hkfile[0] = '\0'; | |
554 if ((p = getenv("SJHK")) && *p != '\0') { | |
555 if (*p != '/') { | |
556 if (home) | |
557 strcpy(hkfile, home); | |
558 strcat(hkfile, "/"); | |
559 } | |
560 strcat(hkfile, p); | |
561 } else if (home) { | |
562 strcpy(hkfile, home); | |
563 strcat(hkfile, "/.sjhk"); | |
564 } else { | |
565 strcpy(hkfile, SJ3DEFPATH); | |
566 strcat(hkfile, DEF_SJHK_FILE); | |
567 } | |
568 if ((value = _Xsj3cReadHK(buf, hkfile, &error)) > 0 ) { | |
569 strcpy(hkfile, SJ3DEFPATH); | |
570 strcat(hkfile, DEF_SJHK_FILE); | |
571 if ((value = _Xsj3cReadHK(buf, hkfile, &error)) > 0 ) { | |
572 Xsj3cError("can't open sjhk file %s", hkfile); | |
573 } else if (value < 0) { | |
574 Xsj3cError("read failed line %s sjhk file %s", | |
575 _Xsj3cItoa(error), hkfile); | |
576 } | |
577 } else if (value < 0) { | |
578 Xsj3cError("read failed line %s sjhk file %s", | |
579 _Xsj3cItoa(error), hkfile); | |
580 } | |
581 } | |
582 return (hktable[serverIF[buf->server].lang]); | |
583 } | |
584 | |
585 #define HKTBMAX (BUFSIZ/sizeof(Xsj3cHKTable)) | |
586 | |
587 static Xsj3cHKTable * | |
588 _Xsj3cAllocHKTable() | |
589 { | |
590 register Xsj3cHKTable *hktp; | |
591 | |
592 if (hknowtp == NULL || hknowtp > hkmaxtp) { | |
593 hktp = (Xsj3cHKTable *)malloc(sizeof(Xsj3cHKTable) * HKTBMAX); | |
594 if (hktp == NULL) | |
595 return (NULL); | |
596 hknowtp = hktp; | |
597 hkmaxtp = hknowtp + HKTBMAX - 1; | |
598 hknowtp++; | |
599 } else { | |
600 hktp = hknowtp; | |
601 hknowtp++; | |
602 } | |
603 hktp->hira = NULL; | |
604 hktp->zkata = NULL; | |
605 hktp->hkata = NULL; | |
606 hktp->halpha = NULL; | |
607 hktp->hlen = 0; | |
608 hktp->next = NULL; | |
609 return (hktp); | |
610 } | |
611 | |
612 static int | |
613 _Xsj3cReadHK(buf, file, error) | |
614 Xsj3cBuf buf; | |
615 register char *file; | |
616 register int *error; | |
617 { | |
618 register FILE *fp; | |
619 unsigned char line[256]; | |
620 unsigned char *p; | |
621 unsigned char zhira[RBUFSIZ], zkata[YBUFSIZ]; | |
622 unsigned char hkata[RBUFSIZ], halpha[RBUFSIZ]; | |
623 register int begin = 0, hkata_len, halpha_len; | |
624 register Xsj3cHKTable *hktp, *hktq, *hktr; | |
625 | |
626 if ((fp = fopen(file, "r")) == NULL) | |
627 return (OPEN_FAILED); | |
628 | |
629 *error = 1; | |
630 hktp = hktable[serverIF[buf->server].lang] = _Xsj3cAllocHKTable(); | |
631 while (fgets(line, sizeof(line), fp) != NULL) { | |
632 p = line; | |
633 while (*p != '\n' && *p != '#') { | |
634 p += _Xsj3cmINtomPS(buf, file, p, zhira); | |
635 CHECK_END(p); | |
636 SKIP(p); | |
637 p += _Xsj3cmINtomPS(buf, file, p, zkata); | |
638 CHECK_END(p); | |
639 SKIP(p); | |
640 p += _Xsj3cmINtomPS(buf, file, p, hkata); | |
641 CHECK_END(p); | |
642 SKIP(p); | |
643 p += _Xsj3cReadAscii(file, p, halpha); | |
644 if (zhira[0] == '\0' || zkata[0] == '\0' | |
645 || hkata[0] == '\0' || halpha[0] == '\0') | |
646 break; | |
647 if (begin++) { | |
648 hktr = _Xsj3cAllocHKTable(); | |
649 if (!hktr) { | |
650 Xsj3cWarning("can't allocate hiragana-katakana conversion table"); | |
651 return (ALLOC_FAILED); | |
652 } | |
653 hktp = hktq->next = hktr; | |
654 } | |
655 hktp->hira = _Xsj3cStoreChar(zhira, strlen(zhira) + 1); | |
656 hktp->zkata = _Xsj3cStoreChar(zkata, strlen(zkata) + 1); | |
657 hktp->hkata = _Xsj3cStoreChar(hkata, | |
658 (hkata_len = strlen(hkata)) + 1); | |
659 hktp->halpha = _Xsj3cStoreChar(halpha, | |
660 (halpha_len = strlen(halpha)) + 1); | |
661 if (!hktp->hira || !hktp->zkata || !hktp->hkata || !hktp->halpha) { | |
662 Xsj3cWarning("can't allocate hiragana-katakana conversion table"); | |
663 return(ALLOC_FAILED); | |
664 } | |
665 hktp->hlen = hkata_len; | |
666 if (hkata_len != halpha_len) | |
667 return (READ_FAILED); | |
668 hktq = hktp; | |
669 } | |
670 (*error)++; | |
671 } | |
672 hktp->next = NULL; | |
673 fclose(fp); | |
674 return (OK); | |
675 } | |
676 | |
677 /* | |
678 * _Xsj3cZHInit() | |
679 * Decide sjzh file to read, then read it and make hankaku-zenkaku | |
680 * conversion table. | |
681 */ | |
682 Xsj3cZHTable * | |
683 _Xsj3cZHInit(buf, sjzh, home) | |
684 Xsj3cBuf buf; | |
685 char *sjzh; | |
686 char *home; | |
687 { | |
688 extern char *getenv(); | |
689 register char *p; | |
690 char zhfile[BUFSIZ]; | |
691 int value, error; | |
692 | |
693 if (zhtable[serverIF[buf->server].lang]) | |
694 return (zhtable[serverIF[buf->server].lang]); | |
695 | |
696 if (sjzh) { | |
697 if ((value = _Xsj3cReadZH(buf, sjzh, &error)) > 0 ) | |
698 Xsj3cError("can't open sjzh file %s", sjzh); | |
699 else if (value < 0) | |
700 Xsj3cError("read failed line %s sjzk file %s", | |
701 _Xsj3cItoa(error), sjzh); | |
702 } else { | |
703 zhfile[0] = '\0'; | |
704 if ((p = getenv("SJZH")) && *p != '\0') { | |
705 if (*p != '/') { | |
706 if (home) | |
707 strcpy(zhfile, home); | |
708 strcat(zhfile, "/"); | |
709 } | |
710 strcat(zhfile, p); | |
711 } else if (home) { | |
712 strcpy(zhfile, home); | |
713 strcat(zhfile, "/.sjzh"); | |
714 } else { | |
715 strcpy(zhfile, SJ3DEFPATH); | |
716 strcat(zhfile, DEF_SJZH_FILE); | |
717 } | |
718 if ((value = _Xsj3cReadZH(buf, zhfile, &error)) > 0 ) { | |
719 strcpy(zhfile, SJ3DEFPATH); | |
720 strcat(zhfile, DEF_SJZH_FILE); | |
721 if ((value = _Xsj3cReadZH(buf, zhfile, &error)) > 0 ) { | |
722 Xsj3cError("can't open sjzh file %s", zhfile); | |
723 } else if (value < 0) { | |
724 Xsj3cError("read failed line %s sjzk file %s", | |
725 _Xsj3cItoa(error), zhfile); | |
726 } | |
727 } else if (value < 0) { | |
728 Xsj3cError("read failed line %s sjzk file %s", | |
729 _Xsj3cItoa(error), zhfile); | |
730 } | |
731 } | |
732 return (zhtable[serverIF[buf->server].lang]); | |
733 } | |
734 | |
735 #define ZHTBMAX (BUFSIZ/sizeof(Xsj3cZHTable)) | |
736 | |
737 static Xsj3cZHTable * | |
738 _Xsj3cAllocZHTable() | |
739 { | |
740 register Xsj3cZHTable *zhtp; | |
741 | |
742 if (zhnowtp == NULL || zhnowtp > zhmaxtp) { | |
743 zhtp = (Xsj3cZHTable *)malloc(sizeof(Xsj3cZHTable) * ZHTBMAX); | |
744 if (zhtp == NULL) | |
745 return (NULL); | |
746 zhnowtp = zhtp; | |
747 zhmaxtp = zhnowtp + ZHTBMAX - 1; | |
748 zhnowtp++; | |
749 } else { | |
750 zhtp = zhnowtp; | |
751 zhnowtp++; | |
752 } | |
753 zhtp->zkana = NULL; | |
754 zhtp->hkata = NULL; | |
755 zhtp->halpha = NULL; | |
756 zhtp->zalpha = NULL; | |
757 zhtp->next = NULL; | |
758 return (zhtp); | |
759 } | |
760 | |
761 static int | |
762 _Xsj3cReadZH(buf, file, error) | |
763 Xsj3cBuf buf; | |
764 char *file; | |
765 register int *error; | |
766 { | |
767 register FILE *fp; | |
768 unsigned char line[256]; | |
769 unsigned char *p; | |
770 unsigned char hanalpha[RBUFSIZ], zenalpha[YBUFSIZ]; | |
771 unsigned char zkana[RBUFSIZ], hkata[RBUFSIZ]; | |
772 register int begin = 0; | |
773 register Xsj3cZHTable *zhtp, *zhtq, *zhtr; | |
774 | |
775 if ((fp = fopen(file, "r")) == NULL) | |
776 return (OPEN_FAILED); | |
777 | |
778 *error = 1; | |
779 zhtp = zhtable[serverIF[buf->server].lang] = _Xsj3cAllocZHTable(); | |
780 while (fgets(line, sizeof(line), fp) != NULL) { | |
781 p = line; | |
782 while (*p != '\n' && *p != '#') { | |
783 p += _Xsj3cReadAscii(file, p, hanalpha); | |
784 CHECK_END(p); | |
785 SKIP(p); | |
786 p += _Xsj3cmINtomPS(buf, file, p, zenalpha); | |
787 CHECK_END(p); | |
788 SKIP(p); | |
789 p += _Xsj3cmINtomPS(buf, file, p, zkana); | |
790 CHECK_END(p); | |
791 SKIP(p); | |
792 p += _Xsj3cmINtomPS(buf, file, p, hkata); | |
793 if (hanalpha[0] == '\0' || zenalpha[0] == '\0' | |
794 || zkana[0] == '\0' || hkata[0] == '\0') | |
795 break; | |
796 if (begin++) { | |
797 zhtr = _Xsj3cAllocZHTable(); | |
798 if (!zhtr) { | |
799 Xsj3cWarning("can't allocate zen/hankaku conversion table"); | |
800 return (ALLOC_FAILED); | |
801 } | |
802 zhtp = zhtq->next = zhtr; | |
803 } | |
804 zhtp->halpha = _Xsj3cStoreChar(hanalpha, strlen(hanalpha) + 1); | |
805 zhtp->zalpha = _Xsj3cStoreChar(zenalpha, strlen(zenalpha) + 1); | |
806 zhtp->zkana = _Xsj3cStoreChar(zkana, strlen(zkana) + 1); | |
807 zhtp->hkata = _Xsj3cStoreChar(hkata, strlen(hkata) + 1); | |
808 if (!zhtp->halpha || !zhtp->zalpha | |
809 || !zhtp->zkana || !zhtp->hkata) { | |
810 Xsj3cWarning("can't allocate zen/han-kaku conversion table"); | |
811 return(ALLOC_FAILED); | |
812 } | |
813 zhtq = zhtp; | |
814 } | |
815 (*error)++; | |
816 } | |
817 zhtp->next = NULL; | |
818 fclose(fp); | |
819 return (OK); | |
820 } | |
821 | |
822 /* | |
823 * _Xsj3cSetPlosive() | |
824 * Set roman-kana plosive conversion data. | |
825 */ | |
826 unsigned char * | |
827 _Xsj3cSetPlosive(buf) | |
828 Xsj3cBuf buf; | |
829 { | |
830 register Xsj3cRKTable *rktp; | |
831 register int i; | |
832 register wchar s; | |
833 unsigned char tmp[KANABUFSIZ]; | |
834 | |
835 if (plosive[serverIF[buf->server].lang]) | |
836 return(plosive[serverIF[buf->server].lang]); | |
837 if (!rktable[serverIF[buf->server].lang]) | |
838 Xsj3cError("Null roman-kana conversion table"); | |
839 i = 0; | |
840 for (rktp = rktable[serverIF[buf->server].lang]; | |
841 rktp->next != NULL; rktp = rktp->next) { | |
842 if (*rktp->str != '\0') { | |
843 s = (*rktp->yomi << 8) + *(rktp->yomi + 1); | |
844 if (isplosive(s, serverIF[buf->server].lang)) { | |
845 tmp[i] = *rktp->str; | |
846 i++; | |
847 } | |
848 } | |
849 } | |
850 tmp[i] = '\0'; | |
851 if ((plosive[serverIF[buf->server].lang] | |
852 = _Xsj3cStoreChar(tmp, strlen(tmp) + 1)) == NULL) | |
853 Xsj3cError("can't allocate for roma-kana plosive conversion table"); | |
854 return(plosive[serverIF[buf->server].lang]); | |
855 } | |
856 | |
857 /* | |
858 * _Xsj3cSetDouble() | |
859 * Set roman-kana double conversion data. | |
860 */ | |
861 unsigned char * | |
862 _Xsj3cSetDouble(buf) | |
863 Xsj3cBuf buf; | |
864 { | |
865 register Xsj3cRKTable *rktp, *rktp2; | |
866 register int i; | |
867 unsigned char tmp[KANABUFSIZ]; | |
868 | |
869 if (rkdouble[serverIF[buf->server].lang]) | |
870 return(rkdouble[serverIF[buf->server].lang]); | |
871 if (!rktable[serverIF[buf->server].lang]) | |
872 Xsj3cError("Null roman-kana conversion table"); | |
873 i = 0; | |
874 for (rktp = rktable[serverIF[buf->server].lang]; | |
875 rktp->next != NULL; rktp = rktp->next) { | |
876 if (rktp->rlen == 1) { | |
877 if (isvowel(*rktp->roma)) | |
878 continue; | |
879 tmp[i] = *rktp->roma; | |
880 for (rktp2 = rktable[serverIF[buf->server].lang]; | |
881 rktp2->next != NULL; rktp2 = rktp2->next) { | |
882 if (rktp2->rlen == 2 && *(rktp2->roma + 1) == tmp[i] | |
883 && *(rktp2->roma) == tmp[i]) { | |
884 if (!strcmp(rktp->yomi, rktp2->yomi)) { | |
885 i++; | |
886 break; | |
887 } | |
888 } | |
889 } | |
890 } | |
891 } | |
892 tmp[i] = '\0'; | |
893 if ((rkdouble[serverIF[buf->server].lang] | |
894 = _Xsj3cStoreChar(tmp, strlen(tmp) + 1)) == NULL) | |
895 Xsj3cError("can't allocate for roma-kana double conversion table"); | |
896 return(rkdouble[serverIF[buf->server].lang]); | |
897 } |