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 }