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 rcsid[] = "$Id: bun.c,v 1.6 2003/09/21 10:16:49 aida_s Exp $";
25 #endif
26
27 /* LINTLIBRARY */
28
29 #include "RKintern.h"
30
31 #define NEED_DEF
32 #ifdef RkSetErrno
33 #undef RkSetErrno
34 #define RkSetErrno(no)
35 #endif
36
37 #ifdef OVERRUN_DEBUG
38 #define OVERRUN_MARGIN 100
39 #else
40 #define OVERRUN_MARGIN 0
41 #endif
42
43 #define STRCMP(d, s) strcmp((char *)(d), (char *)(s))
44 extern void usncopy();
45
46 #ifdef RK_LOG
47 #include <stdio.h>
48 static FILE *
openLogFile(cxnum)49 openLogFile(cxnum)
50 int cxnum;
51 {
52 char file[128];
53 FILE *fp;
54 sprintf(file, "/tmp/henkan%03d.log", cxnum);
55 fp = fopen(file, "a");
56 return fp;
57 }
58
59 static char *
nword2str(cx,w,yomi)60 nword2str(cx, w, yomi)
61 struct RkContext *cx;
62 struct nword *w;
63 Wchar *yomi;
64 {
65 static unsigned char msg[RK_LINE_BMAX];
66 static unsigned char eyomi[RK_LINE_BMAX];
67 struct nword *words[RK_CONC_NMAX], **p, *wp;
68 int msg_idx = 0;
69 char *hinsi;
70 Wchar *kanji, *_RkGetKanji();
71 unsigned char *ekanji, *ustoeuc();
72
73 for (wp = w, p = words; wp; wp = wp->nw_left)
74 *p++ = wp;
75
76 while (p-- > words) {
77 int yomi_len, hinsi_len;
78
79 wp = *p;
80 if (!wp->nw_left)
81 continue;
82 kanji = _RkGetKanji(wp, yomi + wp->nw_left->nw_ylen, cx->concmode);
83 ekanji = ustoeuc(kanji, wp->nw_klen - wp->nw_left->nw_klen,
84 msg + msg_idx, RK_LINE_BMAX - msg_idx);
85 msg_idx = ekanji - msg;
86 ustoeuc(yomi + wp->nw_left->nw_ylen,
87 wp->nw_ylen - wp->nw_left->nw_ylen, eyomi, RK_LINE_BMAX);
88 yomi_len = strlen(eyomi);
89 hinsi = RkGetGramName(cx->gram->gramdic, wp->nw_rowcol);
90 hinsi_len = strlen(hinsi);
91 if (msg_idx + 1 + yomi_len + hinsi_len + 2 >= RK_LINE_BMAX)
92 break;
93 sprintf(msg + msg_idx, "/%s[%s]", eyomi, hinsi);
94 msg_idx += 1 + yomi_len + hinsi_len + 2;
95 }
96 msg[msg_idx] = 0;
97
98 return msg;
99 }
100
101 static
102 dumpBunq(cx, from, end, log, fp)
103 struct RkContext *cx;
104 int from;
105 unsigned end;
106 int log; /* 0 �����ѹ� 1 �Ѵ����� 2 ���� 3 ʸ��Ĺ�ѹ� */
107 FILE *fp;
108 {
109 int i;
110 struct nstore *store = cx->store;
111 struct nbun *bun = store->bunq + from;
112 struct henkanlog *l = store->hlog;
113
114 for (i = 0; i < from; i++) l = l->next;
115 if (log & 1) {
116 /* ʸ��Ĺ�ѹ�����ν���� */
117 char **prev = store->blog;
118 int nprev = store->nblog;
119 store->nblog = end;
120 store->blog = (char **)malloc(sizeof(char *) * end);
121 /* ����ʸ��ޤǤξ�����������ԡ� */
122 if (log == 3)
123 for (i = 0; i <= from; i++)
124 store->blog[i] = prev[i];
125 /* �Ĥ�ϼΤƤ� */
126 for (i = from + (log == 3); i < nprev; i++)
127 if (prev[i]) free(prev[i]);
128 if (prev) free(prev);
129 /* �ʹߤϽ���� */
130 for (i = from + (log == 3); i < end; i++)
131 store->blog[i] = NULL;
132 }
133 for ( i = from; i < end; i++, bun++) {
134 struct nword *w;
135 char *henkan;
136 int n = bun->nb_curcand;
137 /* ���߸���μ��� */
138 for ( w = bun->nb_cand; w; w = w->nw_next ) {
139 if ( CanSplitWord(w) && bun->nb_curlen == w->nw_ylen )
140 if ( n-- <= 0 ) break;
141 }
142 if (log & 1) {
143 /* ����������� */
144 struct henkanlog *p = NULL, *q;
145 if (q = l->next) {
146 p = q->next;
147 if (q->henkan) {
148 if (log == 3 && from == i && !store->blog[i])
149 store->blog[i] = q->henkan;
150 else
151 if (q->henkan[0]) free(q->henkan);
152 }
153 free(q);
154 }
155 l = l->next = (struct henkanlog *)
156 malloc(sizeof(struct henkanlog));
157 l->next = p;
158 } else if (log == 2) l = l->next;
159
160 if (!w) {
161 if (log & 1) l->henkan = "";
162 else if (log == 2) {
163 unsigned char msg[RK_LINE_BMAX];
164 unsigned char *ekanji, *ustoeuc();
165 ustoeuc(store->yomi + bun->nb_yoff, bun->nb_curlen,
166 msg, RK_LINE_BMAX);
167 fprintf(fp, "��ƥ�� %s\n", msg);
168 }
169 } else {
170 henkan = nword2str(cx, w, store->yomi + bun->nb_yoff);
171 if (log & 1) {
172 l->henkan = (char *)malloc(strlen(henkan) + 1);
173 strcpy(l->henkan, henkan);
174 }
175 else if (log == 2) {
176 if (store->blog[i]) {
177 fprintf(fp, "���Ѵ� ʸ��Ĺ�ѹ� %s -> %s\n",
178 store->blog[i], henkan);
179 }
180 if (STRCMP(l->henkan, henkan))
181 fprintf(fp, "���Ѵ� %s -> %s\n", l->henkan, henkan);
182 else
183 fprintf(fp, "���� %s\n", henkan);
184 }
185 }
186 }
187 fprintf(fp, "\n");
188 fflush(fp);
189 }
190 #endif
191
192 static void
freeBunStorage(s)193 freeBunStorage(s)
194 struct nstore *s;
195 {
196 if (s) {
197 if (s->yomi)
198 (void)free((char *)(s->yomi-OVERRUN_MARGIN));
199 if (s->bunq)
200 (void)free((char *)(s->bunq-OVERRUN_MARGIN));
201 if (s->xq)
202 (void)free((char *)(s->xq-OVERRUN_MARGIN));
203 if (s->xqh)
204 (void)free((char *)(s->xqh-OVERRUN_MARGIN));
205 (void)free((char *)s);
206 }
207 }
208
209 static struct nstore *
allocBunStorage(len)210 allocBunStorage(len)
211 unsigned len;
212 {
213 struct nstore *s;
214
215 s = (struct nstore *)malloc((unsigned)sizeof(struct nstore));
216 if (s) {
217 Wchar *p, *q, pat;
218 int i;
219
220 s->yomi = (Wchar *)0;
221 s->bunq = (struct nbun *)0;
222 s->xq = (struct nqueue *)0;
223 s->xqh = (struct nword **)0;
224 s->nyomi = (unsigned)0;
225 s->maxyomi = (unsigned)len;
226 #ifdef RK_LOG
227 s->nblog = 0;
228 s->blog = NULL;
229 s->hlog = &s->dmi;
230 s->dmi.next = NULL; s->dmi.henkan = NULL;
231 #endif
232
233 s->yomi = (Wchar *)calloc((s->maxyomi+1+2*OVERRUN_MARGIN), sizeof(Wchar));
234 s->maxbunq = (unsigned)len;
235 s->maxbun = (unsigned)0;
236 s->curbun = 0;
237 s->bunq = (struct nbun *)calloc((unsigned)(s->maxbunq+1+2*OVERRUN_MARGIN),
238 sizeof(struct nbun));
239 s->maxxq = len;
240 s->xq = (struct nqueue *)calloc((unsigned)(s->maxxq+1+2*OVERRUN_MARGIN),
241 sizeof(struct nqueue));
242 s->xqh = (struct nword **)calloc((unsigned)(s->maxxq+1+2*OVERRUN_MARGIN),
243 sizeof(struct nword *));
244 if (!s->yomi || !s->bunq || !s->xq || !s->xqh) {
245 RkSetErrno(RK_ERRNO_ENOMEM);
246 freeBunStorage(s);
247 return (struct nstore *)0;
248 }
249 s->yomi += OVERRUN_MARGIN;
250 s->bunq += OVERRUN_MARGIN;
251 s->xq += OVERRUN_MARGIN;
252 s->xqh += OVERRUN_MARGIN;
253 p = (Wchar*)&s->yomi[0];
254 q = (Wchar*)&s->yomi[s->maxyomi+1];
255 for (i = 0; pat = (Wchar)~i, i < OVERRUN_MARGIN; i++)
256 p[-i-1] = q[i] = pat;
257 p = (Wchar*)&s->bunq[0];
258 q = (Wchar*)&s->bunq[s->maxbunq+1];
259 for (i = 0; pat = (Wchar)~i, i < OVERRUN_MARGIN; i++)
260 p[-i-1] = q[i] = pat;
261 p = (Wchar*)&s->xq[0];
262 q = (Wchar*)&s->xq[s->maxxq+1];
263 for (i = 0; pat = (Wchar)~i, i < OVERRUN_MARGIN; i++)
264 p[-i-1] = q[i] = pat;
265 p = (Wchar*)&s->xqh[0];
266 q = (Wchar*)&s->xqh[s->maxxq+1];
267 for (i = 0; pat = (Wchar)~i, i < OVERRUN_MARGIN; i++)
268 p[-i-1] = q[i] = pat;
269 s->word_in_use = 0;
270 };
271 if (!s) /* EMPTY */RkSetErrno(RK_ERRNO_ENOMEM);
272 return s;
273 }
274
275 struct nstore *
_RkReallocBunStorage(src,len)276 _RkReallocBunStorage(src, len)
277 struct nstore *src;
278 unsigned len;
279 {
280 struct nstore *dst = allocBunStorage(len);
281
282 if (dst) {
283 int i;
284
285 if (src->yomi) {
286 for (i = 0; i <= (int)src->maxyomi; i++)
287 dst->yomi[i] = src->yomi[i];
288 (void)free((char *)(src->yomi-OVERRUN_MARGIN));
289 };
290 dst->nyomi = src->nyomi;
291 if (src->bunq) {
292 for (i = 0; i <= (int)src->maxbun; i++)
293 dst->bunq[i] = src->bunq[i];
294 (void)free((char *)(src->bunq-OVERRUN_MARGIN));
295 };
296 dst->maxbun = src->maxbun;
297 dst->curbun = src->curbun;
298 if (src->xq) {
299 for (i = 0; i <= src->maxxq; i++)
300 dst->xq[i] = src->xq[i];
301 (void)free((char *)(src->xq-OVERRUN_MARGIN));
302 };
303 if (src->xqh) {
304 for (i = 0; i <= src->maxxq; i++)
305 dst->xqh[i] = src->xqh[i];
306 (void)free((char *)(src->xqh-OVERRUN_MARGIN));
307 };
308 dst->word_in_use = src->word_in_use;
309 (void)free((char *)src);
310 return(dst);
311 }
312 return((struct nstore *)0);
313 }
314
315 static struct nbun *
getCurrentBun(store)316 getCurrentBun(store)
317 struct nstore *store;
318 {
319 if (store && 0 <= store->curbun && store->curbun < (int)store->maxbun)
320 return &store->bunq[store->curbun];
321 return (struct nbun *)0;
322 }
323
324 /* RkBgnBun
325 * renbunsetu henkan wo kaishi surutameno shokisettei wo okonau
326 * reuturns:
327 * # >=0 shoki bunsetsu no kosuu
328 * -1 shoki ka sippai
329 * RK_ERRNO_ECTXNO
330 * RK_ERRNO_EINVAL
331 * RK_ERRNO_ENOMEM
332 */
333 #ifdef __STDC__
334 int
RkwBgnBun(int cx_num,Wchar * yomi,int n,int kouhomode)335 RkwBgnBun(
336 int cx_num,
337 Wchar *yomi,
338 int n,
339 int kouhomode
340 )
341 #else
342 int
343 RkwBgnBun(cx_num, yomi, n, kouhomode)
344 int cx_num;
345 Wchar *yomi;
346 int n;
347 int kouhomode;
348 #endif
349 {
350 struct RkContext *cx;
351 unsigned long mask1, mask2;
352 int asset = 0;
353
354 if (!(cx = RkGetContext(cx_num))) {
355 RkSetErrno(RK_ERRNO_ECTXNO);
356 return(-1);
357 }
358 if (IS_XFERCTX(cx)) {
359 RkSetErrno(0);
360 return(-1);
361 }
362 for (mask1 = (unsigned long) kouhomode, mask2 = 0L;
363 mask1; mask1 >>= RK_XFERBITS) {
364 if ((mask1 & (unsigned long)RK_XFERMASK) == (unsigned long)RK_CTRLHENKAN) {
365 mask1 >>= RK_XFERBITS;
366 asset = 1;
367 break;
368 }
369 mask2 = (mask2 << RK_XFERBITS) | ((unsigned long)RK_XFERMASK);
370 }
371 if (!(cx->store = allocBunStorage((unsigned)n))) {
372 RkSetErrno(RK_ERRNO_ENOMEM);
373 return(-1);
374 }
375 cx->flags |= (unsigned)CTX_XFER;
376 cx->concmode = (RK_CONNECT_WORD
377 | (asset ? ((int)mask1 & ~RK_TANBUN) :
378 (RK_MAKE_KANSUUJI | RK_MAKE_WORD | RK_MAKE_EISUUJI)));
379 cx->kouhomode = ((unsigned long)kouhomode) & mask2;
380 if (yomi) {
381 int i;
382
383 if (n <= 0) {
384 RkSetErrno(RK_ERRNO_EINVAL);
385 RkwEndBun(cx_num, 0);
386 return(-1);
387 };
388 for (i = 0; i < n; i++)
389 cx->store->yomi[i] = yomi[i];
390 cx->store->yomi[n] = 0;
391 cx->store->nyomi = n;
392 cx->store->bunq[0].nb_yoff = 0;
393 i = _RkRenbun2(cx, mask1 & RK_TANBUN ? n : 0);
394 #ifdef RK_LOG
395 {
396 FILE *fp = openLogFile(cx_num);
397 dumpBunq(cx, 0, cx->store->maxbun, 1, fp);
398 fclose(fp);
399 }
400 #endif
401 return(i);
402 } else {
403 cx->concmode |= RK_MAKE_WORD;
404 cx->flags |= (unsigned) CTX_XAUT;
405 if (n < 0) {
406 RkSetErrno(RK_ERRNO_EINVAL);
407 RkwEndBun(cx_num, 0);
408 return(-1);
409 };
410 return(0);
411 }
412 }
413
414 /* RkEndBun
415 * bunsetsu henkan wo shuuryou suru
416 * hituyou ni oujite, henkan kekka wo motoni gakushuu wo okonau
417 *
418 * return 0
419 * -1(RK_ERRNO_ECTX)
420 */
421 #ifdef __STDC__
422 int
RkwEndBun(int cx_num,int mode)423 RkwEndBun(
424 int cx_num,
425 int mode
426 )
427 #else
428 int
429 RkwEndBun(cx_num, mode)
430 int cx_num;
431 int mode;
432 #endif
433 {
434 struct RkContext *cx;
435 struct nstore *store;
436 int i;
437
438 if (!(cx = RkGetXContext(cx_num)) ||
439 !(store = cx->store)) {
440 RkSetErrno(RK_ERRNO_ECTXNO);
441 return(-1);
442 }
443 if (mode) {
444 #define DO_LEARN 1
445 if (mode != DO_LEARN) {
446 RkSetErrno(RK_ERRNO_EINVAL);
447 return -1;
448 };
449 }
450 #ifdef RK_LOG
451 if (mode) {
452 FILE *fp = openLogFile(cx_num);
453 dumpBunq(cx, 0, store->maxbun, 2, fp);
454 fclose(fp);
455 }
456 #endif
457 for (i = 0; i < (int)store->maxbun; i++)
458 (void)_RkLearnBun(cx, i, mode);
459 if (cx->flags & CTX_XAUT)
460 _RkFreeQue(store, 0, store->maxxq + 1);
461 cx->concmode &= ~(RK_CONNECT_WORD | RK_MAKE_WORD |
462 RK_MAKE_KANSUUJI | RK_MAKE_EISUUJI);
463 _RkEndBun(cx);
464 freeBunStorage(store);
465 return(0);
466 }
467
468 /* RkRemoveBun
469 * current bunsetu made wo sakujo suru
470 * current bunsetu ha 0 ni naru.
471 */
472
473 int RkwRemoveBun pro((int, int));
474
475 int
RkwRemoveBun(cx_num,mode)476 RkwRemoveBun(cx_num, mode)
477 int cx_num;
478 int mode;
479 {
480 struct RkContext *cx;
481 struct nstore *store;
482 int i, c;
483
484 if (!(cx = RkGetXContext(cx_num))
485 || !(store = cx->store)
486 || !IS_XFERCTX(cx)
487 || store->maxbun <= 0) {
488 RkSetErrno(RK_ERRNO_ECTXNO);
489 return -1;
490 }
491 for (i = 0; i <= store->curbun; i++)
492 _RkLearnBun(cx, i, mode);
493 c = store->bunq[store->curbun + 1].nb_yoff;
494 for (i = store->curbun + 1; i <= (int)store->maxbun; i++) {
495 store->bunq[i - store->curbun - 1] = store->bunq[i];
496 store->bunq[i - store->curbun - 1].nb_yoff -= c;
497 }
498 store->nyomi -= c;
499 usncopy(store->yomi, store->yomi + c, (unsigned)store->nyomi);
500 store->maxbun -= store->curbun + 1;
501 store->curbun = 0;
502 return(store->maxbun);
503 }
504
505 /* RkSubstYomi
506 * change the contents of hiragana buffer
507 * returns:
508 * # bunsetu
509 */
510
511 int RkwSubstYomi pro((int, int, int, Wchar *, int));
512
RkwSubstYomi(cx_num,ys,ye,yomi,newLen)513 RkwSubstYomi(cx_num, ys, ye, yomi, newLen)
514 int cx_num;
515 int ys, ye;
516 Wchar *yomi;
517 int newLen;
518 {
519 struct RkContext *cx;
520 struct nstore *store;
521 struct nbun *bun;
522
523 if (!(cx = RkGetContext(cx_num))) {
524 RkSetErrno(RK_ERRNO_ECTXNO);
525 return(-1);
526 }
527 if (!(store = cx->store) ||
528 !(bun = &store->bunq[store->maxbun]) ||
529 !IS_XFERCTX(cx) ||
530 !IS_XAUTCTX(cx) ||
531 !(0 <= ys && ys <= ye && ye <= (int)(store->nyomi - bun->nb_yoff)) ||
532 (newLen < 0)) {
533 RkSetErrno(RK_ERRNO_EINVAL);
534 return -1;
535 }
536 return _RkSubstYomi(cx, ys, ye, yomi, newLen);
537 }
538
539 /* RkFlushYomi
540 * force to convert the remaining hiragana
541 * returns:
542 * # bunsetu
543 */
544
545 int RkwFlushYomi pro((int));
546
547 int
RkwFlushYomi(cx_num)548 RkwFlushYomi(cx_num)
549 int cx_num;
550 {
551 struct RkContext *cx;
552 if (!(cx = RkGetContext(cx_num)) ||
553 !IS_XFERCTX(cx) ||
554 !IS_XAUTCTX(cx)) {
555 RkSetErrno(RK_ERRNO_ECTXNO);
556 return(-1);
557 }
558 return(_RkFlushYomi(cx));
559 }
560
561 /* RkResize/RkEnlarge/RkShorten
562 * current bunsetsu no ookisa wo henkou
563 */
564 int
_RkResize(cx_num,len,t)565 _RkResize(cx_num, len, t)
566 int cx_num;
567 int len;
568 int t;
569 {
570 struct RkContext *cx;
571 struct nbun *bun;
572 struct nstore *store;
573
574 if (!(cx = RkGetXContext(cx_num)) ||
575 !(store = cx->store) ||
576 !(bun = getCurrentBun(store))) {
577 RkSetErrno(RK_ERRNO_ECTXNO);
578 return(-1);
579 }
580 if (t)
581 len = HowManyChars(store->yomi + store->bunq[store->curbun].nb_yoff, len);
582 if (0 < len && (unsigned)(bun->nb_yoff + len) <= store->nyomi) {
583 bun->nb_flags |= RK_REARRANGED;
584 #ifndef RK_LOG
585 return(_RkRenbun2(cx, len));
586 #else
587 {
588 int ret_val = _RkRenbun2(cx, len);
589 FILE *fp = openLogFile(cx_num);
590 dumpBunq(cx, store->curbun, store->maxbun, 3, fp);
591 fclose(fp);
592 return ret_val;
593 }
594 #endif
595 }
596 return(store->maxbun);
597 }
598
599 int RkwResize pro((int, int));
600
601 int
RkwResize(cx_num,len)602 RkwResize(cx_num, len)
603 int cx_num;
604 int len;
605 {
606 return(_RkResize(cx_num, len, 0));
607 }
608
609 #ifdef __STDC__
610 int
RkeResize(int cx_num,int len)611 RkeResize(
612 int cx_num,
613 int len
614 )
615 #else
616 int
617 RkeResize(cx_num, len)
618 int cx_num;
619 int len;
620 #endif
621 {
622 return(_RkResize(cx_num, len, 1));
623 }
624
625 int RkwEnlarge pro((int));
626
627 int
RkwEnlarge(cx_num)628 RkwEnlarge(cx_num)
629 int cx_num;
630 {
631 struct RkContext *cx;
632 struct nstore *store;
633 struct nbun *bun;
634
635 if (!(cx = RkGetXContext(cx_num)) ||
636 !(store = cx->store)||
637 !(bun = getCurrentBun(store))) {
638 RkSetErrno(RK_ERRNO_ENOMEM);
639 return(0);
640 }
641 if (store->nyomi > (unsigned)(bun->nb_yoff + bun->nb_curlen) &&
642 store->yomi[bun->nb_yoff + bun->nb_curlen]) {
643 bun->nb_flags |= RK_REARRANGED;
644 #ifdef RK_LOG
645 {
646 int ret_val = _RkRenbun2(cx, (int)(bun->nb_curlen + 1));
647 FILE *fp = openLogFile(cx_num);
648 dumpBunq(cx, store->curbun, store->maxbun, 3, fp);
649 fclose(fp);
650 return ret_val;
651 }
652 #else
653 return(_RkRenbun2(cx, (int)(bun->nb_curlen + 1)));
654 #endif
655 }
656 return(store->maxbun);
657 }
658
659 int RkwShorten pro((int));
660
661 int
RkwShorten(cx_num)662 RkwShorten(cx_num)
663 int cx_num;
664 {
665 struct RkContext *cx;
666 struct nstore *store;
667 struct nbun *bun;
668
669 if (!(cx = RkGetXContext(cx_num)) ||
670 !(store = cx->store) ||
671 !(bun = getCurrentBun(store))) {
672 RkSetErrno(RK_ERRNO_ECTXNO);
673 return 0;
674 }
675 if (bun->nb_curlen > 1) {
676 bun->nb_flags |= RK_REARRANGED;
677 #ifdef RK_LOG
678 {
679 int ret_val = _RkRenbun2(cx, (int)(bun->nb_curlen - 1));
680 FILE *fp = openLogFile(cx_num);
681 dumpBunq(cx, store->curbun, store->maxbun, 3, fp);
682 fclose(fp);
683 return ret_val;
684 }
685 #else
686 return(_RkRenbun2(cx, (int)(bun->nb_curlen - 1)));
687 #endif
688 }
689 return(store->maxbun);
690 }
691
692 /* RkStoreYomi
693 * current bunsetu no yomi wo sitei sareta mono to okikaeru
694 * okikaeta noti, saihen kan suru
695 */
696
697 int RkwStoreYomi pro((int, Wchar *, int));
698
699 int
RkwStoreYomi(cx_num,yomi,nlen)700 RkwStoreYomi(cx_num, yomi, nlen)
701 int cx_num;
702 Wchar *yomi;
703 int nlen;
704 {
705 unsigned nmax, omax, cp;
706 Wchar *s, *d, *e;
707 int i, olen, diff;
708 struct RkContext *cx;
709 struct nstore *store;
710 struct nbun *bun;
711
712 if (!(cx = RkGetXContext(cx_num)) ||
713 !(store = cx->store) ||
714 !(bun = getCurrentBun(store))) {
715 RkSetErrno(RK_ERRNO_ECTXNO);
716 return -1;
717 }
718 if ((nlen && !yomi) || nlen < 0 || uslen(yomi) < nlen) {
719 RkSetErrno(RK_ERRNO_EINVAL);
720 return -1;
721 }
722 nmax = store->nyomi + (diff = nlen - (olen = bun->nb_curlen));
723 omax = store->nyomi;
724 /* nobiru */
725 if (nlen > olen) {
726 if (!(store = _RkReallocBunStorage(store, store->maxyomi + diff))) {
727 RkSetErrno(RK_ERRNO_ENOMEM);
728 return -1;
729 }
730 cx->store = store;
731 bun = getCurrentBun(store);
732 /* shift yomi */
733 s = store->yomi + omax;
734 d = store->yomi + nmax;
735 e = store->yomi + bun->nb_yoff + olen;
736 while (s > e)
737 *--d = *--s;
738 } else if (nlen < olen) { /* chizimu */
739 s = store->yomi + bun->nb_yoff + olen;
740 d = store->yomi + bun->nb_yoff + nlen;
741 e = store->yomi + omax;
742 while (s < e)
743 *d++ = *s++;
744 }
745 store->yomi[nmax] = (Wchar)0;
746 store->nyomi = nmax;
747 for (i = store->curbun + 1; i <= (int)store->maxbun; i++)
748 store->bunq[i].nb_yoff += diff;
749 cp = store->curbun;
750 if (!nlen) {
751 _RkFreeBunq(store);
752 for (i = store->curbun; i < (int)store->maxbun; i++)
753 store->bunq[i] = store->bunq[i + 1];
754 store->maxbun--;
755 cp = store->curbun;
756 if (cp >= store->maxbun && cp > 0)
757 cp -= 1;
758 } else
759 usncopy((store->yomi + bun->nb_yoff), yomi, (unsigned)nlen);
760 #ifdef RK_LOG
761 {
762 int ret_val = _RkRenbun2(cx, 0);
763 FILE *fp = openLogFile(cx_num);
764 fputs("�ɤߤ��ִ�\n", fp);
765 dumpBunq(cx, store->curbun, store->maxbun, 1, fp);
766 fclose(fp);
767 if ((i = ret_val) != -1)
768 store->curbun = cp;
769 return(i);
770 }
771 #else
772 if ((i = _RkRenbun2(cx, 0)) != -1)
773 store->curbun = cp;
774 return(i);
775 #endif
776 }
777
778 /* RkGoTo/RkLeft/RkRight
779 * current bunsetu no idou
780 */
781
782 int RkwGoTo pro((int, int));
783
784 int
RkwGoTo(cx_num,bnum)785 RkwGoTo(cx_num, bnum)
786 int cx_num;
787 int bnum;
788 {
789 struct RkContext *cx;
790 struct nstore *store;
791
792 if (!(cx = RkGetXContext(cx_num)) ||
793 !(store = cx->store) ||
794 !store->maxbun) {
795 RkSetErrno(RK_ERRNO_ECTXNO);
796 return 0;
797 }
798 if ((0 <= bnum) && (bnum < (int)store->maxbun))
799 store->curbun = bnum;
800 return(store->curbun);
801 }
802
803 #ifdef __STDC__
804 int
RkwLeft(int cx_num)805 RkwLeft(
806 int cx_num
807 )
808 #else
809 int
810 RkwLeft(cx_num)
811 int cx_num;
812 #endif
813 {
814 struct RkContext *cx;
815 struct nstore *store;
816
817 if (!(cx = RkGetXContext(cx_num)) ||
818 !(store = cx->store) ||
819 !store->maxbun) {
820 RkSetErrno(RK_ERRNO_ECTXNO);
821 return 0;
822 }
823 if (--store->curbun < 0)
824 store->curbun = store->maxbun - 1;
825 return store->curbun;
826 }
827
828 #ifdef __STDC__
829 int
RkwRight(int cx_num)830 RkwRight(
831 int cx_num
832 )
833 #else
834 int
835 RkwRight(cx_num)
836 int cx_num;
837 #endif
838 {
839 struct RkContext *cx;
840 struct nstore *store;
841
842 if (!(cx = RkGetXContext(cx_num)) ||
843 !(store = cx->store) ||
844 !store->maxbun) {
845 RkSetErrno(RK_ERRNO_ECTXNO);
846 return 0;
847 }
848 if (++store->curbun >= (int)store->maxbun)
849 store->curbun = 0;
850 return(store->curbun);
851 }
852
853 /* RkXfer/RkNfer/RkNext/RkPrev
854 * current kouho wo henkou
855 */
856 static int
countCand(cx)857 countCand(cx)
858 struct RkContext *cx;
859 {
860 struct nbun *bun;
861 int maxcand = 0;
862 unsigned long mask;
863
864 bun = getCurrentBun(cx->store);
865 if (bun) {
866 maxcand = bun->nb_maxcand;
867 for (mask = cx->kouhomode; mask; mask >>= RK_XFERBITS)
868 maxcand++;
869 };
870 return(maxcand);
871 }
872
873 static int
getXFER(cx,cnum)874 getXFER(cx, cnum)
875 struct RkContext *cx;
876 int cnum;
877 {
878 struct nbun *bun = getCurrentBun(cx->store);
879
880 cnum -= ((int)bun->nb_maxcand);
881 return(cnum < 0 ? RK_NFER : (cx->kouhomode>>(RK_XFERBITS*cnum))&RK_XFERMASK);
882 }
883
884 #ifdef __STDC__
885 int
RkwXfer(int cx_num,int knum)886 RkwXfer(
887 int cx_num,
888 int knum
889 )
890 #else
891 int
892 RkwXfer(cx_num, knum)
893 int cx_num;
894 int knum;
895 #endif
896 {
897 struct RkContext *cx;
898 struct nbun *bun;
899
900 if (!(cx = RkGetXContext(cx_num)) ||
901 !(cx->store) ||
902 !(bun = getCurrentBun(cx->store))) {
903 RkSetErrno(RK_ERRNO_ECTXNO);
904 return 0;
905 }
906 if (0 <= knum && knum < countCand(cx))
907 bun->nb_curcand = knum;
908 return(bun->nb_curcand);
909 }
910
911 #ifdef __STDC__
912 int
RkwNfer(int cx_num)913 RkwNfer(
914 int cx_num
915 )
916 #else
917 int
918 RkwNfer(cx_num)
919 int cx_num;
920 #endif
921 {
922 struct RkContext *cx;
923 struct nbun *bun;
924
925 if (!(cx = RkGetXContext(cx_num)) ||
926 !(cx->store) ||
927 !(bun = getCurrentBun(cx->store))) {
928 RkSetErrno(RK_ERRNO_ECTXNO);
929 return(0);
930 }
931 return(bun->nb_curcand = bun->nb_maxcand);
932 }
933
934 int RkwNext pro((int));
935
936 int
RkwNext(cx_num)937 RkwNext(cx_num)
938 int cx_num;
939 {
940 struct RkContext *cx;
941 struct nbun *bun;
942
943 if (!(cx = RkGetXContext(cx_num)) ||
944 !(cx->store) ||
945 !(bun = getCurrentBun(cx->store))) {
946 RkSetErrno(RK_ERRNO_ECTXNO);
947 return(0);
948 }
949 if (++bun->nb_curcand >= (Wchar)countCand(cx))
950 bun->nb_curcand = 0;
951 return(bun->nb_curcand);
952 }
953
954 int RkwPrev pro((int));
955
956 int
RkwPrev(cx_num)957 RkwPrev(cx_num)
958 int cx_num;
959 {
960 struct RkContext *cx;
961 struct nbun *bun;
962
963 if (!(cx = RkGetXContext(cx_num)) ||
964 !(cx->store) ||
965 !(bun = getCurrentBun(cx->store))) {
966 RkSetErrno(RK_ERRNO_ECTXNO);
967 return(0);
968 }
969
970 if (!bun->nb_curcand)
971 bun->nb_curcand = countCand(cx);
972 return(--bun->nb_curcand);
973 }
974
975 /* findBranch
976 * shiteisareta kouho wo fukumu path wo motomeru
977 */
978 static
979 struct nword *
findBranch(store,cnum)980 findBranch(store, cnum)
981 struct nstore *store;
982 int cnum;
983 {
984 struct nbun *bun;
985 struct nword *w;
986
987 if (!(bun = getCurrentBun(store)) ||
988 (0 > cnum) ||
989 (cnum >= (int)bun->nb_maxcand))
990 return((struct nword *)0);
991 for (w = bun->nb_cand; w; w = w->nw_next) {
992 if (CanSplitWord(w) && bun->nb_curlen == w->nw_ylen) {
993 if (cnum-- <= 0)
994 return(w);
995 }
996 }
997 return((struct nword *)0);
998 }
999
1000 /* RkGetStat
1001 */
1002 #ifdef __STDC__
1003 int
RkwGetStat(int cx_num,RkStat * st)1004 RkwGetStat(
1005 int cx_num,
1006 RkStat *st
1007 )
1008 #else
1009 int
1010 RkwGetStat(cx_num, st)
1011 int cx_num;
1012 RkStat *st;
1013 #endif
1014 {
1015 struct RkContext *cx;
1016 struct nstore *store;
1017 struct nbun *bun;
1018 struct nword *cw, *lw;
1019
1020 if (!(cx = RkGetXContext(cx_num)) ||
1021 !(store = cx->store) ||
1022 !(bun = getCurrentBun(store)) ||
1023 !st) {
1024 RkSetErrno(RK_ERRNO_ECTXNO);
1025 return -1;
1026 }
1027 /* set up void values */
1028 st->bunnum = st->candnum = st->maxcand =
1029 st->diccand = st->ylen = st->klen = st->tlen = 0;
1030 st->bunnum = store->curbun;
1031 st->candnum = bun->nb_curcand;
1032
1033 st->maxcand = countCand(cx);
1034 st->diccand = bun->nb_maxcand;
1035 st->ylen = bun->nb_curlen;
1036 st->klen = bun->nb_curlen;
1037 st->tlen = 1;
1038 /* look up the word node containing the current candidate */
1039 cw = findBranch(store, (int)bun->nb_curcand);
1040 if (cw) {
1041 st->klen = st->tlen = 0;
1042 for (; cw; cw = cw->nw_left) {
1043 if (!(lw = cw->nw_left))
1044 break;
1045 if (cw->nw_klen == lw->nw_klen)
1046 st->klen += (cw->nw_ylen - lw->nw_ylen);
1047 else
1048 st->klen += (cw->nw_klen - lw->nw_klen);
1049 st->tlen++;
1050 }
1051 } else {
1052 Wchar *yomi = store->yomi + bun->nb_yoff;
1053 switch(getXFER(cx, (int)bun->nb_curcand)) {
1054 default:
1055 case RK_XFER:
1056 st->klen = RkwCvtHira((Wchar *)0, 0, yomi, st->ylen);
1057 break;
1058 case RK_KFER:
1059 st->klen = RkwCvtKana((Wchar *)0, 0, yomi, st->ylen);
1060 break;
1061 case RK_HFER:
1062 st->klen = RkwCvtHan((Wchar *)0, 0, yomi, st->ylen);
1063 break;
1064 case RK_ZFER:
1065 st->klen = RkwCvtZen((Wchar *)0, 0, yomi, st->ylen);
1066 break;
1067 }
1068 }
1069 return 0;
1070 }
1071
1072 /* RkGetStat
1073 */
1074 #ifdef __STDC__
1075 int
RkeGetStat(int cx_num,RkStat * st)1076 RkeGetStat(
1077 int cx_num,
1078 RkStat *st
1079 )
1080 #else
1081 int
1082 RkeGetStat(cx_num, st)
1083 int cx_num;
1084 RkStat *st;
1085 #endif
1086 {
1087 struct RkContext *cx;
1088 struct nstore *store;
1089 Wchar *yomi;
1090 int res, klen;
1091 #ifndef USE_MALLOC_FOR_BIG_ARRAY
1092 Wchar kanji[RK_LEN_WMAX+1];
1093 #else
1094 Wchar *kanji = (Wchar *)malloc(sizeof(Wchar) * (RK_LEN_WMAX + 1));
1095 if (!kanji) {
1096 return -1;
1097 }
1098 #endif
1099
1100 if (!(cx = RkGetXContext(cx_num)) || !(store = cx->store)) {
1101 RkSetErrno(RK_MSG_ECTXNO);
1102 res = -1;
1103 goto return_res;
1104 }
1105
1106 yomi = store->yomi + store->bunq[store->curbun].nb_yoff;
1107 klen = RkwGetKanji(cx_num, kanji, RK_LEN_WMAX + 1);
1108 res = RkwGetStat(cx_num, st);
1109 if (res < 0 || klen != st->klen) {
1110 res = -1;
1111 goto return_res;
1112 }
1113 if (st) {
1114 st->ylen = HowManyBytes(yomi, st->ylen);
1115 st->klen = HowManyBytes(kanji, klen);
1116 }
1117 return_res:
1118 #ifdef USE_MALLOC_FOR_BIG_ARRAY
1119 (void)free((char *)kanji);
1120 #endif
1121 return res;
1122 }
1123
1124 static int addIt pro((struct nword *, Wchar *,
1125 int (*proc)(Wchar *, int, int, Wchar *, Wchar *,
1126 RkLex *, struct RkContext *),
1127 Wchar *dst, int, int, unsigned long,
1128 struct RkContext *));
1129 static int
addIt(cw,key,proc,dst,ind,maxdst,mode,cx)1130 addIt(cw, key, proc, dst, ind, maxdst, mode, cx)
1131 struct nword *cw;
1132 Wchar *key;
1133 int (*proc) pro((Wchar *, int, int, Wchar *, Wchar *,
1134 RkLex *, struct RkContext *));
1135 Wchar *dst;
1136 int ind;
1137 int maxdst;
1138 unsigned long mode;
1139 struct RkContext *cx;
1140 {
1141 struct nword *lw;
1142 Wchar *y, *_RkGetKanji();
1143 RkLex lex;
1144
1145 lw = cw->nw_left;
1146 if (lw) {
1147 ind = addIt(lw, key, proc, dst, ind, maxdst, mode, cx);
1148 y = key + lw->nw_ylen;
1149 lex.ylen = cw->nw_ylen - lw->nw_ylen;
1150 lex.klen = cw->nw_klen - lw->nw_klen;
1151 lex.rownum = cw->nw_rowcol;
1152 #ifdef NEED_DEF
1153 lex.colnum = cw->nw_rowcol;
1154 #endif
1155 lex.dicnum = cw->nw_class;
1156 ind = (*proc)(dst, ind, maxdst, y, _RkGetKanji(cw, y, mode), &lex, cx);
1157 }
1158 return ind;
1159 }
1160
1161 static int
getIt(cx,cnum,proc,dst,max)1162 getIt(cx, cnum, proc, dst, max)
1163 struct RkContext *cx;
1164 int cnum;
1165 int (*proc) pro((Wchar *, int, int, Wchar *, Wchar *,
1166 RkLex *, struct RkContext *));
1167 Wchar *dst;
1168 int max;
1169 {
1170 struct nstore *store = cx->store;
1171 struct nbun *bun;
1172 struct nword *w;
1173
1174 if (!(bun = getCurrentBun(store)) ||
1175 !(w = findBranch(store, cnum)))
1176 return(-1);
1177 return addIt(w, store->yomi + bun->nb_yoff, proc, dst, 0, max,
1178 (unsigned long)cx->concmode, cx);
1179 }
1180
1181 /*ARGSUSED*/
1182 static int
addYomi(dst,ind,max,yomi,kanji,lex)1183 addYomi(dst, ind, max, yomi, kanji, lex)
1184 Wchar *dst;
1185 int ind;
1186 int max;
1187 Wchar *yomi;
1188 Wchar *kanji;
1189 RkLex *lex;
1190 {
1191 int ylen;
1192
1193 ylen = lex->ylen;
1194 while (ylen--) {
1195 if (ind < max) {
1196 if (dst)
1197 dst[ind] = *yomi++;
1198 ind++;
1199 }
1200 }
1201 return ind;
1202 }
1203 /* RkGetYomi
1204 * current bunsetu no yomi wo toru
1205 */
1206
1207 int RkwGetYomi pro((int, Wchar *, int));
1208
1209 int
RkwGetYomi(cx_num,yomi,maxyomi)1210 RkwGetYomi(cx_num, yomi, maxyomi)
1211 int cx_num;
1212 Wchar *yomi;
1213 int maxyomi;
1214 {
1215 struct RkContext *cx;
1216 struct nbun *bun;
1217 RkLex lex;
1218 int i;
1219 struct nstore *store;
1220
1221 if (!(cx = RkGetXContext(cx_num)) ||
1222 !(store = cx->store) ||
1223 !(bun = getCurrentBun(store))) {
1224 RkSetErrno(RK_ERRNO_ECTXNO);
1225 return -1;
1226 };
1227 if (!yomi) {
1228 RkSetErrno(RK_ERRNO_EINVAL);
1229 return -1;
1230 };
1231 lex.ylen = bun->nb_curlen;
1232 i = addYomi(yomi, 0, maxyomi - 1,
1233 store->yomi + bun->nb_yoff,
1234 store->yomi+bun->nb_yoff,
1235 &lex);
1236 if (yomi && i < maxyomi)
1237 yomi[i] = (Wchar)0;
1238 return i;
1239 }
1240
1241 int RkwGetLastYomi pro((int, Wchar *, int));
1242
1243 int
RkwGetLastYomi(cx_num,yomi,maxyomi)1244 RkwGetLastYomi(cx_num, yomi, maxyomi)
1245 int cx_num;
1246 Wchar *yomi;
1247 int maxyomi;
1248 {
1249 struct RkContext *cx;
1250 struct nbun *bun;
1251 struct nstore *store;
1252 int nyomi;
1253
1254 if (!(cx = RkGetXContext(cx_num)) ||
1255 !(store = cx->store) ||
1256 !(bun = &store->bunq[store->maxbun])) {
1257 RkSetErrno(RK_ERRNO_ECTXNO);
1258 return -1;
1259 }
1260 if (!(cx->flags & CTX_XAUT) || maxyomi < 0) {
1261 RkSetErrno(RK_ERRNO_EINVAL);
1262 return -1;
1263 }
1264 nyomi = store->nyomi - bun->nb_yoff;
1265 if (yomi) {
1266 usncopy(yomi, store->yomi + bun->nb_yoff, (unsigned)(maxyomi));
1267 if (nyomi + 1 < maxyomi) {
1268 yomi[nyomi] = (Wchar)0;
1269 } else {
1270 yomi[maxyomi - 1] = (Wchar)0;
1271 };
1272 }
1273 return nyomi;
1274 }
1275
1276 /*ARGSUSED*/
1277 static int
addKanji(dst,ind,max,yomi,kanji,lex,cx)1278 addKanji(dst, ind, max, yomi, kanji, lex, cx)
1279 Wchar *dst;
1280 int ind;
1281 int max;
1282 Wchar *yomi;
1283 Wchar *kanji;
1284 RkLex *lex;
1285 struct RkContext *cx; /* ARGSUSED */
1286 {
1287 int klen;
1288
1289 klen = lex->klen;
1290 while (klen-- > 0) {
1291 if (ind < max) {
1292 if (dst)
1293 dst[ind] = *kanji++;
1294 ind++;
1295 }
1296 }
1297 return ind;
1298 }
1299
1300 static int
getKanji(cx,cnum,dst,maxdst)1301 getKanji(cx, cnum, dst, maxdst)
1302 struct RkContext *cx;
1303 int cnum;
1304 Wchar *dst;
1305 int maxdst;
1306 {
1307 struct nbun *bun = getCurrentBun(cx->store);
1308 Wchar *yomi;
1309 int i, ylen;
1310
1311 i = getIt(cx, cnum, addKanji, dst, maxdst - 1);
1312 if (i < 0) {
1313 yomi = cx->store->yomi + bun->nb_yoff;
1314 ylen = bun->nb_curlen;
1315 switch(getXFER(cx, cnum)) {
1316 default:
1317 case RK_XFER:
1318 i = RkwCvtHira(dst, maxdst, yomi, ylen); break;
1319 case RK_KFER:
1320 i = RkwCvtKana(dst, maxdst, yomi, ylen); break;
1321 case RK_HFER:
1322 i = RkwCvtHan(dst, maxdst, yomi, ylen); break;
1323 case RK_ZFER:
1324 i = RkwCvtZen(dst, maxdst, yomi, ylen); break;
1325 }
1326 }
1327 if (dst && i < maxdst)
1328 dst[i] = (Wchar)0;
1329 return i;
1330 }
1331
1332 /* RkGetKanji
1333 * current bunsetu no kanji tuduri wo toru
1334 */
1335
1336 int RkwGetKanji pro((int, Wchar *, int));
1337
1338 int
RkwGetKanji(cx_num,dst,maxdst)1339 RkwGetKanji(cx_num, dst, maxdst)
1340 int cx_num;
1341 Wchar *dst;
1342 int maxdst;
1343 {
1344 RkContext *cx;
1345 struct nbun *bun;
1346 int i;
1347
1348 if (!(cx = RkGetXContext(cx_num)) ||
1349 !(cx->store) ||
1350 !(bun = getCurrentBun(cx->store))) {
1351 RkSetErrno(RK_ERRNO_ECTXNO);
1352 return -1;
1353 }
1354
1355 i = getKanji(cx, (int)bun->nb_curcand, dst, maxdst);
1356 if (dst && i < maxdst)
1357 dst[i] = 0;
1358 return i;
1359 }
1360
1361 /* RkGetKanjiList
1362 * genzai sentaku sareta kouho mojiretu wo toridasu
1363 */
1364 #ifdef __STDC__
1365 int
RkwGetKanjiList(int cx_num,Wchar * dst,int maxdst)1366 RkwGetKanjiList(
1367 int cx_num,
1368 Wchar *dst,
1369 int maxdst
1370 )
1371 #else
1372 int
1373 RkwGetKanjiList(cx_num, dst, maxdst)
1374 int cx_num;
1375 Wchar *dst;
1376 int maxdst;
1377 #endif
1378 {
1379 struct RkContext *cx;
1380 int i, len, ind = 0, num = 0;
1381 int maxcand;
1382
1383 if (!(cx = RkGetXContext(cx_num)) ||
1384 !(cx->store)) {
1385 RkSetErrno(RK_ERRNO_ECTXNO);
1386 return -1;
1387 }
1388 maxcand = countCand(cx);
1389 for (i = 0; i < maxcand; i++) {
1390 if (dst)
1391 len = getKanji(cx, i, dst + ind, maxdst - ind - 1);
1392 else
1393 len = getKanji(cx, i, dst, maxdst - ind - 1);
1394 if (0 < len && ind + len + 1 < maxdst - 1) {
1395 if (dst)
1396 dst[ind + len] = (Wchar)0;
1397 ind += len + 1;
1398 num++;
1399 }
1400 }
1401 if (dst && ind < maxdst)
1402 dst[ind] = (Wchar)0;
1403 return num;
1404 }
1405
1406 /* RkGetLex
1407 * current bunsetu no hishi jouhou wo toru
1408 */
1409 /*ARGSUSED*/
1410 static int
addLex(dst,ind,max,yomi,kanji,lex,cx)1411 addLex(dst, ind, max, yomi, kanji, lex, cx)
1412 RkLex *dst;
1413 int ind;
1414 int max;
1415 Wchar *yomi;
1416 Wchar *kanji;
1417 RkLex *lex;
1418 struct RkContext *cx; /* ARGSUSED */
1419 {
1420 if (ind + 1 <= max) {
1421 if (dst)
1422 dst[ind] = *lex;
1423 ind++;
1424 }
1425 return ind;
1426 }
1427
1428 #ifdef __STDC__
1429 int
RkwGetLex(int cx_num,RkLex * dst,int maxdst)1430 RkwGetLex(
1431 int cx_num,
1432 RkLex *dst,
1433 int maxdst
1434 )
1435 #else
1436 int
1437 RkwGetLex(cx_num, dst, maxdst)
1438 int cx_num;
1439 RkLex *dst;
1440 int maxdst;
1441 #endif
1442 {
1443 RkContext *cx;
1444 struct nbun *bun;
1445 int i;
1446
1447 if (!(cx = RkGetXContext(cx_num)) ||
1448 !(cx->store) ||
1449 !(bun = getCurrentBun(cx->store))) {
1450 RkSetErrno(RK_ERRNO_ECTXNO);
1451 return -1;
1452 }
1453 i = getIt(cx, (int)bun->nb_curcand, addLex, (Wchar *)dst, maxdst - 1);
1454 if (i < 0) {
1455 if (dst && 1 < maxdst) {
1456 dst[0].ylen = bun->nb_curlen;
1457 dst[0].klen = bun->nb_curlen;
1458 dst[0].rownum = cx->gram->P_BB; /* ʸ�� */
1459 dst[0].colnum = cx->gram->P_BB; /* ʸ�� */
1460 dst[0].dicnum = ND_EMP;
1461 }
1462 i = 1;
1463 }
1464 return i;
1465 }
1466
1467 /* RkeGetLex -- �ۤ� RkwGetLex ��Ʊ������Ĺ���ϥХ���Ĺ���֤� */
1468
1469 #ifdef __STDC__
1470 int
RkeGetLex(int cx_num,RkLex * dst,int maxdst)1471 RkeGetLex(
1472 int cx_num,
1473 RkLex *dst,
1474 int maxdst
1475 )
1476 #else
1477 int
1478 RkeGetLex(cx_num, dst, maxdst)
1479 int cx_num;
1480 RkLex *dst;
1481 int maxdst;
1482 #endif
1483 {
1484 struct RkContext *cx;
1485 struct nstore *store;
1486 Wchar *yomi, *kp;
1487 int nwords, i;
1488 #ifndef USE_MALLOC_FOR_BIG_ARRAY
1489 Wchar kanji[RK_LEN_WMAX+1];
1490 #else
1491 Wchar *kanji = (Wchar *)malloc(sizeof(Wchar) * (RK_LEN_WMAX + 1));
1492 if (!kanji) {
1493 return -1;
1494 }
1495 #endif
1496
1497 if (!(cx = RkGetXContext(cx_num)) ||
1498 !(store = cx->store)) {
1499 RkSetErrno(RK_MSG_ECTXNO);
1500 nwords = -1;
1501 goto return_nwords;
1502 }
1503
1504 yomi = store->yomi + store->bunq[store->curbun].nb_yoff;
1505 (void)RkwGetKanji(cx_num, kanji, RK_LEN_WMAX + 1);
1506 kp = kanji;
1507 nwords = RkwGetLex(cx_num, dst, maxdst);
1508 if (dst) {
1509 for (i = 0; i < nwords; i++) {
1510 int tmp;
1511 tmp = dst[i].ylen;
1512 dst[i].ylen = HowManyBytes(yomi, tmp); yomi += tmp;
1513 tmp = dst[i].klen;
1514 dst[i].klen = HowManyBytes(kp, tmp); kp += tmp;
1515 }
1516 }
1517 return_nwords:
1518 #ifdef USE_MALLOC_FOR_BIG_ARRAY
1519 (void)free((char *)kanji);
1520 #endif
1521 return nwords;
1522 }
1523
1524 /*ARGSUSED*/
1525 static int
addHinshi(dst,ind,max,yomi,kanji,lex,cx)1526 addHinshi(dst, ind, max, yomi, kanji, lex, cx)
1527 Wchar *dst;
1528 int ind;
1529 int max;
1530 Wchar *yomi;
1531 Wchar *kanji;
1532 RkLex *lex;
1533 struct RkContext *cx;
1534 {
1535 int bytes;
1536 Wchar *p;
1537 #ifndef USE_MALLOC_FOR_BIG_ARRAY
1538 Wchar hinshi[256];
1539 #else
1540 Wchar *hinshi = (Wchar *)malloc(sizeof(Wchar) * 256);
1541 if (!hinshi) {
1542 return ind;
1543 }
1544 #endif
1545
1546 if (cx) {
1547 p = RkUparseGramNum(cx->gram->gramdic, lex->rownum, hinshi, 256);
1548 if (p) {
1549 bytes = p - hinshi;
1550 if (ind + bytes < max) {
1551 if (dst)
1552 usncopy(dst + ind, hinshi, bytes);
1553 ind += bytes;
1554 }
1555 }
1556 }
1557 #ifdef USE_MALLOC_FOR_BIG_ARRAY
1558 (void)free((char *)hinshi);
1559 #endif
1560 return ind;
1561 }
1562
1563 /* RkGetHinshi
1564 * current bunsetu no hinshi mojiretu wo toru
1565 */
1566
1567 int RkwGetHinshi pro((int, Wchar *, int));
1568
1569 int
RkwGetHinshi(cx_num,dst,maxdst)1570 RkwGetHinshi(cx_num, dst, maxdst)
1571 int cx_num;
1572 Wchar *dst;
1573 int maxdst;
1574 {
1575 struct RkContext *cx;
1576 struct nbun *bun;
1577 int i;
1578
1579 if (!(cx = RkGetXContext(cx_num)) ||
1580 !(cx->store) ||
1581 !(bun = getCurrentBun(cx->store))) {
1582 RkSetErrno(RK_ERRNO_ECTXNO);
1583 return(-1);
1584 }
1585 i = getIt(cx, (int)bun->nb_curcand, addHinshi, dst, maxdst - 1);
1586 if (i < 0) {
1587 if (dst && 1 < maxdst)
1588 dst[0] = (Wchar)0;
1589 i = 1;
1590 }
1591 return(i);
1592 }
1593
1594 #include <sys/types.h>
1595 #include <sys/stat.h>
1596
1597 #define CloseContext(a) {if ((a) != cx_num) RkwCloseContext(a);}
1598
1599 int
1600 #ifdef __STDC__
RkwQueryDic(int cx_num,char * dirname,char * dicname,struct DicInfo * status)1601 RkwQueryDic(
1602 int cx_num,
1603 char *dirname,
1604 char *dicname,
1605 struct DicInfo *status
1606 )
1607 #else
1608 RkwQueryDic(cx_num, dirname, dicname, status)
1609 int cx_num;
1610 char *dirname;
1611 char *dicname;
1612 struct DicInfo *status;
1613 #endif
1614 {
1615 struct RkContext *cx;
1616 int new_cx_num, size;
1617 unsigned char *buff;
1618 char *file;
1619 struct DM *dm;
1620 struct DF *df;
1621 struct stat st;
1622
1623 if (!(cx = RkGetContext(cx_num))
1624 || !status || !dirname || !dicname || !dicname[0])
1625 return(-1);
1626 size = strlen(dicname) + 1;
1627 if (!(buff = (unsigned char *)malloc(size)))
1628 return(-1);
1629 (void)strcpy((char *)buff, dicname);
1630 if (*dirname && strcmp(dirname, cx->ddpath[0]->dd_name)
1631 && strcmp(dirname, (char *)SYSTEM_DDHOME_NAME)) {
1632 if((new_cx_num = RkwCreateContext()) < 0) {
1633 (void)free((char *)buff);
1634 return BADCONT;
1635 }
1636 if(RkwSetDicPath(new_cx_num, dirname) < 0) {
1637 CloseContext(new_cx_num);
1638 (void)free((char *)buff);
1639 return NOTALC;
1640 }
1641 if (!(cx = RkGetContext(new_cx_num))) {
1642 (void)free((char *)buff);
1643 return(-1);
1644 }
1645 } else {
1646 if (!strcmp(dirname, (char *)SYSTEM_DDHOME_NAME))
1647 dirname = SYSTEM_DDHOME_NAME;
1648 else
1649 dirname = cx->ddpath[0]->dd_name;
1650 new_cx_num = cx_num;
1651 }
1652 if (!strcmp(dirname, (char *)SYSTEM_DDHOME_NAME)) {
1653 if (!(dm = _RkSearchDDP(cx->ddpath, dicname))) {
1654 CloseContext(new_cx_num);
1655 (void)free((char *)buff);
1656 return NOENT;
1657 }
1658 } else {
1659 if (!(dm = _RkSearchUDDP(cx->ddpath, dicname))) {
1660 CloseContext(new_cx_num);
1661 (void)free((char *)buff);
1662 return NOENT;
1663 }
1664 }
1665 df = dm->dm_file;
1666 if (df) {
1667 file = _RkCreatePath(df->df_direct, df->df_link);
1668 if (file) {
1669 status->di_dic = (unsigned char *)dm->dm_nickname;
1670 status->di_file = (unsigned char *)df->df_link;
1671 status->di_form = (DM2TYPE(dm) == DF_TEMPDIC) ? RK_TXT : RK_BIN;
1672 status->di_kind = dm->dm_class;
1673 status->di_count = stat(file, &st) >= 0 ? st.st_size : 0;
1674 status->di_time = stat(file, &st) >= 0 ? st.st_ctime : 0;
1675 status->di_mode = 0;
1676 CloseContext(new_cx_num);
1677 free((char *)file);
1678 free((char *)buff);
1679 return(0);
1680 }
1681 }
1682 free((char *)buff);
1683 CloseContext(new_cx_num);
1684 return(-1);
1685 }
1686
1687 #define DL_SIZE 1024
1688
1689
1690 int
_RkwSync(cx,dicname)1691 _RkwSync(cx, dicname)
1692 struct RkContext *cx;
1693 char *dicname;
1694 {
1695 struct DM *dm, *qm;
1696
1697 dm = _RkSearchDicWithFreq(cx->ddpath, dicname, &qm);
1698
1699 if (dm)
1700 return(DST_SYNC(cx, dm, qm));
1701 else
1702 return (-1);
1703 }
1704
1705
1706 int
RkwSync(cx_num,dicname)1707 RkwSync(cx_num, dicname)
1708 int cx_num;
1709 char *dicname;
1710 {
1711 struct RkContext *cx;
1712 int ret = -1;
1713
1714 if (!(cx = RkGetContext(cx_num)))
1715 return (-1);
1716
1717 if (!dicname || !*dicname) {
1718 int i, rv;
1719 char *p;
1720 #ifndef USE_MALLOC_FOR_BIG_ARRAY
1721 char diclist[DL_SIZE];
1722 #else
1723 char *diclist = malloc(DL_SIZE);
1724 if (!diclist) {
1725 return -1;
1726 }
1727 #endif
1728
1729 if (!(i = RkwGetDicList(cx_num, diclist, DL_SIZE))) {
1730 ret = 0;
1731 }
1732 else {
1733 if (i > 0) {
1734 for (p = diclist, rv = 0; *p;) {
1735 rv += _RkwSync(cx, p);
1736 p += strlen(p) + 1;
1737 }
1738 if (!rv) {
1739 ret = 0;
1740 goto return_ret;
1741 }
1742 }
1743 ret = -1;
1744 }
1745 return_ret:;
1746 #ifdef USE_MALLOC_FOR_BIG_ARRAY
1747 (void)free((char *)diclist);
1748 #endif
1749 } else {
1750 ret = _RkwSync(cx, dicname);
1751 }
1752 return ret;
1753 }
1754
1755 /*ARGSUSED*/
RkwGetSimpleKanji(cxnum,dicname,yomi,maxyomi,kanjis,maxkanjis,hinshis,maxhinshis)1756 RkwGetSimpleKanji(cxnum, dicname, yomi, maxyomi,
1757 kanjis, maxkanjis, hinshis, maxhinshis)
1758 int cxnum, maxyomi, maxkanjis, maxhinshis;
1759 char *dicname;
1760 Wchar *yomi, *kanjis, *hinshis;
1761 {
1762 return -1;
1763 }
1764
1765 /*ARGSUSED*/
1766 int
RkwStoreRange(cx_num,yomi,maxyomi)1767 RkwStoreRange(cx_num, yomi, maxyomi)
1768 int cx_num;
1769 Wchar *yomi;
1770 int maxyomi;
1771 {
1772 return(0);
1773 }
1774
1775 /*ARGSUSED*/
1776 int
RkwSetLocale(cx_num,locale)1777 RkwSetLocale(cx_num, locale)
1778 int cx_num;
1779 unsigned char *locale;
1780 {
1781 return(0);
1782 }
1783