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