From b38b829612793bb6694744c7fe92efcedc623c7e Mon Sep 17 00:00:00 2001 From: Nishi Date: Wed, 23 Sep 2026 19:46:54 +0900 Subject: [PATCH] some fast patch --- include/sj4core/Struct.h | 15 ++++- include/sj4core/sj_kanakan.h | 7 ++- include/sj4core/sj_struct.h | 1 + include/sj4core/sj_typedef.h | 6 ++ lib/sj4core/init.c | 5 +- lib/sj4core/sdepend.c | 110 +++++++++++++++++++++++++++++++++++ lib/sj4core/srchdict.c | 9 +++ lib/sj4ime/ime.c | 2 +- lib/sj4lib/sj.c | 2 +- 9 files changed, 150 insertions(+), 7 deletions(-) diff --git a/include/sj4core/Struct.h b/include/sj4core/Struct.h index 1280499..310d925 100644 --- a/include/sj4core/Struct.h +++ b/include/sj4core/Struct.h @@ -108,6 +108,17 @@ typedef struct global { TypeDicSeg Jpeepidx; } Global; +typedef struct dictskipseg { + u_int first; + u_short count; + TypeDicOfs end; +} DictSkipSeg; + +typedef struct dictskipent { + TypeDicOfs offset; + u_short lower; +} DictSkipEnt; + typedef struct vfile { u_char* buffer; u_int size; @@ -128,7 +139,9 @@ typedef struct dictfile { long idxstrt; long segstrt; - TypeIdxOfs* ofsptr; + TypeIdxOfs* ofsptr; + DictSkipSeg* skipseg; + DictSkipEnt* skipent; struct dictfile* link; } DictFile; diff --git a/include/sj4core/sj_kanakan.h b/include/sj4core/sj_kanakan.h index b8c3dde..e795f9d 100644 --- a/include/sj4core/sj_kanakan.h +++ b/include/sj4core/sj_kanakan.h @@ -65,7 +65,8 @@ CLREC* alloc_clrec(SJ4_CONTEXT2); void free_clrec(SJ4_CONTEXT CLREC*); /* charsize.c */ -static __inline int codesize_inline(u_char code) { +static __inline int +codesize_inline(u_char code) { switch(code & KANJIMODEMASK) { case ZENHIRAASSYUKU: case ZENKATAASSYUKU: @@ -159,7 +160,8 @@ int getkanji(SJ4_CONTEXT u_char*, int, u_char*, u_char*); void getrank(SJ4_CONTEXT2); /* hzstrlen.c */ -static __inline int euc_codesize_inline(u_char c) { +static __inline int +euc_codesize_inline(u_char c) { if((c & KANJIMODEMASK) == 0x90) { return 1; } else if(isknj1(c)) { @@ -268,6 +270,7 @@ extern u_char kigou[]; /* sdepend.c */ DictFile* opendict(SJ4_CONTEXT char*, char*); int closedict(SJ4_CONTEXT DictFile*); +u_char* skipdict(SJ4_CONTEXT u_char*, TypeDicSeg, u_char); StdyFile* openstdy(SJ4_CONTEXT char*, char*); int closestdy(SJ4_CONTEXT StdyFile*); int putstydic(SJ4_CONTEXT2); diff --git a/include/sj4core/sj_struct.h b/include/sj4core/sj_struct.h index d2176ee..e33becb 100644 --- a/include/sj4core/sj_struct.h +++ b/include/sj4core/sj_struct.h @@ -142,6 +142,7 @@ typedef struct dict { IFunc putidx; IFunc putdic; IFunc rszdic; + VFuncDict skipdic; } DICT; typedef struct dictl { diff --git a/include/sj4core/sj_typedef.h b/include/sj4core/sj_typedef.h index dac2428..3d981b3 100644 --- a/include/sj4core/sj_typedef.h +++ b/include/sj4core/sj_typedef.h @@ -55,6 +55,12 @@ typedef int (*IFuncDict)( #endif void*); +typedef void* (*VFuncDict)( +#ifndef SJ4_GLOBAL + void*, +#endif + void*, short); + typedef u_char TypeGroup; typedef u_char TypeGram; typedef u_short TypeIdxOfs; diff --git a/lib/sj4core/init.c b/lib/sj4core/init.c index 8270feb..70ea432 100644 --- a/lib/sj4core/init.c +++ b/lib/sj4core/init.c @@ -74,8 +74,9 @@ void initwork(SJ4_CONTEXT2) { } #ifndef SJ4_GLOBAL -Sj4Context* alloccontext(const char* dic) { - Sj4Context* ctx = calloc(1, sizeof(*ctx)); +Sj4Context* +alloccontext(const char* dic) { + Sj4Context* ctx = (Sj4Context*)calloc(1, sizeof(*ctx)); DictFile* dict; DICTL* node; diff --git a/lib/sj4core/sdepend.c b/lib/sj4core/sdepend.c index 4c99f11..8bed526 100644 --- a/lib/sj4core/sdepend.c +++ b/lib/sj4core/sdepend.c @@ -217,6 +217,114 @@ rszdic(SJ4_CONTEXT DictFile* dp, TypeDicSeg seg) { return fputfile(dp->fp, 0, HEADERLENGTH, dp->buffer); } +static void +freedicskip(DictFile* dp) { + free((char*)dp->skipent); + free((char*)dp->skipseg); + dp->skipent = NULL; + dp->skipseg = NULL; +} + +static void +mkdicskip(DictFile* dp) { + DictSkipSeg* segs; + DictSkipEnt* ents; + u_short* stack; + u_int total = 0; + int seg; + + if(dp->dict.maxunit != 0 || dp->dict.segunit <= 0) return; + + segs = (DictSkipSeg*)calloc(dp->dict.segunit, sizeof(*segs)); + if(segs == NULL) return; + + for(seg = 0; seg < dp->dict.segunit; seg++) { + u_char* base = dp->buffer + dp->segstrt + dp->dict.seglen * seg; + u_char* p = base + *base + 1; + + segs[seg].first = total; + while(p < base + dp->dict.seglen && *p != DICSEGTERM) { + segs[seg].count++; + total++; + p = getntag(p); + } + segs[seg].end = (TypeDicOfs)(p - base); + } + + ents = (DictSkipEnt*)malloc(total * sizeof(*ents)); + stack = (u_short*)malloc(dp->dict.seglen * sizeof(*stack)); + if(ents == NULL || stack == NULL) { + free((char*)stack); + free((char*)ents); + free((char*)segs); + } + + for(seg = 0; seg < dp->dict.segunit; seg++) { + DictSkipSeg* s = &segs[seg]; + u_char* base = dp->buffer + dp->segstrt + dp->dict.seglen * seg; + u_char* p = base + *base + 1; + int top = 0; + int i; + + for(i = 0; i < s->count; i++) { + ents[s->first + i].offset = (TypeDicOfs)(p - base); + p = getntag(p); + } + + for(i = s->count - 1; i >= 0; i--) { + u_char plen = getplen(base + ents[s->first + i].offset); + + while(top > 0 && getplen(base + ents[s->first + stack[top - 1]].offset) >= plen) top--; + + ents[s->first + i].lower = (top > 0) ? stack[top - 1] : s->count; + stack[top++] = (u_short)i; + } + } + + free((char*)stack); + dp->skipseg = segs; + dp->skipent = ents; +} + +static u_char* +skipdic(SJ4_CONTEXT u_char* tagp, TypeDicSeg seg) { + DictFile* dp = (DictFile*)curdict; + DictSkipSeg* s; + TypeDicOfs offset; + int lo, hi; + u_short i; + + if(dp->skipseg == NULL || seg < 0 || seg >= dp->dict.segunit) return NULL; + + s = &dp->skipseg[seg]; + offset = (TypeDicOfs)(tagp - dicbuf); + lo = 0; + hi = s->count - 1; + while(lo <= hi) { + int mid = (lo + hi) / 2; + TypeDicOfs moff = dp->skipent[s->first + mid].offset; + + if(moff < offset) + lo = mid + 1; + else if(moff > offset) + hi = mid - 1; + else { + i = (u_short)mid; + while(i < s->count) { + u_short next = dp->skipent[s->first + i].lower; + + if(next >= s->count) return dicbuf + s->end; + i = next; + if(getplen(dicbuf + dp->skipent[s->first + i].offset) <= dicsaml) + return dicbuf + dp->skipent[s->first + i].offset; + } + return dicbuf + s->end; + } + } + + return NULL; +} + DictFile* opendict(SJ4_CONTEXT char* name, char* passwd) { FILE* fp = NULL; @@ -298,6 +406,7 @@ opendict(SJ4_CONTEXT char* name, char* passwd) { dfp->dict.putidx = (IFunc)putidx; dfp->dict.putdic = (IFunc)putdic; dfp->dict.rszdic = (IFunc)rszdic; + dfp->dict.skipdic = (VFuncDict)skipdic; dfp->refcnt = 1; dfp->fp = fp; dfp->vf = vf; @@ -314,6 +423,7 @@ opendict(SJ4_CONTEXT char* name, char* passwd) { goto error3; } mkidxtbl(SJ4_CONTEXT_PASS & (dfp->dict)); + mkdicskip(dfp); dfp->link = dictlink; dictlink = dfp; diff --git a/lib/sj4core/srchdict.c b/lib/sj4core/srchdict.c index 83acefe..3325ff7 100644 --- a/lib/sj4core/srchdict.c +++ b/lib/sj4core/srchdict.c @@ -222,6 +222,15 @@ srchdict(SJ4_CONTEXT u_char* tagp) { return tagp; } } + + else if(cmp == CONT && getnlen(tagp) != 0 && getplen(tagp) > dicsaml && curdict->skipdic != NULL) { + u_char* next = (*curdict->skipdic)(SJ4_CONTEXT_PASS tagp, segno); + + if(next != NULL) { + tagp = next; + continue; + } + } tagp = getntag(tagp); } dicinl = dicsaml + 1; diff --git a/lib/sj4ime/ime.c b/lib/sj4ime/ime.c index 4398f3c..ac5532b 100644 --- a/lib/sj4ime/ime.c +++ b/lib/sj4ime/ime.c @@ -39,7 +39,7 @@ static struct sj4table { Sj4Ime* sj4_ime(int charset, const char* dict, Sj4ImePacket packet) { Sj4Ime* ime; - if((ime = calloc(1, sizeof(*ime))) == NULL) return NULL; + if((ime = (Sj4Ime*)calloc(1, sizeof(*ime))) == NULL) return NULL; if((ime->lib = sj4_open(charset, dict)) == NULL) { free((char*)ime); diff --git a/lib/sj4lib/sj.c b/lib/sj4lib/sj.c index 24ab3ad..06aa61c 100644 --- a/lib/sj4lib/sj.c +++ b/lib/sj4lib/sj.c @@ -25,7 +25,7 @@ Sj4Lib* sj4_open(int charset, const char* dic) { if(charset == SJ4UTF8 || charset == SJ4UTF16) return NULL; #endif - if((ctx = calloc(1, sizeof(*ctx))) == NULL) return NULL; + if((ctx = (Sj4Lib*)calloc(1, sizeof(*ctx))) == NULL) return NULL; if((ctx->ctx = alloccontext(dic)) == NULL) { free((char*)ctx);