sj4/lib/sj4rkcv/sj4_rkcv.c
2026-07-02 13:31:52 +09:00

791 lines
17 KiB
C

/*
* Copyright (c) 1994 Sony Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Sony Corporation
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
* from Sony Corporation.
*
*/
#include <stdlib.h>
#include <string.h>
#include "wchar16.h"
#include "kana.h"
#include "rk.h"
#include "kctype.h"
#include "sj4rkcv.h"
#if defined(__sony_news) && (SVR4)
#define wscmp sj4_wscmp16
#define wsncmp sj4_wsncmp16
#define wsncpy sj4_wsncpy16
#define wscpy sj4_wscpy16
#define wslen sj4_wslen16
#define mbstowcs sj4_mbstowcs16
#define wcstombs sj4_wcstombs16
#endif
extern int current_locale;
#define sj_iskata(c) (c >= 0xa5a1 && c <= 0xa5f6)
#define sj_ishira(c) (c >= 0xa4a1 && c <= 0xa4f3)
static wchar16_t intmp[MAXLLEN];
static wchar16_t outtmp[MAXLLEN];
static u_char mtmp[MAXLLEN];
static u_short HKtable[ZKATAn] = {
KANA_XA, KANA_A,
KANA_XA + 1, KANA_A + 1,
KANA_XA + 2, KANA_A + 2,
KANA_XA + 3, KANA_A + 3,
KANA_XA + 4, KANA_A + 4,
KANA_KA, KANA_GA,
KANA_KA + 1, KANA_GA + (1 << 8),
KANA_KA + 2, KANA_GA + (2 << 8),
KANA_KA + 3, KANA_GA + (3 << 8),
KANA_KA + 4, KANA_GA + (4 << 8),
KANA_SA, KANA_ZA,
KANA_SA + 1, KANA_ZA + (1 << 8),
KANA_SA + 2, KANA_ZA + (2 << 8),
KANA_SA + 3, KANA_ZA + (3 << 8),
KANA_SA + 4, KANA_ZA + (4 << 8),
KANA_TA, KANA_DA,
KANA_TA + 1, KANA_DA + (1 << 8),
KANA_XTSU, KANA_TA + 2, KANA_DA + (2 << 8),
KANA_TA + 3, KANA_DA + (3 << 8),
KANA_TA + 4, KANA_DA + (4 << 8),
KANA_NA,
KANA_NA + 1,
KANA_NA + 2,
KANA_NA + 3,
KANA_NA + 4,
KANA_HA, KANA_BA, KANA_PA,
KANA_HA + 1, KANA_BA + (1 << 8), KANA_PA + (1 << 8),
KANA_HA + 2, KANA_BA + (2 << 8), KANA_PA + (2 << 8),
KANA_HA + 3, KANA_BA + (3 << 8), KANA_PA + (3 << 8),
KANA_HA + 4, KANA_BA + (4 << 8), KANA_PA + (4 << 8),
KANA_MA,
KANA_MA + 1,
KANA_MA + 2,
KANA_MA + 3,
KANA_MA + 4,
KANA_XYA, KANA_YA,
KANA_XYA + 1, KANA_YA + 1,
KANA_XYA + 2, KANA_YA + 2,
KANA_RA,
KANA_RA + 1,
KANA_RA + 2,
KANA_RA + 3,
KANA_RA + 4,
KANA_WA, KANA_WA,
KANA_A + 1,
KANA_A + 3,
KANA_WO,
KANA_WA + 1,
((KANA_A + 2) << 8) + KANA_DTEN,
KANA_KA,
KANA_KA + 3};
static struct ztohkktbl {
u_short zen;
u_short han;
} HKKtbl[8] = {
ZEN_KTEN, KANA_KTEN,
ZEN_FKAKKO, KANA_FKAKKO,
ZEN_EKAKKO, KANA_EKAKKO,
ZEN_TTEN, KANA_TTEN,
ZEN_CTEN, KANA_CTEN,
ZEN_CHOUON, KANA_CHOUON,
ZEN_DTEN, KANA_DTEN,
ZEN_HDTEN, KANA_HDTEN};
static struct hzkigoutbl {
wchar16_t han;
u_short zen;
} HZKtbl[6] = {
',', ZEN_TTEN,
'.', ZEN_KTEN,
'-', ZEN_CHOUON,
'@', ZEN_CTEN,
'[', ZEN_FKAKKO,
']', ZEN_EKAKKO};
static u_short HZtbl[95] = {
0xa1a1, 0xa1aa, 0xa1c9, 0xa1f4, 0xa1f0, 0xa1f3, 0xa1f5, 0xa1c7,
0xa1ca, 0xa1cb, 0xa1f6, 0xa1dc, 0xa1a4, 0xa1dd, 0xa1a5, 0xa1bf,
0xa3b0, 0xa3b1, 0xa3b2, 0xa3b3, 0xa3b4, 0xa3b5, 0xa3b6, 0xa3b7,
0xa3b8, 0xa3b9, 0xa1a7, 0xa1a8, 0xa1e3, 0xa1e1, 0xa1e4, 0xa1a9,
0xa1f7, 0xa3c1, 0xa3c2, 0xa3c3, 0xa3c4, 0xa3c5, 0xa3c6, 0xa3c7,
0xa3c8, 0xa3c9, 0xa3ca, 0xa3cb, 0xa3cc, 0xa3cd, 0xa3ce, 0xa3cf,
0xa3d0, 0xa3d1, 0xa3d2, 0xa3d3, 0xa3d4, 0xa3d5, 0xa3d6, 0xa3d7,
0xa3d8, 0xa3d9, 0xa3da, 0xa1ce, 0xa1ef, 0xa1cf, 0xa1b0, 0xa1b2,
0xa1c6, 0xa3e1, 0xa3e2, 0xa3e3, 0xa3e4, 0xa3e5, 0xa3e6, 0xa3e7,
0xa3e8, 0xa3e9, 0xa3ea, 0xa3eb, 0xa3ec, 0xa3ed, 0xa3ee, 0xa3ef,
0xa3f0, 0xa3f1, 0xa3f2, 0xa3f3, 0xa3f4, 0xa3f5, 0xa3f6, 0xa3f7,
0xa3f8, 0xa3f9, 0xa3fa, 0xa1d0, 0xa1c3, 0xa1d1, 0xa1b1};
#ifdef ADDHK
void setl_hktozh() {
int i;
u_short c, zen1;
wchar16_t rstr[2];
wchar16_t kstr[2];
RkTablW16 *rktp, *mktable();
zen1 = (ZHIRA1 << 8);
rstr[1] = '\0';
kstr[1] = 0;
for(i = 0; i < ZKATAn - 3; i++) {
c = HKtable[i];
if(!(c & RKZEN)) {
rstr[0] = c;
if((rktp = mktable(rstr, 1)) == NULL)
break;
if(rktp->k_yomi != NULL)
continue;
kstr[0] = zen1 + (ZHIRAF2 + i);
if(kstradd(&(rktp->k_yomi), kstr, 2) == -1)
break;
}
}
for(i = 0; i < 8; i++) {
rstr[0] = HKKtbl[i].han;
if((rktp = mktable(rstr, 1)) == NULL)
break;
if(rktp->k_yomi != NULL)
continue;
kstr[0] = HKKtbl[i].zen;
if(kstradd(&(rktp->k_yomi), kstr, 2) == -1)
break;
}
}
#endif
void mkkigou() {
int i;
wchar16_t rstr[2];
wchar16_t kstr[2];
RkTablW16 *rktp, *mktable();
rstr[1] = '\0';
kstr[1] = 0;
for(i = 0; i < 6; i++) {
rstr[0] = HZKtbl[i].han;
if((rktp = mktable(rstr, 1)) == NULL)
break;
if(rktp->k_yomi != NULL)
continue;
kstr[0] = HZKtbl[i].zen;
if(kstradd(&(rktp->k_yomi), kstr, 2) == -1)
break;
}
}
int sj_addten(u_short prefix, u_short c) {
u_short c1, cc;
cc = 0;
if((c == ZEN_DTEN || c == ZEN_HDTEN) &&
(sj_ishira(prefix) || sj_iskata(prefix))) {
c1 = sj_zen2han(prefix);
if((c1 >= KANA_KA && c1 < KANA_NA) ||
(c1 >= KANA_HA && c1 < KANA_MA)) {
if(c == ZEN_DTEN)
cc = prefix + 1;
else if(c == ZEN_HDTEN && c1 >= KANA_HA)
cc = prefix + 2;
} else if(c1 == KANA_A + 2 && sj_iskata(prefix) && c == ZEN_DTEN)
cc = ZEN_VU;
}
return (cc);
}
int sj_han2zen(u_short c) {
int i;
u_short cc;
if(WcIsHANKAKU(c) && iskana2(c)) {
for(i = 0; i < ZKATAn; i++) {
if(c == HKtable[i]) {
if(i >= ZKATAn - 3) {
cc = (ZKATA1 << 8) + (ZKATAF2 + i + 1);
} else {
cc = (ZHIRA1 << 8) + (ZHIRAF2 + i);
if(c == KANA_WA)
cc++;
}
break;
}
}
if(i >= ZKATAn) {
for(i = 0; i < 8; i++) {
if(c == HKKtbl[i].han) {
cc = HKKtbl[i].zen;
break;
}
}
if(i >= 8)
cc = ZEN_SPACE;
}
} else {
if(c >= 0x20 && c <= 0x7e)
cc = HZtbl[c - 0x20];
else
cc = c;
}
return (cc);
}
int sj4_hantozen(u_char* out, u_char* in) {
wchar16_t *winstr, *woutstr;
u_char* mstr;
int inlen, outlen, imflag = 0, omflag = 0, mmflag = 0, ret;
inlen = strlen(in) + 1;
if(current_locale == LC_CTYPE_EUC) {
if(inlen > sizeof(mtmp)) {
mstr = (u_char*)malloc(inlen);
mmflag = 1;
} else {
mstr = mtmp;
}
if(sjistoeuc(mstr, inlen, in, inlen) < 0) {
if(mmflag) free(mstr);
return -1;
}
} else {
mstr = in;
}
if((inlen * sizeof(wchar16_t)) > sizeof(intmp)) {
winstr = (wchar16_t*)malloc(inlen * sizeof(wchar16_t));
if(!winstr) {
if(mmflag) free(mstr);
return -1;
}
imflag = 1;
} else {
winstr = (wchar16_t*)intmp;
}
if(mbstowcs(winstr, (char*)mstr, inlen) == -1) {
if(mmflag) free(mstr);
if(imflag) free(winstr);
return -1;
}
outlen = inlen;
if((outlen * sizeof(wchar16_t)) > sizeof(outtmp)) {
woutstr = (wchar16_t*)malloc(outlen * sizeof(wchar16_t));
if(!woutstr) {
if(mmflag) free(mstr);
if(imflag) free(winstr);
return -1;
}
omflag = 1;
} else {
woutstr = (wchar16_t*)outtmp;
}
ret = sj4_hantozen_w16(woutstr, winstr);
if(mmflag) {
free(mstr);
mmflag = 0;
}
if(ret == 0 || ret == -1) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
return ret;
}
outlen = ret * 3;
if(outlen > sizeof(mtmp)) {
mstr = (u_char*)malloc(outlen);
if(!mstr) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
return -1;
}
mmflag = 1;
} else {
mstr = mtmp;
}
if(wcstombs((char*)mstr, woutstr, outlen) == -1) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
if(mmflag) free(mstr);
return -1;
}
if(current_locale == LC_CTYPE_EUC) {
inlen = euctosjis(out, outlen, mstr, outlen);
} else {
(void)memcpy(out, mstr, strlen(mstr) + 1);
}
if(imflag) free(winstr);
if(omflag) free(woutstr);
if(mmflag) free(mstr);
if(inlen > 0) {
return ret;
} else {
return inlen;
}
}
int sj4_hantozen_euc(u_char* out, u_char* in) {
wchar16_t *winstr, *woutstr;
u_char* mstr;
int inlen, outlen, imflag = 0, omflag = 0, mmflag = 0, ret;
inlen = strlen(in) + 1;
if(current_locale == LC_CTYPE_EUC) {
mstr = in;
} else {
if(inlen > sizeof(mtmp)) {
mstr = (u_char*)malloc(inlen);
mmflag = 1;
} else {
mstr = mtmp;
}
if(euctosjis(mstr, inlen, in, inlen) < 0) {
if(mmflag) free(mstr);
return -1;
}
}
if((inlen * sizeof(wchar16_t)) > sizeof(intmp)) {
winstr = (wchar16_t*)malloc(inlen * sizeof(wchar16_t));
if(!winstr) {
if(mmflag) free(mstr);
return -1;
}
imflag = 1;
} else {
winstr = (wchar16_t*)intmp;
}
if(mbstowcs(winstr, (char*)mstr, inlen) == -1) {
if(mmflag) free(mstr);
if(imflag) free(winstr);
return -1;
}
outlen = inlen;
if((outlen * sizeof(wchar16_t)) > sizeof(outtmp)) {
woutstr = (wchar16_t*)malloc(outlen * sizeof(wchar16_t));
if(!woutstr) {
if(mmflag) free(mstr);
if(imflag) free(winstr);
return -1;
}
omflag = 1;
} else {
woutstr = (wchar16_t*)outtmp;
}
ret = sj4_hantozen_w16(woutstr, winstr);
if(mmflag) {
free(mstr);
mmflag = 0;
}
if(ret == 0 || ret == -1) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
return ret;
}
outlen = ret * 3;
if(outlen > sizeof(mtmp)) {
mstr = (u_char*)malloc(outlen);
if(!mstr) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
return -1;
}
mmflag = 1;
} else {
mstr = mtmp;
}
if(wcstombs((char*)mstr, woutstr, outlen) == -1) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
if(mmflag) free(mstr);
return -1;
}
if(current_locale == LC_CTYPE_EUC) {
(void)memcpy(out, mstr, strlen(mstr) + 1);
} else {
inlen = sjistoeuc(out, outlen, mstr, outlen);
}
if(imflag) free(winstr);
if(omflag) free(woutstr);
if(mmflag) free(mstr);
if(inlen > 0) {
return ret;
} else {
return inlen;
}
}
int sj4_hantozen_mb(u_char* s1, u_char* s2) {
if(current_locale == LC_CTYPE_EUC)
return sj4_hantozen_euc(s1, s2);
else
return sj4_hantozen(s1, s2);
}
int sj4_hantozen_w16(wchar16_t* s1, wchar16_t* s2) {
return sj_hantozen(s1, s2, wslen(s2));
}
int sj_hantozen(wchar16_t* s1, wchar16_t* s2, int len) {
u_short c1, cc, prefix;
wchar16_t c;
int i;
int rlen;
prefix = 0;
rlen = 0;
for(i = 0; i < len && *s2 != '\0'; i++) {
c = *s2++;
cc = sj_han2zen(c);
if(cc & RKZEN) {
if(prefix != 0 && (c1 = sj_addten(prefix, cc)) != 0) {
s1 -= 1;
rlen -= 1;
cc = c1;
prefix = 0;
} else
prefix = cc;
*s1++ = cc;
rlen++;
} else {
*s1++ = cc;
rlen++;
prefix = 0;
}
}
*s1 = '\0';
return (rlen);
}
int sj_zen2han(u_short c) {
int i;
u_short cc;
i = ZKATAn;
cc = c & MASK;
if(sj_ishira(c))
i = cc - ZHIRAF2;
else if(sj_iskata(c)) {
i = cc - ZKATAF2;
}
if(i < ZKATAn)
cc = HKtable[i];
else {
for(i = 0; i < 8; i++) {
if(c == HKKtbl[i].zen) {
cc = HKKtbl[i].han;
break;
}
}
if(i >= 8) {
cc = c;
for(i = 0; i < 95; i++) {
if(c == HZtbl[i]) {
cc = i + 0x20;
break;
}
}
}
}
return (cc);
}
int sj4_zentohan(u_char* out, u_char* in) {
wchar16_t *winstr, *woutstr;
u_char* mstr;
int inlen, outlen, imflag = 0, omflag = 0, mmflag = 0, ret;
inlen = strlen(in) + 1;
if(inlen > sizeof(mtmp)) {
mstr = (u_char*)malloc(inlen);
if(!mstr) {
return -1;
}
mmflag = 1;
} else {
mstr = mtmp;
}
if(current_locale == LC_CTYPE_EUC) {
(void)euctosjis(mstr, inlen, in, inlen);
} else {
(void)memcpy(mstr, in, inlen);
}
if(inlen > sizeof(intmp)) {
winstr = (wchar16_t*)malloc(((inlen / 2) + 1) * sizeof(wchar16_t));
if(!winstr) {
if(mmflag) free(mstr);
return -1;
}
imflag = 1;
} else {
winstr = (wchar16_t*)intmp;
}
if(mbstowcs(winstr, (char*)mstr, inlen) == -1) {
if(mmflag) free(mstr);
if(imflag) free(winstr);
return -1;
}
if(mmflag) {
free(mstr);
mmflag = 0;
}
outlen = ((inlen - 1) / 2) + 1;
if(outlen * sizeof(wchar16_t) > sizeof(outtmp)) {
woutstr = (wchar16_t*)malloc(outlen * sizeof(wchar16_t));
if(!woutstr) {
if(imflag) free(winstr);
return -1;
}
omflag = 1;
} else {
woutstr = (wchar16_t*)outtmp;
}
ret = sj4_zentohan_w16(woutstr, winstr);
if(ret == 0 || ret == -1) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
return ret;
}
outlen = ret * 3;
if(current_locale == LC_CTYPE_EUC) {
if(outlen > sizeof(mtmp)) {
mstr = (u_char*)malloc(outlen);
mmflag = 1;
} else {
mstr = mtmp;
}
} else {
mstr = out;
}
if(wcstombs((char*)mstr, woutstr, outlen) == -1) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
return -1;
}
if(current_locale == LC_CTYPE_EUC) {
if(euctosjis(out, outlen, mstr, outlen) < 0) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
if(mmflag) free(mstr);
return -1;
}
}
if(imflag) free(winstr);
if(omflag) free(woutstr);
if(mmflag) free(mstr);
return ret;
}
int sj4_zentohan_euc(u_char* out, u_char* in) {
wchar16_t *winstr, *woutstr;
u_char* mstr;
int inlen, outlen, imflag = 0, omflag = 0, mmflag = 0, ret;
inlen = strlen(in) + 1;
if(inlen > sizeof(mtmp)) {
mstr = (u_char*)malloc(inlen);
if(!mstr) {
return -1;
}
mmflag = 1;
} else {
mstr = mtmp;
}
if(current_locale == LC_CTYPE_EUC) {
(void)euctosjis(mstr, inlen, in, inlen);
} else {
(void)memcpy(mstr, in, inlen);
}
if(inlen > sizeof(intmp)) {
winstr = (wchar16_t*)malloc(((inlen / 2) + 1) * sizeof(wchar16_t));
if(!winstr) {
if(mmflag) free(mstr);
return -1;
}
imflag = 1;
} else {
winstr = (wchar16_t*)intmp;
}
if(mbstowcs(winstr, (char*)mstr, inlen) == -1) {
if(mmflag) free(mstr);
if(imflag) free(winstr);
return -1;
}
if(mmflag) {
free(mstr);
mmflag = 0;
}
outlen = ((inlen - 1) / 2) + 1;
if(outlen * sizeof(wchar16_t) > sizeof(outtmp)) {
woutstr = (wchar16_t*)malloc(outlen * sizeof(wchar16_t));
if(!woutstr) {
if(mmflag) free(mstr);
if(imflag) free(winstr);
return -1;
}
omflag = 1;
} else {
woutstr = (wchar16_t*)outtmp;
}
ret = sj4_zentohan_w16(woutstr, winstr);
if(ret == 0 || ret == -1) {
if(mmflag) free(mstr);
if(imflag) free(winstr);
if(omflag) free(woutstr);
return ret;
}
outlen = ret * 3;
if(current_locale == LC_CTYPE_EUC) {
mstr = out;
} else {
if(outlen > sizeof(mtmp)) {
mstr = (u_char*)malloc(outlen);
mmflag = 1;
} else {
mstr = mtmp;
}
}
if(wcstombs((char*)mstr, woutstr, outlen) == -1) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
return -1;
}
if(current_locale == LC_CTYPE_SHIFTJIS) {
if(sjistoeuc(out, outlen, mstr, outlen) < 0) {
if(imflag) free(winstr);
if(omflag) free(woutstr);
if(mmflag) free(mstr);
return -1;
}
}
if(imflag) free(winstr);
if(omflag) free(woutstr);
if(mmflag) free(mstr);
return ret;
}
int sj4_zentohan_mb(u_char* s1, u_char* s2) {
if(current_locale == LC_CTYPE_EUC)
return sj4_zentohan_euc(s1, s2);
else
return sj4_zentohan(s1, s2);
}
int sj4_zentohan_w16(wchar16_t* s1, wchar16_t* s2) {
return sj_zentohan(s1, s2, wslen(s2));
}
int sj_zentohan(wchar16_t* s1, wchar16_t* s2, int len) {
u_short cc;
wchar16_t c;
int i, rlen;
rlen = 0;
for(i = 0; i < len && *s2 != (wchar16_t)'\0'; i++) {
c = *s2++;
if(WcIsZENKAKU(c)) {
cc = sj_zen2han(c);
if((cc >> 8) && (cc != c)) {
*s1++ = (cc >> 8);
rlen++;
*s1++ = cc & 0xff;
rlen++;
continue;
}
} else
cc = c;
if(cc & RKZEN) {
*s1++ = (cc >> 8);
rlen++;
}
*s1++ = (wchar16_t)cc;
rlen++;
}
*s1 = (wchar16_t)'\0';
return (rlen);
}
int sj_tokata(wchar16_t c) {
if(sj_ishira(c)) {
c += 0x0100;
}
return (c);
}
int sj_tohira(wchar16_t c) {
if(sj_iskata(c) && (short)c <= (short)0xa5f3) {
c -= 0x0100;
}
return (c);
}
int sj_htok(wchar16_t* s1, wchar16_t* s2) {
wchar16_t cc;
wchar16_t c;
while((c = *s2++) != (wchar16_t)'\0') {
if(WcIsX0208(c)) {
cc = sj_tokata(c);
*s1++ = cc;
} else
*s1++ = c;
}
*s1 = (wchar16_t)'\0';
return 0;
}
int sj_ktoh(wchar16_t* s1, wchar16_t* s2) {
wchar16_t cc;
wchar16_t c;
while((c = *s2++) != (wchar16_t)'\0') {
if(WcIsX0208(c)) {
cc = sj_tohira(c);
*s1++ = cc;
} else
*s1++ = c;
}
*s1 = (wchar16_t)'\0';
return 0;
}