537 lines
10 KiB
C
537 lines
10 KiB
C
/*
|
|
* Copyright (c) 1991-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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include "sj_struct.h"
|
|
#include "dicttool.h"
|
|
|
|
#ifndef SS2
|
|
#define SS2 0x8e
|
|
#endif
|
|
|
|
extern DouonRec* douon_ptr;
|
|
extern int douon_num;
|
|
extern int yomi_len;
|
|
extern int hinshi_num;
|
|
extern int kanji_len;
|
|
extern HindoRec* hindo[];
|
|
extern int hindo_num;
|
|
extern HindoRec* askknj[];
|
|
extern int askknj_num;
|
|
extern HindoRec* asshuku;
|
|
|
|
static DouonRec* drectmp = NULL;
|
|
|
|
static void
|
|
clearklist(KanjiRec* krec) {
|
|
KanjiRec* p;
|
|
|
|
while(krec) {
|
|
|
|
Free(krec->kptr);
|
|
Free(krec->aptr);
|
|
|
|
p = krec;
|
|
krec = krec->knext;
|
|
|
|
Free(p);
|
|
}
|
|
}
|
|
|
|
static void
|
|
clearhlist(HinshiRec* hrec) {
|
|
HinshiRec* p;
|
|
|
|
while(hrec) {
|
|
|
|
clearklist(hrec->krec);
|
|
|
|
p = hrec;
|
|
hrec = hrec->hnext;
|
|
|
|
Free(p);
|
|
}
|
|
}
|
|
|
|
void clear_list(void) {
|
|
DouonRec* p;
|
|
DouonRec* drec = douon_ptr;
|
|
|
|
while(drec) {
|
|
|
|
Free(drec->yptr);
|
|
|
|
clearhlist(drec->hrec);
|
|
|
|
p = drec;
|
|
drec = drec->dnext;
|
|
|
|
Free(p);
|
|
}
|
|
|
|
douon_ptr = NULL;
|
|
}
|
|
|
|
static unsigned char*
|
|
makekanji(int* yomi, int* kanji, int* atr, int* len) {
|
|
int kana[MaxYomiLength + 1];
|
|
unsigned char ktmp[MaxKanjiLength * 3 + MaxAtrNumber * 2 + 1];
|
|
int i;
|
|
int pos = 0;
|
|
int* p;
|
|
unsigned char* q;
|
|
|
|
for(p = yomi, i = 0; *p;)
|
|
kana[i++] = h2kcode(*p++);
|
|
kana[i] = 0;
|
|
|
|
while(*atr) {
|
|
i = *atr;
|
|
atr++;
|
|
#ifndef NO_ATR
|
|
ktmp[pos++] = (AiAttribute | ((i >> 8) & 0xff));
|
|
ktmp[pos++] = (i & 0xff);
|
|
#endif
|
|
}
|
|
|
|
if((i = top_strcmp(yomi, kanji)) != 0) {
|
|
kanji += i;
|
|
ktmp[pos++] = (ZenHiraAsshuku | (i - 1));
|
|
}
|
|
|
|
else if((i = top_strcmp(kana, kanji)) != 0) {
|
|
kanji += i;
|
|
ktmp[pos++] = (ZenKataAsshuku | (i - 1));
|
|
}
|
|
|
|
while(*kanji) {
|
|
|
|
if((i = last_strcmp(yomi, kanji)) != 0) {
|
|
kanji += i;
|
|
ktmp[pos++] = (ZenHiraAsshuku | (i - 1));
|
|
}
|
|
|
|
else if((i = last_strcmp(kana, kanji)) != 0) {
|
|
kanji += i;
|
|
ktmp[pos++] = (ZenKataAsshuku | (i - 1));
|
|
}
|
|
|
|
else if(((*kanji >> 8) & 0xff) == SS2 || *kanji < 0x100) {
|
|
ktmp[pos] = LeadingHankaku;
|
|
ktmp[pos + 1] = (*kanji & 0xff);
|
|
kanji++;
|
|
pos += 2;
|
|
}
|
|
|
|
else {
|
|
if(*kanji < 0x10000) {
|
|
ktmp[pos] = ((*kanji >> 8) & NormalKanjiMask);
|
|
ktmp[pos + 1] = (*kanji & NormalKanjiMask);
|
|
kanji++;
|
|
pos += 2;
|
|
} else if(*kanji < 0x1000000) {
|
|
ktmp[pos] = ((*kanji >> 8) & NormalKanjiMask);
|
|
ktmp[pos + 1] = (*kanji & 0xff);
|
|
kanji++;
|
|
pos += 2;
|
|
} else {
|
|
fprintf(stderr, "Error: 4 byte code is found\n");
|
|
exit(0);
|
|
}
|
|
}
|
|
}
|
|
*len = pos;
|
|
|
|
q = (unsigned char*)Malloc(pos);
|
|
if(!q) {
|
|
fprintf(stderr, "\245\341\245\342\245\352\244\254\311\324\302\255\244\267\244\336\244\267\244\277");
|
|
exit(1);
|
|
}
|
|
memcpy(q, ktmp, pos);
|
|
|
|
return q;
|
|
}
|
|
|
|
static unsigned char*
|
|
makeyomi(int* yomi) {
|
|
unsigned char tmp[MaxYomiLength + 1];
|
|
int i;
|
|
int j;
|
|
int* y = yomi;
|
|
unsigned char* p;
|
|
|
|
for(i = 0; *y;) {
|
|
j = cnvyomi(*y++);
|
|
if(j == 0) {
|
|
fprintf(stderr, "\311\324\300\265\244\312\312\270\273\372\244\254\306\311\244\337\244\313\273\310\244\357\244\354\244\306\244\244\244\336\244\271\n");
|
|
output_int(stderr, yomi);
|
|
fputc('\n', stderr);
|
|
exit(1);
|
|
}
|
|
tmp[i++] = j;
|
|
}
|
|
tmp[i++] = 0;
|
|
|
|
p = (unsigned char*)Malloc(i);
|
|
if(!p) {
|
|
fprintf(stderr, "\245\341\245\342\245\352\244\254\311\324\302\255\244\267\244\336\244\267\244\277");
|
|
exit(1);
|
|
}
|
|
memcpy(p, tmp, i);
|
|
|
|
return p;
|
|
}
|
|
|
|
static KanjiRec*
|
|
make_krec(unsigned char* kcode, int klen) {
|
|
KanjiRec* krec;
|
|
|
|
krec = (KanjiRec*)Malloc(sizeof(KanjiRec));
|
|
if(!krec) {
|
|
fprintf(stderr, "\245\341\245\342\245\352\244\254\311\324\302\255\244\267\244\336\244\267\244\277");
|
|
exit(1);
|
|
}
|
|
|
|
krec->klen = klen;
|
|
krec->kptr = kcode;
|
|
krec->alen = 0;
|
|
krec->aptr = NULL;
|
|
krec->knext = NULL;
|
|
|
|
return krec;
|
|
}
|
|
|
|
static HinshiRec*
|
|
make_hrec(int hinshi) {
|
|
HinshiRec* hrec;
|
|
|
|
hrec = (HinshiRec*)Malloc(sizeof(HinshiRec));
|
|
if(!hrec) {
|
|
fprintf(stderr, "\245\341\245\342\245\352\244\254\311\324\302\255\244\267\244\336\244\267\244\277");
|
|
exit(1);
|
|
}
|
|
|
|
hrec->hinshi = hinshi;
|
|
hrec->krec = NULL;
|
|
hrec->hnext = NULL;
|
|
|
|
return hrec;
|
|
}
|
|
|
|
static DouonRec*
|
|
make_drec(unsigned char* ycode) {
|
|
DouonRec* drec;
|
|
|
|
drec = (DouonRec*)Malloc(sizeof(DouonRec));
|
|
if(!drec) {
|
|
fprintf(stderr, "\245\341\245\342\245\352\244\254\311\324\302\255\244\267\244\336\244\267\244\277");
|
|
exit(1);
|
|
}
|
|
|
|
drec->yptr = ycode;
|
|
drec->hrec_num = 0;
|
|
drec->hrec = NULL;
|
|
drec->dnext = NULL;
|
|
|
|
return drec;
|
|
}
|
|
|
|
static int
|
|
diff_ylen(DouonRec* drec) {
|
|
DouonRec* dptr;
|
|
DouonRec* dprev;
|
|
unsigned char* p1;
|
|
unsigned char* p2;
|
|
int ylen = 0;
|
|
|
|
dptr = douon_ptr;
|
|
dprev = NULL;
|
|
while(dptr) {
|
|
dprev = dptr;
|
|
dptr = dptr->dnext;
|
|
}
|
|
|
|
if(dprev) {
|
|
|
|
p1 = dprev->yptr;
|
|
p2 = drec->yptr;
|
|
while(*p1 && (*p1 == *p2)) {
|
|
p1++;
|
|
p2++;
|
|
}
|
|
|
|
if(*p1 == *p2) {
|
|
fprintf(stderr, "\305\371\244\267\244\244\306\311\244\337\244\316\306\261\262\273\270\354\245\326\245\355\245\303\245\257\244\254\244\242\244\353\n");
|
|
output_yomi(stderr, dprev->yptr);
|
|
fputc('\n', stderr);
|
|
exit(1);
|
|
}
|
|
|
|
else if(*p1 > *p2) {
|
|
fprintf(stderr, "\306\311\244\337\244\316\275\347\275\370\244\254\244\252\244\253\244\267\244\244\n");
|
|
output_yomi(stderr, dprev->yptr);
|
|
fputc('\n', stderr);
|
|
output_yomi(stderr, drec->yptr);
|
|
fputc('\n', stderr);
|
|
exit(1);
|
|
}
|
|
|
|
while(*p2++) ylen++;
|
|
}
|
|
|
|
return ylen;
|
|
}
|
|
|
|
static int
|
|
douon_knj(DouonRec* drec) {
|
|
int i;
|
|
int len = 0;
|
|
unsigned char* p;
|
|
unsigned char* knjofscvt();
|
|
HinshiRec* hrec;
|
|
KanjiRec* krec;
|
|
|
|
for(hrec = drec->hrec; hrec; hrec = hrec->hnext) {
|
|
|
|
for(krec = hrec->krec; krec; krec = krec->knext) {
|
|
|
|
p = knjofscvt(krec->kptr, krec->klen, &i);
|
|
|
|
len += i + 1;
|
|
|
|
knjhnd_set(p, i);
|
|
|
|
krec->alen = i;
|
|
krec->aptr = p;
|
|
|
|
set_ofsrec(krec->kptr, krec->klen, 0);
|
|
}
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
static void
|
|
make_d_list(DouonRec* drec) {
|
|
DouonRec *dptr, *dprev;
|
|
HinshiRec* hptr;
|
|
KanjiRec* kptr;
|
|
int ylen;
|
|
int klen;
|
|
int hnum;
|
|
int len;
|
|
int i;
|
|
|
|
start:
|
|
|
|
if(douon_ptr == NULL) {
|
|
douon_num = 0;
|
|
yomi_len = 0;
|
|
hinshi_num = 0;
|
|
kanji_len = 0;
|
|
asshuku = NULL;
|
|
}
|
|
|
|
klen = douon_knj(drec);
|
|
|
|
ylen = diff_ylen(drec);
|
|
|
|
hnum = drec->hrec_num;
|
|
|
|
i = 1 +
|
|
MaxKnjAskNumber +
|
|
|
|
douon_num * DouonBlkSizeNumber + DouonBlkSizeNumber +
|
|
yomi_len + ylen +
|
|
hinshi_num + hnum +
|
|
hinshi_num + hnum +
|
|
kanji_len + klen;
|
|
|
|
len = (i <= MainSegmentLength) ? 0 : decide_knjask();
|
|
|
|
if((i - len) <= MainSegmentLength) {
|
|
|
|
if(douon_ptr) {
|
|
|
|
dptr = douon_ptr;
|
|
dprev = NULL;
|
|
while(dptr) {
|
|
dprev = dptr;
|
|
dptr = dptr->dnext;
|
|
}
|
|
|
|
dprev->dnext = drec;
|
|
}
|
|
|
|
else {
|
|
|
|
douon_ptr = drec;
|
|
}
|
|
drec->dnext = NULL;
|
|
|
|
drec->dlen = ylen;
|
|
|
|
douon_num += 1;
|
|
|
|
yomi_len += ylen;
|
|
|
|
hinshi_num += hnum;
|
|
|
|
kanji_len += klen;
|
|
|
|
return;
|
|
}
|
|
|
|
else if(douon_ptr == NULL) {
|
|
fprintf(stderr, "\243\261\306\261\262\273\270\354\245\326\245\355\245\303\245\257\244\254\302\347\244\255\244\271\244\256\244\336\244\271\n");
|
|
exit(1);
|
|
}
|
|
|
|
for(hptr = drec->hrec; hptr; hptr = hptr->hnext) {
|
|
for(kptr = hptr->krec; kptr; kptr = kptr->knext) {
|
|
|
|
knjhnd_reset(kptr->aptr, kptr->alen);
|
|
|
|
Free(kptr->aptr);
|
|
kptr->aptr = NULL;
|
|
}
|
|
}
|
|
|
|
len = decide_knjask();
|
|
|
|
makeseg();
|
|
|
|
clear_list();
|
|
|
|
clear_hindo();
|
|
|
|
clear_ofsrec();
|
|
|
|
askknj_num = 0;
|
|
|
|
clear_asshuku();
|
|
|
|
goto start;
|
|
}
|
|
|
|
void flush_douon(void) {
|
|
if(drectmp) {
|
|
|
|
make_d_list(drectmp);
|
|
|
|
drectmp = NULL;
|
|
}
|
|
|
|
if(douon_ptr) {
|
|
|
|
decide_knjask();
|
|
|
|
makeseg();
|
|
|
|
clear_list();
|
|
|
|
clear_hindo();
|
|
|
|
clear_ofsrec();
|
|
|
|
askknj_num = 0;
|
|
}
|
|
}
|
|
|
|
void makelist(int* yomi, int* kanji, int hinshi, int* atr) {
|
|
unsigned char* ycode;
|
|
unsigned char* kcode;
|
|
int klen;
|
|
HinshiRec* hrec;
|
|
KanjiRec * krec, *kprev;
|
|
|
|
ycode = makeyomi(yomi);
|
|
|
|
kcode = makekanji(yomi, kanji, atr, &klen);
|
|
|
|
if(drectmp && strcmp(ycode, drectmp->yptr)) {
|
|
|
|
make_d_list(drectmp);
|
|
|
|
drectmp = NULL;
|
|
}
|
|
|
|
if(!drectmp) {
|
|
|
|
drectmp = make_drec(ycode);
|
|
|
|
hrec = make_hrec(hinshi);
|
|
drectmp->hrec = hrec;
|
|
drectmp->hrec_num = 1;
|
|
|
|
krec = make_krec(kcode, klen);
|
|
hrec->krec = krec;
|
|
|
|
return;
|
|
}
|
|
|
|
for(hrec = drectmp->hrec; hrec->hnext; hrec = hrec->hnext)
|
|
if(hrec->hinshi == hinshi) break;
|
|
|
|
if(hrec->hinshi == hinshi) {
|
|
|
|
for(krec = hrec->krec; krec; krec = krec->knext) {
|
|
|
|
if((krec->klen == klen) &&
|
|
!memcmp(krec->kptr, kcode, klen)) {
|
|
fprintf(stderr, "\306\261\260\354\244\316\275\317\270\354\244\254\302\270\272\337\244\267\244\277\n");
|
|
fprintf(stderr, "\t\306\311\244\337:");
|
|
output_int(stderr, yomi);
|
|
fprintf(stderr, "\n");
|
|
fprintf(stderr, "\t\264\301\273\372:");
|
|
output_int(stderr, kanji);
|
|
fprintf(stderr, "\n");
|
|
|
|
Free(kcode);
|
|
|
|
return;
|
|
}
|
|
kprev = krec;
|
|
}
|
|
|
|
kprev->knext = make_krec(kcode, klen);
|
|
|
|
return;
|
|
}
|
|
|
|
hrec->hnext = make_hrec(hinshi);
|
|
hrec = hrec->hnext;
|
|
drectmp->hrec_num += 1;
|
|
|
|
krec = make_krec(kcode, klen);
|
|
hrec->krec = krec;
|
|
}
|