/* * 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. * */ /* * $SonyRCSfile: srchnum.c,v $ * $SonyRevision: 1.1 $ * $SonyDate: 1994/06/03 08:02:30 $ */ #include #include "sj_kcnv.h" #include "sj_yomi.h" #include "sj_hinsi.h" #include "sj_suuji.h" #include "sj_kanakan.h" static void srch_kurai1(), srch_kurai2(); static void srch_josuu_sub(JREC* jrec, TypeGram gram) { u_char* tagp; DICTL* dp; for(dp = dictlist; dp; dp = dp->next) { curdict = dp->dict; dicinl = 1; dicsaml = 0; prevseg = -1; while(tagp = srchdict(tagp)) setnumrec(tagp, jrec, gram); } } static void srch_josuu(JREC* jrec) { u_char* kp; int klen; int len; if(headcode && headcode != SETTOU_DAI) return; kp = cnvstart; klen = cnvlen; cnvstart += (len = jrec->numlen); cnvlen -= len; srch_josuu_sub(jrec, JOSUUSI); if(!headcode) srch_josuu_sub(jrec, JOSUUSI2); cnvstart = kp; cnvlen = klen; } static void setnrec_sub(u_char* p, u_short flag, int stb) { JREC* rec; int len1; int len2; len1 = len2 = p - suuji_yptr; if(headcode) len1 += headlen; if(stb) len2--; if((int)suuji_len == len2) { if(suuji_wkeep) { memcpy((u_char*)suuji_wkeep, (u_char*)suuji_wbuf, sizeof(suuji_wbuf[0]) * NUMWORDBUF); } if(suuji_ukeep) { memcpy(suuji_ukeep, suuji_ubuf, NUMKETALENGTH); } suuji_exit = suuji_keta; return; } if(rec = argjrec(len1, (JREC*)NULL)) { rec->class = suuji_class; rec->hinsi = SUUSI; rec->sttofs = headcode; rec->stbofs = (u_char)stb; rec->flags = flag; rec->numlen = (u_char)len2; if(!stb) srch_josuu(rec); } } static void setnrec(u_char* p, u_short flag) { setnrec_sub(p, flag, 0); if(!headcode && (*p == Y_S_KIGOU2)) { setnrec_sub(p + 1, flag, -1); } } static u_char* srchtbl(u_char ch, u_char* tbl, int rec, int n) { int high, low, mid; u_char* p; if(!ch) return NULL; low = 0; high = n - 1; while(low <= high) { mid = (low + high) / 2; p = tbl + mid * rec; if(ch == *p) break; else if(ch < *p) high = mid - 1; else low = mid + 1; } if(low > high) return NULL; while(mid-- > 0 && ch == *(p - rec)) p -= rec; return p; } static int isconnect(u_char* cnct, int num) { return (cnct[num / 8] & (0x80 >> (num % 8))); } static int string_cmp(u_char* s, int l, u_char* d) { u_char* p; p = s; while(*s && l-- > 0) { if(*s != *d) return 0; s++; d++; } return (s - p); } static int check_num(u_char* ptr) { int i; int j; int k; int tmp; int hketa; int lketa; int flg = FALSE; int cnt; u_short flag; memset((u_char*)suuji_wbuf, 0, sizeof(u_short) * NUMWORDBUF); flag = 0; hketa = lketa = cnt = 0; for(i = suuji_keta; --i >= 0;) { if(hketa >= 4) return FALSE; tmp = suuji_ubuf[i]; if(j = ((tmp >> 6) & 3)) { if(j < hketa) return FALSE; if(j > hketa) { flag |= JFLAG_N01; do { suuji_wbuf[hketa] |= (_NUM0 << (lketa * 4)); if(++lketa >= 4) { lketa = 0; hketa++; } } while(j > hketa); } } k = ((tmp >> 4) & 3); if(j || k) { if(k < lketa) return FALSE; if(k > lketa) { flag |= JFLAG_N01; do { suuji_wbuf[hketa] |= (_NUM0 << (lketa * 4)); lketa++; } while(k > lketa); } flg = TRUE; } tmp &= 0x0f; suuji_wbuf[hketa] |= (tmp << (lketa * 4)); cnt++; j = (1 << tmp); if(j & NUMBERS1) flag |= JFLAG_NS1; if(j & NUMBER01) flag |= JFLAG_N01; if(j & NUMBER23) flag |= JFLAG_N23; if(tmp != _NUM0) { flg = FALSE; switch(lketa) { case 0: if(tmp == _NUM1) flag |= JFLAG_N_1; break; case 1: flag |= JFLAG_N10; break; } } if(++lketa >= 4) { lketa = 0; hketa++; } } if(flg) return FALSE; if(suuji_keta == 1 || tmp != _NUM0) flag |= JFLAG_NN0; if(hketa) flag |= (JFLAG_NK4 | JFLAG_NK2); else if(lketa > 1) flag |= JFLAG_NK2; if(cnt > 1) flag |= JFLAG_NSN; setnrec(ptr, flag); return TRUE; } static void srch_number1(u_char* ptr) { u_char ch; u_char mode; u_char* p; int l; TypeClass cls; int len; u_char* tptr; if(suuji_keta >= NUMKETALENGTH) return; if(!(p = srchtbl((ch = *ptr), Suuji_tbl, SJTBLRECLEN, SJTBLRECNUM))) return; len = suuji_yptr + MAXCLINPUTLEN - ptr; for(; *SjTblYPos(p) == ch; p += SJTBLRECLEN) { if(!(l = string_cmp(SjTblYPos(p), SJTBLYLEN, ptr))) continue; if(l > len) continue; mode = *SjTblModeP(p); suuji_ubuf[suuji_keta++] = SjTblNumber(mode); tptr = ptr + l; switch(suuji_class) { case C_N_ARABIA: if(!(mode & SJTBLNARABIAF)) break; check_num(tptr); srch_number1(tptr); srch_kurai2(tptr, (u_char*)NULL); break; case C_N_SUUJI: if(mode & (SJTBLNARABIAF | SJTBLNYOMIF)) break; check_num(tptr); srch_number1(tptr); srch_kurai1(tptr, (u_char*)NULL); srch_kurai2(tptr, (u_char*)NULL); break; case C_N_KAZU: case C_N_NANSUU: if(mode & SJTBLNNARABIF) break; if(mode & SJTBLNNANSUUF) { cls = suuji_class; suuji_class = C_N_NANSUU; } check_num(tptr); srch_kurai1(tptr, SjTblCnctP(p)); srch_kurai2(tptr, SjTblCnctP(p)); if(mode & SJTBLNNANSUUF) suuji_class = cls; break; default: if(mode & SJTBLNARABIAF) { suuji_class = C_N_ARABIA; check_num(tptr); srch_number1(tptr); srch_kurai2(tptr, (u_char*)NULL); suuji_class = C_N_KAZU; } else if(mode & SJTBLNYOMIF) { if(mode & SJTBLNNANSUUF) suuji_class = C_N_NANSUU; else suuji_class = C_N_KAZU; check_num(tptr); } else if(mode & SJTBLNNARABIF) { suuji_class = C_N_SUUJI; check_num(tptr); srch_number1(tptr); break; } else { suuji_class = C_N_SUUJI; srch_number1(tptr); suuji_class = C_N_KAZU; check_num(tptr); } srch_kurai1(tptr, SjTblCnctP(p)); srch_kurai2(tptr, SjTblCnctP(p)); break; } suuji_keta--; } } static void srch_kurai1(u_char* ptr, u_char* cnct) { u_char ch; u_char* p; int l; int keta; int mode; TypeClass cls; int len; u_char* tptr; if(!(p = srchtbl((ch = *ptr), Kurai1_tbl, KR1TBLRECLEN, KR1TBLRECNUM))) return; len = suuji_yptr + MAXCLINPUTLEN - ptr; for(; *Kr1TblYPos(p) == ch; p += KR1TBLRECLEN) { if(!(l = string_cmp(Kr1TblYPos(p), KR1TBLYLEN, ptr))) continue; if(l > len) continue; mode = *Kr1TblModeP(p); keta = Kr1TblKeta(mode); tptr = ptr + l; if(suuji_class != C_N_KAZU && suuji_class != C_N_NANSUU) { cls = suuji_class; suuji_class = (suuji_class == C_N_ARABIA) ? C_N_ARAKURA : C_N_KANKURA; suuji_ubuf[suuji_keta - 1] |= (keta << 4); check_num(tptr); suuji_class = cls; suuji_ubuf[suuji_keta - 1] &= 0xcf; continue; } if(cnct) { if(!isconnect(cnct, (int)Kr1TblCnct(mode))) continue; suuji_ubuf[suuji_keta - 1] |= (keta << 4); } else { if(!Kr1TblTop(mode)) continue; if(suuji_keta >= NUMKETALENGTH) continue; suuji_ubuf[suuji_keta++] = (_NUM1 | (keta << 4)); } check_num(tptr); srch_number1(tptr); srch_kurai1(tptr, (u_char*)NULL); srch_kurai2(tptr, Kr1TblCnctP(p)); if(cnct) suuji_ubuf[suuji_keta - 1] &= 0xcf; else suuji_keta--; } } static void srch_kurai2(u_char* ptr, u_char* cnct) { u_char ch; u_char* p; int l; int keta; int mode; TypeClass cls; int len; u_char* tptr; if((suuji_ubuf[0] & 0x0f) == _NUM0) return; if(!(p = srchtbl((ch = *ptr), Kurai2_tbl, KR2TBLRECLEN, KR2TBLRECNUM))) return; len = suuji_yptr + MAXCLINPUTLEN - ptr; for(; *Kr2TblYPos(p) == ch; p += KR2TBLRECLEN) { if(!(l = string_cmp(Kr2TblYPos(p), KR2TBLYLEN, ptr))) continue; if(l > len) continue; mode = *Kr2TblModeP(p); keta = Kr2TblKeta(mode); tptr = ptr + l; if(suuji_class != C_N_KAZU && suuji_class != C_N_NANSUU) { suuji_ubuf[suuji_keta - 1] |= (keta << 6); cls = suuji_class; suuji_class = (suuji_class == C_N_ARABIA) ? C_N_ARAKURA : C_N_KANKURA; check_num(tptr); suuji_class = cls; suuji_ubuf[suuji_keta - 1] &= 0x3f; continue; } if(cnct) { if(!isconnect(cnct, (int)Kr2TblCnct(mode))) continue; suuji_ubuf[suuji_keta - 1] |= (keta << 6); } else { if(suuji_keta >= NUMKETALENGTH) continue; suuji_ubuf[suuji_keta++] = (_NUM1 | (keta << 6)); } check_num(tptr); srch_number1(tptr); srch_kurai1(tptr, (u_char*)NULL); if(cnct) suuji_ubuf[suuji_keta - 1] &= 0x3f; else suuji_keta--; } } static void srch_number2(u_char* p) { u_char ch; int i; suuji_class = (*p == N_0) ? C_N_SUUJILONG : C_N_KAZULONG; suuji_keta = suuji_comma = 0; for(i = 0; i < MAXCLINPUTLEN; i++) { if((ch = *p++) == Y_COMMA) { if(suuji_keta) { if(suuji_comma) { if(suuji_comma != 3) break; } else { if(suuji_keta >= 4) break; if(*suuji_yptr == N_0) break; } } else break; suuji_comma = 1; ch = *p++; } else if(suuji_comma) { suuji_comma++; } if(suuji_comma > 3) break; if(!(Chrtbl[ch] & NUMBER)) break; if(suuji_keta < NUMKETALENGTH) { suuji_ubuf[suuji_keta] = ch - N_0 + _NUM0; } suuji_keta++; if(!suuji_comma && suuji_keta > NUMKETALENGTH) { setnrec(p, 0); } else if(suuji_comma == 3) { if(suuji_keta <= NUMKETALENGTH) { suuji_class = C_N_ARACMA; check_num(p); } else { suuji_class = C_N_KAZULCMA; setnrec(p, 0); } } } } static void srchnum_sub(u_char* p) { suuji_yptr = p; suuji_comma = suuji_keta = 0; suuji_class = 0; srch_number1(p); suuji_keta = 0; suuji_class = C_N_KAZU; srch_kurai1(p, (u_char*)NULL); if(suuji_exit) return; srch_number2(p); } void srchnum() { suuji_len = suuji_exit = 0; srchnum_sub(cnvstart); if(!headcode && (*cnvstart == Y_S_KIGOU1)) { headcode = SETTOU_KIGOU; headlen = 1; srchnum_sub(cnvstart + 1); headcode = headlen = 0; } } void setwdnum(u_char* p, int len, u_short* wd) { suuji_len = (u_char)len; suuji_wkeep = wd; suuji_ukeep = NULL; headcode = headlen = 0; suuji_exit = 0; srchnum_sub(p); } int setucnum(u_char* p, int len, u_char* ud) { suuji_len = (u_char)len; suuji_wkeep = NULL; suuji_ukeep = ud; headcode = headlen = 0; suuji_exit = 0; srchnum_sub(p); return (int)suuji_exit; }