1 /* Copyright 1994 NEC Corporation, Tokyo, Japan.
2 *
3 * Permission to use, copy, modify, distribute and sell this software
4 * and its documentation for any purpose is hereby granted without
5 * fee, provided that the above copyright notice appear in all copies
6 * and that both that copyright notice and this permission notice
7 * appear in supporting documentation, and that the name of NEC
8 * Corporation not be used in advertising or publicity pertaining to
9 * distribution of the software without specific, written prior
10 * permission. NEC Corporation makes no representations about the
11 * suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
13 *
14 * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
16 * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19 * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23 #if !defined(lint) && !defined(__CODECENTER__)
24 static char rcs_id[] = "$Id: permdic.c,v 1.8 2003/09/17 08:50:52 aida_s Exp $";
25 #endif
26
27 #include "RKintern.h"
28
29
30 #ifdef SVR4
31 #include <unistd.h>
32 #endif
33
34 #ifdef __CYGWIN32__
35 #include <fcntl.h> /* for O_BINARY */
36 #endif
37
38 #define dm_xdm dm_extdata.ptr
39 #define df_fdes df_extdata.var
40
41 extern unsigned _RkCalcLVO();
42 extern Wchar uniqAlnum();
43
44 #ifdef MMAP
45 /* If you compile with Visual C++, then please comment out the next 3 lines. */
46 #include <sys/types.h> /* mmap */
47 #include <sys/mman.h> /* mmap */
48 #include <fcntl.h> /* mmap */
49 extern int fd_dic; /* mmap */
50 #endif
51
52 static int
openDF(df,dfnm,w,gramoff,gramsz)53 openDF(df, dfnm, w, gramoff, gramsz)
54 struct DF *df;
55 char *dfnm;
56 int *w;
57 off_t *gramoff;
58 size_t *gramsz;
59 {
60 struct HD hd;
61 struct ND nd, *xnd;
62 struct DM *dm, *dmh;
63 off_t off;
64 unsigned char ll[4];
65 int count = 0, err;
66 int fd;
67 int errres = -1;
68
69 *w = 0;
70 if ((fd = open(dfnm, 0)) == -1)
71 return errres;
72 #ifdef __CYGWIN32__
73 setmode(fd, O_BINARY);
74 #endif
75
76 for (off = 0, err = 0; !err && _RkReadHeader(fd, &hd, off) >= 0;) {
77
78 if (hd.flag[HD_CODM] > 0) {
79 _RkClearHeader(&hd);
80 break;
81 }
82 nd.time = hd.data[HD_TIME].var;
83 /* XXX: sanity check taking advantage of this CRC */
84 if (hd.flag[HD_CRC]) {
85 nd.crc = hd.data[HD_CRC].var;
86 nd.crc_found = 1;
87 } else {
88 nd.crc_found = 0;
89 }
90 nd.rec = hd.data[HD_REC].var;
91 nd.can = hd.data[HD_CAN].var;
92 nd.doff = off + hd.data[HD_HSZ].var;
93 nd.sz = hd.data[HD_SIZ].var;
94 nd.drsz = hd.data[HD_PGOF].var - hd.data[HD_DROF].var;
95 nd.pgsz = _RkCalcUnlog2(hd.data[HD_L2P].var) + 1;
96 nd.ttlpg = hd.data[HD_PAG].var;
97 nd.fd = fd;
98 nd.buf = (unsigned char *)0;
99 nd.pgs = (struct NP *)0;
100 nd.version = HD_VERSION(&hd);
101 off += hd.data[HD_SIZ].var;
102 if (!strncmp(".swd",
103 (char *)(hd.data[HD_DMNM].ptr
104 + strlen((char *)hd.data[HD_DMNM].ptr) - 4),
105 4)) {
106 if (nd.version >= 0x300702L) {
107 if (hd.flag[HD_GRAM] == -1) {
108 *gramoff = hd.data[HD_GRAM].var;
109 *gramsz = hd.data[HD_GRSZ].var;
110 } else {
111 *gramoff = 0;
112 *gramsz = 0;
113 }
114 } else {
115 if (lseek(fd, off, 0) < 0 || read(fd, (char *)ll, 4) != 4) {
116 err++;
117 *gramoff = 0;
118 *gramsz = 0;
119 } else {
120 *gramoff = off;
121 *gramsz = (size_t)-1;
122 off += bst4_to_l(ll) + 4;
123 }
124 }
125 }
126 dmh = &df->df_members;
127 for (dm = dmh->dm_next; dm != dmh; dm = dm->dm_next) {
128 if (!strcmp((char *)dm->dm_dicname, (char *)hd.data[HD_DMNM].ptr)) {
129 if (!dm->dm_xdm) {
130 if (!(xnd = (struct ND *)malloc(sizeof(struct ND))))
131 break;
132 dm->dm_xdm = (pointer)xnd;
133 *xnd = nd;
134 dm->dm_flags |= DM_EXIST;
135 dm->dm_offset = xnd->doff;
136 count++;
137 break;
138 }
139 }
140 }
141 _RkClearHeader(&hd);
142 }
143 _RkClearHeader(&hd);
144 df->df_size = off;
145 if (!count) {
146 (void)close(fd);
147 return errres;
148 }
149 return (df->df_fdes = fd);
150 }
151
152 int
_Rkpopen(dm,dfnm,mode,gram)153 _Rkpopen(dm, dfnm, mode, gram)
154 struct DM *dm;
155 char *dfnm;
156 int mode;
157 struct RkKxGram *gram; /* ARGSUSED */
158 {
159 struct DF *df;
160 struct DD *dd;
161 struct ND *xdm;
162 int writable, i, readsize;
163 int fd;
164 off_t gramoff;
165 size_t gramsz;
166
167 if (!(df = dm->dm_file) || !(dd = df->df_direct))
168 return -1;
169 if (!df->df_rcount) {
170 if ((df->df_fdes = (long)openDF(df, dfnm, &writable, &gramoff, &gramsz)) < 0)
171 return -1;
172 if (writable)
173 df->df_flags |= DF_WRITABLE;
174 else
175 df->df_flags &= ~DF_WRITABLE;
176 df->df_flags |= DF_EXIST;
177 dd->dd_rcount++;
178 }
179 if (!(dm->dm_flags & DM_EXIST))
180 return -1;
181 df->df_rcount++;
182 xdm = (struct ND *)dm->dm_xdm;
183 fd = df->df_fdes;
184
185 if (!(xdm->buf = (unsigned char *)malloc((size_t)xdm->drsz))) {
186 return(-1);
187 }
188 if (!(xdm->pgs
189 = (struct NP *)malloc((size_t)(sizeof(struct NP) * xdm->ttlpg)))) {
190 (void)free((char *)xdm->buf);
191 xdm->buf = (unsigned char *)0;
192 return(-1);
193 }
194 for (i = 0; i < (int)xdm->ttlpg; i++) {
195 xdm->pgs[i].lnksz = (unsigned) 0;
196 xdm->pgs[i].ndsz = (unsigned) 0;
197 xdm->pgs[i].lvo = (unsigned long) 0;
198 xdm->pgs[i].csn = (unsigned long) 0;
199 xdm->pgs[i].flags = (unsigned) 0;
200 xdm->pgs[i].count = 0;
201 xdm->pgs[i].buf = (unsigned char *) 0;
202 }
203
204 (void)lseek(fd, xdm->doff, 0);
205 readsize = read(fd, (char *)xdm->buf, (unsigned int) xdm->drsz);
206 if (readsize != ((int) xdm->drsz)) {
207 (void)free((char *)xdm->pgs);
208 (void)free((char *)xdm->buf);
209 xdm->buf = (unsigned char *)0;
210 xdm->pgs = (struct NP *)0;
211 return(-1);
212 }
213 if (dm->dm_class == ND_SWD && gramsz) {
214 struct RkKxGram *gram;
215
216 lseek(fd, gramoff, 0);
217 gram = RkReadGram(fd, gramsz);
218 if (gram) {
219 dm->dm_gram = (struct RkGram *)malloc(sizeof(struct RkGram));
220 if (dm->dm_gram) {
221 dm->dm_gram->gramdic = gram;
222 dm->dm_gram->P_BB = RkGetGramNum(gram, "BB");
223 dm->dm_gram->P_NN = RkGetGramNum(gram, "NN");
224 dm->dm_gram->P_T00 = RkGetGramNum(gram, "T00");
225 dm->dm_gram->P_T30 = RkGetGramNum(gram, "T30");
226 dm->dm_gram->P_T35 = RkGetGramNum(gram, "T35");
227 #ifdef LOGIC_HACK
228 dm->dm_gram->P_KJ = RkGetGramNum(gram, "KJ");
229 #endif
230 dm->dm_gram->P_Ftte = RkGetGramNum(gram, "Ftte");
231 dm->dm_gram->refcount = 1;
232 goto next;
233 }
234 RkCloseGram(gram);
235 }
236 }
237
238 next:
239 if ((mode & DM_WRITABLE) && (df->df_flags & DF_WRITABLE)) {
240 dm->dm_flags |= DM_WRITABLE;
241 }
242 return 0;
243 }
244
245 int
_Rkpclose(dm,dfnm,gram)246 _Rkpclose(dm, dfnm, gram)
247 struct DM *dm;
248 char *dfnm;
249 struct RkKxGram *gram; /* ARGSUSED */
250 {
251 struct DF *df = dm->dm_file;
252 struct ND *xdm = (struct ND *)dm->dm_xdm;
253 int i;
254
255 _RkKillCache(dm);
256 if (dm->dm_gram) {
257 dm->dm_gram->refcount--;
258 if (dm->dm_gram->refcount == 0) {
259 (void)RkCloseGram(dm->dm_gram->gramdic);
260 free((char *)dm->dm_gram);
261 }
262 }
263 if (xdm) {
264 if (xdm->pgs) {
265 for (i = 0; i < (int)xdm->ttlpg; i++)
266 if (xdm->pgs[i].flags & RK_PG_LOADED) {
267 #ifdef MMAP
268 if (((int) (xdm->pgs[i].buf)) != -1)
269 munmap((caddr_t)xdm->pgs[i].buf, xdm->pgsz);
270 #else
271 if (xdm->pgs[i].buf) {
272 (void)free((char *)xdm->pgs[i].buf);
273 }
274 #endif
275 xdm->pgs[i].flags &= ~RK_PG_LOADED;
276 }
277 (void)free((char *)xdm->pgs);
278 xdm->pgs = (struct NP *)0;
279 }
280 if (xdm->buf) {
281 (void)free((char *) xdm->buf);
282 xdm->buf = (unsigned char *)0;
283 }
284 }
285
286 if (--df->df_rcount == 0) {
287 int fd;
288 struct DM *dmh, *ddm;
289
290 fd = df->df_fdes;
291
292 (void)close(fd);
293 dmh = &df->df_members;
294 for (ddm = dmh->dm_next; ddm != dmh; ddm = ddm->dm_next) {
295 xdm = (struct ND *)ddm->dm_xdm;
296 if (xdm) {
297 (void)free((char *)xdm);
298 ddm->dm_xdm = (pointer)0;
299 }
300 }
301 }
302 return 0;
303 }
304
305 static
306 unsigned char *
assurep(dic,id)307 assurep(dic, id)
308 struct ND *dic;
309 int id;
310 {
311 off_t off = dic->doff + dic->drsz + dic->pgsz * id;
312 unsigned size = dic->pgsz;
313 unsigned char *buf;
314 int i;
315 int fd;
316
317 fd = dic->fd;
318 if (!dic->pgs)
319 return((unsigned char *)0);
320 if ((unsigned)id >= dic->ttlpg)
321 return((unsigned char *)0);
322 if (!isLoadedPage(dic->pgs + id)) {
323
324 #ifdef MMAP
325 buf = (unsigned char *)mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_dic, 0);
326 if ((int)buf == -1)
327 return((unsigned char *)0);
328 #else
329 if (!(buf = (unsigned char *)malloc(size)))
330 return((unsigned char *)0);
331 #endif
332 (void)lseek(fd, off, 0);
333 if (read(fd, (char *)buf, size) != (int)size) {
334 free((char *)buf);
335 return((unsigned char *)0);
336 }
337
338 dic->pgs[id].buf = buf;
339 dic->pgs[id].count = 0;
340 dic->pgs[id].flags |= RK_PG_LOADED;
341 dic->pgs[id].ndsz = bst2_to_s(buf + 2);
342 dic->pgs[id].lnksz = bst2_to_s(buf + 4);
343 dic->pgs[id].lvo = bst3_to_l(buf + 7);
344 dic->pgs[id].csn = bst3_to_l(buf + 10);
345 return(buf);
346 } else {
347 return(dic->pgs[id].buf);
348 }
349 }
350
351 int
_RkEql(a,b,n)352 _RkEql(a, b, n)
353 Wchar *a;
354 unsigned char *b;
355 int n;
356 {
357 Wchar c, d;
358 for (; n-- > 0; b += 2) {
359 c = uniqAlnum(*a++);
360 d = (*b << 8) | *(b+1);
361 if (c != d)
362 return(0);
363 }
364 return(1);
365 }
366
367 static
368 readThisCache(dm, xdm, pgno, val, key, cur, ylen, nread, mc, nc, cf)
369 struct DM *dm;
370 struct ND *xdm;
371 long pgno;
372 unsigned long val;
373 Wchar *key;
374 int cur;
375 int ylen;
376 struct nread *nread;
377 int mc;
378 int nc;
379 int *cf;
380 {
381 int remlen;
382 unsigned char *wrec1, *wrec;
383
384 if (xdm->pgs[pgno].buf) {
385 if (*(wrec1 = wrec = xdm->pgs[pgno].buf + val) & 0x80)
386 wrec1 += 2;
387 wrec1 += 2;
388 remlen = (*wrec >> 1) & 0x3f;
389 if (_RkEql(key + cur, (unsigned char *)wrec1, remlen)) {
390 if (remlen + cur > ylen)
391 (*cf)++;
392 else if (nc < mc) {
393 nread[nc].cache = _RkReadCache(dm, (long)wrec);
394 if (nread[nc].cache) {
395 if (_RkGetLink(xdm, pgno, val, &nread[nc].offset, &nread[nc].csn) < 0) {
396 _RkDerefCache(nread[nc].cache);
397 return(0);
398 }
399 nread[nc].nk = cur + remlen;
400 nc++;
401 } else
402 (*cf)++;
403 } else
404 (*cf)++;
405 }
406 }
407 return(nc);
408 }
409
410 static int
SearchInPage(dm,xdm,pgno,buf,val,key,cur,ylen,nread,mc,nc,cf)411 SearchInPage(dm, xdm, pgno, buf, val, key, cur, ylen, nread, mc, nc, cf)
412 struct DM *dm;
413 struct ND *xdm;
414 unsigned char *buf;
415 long pgno;
416 unsigned long val;
417 Wchar *key;
418 int cur;
419 int ylen;
420 struct nread *nread;
421 int mc;
422 int nc;
423 int *cf;
424 {
425 Wchar kv, wc;
426 unsigned char *pos = buf + val;
427
428 if (!*pos && !*(pos + 1)) {
429 val = ((*(pos + 2) & 0x3f) << BIT_UNIT) | *(pos + 3);
430 nc = readThisCache(dm, xdm, pgno, val, key,
431 cur, ylen, nread, mc, nc, cf);
432 if (*(pos + 2) & LAST_NODE)
433 return(nc);
434 pos += 4;
435 }
436 if (cur == ylen) {
437 (*cf)++;
438 return(nc);
439 }
440 kv = uniqAlnum(*(key + cur));
441 for (wc = bst2_to_s(pos); wc != kv; pos += 4, wc = bst2_to_s(pos)) {
442 if (*(pos + 2) & LAST_NODE)
443 return(nc);
444 }
445 val = ((*(pos + 2) & 0x3f) << BIT_UNIT) | *(pos + 3);
446 cur++;
447 if (*(pos + 2) & WORD_NODE)
448 nc = readThisCache(dm, xdm, pgno, val, key,
449 cur, ylen, nread, mc, nc, cf);
450 else
451 nc = SearchInPage(dm, xdm, pgno, buf, val, key,
452 cur, ylen, nread, mc, nc, cf);
453 return(nc);
454 }
455
456 static int
SearchInDir(dm,xdm,pos,key,cur,ylen,nread,mc,nc,cf)457 SearchInDir(dm, xdm, pos, key, cur, ylen, nread, mc, nc, cf)
458 struct DM *dm;
459 struct ND *xdm;
460 unsigned char *pos;
461 Wchar *key;
462 int cur;
463 int ylen;
464 struct nread *nread;
465 int mc;
466 int nc;
467 int *cf;
468 {
469 Wchar kv, wc, nw;
470 unsigned long val;
471 long next, pgno, iw;
472 unsigned char *p;
473
474 nw = bst2_to_s(pos);
475 pos += 5;
476 if (!*pos && !*(pos + 1)) {
477 val = bst3_to_l(pos + 2);
478 if (val & ~VMASK) {
479 val &= VMASK;
480 pgno = (val - xdm->drsz) / xdm->pgsz;
481 val -= pgno * xdm->pgsz + xdm->drsz;
482 if (assurep(xdm, pgno))
483 nc = readThisCache(dm, xdm, pgno, val, key,
484 cur, ylen, nread, mc, nc, cf);
485 }
486 }
487 if (cur == ylen) {
488 (*cf)++;
489 return(nc);
490 }
491 kv = uniqAlnum(*(key + cur));
492 next = (int)(kv % nw);
493 do {
494 p = pos + (((Wchar) next++) % nw) * 5;
495 if ((wc = bst2_to_s(p)) == 0xffff)
496 return(nc);
497 } while (wc != kv);
498 val = bst3_to_l(p + 2);
499 cur++;
500 iw = (val & ~VMASK);
501 val &= VMASK;
502 if (iw) {
503 pgno = (val - xdm->drsz) / xdm->pgsz;
504 val -= pgno * xdm->pgsz + xdm->drsz;
505 if (assurep(xdm, pgno))
506 nc = readThisCache(dm, xdm, pgno, val, key,
507 cur, ylen, nread, mc, nc, cf);
508 } else {
509 if (val < xdm->drsz)
510 nc = SearchInDir(dm, xdm, xdm->buf + val, key,
511 cur, ylen, nread, mc, nc, cf);
512 else {
513 pgno = (val - xdm->drsz) / xdm->pgsz;
514 val -= pgno * xdm->pgsz + xdm->drsz;
515 p = assurep(xdm, pgno);
516 if (p)
517 nc = SearchInPage(dm, xdm, pgno, p, val, key,
518 cur, ylen, nread, mc, nc, cf);
519 }
520 }
521 return(nc);
522 }
523
524 int
_Rkpsearch(cx,dm,key,n,nread,mc,cf)525 _Rkpsearch(cx, dm, key, n, nread, mc, cf)
526 struct RkContext *cx;
527 struct DM *dm;
528 Wchar *key;
529 int n;
530 struct nread *nread;
531 int mc;
532 int *cf;
533 /* ARGSUSED */
534 {
535 struct ND *xdm;
536
537 *cf = 0;
538 xdm = (struct ND *)dm->dm_xdm;
539 if (xdm) {
540 if (xdm->buf)
541 return(SearchInDir(dm, xdm, xdm->buf, key, 0, n, nread, mc, 0, cf));
542 }
543 return(0);
544 }
545
546 int
_Rkpio(dm,cp,io)547 _Rkpio(dm, cp, io)
548 struct DM *dm;
549 struct ncache *cp;
550 int io;
551 /* ARGSUSED */
552 {
553 if (io == 0) {
554 cp->nc_word = (Wrec *)cp->nc_address;
555 cp->nc_flags |= NC_NHEAP;
556 }
557 return 0;
558 }
559
560 #if 0 /* �Ȥ��Ƥ��ʤ��ΤǤȤꤢ���������Ȥˤ��� */
561 static void
562 ch_perm(qm, offset, size, num)
563 struct DM *qm;
564 unsigned offset;
565 int size, num;
566 {
567 unsigned char tmp[8192];
568 /* I leave this stack located array because of it is not used */
569
570 if (num > 0) {
571 _RkCopyBits(tmp, 0, size, qm->dm_qbits, offset, num);
572 _RkCopyBits(qm->dm_qbits, offset + 0, size,
573 qm->dm_qbits, offset + num*size, 1);
574 _RkCopyBits(qm->dm_qbits, offset + size, size, tmp, 0, num);
575 }
576 }
577 #endif
578
579 #define PERM_WRECSIZE 2048
580 #define PERM_NREADSIZE 128
581
582 int
_Rkpctl(dm,qm,what,arg,gram)583 _Rkpctl(dm, qm, what, arg, gram)
584 struct DM *dm;
585 struct DM *qm;
586 int what;
587 Wchar *arg;
588 struct RkKxGram *gram;
589 {
590 int nc, cf = 0, ret = -1;
591 struct ND *xdm;
592 unsigned long lucks[2];
593 #ifndef USE_MALLOC_FOR_BIG_ARRAY
594 Wrec wrec[PERM_WRECSIZE];
595 Wchar key[64];
596 struct nread nread[PERM_NREADSIZE];
597 unsigned permutation[RK_CAND_NMAX];
598 #else
599 Wrec *wrec;
600 Wchar *key;
601 struct nread *nread;
602 unsigned *permutation;
603 wrec = (Wrec *)malloc(sizeof(Wrec) * PERM_WRECSIZE);
604 key = (Wchar *)malloc(sizeof(Wchar) * 64);
605 nread = (struct nread *)malloc(sizeof(struct nread) * PERM_NREADSIZE);
606 permutation = (unsigned *)malloc(sizeof(unsigned) * RK_CAND_NMAX);
607 if (!wrec || !key || !nread || !permutation) {
608 if (wrec) (void)free((char *)wrec);
609 if (key) (void)free((char *)key);
610 if (nread) (void)free((char *)nread);
611 if (permutation) (void)free((char *)permutation);
612 return ret;
613 }
614 #endif
615
616 if (!dm || !qm || (qm && !qm->dm_qbits)) {
617 goto done;
618 }
619
620 if ((qm->dm_flags & (DM_WRITABLE | DM_WRITEOK)) ==
621 (DM_WRITABLE | DM_WRITEOK)) {
622 /* (writable and write ok) */
623
624 if (RkParseOWrec(gram, arg, wrec, PERM_WRECSIZE, lucks)) {
625 Wrec *p, *q, *kanji;
626 Wchar *wkey;
627 int maxcache = PERM_NREADSIZE;
628 int ylen, klen, cnum, y_off = 2, k_off;
629
630
631 ylen = (wrec[0] >> 1) & 0x3f;
632 if (wrec[0] & 0x80)
633 y_off += 2;
634 p = wrec + y_off;
635 q = p + (ylen * 2);
636 for (wkey = key; p < q ; wkey++) {
637 *wkey = (*p << 8) | *(p + 1);
638 p += 2;
639 }
640 *(key+ylen) = 0;
641
642 /* �ʻ졢��������μ��Ф� */
643 k_off = y_off + ylen * 2;
644 klen = (wrec[k_off] >> 1) & 0x7f;
645 cnum = ((wrec[k_off] & 0x01) << 8) | wrec[k_off+1];
646 kanji = wrec + k_off + 2;
647
648 nc = -1;
649 xdm = (struct ND *)dm->dm_xdm;
650 if (xdm) {
651 if (xdm->buf)
652 nc = SearchInDir(dm, xdm, xdm->buf, key, 0, ylen, nread,
653 maxcache, 0, &cf);
654 }
655
656 if (nc > 0) {
657 struct nread *thisRead;
658 struct ncache *thisCache;
659 unsigned char *wp;
660 int nk, nl, pre;
661 unsigned long offset;
662 int bitSize, fnum = -1, nnum, i;
663
664 for (i = 0 ; i < nc ; i++) {
665 if (nread[i].nk == ylen) {
666 break;
667 }
668 }
669 /* �Ȥ�ʤ�ñ�����Ϥ��餫���� _RkDerefCache ���� */
670 for (pre = 0 ; pre < nc ; pre++) {
671 if (pre != i) {
672 thisRead = nread + pre;
673 thisCache = thisRead->cache;
674 _RkDerefCache(thisCache);
675 }
676 }
677
678 if (i < nc) {
679 thisRead = nread + i;
680 thisCache = thisRead->cache;
681 wp = thisCache->nc_word;
682
683 nk = _RkCandNumber(wp);
684 nl = (*wp >> 1) & 0x3f;
685 if (*wp & 0x80)
686 wp += 2;
687 wp += 2 + nl *2;
688
689 /* ��������ʬ�Ǽ���β����ܤˤǤƤ��뤫 (fnum) ��õ�� */
690 for (i = 0; i < nk; i++) {
691 unsigned char *kp;
692
693 nl = (*wp >> 1) & 0x7f; /* ����Š*/
694 nnum = ((*wp & 0x01) << 8) | *(wp+1); /* �ʻ��ֹ� */
695 if (nl == klen && nnum == cnum) {
696 int lc;
697
698 for (lc = 0, kp = wp + 2; lc < klen*2; lc++) {
699 if (*(kanji+lc) != *(kp+lc))
700 break;
701 }
702 if (lc == klen*2) {
703 fnum = i;
704 break;
705 }
706 }
707 wp += 2 + nl*2;
708 }
709
710 offset = thisRead->offset;
711 if (fnum >= 0 && fnum < nk && 0 < thisRead->nk &&
712 thisRead->nk <= ylen && thisRead->nk <= RK_KEY_WMAX) {
713 int ecount, cval, i, dn = -1, ndel = 0;
714
715 bitSize = _RkCalcLog2(nk + 1) + 1;
716 _RkUnpackBits(permutation, qm->dm_qbits, offset, bitSize, nk);
717 switch (what) {
718 case DST_DoDefine:
719 for (ecount = cval = i = 0; i < nk; i++) {
720 if ((int)permutation[i]/2 > nk) {
721 ecount++;
722 break;
723 };
724 cval += permutation[i];
725 if ((unsigned)nk == permutation[i]/2 && dn < 0)
726 dn = i;
727 if ((unsigned)fnum == permutation[i]/2) {
728 ndel = -1;
729 dn = i;
730 }
731 }
732 break;
733 case DST_DoDelete:
734 for (ecount = cval = i = 0; i < nk; i++) {
735 if ((int)permutation[i]/2 > nk) {
736 ecount++;
737 break;
738 };
739 cval += permutation[i];
740 if ((unsigned)fnum == permutation[i]/2)
741 dn = i;
742 };
743 break;
744 }
745 if (ecount || cval < (nk-1)*(nk-2)) {
746 for (i = 0; i < nk; i++)
747 permutation[i] = 2*i;
748 _RkPackBits(qm->dm_qbits, offset, bitSize, permutation, nk);
749 } else {
750 if (dn >= 0) {
751 if (!ndel) {
752 switch (what) {
753 case DST_DoDefine:
754 _RkSetBitNum(qm->dm_qbits, offset, bitSize, dn, fnum*2);
755 /* �������¤ӽ���ѹ�����ؿ������Ȥꤢ���������Ȥˤ��롣
756 ch_perm(qm, offset, bitSize, dn);
757 */
758 break;
759 case DST_DoDelete:
760 _RkSetBitNum(qm->dm_qbits, offset, bitSize, dn, nk*2);
761 break;
762 }
763 qm->dm_flags |= DM_UPDATED;
764 }
765 _RkDerefCache(thisCache);
766 ret = 0;
767 goto done;
768 }
769 }
770 }
771 _RkDerefCache(thisCache);
772 }
773 }
774 }
775 }
776 done:
777 #ifdef USE_MALLOC_FOR_BIG_ARRAY
778 (void)free((char *)wrec);
779 (void)free((char *)key);
780 (void)free((char *)nread);
781 (void)free((char *)permutation);
782 #endif
783 return ret;
784 }
785
786 int
_Rkpsync(cx,dm,qm)787 _Rkpsync(cx, dm, qm)
788 struct RkContext *cx;
789 struct DM *dm, *qm;
790 {
791 struct DF *df;
792 struct DD *dd;
793 #ifdef MMAP
794 struct ND *dic;
795 #endif
796 char *file;
797
798 if (qm) {
799 df = qm->dm_file;
800 dd = df->df_direct;
801 file = _RkCreatePath(dd, df->df_link);
802 if (file) {
803 int i;
804 #ifdef MMAP
805 int j;
806 #endif
807 i = FQsync(cx, dm, qm, file);
808 (void)free(file);
809 #ifdef MMAP
810 dic = (struct ND *)dm->dm_xdm;
811 if(dic)
812 for(j=0;j<dic->ttlpg;j++) {
813 if (isLoadedPage(dic->pgs + j))
814 if (_RkDoInvalidateCache(dic->pgs[j].buf, dic->pgsz) == 1) {
815 if (((int) (dic->pgs[j].buf)) != -1)
816 munmap((caddr_t)dic->pgs[j].buf, dic->pgsz);
817 dic->pgs[j].buf = (unsigned char *)0;
818 dic->pgs[j].lnksz = (unsigned) 0;
819 dic->pgs[j].ndsz = (unsigned) 0;
820 dic->pgs[j].lvo = (unsigned) 0;
821 dic->pgs[j].csn = (unsigned) 0;
822 dic->pgs[j].flags = (unsigned) 0;
823 dic->pgs[j].count = 0;
824 }
825 }
826 #endif
827 return (i);
828 }
829 }
830 return (0);
831 }
832 /* vim: set sw=2: */
833