Mercurial > kinput2.yaz
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/Xsj3clib/table.c Mon Mar 08 04:44:30 2010 +0900 @@ -0,0 +1,897 @@ +#ifndef lint +static char *rcsid = "$Id: table.c,v 2.3 1993/09/21 09:42:45 nao Exp $"; +#endif +/* + * Copyright 1991 Sony Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sony not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Sony makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SONY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SONY + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Author: Naoshi Suzuki, SONY Corporation. (nao@sm.sony.co.jp) + */ + +#include <stdio.h> +#include <ctype.h> +#include "common.h" +#include "sj3ctype.h" +#include "util.h" + +extern Xsj3cCVServerIF serverIF[SERVER_NUM]; +extern Xsj3cSymbol _Xsj3cSymbolInit(); +extern Xsj3cHinsi _Xsj3cHinsiInit(); + +Xsj3cRKTable *_Xsj3cRKInit(); +Xsj3cHKTable *_Xsj3cHKInit(); +Xsj3cZHTable *_Xsj3cZHInit(); +unsigned char *_Xsj3cSetPlosive(); +unsigned char *_Xsj3cSetDouble(); +void Xsj3cInitializeTables(); + +int _Xsj3cmINtowOUT(); +int _Xsj3cReadAscii(); +wchar *_Xsj3cStoreWchar(); + +static Xsj3cRKTable *_Xsj3cAllocRKTable(); +static Xsj3cHKTable *_Xsj3cAllocHKTable(); +static Xsj3cZHTable *_Xsj3cAllocZHTable(); + +static unsigned char *_Xsj3cStoreChar(); + +static int _Xsj3cmINtomPS(); + +static int _Xsj3cReadRK(); +static int _Xsj3cReadHK(); +static int _Xsj3cReadZH(); + +static unsigned char *chnowp = NULL, *chmaxp = NULL; +static wchar *wnowp = NULL, *wmaxp = NULL; + +static Xsj3cRKTable *rktable[2] = {NULL, NULL}; +static Xsj3cHKTable *hktable[2] = {NULL, NULL}; +static Xsj3cZHTable *zhtable[2] = {NULL, NULL}; +static unsigned char *plosive[2] = {NULL, NULL}; +static unsigned char *rkdouble[2] = {NULL, NULL}; + +static Xsj3cRKTable *rknowtp = NULL, *rkmaxtp = NULL; +static Xsj3cHKTable *hknowtp = NULL, *hkmaxtp = NULL; +static Xsj3cZHTable *zhnowtp = NULL, *zhmaxtp = NULL; + +static unsigned char * +_Xsj3cStoreChar(ch, len) + unsigned char *ch; + int len; +{ + register unsigned char *chp; + + if (chnowp == NULL || chnowp + len > chmaxp) { + chp = (unsigned char *)malloc(BUFSIZ); + if (chp == NULL) + return (NULL); + chnowp = chp; + chmaxp = chnowp + (BUFSIZ/sizeof(unsigned char)); + strcpy (chp, ch); + chnowp += len; + return (chp); + } else { + chp = chnowp; + strcpy (chp, ch); + chnowp += len; + return (chp); + } +} + +wchar * +_Xsj3cStoreWchar(wch, len) + wchar *wch; + int len; +{ + register wchar *wp; + + if (wnowp == NULL || wnowp + len > wmaxp) { + wp = (wchar *)malloc(BUFSIZ); + if (wp == NULL) + return (NULL); + wnowp = wp; + wmaxp = wnowp + (BUFSIZ/sizeof(wchar)); + (void)_Xsj3cWcpy (wp, wch); + wnowp += len; + return (wp); + } else { + wp = wnowp; + (void)_Xsj3cWcpy (wp, wch); + wnowp += len; + return (wp); + } +} + +static int +_Xsj3cmINtomPS(buf, file, src, dest) + Xsj3cBuf buf; + char *file; + register unsigned char *src, *dest; +{ + register unsigned char c; + register wchar s, (*conv)(); + register int i = 0, kanji = OFF, kana = OFF; + + conv = CodeConvFunc[in_lang][serverIF[buf->server].lang]; + while ((*src != '\t' && *src != '\n' + && *src != ' ' && *src != '#')||(kanji || kana)) { + c = *src++; + switch (c) { + case ESC: + c = *src++; + if (c == '$') { + c = *src++; + i++; + if (c == 'B' || c == '@') { + kanji++; + i++; + } else + goto badcode; + } else if (c == '(') { + c = *src++; + i++; + if (c == 'J' || c == 'B' || c == 'H') { + kanji = OFF; + i++; + } else if (c == '$' && *src == 'B') { + src++; + kanji++; + i++; + } else + goto badcode; + } else if (c == '&' && !strcmp("@\033$B", src)) { + src += 4; + i += 5; + kanji++; + } else + goto badcode; + break; + case SI: + kana = OFF; + break; + case SO: + kana++; + break; + case '\\': + if (!kanji & !kana) { + *dest++ = *src++; + i++; + break; + } + default: + if (kanji) { + s = (c << 8) + (*src++ & 0x7f); + s = conv(s); + *dest++ = (s >> 8) & 0xff; + *dest++ = s & 0xff; + i++; + } else if (iskan1(c, in_lang) && iskan2(*src, in_lang)) { + if (conv) { + s = (c << 8) + (*src++ & 0xff); + s = conv(s); + *dest++ = (s >> 8) & 0xff; + *dest++ = s & 0xff; + } else { + *dest++ = c; + *dest++ = *src++; + } + i++; + } else if (iskana(c)) { + if (in_lang == JP_SJIS || in_lang == JP_JIS8) + *dest++ = c; + else if (in_lang == JP_EUC && iseuckana(c) && iskana2(*src)) { + *dest++ = *src++; + i++; + } else + goto badcode; + } else if (iseuckana(c) && iskana2(*src)) { + if (in_lang == JP_EUC) + *dest++ = *src++; + else + goto badcode; + i++; + } else if (kana) { + *dest++ = (c | MSB); + } else if (isascii(c)) { + *dest++ = c; + } else { +badcode: + Xsj3cError("There is bad code %s in %s",_Xsj3cXtoa(c),file); + } + break; + } + i++; + } + *dest = '\0'; + return (i); +} + +int +_Xsj3cReadAscii(file, src, dest) + char *file; + register unsigned char *src, *dest; +{ + register int i = 0, kana = OFF; + + while ((*src != '\t' && *src != ' ' + && *src != '\0' && *src != '\n' && *src != '#')|| kana) { + if (kana) { + *dest++ = (*src++ | MSB); + } if (*src == '\\') { + src++; + i++; + *dest++ = *src++; + } else if (isascii(*src)) { + *dest++ = *src++; + } else if (isdakuten(*src)) { + *dest++ = *src++; + } else if (iseuckana(*src) && isdakuten(*(src + 1))) { + src++; + i++; + *dest++ = *src++; + } else if (*src == SO) { + src++; + kana++; + } else if (*src == SI) { + src++; + kana = OFF; + } else { + int n = *src; + Xsj3cError("There is bad code %s in %s",_Xsj3cXtoa(n),file); + } + i++; + } + *dest = '\0'; + return (i); +} + +int +_Xsj3cmINtowOUT(file, src, dest, len) + char *file; + register unsigned char *src; + register wchar *dest; + register int *len; +{ + register unsigned char c; + register int i = 0, kanji = OFF, kana = OFF; + register wchar (*conv)(); + + *len = 0; + conv = CodeConvFunc[in_lang][out_lang]; + while ((*src != '\t' && *src != ' ' && *src != '\0' + && *src != '\n' && *src != '#')||(kanji || kana)) { + c = *src++; + switch (c) { + case ESC: + c = *src++; + if (c == '$') { + c = *src++; + i++; + if (c == 'B' || c == '@') { + kanji++; + i++; + } else + goto badcode; + } else if (c == '(') { + c = *src++; + i++; + if (c == 'J' || c == 'B' || c == 'H') { + kanji = OFF; + i++; + } else if (c == '$' && *src == 'B') { + src++; + kanji++; + i++; + } else + goto badcode; + } else if (c == '&' && !strcmp("@\033$B", src)) { + src += 4; + i += 5; + kanji++; + } else + goto badcode; + break; + case SI: + kana = OFF; + break; + case SO: + kana++; + break; + case '\\': + if (!kanji && !kana) { + *dest++ = *src++; + i++; + break; + } + default: + if (kanji || (iskan1(c, in_lang) && iskan2(*src, in_lang))) { + if (conv) + *dest++ = conv((c << 8) + (*src++ & 0xff)); + else + *dest++ = (c << 8) + (*src++ & 0xff); + i++; + } else if (iskana(c)) { + if (in_lang == JP_SJIS || in_lang == JP_JIS8) + *dest++ = c; + else if (in_lang == JP_EUC && iseuckana(c) && iskana2(*src)) { + *dest++ = *src++; + i++; + } else + goto badcode; + } else if (iseuckana(c) && iskana2(*src)) { + if (in_lang == JP_EUC) + *dest++ = *src++; + else + goto badcode; + i++; + } else if (kana) { + *dest++ = (c | MSB); + } else if (isascii(c)) { + *dest++ = c; + } else { +badcode: + Xsj3cError("There is bad code %s in %s",_Xsj3cXtoa(c),file); + } + (*len)++; + break; + } + i++; + } + *dest = '\0'; + return (i); +} + +/* + * Xsj3cInitializeTables() + * Read definition files and initialize conversion tables. + */ +void +Xsj3cInitializeTables(buf, home, sjrk, sjhk, sjzh, sjsb) + Xsj3cBuf buf; + char *home; + char *sjrk, *sjhk, *sjzh, *sjsb; +{ + buf->rktable = _Xsj3cRKInit(buf, sjrk, home); + buf->hktable = _Xsj3cHKInit(buf, sjhk, home); + buf->zhtable = _Xsj3cZHInit(buf, sjzh, home); + buf->symbol = _Xsj3cSymbolInit(sjsb, home); + buf->plosive = _Xsj3cSetPlosive(buf); + buf->rkdouble = _Xsj3cSetDouble(buf); + buf->hinsi = _Xsj3cHinsiInit(buf); +} + +/* + * _Xsj3cRKInit() + * Decide sjrk file to read, then read it and make table for roman-kana + * conversion table. + */ +Xsj3cRKTable * +_Xsj3cRKInit(buf, sjrk, home) + Xsj3cBuf buf; + char *sjrk; + char *home; +{ + extern char *getenv(); + register char *p; + char rkfile[BUFSIZ]; + int value, error; + + if (rktable[serverIF[buf->server].lang]) + return (rktable[serverIF[buf->server].lang]); + + if (sjrk) { + if ((value = _Xsj3cReadRK(buf, sjrk, &error)) > 0 ) + Xsj3cError("can't open sjrk file %s", sjrk); + else if (value < 0) + Xsj3cError("read failed line %s sjrk file %s", + _Xsj3cItoa(error), sjrk); + } else { + rkfile[0] = '\0'; + if ((p = getenv("SJRK")) && *p != '\0') { + if (*p != '/') { + if (home) + strcpy(rkfile, home); + strcat(rkfile, "/"); + } + strcat(rkfile, p); + } else if (home) { + strcpy(rkfile, home); + strcat(rkfile, "/.sjrk"); + } else { + strcpy(rkfile, SJ3DEFPATH); + strcat(rkfile, DEF_SJRK_FILE); + } + if ((value = _Xsj3cReadRK(buf, rkfile, &error)) > 0 ) { + strcpy(rkfile, SJ3DEFPATH); + strcat(rkfile, DEF_SJRK_FILE); + if ((value = _Xsj3cReadRK(buf, rkfile, &error)) > 0 ) { + Xsj3cError("can't open sjrk file %s", rkfile); + } else if (value < 0) { + Xsj3cError("read failed line %s sjrk file %s", + _Xsj3cItoa(error), rkfile); + } + } else if (value < 0) { + Xsj3cError("read failed line %s sjrk file %s", + _Xsj3cItoa(error), rkfile); + } + } + return (rktable[serverIF[buf->server].lang]); +} + +#define RKTBMAX (BUFSIZ/sizeof(Xsj3cRKTable)) + +static Xsj3cRKTable * +_Xsj3cAllocRKTable() +{ + register Xsj3cRKTable *rktp; + + if (rknowtp == NULL || rknowtp > rkmaxtp) { + rktp = (Xsj3cRKTable *)malloc(sizeof(Xsj3cRKTable) * RKTBMAX); + if (rktp == NULL) + return (NULL); + rknowtp = rktp; + rkmaxtp = rknowtp + RKTBMAX - 1; + rknowtp++; + } else { + rktp = rknowtp; + rknowtp++; + } + rktp->roma = NULL; + rktp->yomi = NULL; + rktp->str = NULL; + rktp->rlen = 0; + rktp->ylen = 0; + rktp->next = NULL; + return (rktp); +} + +/* + * _Xsj3cReadRK() + * Read sjrk file like a format sj3's roman-kana conversion file, + * and make conversion table. + * But this routine distinguishes upper-case and lower-case. + * It's a big difference. + */ +static int +_Xsj3cReadRK(buf, file, error) + Xsj3cBuf buf; + register char *file; + register int *error; +{ + register FILE *fp; + unsigned char line[256]; + unsigned char *p; + unsigned char roma[RBUFSIZ], yomi[YBUFSIZ], str[RBUFSIZ]; + register int begin = 0, rlen, ylen; + register Xsj3cRKTable *rktp, *rktq, *rktr; + + if ((fp = fopen(file, "r")) == NULL) + return (OPEN_FAILED); + + *error = 1; + rktp = rktable[serverIF[buf->server].lang] = _Xsj3cAllocRKTable(); + while (fgets(line, sizeof(line), fp) != NULL) { + p = line; + while (*p != '\n' && *p != '#') { + p += _Xsj3cReadAscii(file, p, roma); + CHECK_END(p); + SKIP(p); + p += _Xsj3cmINtomPS(buf, file, p, yomi); + SKIP(p); + p += _Xsj3cReadAscii(file, p, str); + if (roma[0] == '\0' || yomi[0] == '\0') + break; + if (begin++) { + rktr = _Xsj3cAllocRKTable(); + if (!rktr) { + Xsj3cWarning("can't allocate roman-kana conversion table"); + return (ALLOC_FAILED); + } + rktp = rktq->next = rktr; + } + rktp->roma = _Xsj3cStoreChar(roma, (rlen = strlen(roma)) + 1); + rktp->yomi = _Xsj3cStoreChar(yomi, (ylen = strlen(yomi)) + 1); + rktp->str = _Xsj3cStoreChar(str, strlen(str) + 1); + if (!rktp->roma || !rktp->yomi || !rktp->str) { + Xsj3cWarning("can't allocate roman-kana conversion table"); + return(ALLOC_FAILED); + } + rktp->rlen = rlen; + rktp->ylen = ylen; + rktq = rktp; + } + (*error)++; + } + rktp->next = NULL; + fclose(fp); + return (OK); +} + +/* + * _Xsj3cHKInit() + * Decide sjhk file to read, then read it and make hiragana-katakana + * conversion table. + */ +Xsj3cHKTable * +_Xsj3cHKInit(buf, sjhk, home) + Xsj3cBuf buf; + char *sjhk; + char *home; +{ + extern char *getenv(); + register char *p; + char hkfile[BUFSIZ]; + int value, error; + + if (hktable[serverIF[buf->server].lang]) + return (hktable[serverIF[buf->server].lang]); + + if (sjhk) { + if ((value = _Xsj3cReadHK(buf, sjhk, &error)) > 0 ) + Xsj3cError("can't open sjhk file %s", sjhk); + else if (value < 0) + Xsj3cError("read failed line %s sjhk file %s", + _Xsj3cItoa(error), sjhk); + } else { + hkfile[0] = '\0'; + if ((p = getenv("SJHK")) && *p != '\0') { + if (*p != '/') { + if (home) + strcpy(hkfile, home); + strcat(hkfile, "/"); + } + strcat(hkfile, p); + } else if (home) { + strcpy(hkfile, home); + strcat(hkfile, "/.sjhk"); + } else { + strcpy(hkfile, SJ3DEFPATH); + strcat(hkfile, DEF_SJHK_FILE); + } + if ((value = _Xsj3cReadHK(buf, hkfile, &error)) > 0 ) { + strcpy(hkfile, SJ3DEFPATH); + strcat(hkfile, DEF_SJHK_FILE); + if ((value = _Xsj3cReadHK(buf, hkfile, &error)) > 0 ) { + Xsj3cError("can't open sjhk file %s", hkfile); + } else if (value < 0) { + Xsj3cError("read failed line %s sjhk file %s", + _Xsj3cItoa(error), hkfile); + } + } else if (value < 0) { + Xsj3cError("read failed line %s sjhk file %s", + _Xsj3cItoa(error), hkfile); + } + } + return (hktable[serverIF[buf->server].lang]); +} + +#define HKTBMAX (BUFSIZ/sizeof(Xsj3cHKTable)) + +static Xsj3cHKTable * +_Xsj3cAllocHKTable() +{ + register Xsj3cHKTable *hktp; + + if (hknowtp == NULL || hknowtp > hkmaxtp) { + hktp = (Xsj3cHKTable *)malloc(sizeof(Xsj3cHKTable) * HKTBMAX); + if (hktp == NULL) + return (NULL); + hknowtp = hktp; + hkmaxtp = hknowtp + HKTBMAX - 1; + hknowtp++; + } else { + hktp = hknowtp; + hknowtp++; + } + hktp->hira = NULL; + hktp->zkata = NULL; + hktp->hkata = NULL; + hktp->halpha = NULL; + hktp->hlen = 0; + hktp->next = NULL; + return (hktp); +} + +static int +_Xsj3cReadHK(buf, file, error) + Xsj3cBuf buf; + register char *file; + register int *error; +{ + register FILE *fp; + unsigned char line[256]; + unsigned char *p; + unsigned char zhira[RBUFSIZ], zkata[YBUFSIZ]; + unsigned char hkata[RBUFSIZ], halpha[RBUFSIZ]; + register int begin = 0, hkata_len, halpha_len; + register Xsj3cHKTable *hktp, *hktq, *hktr; + + if ((fp = fopen(file, "r")) == NULL) + return (OPEN_FAILED); + + *error = 1; + hktp = hktable[serverIF[buf->server].lang] = _Xsj3cAllocHKTable(); + while (fgets(line, sizeof(line), fp) != NULL) { + p = line; + while (*p != '\n' && *p != '#') { + p += _Xsj3cmINtomPS(buf, file, p, zhira); + CHECK_END(p); + SKIP(p); + p += _Xsj3cmINtomPS(buf, file, p, zkata); + CHECK_END(p); + SKIP(p); + p += _Xsj3cmINtomPS(buf, file, p, hkata); + CHECK_END(p); + SKIP(p); + p += _Xsj3cReadAscii(file, p, halpha); + if (zhira[0] == '\0' || zkata[0] == '\0' + || hkata[0] == '\0' || halpha[0] == '\0') + break; + if (begin++) { + hktr = _Xsj3cAllocHKTable(); + if (!hktr) { + Xsj3cWarning("can't allocate hiragana-katakana conversion table"); + return (ALLOC_FAILED); + } + hktp = hktq->next = hktr; + } + hktp->hira = _Xsj3cStoreChar(zhira, strlen(zhira) + 1); + hktp->zkata = _Xsj3cStoreChar(zkata, strlen(zkata) + 1); + hktp->hkata = _Xsj3cStoreChar(hkata, + (hkata_len = strlen(hkata)) + 1); + hktp->halpha = _Xsj3cStoreChar(halpha, + (halpha_len = strlen(halpha)) + 1); + if (!hktp->hira || !hktp->zkata || !hktp->hkata || !hktp->halpha) { + Xsj3cWarning("can't allocate hiragana-katakana conversion table"); + return(ALLOC_FAILED); + } + hktp->hlen = hkata_len; + if (hkata_len != halpha_len) + return (READ_FAILED); + hktq = hktp; + } + (*error)++; + } + hktp->next = NULL; + fclose(fp); + return (OK); +} + +/* + * _Xsj3cZHInit() + * Decide sjzh file to read, then read it and make hankaku-zenkaku + * conversion table. + */ +Xsj3cZHTable * +_Xsj3cZHInit(buf, sjzh, home) + Xsj3cBuf buf; + char *sjzh; + char *home; +{ + extern char *getenv(); + register char *p; + char zhfile[BUFSIZ]; + int value, error; + + if (zhtable[serverIF[buf->server].lang]) + return (zhtable[serverIF[buf->server].lang]); + + if (sjzh) { + if ((value = _Xsj3cReadZH(buf, sjzh, &error)) > 0 ) + Xsj3cError("can't open sjzh file %s", sjzh); + else if (value < 0) + Xsj3cError("read failed line %s sjzk file %s", + _Xsj3cItoa(error), sjzh); + } else { + zhfile[0] = '\0'; + if ((p = getenv("SJZH")) && *p != '\0') { + if (*p != '/') { + if (home) + strcpy(zhfile, home); + strcat(zhfile, "/"); + } + strcat(zhfile, p); + } else if (home) { + strcpy(zhfile, home); + strcat(zhfile, "/.sjzh"); + } else { + strcpy(zhfile, SJ3DEFPATH); + strcat(zhfile, DEF_SJZH_FILE); + } + if ((value = _Xsj3cReadZH(buf, zhfile, &error)) > 0 ) { + strcpy(zhfile, SJ3DEFPATH); + strcat(zhfile, DEF_SJZH_FILE); + if ((value = _Xsj3cReadZH(buf, zhfile, &error)) > 0 ) { + Xsj3cError("can't open sjzh file %s", zhfile); + } else if (value < 0) { + Xsj3cError("read failed line %s sjzk file %s", + _Xsj3cItoa(error), zhfile); + } + } else if (value < 0) { + Xsj3cError("read failed line %s sjzk file %s", + _Xsj3cItoa(error), zhfile); + } + } + return (zhtable[serverIF[buf->server].lang]); +} + +#define ZHTBMAX (BUFSIZ/sizeof(Xsj3cZHTable)) + +static Xsj3cZHTable * +_Xsj3cAllocZHTable() +{ + register Xsj3cZHTable *zhtp; + + if (zhnowtp == NULL || zhnowtp > zhmaxtp) { + zhtp = (Xsj3cZHTable *)malloc(sizeof(Xsj3cZHTable) * ZHTBMAX); + if (zhtp == NULL) + return (NULL); + zhnowtp = zhtp; + zhmaxtp = zhnowtp + ZHTBMAX - 1; + zhnowtp++; + } else { + zhtp = zhnowtp; + zhnowtp++; + } + zhtp->zkana = NULL; + zhtp->hkata = NULL; + zhtp->halpha = NULL; + zhtp->zalpha = NULL; + zhtp->next = NULL; + return (zhtp); +} + +static int +_Xsj3cReadZH(buf, file, error) + Xsj3cBuf buf; + char *file; + register int *error; +{ + register FILE *fp; + unsigned char line[256]; + unsigned char *p; + unsigned char hanalpha[RBUFSIZ], zenalpha[YBUFSIZ]; + unsigned char zkana[RBUFSIZ], hkata[RBUFSIZ]; + register int begin = 0; + register Xsj3cZHTable *zhtp, *zhtq, *zhtr; + + if ((fp = fopen(file, "r")) == NULL) + return (OPEN_FAILED); + + *error = 1; + zhtp = zhtable[serverIF[buf->server].lang] = _Xsj3cAllocZHTable(); + while (fgets(line, sizeof(line), fp) != NULL) { + p = line; + while (*p != '\n' && *p != '#') { + p += _Xsj3cReadAscii(file, p, hanalpha); + CHECK_END(p); + SKIP(p); + p += _Xsj3cmINtomPS(buf, file, p, zenalpha); + CHECK_END(p); + SKIP(p); + p += _Xsj3cmINtomPS(buf, file, p, zkana); + CHECK_END(p); + SKIP(p); + p += _Xsj3cmINtomPS(buf, file, p, hkata); + if (hanalpha[0] == '\0' || zenalpha[0] == '\0' + || zkana[0] == '\0' || hkata[0] == '\0') + break; + if (begin++) { + zhtr = _Xsj3cAllocZHTable(); + if (!zhtr) { + Xsj3cWarning("can't allocate zen/hankaku conversion table"); + return (ALLOC_FAILED); + } + zhtp = zhtq->next = zhtr; + } + zhtp->halpha = _Xsj3cStoreChar(hanalpha, strlen(hanalpha) + 1); + zhtp->zalpha = _Xsj3cStoreChar(zenalpha, strlen(zenalpha) + 1); + zhtp->zkana = _Xsj3cStoreChar(zkana, strlen(zkana) + 1); + zhtp->hkata = _Xsj3cStoreChar(hkata, strlen(hkata) + 1); + if (!zhtp->halpha || !zhtp->zalpha + || !zhtp->zkana || !zhtp->hkata) { + Xsj3cWarning("can't allocate zen/han-kaku conversion table"); + return(ALLOC_FAILED); + } + zhtq = zhtp; + } + (*error)++; + } + zhtp->next = NULL; + fclose(fp); + return (OK); +} + +/* + * _Xsj3cSetPlosive() + * Set roman-kana plosive conversion data. + */ +unsigned char * +_Xsj3cSetPlosive(buf) + Xsj3cBuf buf; +{ + register Xsj3cRKTable *rktp; + register int i; + register wchar s; + unsigned char tmp[KANABUFSIZ]; + + if (plosive[serverIF[buf->server].lang]) + return(plosive[serverIF[buf->server].lang]); + if (!rktable[serverIF[buf->server].lang]) + Xsj3cError("Null roman-kana conversion table"); + i = 0; + for (rktp = rktable[serverIF[buf->server].lang]; + rktp->next != NULL; rktp = rktp->next) { + if (*rktp->str != '\0') { + s = (*rktp->yomi << 8) + *(rktp->yomi + 1); + if (isplosive(s, serverIF[buf->server].lang)) { + tmp[i] = *rktp->str; + i++; + } + } + } + tmp[i] = '\0'; + if ((plosive[serverIF[buf->server].lang] + = _Xsj3cStoreChar(tmp, strlen(tmp) + 1)) == NULL) + Xsj3cError("can't allocate for roma-kana plosive conversion table"); + return(plosive[serverIF[buf->server].lang]); +} + +/* + * _Xsj3cSetDouble() + * Set roman-kana double conversion data. + */ +unsigned char * +_Xsj3cSetDouble(buf) + Xsj3cBuf buf; +{ + register Xsj3cRKTable *rktp, *rktp2; + register int i; + unsigned char tmp[KANABUFSIZ]; + + if (rkdouble[serverIF[buf->server].lang]) + return(rkdouble[serverIF[buf->server].lang]); + if (!rktable[serverIF[buf->server].lang]) + Xsj3cError("Null roman-kana conversion table"); + i = 0; + for (rktp = rktable[serverIF[buf->server].lang]; + rktp->next != NULL; rktp = rktp->next) { + if (rktp->rlen == 1) { + if (isvowel(*rktp->roma)) + continue; + tmp[i] = *rktp->roma; + for (rktp2 = rktable[serverIF[buf->server].lang]; + rktp2->next != NULL; rktp2 = rktp2->next) { + if (rktp2->rlen == 2 && *(rktp2->roma + 1) == tmp[i] + && *(rktp2->roma) == tmp[i]) { + if (!strcmp(rktp->yomi, rktp2->yomi)) { + i++; + break; + } + } + } + } + } + tmp[i] = '\0'; + if ((rkdouble[serverIF[buf->server].lang] + = _Xsj3cStoreChar(tmp, strlen(tmp) + 1)) == NULL) + Xsj3cError("can't allocate for roma-kana double conversion table"); + return(rkdouble[serverIF[buf->server].lang]); +}