1 /* Copyright 1992 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[] = "@(#) 102.1 $Id: henkan.c,v 1.8.2.2 2004/04/26 22:53:02 aida_s Exp $";
25 #endif /* lint */
26 
27 #include	"canna.h"
28 #include	"rkcapi.h"
29 
30 #include	<errno.h>
31 #include	<fcntl.h>
32 #ifdef MEASURE_TIME
33 #include <sys/types.h>
34 #include <sys/times.h>
35 #endif
36 
37 #ifdef luna88k
38 extern int errno;
39 #endif
40 
41 /*********************************************************************
42  *                      wchar_t replace begin                        *
43  *********************************************************************/
44 #ifdef wchar_t
45 # error "wchar_t is already defined"
46 #endif
47 #define wchar_t cannawc
48 
49 extern int defaultBushuContext;
50 extern int yomiInfoLevel;
51 extern int ckverbose;
52 extern int defaultContext;
53 extern struct dicname *RengoGakushu, *KatakanaGakushu, *HiraganaGakushu;
54 extern KanjiModeRec cy_mode, cb_mode, yomi_mode, tankouho_mode, empty_mode;
55 extern char saveapname[];
56 extern int mountnottry;
57 extern exp(int) RkwGetServerVersion pro((int *, int *));
58 
59 #define DICERRORMESGLEN 78
60 
61 static int doYomiHenkan pro((uiContext, int, wchar_t *, yomiContext));
62 static yomiContext tanbunToYomi pro((uiContext, tanContext, wchar_t *));
63 static void tanbunCommitYomi pro((uiContext, tanContext, yomiContext));
64 
65 static char dictmp[DICERRORMESGLEN];
66 static char *mountErrorMessage = "\244\362\245\336\245\246\245\363\245\310"
67 	"\244\307\244\255\244\336\244\273\244\363\244\307\244\267\244\277";
68                                  /* ��ޥ���ȤǤ��ޤ���Ǥ��� */
69 
70 static int
kanakanError(d)71 kanakanError(d)
72 uiContext d;
73 {
74   return makeRkError(d, "\244\253\244\312\264\301\273\372\312\321\264\271"
75 	"\244\313\274\272\307\324\244\267\244\336\244\267\244\277");
76                         /* ���ʴ����Ѵ��˼��Ԥ��ޤ��� */
77 }
78 
79 static void
dicMesg(s,d)80 dicMesg(s, d)
81 char *s, *d;
82 {
83   if (ckverbose == CANNA_FULL_VERBOSE) {
84     char buf[128];
85     sprintf(buf, "\"%s\"", d);
86     printf("%14s %-20s ����ꤷ�Ƥ��ޤ���\n", s, buf);
87   }
88 }
89 
90 static void
RkwInitError()91 RkwInitError()
92 {
93   if (errno == EPIPE) {
94     jrKanjiError = KanjiInitError();
95   }
96   else {
97     jrKanjiError = "\244\253\244\312\264\301\273\372\312\321\264\271\274\255"
98 	"\275\361\244\316\275\351\264\374\262\275\244\313\274\272\307\324"
99 	"\244\267\244\336\244\267\244\277";
100                    /* ���ʴ����Ѵ�����ν�����˼��Ԥ��ޤ��� */
101   }
102   addWarningMesg(jrKanjiError);
103   RkwFinalize();
104 }
105 
106 static void
mountError(dic)107 mountError(dic)
108 char *dic;
109 {
110   int mnterrlen;
111   if (DICERRORMESGLEN <
112       (unsigned)(strlen(dic) + (mnterrlen = strlen(mountErrorMessage)) + 1)) {
113     (void)strncpy(dictmp, dic, DICERRORMESGLEN - mnterrlen - 3/* ... */ - 1);
114     (void)strcpy(dictmp + DICERRORMESGLEN - mnterrlen - 3 - 1, "...");
115     strcpy(dictmp + DICERRORMESGLEN - mnterrlen - 1, mountErrorMessage);
116   }
117   else {
118     sprintf(dictmp, "%s%s", dic, mountErrorMessage);
119   }
120   jrKanjiError = dictmp;
121   addWarningMesg(dictmp);
122 }
123 
124 static void
autodicError()125 autodicError()
126 {
127 #ifndef CODED_MESSAGE
128   jrKanjiError = "��ư��Ͽ�Ѽ���¸�ߤ��ޤ���";
129 #else
130   jrKanjiError = "\274\253\306\260\305\320\317\277\315\321\274\255\275\361"
131                  "\244\254\302\270\272\337\244\267\244\336\244\273\244\363";
132 #endif
133   addWarningMesg(jrKanjiError);
134 }
135 
136 static void
warnRKCErrors(errors)137 warnRKCErrors(errors)
138 const char *const *errors;
139 {
140   for (; *errors; ++errors)
141     addWarningMesg((char *)*errors);
142 }
143 
144 /*
145  * ���ʴ����Ѵ��Τ���ν������
146  *
147  * ��RkwInitialize��Ƥ�ǡ�defaultContext ���������
148  * ��defaultBushuContext ���������
149  * ������Υ������ѥ������ꤹ��
150  * �������ƥ༭�������Ѽ����桼�������ޥ���Ȥ���
151  *
152  * ������	�ʤ�
153  * �����	0:�ޤ���� -1:�Ȥ��Ȥ�����
154  */
KanjiInit()155 KanjiInit()
156 {
157   char *ptr, *getenv(), *kodmesg = ""/* ����μ�����Υ�å����� */;
158   int con;
159   struct dicname *stp;
160   extern struct dicname *kanjidicnames;
161   extern FirstTime;
162   extern jrUserInfoStruct *uinfo;
163   extern char *RkGetServerHost pro((void));
164   int ret = -1;
165 #ifndef USE_MALLOC_FOR_BIG_ARRAY
166   char buf[256];
167 #else
168   char *buf = malloc(256);
169   if (!buf) {
170     return ret;
171   }
172 #endif
173 
174 #if defined(DEBUG)
175   if (iroha_debug) {
176     fprintf(stderr,"\n�����Ф���³���� strokelimit = %d (default:%d)\n",
177               cannaconf.strokelimit, STROKE_LIMIT);
178   }
179 #endif
180   /* Ϣʸ��饤�֥����������� */
181   if (uinfo) {
182     RkwSetUserInfo(uinfo->uname, uinfo->gname, uinfo->topdir);
183   }
184 
185   if (!(ptr = RkGetServerHost()) &&
186       !(ptr = getenv("IROHADICDIR"))) {
187     if (uinfo && uinfo->topdir) {
188       strcpy(buf, uinfo->topdir);
189       strcat(buf, "/dic");
190       ptr = buf;
191     }
192     else {
193       ptr = DICHOME;
194     }
195   }
196   if (ckverbose >= CANNA_HALF_VERBOSE)
197     RkcListenConfigErrors(&warnRKCErrors);
198   defaultContext = RkwInitialize(ptr);
199   RkcListenConfigErrors(NULL);
200   if (defaultContext == -1) {
201     RkwInitError();
202     ret = -1;
203     goto return_ret;
204   }
205 
206   if (defaultContext != -1) {
207     if((defaultBushuContext = RkwCreateContext()) == -1) {
208       jrKanjiError = "\311\364\274\363\315\321\244\316\245\263\245\363\245\306"
209 	"\245\257\245\271\245\310\244\362\272\356\300\256\244\307\244\255"
210 	"\244\336\244\273\244\363\244\307\244\267\244\277";
211                      /* �����ѤΥ���ƥ����Ȥ�����Ǥ��ޤ���Ǥ��� */
212       addWarningMesg(jrKanjiError);
213       defaultContext = -1;
214       RkwFinalize();
215       ret = -1;
216       goto return_ret;
217     }
218   } else {
219     defaultBushuContext = -1;
220   }
221 
222   debug_message("\245\307\245\325\245\251\245\353\245\310\245\263\245\363"
223 	"\245\306\245\255\245\271\245\310(%d), \311\364\274\363\245\263"
224 	"\245\363\245\306\245\255\245\271\245\310(%d)\n",
225 		defaultContext, defaultBushuContext, 0);
226                /* �ǥե���ȥ���ƥ�����(%d), ������ƥ�����(%d)\n */
227 
228   if (defaultContext != -1) {
229 
230     if (saveapname[0]) {
231       RkwSetAppName(defaultContext, saveapname);
232     }
233 
234     if (!FirstTime && !mountnottry) { /* KC_INITIALIZE �ǸƤӽФ���Ƥ��ʤ��ơ�
235 					 ���˥ޥ���Ƚ�����ԤäƤ����� */
236       /* ʸˡ����Υޥ���� */
237       for (stp = kanjidicnames; stp ; stp = stp->next) {
238 	if (stp->dictype == DIC_GRAMMAR) {
239 	  if (stp->dicflag == DIC_MOUNTED) {
240 	    if (RkwMountDic(defaultContext, stp->name,
241 			    cannaconf.kojin ? PL_ALLOW : PL_INHIBIT) == -1) {
242 	      stp->dicflag = DIC_MOUNT_FAILED;
243 	      mountError(stp->name);
244 	    }
245 	    else {
246 	      stp->dicflag = DIC_MOUNTED;
247 	      dicMesg("\312\270\313\241\274\255\275\361", stp->name);
248                       /* ʸˡ���� */
249 	    }
250 	  }
251 	}
252       }
253       /* �����ƥ༭��Υޥ���� */
254       for (stp = kanjidicnames ; stp ; stp = stp->next) {
255         if (stp->dictype != DIC_GRAMMAR) {
256           if (stp->dicflag == DIC_MOUNTED) {
257             if (stp->dictype == DIC_BUSHU) {
258               con = defaultBushuContext;
259             }
260             else {
261               con = defaultContext;
262             }
263             if (RkwMountDic(con, stp->name,
264 			    cannaconf.kojin ? PL_ALLOW : PL_INHIBIT)
265               == -1) {
266 #if defined(DEBUG)
267             if (iroha_debug) {
268               fprintf(stderr, "saveddicname = %s\n", stp->name);
269             }
270 #endif
271 	      stp->dicflag = DIC_MOUNT_FAILED;
272 	      mountError(stp->name);
273 	    }
274 	    dicMesg("saveddicname\244\316\274\255\275\361", stp->name);
275                     /* saveddicname�μ��� */
276 	  }
277 	}
278       }
279     }
280     else { /* KC_INITIALIZE ����ƤӽФ���Ƥ����硣
281               �ޤ��ϡ��ޥ���Ƚ�����ԤäƤ��ʤ���� */
282 #if defined(DEBUG)
283       if (iroha_debug) {
284         fprintf(stderr, "�����.canna���̤�˥ޥ���Ȥ���\n");
285       }
286 #endif
287 
288       mountnottry = 0; /* �ޥ���Ƚ�����Ԥ��Τ� mountnottry = 0 �ˤ��� */
289       /* ʸˡ����Υޥ���� */
290       for (stp = kanjidicnames; stp ; stp = stp->next) {
291 	if (stp->dictype == DIC_GRAMMAR) {
292 	  if (RkwMountDic(defaultContext, stp->name,
293 			  cannaconf.kojin ? PL_ALLOW : PL_INHIBIT) == -1) {
294 	    stp->dicflag = DIC_MOUNT_FAILED;
295 	    mountError(stp->name);
296 	  }
297 	  else {
298 	    stp->dicflag = DIC_MOUNTED;
299 	    dicMesg("\312\270\313\241\274\255\275\361", stp->name);
300                     /* ʸˡ���� */
301 	  }
302 	}
303       }
304 
305       /* �����ƥ༭��Υޥ���� */
306       for (stp = kanjidicnames ; stp ; stp = stp->next) {
307         if (stp->dictype != DIC_GRAMMAR) {
308           con = defaultContext;
309           if (stp->dictype == DIC_PLAIN) {
310             kodmesg = "\245\267\245\271\245\306\245\340\274\255\275\361";
311                       /* "�����ƥ༭��"; */
312           }
313           else if (stp->dictype == DIC_USER) {
314             /* �桼������Υޥ���� */
315            kodmesg = "\303\261\270\354\305\320\317\277\315\321\274\255\275\361";
316                      /* "ñ����Ͽ�Ѽ���"; */
317           }
318           else if (stp->dictype == DIC_RENGO) {
319             /* Ϣ�켭��Υޥ���� */
320             RengoGakushu = stp;
321             kodmesg = "\317\242\270\354\274\255\275\361";
322                       /* "Ϣ�켭��"; */
323           }
324           else if (stp->dictype == DIC_KATAKANA) {
325             KatakanaGakushu = stp;
326             kodmesg = "\274\253\306\260\305\320\317\277\315\321\274\255\275\361";
327                       /* "��ư��Ͽ�Ѽ���"; */
328           }
329           else if (stp->dictype == DIC_HIRAGANA) {
330             HiraganaGakushu = stp;
331 #ifdef HIRAGANAAUTO
332             kodmesg = "\274\253\306\260\305\320\317\277\315\321\274\255\275\361";
333                       /* "��ư��Ͽ�Ѽ���"; */
334 #else
335             kodmesg = "\317\242\270\354\274\255\275\361";
336                       /* "Ϣ�켭��"; */
337 #endif
338           }
339           else if (stp->dictype == DIC_BUSHU) {
340             kodmesg = "\311\364\274\363\274\255\275\361";
341                       /* "������"; */
342             con = defaultBushuContext;
343           }
344           if (RkwMountDic(con, stp->name,
345 			  cannaconf.kojin ? PL_ALLOW : PL_INHIBIT) == -1) {
346             extern int auto_define;
347 
348             stp->dicflag = DIC_MOUNT_FAILED;
349             if (stp->dictype == DIC_KATAKANA
350 #ifdef HIRAGANAAUTO
351                 || stp->dictype == DIC_HIRAGANA
352 #endif
353                ) {
354               /* ��ư��Ͽ������ä��顢��ư��Ͽ���ʤ� */
355               auto_define = 0;
356             }
357             if (stp->dictype != DIC_USER || strcmp(stp->name, "user")) {
358               /* �桼������� user �Ȥ���̾���ξ��ϥ��顼ɽ�� *
359                * ���ʤ��褦�ˤ��뤿��                           */
360               int majv, minv;
361 
362               RkwGetServerVersion(&majv, &minv);
363               if (!(canna_version(majv, minv) < canna_version(3, 4))
364                   || ((stp->dictype != DIC_KATAKANA ||
365                          strcmp(stp->name, "katakana"))
366 #ifdef HIRAGANAAUTO
367                      && (stp->dictype != DIC_HIRAGANA ||
368                            strcmp(stp->name, "hiragana"))
369 #endif
370                   )) {
371                 /* V3.3 �����ǡ��������ʼ��� katakana���Ҥ餬�ʼ���
372                    hiragana �ξ��ϥ��顼�ˤ��ʤ�����                  */
373                 extern char *kataautodic;
374 #ifdef HIRAGANAAUTO
375                 extern char *hiraautodic;
376 #endif
377 
378                 if (!auto_define ||
379                     ((kataautodic && strcmp(stp->name, kataautodic))
380 #ifdef HIRAGANAAUTO
381                     && (hiraautodic && strcmp(stp->name, hiraautodic))
382 #endif
383                    )) {
384                   if (stp->dictype == DIC_KATAKANA
385 #ifdef HIRAGANAAUTO
386                       || stp->dictype == DIC_HIRAGANA
387 #endif
388                      ) {
389                     autodicError();
390                   }
391                   else {
392                     mountError(stp->name);
393                   }
394                 }
395               }
396             }
397           }
398           else {
399             stp->dicflag = DIC_MOUNTED;
400             dicMesg(kodmesg, stp->name);
401           }
402         }
403       }
404     }
405     ret = 0;
406     goto return_ret;
407   }
408   ret = -1;
409  return_ret:
410 #ifdef USE_MALLOC_FOR_BIG_ARRAY
411   (void)free(buf);
412 #endif
413   return ret;
414 }
415 
416 /*
417  * ���ʴ����Ѵ��Τ���θ����
418  *
419  * �������ƥ༭�������Ѽ����桼���������ޥ���Ȥ���
420  * ��RkwFinalize��Ƥ�
421  *
422  * ������	�ʤ�
423  * �����	�ʤ�
424  */
KanjiFin()425 KanjiFin()
426 {
427   struct dicname *dp, *np;
428   int con;
429 
430   for (dp = kanjidicnames ; dp ;) {
431     if (dp->dictype == DIC_BUSHU) {
432       con = defaultBushuContext;
433     }
434     else {
435       con = defaultContext;
436     }
437     if (dp->dicflag == DIC_MOUNTED) {
438       if (RkwUnmountDic(con, dp->name) == -1) {
439 #ifndef USE_MALLOC_FOR_BIG_ARRAY
440         char buf[256];
441 #else
442 	char *buf = malloc(128);
443 	if (buf)
444 #endif
445 	{
446 #ifdef CODED_MESSAGE
447 	  sprintf(buf, "%s \244\362\245\242\245\363\245\336\245\246\245\363"
448 	  "\245\310\244\307\244\255\244\336\244\273\244\363\244\307\244\267"
449 	  "\244\277", dp->name);
450 #else
451 	sprintf(buf, "%s ����ޥ���ȤǤ��ޤ���Ǥ�����", dp->name);
452 #endif
453 	  addWarningMesg(buf);
454 #ifdef USE_MALLOC_FOR_BIG_ARRAY
455 	  (void)free(buf);
456 #endif
457 	}
458       }
459     }
460     np = dp->next;
461     free(dp->name);
462     free((char *)dp);
463     dp = np;
464   }
465   kanjidicnames = (struct dicname *)0;
466 
467   defaultContext = -1;
468   defaultBushuContext = -1;
469   mountnottry = 1;
470   /* Ϣʸ��饤�֥���λ������ */
471   RkwFinalize();
472 
473   return(0);
474 }
475 
476 static tanContext
newTanContext(majo,mino)477 newTanContext(majo, mino)
478 int majo, mino;
479 {
480   tanContext tan;
481 
482   tan = (tanContext)malloc(sizeof(tanContextRec));
483   if (tan) {
484     bzero(tan, sizeof(tanContextRec));
485     tan->id = TAN_CONTEXT;
486     tan->majorMode = majo;
487     tan->minorMode = mino;
488     tan->left = tan->right = (tanContext)0;
489     tan->next = (mode_context)0;
490     tan->curMode = &tankouho_mode;
491   }
492   return tan;
493 }
494 
495 void
freeTanContext(tan)496 freeTanContext(tan)
497 tanContext tan;
498 {
499   if (tan->kanji) free((char *)tan->kanji);
500   if (tan->yomi) free((char *)tan->yomi);
501   if (tan->roma) free((char *)tan->roma);
502   if (tan->kAttr) free((char *)tan->kAttr);
503   if (tan->rAttr) free((char *)tan->rAttr);
504   free((char *)tan);
505 }
506 
507 static wchar_t *
DUpwstr(w,l)508 DUpwstr(w, l)
509 wchar_t *w;
510 int l;
511 {
512   wchar_t *res;
513 
514   res = (wchar_t *)malloc((l + 1) * sizeof(wchar_t));
515   if (res) {
516     WStrncpy(res, w, l);
517     res[l] = (wchar_t)0;
518   }
519   return res;
520 }
521 
522 static BYTE *
DUpattr(a,l)523 DUpattr(a, l)
524 BYTE *a;
525 int l;
526 {
527   BYTE *res;
528 
529   res = (BYTE *)malloc((l + 1) * sizeof(BYTE));
530   if (res) {
531     bcopy(a, res, (l + 1) * sizeof(BYTE));
532   }
533   return res;
534 }
535 
536 static void
copyYomiinfo2Tan(yc,tan)537 copyYomiinfo2Tan(yc, tan)
538 yomiContext yc;
539 tanContext tan;
540 {
541   tan->next = yc->next;
542   tan->prevMode = yc->prevMode;
543   tan->generalFlags = yc->generalFlags;
544   tan->savedFlags = yc->savedFlags;
545 
546   tan->romdic = yc->romdic;
547   tan->myMinorMode = yc->myMinorMode;
548   tan->myEmptyMode = yc->myEmptyMode;
549   tan->savedMinorMode = yc->savedMinorMode;
550   tan->allowedChars = yc->allowedChars;
551   tan->henkanInhibition = yc->henkanInhibition;
552 }
553 
554 static void
copyTaninfo2Yomi(tan,yc)555 copyTaninfo2Yomi(tan, yc)
556 tanContext tan;
557 yomiContext yc;
558 {
559   /* next �� prevMode �ϴ�������Ѥ� */
560   yc->generalFlags = tan->generalFlags;
561   yc->savedFlags = tan->savedFlags;
562 
563   yc->romdic = tan->romdic;
564   yc->myMinorMode = tan->myMinorMode;
565   yc->myEmptyMode = tan->myEmptyMode;
566   yc->savedMinorMode = tan->savedMinorMode;
567   yc->allowedChars = tan->allowedChars;
568   yc->henkanInhibition = tan->henkanInhibition;
569 }
570 
571 extern yomiContext dupYomiContext pro((yomiContext));
572 extern void setMode pro((uiContext, tanContext, int));
573 
574 extern void trimYomi pro((uiContext, int, int, int, int));
575 
576 /*
577  * �ؽ����ǽ�ˤ��뤿��tanContext��yomiContext�ˤ��롣
578  * ���Ԥ�����tanContext�Τޤޤˤ��Ƥ�����
579  * ������tanContext���ѻߤ��٤��������Ȥꤢ����quick hack��
580  * DO_MERGE�ˤ������б����Ƥ��ʤ���
581  */
582 static void
tanbunToYomiAll(d,st,et)583 tanbunToYomiAll(d, st, et)
584 uiContext d;
585 tanContext st;
586 tanContext et;
587 {
588   tanContext tan;
589   for (tan = st; tan != et; tan = tan->right) {
590     yomiContext tyc;
591     if (tan->id != TAN_CONTEXT)
592       continue;
593     tyc = tanbunToYomi(d, tan, tan->kanji);
594     if (tyc) {
595       tanbunCommitYomi(d, tan, tyc);
596       tan = (tanContext)tyc;
597     }
598   }
599 }
600 
601 /*
602   ��ʸ��� tanContext ���Ѵ�����
603  */
604 
605 int
doTanConvertTb(d,yc)606 doTanConvertTb(d, yc)
607 uiContext d;
608 yomiContext yc;
609 {
610   int cur = yc->curbun, i, len, ylen = 0, rlen = 0, ret = 0;
611   int scuryomi, ecuryomi, scurroma, ecurroma;
612   tanContext tan, prevLeft = yc->left, curtan = (tanContext)0;
613   tanContext st = (tanContext)NULL, et = (tanContext)NULL;
614   BYTE *p, *q, *r;
615 #ifndef USE_MALLOC_FOR_BIG_ARRAY
616   wchar_t xxx[ROMEBUFSIZE];
617 #else
618   wchar_t *xxx = (wchar_t *)malloc(sizeof(wchar_t) * ROMEBUFSIZE);
619   if (!xxx) {
620     return ret;
621   }
622 #endif
623 
624   yc->kouhoCount = 0;
625   scuryomi = ecuryomi = scurroma = ecurroma = 0;
626 
627 /*  jrKanjiError = "���꤬­��ޤ���"; */
628   jrKanjiError = "malloc (doTanBubunMuhenkan) \244\307\244\255\244\336\244\273"
629 	"\244\363\244\307\244\267\244\277\241\243";
630                  /* malloc (doTanBubunMuhenkan) �Ǥ��ޤ���Ǥ��� */
631   for (i = 0 ; i < yc->nbunsetsu ; i++) {
632     tan = newTanContext(yc->majorMode, CANNA_MODE_TankouhoMode);
633     if (tan) {
634       copyYomiinfo2Tan(yc, tan);
635       RkwGoTo(yc->context, i);
636       len = RkwGetKanji(yc->context, xxx, ROMEBUFSIZE);
637       if (len >= 0) {
638 	tan->kanji = DUpwstr(xxx, len);
639 	if (tan->kanji) {
640 	  len = RkwGetYomi(yc->context, xxx, ROMEBUFSIZE);
641 	  if (len >= 0) {
642 	    tan->yomi = DUpwstr(xxx, len);
643 	    if (tan->yomi) {
644 	      tan->kAttr = DUpattr(yc->kAttr + ylen, len);
645 	      if (tan->kAttr) {
646 		r = yc->rAttr + rlen;
647 		for (p = yc->kAttr + ylen, q = p + len ; p < q ; p++) {
648 		  if (*p & SENTOU) {
649 		    r++;
650 		    while (!(*r & SENTOU)) {
651 		      r++;
652 		    }
653 		  }
654 		}
655 		ylen += len;
656 		len = r - yc->rAttr - rlen; /* ���޻���Ĺ�� */
657 		tan->roma = DUpwstr(yc->romaji_buffer + rlen, len);
658 		if (tan->roma) {
659 		  tan->rAttr = DUpattr(yc->rAttr + rlen, len);
660 		  if (tan->rAttr) {
661 		    rlen += len;
662 		    /* �Ȥꤢ�������ˤĤʤ��� */
663 		    tan->right = (tanContext)yc;
664 		    tan->left = yc->left;
665 		    if (yc->left) {
666 		      yc->left->right = tan;
667 		    }
668 		    yc->left = tan;
669 		    if (i == 0)
670 		      st = tan;
671 		    if (i == cur) {
672 		      curtan = tan;
673 		    }
674 		    continue;
675 		  }
676 		  free((char *)tan->roma);
677 		}
678 		free((char *)tan->kAttr);
679 	      }
680 	      free((char *)tan->yomi);
681 	    }
682 	  }
683 	  else {
684 	    makeRkError(d, KanjiInitError());
685 	  }
686 	  free((char *)tan->kanji);
687 	}
688       }
689       else {
690 	makeRkError(d, KanjiInitError());
691       }
692       freeTanContext(tan);
693     }
694     /* ���顼�������� */
695   procerror:
696     while ((tan = yc->left) != prevLeft) {
697       yc->left = tan->left;
698       freeTanContext(tan);
699     }
700     ret = -1;
701     goto return_ret;
702   }
703 
704   if (chikujip(yc) && chikujiyomiremain(yc)) {
705     int rpos;
706     yomiContext lyc = dupYomiContext(yc);
707 
708     if (!lyc) { /* ���顼�������� */
709       goto procerror;
710     }
711 
712     if (yc->right) { /* �༡�ξ��ʤ��Ϥ�����ǰ�Τ��� */
713       yc->right->left = (tanContext)lyc;
714     }
715     lyc->right = yc->right;
716     yc->right = (tanContext)lyc;
717     lyc->left = (tanContext)yc;
718 
719     kPos2rPos(lyc, 0, yc->cStartp, (int *)0, &rpos);
720     d->modec = (mode_context)lyc;
721     moveToChikujiYomiMode(d);
722     trimYomi(d, yc->cStartp, yc->kEndp, rpos, yc->rEndp);
723     d->modec = (mode_context)yc;
724     yc->status = lyc->status;
725     lyc->cStartp = lyc->cRStartp = lyc->ys = lyc->ye = 0;
726   }
727 
728   RkwGoTo(yc->context, cur);
729   if (RkwEndBun(yc->context, 0) == -1) {
730     jrKanjiError = "\244\253\244\312\264\301\273\372\312\321\264\271\244\316"
731 	"\275\252\316\273\244\313\274\272\307\324\244\267\244\336\244\267"
732 	"\244\277";
733                    /* ���ʴ����Ѵ��ν�λ�˼��Ԥ��ޤ��� */
734     if (errno == EPIPE) {
735       jrKanjiPipeError();
736     }
737   }
738 
739   d->modec = (mode_context)curtan;
740   setMode(d, curtan, 1);
741   makeKanjiStatusReturn(d, (yomiContext)curtan);
742 
743   et = yc->right;
744   /* yc ��������ȴ�� */
745   if (yc->left) {
746     yc->left->right = yc->right;
747   }
748   if (yc->right) {
749     yc->right->left = yc->left;
750   }
751   abandonContext(d, yc);
752   freeYomiContext(yc);
753   tanbunToYomiAll(d, st, et);
754 
755  return_ret:
756 #ifdef USE_MALLOC_FOR_BIG_ARRAY
757   (void)free((char *)xxx);
758 #endif
759 
760   return ret;
761 }
762 
763 static int
doTanBubunMuhenkan(d,yc)764 doTanBubunMuhenkan(d, yc)
765 uiContext d;
766 yomiContext yc;
767 {
768   int cur = yc->curbun, i, len, ylen = 0, rlen = 0, ret = 0;
769   int scuryomi, ecuryomi, scurroma, ecurroma;
770   tanContext tan, prevLeft = yc->left, prevRight = yc->right;
771   BYTE *p, *q, *r;
772 #ifndef USE_MALLOC_FOR_BIG_ARRAY
773   wchar_t xxx[ROMEBUFSIZE];
774 #else
775   wchar_t *xxx = (wchar_t *)malloc(sizeof(wchar_t) * ROMEBUFSIZE);
776   if (!xxx) {
777     return ret;
778   }
779 #endif
780 
781   yc->kouhoCount = 0;
782   scuryomi = ecuryomi = scurroma = ecurroma = 0;
783 
784 /*  jrKanjiError = "���꤬­��ޤ���"; */
785   jrKanjiError = "malloc (doTanBubunMuhenkan) \244\307\244\255\244\336\244\273"
786 	"\244\363\244\307\244\267\244\277\241\243";
787                  /* malloc (doTanBubunMuhenkan) �Ǥ��ޤ���Ǥ��� */
788   for (i = 0 ; i < yc->nbunsetsu ; i++) {
789     tan = (tanContext)0;
790     if (i == cur ||
791 	(tan = newTanContext(yc->majorMode, CANNA_MODE_TankouhoMode))) {
792       if (tan) {
793 	copyYomiinfo2Tan(yc, tan);
794       }
795       RkwGoTo(yc->context, i);
796       len = RkwGetKanji(yc->context, xxx, ROMEBUFSIZE);
797       if (len >= 0) {
798 	if (!tan || (tan->kanji = DUpwstr(xxx, len))) {
799 	  len = RkwGetYomi(yc->context, xxx, ROMEBUFSIZE);
800 	  if (len >= 0) {
801 	    if (!tan || (tan->yomi = DUpwstr(xxx, len))) {
802 	      if (!tan || (tan->kAttr = DUpattr(yc->kAttr + ylen, len))) {
803 		r = yc->rAttr + rlen;
804 		for (p = yc->kAttr + ylen, q = p + len ; p < q ; p++) {
805 		  if (*p & SENTOU) {
806 		    r++;
807 		    while (!(*r & SENTOU)) {
808 		      r++;
809 		    }
810 		  }
811 		}
812 		if (i == cur) {
813 		  scuryomi = ylen;
814 		  ecuryomi = ylen + len;
815 		}
816 		ylen += len;
817 		len = r - yc->rAttr - rlen; /* ���޻���Ĺ�� */
818 		if (!tan ||
819 		    (tan->roma = DUpwstr(yc->romaji_buffer + rlen, len))) {
820 		  if (!tan || (tan->rAttr = DUpattr(yc->rAttr + rlen, len))) {
821 		    if (i == cur) {
822 		      scurroma = rlen;
823 		      ecurroma = rlen + len;
824 		    }
825 		    rlen += len;
826 		    if (tan) {
827 		      if (i != cur) {
828 			/* �Ȥꤢ�������ˤĤʤ��� */
829 			tan->right = (tanContext)yc;
830 			tan->left = yc->left;
831 			if (yc->left) {
832 			  yc->left->right = tan;
833 			}
834 			yc->left = tan;
835 		      }
836 #if defined(DEBUG)
837 		      {
838 			char yyy[ROMEBUFSIZE];
839 			WCstombs(yyy, tan->kanji, ROMEBUFSIZE);
840 			printf("%s/", yyy);
841 			WCstombs(yyy, tan->yomi, ROMEBUFSIZE);
842 			printf("%s/", yyy);
843 			WCstombs(yyy, tan->roma, ROMEBUFSIZE);
844 			printf("%s\n", yyy);
845 		      }
846 #endif
847 		    }
848 		    continue;
849 		  }
850 		  if (tan) free((char *)tan->roma);
851 		}
852 		if (tan) free((char *)tan->kAttr);
853 	      }
854 	      if (tan) free((char *)tan->yomi);
855 	    }
856 	  }
857 	  else {
858 	    makeRkError(d, KanjiInitError());
859 	  }
860 	  if (tan) free((char *)tan->kanji);
861 	}
862       }
863       else {
864 	makeRkError(d, KanjiInitError());
865       }
866       if (tan) freeTanContext(tan);
867     }
868     /* ���顼�������� */
869     while ((tan = yc->left) != prevLeft) {
870       yc->left = tan->left;
871       freeTanContext(tan);
872     }
873     ret = -1;
874     goto return_ret;
875   }
876 
877   if (chikujip(yc) && chikujiyomiremain(yc)) {
878     int rpos;
879     yomiContext lyc = dupYomiContext(yc);
880 
881     if (!lyc) { /* ���顼�������� */
882       while ((tan = yc->left) != prevLeft) {
883 	yc->left = tan->left;
884 	freeTanContext(tan);
885       }
886       ret = -1;
887       goto return_ret;
888     }
889 
890     if (yc->right) { /* �ʤ��Ϥ� */
891       yc->right->left = (tanContext)lyc;
892     }
893     lyc->right = yc->right;
894     yc->right = (tanContext)lyc;
895     lyc->left = (tanContext)yc;
896 
897     kPos2rPos(lyc, 0, yc->cStartp, (int *)0, &rpos);
898     d->modec = (mode_context)lyc;
899     moveToChikujiYomiMode(d);
900     trimYomi(d, yc->cStartp, yc->kEndp, rpos, yc->rEndp);
901     d->modec = (mode_context)yc;
902     yc->status = lyc->status;
903     lyc->cStartp = lyc->cRStartp = lyc->ys = lyc->ye = 0;
904   }
905 
906   if (cur + 1 < yc->nbunsetsu) { /* yc ���Ǹ夸��ʤ���� */
907     int n = yc->nbunsetsu - cur - 1;
908     tan = yc->left;
909     tan->right = yc->right;
910     if (yc->right) {
911       yc->right->left = tan;
912     }
913     for (i = 1 ; i < n ; i++) { /* yomi �� right �����٤� tan �������� */
914       tan = tan->left;
915     }
916     if (tan->left) {
917       tan->left->right = (tanContext)yc;
918     }
919     yc->left = tan->left;
920     tan->left = (tanContext)yc;
921     yc->right = tan;
922   }
923   RkwGoTo(yc->context, cur);
924   if (RkwEndBun(yc->context, 0) == -1) {
925     jrKanjiError = "\244\253\244\312\264\301\273\372\312\321\264\271\244\316"
926 	"\275\252\316\273\244\313\274\272\307\324\244\267\244\336\244\267"
927 	"\244\277";
928                    /* ���ʴ����Ѵ��ν�λ�˼��Ԥ��ޤ��� */
929     if (errno == EPIPE) {
930       jrKanjiPipeError();
931     }
932   }
933 
934   trimYomi(d, scuryomi, ecuryomi, scurroma, ecurroma);
935 
936   yc->cRStartp = yc->rCurs = yc->rStartp = 0;
937   yc->cStartp = yc->kCurs = yc->kRStartp =
938     yc->ys = yc->ye = 0;
939   yc->status &= CHIKUJI_NULL_STATUS;
940   /* �ʤ���༡�Ǥʤ��ʤ� */
941   if (chikujip(yc)) {
942     yc->generalFlags &= ~CANNA_YOMI_CHIKUJI_MODE;
943     yc->generalFlags |= CANNA_YOMI_BASE_CHIKUJI;
944   }
945 
946   d->current_mode = yc->curMode = &yomi_mode;
947   yc->minorMode = getBaseMode(yc);
948 
949   /* ����̵�Ѵ��ˤ��� */
950   yc->nbunsetsu = 0;
951 
952   /* ñ������֤����ɤߤ����Ȥ��ˤ�̵����mark����Ƭ���᤹ */
953   yc->cmark = yc->pmark = 0;
954 
955   abandonContext(d, yc);
956   ret = 0;
957   if (prevLeft)
958     tan = prevLeft->right;
959   else if (!yc->left)
960     tan = (tanContext)yc;
961   else
962     for (tan = yc->left; tan->left; tan = tan->left);
963   tanbunToYomiAll(d, tan, prevRight);
964 
965  return_ret:
966 #ifdef USE_MALLOC_FOR_BIG_ARRAY
967   (void)free((char *)xxx);
968 #endif
969 
970   return ret;
971 }
972 
973 extern void restoreChikujiIfBaseChikuji pro((yomiContext));
974 extern void ReCheckStartp pro((yomiContext));
975 extern void fitmarks pro((yomiContext));
976 
977 int YomiBubunKakutei pro((uiContext));
978 
979 int
YomiBubunKakutei(d)980 YomiBubunKakutei(d)
981 uiContext d;
982 {
983   yomiContext yc = (yomiContext)d->modec;
984   tanContext tan;
985   int len;
986 
987   if (yc->id != YOMI_CONTEXT) {
988     /* �������ʤ��ΤǤ�? */
989   }
990   else /* if (yc->left) */ {
991     /* yomiContext �Ǻ��������ʬ��ޤ� tanContext ���ڤ�Ф���yc �κ�
992        ¦���������롣���� yc �κ���Фä���ȳ��ꤹ�롣
993        ���Ƥ��Υ��å��Ǥ�������顣
994        */
995     tan = newTanContext(yc->majorMode, CANNA_MODE_TankouhoMode);
996     if (tan) {
997       copyYomiinfo2Tan(yc, tan);
998       /* ���ʤ��ԡ����� */
999       tan->kanji = DUpwstr(yc->kana_buffer, yc->kCurs);
1000       if (tan->kanji) {
1001 	/* ������Ʊ�����ʤ��ԡ����� */
1002 	tan->yomi = DUpwstr(yc->kana_buffer, yc->kCurs);
1003 	if (tan->yomi) {
1004 	  tan->kAttr = DUpattr(yc->kAttr, yc->kCurs);
1005 	  if (tan->kAttr) {
1006 	    tan->roma = DUpwstr(yc->romaji_buffer, yc->rCurs);
1007 	    if (tan->roma) {
1008 	      tan->rAttr = DUpattr(yc->rAttr, yc->rCurs);
1009 	      if (tan->rAttr) {
1010 		wchar_t *sb = d->buffer_return, *eb = sb + d->n_buffer;
1011 
1012 		tan->left = yc->left;
1013 		tan->right = (tanContext)yc;
1014 		if (yc->left) {
1015 		  yc->left->right = tan;
1016 		}
1017 		yc->left = tan;
1018 		while (tan->left) {
1019 		  tan = tan->left;
1020 		}
1021 
1022 		trimYomi(d, yc->kCurs, yc->kEndp, yc->rCurs, yc->rEndp);
1023 
1024 		len = doKakutei(d, tan, (tanContext)yc, sb, eb,
1025 				(yomiContext *)0);
1026 		d->modec = (mode_context)yc;
1027 		yc->left = (tanContext)0;
1028 		goto done;
1029 	      }
1030 	      free((char *)tan->roma);
1031 	    }
1032 	    free((char *)tan->kAttr);
1033 	  }
1034 	  free((char *)tan->yomi);
1035 	}
1036 	free((char *)tan->kanji);
1037       }
1038       free((char *)tan); /* not freeTanContext(tan); */
1039     }
1040   }
1041 #if 0
1042   /* ���褳���ν������줿������Ψ���ɤ��Ȼפ��뤬���ɤߤΰ������
1043   �ꤵ���ơ���������޻�����ʤɤ⤤���Τ����ݤʤΤǤ��Ȥޤ路�Ȥ��� */
1044   else {
1045 
1046     /* ���ꤵ���롣
1047        ���� trim ����*/
1048   }
1049 #endif
1050 
1051  done:
1052   if (!yc->kEndp) {
1053     if (yc->savedFlags & CANNA_YOMI_MODE_SAVED) {
1054       restoreFlags(yc);
1055     }
1056     if (yc->right) {
1057       removeCurrentBunsetsu(d, (tanContext)yc);
1058       yc = (yomiContext)0;
1059     }
1060     else {
1061       /* ̤����ʸ���������ʤ��ʤä��Τʤ顢�ե⡼�ɤ����ܤ��� */
1062       restoreChikujiIfBaseChikuji(yc);
1063       d->current_mode = yc->curMode = yc->myEmptyMode;
1064       d->kanji_status_return->info |= KanjiEmptyInfo;
1065     }
1066     currentModeInfo(d);
1067   }
1068   else {
1069     if (yc->kCurs != yc->kRStartp) {
1070       ReCheckStartp(yc);
1071     }
1072   }
1073 
1074   if (yc) {
1075     fitmarks(yc);
1076   }
1077 
1078   makeYomiReturnStruct(d);
1079   return len;
1080 }
1081 
1082 yomiContext
newFilledYomiContext(next,prev)1083 newFilledYomiContext(next, prev)
1084 mode_context next;
1085 KanjiMode prev;
1086 {
1087   yomiContext yc;
1088 
1089   yc = newYomiContext((wchar_t *)NULL, 0, /* ��̤ϳ�Ǽ���ʤ� */
1090 		      CANNA_NOTHING_RESTRICTED,
1091 		      (int)!CANNA_YOMI_CHGMODE_INHIBITTED,
1092 		      (int)!CANNA_YOMI_END_IF_KAKUTEI,
1093 		      CANNA_YOMI_INHIBIT_NONE);
1094   if (yc) {
1095     yc->majorMode = yc->minorMode = CANNA_MODE_HenkanMode;
1096     yc->curMode = &yomi_mode;
1097     yc->myEmptyMode = &empty_mode;
1098     yc->romdic = romajidic;
1099     yc->next = next;
1100     yc->prevMode = prev;
1101   }
1102   return yc;
1103 }
1104 
1105 #ifdef DO_MERGE
1106 static
1107 yomiContext
mergeYomiContext(yc)1108 mergeYomiContext(yc)
1109 yomiContext yc;
1110 {
1111   yomiContext res, a, b;
1112 
1113   res = yc;
1114   while (res->left && res->left->id == YOMI_CONTEXT) {
1115     res = (yomiContext)res->left;
1116   }
1117   for (a = (yomiContext)res->right ; a && a->id == YOMI_CONTEXT ; a = b) {
1118     b = (yomiContext)a->right;
1119     appendYomi2Yomi(a, res);
1120     if (yc == a) {
1121       res->kCurs = res->kRStartp = res->kEndp;
1122       res->rCurs = res->rStartp = res->rEndp;
1123       res->cmark = res->kCurs;
1124     }
1125     res->right = a->right;
1126     if (res->right) {
1127       res->right->left = (tanContext)res;
1128     }
1129     /* yc->context �� close �Ϥ���ʤ��Τ��ʤ���1996.10.30 �� */
1130     freeYomiContext(a);
1131   }
1132   return res;
1133 }
1134 #endif
1135 
1136 /*
1137   tanContext �� yomiContext �ˤ��ơ��ɤ����Ͼ��֤ˤ���
1138 
1139    0          ����(jrKanjiError�����ꤵ��롣�����ɥ饤�������Ǥ��롣)
1140    otherwise  �����餷���ɤߥ���ƥ����Ȥ��֤�
1141    ����Ū�������ѤϤʤ���
1142    yc��kanji����ꤹ���tankouho_mode, ���ꤷ�ʤ����yomi_mode�ˤʤ롣
1143  */
1144 
1145 static yomiContext
tanbunToYomi(d,tan,kanji)1146 tanbunToYomi(d, tan, kanji)
1147 uiContext d;
1148 tanContext tan;
1149 wchar_t *kanji;
1150 {
1151   yomiContext yc;
1152 
1153   yc = newFilledYomiContext(tan->next, tan->prevMode);
1154   if (yc) {
1155     extern KanjiModeRec tankouho_mode;
1156 
1157     appendTan2Yomi(tan, yc);
1158     copyTaninfo2Yomi(tan, yc);
1159     if (kanji) {
1160       if (doYomiHenkan(d, 0, kanji, yc)) {
1161 	freeYomiContext(yc);
1162 	return (yomiContext)NULL;
1163       }
1164       yc->curMode = &tankouho_mode;
1165       yc->minorMode = CANNA_MODE_TankouhoMode;
1166       yc->kouhoCount = 0;
1167     }
1168     yc->right = tan->right;
1169     yc->left = tan->left;
1170     if (yc->myMinorMode) {
1171       yc->minorMode = yc->myMinorMode;
1172     }
1173 
1174     if (chikujip(yc)) { /* �༡�ˤϤ��ʤ� */
1175       yc->generalFlags &= ~CANNA_YOMI_CHIKUJI_MODE;
1176       yc->generalFlags |= CANNA_YOMI_BASE_CHIKUJI;
1177     }
1178 
1179     return yc;
1180   }
1181   jrKanjiError = "\245\341\245\342\245\352\244\254\302\255\244\352\244\336"
1182 	"\244\273\244\363";
1183                  /* ���꤬­��ޤ��� */
1184   return (yomiContext)0;
1185 }
1186 
1187 /*
1188  * tanbunToYomi�Ǻ��줿yc��ͭ���ˤ��롣
1189  * ����Ū�ˤϡ�ʸ��ꥹ�Ȥ����촹�����⡼�����ܡ��Ť�tanContext���˴�
1190  * ��Ԥ���ʸ��ꥹ�Ȥ�tanbunToYomi�λ��������ѹ�����Ƥ��ƤϤʤ�ʤ�����
1191  * yc->curMode���ѹ�����Ƥ��Ƥ�褤��
1192  */
1193 static void
tanbunCommitYomi(d,tan,yc)1194 tanbunCommitYomi(d, tan, yc)
1195 uiContext d;
1196 tanContext tan;
1197 yomiContext yc;
1198 {
1199   if (yc->left)
1200     yc->left->right = (tanContext)yc;
1201   if (yc->right)
1202     yc->right->left = (tanContext)yc;
1203 #ifdef DO_MERGE /* ������Ƥ��ʤ� */
1204   yc = mergeYomiContext(yc);
1205 #endif
1206   if (d && d->modec == (mode_context)tan) {
1207     d->current_mode = yc->curMode;
1208     d->modec = (mode_context)yc;
1209   }
1210   freeTanContext(tan);
1211 }
1212 
1213 static int
TbBubunMuhenkan(d)1214 TbBubunMuhenkan(d)
1215 uiContext d;
1216 {
1217   tanContext tan = (tanContext)d->modec;
1218   yomiContext yc;
1219 
1220   yc = tanbunToYomi(d, tan, (wchar_t *)NULL);
1221   if (yc) {
1222     tanbunCommitYomi(d, tan, yc);
1223     currentModeInfo(d);
1224     makeKanjiStatusReturn(d, yc);
1225     return 0;
1226   }
1227   makeGLineMessageFromString(d, jrKanjiError);
1228   return NothingChangedWithBeep(d);
1229 }
1230 
1231 /*
1232   TanBubunMuhenkan -- �Ѵ����ʸ�����ʸ�����ʬ�䤹�롣
1233 
1234     ���κݡ��ɤߤ���޻���ʬ�䤹��
1235  */
1236 
1237 int
TanBubunMuhenkan(d)1238 TanBubunMuhenkan(d)
1239 uiContext d;
1240 {
1241   yomiContext yc = (yomiContext)d->modec;
1242 
1243   if (yc->id != YOMI_CONTEXT) {
1244     return TbBubunMuhenkan(d);
1245   }
1246 
1247   if (!yc->right && !yc->left && yc->nbunsetsu == 1) {
1248     return TanMuhenkan(d);
1249   }
1250 
1251   if (doTanBubunMuhenkan(d, yc) < 0) {
1252     makeGLineMessageFromString(d, jrKanjiError);
1253     return TanMuhenkan(d);
1254   }
1255   makeYomiReturnStruct(d);
1256   currentModeInfo(d);
1257   return 0;
1258 }
1259 
1260 int
prepareHenkanMode(d)1261 prepareHenkanMode(d)
1262 uiContext d;
1263 {
1264   yomiContext yc = (yomiContext)d->modec;
1265 
1266   if (confirmContext(d, yc) < 0) {
1267     return 0;
1268   }
1269   d->current_mode = yc->curMode = &tankouho_mode;
1270 
1271   return 1;
1272 }
1273 
doHenkan(d,len,kanji)1274 doHenkan(d, len, kanji)
1275 uiContext d;
1276 int len;
1277 wchar_t *kanji;
1278 {
1279   /* ��ߤ�������Ѵ����� */
1280   if(doYomiHenkan(d, len, kanji, (yomiContext)d->modec) == NG) {
1281     return -1;
1282   }
1283 
1284   /* kanji_status_return���� */
1285   makeKanjiStatusReturn(d, (yomiContext)d->modec);
1286   return 0;
1287 }
1288 
1289 
1290 /*
1291  * ���ʴ����Ѵ���Ԥ�
1292  * ��yc->kana_buffer���ɤߤǡ�RkwBgnBun��Ƥ�Ǥ��ʴ����Ѵ����Ϥ���
1293  * ��d->genbuf,contextCache��Ȥ�¾��jrKanjiError�����ꤵ���
1294  * ���֤��ʴ����Ѵ��˼��Ԥ��ޤ����פξ����������ɥ饤�����������뤬��
1295  * �������ɥ饤��Ϻ����ꤷ�Ƥ��ɤ��Τǡ�ñ��̤����Ȥ��ư������ɤ�
1296  * ������ʳ��������ѤϤʤ��Ϥ�
1297  *
1298  * ������	uiContext
1299  *		len       len �����ꤵ��Ƥ�����ʸ��Ĺ����Ĺ���ˤ��롣
1300  *		kanji	  kanji �����ꤵ��Ƥ�����ñʸ���Ѵ����ơ�
1301  *			  �����ȸ���� kanji �Ǽ����줿����˹�碌�롣
1302  * �����	���ェλ�� 0	�۾ェλ�� -1
1303  */
1304 static
doYomiHenkan(d,len,kanji,yc)1305 doYomiHenkan(d, len, kanji, yc)
1306 uiContext	d;
1307 int len;
1308 wchar_t *kanji;
1309 yomiContext yc;
1310 {
1311   unsigned int mode;
1312   extern defaultContext;
1313 
1314 #if defined(DEBUG)
1315   if (iroha_debug) {
1316 /*    printf("yomi     => "); Wprintf(hc->yomi_buffer); putchar('\n');*/
1317     printf("yomi len => %d\n", hc->yomilen);
1318   }
1319 #endif
1320 
1321   /* Ϣʸ���Ѵ����Ϥ��� *//* ����ˤʤ� �������� �Ҥ餬�� ���ղä��� */
1322   mode = 0;
1323   mode = (RK_XFER<<RK_XFERBITS) | RK_KFER;
1324   if (kanji) {
1325     mode |= RK_HENKANMODE(RK_TANBUN |
1326 			  RK_MAKE_WORD |
1327 			  RK_MAKE_EISUUJI |
1328 			  RK_MAKE_KANSUUJI) << (2 * RK_XFERBITS);
1329   }
1330 
1331   if (confirmContext(d, yc) < 0) {
1332     return NG;
1333   }
1334 
1335 #ifdef MEASURE_TIME
1336   {
1337     struct tms timebuf;
1338     long RkTime, times();
1339 
1340     RkTime = times(&timebuf);
1341 #endif /* MEASURE_TIME */
1342 
1343     if ((yc->nbunsetsu =
1344 	 RkwBgnBun(yc->context, yc->kana_buffer, yc->kEndp, mode)) == -1) {
1345       yc->nbunsetsu = 0;
1346       return kanakanError(d);
1347     }
1348 
1349     if (len > 0 && (yc->nbunsetsu = RkwResize(yc->context, len)) == -1) {
1350       RkwEndBun(yc->context, 0);
1351       yc->nbunsetsu = 0;
1352       return kanakanError(d);
1353     }
1354 
1355     if (kanji) {
1356       /* kanji �����ꤵ��Ƥ����顢Ʊ�����䤬�Ǥ�ޤ� RkwNext ���� */
1357       int i, n;
1358 
1359       n = RkwGetKanjiList(yc->context, d->genbuf, ROMEBUFSIZE);
1360       if (n < 0) {
1361 	return kanakanError(d);
1362       }
1363       for (i = 0 ; i < n ; i++) {
1364 	RkwXfer(yc->context, i);
1365 	len = RkwGetKanji(yc->context, d->genbuf, ROMEBUFSIZE);
1366 	if (len < 0) {
1367 	  return kanakanError(d);
1368 	}
1369 	d->genbuf[len] = (wchar_t)'\0';
1370 	if (!WStrcmp(kanji, d->genbuf)) {
1371 	  break;
1372 	}
1373       }
1374       if (i == n) {
1375 	RkwXfer(yc->context, 0);
1376       }
1377     }
1378 
1379 #ifdef MEASURE_TIME
1380     yc->rktime = times(&timebuf);
1381     yc->rktime -= RkTime;
1382   }
1383 #endif /* MEASURE_TIME */
1384 
1385   /* ������ʸ�����Ƭʸ�� */
1386   yc->curbun = 0;
1387 
1388   return(0);
1389 }
1390 
1391 int
TanNop(d)1392 TanNop(d)
1393 uiContext	d;
1394 {
1395   yomiContext yc = (yomiContext)d->modec;
1396 
1397   /* currentModeInfo �ǥ⡼�ɾ���ɬ���֤�褦�˥��ߡ��Υ⡼�ɤ�����Ƥ��� */
1398   d->majorMode = d->minorMode = CANNA_MODE_AlphaMode;
1399   currentModeInfo(d);
1400 
1401   makeKanjiStatusReturn(d, yc);
1402   return 0;
1403 }
1404 
1405 static int
doGoTo(d,yc)1406 doGoTo(d, yc)
1407 uiContext d;
1408 yomiContext yc;
1409 {
1410   if (RkwGoTo(yc->context, yc->curbun) == -1) {
1411     return makeRkError(d, "\312\270\300\341\244\316\260\334\306\260\244\313"
1412 	"\274\272\307\324\244\267\244\336\244\267\244\277");
1413                           /* ʸ��ΰ�ư�˼��Ԥ��ޤ��� */
1414   }
1415   yc->status |= CHIKUJI_OVERWRAP;
1416 
1417   /* kanji_status_return���� */
1418   makeKanjiStatusReturn(d, yc);
1419   return 0;
1420 }
1421 
1422 /*
1423  * ��ʸ��˰�ư����
1424  *
1425  * ������	uiContext
1426  * �����	���ェλ�� 0	�۾ェλ�� -1
1427  */
1428 
1429 int
TanForwardBunsetsu(d)1430 TanForwardBunsetsu(d)
1431 uiContext	d;
1432 {
1433   yomiContext yc = (yomiContext)d->modec;
1434 
1435   if (yc->id != YOMI_CONTEXT) {
1436     return TbForward(d);
1437   }
1438 
1439   yc->kouhoCount = 0;
1440   if (yc->curbun + 1 < yc->nbunsetsu) {
1441     yc->curbun++;
1442   }
1443   else if (yc->cStartp && yc->cStartp < yc->kEndp) { /* �༡���ɤߤ����ˤ��� */
1444     yc->kRStartp = yc->kCurs = yc->cStartp;
1445     yc->rStartp = yc->rCurs = yc->cRStartp;
1446     moveToChikujiYomiMode(d);
1447   }
1448   else if (yc->right) {
1449     return TbForward(d);
1450   }
1451   else if (cannaconf.kakuteiIfEndOfBunsetsu) {
1452     d->nbytes = TanKakutei(d);
1453     d->kanji_status_return->length
1454      = d->kanji_status_return->revPos
1455        = d->kanji_status_return->revLen = 0;
1456     return d->nbytes;
1457   }
1458   else if (!cannaconf.CursorWrap) {
1459     return NothingForGLine(d);
1460   }
1461   else if (yc->left) {
1462     return TbBeginningOfLine(d);
1463   }
1464   else {
1465     yc->curbun = 0;
1466   }
1467 
1468   /* ������ʸ����ı��˰ܤ� */
1469   /* ������ʸ�᤬�DZ����ä��顢
1470      �Ǻ�������ʸ��ˤ���   */
1471   return doGoTo(d, yc);
1472 }
1473 
1474 /*
1475  * ��ʸ��˰�ư����
1476  *
1477  * ������	uiContext
1478  * �����	���ェλ�� 0	�۾ェλ�� -1
1479  */
1480 int
TanBackwardBunsetsu(d)1481 TanBackwardBunsetsu(d)
1482 uiContext	d;
1483 {
1484   yomiContext yc = (yomiContext)d->modec;
1485 
1486   if (yc->id != YOMI_CONTEXT) {
1487     return TbBackward(d);
1488   }
1489 
1490   yc->kouhoCount = 0;
1491   if (yc->curbun) {
1492     yc->curbun--;
1493   }
1494   else if (yc->left) {
1495     return TbBackward(d);
1496   }
1497   else if (!cannaconf.CursorWrap) {
1498     return NothingForGLine(d);
1499   }
1500   else if (yc->right) {
1501     return TbEndOfLine(d);
1502   }
1503   else if (yc->cStartp && yc->cStartp < yc->kEndp) { /* �༡���ɤߤ����ˤ��� */
1504     yc->kCurs = yc->kRStartp = yc->kEndp;
1505     yc->rCurs = yc->rStartp = yc->rEndp;
1506     moveToChikujiYomiMode(d);
1507   }
1508   else {
1509     yc->curbun = yc->nbunsetsu - 1;
1510   }
1511 
1512   return doGoTo(d, yc);
1513 }
1514 
1515 /*
1516  * ����������ȸ���ˤ���
1517  *
1518  * ������	uiContext
1519  * �����	���ェλ�� 0	�۾ェλ�� -1
1520  */
1521 
1522 static
tanNextKouho(d,yc)1523 tanNextKouho(d, yc)
1524 uiContext	d;
1525 yomiContext   yc;
1526 {
1527 #ifdef MEASURE_TIME
1528   struct tms timebuf;
1529   long proctime, times();
1530 
1531   proctime = times(&timebuf);
1532 #endif /* MEASURE_TIME */
1533 
1534   /* ���θ�������ȸ���Ȥ��� */
1535   if (RkwNext(yc->context) == -1) {
1536     makeRkError(d, "\245\253\245\354\245\363\245\310\270\365\312\344\244\362"
1537 	"\274\350\244\352\275\320\244\273\244\336\244\273\244\363\244\307"
1538 	"\244\267\244\277");
1539                    /* �����ȸ������Ф��ޤ���Ǥ��� */
1540     return TanMuhenkan(d);
1541   }
1542 
1543 #ifdef MEASURE_TIME
1544   yc->rktime = times(&timebuf);
1545   yc->rktime -= proctime;
1546 #endif /* MEASURE_TIME */
1547 
1548   /* kanji_status_return���� */
1549   makeKanjiStatusReturn(d, yc);
1550 
1551 #ifdef MEASURE_TIME
1552   yc->proctime = times(&timebuf);
1553   yc->proctime -= proctime;
1554 #endif /* MEASURE_TIME */
1555 
1556   return(0);
1557 }
1558 
1559 /*
1560   enterTanHenkanMode -- tanContext �� yomiContext �ˤ����Ѵ��ν�������
1561 
1562  */
1563 
1564 static int
enterTanHenkanMode(d,fnum)1565 enterTanHenkanMode(d, fnum)
1566 uiContext d;
1567 {
1568   tanContext tan = (tanContext)d->modec;
1569   yomiContext yc;
1570   wchar_t *prevkanji;
1571 
1572   prevkanji = tan->kanji;
1573   tan->kanji = (wchar_t *)0;
1574 
1575   yc = tanbunToYomi(d, tan, prevkanji);
1576   free((char *)prevkanji);
1577   if (yc) {
1578 
1579     /*������
1580       ñ����⡼�ɤη��ˤ���
1581       */
1582     if (confirmContext(d, yc) >= 0) { /* really needed? */
1583       tanbunCommitYomi(d, tan, yc);
1584       yc->kouhoCount = 1;
1585 
1586       d->more.todo = 1;
1587       d->more.ch = d->ch;
1588       d->more.fnum = fnum;
1589       return 0;
1590     }
1591     freeYomiContext(yc);
1592   }
1593   makeGLineMessageFromString(d, jrKanjiError);
1594   return NothingChangedWithBeep(d);
1595 }
1596 
1597 /*
1598  * ��������Ԥ�ɽ������
1599  *
1600  * ���������ɽ���Τ���Υǡ�����ơ��֥�˺�������
1601  * ���������ɽ���Ԥ������Ȥ��ϡ�������ɽ�����ʤ��Ǽ�������ξ��ɽ������
1602  *
1603  * ������	uiContext
1604  * �����	���ェλ�� 0	�۾ェλ�� -1
1605  */
1606 
TanKouhoIchiran(d)1607 TanKouhoIchiran(d)
1608 uiContext d;
1609 {
1610   if (d->modec->id != YOMI_CONTEXT) {
1611     return enterTanHenkanMode(d, CANNA_FN_KouhoIchiran);
1612   }
1613   return tanKouhoIchiran(d, 1);
1614 }
1615 
TanNextKouho(d)1616 TanNextKouho(d)
1617 uiContext d;
1618 {
1619   yomiContext yc = (yomiContext)d->modec;
1620 
1621   if (yc->id != YOMI_CONTEXT) {
1622     return enterTanHenkanMode(d, CANNA_FN_Next);
1623   }
1624   yc->status |= CHIKUJI_OVERWRAP;
1625   yc->kouhoCount = 0;
1626   return tanNextKouho(d, yc);
1627 }
1628 
1629 /*
1630 
1631   TanHenkan -- ���������å�����ʳ��� TanNextKouho �Ȥۤ�Ʊ��
1632 
1633  */
1634 static TanHenkan pro((uiContext));
1635 
1636 static int
TanHenkan(d)1637 TanHenkan(d)
1638 uiContext d;
1639 {
1640   yomiContext yc = (yomiContext)d->modec;
1641 
1642   if (yc->id != YOMI_CONTEXT) {
1643     return enterTanHenkanMode(d, CANNA_FN_Henkan);
1644   }
1645 
1646   if (cannaconf.kouho_threshold &&
1647       ++yc->kouhoCount >= cannaconf.kouho_threshold) {
1648     return TanKouhoIchiran(d);
1649   }
1650   else {
1651     return tanNextKouho(d, yc);
1652   }
1653 }
1654 
1655 /*
1656  * ����������ȸ���ˤ���
1657  *
1658  * ������	uiContext
1659  * �����	���ェλ�� 0	�۾ェλ�� -1
1660  */
TanPreviousKouho(d)1661 TanPreviousKouho(d)
1662 uiContext	d;
1663 {
1664   yomiContext yc = (yomiContext)d->modec;
1665 
1666   if (yc->id != YOMI_CONTEXT) {
1667     return enterTanHenkanMode(d, CANNA_FN_Prev);
1668   }
1669 
1670   yc->status |= CHIKUJI_OVERWRAP;
1671   yc->kouhoCount = 0;
1672   /* ���θ�������ȸ���Ȥ��� */
1673   if (RkwPrev(yc->context) == -1) {
1674     makeRkError(d, "\245\253\245\354\245\363\245\310\270\365\312\344\244\362"
1675 	"\274\350\244\352\275\320\244\273\244\336\244\273\244\363\244\307"
1676 	"\244\267\244\277");
1677                    /* �����ȸ������Ф��ޤ���Ǥ��� */
1678     return TanMuhenkan(d);
1679   }
1680 
1681   /* kanji_status_return���� */
1682   makeKanjiStatusReturn(d, yc);
1683 
1684   return 0;
1685 }
1686 
1687 /*
1688   tanJishuHenkan -- �����ʸ����������Ѵ�����
1689  */
1690 
1691 static int tanJishuHenkan pro((uiContext, int));
1692 
1693 static int
tanJishuHenkan(d,fn)1694 tanJishuHenkan(d, fn)
1695 uiContext d;
1696 int fn;
1697 {
1698   d->nbytes = TanBubunMuhenkan(d);
1699   d->more.todo = 1;
1700   d->more.ch = d->ch;
1701   d->more.fnum = fn;
1702   return d->nbytes;
1703 }
1704 
TanHiragana(d)1705 TanHiragana(d)
1706 uiContext	d;
1707 {
1708   return tanJishuHenkan(d, CANNA_FN_Hiragana);
1709 }
1710 
TanKatakana(d)1711 TanKatakana(d)
1712 uiContext	d;
1713 {
1714   return tanJishuHenkan(d, CANNA_FN_Katakana);
1715 }
1716 
TanRomaji(d)1717 TanRomaji(d)
1718 uiContext	d;
1719 {
1720   return tanJishuHenkan(d, CANNA_FN_Romaji);
1721 }
1722 
TanUpper(d)1723 TanUpper(d)
1724 uiContext	d;
1725 {
1726   return tanJishuHenkan(d, CANNA_FN_ToUpper);
1727 }
1728 
TanCapitalize(d)1729 TanCapitalize(d)
1730 uiContext	d;
1731 {
1732   return tanJishuHenkan(d, CANNA_FN_Capitalize);
1733 }
1734 
TanZenkaku(d)1735 TanZenkaku(d)
1736 uiContext d;
1737 {
1738   return tanJishuHenkan(d, CANNA_FN_Zenkaku);
1739 }
1740 
TanHankaku(d)1741 TanHankaku(d)
1742 uiContext d;
1743 {
1744   return tanJishuHenkan(d, CANNA_FN_Hankaku);
1745 }
1746 
1747 int TanKanaRotate pro((uiContext));
1748 
TanKanaRotate(d)1749 TanKanaRotate(d)
1750 uiContext d;
1751 {
1752   return tanJishuHenkan(d, CANNA_FN_KanaRotate);
1753 }
1754 
1755 int TanRomajiRotate pro((uiContext));
1756 
TanRomajiRotate(d)1757 TanRomajiRotate(d)
1758 uiContext d;
1759 {
1760   return tanJishuHenkan(d, CANNA_FN_RomajiRotate);
1761 }
1762 
1763 int TanCaseRotateForward pro((uiContext));
1764 
TanCaseRotateForward(d)1765 TanCaseRotateForward(d)
1766 uiContext d;
1767 {
1768   return tanJishuHenkan(d, CANNA_FN_CaseRotate);
1769 }
1770 
1771 static int
gotoBunsetsu(yc,n)1772 gotoBunsetsu(yc, n)
1773 yomiContext yc;
1774 int n;
1775 {
1776   /* ������ʸ����ư���� */
1777   if (RkwGoTo(yc->context, n) == -1) {
1778     if (errno == EPIPE) {
1779       jrKanjiPipeError();
1780     }
1781     jrKanjiError = "\312\270\300\341\244\316\260\334\306\260\244\313\274\272"
1782 	"\307\324\244\267\244\336\244\267\244\277";
1783                    /* ʸ��ΰ�ư�˼��Ԥ��ޤ��� */
1784     return NG;
1785   }
1786   yc->curbun = n;
1787   return 0;
1788 }
1789 
1790 /*
1791  * �Ǻ�ʸ��˰�ư����
1792  *
1793  * ������	uiContext
1794  * �����	���ェλ�� 0	�۾ェλ�� -1
1795  */
1796 int
TanBeginningOfBunsetsu(d)1797 TanBeginningOfBunsetsu(d)
1798 uiContext	d;
1799 {
1800   yomiContext yc = (yomiContext)d->modec;
1801 
1802   if (yc->id != YOMI_CONTEXT || yc->left) {
1803     return TbBeginningOfLine(d);
1804   }
1805   yc->kouhoCount = 0;
1806   if (gotoBunsetsu(yc, 0) < 0) {
1807     return NG;
1808   }
1809   makeKanjiStatusReturn(d, yc);
1810   return 0;
1811 }
1812 
1813 /*
1814  * �DZ�ʸ��˰�ư����
1815  *
1816  * ������	uiContext
1817  * �����	���ェλ�� 0	�۾ェλ�� -1
1818  */
1819 int
TanEndOfBunsetsu(d)1820 TanEndOfBunsetsu(d)
1821 uiContext	d;
1822 {
1823   yomiContext yc = (yomiContext)d->modec;
1824 
1825   if (yc->id != YOMI_CONTEXT || yc->right) {
1826     return TbEndOfLine(d);
1827   }
1828 
1829   yc->kouhoCount = 0;
1830   if (yc->cStartp && yc->cStartp < yc->kEndp) {
1831     yc->kRStartp = yc->kCurs = yc->kEndp;
1832     yc->rStartp = yc->rCurs = yc->rEndp;
1833     moveToChikujiYomiMode(d);
1834   }
1835   if (gotoBunsetsu(yc, yc->nbunsetsu - 1) < 0) {
1836     return NG;
1837   }
1838   yc->status |= CHIKUJI_OVERWRAP;
1839   makeKanjiStatusReturn(d, yc);
1840   return 0;
1841 }
1842 
1843 int
tanMuhenkan(d,kCurs)1844 tanMuhenkan(d, kCurs)
1845 uiContext d;
1846 int kCurs;
1847 {
1848   extern KanjiModeRec yomi_mode;
1849   yomiContext yc = (yomiContext)d->modec;
1850   int autoconvert = (yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE);
1851 
1852   if (RkwEndBun(yc->context, 0) == -1) {
1853     if (errno == EPIPE) {
1854       jrKanjiPipeError();
1855     }
1856   }
1857 
1858   if (autoconvert) {
1859     yc->status &= CHIKUJI_NULL_STATUS;
1860     d->current_mode = yc->curMode = &cy_mode;
1861     yc->ys = yc->ye = yc->cStartp = yc->cRStartp = 0;
1862     yc->rCurs = yc->rStartp = yc->rEndp;
1863     yc->kCurs = yc->kRStartp = yc->kEndp;
1864     clearHenkanContext(yc);
1865   }
1866   else {
1867     d->current_mode = yc->curMode = &yomi_mode;
1868   }
1869   yc->minorMode = getBaseMode(yc);
1870 
1871   if (kCurs >= 0) {
1872     int rpos;
1873 
1874     kPos2rPos(yc, 0, kCurs, (int *)0, &rpos);
1875     yc->kCurs = yc->kRStartp = kCurs;
1876     yc->rCurs = yc->rStartp = rpos;
1877   }
1878 
1879   /* ����̵�Ѵ��ˤ��� */
1880   yc->nbunsetsu = 0;
1881 
1882   /* ñ������֤����ɤߤ����Ȥ��ˤ�̵����mark����Ƭ���᤹ */
1883   yc->cmark = yc->pmark = 0;
1884 
1885   abandonContext(d, yc);
1886 
1887   return 0;
1888 }
1889 
1890 /*
1891  * ���Ƥ�ʸ����ɤߤ��ᤷ��YomiInputMode �����
1892  *
1893  * ������	uiContext
1894  * �����	���ェλ�� 0	�۾ェλ�� -1
1895  */
1896 
TanMuhenkan(d)1897 TanMuhenkan(d)
1898 uiContext	d;
1899 {
1900   yomiContext yc = (yomiContext)d->modec, newyc;
1901   tanContext tan;
1902 
1903   if (yc->id != YOMI_CONTEXT || yc->left || yc->right) {
1904     tan = (tanContext)yc;
1905     while (tan->left) {
1906       tan = tan->left;
1907     }
1908     if (tan->id == YOMI_CONTEXT) {
1909       newyc = (yomiContext)tan;
1910     }
1911     else {
1912       newyc = newFilledYomiContext(yc->next, yc->prevMode);
1913       if (newyc) {
1914 	tan->left = (tanContext)newyc;
1915 	newyc->right = tan;
1916 	newyc->generalFlags = tan->generalFlags;
1917 	newyc->savedFlags = tan->savedFlags;
1918 	if (chikujip(newyc)) {
1919 	  newyc->curMode = &cy_mode;
1920 	}
1921 	newyc->minorMode = getBaseMode(newyc);
1922       }
1923       else {
1924 	jrKanjiError = "\245\341\245\342\245\352\244\254\302\255\244\352"
1925 	"\244\336\244\273\244\363";
1926                        /* ���꤬­��ޤ��� */
1927 	makeGLineMessageFromString(d, jrKanjiError);
1928 	return NothingChangedWithBeep(d);
1929       }
1930     }
1931     d->modec = (mode_context)newyc;
1932     d->current_mode = newyc->curMode;
1933 
1934     doMuhenkan(d, newyc);
1935 
1936     if (newyc->generalFlags &
1937 	(CANNA_YOMI_CHIKUJI_MODE | CANNA_YOMI_BASE_CHIKUJI)) {
1938       /* �ֿ����༡���ä��פΤǤ���С��༡�⡼�ɤ��᤹ */
1939       newyc->generalFlags |= CANNA_YOMI_CHIKUJI_MODE;
1940       newyc->generalFlags &= ~CANNA_YOMI_BASE_CHIKUJI;
1941       newyc->minorMode = getBaseMode(newyc);
1942       d->current_mode = newyc->curMode = &cy_mode;
1943     }
1944 
1945     makeYomiReturnStruct(d);
1946     currentModeInfo(d);
1947     return 0;
1948   }
1949 
1950   if (yc->generalFlags &
1951       (CANNA_YOMI_CHIKUJI_MODE | CANNA_YOMI_BASE_CHIKUJI)) {
1952     /* �ֿ����༡���ä��פΤǤ���С��༡�⡼�ɤ��᤹ */
1953     yc->generalFlags |= CANNA_YOMI_CHIKUJI_MODE;
1954     yc->generalFlags &= ~CANNA_YOMI_BASE_CHIKUJI;
1955     /* �̥륹�ơ��������᤹ */
1956     yc->status &= CHIKUJI_NULL_STATUS;
1957   }
1958 
1959   tanMuhenkan(d, -1);
1960   makeYomiReturnStruct(d);
1961   currentModeInfo(d);
1962   return 0;
1963 }
1964 
1965 int
TanDeletePrevious(d)1966 TanDeletePrevious(d)
1967 uiContext	d;
1968 {
1969   yomiContext yc = (yomiContext)d->modec;
1970   int i, j, l = -1, ret = 0;
1971 #ifndef USE_MALLOC_FOR_BIG_ARRAY
1972   wchar_t tmpbuf[ROMEBUFSIZE];
1973 #else
1974   wchar_t *tmpbuf = (wchar_t *)malloc(sizeof(wchar_t) * ROMEBUFSIZE);
1975   if (!tmpbuf) {
1976     return ret;
1977   }
1978 #endif
1979 
1980   if (yc->id != YOMI_CONTEXT) {
1981     ret = TanMuhenkan(d);
1982     goto return_ret;
1983   }
1984 
1985   if ((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) &&
1986       !cannaconf.BackspaceBehavesAsQuit) {
1987     ret = ChikujiTanDeletePrevious(d);
1988     goto return_ret;
1989   }
1990   else {
1991     if (cannaconf.keepCursorPosition) {
1992       for (i = 0, l = 0; i <= yc->curbun; i++) {
1993 	if (RkwGoTo(yc->context, i) == -1
1994 	    || (j = RkwGetYomi(yc->context, tmpbuf, ROMEBUFSIZE)) == -1) {
1995 	  l = -1;
1996 	  break;
1997 	}
1998 	l += j;
1999       }
2000     }
2001     yc->status &= CHIKUJI_NULL_STATUS;
2002     tanMuhenkan(d, l);
2003     makeYomiReturnStruct(d);
2004     currentModeInfo(d);
2005     ret = 0;
2006   }
2007  return_ret:
2008 #ifdef USE_MALLOC_FOR_BIG_ARRAY
2009   (void)free((char *)tmpbuf);
2010 #endif
2011   return ret;
2012 }
2013 
2014 #if 0
2015 /*
2016   doTanKakutei -- ���ꤵ����ư�����
2017 
2018   retval 0 -- ����̵�����ꤷ����
2019          1 -- ���ꤷ����ʤ��ʤä���
2020         -1 -- ���顼��
2021  */
2022 
2023 static
2024 doTanKakutei(d, yc)
2025 uiContext	d;
2026 yomiContext yc;
2027 {
2028   if ((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) &&
2029       (yc->cStartp < yc->kEndp)) {
2030     (void)RomajiFlushYomi(d, (wchar_t *)0, 0);
2031   }
2032 
2033   return 0;
2034 }
2035 #endif /* 0 */
2036 
2037 void
finishTanKakutei(d)2038 finishTanKakutei(d)
2039 uiContext d;
2040 {
2041   yomiContext yc = (yomiContext)d->modec;
2042   int autoconvert = yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE;
2043 
2044 #ifdef DO_RENGO_LEARNING
2045 #define RENGOBUFSIZE 256
2046 
2047   /* BIGARRAY */
2048   if (RengoGakushu && hc->nbunsetsu > 1) { /* Ϣ��ؽ����褦���ʤ� */
2049     RkLex  lex[2][RENGOBUFSIZE];
2050     wchar_t yomi[2][RENGOBUFSIZE];
2051     wchar_t kanji[2][RENGOBUFSIZE];
2052     wchar_t word[1024], *w;
2053     unsigned char xxxx[ROMEBUFSIZE];
2054     int    nword[2], wlen;
2055 
2056     *(w = word) = (wchar_t) '\0';
2057     wlen = 1024;
2058 
2059     RkwGoTo(hc->context, 0);
2060     nword[0] = RkwGetLex(hc->context, lex[0], RENGOBUFSIZE);
2061     yomi[0][0] =
2062       (wchar_t) '\0'; /* yomi[current][0]�ο����� �� RkwGetYomi������ */
2063 
2064     for (i = 1 ; i < hc->nbunsetsu ; i++) {
2065       int current, previous, mighter;
2066 
2067       current = i % 2;
2068       previous = 1 - current;
2069 
2070       nword[current] = 0;
2071       if ( !nword[previous] ) {
2072 	nword[previous] = RkwGetLex(hc->context, lex[previous], RENGOBUFSIZE);
2073       }
2074       RkwRight(hc->context);
2075 
2076       if (nword[previous] == 1) {
2077 	nword[current] = RkwGetLex(hc->context, lex[current], RENGOBUFSIZE);
2078 	yomi[current][0] = (wchar_t) '\0';
2079 	if (((lex[previous][0].ylen <= 3 && lex[previous][0].klen == 1) ||
2080 	     (lex[current][0].ylen <= 3 && lex[current][0].klen == 1)) &&
2081 	    (lex[current][0].rownum < R_K5 ||
2082 	     R_NZX < lex[current][0].rownum)) {
2083 	  if ( !yomi[previous][0] ) {
2084 	    RkwLeft(hc->context);
2085 	    RkwGetYomi(hc->context, yomi[previous], RENGOBUFSIZE);
2086 	    RkwGetKanji(hc->context, kanji[previous], RENGOBUFSIZE);
2087 	    RkwRight(hc->context);
2088 	  }
2089 	  RkwGetYomi(hc->context, yomi[current], RENGOBUFSIZE);
2090 	  RkwGetKanji(hc->context, kanji[current], RENGOBUFSIZE);
2091 
2092 	  WStrncpy(yomi[previous] + lex[previous][0].ylen,
2093 		   yomi[current], lex[current][0].ylen);
2094 	  yomi[previous][lex[previous][0].ylen + lex[current][0].ylen] =
2095 	    (wchar_t) '\0';
2096 
2097 	  WStrncpy(kanji[previous] + lex[previous][0].klen,
2098 		   kanji[current], lex[current][0].klen);
2099 	  kanji[previous][lex[previous][0].klen + lex[current][0].klen] =
2100 	    (wchar_t) '\0';
2101 
2102 #ifdef NAGASADEBUNPOUWOKIMEYOU
2103 	  if (lex[previous][0].klen >= lex[current][0].klen) {
2104 	    /* ���δ�����Ĺ��       >=    ���δ�����Ĺ�� */
2105 	    mighter = previous;
2106 	  }
2107 	  else {
2108 	    mighter = current;
2109 	  }
2110 #else /* !NAGASADEBUNPOUWOKIMEYOU */
2111 	  mighter = current;
2112 #endif /* !NAGASADEBUNPOUWOKIMEYOU */
2113 	  WStrcpy(w, yomi[previous]);
2114 	  printf(xxxx, " #%d#%d ", lex[mighter][0].rownum,
2115 		 lex[mighter][0].colnum);
2116 	  MBstowcs(w + WStrlen(w), xxxx, wlen - WStrlen(w));
2117 	  WStrcat(w, kanji[previous]);
2118 	  wlen -= (WStrlen(w) + 1); w += WStrlen(w) + 1; *w = (wchar_t) '\0';
2119 	}
2120       }
2121     }
2122   }
2123 #endif /* DO_RENGO_LEARNING */
2124 
2125   if (RkwEndBun(yc->context, cannaconf.Gakushu ? 1 : 0) == -1) {
2126     if (errno == EPIPE) {
2127       jrKanjiPipeError();
2128     }
2129   }
2130 
2131 #ifdef DO_RENGO_LEARNING
2132   if (RengoGakushu && yc->nbunsetsu > 1) { /* Ϣ��ؽ����褦���ʤ� */
2133     for (w = word ; *w ; w += WStrlen(w) + 1) {
2134       RkwDefineDic(yc->context, RengoGakushu, w);
2135     }
2136   }
2137 #endif /* DO_RENGO_LEARNING */
2138 
2139   if (autoconvert) {
2140     yc->status &= CHIKUJI_NULL_STATUS;
2141     yc->ys = yc->ye = yc->cStartp = yc->cRStartp = 0;
2142     clearHenkanContext(yc);
2143     yc->kEndp = yc->rEndp = yc->kCurs = yc->rCurs =
2144       yc->cStartp = yc->cRStartp =
2145 	yc->rStartp = yc->kRStartp = 0;
2146     yc->kAttr[0] = yc->rAttr[0] = SENTOU;
2147     yc->kana_buffer[0] = yc->romaji_buffer[0] = 0;
2148 /*    d->kanji_status_return->info |= KanjiEmptyInfo; ¿ʬ�פ�ʤ��Τ�.. */
2149     d->current_mode = yc->curMode = yc->myEmptyMode;
2150   }
2151   yc->minorMode = getBaseMode(yc);
2152 
2153   /* ñ������֤����ɤߤ����Ȥ��ˤ�̵����mark����Ƭ���᤹ */
2154   yc->nbunsetsu = 0;
2155   yc->cmark = yc->pmark = 0;
2156 
2157   abandonContext(d, yc);
2158 
2159   if (yc->savedFlags & CANNA_YOMI_MODE_SAVED) {
2160     restoreFlags(yc);
2161   }
2162 }
2163 
TanKakutei(d)2164 TanKakutei(d)
2165 uiContext d;
2166 {
2167   return YomiKakutei(d);
2168 }
2169 
2170 /*
2171  * �����������ꤵ�������޻��������Ȥ���
2172  *
2173  * renbun-continue �� t �ΤȤ��ϡ��ºݤˤϳ��ꤷ�ʤ��Τǽ�����
2174  * ���ݤ��ä��ꤹ�롣
2175  *
2176  * ������	uiContext
2177  * �����	���ェλ�� 0	�۾ェλ�� -1
2178  */
2179 
2180 static TanKakuteiYomiInsert pro((uiContext));
2181 
2182 static int
TanKakuteiYomiInsert(d)2183 TanKakuteiYomiInsert(d)
2184 uiContext d;
2185 {
2186   yomiContext yc = (yomiContext)d->modec;
2187   tanContext tan;
2188 
2189   if ((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE)
2190       ? cannaconf.ChikujiContinue : cannaconf.RenbunContinue) {
2191     d->nbytes = 0;
2192     for (tan = (tanContext)yc ; tan->right ; tan = tan->right)
2193       /* bodyless 'for' */;
2194     yc = (yomiContext)0; /* ǰ�Τ��� */
2195     d->modec = (mode_context)tan;
2196     setMode(d, tan, 1);
2197 
2198     if (tan->id == YOMI_CONTEXT) {
2199       yc = (yomiContext)tan;
2200 
2201       if (yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) {
2202 	/* �༡�ʤ����̤�³�������������ʤ� */
2203 	yc->minorMode = CANNA_MODE_ChikujiTanMode;
2204 	d->current_mode = yc->curMode = &cb_mode;
2205 	currentModeInfo(d);
2206 	yc->status &= ~CHIKUJI_OVERWRAP;
2207 	if (yc->kCurs != yc->kEndp) {
2208 	  yc->rStartp = yc->rCurs = yc->rEndp;
2209 	  yc->kRStartp = yc->kCurs = yc->kEndp;
2210 	}
2211 	yc->ys = yc->ye = yc->cStartp;
2212 	return YomiInsert(d);
2213       }
2214       else { /* �༡����ʤ���� */
2215 	extern nKouhoBunsetsu;
2216 
2217 	yc->curbun = yc->nbunsetsu;
2218 	if (doTanBubunMuhenkan(d, yc) < 0) {
2219 	  makeGLineMessageFromString(d, jrKanjiError);
2220 	  return NothingChangedWithBeep(d);
2221 	}
2222 	if (nKouhoBunsetsu) {
2223 	  (void)cutOffLeftSide(d, yc, nKouhoBunsetsu);
2224 	}
2225       }
2226     }
2227     else {
2228       yc = newFilledYomiContext(tan->next, tan->prevMode);
2229       /* �������ʤ� if (tan->right) yc->right = tan->right;
2230 	 yc->right->left = yc; */
2231       tan->right = (tanContext)yc;
2232       yc->left = tan;
2233       d->modec = (mode_context)yc;
2234       /* d->current_mode = yc->curMode = yc->myEmptyMode; */
2235     }
2236   }
2237   else {
2238     d->nbytes = YomiKakutei(d);
2239   }
2240   /* YomiKakutei(d) �� d->modec ���ѹ����줿��ǽ��������ΤǺ��ɤ߹��ߤ��� */
2241   yc = (yomiContext)d->modec;
2242 
2243   if (yc->id == YOMI_CONTEXT) {
2244     yc->minorMode = getBaseMode(yc);
2245   }
2246   currentModeInfo(d);
2247   d->more.todo = 1;
2248   d->more.ch = d->ch;
2249   d->more.fnum = 0;    /* ��� ch �Ǽ������������� */
2250   return d->nbytes;
2251 }
2252 
2253 
2254 /* cfuncdef
2255 
2256   pos �ǻ��ꤵ�줿ʸ�ᤪ��Ӥ�������ʸ��λ����Ѵ������
2257   ���ꥢ���롣
2258 */
2259 
2260 static int
doTbResize(d,yc,n)2261 doTbResize(d, yc, n)
2262 uiContext d;
2263 yomiContext yc;
2264 int n;
2265 {
2266   int len;
2267 
2268   if (doTanBubunMuhenkan(d, yc) < 0) {
2269     makeGLineMessageFromString(d, jrKanjiError);
2270     return NothingChangedWithBeep(d);
2271   }
2272   len = yc->kEndp;
2273   doMuhenkan(d, yc); /* yc ���鱦��ߤ��̵�Ѵ��ˤ��� yc �ˤĤʤ��� */
2274   if (!prepareHenkanMode(d)) {
2275     makeGLineMessageFromString(d, jrKanjiError);
2276     makeYomiReturnStruct(d);
2277     currentModeInfo(d);
2278     return 0;
2279   }
2280   yc->minorMode = CANNA_MODE_TankouhoMode;
2281   yc->kouhoCount = 0;
2282   if (doHenkan(d, len + n, (wchar_t *)0) < 0) {
2283     makeGLineMessageFromString(d, jrKanjiError);
2284     makeYomiReturnStruct(d);
2285     currentModeInfo(d);
2286     return 0;
2287   }
2288   currentModeInfo(d);
2289   makeKanjiStatusReturn(d, yc);
2290   return 0;
2291 }
2292 
2293 /*
2294  * ʸ����Ф�
2295  *
2296  * ������	uiContext
2297  * �����	���ェλ�� 0	�۾ェλ�� -1
2298  */
2299 static TanExtendBunsetsu pro((uiContext));
2300 
2301 static int
TanExtendBunsetsu(d)2302 TanExtendBunsetsu(d)
2303 uiContext	d;
2304 {
2305   yomiContext yc = (yomiContext)d->modec;
2306 
2307   if (yc->id != YOMI_CONTEXT) {
2308     return enterTanHenkanMode(d, CANNA_FN_Extend);
2309   }
2310 
2311   d->nbytes = 0;
2312   yc->kouhoCount = 0;
2313   if (yc->right) {
2314     return doTbResize(d, yc, 1);
2315   }
2316   if ((yc->nbunsetsu = RkwEnlarge(yc->context)) <= 0) {
2317     makeRkError(d, "\312\270\300\341\244\316\263\310\302\347\244\313\274\272"
2318 	"\307\324\244\267\244\336\244\267\244\277");
2319                    /* ʸ��γ���˼��Ԥ��ޤ��� */
2320     return TanMuhenkan(d);
2321   }
2322   makeKanjiStatusReturn(d, yc);
2323   return(d->nbytes);
2324 }
2325 
2326 /*
2327  * ʸ���̤��
2328  *
2329  * ������	uiContext
2330  * �����	���ェλ�� 0	�۾ェλ�� -1
2331  */
2332 static TanShrinkBunsetsu pro((uiContext));
2333 
2334 static int
TanShrinkBunsetsu(d)2335 TanShrinkBunsetsu(d)
2336 uiContext	d;
2337 {
2338   yomiContext yc = (yomiContext)d->modec;
2339 
2340   if (yc->id != YOMI_CONTEXT) {
2341     return enterTanHenkanMode(d, CANNA_FN_Shrink);
2342   }
2343 
2344   d->nbytes = 0;
2345   yc->kouhoCount = 0;
2346 
2347   if (yc->right) {
2348     return doTbResize(d, yc, -1);
2349   }
2350 
2351   /* ʸ���̤�� */
2352   if ((yc->nbunsetsu = RkwShorten(yc->context)) <= 0) {
2353     makeRkError(d, "\312\270\300\341\244\316\275\314\276\256\244\313\274\272"
2354 	"\307\324\244\267\244\336\244\267\244\277");
2355                    /* ʸ��ν̾��˼��Ԥ��ޤ��� */
2356     return TanMuhenkan(d);
2357   }
2358   makeKanjiStatusReturn(d, yc);
2359 
2360   return(d->nbytes);
2361 }
2362 
2363 #define BUNPOU_DISPLAY
2364 
2365 #ifdef BUNPOU_DISPLAY
2366 /*
2367  * ʸˡ�����ץ��Ȥ���
2368  *
2369  * ������	uiContext
2370  * �����	���ェλ�� 0	�۾ェλ�� -1
2371  */
TanPrintBunpou(d)2372 TanPrintBunpou(d)
2373 uiContext	d;
2374 {
2375   yomiContext yc = (yomiContext)d->modec;
2376   static wchar_t mesg[512]; /* static! */
2377 
2378   if (yc->id != YOMI_CONTEXT) {
2379     return enterTanHenkanMode(d, CANNA_FN_ConvertAsHex);
2380   }
2381 
2382 #ifdef notdef
2383 #ifdef DO_GETYOMI
2384   if (RkwGetYomi(yc->context, buf, 256) == -1) {
2385     if (errno == EPIPE) {
2386       jrKanjiPipeError();
2387       TanMuhenkan(d);
2388     }
2389     fprintf(stderr, "�����ȸ�����ɤߤ���Ф��ޤ���Ǥ�����\n");
2390   }
2391   Wfprintf(stderr, "%s\n", buf);
2392 #endif /* DO_GETYOMI */
2393 
2394   if(RkwGetKanji(yc->context, buf, 256) == -1) {
2395     if(errno == EPIPE) {
2396       jrKanjiPipeError();
2397     }
2398     jrKanjiError = "\245\253\245\354\245\363\245\310\270\365\312\344\244\362"
2399 	"\274\350\244\352\275\320\244\273\244\336\244\273\244\363\244\307"
2400 	"\244\267\244\277";
2401                    /* �����ȸ������Ф��ޤ���Ǥ��� */
2402     return NG;
2403   }
2404 #endif
2405 
2406   if (RkwGetHinshi(yc->context, mesg, sizeof(mesg) / sizeof(wchar_t)) < 0) {
2407     jrKanjiError = "\311\312\273\354\276\360\312\363\244\362\274\350\244\352"
2408 	"\275\320\244\273\244\336\244\273\244\363\244\307\244\267\244\277";
2409                    /* �ʻ�������Ф��ޤ���Ǥ��� */
2410     makeGLineMessageFromString(d, jrKanjiError);
2411     makeKanjiStatusReturn(d, yc);
2412     return 0;
2413   }
2414 
2415   makeKanjiStatusReturn(d, yc);
2416   d->kanji_status_return->info |= KanjiGLineInfo;
2417   d->kanji_status_return->gline.line = mesg;
2418   d->kanji_status_return->gline.length = WStrlen(mesg);
2419   d->kanji_status_return->gline.revPos = 0;
2420   d->kanji_status_return->gline.revLen = 0;
2421   d->flags |= PLEASE_CLEAR_GLINE;
2422   d->flags &= ~PCG_RECOGNIZED;
2423   return 0;
2424 }
2425 #endif /* BUNPOU_DISPLAY */
2426 
2427 #ifdef MEASURE_TIME
2428 static
TanPrintTime(d)2429 TanPrintTime(d)
2430 uiContext	d;
2431 {
2432   /* BIGARRAY */
2433   unsgined char tmpbuf[1024];
2434   static wchar_t buf[256];
2435   yomiContext yc = (yomiContext)d->modec;
2436 
2437   ycc->kouhoCount = 0;
2438   sprintf(tmpbuf, "\312\321\264\271\273\376\264\326 %d [ms]��\244\246\244\301"
2439 	" UI \311\364\244\317 %d [ms]",
2440 	   (yc->proctime) * 50 / 3,
2441 	   (yc->proctime - yc->rktime) * 50 / 3);
2442                /* �Ѵ����� %d [ms]������ UI ���� %d [ms] */
2443   MBstowcs(buf, tmpbuf, 1024);
2444   d->kanji_status_return->info |= KanjiGLineInfo;
2445   d->kanji_status_return->gline.line = buf;
2446   d->kanji_status_return->gline.length = WStrlen(buf);
2447   d->kanji_status_return->gline.revPos = 0;
2448   d->kanji_status_return->gline.revLen = 0;
2449   d->kanji_status_return->length = -1;
2450   d->flags |= PLEASE_CLEAR_GLINE;
2451   d->flags &= ~PCG_RECOGNIZED;
2452   return 0;
2453 }
2454 #endif /* MEASURE_TIME */
2455 
2456 void
jrKanjiPipeError()2457 jrKanjiPipeError()
2458 {
2459   extern defaultContext, defaultBushuContext;
2460 
2461   defaultContext = -1;
2462   defaultBushuContext = -1;
2463 
2464   makeAllContextToBeClosed(0);
2465 
2466   RkwFinalize();
2467 #if defined(DEBUG)
2468   if (iroha_debug) {
2469     fprintf(stderr, "\300\334\302\263\244\254\300\332\244\354\244\277\n");
2470                     /* ��³���ڤ줿 */
2471   }
2472 #endif
2473 }
2474 
2475 /* cfuncdef
2476 
2477   TanBunsetsuMode -- ñ����⡼�ɤ���ʸ�῭�Ф��̤�⡼�ɤذܹԤ���
2478 
2479  */
2480 
2481 static TanBunsetsuMode pro((uiContext));
2482 
2483 static
TanBunsetsuMode(d)2484 TanBunsetsuMode(d)
2485 uiContext	d;
2486 {
2487   yomiContext yc = (yomiContext)d->modec;
2488 
2489   if (yc->id != YOMI_CONTEXT) {
2490     return enterTanHenkanMode(d, CANNA_FN_AdjustBunsetsu);
2491   }
2492   if (yc->right) {
2493     doTbResize(d, yc, 0);
2494     yc = (yomiContext)d->modec;
2495   }
2496   if (enterAdjustMode(d, yc) < 0) {
2497     return TanMuhenkan(d);
2498   }
2499   makeKanjiStatusReturn(d, yc);
2500   currentModeInfo(d);
2501   return 0;
2502 }
2503 
2504 static void
chikujiSetCursor(d,forw)2505 chikujiSetCursor(d, forw)
2506 uiContext d;
2507 int forw;
2508 {
2509   yomiContext yc = (yomiContext)d->modec;
2510 
2511   if (forw) { /* ���ֺ��عԤ� */
2512     if (yc->nbunsetsu) { /* ʸ�᤬���롩 */
2513       gotoBunsetsu(yc, 0);
2514       moveToChikujiTanMode(d);
2515     }
2516     else {
2517       yc->kRStartp = yc->kCurs = yc->cStartp;
2518       yc->rStartp = yc->rCurs = yc->cRStartp;
2519       moveToChikujiYomiMode(d);
2520     }
2521   }
2522   else { /* ���ֱ��عԤ� */
2523     if (yc->cStartp < yc->kEndp) { /* �ɤߤ����롩 */
2524       yc->kRStartp = yc->kCurs = yc->kEndp;
2525       yc->rStartp = yc->rCurs = yc->rEndp;
2526       moveToChikujiYomiMode(d);
2527     }
2528     else {
2529       gotoBunsetsu(yc, yc->nbunsetsu - 1);
2530       moveToChikujiTanMode(d);
2531     }
2532   }
2533 }
2534 
2535 
2536 void
setMode(d,tan,forw)2537 setMode(d, tan, forw)
2538 uiContext d;
2539 tanContext tan;
2540 int forw;
2541 {
2542   yomiContext yc = (yomiContext)tan;
2543 
2544   d->current_mode = yc->curMode;
2545   currentModeInfo(d);
2546   if (tan->id == YOMI_CONTEXT) {
2547     if (yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) {
2548       chikujiSetCursor(d, forw);
2549     }
2550     else if (yc->nbunsetsu) {
2551       if (forw) {
2552 	gotoBunsetsu(yc, 0);
2553       }
2554       else {
2555 	gotoBunsetsu(yc, yc->nbunsetsu - 1);
2556       }
2557     }
2558     else /* �ɤߥ⡼�� */ if (forw) {
2559       yc->kCurs = yc->kRStartp = yc->cStartp;
2560       yc->rCurs = yc->rStartp = yc->cRStartp;
2561     }
2562     else {
2563       yc->kCurs = yc->kRStartp = yc->kEndp;
2564       yc->rCurs = yc->rStartp = yc->rEndp;
2565     }
2566   }
2567 }
2568 
2569 int
TbForward(d)2570 TbForward(d)
2571 uiContext d;
2572 {
2573   tanContext tan = (tanContext)d->modec;
2574 
2575   if (tan->right) {
2576     d->modec = (mode_context)tan->right;
2577     tan = (tanContext)d->modec;
2578   }
2579   else if (cannaconf.CursorWrap && tan->left) {
2580     while (tan->left) {
2581       tan = tan->left;
2582     }
2583     d->modec = (mode_context)tan;
2584   }
2585   else {
2586     return NothingChanged(d);
2587   }
2588   setMode(d, tan, 1);
2589   makeKanjiStatusReturn(d, (yomiContext)d->modec);
2590   return 0;
2591 }
2592 
2593 int
TbBackward(d)2594 TbBackward(d)
2595 uiContext d;
2596 {
2597   tanContext tan = (tanContext)d->modec;
2598 
2599   if (tan->left) {
2600     d->modec = (mode_context)tan->left;
2601     tan = (tanContext)d->modec;
2602   }
2603   else if (cannaconf.CursorWrap && tan->right) {
2604     while (tan->right) {
2605       tan = tan->right;
2606     }
2607     d->modec = (mode_context)tan;
2608   }
2609   else {
2610     return NothingChanged(d);
2611   }
2612   setMode(d, tan, 0);
2613   makeKanjiStatusReturn(d, (yomiContext)d->modec);
2614   return 0;
2615 }
2616 
2617 int
TbBeginningOfLine(d)2618 TbBeginningOfLine(d)
2619 uiContext d;
2620 {
2621   tanContext tan = (tanContext)d->modec;
2622 
2623   while (tan->left) {
2624     tan = tan->left;
2625   }
2626   d->modec = (mode_context)tan;
2627   setMode(d, tan, 1);
2628   makeKanjiStatusReturn(d, (yomiContext)d->modec);
2629   return 0;
2630 }
2631 
2632 int
TbEndOfLine(d)2633 TbEndOfLine(d)
2634 uiContext d;
2635 {
2636   tanContext tan = (tanContext)d->modec;
2637 
2638   while (tan->right) {
2639     tan = tan->right;
2640   }
2641   d->modec = (mode_context)tan;
2642   setMode(d, tan, 0);
2643   makeKanjiStatusReturn(d, (yomiContext)d->modec);
2644   return 0;
2645 }
2646 
2647 static TbChooseChar pro((uiContext, int));
2648 
2649 static
TbChooseChar(d,head)2650 TbChooseChar(d, head)
2651 uiContext d;
2652 int head;
2653 {
2654   tanContext tan = (tanContext)d->modec;
2655 
2656   if (!head) {
2657     int len = WStrlen(tan->kanji);
2658     tan->kanji[0] = tan->kanji[len - 1];
2659   }
2660   tan->yomi[0] = tan->roma[0] = tan->kanji[0];
2661   tan->yomi[1] = tan->roma[1] = tan->kanji[1] = (wchar_t)0;
2662   tan->rAttr[0] = SENTOU;
2663   tan->kAttr[0] = SENTOU | HENKANSUMI;
2664   tan->rAttr[1] = tan->kAttr[1] = SENTOU;
2665 
2666   makeKanjiStatusReturn(d, (yomiContext)tan);
2667   return 0;
2668 }
2669 
2670 static int
TanChooseChar(d,head)2671 TanChooseChar(d, head)
2672 uiContext d;
2673 int head;
2674 {
2675   int retval, len;
2676   yomiContext yc = (yomiContext)d->modec;
2677 #ifndef USE_MALLOC_FOR_BIG_ARRAY
2678   wchar_t xxx[ROMEBUFSIZE];
2679 #else
2680   wchar_t *xxx;
2681 #endif
2682 
2683   if (yc->id != YOMI_CONTEXT) {
2684     return TbChooseChar(d, head);
2685   }
2686 #ifdef USE_MALLOC_FOR_BIG_ARRAY
2687   xxx = (wchar_t *)malloc(sizeof(wchar_t) * ROMEBUFSIZE);
2688   if (!xxx) {
2689     return 0;
2690   }
2691 #endif
2692   RkwGoTo(yc->context, yc->curbun);
2693   len = RkwGetKanji(yc->context, xxx, ROMEBUFSIZE);
2694   if (len >= 0) {
2695     retval = TanBubunMuhenkan(d);
2696     if (retval >= 0) {
2697       tanContext tan;
2698       yc = (yomiContext)d->modec;
2699       tan = newTanContext(yc->majorMode, CANNA_MODE_TankouhoMode);
2700       if (tan) {
2701 	copyYomiinfo2Tan(yc, tan);
2702 	tan->kanji = DUpwstr(xxx + (head ? 0 : len - 1), 1);
2703 	tan->yomi = DUpwstr(yc->kana_buffer, yc->kEndp);
2704 	tan->roma = DUpwstr(yc->romaji_buffer, yc->rEndp);
2705 	tan->kAttr = DUpattr(yc->kAttr, yc->kEndp);
2706 	tan->rAttr = DUpattr(yc->rAttr, yc->rEndp);
2707 	tan->right = yc->right;
2708 	if (tan->right) tan->right->left = tan;
2709 	yc->right = tan;
2710 	tan->left = (tanContext)yc;
2711 	removeCurrentBunsetsu(d, (tanContext)yc);
2712 	makeKanjiStatusReturn(d, (yomiContext)tan);
2713 	goto done;
2714       }
2715     }
2716   }
2717   retval = NothingChangedWithBeep(d);
2718  done:
2719 #ifdef USE_MALLOC_FOR_BIG_ARRAY
2720   (void)free((char *)xxx);
2721 #endif
2722   return retval;
2723 }
2724 
2725 static TanChooseHeadChar pro((uiContext));
2726 static TanChooseTailChar pro((uiContext));
2727 
2728 static
TanChooseHeadChar(d)2729 TanChooseHeadChar(d)
2730 uiContext d;
2731 {
2732   return TanChooseChar(d, 1);
2733 }
2734 
2735 static
TanChooseTailChar(d)2736 TanChooseTailChar(d)
2737 uiContext d;
2738 {
2739   return TanChooseChar(d, 0);
2740 }
2741 
2742 #include	"tanmap.h"
2743 
2744 #ifndef wchar_t
2745 # error "wchar_t is already undefined"
2746 #endif
2747 #undef wchar_t
2748 /*********************************************************************
2749  *                       wchar_t replace end                         *
2750  *********************************************************************/
2751