/* * 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 #include #include #include "sj_struct.h" #include "dicttool.h" extern HindoRec* hindo[]; extern int hindo_num; extern AsshukuRec* asshuku; extern HindoRec* askknj[]; extern int askknj_num; extern int kanji_num; int check_hindo(unsigned char* ptr, int len) { int low, high, mid; int i; if(hindo_num <= 0) return 0; low = 0; high = hindo_num - 1; while(low <= high) { mid = (low + high) / 2; i = string_cmp(hindo[mid]->kptr, hindo[mid]->klen, ptr, len); if(i > 0) high = mid - 1; else if(i < 0) low = ++mid; else return (hindo[mid]->exist + hindo[mid]->hindo); } return 0; } static AsshukuRec* makeasshuku(int num) { AsshukuRec* arec; arec = (AsshukuRec*)Malloc(sizeof(AsshukuRec)); if(!arec) { fprintf(stderr, "\245\341\245\342\245\352\244\254\302\255\244\352\244\336\244\273\244\363\n"); exit(1); } arec->len = num; arec->nrec = NULL; arec->anext = NULL; return arec; } static int asshuku_len(HindoRec* hrec) { int org; int old; int new; OffsetRec* p; if(((*(hrec->kptr) & KanjiModeMask) == OffsetAsshuku) && (hrec->klen == 2)) { p = real_ofsrec(hrec->kptr); org = check_hindo(p->kptr, p->klen); old = p->klen * org + 2 * (hrec->exist + hrec->hindo); new = p->klen + (hrec->exist + hrec->hindo + org); } else { old = hrec->klen * (hrec->exist + hrec->hindo); new = hrec->klen + (hrec->exist + hrec->hindo); } return (old - new); } static void set_asshuku(HindoRec* hrec) { AsshukuRec* arec; AsshukuRec* aprev; int len; len = asshuku_len(hrec); if(len <= 0) return; arec = asshuku; aprev = NULL; while(arec) { if(arec->len == len) { hrec->arec = arec; hrec->anext = arec->nrec; arec->nrec = hrec; return; } else if(arec->len < len) break; aprev = arec; arec = arec->anext; } arec = makeasshuku(len); hrec->anext = NULL; hrec->arec = arec; arec->nrec = hrec; if(aprev) { arec->anext = aprev->anext; aprev->anext = arec; } else { arec->anext = asshuku; asshuku = arec; } } static void reset_asshuku(HindoRec* hrec) { AsshukuRec* arec; AsshukuRec* aptr; AsshukuRec* aprev; HindoRec* hptr; HindoRec* hprev; arec = hrec->arec; if(!arec) return; hrec->arec = NULL; hptr = arec->nrec; hprev = NULL; while(hptr) { if(hptr == hrec) break; hprev = hptr; hptr = hptr->anext; } if(!hptr) return; if(hprev) { hprev->anext = hrec->anext; hrec->anext = NULL; return; } if(hrec->anext) { arec->nrec = hrec->anext; hrec->anext = NULL; return; } if(!asshuku) return; aptr = asshuku; aprev = NULL; while(aptr) { if(aptr == arec) break; aprev = aptr; aptr = aptr->anext; } if(!aptr) return; if(aprev) aprev->anext = arec->anext; else asshuku = arec->anext; Free(arec); hrec->anext = NULL; } static HindoRec* makehindo(unsigned char* ptr, int len, int alen) { HindoRec* hrec; unsigned char* p; hrec = (HindoRec*)Malloc(sizeof(HindoRec)); if(!hrec) { fprintf(stderr, "\245\341\245\342\245\352\244\254\302\255\244\352\244\336\244\273\244\363\n"); exit(1); } p = (unsigned char*)Malloc(len); if(!p) { fprintf(stderr, "\245\341\245\342\245\352\244\254\302\255\244\352\244\336\244\273\244\363\n"); exit(1); } hrec->klen = len; hrec->kptr = p; if(len == alen && len > 2) { hrec->hindo = 0; hrec->exist = 1; hrec->offset = ++kanji_num; } else { hrec->hindo = 1; hrec->exist = 0; hrec->offset = 0; } while(len-- > 0) *p++ = *ptr++; hrec->anext = NULL; hrec->arec = NULL; return hrec; } static void set_hindo(unsigned char* ptr, int len, int alen) { HindoRec* hrec; int low, high, mid; int i; if(hindo_num <= 0) { hrec = makehindo(ptr, len, alen); hindo[0] = hrec; hindo_num = 1; set_asshuku(hrec); return; } low = 0; high = hindo_num - 1; while(low <= high) { mid = (low + high) / 2; i = string_cmp(hindo[mid]->kptr, hindo[mid]->klen, ptr, len); if(i > 0) high = mid - 1; else if(i < 0) low = ++mid; else break; } if(i) { if(hindo_num >= MaxHindoNumber) { fprintf(stderr, "\311\321\305\331\245\306\241\274\245\326\245\353\244\254\244\242\244\325\244\354\244\336\244\267\244\277\n"); exit(1); } hrec = makehindo(ptr, len, alen); for(i = hindo_num; i > mid; i--) hindo[i] = hindo[i - 1]; hindo[mid] = hrec; hindo_num++; } else { hrec = hindo[mid]; reset_asshuku(hrec); if(hrec->exist > 0) hrec->exist += 1; else if(len == alen && len > 2) { hrec->exist = 1; hrec->offset = ++kanji_num; } else hrec->hindo += 1; } set_asshuku(hrec); } static void reset_hindo(unsigned char* p, int l) { HindoRec* hrec; int low, high, mid; int i; if(hindo_num <= 0) return; low = 0; high = hindo_num - 1; while(low <= high) { mid = (low + high) / 2; i = string_cmp(hindo[mid]->kptr, hindo[mid]->klen, p, l); if(i > 0) high = mid - 1; else if(i < 0) low = ++mid; else { hrec = hindo[mid]; reset_asshuku(hrec); if(hrec->exist > 0) hrec->exist -= 1; else if(hrec->hindo > 0) hrec->hindo -= 1; if(hrec->exist + hrec->hindo == 0) { while(++mid < hindo_num) { hindo[mid - 1] = hindo[mid]; } hindo_num--; Free(hrec->kptr); Free(hrec); } else { set_asshuku(hrec); } return; break; } } } void knjhnd_set(unsigned char* p, int l) { unsigned char* kp1; unsigned char* kp2; int i; int kl1; unsigned char tmp[MaxKanjiLength * 2 + MaxAtrNumber * 2 + 1]; for(kp1 = p, kl1 = l; kl1 > 0;) { for(i = 0, kp2 = kp1; i < kl1;) { if(codesize(*kp2) == 1) { tmp[i++] = *kp2++; } else if(codesize(*kp2) == 2) { tmp[i++] = *kp2++; tmp[i++] = *kp2++; } else { tmp[i++] = *kp2++; tmp[i++] = *kp2++; tmp[i++] = *kp2++; } set_hindo(tmp, i, l); } kl1 -= codesize(*kp1); kp1 += codesize(*kp1); } } void knjhnd_reset(unsigned char* p, int l) { unsigned char* kp1; unsigned char* kp2; int i; int kl1; unsigned char tmp[MaxKanjiLength * 2 + MaxAtrNumber * 2 + 1]; for(kp1 = p, kl1 = l; kl1 > 0;) { for(i = 0, kp2 = kp1; i < kl1;) { if(codesize(*kp2) == 1) { tmp[i++] = *kp2++; } else if(codesize(*kp2) == 2) { tmp[i++] = *kp2++; tmp[i++] = *kp2++; } else { tmp[i++] = *kp2++; tmp[i++] = *kp2++; tmp[i++] = *kp2++; } reset_hindo(tmp, i); } kl1 -= codesize(*kp1); kp1 += codesize(*kp1); } } static int check_asshuku(HindoRec* p, HindoRec* q) { unsigned char ptmp[128], qtmp[128]; int plen; int qlen; plen = make_knjstr(p->kptr, p->klen, ptmp); qlen = make_knjstr(q->kptr, q->klen, qtmp); if(bubun_str(ptmp, plen, qtmp, qlen)) { return -1; } if(overlap_str(ptmp, plen, qtmp, qlen)) return -1; return 0; } int decide_knjask(void) { int i, j; AsshukuRec* p; HindoRec* q; unsigned char* r; int len = 0; askknj_num = 0; for(p = asshuku; p; p = p->anext) { if(p->len <= 0) break; for(q = p->nrec; q; q = q->anext) { i = q->klen; r = q->kptr; if(i > 2) { while(i > 0) { if((*r & KanjiModeMask) == OffsetAsshuku) { break; } j = codesize(*r); i -= j; r += j; } if(i) continue; } if(askknj_num) { for(i = 0; i < askknj_num; i++) { if(check_asshuku(askknj[i], q)) break; } if(i >= askknj_num) { askknj[askknj_num++] = q; len += p->len; if(askknj_num >= MaxKnjAskNumber) goto end; } } else { askknj[askknj_num++] = q; len += p->len; } } } end: { int i, j, len; unsigned char* p; for(i = 0; i < askknj_num; i++) { len = askknj[i]->klen; p = askknj[i]->kptr; if(len <= 2) continue; while(len > 0) { if((*p & KanjiModeMask) == OffsetAsshuku) { printf("\245\252\245\325\245\273\245\303\245\310\260\265\275\314\244\362\264\336\244\340 %d\n", i); } j = codesize(*p); len -= j; p += j; } } } return len; } void clear_hindo(void) { int i; for(i = 0; i < hindo_num; i++) { Free(hindo[i]->kptr); Free(hindo[i]); } hindo_num = 0; kanji_num = 0; } void clear_asshuku(void) { AsshukuRec* p; while(asshuku) { p = asshuku; asshuku = asshuku->anext; Free(p); } }