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: romaji.c,v 1.10 2003/09/17 08:50:53 aida_s Exp $";
25 #endif /* lint */
26 
27 #include "canna.h"
28 #include <ctype.h>
29 #include <errno.h>
30 #ifdef MEASURE_TIME
31 #include <sys/types.h>
32 #include <sys/times.h>
33 #endif
34 
35 /* Now canna have only cbp files. */
36 #if 1
37 #define DEFAULT_ROMKANA_TABLE "/dic/default.cbp"
38 #else
39 #define DEFAULT_ROMKANA_TABLE "/dic/default.kp"
40 #endif
41 
42 #ifdef luna88k
43 extern int errno;
44 #endif
45 
46 /*********************************************************************
47  *                      wchar_t replace begin                        *
48  *********************************************************************/
49 #ifdef wchar_t
50 # error "wchar_t is already defined"
51 #endif
52 #define wchar_t cannawc
53 
54 int forceRomajiFlushYomi pro((uiContext));
55 static int KanaYomiInsert pro((uiContext));
56 static int chikujiEndBun pro((uiContext));
57 extern void EWStrcat pro((wchar_t *, char *));
58 
59 extern int yomiInfoLevel;
60 
61 extern struct RkRxDic *englishdic;
62 
63 /*
64  * int d->rStartp;     ro shu c|h    shi f   ���޻� �������� ����ǥå���
65  * int d->rEndp;       ro shu ch     shi f|  ���޻� �Хåե� ����ǥå���
66  * int d->rCurs;       ro shu ch|    shi f   ���޻� �����   ����ǥå���
67  * int d->rAttr[1024]; 10 100 11     100 1   ���޻������Ѵ���Ƭ�ե饰�Хåե�
68  * int d->kEndp;       �� ��  ch  �� ��  f|  ����     �Хåե� ����ǥå���
69  * int d->kRStartp;    �� ��  c|h �� ��  f   �������� �������� ����ǥå���
70  * int d->kCurs;      �� ��  ch| �� ��  f   �������� �����   ����ǥå���
71  * int d->kAttr[1024]; 11 11  00  11 11  0   �����Ѵ������ե饰�Хåե�
72  * int d->nrf;                1              ���޻��Ѵ����ޤ���ե饰
73  */
74 
75 /*
76  * �ե饰��ݥ�����ư��
77  *
78  *           �Ҥ㤯           hyaku
79  *  ��       100010           10010
80  *  ��       111111
81  *  ��       000000
82  * rStartp                         1
83  * rCurs                           1
84  * rEndp                           1
85  * kRstartp        1
86  * kCurs           1
87  * kEndp           1
88  *
89  * ��
90  *           �Ҥ㤯           hyaku
91  *  ��       100010           10010
92  *  ��       111111
93  *  ��       000000
94  * rStartp                       1
95  * rCurs                         1
96  * rEndp                           1
97  * kRstartp      1
98  * kCurs         1
99  * kEndp           1
100  *
101  * ��
102  *           �Ҥ㤯           hyaku
103  *  ��       100010           10010
104  *  ��       111111
105  *  ��       000000
106  * rStartp                       1
107  * rCurs                         1
108  * rEndp                           1
109  * kRstartp    1
110  * kCurs       1
111  * kEndp           1
112  *
113  * ��
114  *           �Ҥ㤯           hyaku
115  *  ��       100010           10010
116  *  ��       111111
117  *  ��       000000
118  * rStartp                    1
119  * rCurs                      1
120  * rEndp                           1
121  * kRstartp  1
122  * kCurs     1
123  * kEndp           1
124  *
125  * ��
126  *           �Ҥ㤯           hyaku
127  *  ��       100010           10010
128  *  ��       111111
129  *  ��       000000
130  * rStartp                       1
131  * rCurs                         1
132  * rEndp                           1
133  * kRstartp    1
134  * kCurs       1
135  * kEndp           1
136  *
137  * 'k'
138  *           ��k�㤯           hyakku
139  *  ��       1010010           100110
140  *  ��       1101111
141  *  ��       0010000
142  * rStartp                        1
143  * rCurs                           1
144  * rEndp                             1
145  * kRstartp    1
146  * kCurs        1
147  * kEndp            1
148  *
149  * 'i'
150  *           �Ҥ��㤯           hyakiku
151  *  ��       10100010           1001010
152  *  ��       11111111
153  *  ��       00110000
154  * rStartp                           1
155  * rCurs                             1
156  * rEndp                               1
157  * kRstartp      1
158  * kCurs         1
159  * kEndp             1
160  */
161 
162 #ifndef KANALIMIT
163 #define KANALIMIT 255
164 #endif
165 #define ROMAJILIMIT 255
166 
167 #define  doubleByteP(x) ((x) & 0x80)
168 
169 #ifdef DEBUG
debug_yomi(x)170 void debug_yomi(x)
171 yomiContext x;
172 {
173   char foo[1024];
174   int len, i;
175 
176   if (iroha_debug) {
177     len = WCstombs(foo, x->romaji_buffer, 1024);
178     foo[len] = '\0';
179     printf("    %s\n��: ", foo);
180     for (i = 0 ; i <= x->rEndp ; i++) {
181       printf("%s", (x->rAttr[i] & SENTOU) ? "1" : " ");
182     }
183     printf("\n��: ");
184     for (i = 0 ; i < x->rStartp ; i++) {
185       printf(" ");
186     }
187     printf("^\n");
188 
189     len = WCstombs(foo, x->kana_buffer, 1024);
190     foo[len] = '\0';
191     printf("    %s\n��: ", foo);
192     for (i = 0 ; i <= x->kEndp ; i++) {
193       printf("%s ", (x->kAttr[i] & SENTOU) ? "1" : " ");
194     }
195     printf("\n��: ");
196     for (i = 0 ; i <= x->kEndp ; i++) {
197       printf("%s", (x->kAttr[i] & HENKANSUMI) ? "��" : "̤");
198     }
199     printf("\n��: ");
200     for (i = 0 ; i < x->kRStartp ; i++) {
201       printf("  ");
202     }
203     printf("��\n");
204 
205   }
206 }
207 #else /* !DEBUG */
208 # define debug_yomi(x)
209 #endif /* !DEBUG */
210 
211 #ifndef CALLBACK
212 #define kanaReplace(where, insert, insertlen, mask) \
213 kanaRepl(d, where, insert, insertlen, mask)
214 
215 static void
kanaRepl(d,where,insert,insertlen,mask)216 kanaRepl(d, where, insert, insertlen, mask)
217 uiContext d;
218 int where, insertlen, mask;
219 wchar_t *insert;
220 {
221   yomiContext yc = (yomiContext)d->modec;
222 
223   generalReplace(yc->kana_buffer, yc->kAttr, &yc->kRStartp,
224 		 &yc->kCurs, &yc->kEndp,
225 		 where, insert, insertlen, mask);
226 }
227 #else /* CALLBACK */
228 #define kanaReplace(where, insert, insertlen, mask) \
229 kanaRepl(d, where, insert, insertlen, mask)
230 
231 static void
kanaRepl(d,where,insert,insertlen,mask)232 kanaRepl(d, where, insert, insertlen, mask)
233 uiContext d;
234 int where, insertlen, mask;
235 wchar_t *insert;
236 {
237   yomiContext yc = (yomiContext)d->modec;
238 #ifndef USE_MALLOC_FOR_BIG_ARRAY
239   wchar_t buf[256];
240 #else
241   wchar_t *buf = (wchar_t *)malloc(sizeof(wchar_t) * 256);
242   if (!buf) {
243     return;
244   }
245 #endif
246 
247   WStrncpy(buf, insert, insertlen);
248   buf[insertlen] = '\0';
249 
250   generalReplace(yc->kana_buffer, yc->kAttr, &yc->kRStartp,
251 		 &yc->kCurs, &yc->kEndp,
252 		 where, insert, insertlen, mask);
253 #ifdef USE_MALLOC_FOR_BIG_ARRAY
254   (void)free((char *)buf);
255 #endif
256 }
257 #endif /* CALLBACK */
258 
259 #define  romajiReplace(where, insert, insertlen, mask) \
260 romajiRepl(d, where, insert, insertlen, mask)
261 
262 static void
romajiRepl(d,where,insert,insertlen,mask)263 romajiRepl(d, where, insert, insertlen, mask)
264 uiContext d;
265 int where, insertlen, mask;
266 wchar_t *insert;
267 {
268   yomiContext yc = (yomiContext)d->modec;
269 
270   generalReplace(yc->romaji_buffer, yc->rAttr,
271 		 &yc->rStartp, &yc->rCurs, &yc->rEndp,
272 		 where, insert, insertlen, mask);
273 }
274 
275 /* cfuncdef
276 
277    kPos2rPos -- ���ʥХåե��Υ꡼���������޻��Хåե��Υ꡼����������
278 
279    yc : �ɤߥ���ƥ�����
280    s  : ���ʥХåե��Υ꡼�����γ��ϰ���
281    e  : ���ʥХåե��Υ꡼�����ν�λ����
282    rs : ���޻��Хåե����б����볫�ϰ��֤��Ǽ�����ѿ��ؤΥݥ���
283    rs : ���޻��Хåե����б����뽪λ���֤��Ǽ�����ѿ��ؤΥݥ���
284  */
285 
286 void
kPos2rPos(yc,s,e,rs,re)287 kPos2rPos(yc, s, e, rs, re)
288 yomiContext yc;
289 int s, e, *rs, *re;
290 {
291   int i, j, k;
292 
293   for (i = 0, j = 0 ; i < s ; i++) {
294     if (yc->kAttr[i] & SENTOU) {
295       do {
296 	j++;
297       } while (!(yc->rAttr[j] & SENTOU));
298     }
299   }
300   for (i = s, k = j ; i < e ; i++) {
301     if (yc->kAttr[i] & SENTOU) {
302       do {
303 	k++;
304       } while (!(yc->rAttr[k] & SENTOU));
305     }
306   }
307   if (rs) *rs = j;
308   if (re) *re = k;
309 }
310 
311 /*
312   makeYomiReturnStruct-- �ɤߤ��ץꥱ���������֤����ι�¤�Τ���ؿ�
313 
314   makeYomiReturnStruct �� kana_buffer ��Ĵ�٤�Ŭ�����ͤ��Ȥ�Ω�Ƥ롣��
315   �λ��˥�С������ΰ�����ꤹ�뤬����С�����ɤΤ��餤���뤫�ϡ�
316   ReverseWidely �Ȥ����ѿ����Ʒ��ꤹ�롣
317 
318   */
319 
320 void
makeYomiReturnStruct(d)321 makeYomiReturnStruct(d)
322 uiContext d;
323 {
324   yomiContext yc = (yomiContext)d->modec;
325 
326   makeKanjiStatusReturn(d, yc);
327 }
328 
329 extern ckverbose;
330 
331 static struct RkRxDic *
OpenRoma(table)332 OpenRoma(table)
333 char *table;
334 {
335   struct RkRxDic *retval = (struct RkRxDic *)0, *RkwOpenRoma();
336   char *p, *getenv();
337 #ifndef USE_MALLOC_FOR_BIG_ARRAY
338   char rdic[1024];
339 #else
340   char *rdic = malloc(1024);
341   if (!rdic) {
342     return (struct RkRxDic *)0;
343   }
344 #endif
345 
346   if (table || *table) {
347     retval = RkwOpenRoma(table);
348 
349     if (ckverbose == CANNA_FULL_VERBOSE) {
350       if (retval != (struct RkRxDic *)NULL) { /* ���������ץ�Ǥ��� */
351         printf("���޻������Ѵ��ơ��֥�� \"%s\" ���Ѥ��ޤ���\n", table);
352       }
353     }
354 
355     if (retval == (struct RkRxDic *)NULL) {
356       /* �⤷���������ץ�Ǥ��ʤ���Х��顼 */
357       extern jrUserInfoStruct *uinfo;
358 
359       rdic[0] = '\0';
360       if (uinfo && uinfo->topdir && uinfo->uname) {
361 	strcpy(rdic, uinfo->topdir);
362 	strcat(rdic, "/dic/user/");
363 	strcat(rdic, uinfo->uname);
364 	strcat(rdic, "/");
365 	strcat(rdic, table);
366 	retval = RkwOpenRoma(rdic);
367       }
368       else {
369         p = getenv("HOME");
370         if (p) {
371           (void)strcpy(rdic, p);
372           (void)strcat(rdic, "/");
373           (void)strcat(rdic, table);
374           retval = RkwOpenRoma(rdic);
375         }
376       }
377 
378       if (ckverbose == CANNA_FULL_VERBOSE) {
379 	if (retval != (struct RkRxDic *)NULL) {
380           printf("���޻������Ѵ��ơ��֥�� \"%s\" ���Ѥ��ޤ���\n", rdic);
381 	}
382       }
383 
384       if (retval == (struct RkRxDic *)NULL) { /* ����⥪���ץ�Ǥ��ʤ� */
385         extern jrUserInfoStruct *uinfo;
386 
387         rdic[0] = '\0';
388         if (uinfo && uinfo->topdir) {
389 	  strcpy(rdic, uinfo->topdir);
390         }
391         else {
392           strcpy(rdic, CANNALIBDIR);
393         }
394 	strcat(rdic, "/dic/");
395 	strcat(rdic, table);
396 	retval = RkwOpenRoma(rdic);
397 
398 	if (ckverbose) {
399 	  if (retval != (struct RkRxDic *)NULL) {
400 	    if (ckverbose == CANNA_FULL_VERBOSE) {
401               printf("���޻������Ѵ��ơ��֥�� \"%s\" ���Ѥ��ޤ���\n", rdic);
402 	    }
403 	  }
404 	}
405       }
406 
407       if (retval == (struct RkRxDic *)NULL) { /* added for Debian by ISHIKAWA Mutsumi <ishikawa@linux.or.jp> */
408         extern jrUserInfoStruct *uinfo;
409 
410         rdic[0] = '\0';
411         if (uinfo && uinfo->topdir) {
412 	  strcpy(rdic, uinfo->topdir);
413         }
414         else {
415           strcpy(rdic, CANNALIBDIR);
416         }
417 	strcat(rdic, "/");
418 	strcat(rdic, table);
419 	retval = RkwOpenRoma(rdic);
420 
421 	if (ckverbose) {
422 	  if (retval != (struct RkRxDic *)NULL) {
423 	    if (ckverbose == CANNA_FULL_VERBOSE) {
424               printf("���޻������Ѵ��ơ��֥�� \"%s\" ���Ѥ��ޤ���\n", rdic);
425 	    }
426 	  }
427 	}
428       }
429 
430 #if 0 /* currently CANNASHAREDDIR is not defined */
431       if (retval == (struct RkRxDic *)NULL) { /* added for Debian by ISHIKAWA Mutsumi <ishikawa@linux.or.jp> */
432         extern jrUserInfoStruct *uinfo;
433 
434         rdic[0] = '\0';
435         if (uinfo && uinfo->topdir) {
436 	  strcpy(rdic, uinfo->topdir);
437         }
438         else {
439           strcpy(rdic, CANNASHAREDIR);
440         }
441 	strcat(rdic, "/");
442 	strcat(rdic, table);
443 	retval = RkwOpenRoma(rdic);
444 
445 	if (ckverbose) {
446 	  if (retval != (struct RkRxDic *)NULL) {
447 	    if (ckverbose == CANNA_FULL_VERBOSE) {
448               printf("���޻������Ѵ��ơ��֥�� \"%s\" ���Ѥ��ޤ���\n", rdic);
449 	    }
450 	  }
451 	}
452       }
453 #endif
454 
455       if (retval == (struct RkRxDic *)NULL) { /* ���������ץ�Ǥ��ʤ� */
456 	sprintf(rdic,
457 #ifndef CODED_MESSAGE
458 		"���޻������Ѵ��ơ��֥�(%s)�������ץ�Ǥ��ޤ���",
459 #else
460 		"\245\355\241\274\245\336\273\372\244\253\244\312"
461 		"\312\321\264\271\245\306\241\274\245\326\245\353\50\45\163\51\244\254"
462 		"\245\252\241\274\245\327\245\363\244\307\244\255\244\336\244\273"
463 		"\244\363\241\243",
464 #endif
465 		table);
466 	/* ���޻������Ѵ��ơ��֥�(%s)�������ץ�Ǥ��ޤ��� */
467 	addWarningMesg(rdic);
468 	retval = (struct RkRxDic *)0;
469       }
470     }
471   }
472 #ifdef USE_MALLOC_FOR_BIG_ARRAY
473   (void)free((char *)rdic);
474 #endif
475   return retval;
476 }
477 
RomkanaInit()478 RomkanaInit()
479 {
480   extern char *RomkanaTable, *EnglishTable;
481   extern extraFunc *extrafuncp;
482   extraFunc *extrafunc1, *extrafunc2;
483   extern jrUserInfoStruct *uinfo;
484 
485   /* ���޻������Ѵ��ơ��֥�Υ����ץ� */
486   if (uinfo) {
487     if (uinfo->romkanatable) {
488       if (RomkanaTable) {
489         free(RomkanaTable);
490       }
491       RomkanaTable = malloc(strlen(uinfo->romkanatable) + 1);
492       if (RomkanaTable) {
493         strcpy(RomkanaTable, uinfo->romkanatable);
494       }
495     }
496   }
497   if (RomkanaTable) {
498     romajidic = OpenRoma(RomkanaTable);
499   }
500   else {
501 #ifndef USE_MALLOC_FOR_BIG_ARRAY
502     char buf[1024];
503 #else
504     char *buf = malloc(1024);
505     if (!buf) {
506       return 0;
507     }
508 #endif
509 
510     buf[0] = '\0';
511     if (uinfo && uinfo->topdir) {
512       strcpy(buf, uinfo->topdir);
513     }
514     else {
515       strcpy(buf, CANNALIBDIR);
516     }
517     strcat(buf, DEFAULT_ROMKANA_TABLE);
518     romajidic = RkwOpenRoma(buf);
519 
520     if (romajidic != (struct RkRxDic *)NULL) {
521       int len = strlen(buf);
522       RomkanaTable = malloc(len + 1);
523       if (RomkanaTable) {
524 	strcpy(RomkanaTable, buf);
525       }
526       if (ckverbose == CANNA_FULL_VERBOSE) {
527         printf("���޻������Ѵ��ơ��֥�� \"%s\" ���Ѥ��ޤ���\n", buf);
528       }
529     }
530     else { /* �����ץ�Ǥ��ʤ��ä� */
531       if (ckverbose) {
532         printf("���޻������Ѵ��ơ��֥� \"%s\" �������ץ�Ǥ��ޤ���\n",
533                buf);
534       }
535       sprintf(buf, "\245\267\245\271\245\306\245\340\244\316\245\355\241\274"
536 	"\245\336\273\372\244\253\244\312\312\321\264\271\245\306\241\274"
537 	"\245\326\245\353\244\254\245\252\241\274\245\327\245\363\244\307"
538 	"\244\255\244\336\244\273\244\363\241\243");
539          /* �����ƥ�Υ��޻������Ѵ��ơ��֥뤬�����ץ�Ǥ��ޤ��� */
540       addWarningMesg(buf);
541     }
542 #ifdef USE_MALLOC_FOR_BIG_ARRAY
543     (void)free(buf);
544 #endif
545   }
546 
547 #ifndef NOT_ENGLISH_TABLE
548   if (EnglishTable && (!RomkanaTable || strcmp(RomkanaTable, EnglishTable))) {
549     /* RomkanaTable �� EnglishTable �������ä������ */
550     englishdic = OpenRoma(EnglishTable);
551   }
552 #endif
553 
554   /* �桼���⡼�ɤν���� */
555   for (extrafunc1 = extrafuncp ; extrafunc1 ; extrafunc1 = extrafunc1->next) {
556     /* ���޻������Ѵ��ơ��֥�Υ����ץ� */
557     if (extrafunc1->keyword == EXTRA_FUNC_DEFMODE) {
558       if (extrafunc1->u.modeptr->romaji_table) {
559         if (RomkanaTable &&
560             !strcmp(RomkanaTable,
561 		    (char *)extrafunc1->u.modeptr->romaji_table)) {
562 	  extrafunc1->u.modeptr->romdic = romajidic;
563 	  extrafunc1->u.modeptr->romdic_owner = 0;
564         }
565 #ifndef NOT_ENGLISH_TABLE
566         else if (EnglishTable &&
567 	         !strcmp(EnglishTable,
568 			 (char *)extrafunc1->u.modeptr->romaji_table)) {
569 	  extrafunc1->u.modeptr->romdic = englishdic;
570 	  extrafunc1->u.modeptr->romdic_owner = 0;
571         }
572 #endif
573         else {
574 	  for (extrafunc2 = extrafuncp ; extrafunc1 != extrafunc2 ;
575 					extrafunc2 = extrafunc2->next) {
576 	    if (extrafunc2->keyword == EXTRA_FUNC_DEFMODE &&
577 		extrafunc2->u.modeptr->romaji_table) {
578 	      if (!strcmp((char *)extrafunc1->u.modeptr->romaji_table,
579 			  (char *)extrafunc2->u.modeptr->romaji_table)) {
580 	        extrafunc1->u.modeptr->romdic = extrafunc2->u.modeptr->romdic;
581 	        extrafunc1->u.modeptr->romdic_owner = 0;
582 	        break;
583 	      }
584 	    }
585 	  }
586 	  if (extrafunc2 == extrafunc1) {
587 	    extrafunc1->u.modeptr->romdic =
588               OpenRoma(extrafunc1->u.modeptr->romaji_table);
589 	    extrafunc1->u.modeptr->romdic_owner = 1;
590 	  }
591         }
592       }
593       else {
594         extrafunc1->u.modeptr->romdic = (struct RkRxDic *)0; /* nil�Ǥ��衪 */
595         extrafunc1->u.modeptr->romdic_owner = 0;
596       }
597     }
598   }
599 
600   return 0;
601 }
602 
603 /* ���޻������Ѵ��ơ��֥�Υ����� */
604 
605 extern keySupplement keysup[];
606 extern exp(void) RkwCloseRoma pro((struct RkRxDic *));
607 
608 void
RomkanaFin()609 RomkanaFin()
610 {
611   extern char *RomkanaTable, *EnglishTable;
612   extern nkeysup;
613   int i;
614 
615   /* ���޻������Ѵ��ơ��֥�Υ����� */
616   if (romajidic != (struct RkRxDic *)NULL) {
617     RkwCloseRoma(romajidic);
618   }
619   if (RomkanaTable) {
620     free(RomkanaTable);
621     RomkanaTable = (char *)NULL;
622   }
623 #ifndef NOT_ENGLISH_TABLE
624   if (englishdic != (struct RkRxDic *)NULL) {
625     RkwCloseRoma(englishdic);
626   }
627   if (EnglishTable) {
628     free(EnglishTable);
629     EnglishTable = (char *)NULL;
630   }
631 #endif
632   /* ���޻������Ѵ��롼�����­�Τ�����ΰ�β��� */
633   for (i = 0 ; i < nkeysup ; i++) {
634     if (keysup[i].cand) {
635       free((char *)keysup[i].cand);
636       keysup[i].cand = (wchar_t **)NULL;
637     }
638     if (keysup[i].fullword) {
639       free((char *)keysup[i].fullword);
640       keysup[i].fullword = (wchar_t *)NULL;
641     }
642   }
643   nkeysup = 0;
644 }
645 
646 /* cfunc newYomiContext
647 
648   yomiContext ��¤�Τ��ĺ���֤���
649 
650  */
651 
652 yomiContext
newYomiContext(buf,bufsize,allowedc,chmodinhibit,quitTiming,hinhibit)653 newYomiContext(buf, bufsize, allowedc, chmodinhibit,
654 	       quitTiming, hinhibit)
655      wchar_t *buf;
656      int bufsize;
657      int allowedc, chmodinhibit, quitTiming, hinhibit;
658 {
659   yomiContext ycxt;
660 
661   ycxt = (yomiContext)malloc(sizeof(yomiContextRec));
662   if (ycxt) {
663     bzero(ycxt, sizeof(yomiContextRec));
664     ycxt->id = YOMI_CONTEXT;
665     ycxt->allowedChars = allowedc;
666     ycxt->generalFlags = chmodinhibit ? CANNA_YOMI_CHGMODE_INHIBITTED : 0;
667     ycxt->generalFlags |= quitTiming ? CANNA_YOMI_END_IF_KAKUTEI : 0;
668     ycxt->savedFlags = (long)0;
669     ycxt->henkanInhibition = hinhibit;
670     ycxt->n_susp_chars = 0;
671     ycxt->retbufp = ycxt->retbuf = buf;
672     ycxt->romdic = (struct RkRxDic *)0;
673     ycxt->myEmptyMode = (KanjiMode)0;
674     ycxt->last_rule = 0;
675     if ((ycxt->retbufsize = bufsize) == 0) {
676       ycxt->retbufp = 0;
677     }
678     ycxt->right = ycxt->left = (tanContext)0;
679     ycxt->next = (mode_context)0;
680     ycxt->prevMode = 0;
681 
682     /* �Ѵ���ʬ */
683     ycxt->nbunsetsu = 0;  /* ʸ��ο���������ɤߥ⡼�ɤ��ɤ�����Ƚ��⤹�� */
684     ycxt->context = -1;
685     ycxt->kouhoCount = 0;
686     ycxt->allkouho = (wchar_t **)0;
687     ycxt->curbun = 0;
688     ycxt->curIkouho = 0;  /* �����ȸ��� */
689     ycxt->proctime = ycxt->rktime = 0;
690 
691     /* �༡��ʬ */
692     ycxt->ys = ycxt->ye = ycxt->cStartp = ycxt->cRStartp = ycxt->status = 0;
693   }
694   return ycxt;
695 }
696 
697 /*
698 
699   GetKanjiString �ϴ������ʺ�����ʸ���äƤ���ؿ��Ǥ��롣�ºݤˤ�
700   empty �⡼�ɤ����ꤹ������ǥ꥿�����롣�ǽ�Ū�ʷ�̤� buf �ǻ���
701   ���줿�Хåե��˳�Ǽ���� exitCallback ���ƤӽФ���뤳�Ȥˤ�äƸƤ�
702   �Ф�¦�ϴ������ʺ�����ʸ�������뤳�Ȥ��Ǥ��롣
703 
704   �裲������ ycxt ���̾�ϣ�����ꤹ�롣����ե��٥åȥ⡼�ɤ������ܸ�
705   �⡼�ɤؤ��ڤ��ؤ��˺ݤ��ƤΤߤ� uiContext �������¸���Ƥ��륳���
706   �����Ȥ��Ѥ��롣����ե��٥åȥ⡼�ɤ����ܸ�⡼�ɤȤ��ڤ��ؤ��ϥ�����
707   ������Ѥ߹��ޤ줿�⡼�ɤ� push/pop ���ǤϤʤ�������å׾�Υ⡼��
708   �ΰ��־�����Ǥ������ؤ��ˤʤ롣
709 
710   ���Ĥ� Callback �Τ�����exitCallback �ϤҤ�äȤ�����Ȥ��ʤ��ǡ�
711   everyTimeCallback �� quitCallback �����Ѥ��ʤ������Τ�ʤ���
712 
713  */
714 
715 yomiContext
GetKanjiString(d,buf,bufsize,allowedc,chmodinhibit,quitTiming,hinhibit,everyTimeCallback,exitCallback,quitCallback)716 GetKanjiString(d, buf, bufsize, allowedc, chmodinhibit,
717 	       quitTiming, hinhibit,
718 	       everyTimeCallback, exitCallback, quitCallback)
719      uiContext d;
720      wchar_t *buf;
721      int bufsize, allowedc, chmodinhibit, quitTiming, hinhibit;
722      canna_callback_t everyTimeCallback, exitCallback, quitCallback;
723 {
724   extern KanjiModeRec empty_mode;
725   yomiContext yc;
726 
727   if ((pushCallback(d, d->modec, everyTimeCallback, exitCallback, quitCallback,
728 		    NO_CALLBACK)) == (struct callback *)0) {
729     return (yomiContext)0;
730   }
731 
732   yc = newYomiContext(buf, bufsize, allowedc, chmodinhibit,
733 		      quitTiming, hinhibit);
734   if (yc == (yomiContext)0) {
735     popCallback(d);
736     return (yomiContext)0;
737   }
738   yc->romdic = romajidic;
739   yc->majorMode = d->majorMode;
740   yc->minorMode = CANNA_MODE_HenkanMode;
741   yc->next = d->modec;
742   d->modec = (mode_context)yc;
743   /* ���Υ⡼�ɤ���¸ */
744   yc->prevMode = d->current_mode;
745   /* �⡼���ѹ� */
746   d->current_mode = yc->curMode = yc->myEmptyMode = &empty_mode;
747   return yc;
748 }
749 
750 /* cfuncdef
751 
752    popYomiMode -- �ɤߥ⡼�ɤ�ݥåץ��åפ��롣
753 
754  */
755 
756 void
popYomiMode(d)757 popYomiMode(d)
758 uiContext d;
759 {
760   yomiContext yc = (yomiContext)d->modec;
761 
762   d->modec = yc->next;
763   d->current_mode = yc->prevMode;
764 
765   if (yc->context >= 0) {
766     RkwCloseContext(yc->context);
767     yc->context = -1;
768   }
769 
770   freeYomiContext(yc);
771 }
772 
773 /* cfuncdef
774 
775   checkIfYomiExit -- �ɤߥ⡼�ɤ���λ���ɤ�����Ĵ�٤��ͤ��֤��ե��륿
776 
777   ���Υե��륿���ɤߥ⡼�ɤγƴؿ����ͤ��֤����Ȥ�����˸Ƥ֡��ɤߥ⡼
778   �ɤǤν�������λ����Ȥ���Ǥ���С��ɤߥ⡼�ɤ�λ����uiContext ��
779   �ץå��夵��Ƥ���������ǡ�����⡼�ɹ�¤�Τ��ݥåפ���롣
780 
781   ������ǡ����� exitCallback ���������Ƥ��ʤ���Ф����ʤ���ˤ�
782   ��¤�ΤΥݥåץ��åפϹԤ��ʤ���
783 
784   ���ΤȤ����ɤߥ⡼�ɤν�λ�ϼ��Τ褦�ʾ�礬�ͤ����롣
785 
786   (1) C-m �������ɤߤκǸ��ʸ���Ȥ����֤��줿����(�Ѵ����Ĥλ�)
787 
788   (2) ����ʸ����¸�ߤ����硣(�Ѵ��ػߤλ�)
789 
790   quit ���ɤߥ⡼�ɤ�λ�������?¾�δؿ�?��Ƥ֡�
791 
792  */
793 
794 static
checkIfYomiExit(d,retval)795 checkIfYomiExit(d, retval)
796 uiContext d;
797 int retval;
798 {
799   yomiContext yc = (yomiContext)d->modec;
800 
801   if (retval <= 0) {
802     /* ����ʸ�����ʤ������顼�ξ�� �� exit �ǤϤʤ� */
803     return retval;
804   }
805   if (yc->retbufp && yc->retbufsize - (yc->retbufp - yc->retbuf) > retval) {
806     /* ʸ�����Ǽ�Хåե������äơ����ꤷ��ʸ������⤢�ޤäƤ�����
807        �褬Ĺ���ΤǤ���г�Ǽ�Хåե��˳��ꤷ��ʸ������ԡ����� */
808     WStrncpy(yc->retbufp, d->buffer_return, retval);
809     yc->retbufp[retval] = (wchar_t)0;
810     yc->retbufp += retval;
811   }
812   if (yc->generalFlags & CANNA_YOMI_END_IF_KAKUTEI
813       || d->buffer_return[retval - 1] == '\n') {
814     /* �Ѵ����ػߤ���Ƥ���Ȥ����� exit */
815     /* �����Ǥʤ����ϡ�\n �����äƤ����� exit */
816     d->status = EXIT_CALLBACK;
817     if (!(d->cb && d->cb->func[EXIT_CALLBACK] == NO_CALLBACK)) {
818       d->status = EXIT_CALLBACK;
819       popYomiMode(d);
820     }
821   }
822   return retval;
823 }
824 
825 static
checkIfYomiQuit(d,retval)826 checkIfYomiQuit(d, retval)
827 uiContext d;
828 int retval;
829 /* ARGSUSED */
830 {
831 #ifdef QUIT_IN_YOMI /* �����ȥ����Ȥ�����Ū�� ifdef */
832   yomiContext yc = (yomiContext)d->modec;
833 
834   if (d->cb && d->cb->func[QUIT_CALLBACK] == NO_CALLBACK) {
835     /* ������Хå����ʤ����
836 
837        ����ʥ����å�����ڤ˹Ԥ��Τϡ��ɤߥ⡼�ɤ����˴���Ū�ʥ⡼��
838        �Ǥ��ꡢ������ȴ����Ȥ��ˤ虜�虜�ݥåץ��åפ��Ƥ⤹���˥ץå���
839        �����礬¿���ȹͤ����ƽ�����̵�̤�����Ǥ��롣
840 
841      */
842   }
843   else {
844     d->status = QUIT_CALLBACK;
845     popYomiMode(d);
846   }
847 #endif /* QUIT_IN_YOMI */
848   return retval;
849 }
850 
851 #ifdef __STDC__
852 void fitmarks(yomiContext);
853 #endif
854 
855 void
fitmarks(yc)856 fitmarks(yc)
857 yomiContext yc;
858 {
859   if (yc->kRStartp < yc->pmark) {
860     yc->pmark = yc->kRStartp;
861   }
862   if (yc->kRStartp < yc->cmark) {
863     yc->cmark = yc->kRStartp;
864   }
865 }
866 
867 /* ľ����̤�Ѵ�ʸ�����ʤ����ɤ�����ǧ */
868 void
ReCheckStartp(yc)869 ReCheckStartp(yc)
870 yomiContext yc;
871 {
872   int r = yc->rStartp, k = yc->kRStartp, i;
873 
874   do {
875     yc->kRStartp--;
876     yc->rStartp--;
877   } while ( yc->kRStartp >= 0
878 	   && !(yc->kAttr[yc->kRStartp] & HENKANSUMI)
879 	   );
880   yc->kRStartp++;
881   yc->rStartp++;
882 
883   /* ̤�Ѵ�������Ƭ�ޡ������դ��Ƥ���������Ƭ�ޡ�����Ϥ�����
884 
885      ̤�Ѵ�������Ƭ�˴ؤ��Ƥ���Ƭ�ޡ������դ��Ƥ�����
886      ̤�Ѵ��������ä����(kRStartp < k)�����줬��kCurs ����
887      ��¦�Ǥ������Ƭ�ե饰����Ȥ��� */
888 
889   if (yc->kRStartp < k && k < yc->kCurs) {
890     yc->kAttr[k] &= ~SENTOU;
891     yc->rAttr[r] &= ~SENTOU;
892   }
893   for (i = yc->kRStartp + 1 ; i < k ; i++) {
894     yc->kAttr[i] &= ~SENTOU;
895   }
896   for (i = yc->rStartp + 1 ; i < r ; i++) {
897     yc->rAttr[i] &= ~SENTOU;
898   }
899 }
900 
901 extern void setMode pro((uiContext d, tanContext tan, int forw));
902 
903 void
removeCurrentBunsetsu(d,tan)904 removeCurrentBunsetsu(d, tan)
905 uiContext d;
906 tanContext tan;
907 {
908   if (tan->left) {
909     tan->left->right = tan->right;
910     d->modec = (mode_context)tan->left;
911     d->current_mode = tan->left->curMode;
912     setMode(d, tan->left, 0);
913   }
914   if (tan->right) {
915     tan->right->left = tan->left;
916     d->modec = (mode_context)tan->right;
917     d->current_mode = tan->right->curMode;
918     setMode(d, tan->right, 1);
919   }
920   switch (tan->id) {
921   case YOMI_CONTEXT:
922     freeYomiContext((yomiContext)tan);
923     break;
924   case TAN_CONTEXT:
925     freeTanContext(tan);
926     break;
927   }
928 }
929 
930 /* tabledef
931 
932  charKind -- ����饯���μ���Υơ��֥�
933 
934  0x20 ���� 0x7f �ޤǤΥ���饯���μ����ɽ���ơ��֥�Ǥ��롣
935 
936  3: ����
937  2: �����ʿ��Ȥ����Ѥ�����ѻ�
938  1: ����ʳ��αѻ�
939  0: ����¾
940 
941  �Ȥʤ롣
942 
943  */
944 
945 static BYTE charKind[] = {
946 /*sp !  "  #  $  %  &  '  (  )  *  +  ,  -  .  / */
947   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
948 /*0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ? */
949   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1,
950 /*@  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O */
951   1, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
952 /*P  Q  R  S  T  U  V  W  X  Y  X  [  \  ]  ^  _ */
953   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
954 /*`  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o */
955   1, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
956 /*p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~  DEL */
957   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
958 };
959 
960 /*
961   YomiInsert -- ���޻���ʸ����������ؿ�
962 
963   */
964 
965 static makePhonoOnBuffer();
966 
967 void
restoreChikujiIfBaseChikuji(yc)968 restoreChikujiIfBaseChikuji(yc)
969 yomiContext yc;
970 {
971   if (!chikujip(yc) && (yc->generalFlags & CANNA_YOMI_BASE_CHIKUJI)) {
972     yc->generalFlags &= ~CANNA_YOMI_BASE_CHIKUJI;
973     yc->generalFlags |= CANNA_YOMI_CHIKUJI_MODE;
974     yc->minorMode = getBaseMode(yc);
975   }
976 }
977 
978 int YomiInsert pro((uiContext));
979 
YomiInsert(d)980 YomiInsert(d)
981 uiContext d;
982 {
983   yomiContext yc = (yomiContext)d->modec;
984   int subst, autoconvert = (yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE);
985   int kugiri = 0;
986 #ifdef USE_ROMKANATABLE_FOR_KANAKEY
987   wchar_t key = 0;
988 #endif
989 
990   d->nbytes = 0;
991   if (autoconvert) {
992     if (yc->status & CHIKUJI_ON_BUNSETSU) {
993       yc->status &= ~CHIKUJI_OVERWRAP;
994       if (yc->kCurs != yc->kEndp) {
995 	yc->rStartp = yc->rCurs = yc->rEndp;
996 	yc->kRStartp = yc->kCurs = yc->kEndp;
997       }
998     }
999     else {
1000       if (yc->rEndp == yc->rCurs) {
1001 	yc->status &= ~CHIKUJI_OVERWRAP;
1002       }
1003       if (yc->kCurs < yc->ys) {
1004 	yc->ys = yc->kCurs;
1005       }
1006     }
1007   }
1008 
1009   if (yc->allowedChars == CANNA_NOTHING_ALLOWED)/* �ɤΥ�������դ��ʤ� */
1010     return NothingChangedWithBeep(d);
1011   if  (yc->rEndp >= ROMAJILIMIT
1012        || yc->kEndp >= KANALIMIT
1013        /* �¤��׻����Ƥ���
1014        || (chc && yc->rEndp + chc->hc->ycx->rEndp > ROMAJILIMIT)*/) {
1015     return NothingChangedWithBeep(d);
1016   }
1017 
1018   fitmarks(yc);
1019 
1020   if (0xa0 < d->ch && d->ch < 0xe0) {
1021 #ifdef USE_ROMKANATABLE_FOR_KANAKEY
1022     key = d->buffer_return[0];
1023 #else
1024     if (yc->allowedChars == CANNA_NOTHING_RESTRICTED) {
1025       return KanaYomiInsert(d); /* callback �Υ����å��� KanaYomiInsert ��! */
1026     }
1027     else {
1028       return NothingChangedWithBeep(d);
1029     }
1030 #endif
1031   }
1032 
1033   /*   (d->ch & ~0x1f) == 0x1f < (unsigned char)d->ch */
1034   if (!(d->ch & ~0x1f) && yc->allowedChars != CANNA_NOTHING_RESTRICTED
1035       || (d->ch < 0x80 ? charKind[d->ch - 0x20] : 1) < yc->allowedChars) {
1036     /* ���ιԡ�USE_ROMKANATABLE_FOR_KANAKEY �ΤȤ��ˤޤ��� */
1037     /* 0x20 �ϥ���ȥ��륭��饯����ʬ */
1038     return NothingChangedWithBeep(d);
1039   }
1040 
1041   if (yc->allowedChars != CANNA_NOTHING_RESTRICTED) {
1042     /* allowed all �ʳ��Ǥϥ��޻������Ѵ���Ԥ�ʤ� */
1043     wchar_t romanBuf[4]; /* ���Х��Ȥǽ�ʬ���Ȼפ����ɤ� */
1044     int len;
1045 #ifdef USE_ROMKANATABLE_FOR_KANAKEY
1046     wchar_t tempc = key ? key : (wchar_t)d->ch;
1047 #else
1048     wchar_t tempc = (wchar_t)d->ch;
1049 #endif
1050     romajiReplace(0, &tempc, 1, SENTOU);
1051 
1052     len = RkwCvtNone(romanBuf, 4, &tempc, 1);
1053 
1054     if (yc->generalFlags & CANNA_YOMI_KAKUTEI) { /* ���ꤷ���㤦 */
1055       WStrncpy(d->buffer_return + d->nbytes, yc->kana_buffer, yc->kCurs);
1056       /* ���޻������Ҥ��ĤäƤ��뤳�ȤϤʤ��Τǡ�yc->kRStartp �Ǥʤ��ơ�
1057 	 yc->kCurs ���Ȥ��� */
1058       d->nbytes += yc->kCurs;
1059       romajiReplace(-yc->rCurs, (wchar_t *)0, 0, 0);
1060       kanaReplace(-yc->kCurs, (wchar_t *)0, 0, 0);
1061 
1062       WStrncpy(d->buffer_return + d->nbytes, romanBuf, len);
1063       d->nbytes += len;
1064       len = 0;
1065     }
1066 
1067     kanaReplace(0, romanBuf, len, HENKANSUMI);
1068     yc->kAttr[yc->kRStartp] |= SENTOU;
1069     yc->rStartp = yc->rCurs;
1070     yc->kRStartp = yc->kCurs;
1071   }
1072   else { /* ���޻������Ѵ������� */
1073 #ifdef USE_ROMKANATABLE_FOR_KANAKEY
1074     wchar_t tempc = key ? key : (wchar_t)d->ch;
1075 #else
1076     wchar_t tempc = (wchar_t)d->ch;
1077 #endif
1078     int ppos;
1079     if (cannaconf.BreakIntoRoman)
1080       yc->generalFlags |= CANNA_YOMI_BREAK_ROMAN;
1081 
1082     /* ľ����̤�Ѵ�ʸ�����ʤ����ɤ�����ǧ */
1083 
1084     if (yc->kCurs == yc->kRStartp) {
1085       ReCheckStartp(yc);
1086     }
1087 
1088     /* �ޤ�����������ʬ�˥��޻���ʸ������� */
1089 
1090     romajiReplace(0, &tempc, 1, (yc->rStartp == yc->rCurs) ? SENTOU : 0);
1091 
1092     ppos = yc->kRStartp;
1093     kanaReplace(0, &tempc, 1, (yc->kRStartp == yc->kCurs) ? SENTOU : 0);
1094 
1095 #ifdef USE_ROMKANATABLE_FOR_KANAKEY
1096     kugiri = makePhonoOnBuffer(d, yc, key ? key : (unsigned char)d->ch, 0, 0);
1097 #else
1098     kugiri = makePhonoOnBuffer(d, yc, (unsigned char)d->ch, 0, 0);
1099 #endif
1100 
1101     if (kugiri && autoconvert) {
1102       if (ppos < yc->ys) {
1103 	yc->ys = ppos;
1104       }
1105       if ((subst = ChikujiSubstYomi(d)) < 0) {
1106 	makeGLineMessageFromString(d, jrKanjiError);
1107 	if (subst == -2) {
1108 	  TanMuhenkan(d);
1109 	}
1110 	else {
1111 	  makeYomiReturnStruct(d);
1112 	}
1113 	return 0; /* ���ޤǹԤ��ʤ��Ƥ����Τ��ʤ� */
1114       }
1115     }
1116   }
1117 
1118   debug_yomi(yc);
1119   makeYomiReturnStruct(d);
1120 
1121   if (!yc->kEndp && !(autoconvert && yc->nbunsetsu)) {
1122     if (yc->left || yc->right) {
1123       removeCurrentBunsetsu(d, (tanContext)yc);
1124     }
1125     else {
1126       /* ̤����ʸ���������ʤ��ʤä��Τʤ顢�ե⡼�ɤ����ܤ��� */
1127       restoreChikujiIfBaseChikuji(yc);
1128       d->current_mode = yc->curMode = yc->myEmptyMode;
1129       d->kanji_status_return->info |= KanjiEmptyInfo;
1130     }
1131     currentModeInfo(d);
1132   }
1133 
1134   return d->nbytes;
1135 }
1136 
1137 /* cfuncdef
1138 
1139    findSup -- supkey ���椫�饭���˰��פ����Τ�õ����
1140 
1141    �֤��ͤ� supkey ����� key �����פ����Τ������ܤ����äƤ��뤫��ɽ����
1142    �����ܤȸ����Τϣ�����Ϥޤ��͡�
1143 
1144    ���Ĥ���ʤ����ϣ����֤���
1145  */
1146 
1147 int findSup pro((wchar_t));
1148 
1149 #ifdef __STDC__
findSup(wchar_t key)1150 findSup(wchar_t key)
1151 #else
1152 findSup(key)
1153 wchar_t key;
1154 #endif
1155 {
1156   int i;
1157   extern nkeysup;
1158 
1159   for (i = 0 ; i < nkeysup ; i++) {
1160     if (key == keysup[i].key) {
1161       return i + 1;
1162     }
1163   }
1164   return 0;
1165 }
1166 
1167 /* cfuncdef
1168 
1169    makePhonoOnBuffer -- yomiContext �ΥХåե���ǥ������Ϣ�ɽ��ʸ���Ѵ���
1170    ����
1171 
1172    �Ѵ��ˤҤȶ��ڤ꤬�դ��������� 1 ���֤�������ʳ��ξ��ˤ� 0 ���֤���
1173 
1174    �Ǹ夫�飲�Ĥ�� flag �� RkwMapPhonogram ���Ϥ��ե饰�ǡ�
1175    �Ǹ�� english �ȸ����Τϱ�ñ�쥫���Ѵ����뤫�ɤ�����ɽ���ե饰
1176 
1177  */
1178 
1179 static
makePhonoOnBuffer(d,yc,key,flag,english)1180 makePhonoOnBuffer(d, yc, key, flag, english)
1181 uiContext d;
1182 yomiContext yc;
1183 unsigned char key;
1184 int flag, english;
1185 {
1186   int i, n, m, t, sm, henkanflag, prevflag, cond;
1187   int retval = 0;
1188   int sup = 0;
1189   int engflag = (english && englishdic);
1190   int engdone = 0;
1191   wchar_t *subp;
1192 #ifndef USE_MALLOC_FOR_BIG_ARRAY
1193   wchar_t kana_char[1024], sub_buf[1024];
1194 #else
1195   wchar_t *kana_char, *sub_buf;
1196 
1197   kana_char = (wchar_t *)malloc(sizeof(wchar_t) * 1024);
1198   sub_buf = (wchar_t *)malloc(sizeof(wchar_t) * 1024);
1199   if (!kana_char || !sub_buf) {
1200     if (kana_char) {
1201       (void)free((char *)kana_char);
1202     }
1203     if (sub_buf) {
1204       (void)free((char *)sub_buf);
1205     }
1206     return 0;
1207   }
1208 #endif
1209 
1210   if (cannaconf.ignore_case) flag |= RK_IGNORECASE;
1211 
1212   /* ̤�Ѵ�����ʸ����Τ����Ѵ� */
1213   for (;;) {
1214 #ifndef USE_ROMKANATABLE_FOR_KANAKEY
1215     if ((flag & RK_FLUSH) &&
1216 	yc->kRStartp != yc->kCurs &&
1217 	!WIsG0(yc->kana_buffer[yc->kCurs - 1])) {
1218       /* ��������ʸ�������äƤ���櫓�Ǥʤ��ä��� */
1219       kana_char[0] = yc->kana_buffer[yc->kRStartp];
1220       n = m = 1; t = 0;
1221       henkanflag = HENKANSUMI;
1222     }
1223     /* ����ޥåԥ���Ĵ�� */
1224     else
1225 #endif
1226       if ((cond = (!(yc->generalFlags & CANNA_YOMI_ROMAJI) &&
1227 		   !(yc->generalFlags & CANNA_YOMI_IGNORE_USERSYMBOLS) &&
1228 		   (yc->kCurs - yc->kRStartp) == 1 &&
1229 		   (sup = findSup(yc->kana_buffer[yc->kRStartp]))) )
1230 	  && keysup[sup - 1].ncand > 0) {
1231       n = 1; t = 0;
1232       WStrcpy(kana_char, keysup[sup - 1].cand[0]);
1233       m = WStrlen(kana_char);
1234       /* defsymbol �ο�������ǽ���б��������� */
1235       yc->romaji_buffer[yc->rStartp] = keysup[sup - 1].xkey;
1236       henkanflag = HENKANSUMI | SUPKEY;
1237     }
1238     else {
1239       if (cond) { /* && keysup[sup - 1].ncand == 0 */
1240       /* defsymbol �ο�������ǽ���б���������������ʸ�����Ȥ��֤������� */
1241 	yc->kana_buffer[yc->kRStartp] =
1242 	  yc->romaji_buffer[yc->rStartp] = keysup[sup - 1].xkey;
1243       }
1244       if (yc->romdic != (struct RkRxDic *)NULL
1245 	  && !(yc->generalFlags & CANNA_YOMI_ROMAJI)) {
1246 	if (engflag &&
1247 	    RkwMapPhonogram(englishdic, kana_char, 1024,
1248 			    yc->kana_buffer + yc->kRStartp,
1249 			    yc->kCurs - yc->kRStartp,
1250 			    (wchar_t)key,
1251 			    flag, &n, &m, &t, &yc->last_rule) &&
1252 	    n > 0) {
1253 	  henkanflag = HENKANSUMI | GAIRAIGO;
1254 	  engdone = 1;
1255 	}
1256 	else if (engflag && 0 == n /* ��� RkwMapPhonogram �������� */ &&
1257 		 RkwMapPhonogram(englishdic, kana_char, 1024,
1258 				 yc->kana_buffer + yc->kRStartp,
1259 				 yc->kCurs - yc->kRStartp,
1260 				 (wchar_t)key,
1261 				 flag | RK_FLUSH,
1262 				 &n, &m, &t, &yc->last_rule) &&
1263 		 n > 0) {
1264 	  henkanflag = HENKANSUMI | GAIRAIGO;
1265 	  engdone = 1;
1266 	}
1267 	else {
1268 	  engflag = 0;
1269 	  if (RkwMapPhonogram(yc->romdic, kana_char, 1024,
1270 			      yc->kana_buffer + yc->kRStartp,
1271 			      yc->kCurs - yc->kRStartp,
1272 			      (wchar_t) key,
1273 			      flag | RK_SOKON, &n, &m, &t, &yc->last_rule)) {
1274 	    /* RK_SOKON ���դ���Τϵ켭���� */
1275 	    henkanflag = HENKANSUMI;
1276 	  }
1277 	  else {
1278 	    henkanflag = 0;
1279 	  }
1280 	  if (n > 0 && !engdone) {
1281 	    engflag = (english && englishdic);
1282 	  }
1283 	}
1284 	if (n == yc->kCurs - yc->kRStartp) {
1285 	  key = (unsigned char)0;
1286 	}
1287       }
1288       else {
1289 	t = 0;
1290 	henkanflag = (yc->generalFlags & CANNA_YOMI_ROMAJI) ?
1291 	  (HENKANSUMI | STAYROMAJI) : 0;
1292 	m = n = (yc->kCurs - yc->kRStartp) ? 1 : 0;
1293 	WStrncpy(kana_char, yc->kana_buffer + yc->kRStartp, n);
1294       }
1295     }
1296 
1297     /* ���޻��Τ��� n ʸ��ʬ���ʤ��Ѵ����줿 */
1298 
1299     if (n <= 0) {
1300       break;
1301     }
1302     else {
1303       int unchanged;
1304 
1305       /* ���޻������Ѵ��η�̤�ù����� */
1306       if (cannaconf.abandonIllegalPhono && !henkanflag && !yc->n_susp_chars) {
1307 	/* �Ѥʥ��޻��ϼΤƤ� */
1308 	sm = 0; subp = sub_buf;
1309 	/* t ������Τ� henkanflag �� 0 �Τ��ȤäƤʤ�������ɤ� */
1310 	/* WStrncpy(subp, kana_char + m, t); */
1311       }
1312       else {
1313 	sm = m; subp = kana_char;
1314 	if (yc->generalFlags & (CANNA_YOMI_KATAKANA | CANNA_YOMI_HIRAGANA)) {
1315 	  int tempm;
1316 
1317 	  if (yc->generalFlags & CANNA_YOMI_KATAKANA) {
1318 	    tempm = RkwCvtKana(sub_buf, 1024, subp, sm);
1319 	  }
1320 	  else {
1321 	    tempm = RkwCvtHira(sub_buf, 1024, subp, sm);
1322 	  }
1323 	  /* Ĺ�������å��������Ϥ��뤬�����ܤΤȤ��ν�����ͤ������ʤ� */
1324 	  WStrncpy(sub_buf + tempm, subp + sm, t);
1325 	  subp = sub_buf;
1326 	  sm = tempm;
1327 	}
1328 	if (yc->generalFlags & (CANNA_YOMI_ZENKAKU | CANNA_YOMI_HANKAKU)) {
1329 	  int tempm;
1330 	  wchar_t *otherp = (subp == sub_buf) ? kana_char : sub_buf;
1331 
1332 	  if (yc->generalFlags & CANNA_YOMI_ZENKAKU) {
1333 	    tempm = RkwCvtZen(otherp, 1024, subp, sm);
1334 	  }
1335 	  else {
1336 	    tempm = RkwCvtHan(otherp, 1024, subp, sm);
1337 	  }
1338 	  WStrncpy(otherp + tempm, subp + sm, t);
1339 	  subp = otherp;
1340 	  sm = tempm;
1341 	}
1342 
1343 	if (yc->generalFlags & CANNA_YOMI_KAKUTEI) { /* ���ꤷ���㤦 */
1344 	  int off;
1345 
1346 	  chikujiEndBun(d);
1347 	  WStrncpy(d->buffer_return + d->nbytes,
1348 		   yc->kana_buffer, yc->kRStartp);
1349 	  d->nbytes += yc->kRStartp;
1350 
1351 	  off = yc->kCurs - yc->kRStartp;
1352 	  yc->kRStartp = 0;
1353 	  yc->kCurs -= off;
1354 	  kanaReplace(-yc->kCurs, (wchar_t *)0, 0, 0);
1355 	  yc->kCurs += off;
1356 
1357 	  WStrncpy(d->buffer_return + d->nbytes, subp, sm);
1358 	  d->nbytes += sm;
1359 	  subp += sm;
1360 	  sm = 0;
1361 	}
1362       }
1363       /* ���޻������Ѵ��η�̤��ʥХåե�������롣 */
1364 
1365       unchanged = yc->kCurs - yc->kRStartp - n;
1366       yc->kCurs -= unchanged;
1367       prevflag = (yc->kAttr[yc->kRStartp] & SENTOU);
1368       kanaReplace(-n, subp, sm + t, henkanflag);
1369       if ( prevflag ) {
1370 	yc->kAttr[yc->kRStartp] |= SENTOU;
1371       }
1372       yc->kRStartp += sm;
1373       if (t == 0 && m > 0 && unchanged) {
1374 	yc->kAttr[yc->kRStartp] |= SENTOU;
1375       }
1376       for (i = yc->kRStartp ; i < yc->kCurs ; i++) {
1377 	yc->kAttr[i] &= ~HENKANSUMI; /* HENKANSUMI �ե饰������� */
1378       }
1379       yc->kCurs += unchanged;
1380 
1381       if (t > 0) {
1382 	/* suspend ���Ƥ���ʸ��Ĺ�ϥ��޻��Хåե��Ȥ��ʥХåե��Ȥ�
1383            ��ʸ�����б��դ��˱ƶ����뤬������Ĵ�����뤿��η׻� */
1384 
1385 	if (yc->n_susp_chars) {
1386 	  yc->n_susp_chars += t - n;
1387 	}
1388 	else {
1389 	  yc->n_susp_chars = SUSPCHARBIAS + t - n;
1390 	}
1391 
1392 	/* �Ĥ��Ǥ˼��Υ��޻������Ѵ��Ѥ� key ��ͤ��Ƥߤ롣 */
1393 	key = (unsigned char)yc->kana_buffer[yc->kRStartp + t];
1394       }
1395       else if (m > 0) { /* ���޻��Ȥ��ʤ��б����դ��뤿��ν��� */
1396 	int n_cor_keys = n -
1397 	  (yc->n_susp_chars ? yc->n_susp_chars - SUSPCHARBIAS : 0);
1398 
1399 	retval = 1; /* �Ҥȶ��ڤ꤬�Ĥ��� */
1400 	yc->rStartp += n_cor_keys;
1401 	if (cannaconf.abandonIllegalPhono &&
1402 	    !henkanflag && !yc->n_susp_chars) {
1403 	  yc->rStartp -= n;
1404 	  unchanged = yc->rCurs - yc->rStartp - n;
1405 	  yc->rCurs -= unchanged;
1406 	  romajiReplace(-n, (wchar_t *)0, 0, 0);
1407 	  yc->rCurs += unchanged;
1408 	  retval = 0; /* ��äѤ���ڤ꤬�Ĥ��Ƥ��ʤ� */
1409 	}
1410 	else if (yc->generalFlags & CANNA_YOMI_KAKUTEI) {
1411 	  int offset = yc->rCurs - yc->rStartp;
1412 
1413 	  yc->rCurs -= offset;
1414 	  romajiReplace(-yc->rCurs, (wchar_t *)0, 0, 0);
1415 	  yc->rCurs += offset;
1416 	  retval = 0; /* ��äѤ���ڤ꤬�Ĥ��Ƥ��ʤ� */
1417 	}
1418 	yc->rAttr[yc->rStartp] |= SENTOU;
1419 	yc->n_susp_chars = /* t ? SUSPCHARBIAS + t : (t ��ɬ�� 0)*/ 0;
1420       }
1421     }
1422   }
1423 #ifdef USE_MALLOC_FOR_BIG_ARRAY
1424   (void)free((char *)kana_char);
1425   (void)free((char *)sub_buf);
1426 #endif
1427   return retval;
1428 }
1429 
1430 #define KANAYOMIINSERT_BUFLEN 10
1431 
1432 /* �ʲ��Τ����Ĥ��δؿ����������ܸ�˰�¸���Ƥ��롣
1433    �������ϤˤĤ��Ƥ�ơ��֥��Ȥ��褦�ˤ��ơ���¸��ʬ��
1434    �ӽ�����褦�ˤ�������Τ� */
1435 
1436 /*
1437   dakuonP -- predicate for Japanese voiced sounds (Japanese specific)
1438 
1439   argument:
1440             ch(wchar_t): character to be inspected
1441 
1442   return value:
1443             0: Not a voiced sound.
1444 	    1: Semi voiced sound.
1445 	    2: Full voiced sound.
1446  */
1447 
1448 #define DAKUON_HV 1
1449 #define DAKUON_FV 2
1450 
1451 static
dakuonP(ch)1452 dakuonP(ch)
1453 wchar_t ch;
1454 {
1455   static dakuon_first_time = 1;
1456   static wchar_t hv, fv;
1457 
1458   if (dakuon_first_time) { /* ���ܸ��ͭ�ν��� */
1459     wchar_t buf[2];
1460 
1461     dakuon_first_time = 0;
1462 
1463     MBstowcs(buf, "\216\336"/* ���� */, 2);
1464     fv = buf[0];
1465     MBstowcs(buf, "\216\337"/* Ⱦ���� */, 2);
1466     hv = buf[0];
1467   }
1468 
1469   if (ch == hv) {
1470     return DAKUON_HV;
1471   }
1472   else if (ch == fv) {
1473     return DAKUON_FV;
1474   }
1475   else {
1476     return 0;
1477   }
1478 }
1479 
1480 /*
1481   growDakuonP -- �������դ����ɤ���
1482 
1483   ����:
1484        ch(wchar_t): Ĵ�٤��оݤ�ʸ��
1485 
1486   �֤���:
1487        0: �դ��ʤ�
1488        1: �֤���
1489        2: �����������դ�
1490        3: Ⱦ�������������դ�
1491  */
1492 
1493 #define GROW_U  1
1494 #define GROW_FV 2
1495 #define GROW_HV 3
1496 
1497 static
growDakuonP(ch)1498 growDakuonP(ch)
1499 wchar_t ch;
1500 {
1501   /* ������³����ǽ��������ʸ���ν��� (���������ȡ��ϡ���) */
1502   static dakuon_first_time = 1;
1503   static wchar_t wu, wka, wto, wha, who;
1504 
1505   if (dakuon_first_time) { /* ���ܸ��ͭ�ν��� */
1506     wchar_t buf[2];
1507 
1508     dakuon_first_time = 0;
1509 
1510     MBstowcs(buf, "\216\263"/* �� */, 2);
1511     wu = buf[0];
1512     MBstowcs(buf, "\216\266"/* �� */, 2);
1513     wka = buf[0];
1514     MBstowcs(buf, "\216\304"/* �� */, 2);
1515     wto = buf[0];
1516     MBstowcs(buf, "\216\312"/* �� */, 2);
1517     wha = buf[0];
1518     MBstowcs(buf, "\216\316"/* �� */, 2);
1519     who = buf[0];
1520   }
1521 
1522   if (ch == wu) {
1523     return GROW_U;
1524   }
1525   else if (wka <= ch && ch <= wto) {
1526     return GROW_FV;
1527   }
1528   else if (wha <= ch && ch <= who) {
1529     return GROW_HV;
1530   }
1531   else {
1532     return 0;
1533   }
1534 }
1535 
1536 static
KanaYomiInsert(d)1537 KanaYomiInsert(d)
1538 uiContext d;
1539 {
1540   static wchar_t kana[3], *kanap;
1541   wchar_t buf1[KANAYOMIINSERT_BUFLEN], buf2[KANAYOMIINSERT_BUFLEN];
1542   /* The array above is not so big (10 wchar_t length) 1996.6.5 kon */
1543   wchar_t *bufp, *nextbufp;
1544   int len, replacelen, spos;
1545   yomiContext yc = (yomiContext)d->modec;
1546   int dakuon, grow_dakuon;
1547 
1548   yc->generalFlags &= ~CANNA_YOMI_BREAK_ROMAN;
1549   kana[0] = (wchar_t)0;
1550   kana[1] = d->buffer_return[0];
1551   kana[2] = (wchar_t)0;
1552   kanap = kana + 1;
1553   replacelen = 0; len = 1;
1554   romajiReplace(0, kanap, 1, SENTOU);
1555   yc->rStartp = yc->rCurs;
1556   if ((dakuon = dakuonP(kanap[0])) != 0) { /* �����ν��� */
1557     if (yc->rCurs > 1) {
1558       kana[0] = yc->romaji_buffer[yc->rCurs - 2];
1559       if ((grow_dakuon = growDakuonP(kana[0])) == GROW_HV ||
1560 	  (grow_dakuon && dakuon == DAKUON_FV)) {
1561 	kanap = kana; len = 2; replacelen = -1;
1562 	yc->rAttr[yc->rCurs - 1] &= ~SENTOU;
1563       }
1564     }
1565   }
1566 #ifdef DEBUG
1567   if (iroha_debug) {
1568     wchar_t aho[200];
1569 
1570     WStrncpy(aho, kana, len);
1571     aho[len] = 0;
1572     fprintf(stderr, "\312\321\264\271\301\260(%s)", aho);
1573                    /* �Ѵ��� */
1574   }
1575 #endif
1576   bufp = kanap; nextbufp = buf1;
1577   if (yc->generalFlags & CANNA_YOMI_ZENKAKU ||
1578       !(yc->generalFlags & (CANNA_YOMI_ROMAJI | CANNA_YOMI_HANKAKU))) {
1579     len = RkwCvtZen(nextbufp, KANAYOMIINSERT_BUFLEN, bufp, len);
1580     bufp = nextbufp;
1581     if (bufp == buf1) {
1582       nextbufp = buf2;
1583     }
1584     else {
1585       nextbufp = buf1;
1586     }
1587   }
1588   if (!(yc->generalFlags & (CANNA_YOMI_ROMAJI | CANNA_YOMI_KATAKANA))) {
1589     /* �Ҥ餬�ʤˤ��� */
1590     len = RkwCvtHira(nextbufp, KANAYOMIINSERT_BUFLEN, bufp, len);
1591     bufp = nextbufp;
1592     if (bufp == buf1) {
1593       nextbufp = buf2;
1594     }
1595     else {
1596       nextbufp = buf1;
1597     }
1598   }
1599 
1600   spos = yc->kCurs + replacelen;
1601   kanaReplace(replacelen, bufp, len, HENKANSUMI);
1602   yc->kAttr[spos] |= SENTOU;
1603 
1604   yc->kRStartp = yc->kCurs;
1605   yc->rStartp = yc->rCurs;
1606   if (growDakuonP(yc->romaji_buffer[yc->rCurs - 1])) {
1607     yc->kRStartp--;
1608     yc->rStartp--;
1609   }
1610 
1611   if (yc->generalFlags & CANNA_YOMI_KAKUTEI) { /* ����⡼�ɤʤ� */
1612     int off, i;
1613 
1614     for (i = len = 0 ; i < yc->kRStartp ; i++) {
1615       if (yc->kAttr[i] & SENTOU) {
1616 	do {
1617 	  len++;
1618 	} while (!(yc->rAttr[len] & SENTOU));
1619       }
1620     }
1621 
1622     if (yc->kRStartp < d->n_buffer) {
1623       WStrncpy(d->buffer_return, yc->kana_buffer, yc->kRStartp);
1624       d->nbytes = yc->kRStartp;
1625     }
1626     else {
1627       d->nbytes = 0;
1628     }
1629     off = yc->kCurs - yc->kRStartp;
1630     yc->kCurs -= off;
1631     kanaReplace(-yc->kCurs, (wchar_t *)0, 0, 0);
1632     yc->kCurs += off;
1633     off = yc->rCurs - len;
1634     yc->rCurs -= off;
1635     romajiReplace(-yc->rCurs, (wchar_t *)0, 0, 0);
1636     yc->rCurs += off;
1637   }
1638   else {
1639     d->nbytes = 0;
1640   }
1641 
1642   if (yc->rStartp == yc->rCurs && yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE &&
1643       ChikujiSubstYomi(d) == -1) {
1644     makeRkError(d, "\303\340\274\241\312\321\264\271\244\313\274\272\307\324"
1645 	"\244\267\244\336\244\267\244\277");
1646                    /* �༡�Ѵ��˼��Ԥ��ޤ��� */
1647     return 0;
1648   }
1649 
1650   makeYomiReturnStruct(d);
1651 
1652   if (yc->kEndp <= yc->cStartp &&
1653       !((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) && yc->nbunsetsu)) {
1654     if (yc->left || yc->right) {
1655       removeCurrentBunsetsu(d, (tanContext)yc);
1656     }
1657     else {
1658       /* ̤����ʸ���������ʤ��ʤä��Τʤ顢�ե⡼�ɤ����ܤ��� */
1659       restoreChikujiIfBaseChikuji(yc);
1660       d->current_mode = yc->curMode = yc->myEmptyMode;
1661       d->kanji_status_return->info |= KanjiEmptyInfo;
1662     }
1663     currentModeInfo(d);
1664   }
1665 
1666   return d->nbytes;
1667 }
1668 
1669 #undef KANAYOMIINSERT_BUFLEN
1670 
1671 void
moveStrings(str,attr,start,end,distance)1672 moveStrings(str, attr, start, end, distance)
1673 wchar_t *str;
1674 BYTE *attr;
1675 int  start, end, distance;
1676 {
1677   int i;
1678 
1679   if (distance > 0) { /* ���ˤ����� */
1680     for (i = end ; start <= i ; i--) { /* ����餺�餹 */
1681       str[i + distance]  = str[i];
1682       attr[i + distance] = attr[i];
1683     }
1684   }
1685   else if (distance < 0) { /* ���ˤ����� */
1686     for (i = start ; i <= end ; i++) {     /* �����餺�餹 */
1687       str[i + distance]  = str[i];
1688       attr[i + distance] = attr[i];
1689     }
1690   }
1691   /* else { �ʤˤ⤷�ʤ� } */
1692 }
1693 
1694 static
howFarToGoBackward(yc)1695 howFarToGoBackward(yc)
1696 yomiContext yc;
1697 {
1698   if (yc->kCurs <= yc->cStartp) {
1699     return 0;
1700   }
1701   if (!cannaconf.ChBasedMove) {
1702     BYTE *st = yc->kAttr;
1703     BYTE *cur = yc->kAttr + yc->kCurs;
1704     BYTE *p = cur;
1705 
1706     for (--p ; p > st && !(*p & SENTOU) ;) {
1707       --p;
1708     }
1709     if (yc->kAttr + yc->cStartp > p) {
1710       p = yc->kAttr + yc->cStartp;
1711     }
1712     return cur - p;
1713   }
1714   return 1;
1715 }
1716 
1717 static
howFarToGoForward(yc)1718 howFarToGoForward(yc)
1719 yomiContext yc;
1720 {
1721   if (yc->kCurs == yc->kEndp) {
1722     return 0;
1723   }
1724   if (!cannaconf.ChBasedMove) {
1725     BYTE *end = yc->kAttr + yc->kEndp;
1726     BYTE *cur = yc->kAttr + yc->kCurs;
1727     BYTE *p = cur;
1728 
1729     for (++p ; p < end && !(*p & SENTOU) ;) {
1730       p++;
1731     }
1732     return p - cur;
1733   }
1734   return 1;
1735 }
1736 
1737 static int YomiBackward pro((uiContext));
1738 
1739 static int
YomiBackward(d)1740 YomiBackward(d) /* ��������κ���ư */
1741 uiContext d;
1742 {
1743   yomiContext yc = (yomiContext)d->modec;
1744   int howManyMove;
1745 
1746   d->nbytes = 0;
1747   if (forceRomajiFlushYomi(d))
1748     return(d->nbytes);
1749 
1750   if ((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) &&
1751       !(yc->status & CHIKUJI_OVERWRAP) && yc->nbunsetsu) {
1752     /* �����Х�åפ���ʤ��ʤ� */
1753     yc->status |= CHIKUJI_OVERWRAP;
1754     moveToChikujiTanMode(d);
1755     return TanBackwardBunsetsu(d);
1756   }
1757 
1758   howManyMove = howFarToGoBackward(yc);
1759   if (howManyMove) {
1760     yc->kCurs -= howManyMove;
1761 
1762     if (yc->kCurs < yc->kRStartp)
1763       yc->kRStartp = yc->kCurs;   /* ̤������޻���������⤺�餹 */
1764 
1765     /* ���ʤΥݥ������Ѵ����줿�Ȥ�������Υǡ����Ǥʤ����
1766        (�Ĥޤ��Ѵ��λ�����Ƭ�Υǡ������ä����)�ˤϥ��޻���
1767        ��������⤺�餹 */
1768 
1769     if (yc->kAttr[yc->kCurs] & SENTOU) {
1770       while ( yc->rCurs > 0 && !(yc->rAttr[--yc->rCurs] & SENTOU) )
1771 	/* EMPTY */
1772 	;
1773       if (yc->rCurs < yc->rStartp)
1774 	yc->rStartp = yc->rCurs;
1775     }
1776   }
1777   else if (yc->nbunsetsu) { /* ʸ�᤬����ʤ�(�༡) */
1778     yc->curbun = yc->nbunsetsu - 1;
1779     if (RkwGoTo(yc->context, yc->nbunsetsu - 1) == -1) { /* �Ǹ���ʸ��� */
1780       return makeRkError(d, "\312\270\300\341\244\316\260\334\306\260\244\313"
1781 	"\274\272\307\324\244\267\244\336\244\267\244\277");
1782                             /* ʸ��ΰ�ư�˼��Ԥ��ޤ��� */
1783     }
1784     yc->kouhoCount = 0;
1785     moveToChikujiTanMode(d);
1786   }
1787   else if (yc->left) {
1788     return TbBackward(d);
1789   }
1790   else if (!cannaconf.CursorWrap) {
1791     return NothingChanged(d);
1792   }
1793   else if (yc->right) {
1794     return TbEndOfLine(d);
1795   }
1796   else {
1797     yc->kCurs = yc->kRStartp = yc->kEndp;
1798     yc->rCurs = yc->rStartp = yc->rEndp;
1799   }
1800   yc->status |= CHIKUJI_OVERWRAP;
1801   makeYomiReturnStruct(d);
1802 
1803   return 0;
1804 }
1805 
1806 static YomiNop pro((uiContext));
1807 
1808 static
YomiNop(d)1809 YomiNop(d)
1810 uiContext d;
1811 {
1812   /* currentModeInfo �ǥ⡼�ɾ���ɬ���֤�褦�˥��ߡ��Υ⡼�ɤ�����Ƥ��� */
1813   d->majorMode = d->minorMode = CANNA_MODE_AlphaMode;
1814   currentModeInfo(d);
1815   makeYomiReturnStruct(d);
1816   return 0;
1817 }
1818 
1819 static YomiForward pro((uiContext));
1820 
1821 static
YomiForward(d)1822 YomiForward(d) /* ��������α���ư */
1823 uiContext d;
1824 {
1825   yomiContext yc = (yomiContext)d->modec;
1826   int howManyMove;
1827 
1828   d->nbytes = 0;
1829   if (forceRomajiFlushYomi(d))
1830     return(d->nbytes);
1831 
1832   if ((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) &&
1833       !(yc->status & CHIKUJI_OVERWRAP) && yc->nbunsetsu) {
1834     yc->status |= CHIKUJI_OVERWRAP;
1835     moveToChikujiTanMode(d);
1836     return TanForwardBunsetsu(d);
1837   }
1838 
1839   howManyMove = howFarToGoForward(yc);
1840   if (howManyMove) {
1841     if (yc->kAttr[yc->kCurs] & SENTOU) { /* ���޻������Ѵ�����Ƭ���ä� */
1842       while ( !yc->rAttr[++yc->rCurs] )
1843 	/* EMPTY */
1844 	; /* ������Ƭ�ޤǤ��餹 */
1845       yc->rStartp = yc->rCurs;
1846     }
1847 
1848     yc->kCurs += howManyMove;   /* ���̤����ϰ��� ����������ˤ��餹 */
1849     yc->kRStartp = yc->kCurs;
1850     yc->status &= ~CHIKUJI_ON_BUNSETSU;
1851   }
1852   else if (yc->right) {
1853     return TbForward(d);
1854   }
1855   else if (!cannaconf.CursorWrap) {
1856     return NothingChanged(d);
1857   }
1858   else if (yc->left) {
1859     return TbBeginningOfLine(d);
1860   }
1861   else if (yc->nbunsetsu) { /* ʸ�᤬����(�༡) */
1862     yc->kouhoCount = 0;
1863     yc->curbun = 0;
1864     if (RkwGoTo(yc->context, 0) == -1) {
1865       return makeRkError(d, "\312\270\300\341\244\316\260\334\306\260\244\313"
1866 	"\274\272\307\324\244\267\244\336\244\267\244\277");
1867                             /* ʸ��ΰ�ư�˼��Ԥ��ޤ��� */
1868     }
1869     moveToChikujiTanMode(d);
1870   }
1871   else {
1872     yc->kRStartp = yc->kCurs = yc->rStartp = yc->rCurs = 0;
1873   }
1874 
1875   yc->status |= CHIKUJI_OVERWRAP;
1876   makeYomiReturnStruct(d);
1877   return 0;
1878 }
1879 
1880 static YomiBeginningOfLine pro((uiContext));
1881 
1882 static
YomiBeginningOfLine(d)1883 YomiBeginningOfLine(d) /* ��������κ�ü��ư */
1884 uiContext d;
1885 {
1886   yomiContext yc = (yomiContext)d->modec;
1887 
1888   d->nbytes = 0;
1889   if (forceRomajiFlushYomi(d))
1890     return(d->nbytes);
1891 
1892   if (yc->left) {
1893     return TbBeginningOfLine(d);
1894   }
1895   else if (yc->nbunsetsu) { /* �༡�Ǻ�¦��ʸ�᤬����ʤ� */
1896     yc->kouhoCount = 0;
1897     if (RkwGoTo(yc->context, 0) < 0) {
1898       return makeRkError(d, "\312\270\300\341\244\316\260\334\306\260\244\313"
1899 	"\274\272\307\324\244\267\244\336\244\267\244\277");
1900                             /* ʸ��ΰ�ư�˼��Ԥ��ޤ��� */
1901     }
1902     yc->curbun = 0;
1903     moveToChikujiTanMode(d);
1904   }
1905   else {
1906     yc->kRStartp = yc->kCurs = yc->cStartp;
1907     yc->rStartp = yc->rCurs = yc->cRStartp;
1908   }
1909   yc->status |= CHIKUJI_OVERWRAP;
1910   makeYomiReturnStruct(d);
1911   return(0);
1912 }
1913 
1914 static YomiEndOfLine pro((uiContext));
1915 
1916 static
YomiEndOfLine(d)1917 YomiEndOfLine(d) /* ��������α�ü��ư */
1918 uiContext d;
1919 {
1920   yomiContext yc = (yomiContext)d->modec;
1921 
1922   d->nbytes = 0;
1923   if (forceRomajiFlushYomi(d))
1924     return(d->nbytes);
1925 
1926   if (yc->right) {
1927     return TbEndOfLine(d);
1928   }
1929   else {
1930     yc->kRStartp = yc-> kCurs = yc->kEndp;
1931     yc->rStartp = yc-> rCurs = yc->rEndp;
1932     yc->status &= ~CHIKUJI_ON_BUNSETSU;
1933     yc->status |= CHIKUJI_OVERWRAP;
1934   }
1935   makeYomiReturnStruct(d);
1936   return 0;
1937 }
1938 
1939 int
forceRomajiFlushYomi(d)1940 forceRomajiFlushYomi(d)
1941 uiContext d;
1942 {
1943   yomiContext yc = (yomiContext)d->modec;
1944 
1945   if (yc->kCurs != yc->kRStartp) {
1946     d->nbytes = 0;
1947     if (RomajiFlushYomi(d, (wchar_t *)NULL, 0) == 0) { /* empty mode */
1948       d->more.todo = 1;
1949       d->more.ch = d->ch;
1950       d->more.fnum = 0;    /* ��� ch �Ǽ������������� */
1951       return(1);
1952     }
1953   }
1954   return(0);
1955 }
1956 
1957 /* RomajiFlushYomi(d, buffer, bufsize) �桼�ƥ���ƥ��ؿ�
1958  *
1959  * ���δؿ��ϡ�(uiContext)d ���ߤ����Ƥ����ɤߤξ���
1960  * (yc->romaji_buffer �� yc->kana_buffer)���Ѥ��ơ�buffer �ˤ����ɤߤ��
1961  * ��å��夷����̤��֤��ؿ��Ǥ��롣�ե�å��夷����̤�ʸ�����Ĺ��
1962  * �Ϥ��δؿ����֤��ͤȤ����֤���롣
1963  *
1964  * buffer �Ȥ��� NULL �����ꤵ�줿���ϡ��Хåե����Ф����Ǽ�ϹԤ�ʤ�
1965  *
1966  * �ں��ѡ�
1967  *
1968  *    �ɤߤ���ꤹ��
1969  *
1970  * �ڰ�����
1971  *
1972  *    d  (uiContext)  ���ʴ����Ѵ���¤��
1973  *    buffer (char *)    �ɤߤ��֤�����ΥХåե� (NULL ��)
1974  *
1975  * ������͡�
1976  *
1977  *    buffer �˳�Ǽ����ʸ�����Ĺ��(�Х���Ĺ)
1978  *
1979  * �������ѡ�
1980  *
1981  */
1982 
RomajiFlushYomi(d,b,bsize)1983 RomajiFlushYomi(d, b, bsize)
1984 uiContext d;
1985 wchar_t *b;
1986 int bsize;
1987 {
1988   int ret;
1989   yomiContext yc = (yomiContext)d->modec;
1990 
1991   yc->generalFlags &= ~CANNA_YOMI_BREAK_ROMAN;
1992 
1993   makePhonoOnBuffer(d, yc, (unsigned char)0, RK_FLUSH, 0);
1994   yc->n_susp_chars = 0; /* ��ιԤ��ݾڤ���뤫���Τ�ʤ� */
1995   yc->last_rule = 0;
1996 
1997   ret = yc->kEndp - yc->cStartp; /* ���η�̤����δؿ����֤��ͤˤʤ� */
1998   if (b) {
1999     if (bsize > ret) {
2000       WStrncpy(b, yc->kana_buffer + yc->cStartp, ret);
2001       b[ret] = '\0';
2002     }
2003     else {
2004       WStrncpy(b, yc->kana_buffer + yc->cStartp, bsize);
2005       ret = bsize;
2006     }
2007   }
2008   if (ret == 0) { /* �ɤߤ�̵���ʤä��Τʤ饨��ץƥ��⡼�ɤ� */
2009     d->current_mode = yc->curMode = yc->myEmptyMode;
2010     /* ��äȤ������ꥢ���������ɤ�����ʤ��� */
2011   }
2012   return ret;
2013 }
2014 
2015 static int saveFlags pro((yomiContext));
2016 
2017 static int
saveFlags(yc)2018 saveFlags(yc)
2019 yomiContext yc;
2020 {
2021   if (!(yc->savedFlags & CANNA_YOMI_MODE_SAVED)) {
2022     yc->savedFlags = (yc->generalFlags &
2023 		      (CANNA_YOMI_ATTRFUNCS | CANNA_YOMI_BASE_HANKAKU)) |
2024 			CANNA_YOMI_MODE_SAVED;
2025     yc->savedMinorMode = yc->minorMode;
2026     return 1;
2027   }
2028   else {
2029     return 0;
2030   }
2031 }
2032 
2033 void
restoreFlags(yc)2034 restoreFlags(yc)
2035 yomiContext yc;
2036 {
2037   yc->generalFlags &= ~(CANNA_YOMI_ATTRFUNCS | CANNA_YOMI_BASE_HANKAKU);
2038   yc->generalFlags |= yc->savedFlags
2039     & (CANNA_YOMI_ATTRFUNCS | CANNA_YOMI_BASE_HANKAKU);
2040   yc->savedFlags = (long)0;
2041   yc->minorMode = yc->savedMinorMode;
2042 }
2043 
2044 /*
2045  doYomiKakutei -- �ɤߤ���ꤵ����ư����롣
2046 
2047   retval 0 -- ����̵�����ꤷ����
2048          1 -- ���ꤷ����ʤ��ʤä���
2049         -1 -- ���顼��
2050  */
2051 
2052 static int
doYomiKakutei(d)2053 doYomiKakutei(d)
2054 uiContext d;
2055 {
2056   int len;
2057 
2058   len = RomajiFlushYomi(d, (wchar_t *)0, 0);
2059   if (len == 0) {
2060     return 1;
2061   }
2062 
2063   return 0;
2064 }
2065 
2066 int
xString(str,len,s,e)2067 xString(str, len, s, e)
2068 wchar_t *str, *s, *e;
2069 int len;
2070 {
2071   if (e < s + len) {
2072     len = e - s;
2073   }
2074   WStrncpy(s, str, len);
2075   return len;
2076 }
2077 
2078 static int
xYomiKakuteiString(yc,s,e)2079 xYomiKakuteiString(yc, s, e)
2080 yomiContext yc;
2081 wchar_t *s, *e;
2082 {
2083   return xString(yc->kana_buffer + yc->cStartp, yc->kEndp - yc->cStartp, s, e);
2084 }
2085 
2086 static int
xYomiYomi(yc,s,e)2087 xYomiYomi(yc, s, e)
2088 yomiContext yc;
2089 wchar_t *s, *e;
2090 {
2091   return xString(yc->kana_buffer, yc->kEndp, s, e);
2092 }
2093 
2094 static int
xYomiRomaji(yc,s,e)2095 xYomiRomaji(yc, s, e)
2096 yomiContext yc;
2097 wchar_t *s, *e;
2098 {
2099   return xString(yc->romaji_buffer, yc->rEndp, s, e);
2100 }
2101 
2102 static void
finishYomiKakutei(d)2103 finishYomiKakutei(d)
2104 uiContext d;
2105 {
2106   yomiContext yc = (yomiContext)d->modec;
2107 
2108   if (yc->savedFlags & CANNA_YOMI_MODE_SAVED) {
2109     restoreFlags(yc);
2110   }
2111 }
2112 
2113 int
appendTan2Yomi(tan,yc)2114 appendTan2Yomi(tan, yc)
2115 tanContext tan;
2116 yomiContext yc;
2117 {
2118   int klen, rlen;
2119 
2120   klen = WStrlen(tan->yomi);
2121   rlen = WStrlen(tan->roma);
2122 
2123   if (yc->kEndp + klen < ROMEBUFSIZE && yc->rEndp + rlen < ROMEBUFSIZE) {
2124     WStrcpy(yc->kana_buffer + yc->kEndp, tan->yomi);
2125     WStrcpy(yc->romaji_buffer + yc->rEndp, tan->roma);
2126     bcopy(tan->kAttr, yc->kAttr + yc->kEndp, (klen + 1) * sizeof(BYTE));
2127     bcopy(tan->rAttr, yc->rAttr + yc->rEndp, (rlen + 1) * sizeof(BYTE));
2128     yc->rEndp += rlen;
2129     yc->kEndp += klen;
2130     return 1;
2131   }
2132   return 0;
2133 }
2134 
2135 static
appendYomi2Yomi(yom,yc)2136 appendYomi2Yomi(yom, yc)
2137 yomiContext yom, yc;
2138 {
2139   int rlen, klen;
2140 
2141   rlen = yom->rEndp;
2142   klen = yom->kEndp;
2143   if (yc->kEndp + klen < ROMEBUFSIZE && yc->rEndp + rlen < ROMEBUFSIZE) {
2144     yom->romaji_buffer[rlen] = (wchar_t)'\0';
2145     yom->kana_buffer[klen] = (wchar_t)'\0';
2146     WStrcpy(yc->romaji_buffer + yc->rEndp, yom->romaji_buffer);
2147     WStrcpy(yc->kana_buffer + yc->kEndp, yom->kana_buffer);
2148     bcopy(yom->kAttr, yc->kAttr + yc->kEndp, (klen + 1) * sizeof(BYTE));
2149     bcopy(yom->rAttr, yc->rAttr + yc->rEndp, (rlen + 1) * sizeof(BYTE));
2150     yc->rEndp += rlen;
2151     yc->kEndp += klen;
2152     return 1;
2153   }
2154   return 0;
2155 }
2156 
2157 yomiContext
dupYomiContext(yc)2158 dupYomiContext(yc)
2159 yomiContext yc;
2160 {
2161   yomiContext res;
2162 
2163   res = newYomiContext((wchar_t *)NULL, 0, /* ��̤ϳ�Ǽ���ʤ� */
2164 		       CANNA_NOTHING_RESTRICTED,
2165 		       (int)!CANNA_YOMI_CHGMODE_INHIBITTED,
2166 		       (int)!CANNA_YOMI_END_IF_KAKUTEI,
2167 		       CANNA_YOMI_INHIBIT_NONE);
2168   if (res) {
2169     res->generalFlags = yc->generalFlags;
2170     res->status = yc->status;
2171     res->majorMode = yc->majorMode;
2172     res->minorMode = yc->minorMode;
2173     res->myMinorMode = yc->myMinorMode;
2174     res->curMode = yc->curMode;
2175     res->myEmptyMode = yc->myEmptyMode;
2176     res->romdic = yc->romdic;
2177     res->next = yc->next;
2178     res->prevMode = yc->prevMode;
2179     appendYomi2Yomi(yc, res);
2180   }
2181   return res;
2182 }
2183 
2184 
2185 /*
2186   doMuhenkan -- ̵�Ѵ��������롣
2187 
2188   yc ���鱦�� tanContext/yomiContext ��ܥĤˤ��ơ����Τʤ��˳�Ǽ����Ƥ���
2189   �ɤߤ� yc �ˤ��äĤ��롣
2190  */
2191 
2192 void
doMuhenkan(d,yc)2193 doMuhenkan(d, yc)
2194 uiContext d;
2195 yomiContext yc;
2196 {
2197   tanContext tan, netan, st = (tanContext)yc;
2198   yomiContext yom;
2199 
2200   /* �ޤ�̵�Ѵ������������� */
2201   for (tan = st ; tan ; tan = tan->right) {
2202     if (tan->id == YOMI_CONTEXT) {
2203       yom = (yomiContext)tan;
2204       d->modec = (mode_context)yom;
2205       if (yom->nbunsetsu || (yom->generalFlags & CANNA_YOMI_CHIKUJI_MODE)) {
2206 	tanMuhenkan(d, -1);
2207       }
2208       if (yom->jishu_kEndp) {
2209 	leaveJishuMode(d, yom);
2210       }
2211       /* else �ɤߥ⡼�ɤǤϤʤˤ⤹��ɬ�פ��ʤ��� */
2212     }
2213   }
2214 
2215   /* �����ɤߤʤɤ�ʸ������Ф� */
2216   for (tan = st ; tan ; tan = netan) {
2217     netan = tan->right;
2218     if (tan->id == TAN_CONTEXT) {
2219       appendTan2Yomi(tan, yc);
2220       freeTanContext(tan);
2221     }
2222     else if (tan->id == YOMI_CONTEXT) {
2223       if ((yomiContext)tan != yc) {
2224 	appendYomi2Yomi((yomiContext)tan, yc);
2225 	freeYomiContext((yomiContext)tan);
2226       }
2227     }
2228   }
2229   yc->rCurs = yc->rStartp = yc->rEndp;
2230   yc->kCurs = yc->kRStartp = yc->kEndp;
2231   yc->right = (tanContext)0;
2232   d->modec = (mode_context)yc;
2233 }
2234 
2235 static int
xTanKakuteiString(yc,s,e)2236 xTanKakuteiString(yc, s, e)
2237 yomiContext yc;
2238 wchar_t *s, *e;
2239 {
2240   wchar_t *ss = s;
2241   int i, len, nbun;
2242 
2243   nbun = yc->bunlen ? yc->curbun : yc->nbunsetsu;
2244 
2245   for (i = 0 ; i < nbun ; i++) {
2246     RkwGoTo(yc->context, i);
2247     len = RkwGetKanji(yc->context, s, (int)(e - s));
2248     if (len < 0) {
2249       if (errno == EPIPE) {
2250 	jrKanjiPipeError();
2251       }
2252       jrKanjiError = "\245\253\245\354\245\363\245\310\270\365\312\344\244\362"
2253 	"\274\350\244\352\275\320\244\273\244\336\244\273\244\363\244\307"
2254 	"\244\267\244\277";
2255                     /* �����ȸ������Ф��ޤ���Ǥ��� */
2256     }
2257     else {
2258       s += len;
2259     }
2260   }
2261   RkwGoTo(yc->context, yc->curbun);
2262 
2263   if (yc->bunlen) {
2264     len = yc->kEndp - yc->kanjilen;
2265     if (((int)(e - s)) < len) {
2266       len = (int)(e - s);
2267     }
2268     WStrncpy(s, yc->kana_buffer + yc->kanjilen, len);
2269     s += len;
2270   }
2271 
2272   if ((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) &&
2273       yc->cStartp < yc->kEndp) {
2274     len = xYomiKakuteiString(yc, s, e);
2275     s += len;
2276   }
2277   return (int)(s - ss);
2278 }
2279 
2280 static int
doJishuKakutei(d,yc)2281 doJishuKakutei(d, yc)
2282 uiContext d;
2283 yomiContext yc;
2284 {
2285   exitJishu(d);
2286   yc->jishu_kEndp = 0;
2287   return 0;
2288 }
2289 
2290 
2291 typedef struct _autoDefRec {
2292     struct _autoDefRec *next;
2293     int ishira;
2294     wchar_t yomibuf[ROMEBUFSIZE];
2295     wchar_t kanabuf[ROMEBUFSIZE];
2296 } autoDefRec, *autoDef;
2297 
2298 /*
2299   doKakutei -- ����������롣
2300 
2301     st ���� et ��ľ���ޤǤ� tanContext/yomiContext ����ꤵ����
2302     s ���� e ���ϰϤ˳����̤���Ǽ����롣
2303     yc_return �� yomiContext ���ĻĤ����ߤ������ˡ��Ĥä� yomiContext
2304     ���Ǽ�����֤�����Υ��ɥ쥹��yc_return ���̥�ʤ顢����Ĥ��� free
2305     ���롣
2306     et->left �ϸƤӽФ����Ȥ���� 0 �ˤ��뤳�ȡ�
2307 
2308     ���ꤷ��ʸ����Ĺ�����֤���롣
2309 
2310     ���δؿ���Ƥ���� d->modec ������Ƥ���Τ�����ľ���ʤ���Фʤ�ʤ�
2311 
2312  */
2313 
2314 int
doKakutei(d,st,et,s,e,yc_return)2315 doKakutei(d, st, et, s, e, yc_return)
2316 uiContext d;
2317 tanContext st, et;
2318 wchar_t *s, *e;
2319 yomiContext *yc_return;
2320 {
2321   tanContext tan, netan;
2322   yomiContext yc;
2323   int len, res;
2324   wchar_t *ss = s;
2325   extern int auto_define;
2326   autoDef autotop = NULL, autocur;
2327   KanjiMode kmsv = d->current_mode;
2328 
2329   /* �ޤ���������������� */
2330   for (tan = st ; tan != et ; tan = tan->right) {
2331     if (tan->id == YOMI_CONTEXT) {
2332       yc = (yomiContext)tan;
2333       d->modec = (mode_context)yc;
2334       if (yc->jishu_kEndp) {
2335 	autocur = NULL;
2336         if (auto_define &&
2337 	    (yc->jishu_kc == JISHU_ZEN_KATA
2338 #ifdef HIRAGANAAUTO
2339 	     || yc->jishu_kc == JISHU_HIRA
2340 #endif
2341 	    ))
2342 	  autocur = (autoDef)malloc(sizeof(autoDefRec));
2343 	if (autocur) {
2344 	  WStrcpy(autocur->yomibuf, yc->kana_buffer);
2345 	  autocur->ishira = (yc->jishu_kc == JISHU_HIRA);
2346 	}
2347 	doJishuKakutei(d, yc);
2348 	if (autocur) {
2349 	  WStrcpy(autocur->kanabuf, yc->kana_buffer);
2350 	  autocur->next = autotop;
2351 	  autotop = autocur;
2352 	}
2353       }
2354       else if (!yc->bunlen && /* ʸ�῭�Ф��̤��� */
2355 	       (!yc->nbunsetsu || /* �������ʤ���... */
2356 		(yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE &&
2357 		 yc->cStartp < yc->kEndp))) { /* �ɤߤ��ޤ����� .. */
2358 	long savedFlag = yc->generalFlags;
2359 	yc->generalFlags &= ~CANNA_YOMI_KAKUTEI;
2360 	/* base-kakutei ���� doYomiKakutei() ���ƤӽФ��Ƥ���
2361 	   RomajiFlushYomi() ����dz���ʸ����ȯ������
2362 	   ���������ݤˤʤ�ΤǤȤꤢ���� base-kakutei ������ */
2363 	doYomiKakutei(d);
2364 	yc->generalFlags = savedFlag;
2365       }
2366     }
2367   }
2368   /* doJishuKakutei,doYomiKakutei��empty_mode�����뤳�Ȥ����� */
2369   d->current_mode = kmsv;
2370 
2371   /* ���˳���ʸ������Ф� */
2372   for (tan = st ; tan != et ; tan = tan->right) {
2373     if (tan->id == TAN_CONTEXT) {
2374       len = extractTanString(tan, s, e);
2375     }
2376     else if (tan->id == YOMI_CONTEXT) {
2377       yc = (yomiContext)tan;
2378       d->modec = (mode_context)yc;
2379       if (yc->nbunsetsu || (yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE)) {
2380 	len = xTanKakuteiString(yc, s, e);
2381       }
2382       else { /* else �äƤ��Ȥϡ��ɤ߾��֤����ʤ� */
2383 	len = xYomiKakuteiString(yc, s, e);
2384       }
2385     }
2386     s += len;
2387   }
2388   res = (int)(s - ss);
2389   if (s < e) {
2390     *s++ = (wchar_t)'\0';
2391   }
2392 
2393   /* yomiInfo �ν������� */
2394   if (yomiInfoLevel > 0) {
2395     d->kanji_status_return->info |= KanjiYomiInfo;
2396     for (tan = st ; tan != et ; tan = tan->right) {
2397       if (tan->id == TAN_CONTEXT) {
2398 	len = extractTanYomi(tan, s, e);
2399       }
2400       else if (tan->id == YOMI_CONTEXT) {
2401 	len = xYomiYomi((yomiContext)tan, s, e);
2402       }
2403       s += len;
2404     }
2405     if (s < e) {
2406       *s++ = (wchar_t)'\0';
2407     }
2408 
2409     if (yomiInfoLevel > 1) {
2410       for (tan = st ; tan != et ; tan = tan->right) {
2411 	if (tan->id == TAN_CONTEXT) {
2412 	  len = extractTanRomaji(tan, s, e);
2413 	}
2414 	else if (tan->id == YOMI_CONTEXT) {
2415 	  len = xYomiRomaji((yomiContext)tan, s, e);
2416 	}
2417 	s += len;
2418       }
2419     }
2420     if (s < e) {
2421       *s++ = (wchar_t)'\0';
2422     }
2423   }
2424 
2425   /* ����λĽ�����Ԥ� */
2426   if (yc_return) {
2427     *yc_return = (yomiContext)0;
2428   }
2429   for (tan = st ; tan != et ; tan = netan) {
2430     netan = tan->right;
2431     if (tan->id == TAN_CONTEXT) {
2432       freeTanContext(tan);
2433     }
2434     else { /* tan->id == YOMI_CONTEXT */
2435       yc = (yomiContext)tan;
2436       d->modec = (mode_context)yc;
2437 
2438       if (yc->nbunsetsu || (yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE)) {
2439 	if (yc->bunlen) {
2440 	  leaveAdjustMode(d, yc);
2441 	}
2442 	finishTanKakutei(d);
2443       }
2444       else { /* �äƤ��Ȥϡ��ɤ߾��֤����ʤ� */
2445 	finishYomiKakutei(d);
2446       }
2447       if (yc_return && !*yc_return) {
2448 	*yc_return = yc;
2449       }
2450       else {
2451 	/* �ȤäƤ�����Ĥ��⤦���뤫������ʤ��ʤ顢���ΤϼΤƤ� */
2452 	/* yc->context �� close �Ϥ���ʤ��Τ��ʤ���1996.10.30 �� */
2453 	freeYomiContext(yc);
2454       }
2455     }
2456   }
2457 
2458   if (yc_return) {
2459     yc = *yc_return;
2460     if (yc) {
2461       yc->left = yc->right = (tanContext)0;
2462     }
2463   }
2464   d->modec = (mode_context)0;
2465   /* ����Ƥ��뤫���Τ�ʤ��ΤǻȤ��ְ��ʤ��褦�˲����Ԥ����Ƥ��� */
2466 
2467   /* �����Ѵ������ѥ������ʤ���ꤷ���顢��ư��Ͽ���� */
2468   for (autocur = autotop; autocur; autocur = autocur->next) {
2469     wchar_t line[ROMEBUFSIZE];
2470     int cnt;
2471     extern int defaultContext;
2472     extern char *kataautodic;
2473 #ifdef HIRAGANAAUTO
2474     extern char *hiraautodic;
2475 #endif
2476 
2477     WStraddbcpy(line, autocur->yomibuf, ROMEBUFSIZE);
2478     EWStrcat(line, " ");
2479     EWStrcat(line, "#T30");
2480     EWStrcat(line, " ");
2481     cnt = WStrlen(line);
2482     WStraddbcpy(line + cnt, autocur->kanabuf, ROMEBUFSIZE - cnt);
2483 
2484     if (defaultContext == -1) {
2485       if ((KanjiInit() < 0) || (defaultContext == -1)) {
2486 	jrKanjiError = KanjiInitError();
2487         makeGLineMessageFromString(d, jrKanjiError);
2488         goto return_res;
2489       }
2490     }
2491 
2492     if (!autocur->ishira) {
2493       if (RkwDefineDic(defaultContext, kataautodic, line) != 0) {
2494         jrKanjiError = "\274\253\306\260\305\320\317\277\244\307\244\255"
2495                        "\244\336\244\273\244\363\244\307\244\267\244\277";
2496                          /* ��ư��Ͽ�Ǥ��ޤ���Ǥ��� */
2497         makeGLineMessageFromString(d, jrKanjiError);
2498 	goto return_res;
2499       }
2500       else {
2501         if (cannaconf.auto_sync) {
2502           (void)RkwSync(defaultContext, kataautodic);
2503         }
2504       }
2505     } else {
2506 #ifdef HIRAGANAAUTO
2507       if (RkwDefineDic(defaultContext, hiraautodic, line) != 0) {
2508         jrKanjiError = "\274\253\306\260\305\320\317\277\244\307\244\255"
2509                        "\244\336\244\273\244\363\244\307\244\267\244\277";
2510                          /* ��ư��Ͽ�Ǥ��ޤ���Ǥ��� */
2511         makeGLineMessageFromString(d, jrKanjiError);
2512 	goto return_res;
2513       }
2514       else {
2515         if (cannaconf.auto_sync) {
2516           (void)RkwSync(defaultContext, hiraautodic);
2517         }
2518       }
2519 #endif
2520     }
2521   }
2522  return_res:
2523   while (autotop) {
2524     autocur = autotop->next;
2525     free(autotop);
2526     autotop = autocur;
2527   }
2528   return res;
2529 }
2530 
2531 /*
2532   cutOffLeftSide -- �������� tanContext ����ꤵ���롣
2533 
2534   n -- ���� n �ĻĤ��Ƴ��ꤹ�롣
2535 
2536  */
2537 
2538 int
cutOffLeftSide(d,yc,n)2539 cutOffLeftSide(d, yc, n)
2540 uiContext d;
2541 yomiContext yc;
2542 int n;
2543 {
2544   int i;
2545   tanContext tan = (tanContext)yc, st;
2546 
2547   for (i = 0 ; i < n && tan ; i++) {
2548     tan = tan->left;
2549   }
2550   if (tan && tan->left) {
2551     st = tan->left;
2552     while (st->left) {
2553       st = st->left;
2554     }
2555     d->nbytes = doKakutei(d, st, tan, d->buffer_return,
2556 			  d->buffer_return + d->n_buffer, (yomiContext *)0);
2557     d->modec = (mode_context)yc;
2558     tan->left = (tanContext)0;
2559     return 1;
2560   }
2561   return 0;
2562 }
2563 
2564 extern KanjiModeRec cy_mode;
2565 
2566 int YomiKakutei pro((uiContext));
2567 
2568 int
YomiKakutei(d)2569 YomiKakutei(d)
2570 uiContext d;
2571 {
2572   yomiContext yc = (yomiContext)d->modec, newFilledYomiContext();
2573   tanContext leftmost;
2574   int len, res;
2575   wchar_t *s = d->buffer_return, *e = s + d->n_buffer;
2576   mode_context next = yc->next;
2577   KanjiMode prev = yc->prevMode;
2578   long prevflags;
2579 
2580   prevflags = (yc->id == YOMI_CONTEXT) ?
2581     yc->generalFlags : ((tanContext)yc)->generalFlags;
2582 
2583   d->kanji_status_return->length = 0;
2584   d->nbytes = 0;
2585 
2586   leftmost = (tanContext)yc;
2587   while (leftmost->left) {
2588     leftmost = leftmost->left;
2589   }
2590 
2591   len = doKakutei(d, leftmost, (tanContext)0, s, e, &yc);
2592 
2593   if (!yc) {
2594     yc = newFilledYomiContext(next, prev);
2595     yc->generalFlags = prevflags;
2596     yc->minorMode = getBaseMode(yc);
2597   }
2598   d->modec = (mode_context)yc;
2599   if (!yc) {
2600     freeRomeStruct(d);
2601     return -1; /* �����ˤ���Ǥ����Τ��������� 1994.2.23 kon */
2602   }
2603   d->current_mode = yc->curMode;
2604   d->nbytes = len;
2605 
2606   res = YomiExit(d, d->nbytes);
2607   currentModeInfo(d);
2608   return res;
2609 }
2610 
2611 /* ���� 0 �ˤ���櫓�ǤϤʤ��Τ���� */
2612 
2613 void
clearYomiContext(yc)2614 clearYomiContext(yc)
2615 yomiContext yc;
2616 {
2617   yc->rStartp = 0;
2618   yc->rCurs = 0;
2619   yc->rEndp = 0;
2620   yc->romaji_buffer[0] = (wchar_t)0;
2621   yc->rAttr[0] = SENTOU;
2622   yc->kRStartp = 0;
2623   yc->kCurs = 0;
2624   yc->kEndp = 0;
2625   yc->kana_buffer[0] = (wchar_t)0;
2626   yc->kAttr[0] = SENTOU;
2627   yc->pmark = yc->cmark = 0;
2628   yc->englishtype = CANNA_ENG_KANA;
2629   yc->cStartp = yc->cRStartp = 0;
2630   yc->jishu_kEndp = 0;
2631 }
2632 
2633 static int
clearChikujiContext(yc)2634 clearChikujiContext(yc)
2635      yomiContext yc;
2636 {
2637   clearYomiContext(yc);
2638   yc->status &= CHIKUJI_NULL_STATUS;
2639   yc->ys = yc->ye = yc->cStartp;
2640   clearHenkanContext(yc);
2641   return 0;
2642 }
2643 
2644 
2645 /* RomajiClearYomi(d) �桼�ƥ���ƥ��ؿ�
2646  *
2647  * ���δؿ��ϡ�(uiContext)d ���ߤ����Ƥ����ɤߤξ���
2648  * ���ꥢ���롣
2649  *
2650  * �ں��ѡ�
2651  *
2652  *    �ɤߤ��ꥢ���롣
2653  *
2654  * �ڰ�����
2655  *
2656  *    d  (uiContext)  ���ʴ����Ѵ���¤��
2657  *
2658  * ������͡�
2659  *
2660  *    �ʤ���
2661  *
2662  * �������ѡ�
2663  *
2664  *    yc->rEndp = 0;
2665  *    yc->kEndp = 0; ��
2666  */
2667 
2668 void
RomajiClearYomi(d)2669 RomajiClearYomi(d)
2670 uiContext d;
2671 {
2672   yomiContext yc = (yomiContext)d->modec;
2673 
2674   if (yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) {
2675     if (yc->context >= 0) {
2676       RkwEndBun(yc->context, 0);
2677       abandonContext(d, yc);
2678     }
2679     clearChikujiContext(yc);
2680   }
2681   else {
2682     clearYomiContext(yc);
2683   }
2684 }
2685 
YomiExit(d,retval)2686 YomiExit(d, retval)
2687 uiContext d;
2688 int retval;
2689 {
2690   yomiContext yc = (yomiContext)d->modec;
2691 
2692   RomajiClearYomi(d);
2693 
2694   /* ���ꤷ�Ƥ��ޤä��顢�ɤߤ��ʤ��ʤ�ΤǦե⡼�ɤ����ܤ��롣 */
2695   restoreChikujiIfBaseChikuji(yc);
2696   d->current_mode = yc->curMode = yc->myEmptyMode;
2697   d->kanji_status_return->info |= KanjiEmptyInfo;
2698 
2699   return checkIfYomiExit(d, retval);
2700 }
2701 
2702 /* RomajiStoreYomi(d, kana) �桼�ƥ���ƥ��ؿ�
2703  *
2704  * ���δؿ��ϡ�(uiContext)d ���ɤߤξ�����ȥ����롣
2705  *
2706  * �ں��ѡ�
2707  *
2708  *    �ɤߤ��Ǽ���롣
2709  *
2710  * �ڰ�����
2711  *
2712  *    d    (uiContext)  ���ʴ����Ѵ���¤��
2713  *    kana (wchar_t *) ����ʸ����
2714  *    roma (wchar_t *) ���޻�ʸ����
2715  * ������͡�
2716  *
2717  *    �ʤ���
2718  *
2719  * �������ѡ�
2720  *
2721  *    yc->rEndp = WStrlen(kana);
2722  *    yc->kEndp = WStrlen(kana); ��
2723  */
2724 
2725 void
RomajiStoreYomi(d,kana,roma)2726 RomajiStoreYomi(d, kana, roma)
2727 uiContext d;
2728 wchar_t *kana, *roma;
2729 {
2730   int i, ylen, rlen, additionalflag;
2731   yomiContext yc = (yomiContext)d->modec;
2732 
2733   rlen = ylen = WStrlen(kana);
2734   if (roma) {
2735     rlen = WStrlen(roma);
2736     additionalflag = 0;
2737   }
2738   else {
2739     additionalflag = SENTOU;
2740   }
2741   WStrcpy(yc->romaji_buffer, (roma ? roma : kana));
2742   yc->rStartp = rlen;
2743   yc->rCurs = rlen;
2744   yc->rEndp = rlen;
2745   WStrcpy(yc->kana_buffer, kana);
2746   yc->kRStartp = ylen;
2747   yc->kCurs = ylen;
2748   yc->kEndp = ylen;
2749   for (i = 0 ; i < rlen ; i++) {
2750     yc->rAttr[i] = additionalflag;
2751   }
2752   yc->rAttr[0] |= SENTOU;
2753   yc->rAttr[i] = SENTOU;
2754   for (i = 0 ; i < ylen ; i++) {
2755     yc->kAttr[i] = HENKANSUMI | additionalflag;
2756   }
2757   yc->kAttr[0] |= SENTOU;
2758   yc->kAttr[i] = SENTOU;
2759 }
2760 
2761 /*
2762   KanaDeletePrevious -- �����ʤȤ�����Ȥ��롣
2763 
2764 */
2765 
KanaDeletePrevious(d)2766 KanaDeletePrevious(d)/* ��������κ���ʸ���κ�� */
2767 uiContext d;
2768 {
2769   int howManyDelete;
2770   int prevflag;
2771   yomiContext yc = (yomiContext)d->modec;
2772 
2773   /* ��������κ�¦��������Τ�������������κ�¦��
2774 
2775     (1) ���޻������Ѵ�������ξ��֤Ǥ��ꡢ����ե��٥åȤˤʤäƤ������
2776     (2) ��Ƭ�Ǥ���Ȥ�
2777 
2778     �ʤɤ��ͤ����롣(�פ���������Ƥ��ʤ��ΤǤ�äȤ��ꤽ��)
2779    */
2780 
2781   if (!yc->kCurs) { /* ��ü�ΤȤ� */
2782     d->kanji_status_return->length = -1;
2783     return 0;
2784   }
2785   yc->last_rule = 0;
2786   howManyDelete = howFarToGoBackward(yc);
2787   if (howManyDelete > 0 && (yc->generalFlags & CANNA_YOMI_BREAK_ROMAN)) {
2788     yc->generalFlags &= ~CANNA_YOMI_BREAK_ROMAN;
2789     yc->rStartp = yc->rCurs - 1;
2790     while ( yc->rStartp > 0 && !(yc->rAttr[yc->rStartp] & SENTOU) ) {
2791       yc->rStartp--;
2792     }
2793     romajiReplace (-1, (wchar_t *)NULL, 0, 0);
2794     yc->kRStartp = yc->kCurs - 1;
2795     while ( yc->kRStartp > 0 && !(yc->kAttr[yc->kRStartp] & SENTOU) )
2796       yc->kRStartp--;
2797     prevflag = (yc->kAttr[yc->kRStartp] & SENTOU);
2798     kanaReplace(yc->kRStartp - yc->kCurs,
2799 		yc->romaji_buffer + yc->rStartp,
2800 		yc->rCurs - yc->rStartp,
2801 		0);
2802     yc->kAttr[yc->kRStartp] |= prevflag;
2803     yc->n_susp_chars = 0; /* �Ȥꤢ�������ꥢ���Ƥ��� */
2804     makePhonoOnBuffer(d, yc, (unsigned char)0, 0, 0);
2805   }
2806   else {
2807     if ( yc->kAttr[yc->kCurs - howManyDelete] & HENKANSUMI ) {
2808       if (yc->kAttr[yc->kCurs - howManyDelete] & SENTOU) {
2809 	/* ���޻������Ѵ�����Ƭ���ä��� */
2810 	if (yc->kAttr[yc->kCurs] & SENTOU) {
2811 	  int n;
2812 
2813 	  /* ��Ƭ���ä�����޻�����Ƭ�ޡ�����Ω�äƤ���Ȥ���ޤ��᤹ */
2814 
2815 	  for (n = 1 ; yc->rCurs > 0 && !(yc->rAttr[--yc->rCurs] & SENTOU) ;) {
2816 	    n++;
2817 	  }
2818 	  moveStrings(yc->romaji_buffer, yc->rAttr,
2819 		      yc->rCurs + n, yc->rEndp,-n);
2820 	  if (yc->rCurs < yc->rStartp) {
2821 	    yc->rStartp = yc->rCurs;
2822 	  }
2823 	  yc->rEndp -= n;
2824 	}
2825 	else {
2826 	  yc->kAttr[yc->kCurs] |= SENTOU;
2827 	}
2828       }
2829     }
2830     else {
2831       romajiReplace(-howManyDelete, (wchar_t *)NULL, 0, 0);
2832     }
2833     kanaReplace(-howManyDelete, (wchar_t *)NULL, 0, 0);
2834   }
2835   debug_yomi(yc);
2836   return(0);
2837 }
2838 
2839 static YomiDeletePrevious pro((uiContext));
2840 
2841 static int
YomiDeletePrevious(d)2842 YomiDeletePrevious(d)
2843 uiContext d;
2844 {
2845   yomiContext yc = (yomiContext)d->modec;
2846 
2847   KanaDeletePrevious(d);
2848   if (!yc->kEndp) {
2849     if (yc->savedFlags & CANNA_YOMI_MODE_SAVED) {
2850       restoreFlags(yc);
2851     }
2852     if (yc->left || yc->right) {
2853       removeCurrentBunsetsu(d, (tanContext)yc);
2854       yc = (yomiContext)0;
2855     }
2856     else {
2857       /* ̤����ʸ���������ʤ��ʤä��Τʤ顢�ե⡼�ɤ����ܤ��� */
2858       restoreChikujiIfBaseChikuji(yc);
2859       d->current_mode = yc->curMode = yc->myEmptyMode;
2860       d->kanji_status_return->info |= KanjiEmptyInfo;
2861     }
2862     currentModeInfo(d);
2863   }
2864   else {
2865     if (yc->kCurs != yc->kRStartp) {
2866       ReCheckStartp(yc);
2867     }
2868   }
2869 
2870   if (yc) {
2871     fitmarks(yc);
2872   }
2873 
2874   makeYomiReturnStruct(d);
2875   return 0;
2876 }
2877 
2878 static YomiDeleteNext pro((uiContext));
2879 
2880 static int
YomiDeleteNext(d)2881 YomiDeleteNext(d)/* ����������ʸ���κ�� */
2882 uiContext d;
2883 {
2884   int howManyDelete;
2885   yomiContext yc = (yomiContext)d->modec;
2886 
2887   if (chikujip(yc) && (yc->status & CHIKUJI_ON_BUNSETSU)) {
2888     return NothingChangedWithBeep(d);
2889   }
2890 
2891   if (yc->kCurs == yc->kEndp) {
2892     /* ��ü������ʤˤ⤷�ʤ��ΤǤ��礦�ͤ� */
2893     d->kanji_status_return->length = -1;
2894     return 0;
2895   }
2896 
2897   fitmarks(yc);
2898 
2899   yc->last_rule = 0;
2900   howManyDelete = howFarToGoForward(yc);
2901 
2902   if (yc->kAttr[yc->kCurs] & SENTOU) {
2903     if (yc->kAttr[yc->kCurs + howManyDelete] & SENTOU) {
2904       int n = 1;
2905       while ( !(yc->rAttr[++yc->rCurs] & SENTOU) )
2906 	n++;
2907       moveStrings(yc->romaji_buffer, yc->rAttr, yc->rCurs, yc->rEndp, -n);
2908       yc->rCurs -= n;
2909       yc->rEndp -= n;
2910     }
2911     else {
2912       yc->kAttr[yc->kCurs + howManyDelete] |= SENTOU;
2913     }
2914   }
2915   kanaReplace(howManyDelete, (wchar_t *)NULL, 0, 0);
2916   /* �����ޤǺ������ */
2917 
2918   if (yc->cStartp < yc->kEndp) { /* �ɤߤ��ޤ����� */
2919     if (yc->kCurs < yc->ys) {
2920       yc->ys = yc->kCurs; /* ����ʤ��Ǥ����ΤǤ��礦���� */
2921     }
2922   }
2923   else if (yc->nbunsetsu) { /* �ɤߤϤʤ���ʸ��Ϥ��� */
2924     if (RkwGoTo(yc->context, yc->nbunsetsu - 1) == -1) {
2925       return makeRkError(d, "\312\270\300\341\244\316\260\334\306\260\244\313"
2926 	"\274\272\307\324\244\267\244\336\244\267\244\277");
2927                             /* ʸ��ΰ�ư�˼��Ԥ��ޤ��� */
2928     }
2929     yc->kouhoCount = 0;
2930     yc->curbun = yc->nbunsetsu - 1;
2931     moveToChikujiTanMode(d);
2932   }
2933   else { /* �ɤߤ�ʸ���ʤ� */
2934     if (yc->savedFlags & CANNA_YOMI_MODE_SAVED) {
2935       restoreFlags(yc);
2936     }
2937     if (yc->left || yc->right) {
2938       removeCurrentBunsetsu(d, (tanContext)yc);
2939     }
2940     else {
2941       /* ̤����ʸ���������ʤ��ʤä��Τʤ顢�ե⡼�ɤ����ܤ��� */
2942       restoreChikujiIfBaseChikuji(yc);
2943       d->current_mode = yc->curMode = yc->myEmptyMode;
2944       d->kanji_status_return->info |= KanjiEmptyInfo;
2945     }
2946     currentModeInfo(d);
2947   }
2948   makeYomiReturnStruct(d);
2949   return 0;
2950 }
2951 
2952 static YomiKillToEndOfLine pro((uiContext));
2953 
2954 static int
YomiKillToEndOfLine(d)2955 YomiKillToEndOfLine(d)  /* �������뤫�鱦�Τ��٤Ƥ�ʸ���κ�� */
2956 uiContext d;
2957 {
2958   yomiContext yc = (yomiContext)d->modec;
2959 
2960   romajiReplace (yc->rEndp - yc->rCurs, (wchar_t *)NULL, 0, 0);
2961   kanaReplace   (yc->kEndp - yc->kCurs, (wchar_t *)NULL, 0, 0);
2962 
2963   fitmarks(yc);
2964 
2965   if (!yc->kEndp) {
2966     if (yc->savedFlags & CANNA_YOMI_MODE_SAVED) {
2967       restoreFlags(yc);
2968     }
2969     if (yc->left || yc->right) {
2970       removeCurrentBunsetsu(d, (tanContext)yc);
2971     }
2972     else {
2973       /* ̤����ʸ���������ʤ��ʤä��Τʤ顢�ե⡼�ɤ����ܤ��� */
2974       restoreChikujiIfBaseChikuji(yc);
2975       d->current_mode = yc->curMode = yc->myEmptyMode;
2976       d->kanji_status_return->info |= KanjiEmptyInfo;
2977     }
2978     currentModeInfo(d);
2979   }
2980   makeYomiReturnStruct(d);
2981   return 0;
2982 }
2983 
2984 static YomiQuit pro((uiContext));
2985 
2986 static int
YomiQuit(d)2987 YomiQuit(d)/* �ɤߤμ��ä� */
2988 uiContext d;
2989 {
2990   yomiContext yc = (yomiContext)d->modec;
2991 
2992   /* ̤����ʸ����������� */
2993   RomajiClearYomi(d);
2994 
2995   if (yc->left || yc->right) {
2996     removeCurrentBunsetsu(d, (tanContext)yc);
2997   }
2998   else {
2999     /* ̤����ʸ���������ʤ��ʤä��Τǡ��ե⡼�ɤ����ܤ��� */
3000     restoreChikujiIfBaseChikuji(yc);
3001     d->current_mode = yc->curMode = yc->myEmptyMode;
3002     d->kanji_status_return->info |= KanjiEmptyInfo;
3003   }
3004   makeYomiReturnStruct(d);
3005   currentModeInfo(d);
3006   return checkIfYomiQuit(d, 0);
3007 }
3008 
3009 coreContext
newCoreContext()3010 newCoreContext()
3011 {
3012   coreContext cc;
3013 
3014   cc = (coreContext)malloc(sizeof(coreContextRec));
3015   if (cc) {
3016     cc->id = CORE_CONTEXT;
3017   }
3018   return cc;
3019 }
3020 
3021 static simplePopCallback pro((uiContext, int, mode_context));
3022 
3023 static
simplePopCallback(d,retval,env)3024 simplePopCallback(d, retval, env)
3025 uiContext d;
3026 int retval;
3027 mode_context env;
3028 /* ARGSUSED */
3029 {
3030   popCallback(d);
3031   currentModeInfo(d);
3032   return retval;
3033 }
3034 
alphaMode(d)3035 alphaMode(d)
3036 uiContext d;
3037 {
3038   extern KanjiModeRec alpha_mode;
3039   coreContext cc;
3040   char *bad = "\245\341\245\342\245\352\244\254\302\255\244\352\244\336"
3041 	"\244\273\244\363";
3042               /* ���꤬­��ޤ��� */
3043 
3044   cc = newCoreContext();
3045   if (cc == (coreContext)0) {
3046     makeGLineMessageFromString(d, bad);
3047     return 0;
3048   }
3049   if (pushCallback(d, d->modec,
3050 		   NO_CALLBACK, simplePopCallback,
3051                    simplePopCallback, NO_CALLBACK) == 0) {
3052     freeCoreContext(cc);
3053     makeGLineMessageFromString(d, bad);
3054     return 0;
3055   }
3056   cc->prevMode = d->current_mode;
3057   cc->next = d->modec;
3058   cc->majorMode =
3059     cc->minorMode = CANNA_MODE_AlphaMode;
3060   d->current_mode = &alpha_mode;
3061   d->modec = (mode_context)cc;
3062   return 0;
3063 }
3064 
3065 /* Quoted Insert Mode -- �������ϥ⡼�ɡ�
3066 
3067    ���Υ⡼�ɤǤϼ��ΰ�ʸ�����ݱ�̵���ˤ��Τޤ����Ϥ���롣
3068 
3069  */
3070 
3071 static exitYomiQuotedInsert pro((uiContext, int, mode_context));
3072 
3073 static
exitYomiQuotedInsert(d,retval,env)3074 exitYomiQuotedInsert(d, retval, env)
3075 uiContext d;
3076 int retval;
3077 mode_context env;
3078 /* ARGSUSED */
3079 {
3080   popCallback(d);
3081   return retval;
3082 }
3083 
3084 static
YomiInsertQuoted(d)3085 YomiInsertQuoted(d)
3086 uiContext d;
3087 {
3088   unsigned char ch;
3089   coreContext cc = (coreContext)d->modec;
3090   yomiContext yc;
3091 
3092   ch = (unsigned char)*(d->buffer_return);
3093 
3094   if (IrohaFunctionKey(ch)) {
3095     d->kanji_status_return->length = -1;
3096     d->kanji_status_return->info = 0;
3097     return 0;
3098   } else {
3099     d->current_mode = cc->prevMode;
3100     d->modec = cc->next;
3101     free(cc);
3102 
3103     yc = (yomiContext)d->modec;
3104 
3105     romajiReplace (0, d->buffer_return, d->nbytes, 0);
3106     kanaReplace   (0, d->buffer_return, d->nbytes, HENKANSUMI);
3107     yc->rStartp = yc->rCurs;
3108     yc->kRStartp = yc->kCurs;
3109     makeYomiReturnStruct(d);
3110     currentModeInfo(d);
3111     d->status = EXIT_CALLBACK;
3112     return 0;
3113   }
3114 }
3115 
3116 static yomiquotedfunc pro((uiContext, KanjiMode, int, int, int));
3117 
3118 static
yomiquotedfunc(d,mode,whattodo,key,fnum)3119 yomiquotedfunc(d, mode, whattodo, key, fnum)
3120      uiContext d;
3121      KanjiMode mode;
3122      int whattodo;
3123      int key;
3124      int fnum;
3125      /* ARGSUSED */
3126 {
3127   switch (whattodo) {
3128   case KEY_CALL:
3129     return YomiInsertQuoted(d);
3130   case KEY_CHECK:
3131     return 1;
3132   case KEY_SET:
3133     return 0;
3134   }
3135   /* NOTREACHED */
3136 }
3137 
3138 static KanjiModeRec yomi_quoted_insert_mode = {
3139   yomiquotedfunc,
3140   0, 0, 0,
3141 };
3142 
3143 static void
yomiQuotedInsertMode(d)3144 yomiQuotedInsertMode(d)
3145 uiContext d;
3146 {
3147   coreContext cc;
3148 
3149   cc = newCoreContext();
3150   if (cc == 0) {
3151     NothingChangedWithBeep(d);
3152     return;
3153   }
3154   cc->prevMode = d->current_mode;
3155   cc->next = d->modec;
3156   cc->majorMode = d->majorMode;
3157   cc->minorMode = CANNA_MODE_QuotedInsertMode;
3158   if (pushCallback(d, d->modec,
3159                    NO_CALLBACK, exitYomiQuotedInsert,
3160                    NO_CALLBACK, NO_CALLBACK) == (struct callback *)0) {
3161     freeCoreContext(cc);
3162     NothingChangedWithBeep(d);
3163     return;
3164   }
3165   d->modec = (mode_context)cc;
3166   d->current_mode = &yomi_quoted_insert_mode;
3167   currentModeInfo(d);
3168   return;
3169 }
3170 
YomiQuotedInsert(d)3171 YomiQuotedInsert(d)
3172 uiContext d;
3173 {
3174   yomiContext yc = (yomiContext)d->modec;
3175 
3176   d->nbytes = 0;
3177 
3178   if (yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) {
3179     if (yc->status & CHIKUJI_ON_BUNSETSU) {
3180       if (yc->kEndp != yc->kCurs) {
3181 	yc->rStartp = yc->rCurs = yc->rEndp;
3182 	yc->kRStartp = yc->kCurs = yc->kEndp;
3183       }
3184       yc->status &= ~CHIKUJI_ON_BUNSETSU;
3185       yc->status |= CHIKUJI_OVERWRAP;
3186     }
3187     else if (yc->rEndp == yc->rCurs) {
3188       yc->status &= ~CHIKUJI_OVERWRAP;
3189     }
3190   }
3191 
3192   if (forceRomajiFlushYomi(d))
3193     return(d->nbytes);
3194 
3195   fitmarks(yc);
3196 
3197   yomiQuotedInsertMode(d);
3198   d->kanji_status_return->length = -1;
3199   return 0;
3200 }
3201 
3202 static int
mapAsKuten(d)3203 mapAsKuten(d)
3204      uiContext d;
3205 {
3206   yomiContext yc = (yomiContext)d->modec;
3207   int i, j, ch, len, clen, kanalen, pos;
3208   char tmpbuf[4];
3209   wchar_t *hexbuf;
3210   wchar_t buf[2];
3211   static allowTwoByte = 1;
3212 
3213   tmpbuf[0] = tmpbuf[1] = tmpbuf[2] = tmpbuf[3] = '\0';
3214 
3215   if (yc->kCurs < yc->cmark) {
3216     int tmp = yc->kCurs;
3217     yc->kCurs = yc->cmark;
3218     yc->cmark = tmp;
3219     kPos2rPos(yc, 0, yc->kCurs, (int *) 0, &tmp);
3220     yc->rCurs = tmp;
3221   }
3222   else if (yc->kCurs == yc->cmark) {
3223     yc->kCurs = yc->kRStartp = yc->kEndp;
3224     yc->rCurs = yc->rStartp = yc->rEndp;
3225   }
3226 
3227   if (*yc->romaji_buffer == 'x' || *yc->romaji_buffer == 'X')
3228     len = yc->rCurs - 1;
3229   else
3230     len = yc->rCurs;
3231   if (len > 6) {
3232     return 0;
3233   }
3234   hexbuf = yc->romaji_buffer + yc->rCurs - len;
3235 
3236   kPos2rPos(yc, 0, yc->cmark, (int *) 0, &pos);
3237 
3238   if (hexbuf < yc->romaji_buffer + pos) {
3239     if (hexbuf + 6 < yc->romaji_buffer + pos) {
3240       return 0;
3241     }
3242   }
3243   for (i = 0, j = 1; i < len; i++) {
3244     ch = *(hexbuf + i);
3245     if ('0' <= ch && ch <= '9')
3246       tmpbuf[j] = tmpbuf[j] * 10 + (ch - '0');
3247     else if (ch == '-' && j == 1)
3248       j++;
3249     else
3250       return 0;
3251   }
3252   tmpbuf[2] = (char)((0x80 | tmpbuf[2]) + 0x20);
3253   if (tmpbuf[1] < 0x5f) {
3254     tmpbuf[1] = (char)((0x80 | tmpbuf[1]) + 0x20);
3255   }
3256   else {
3257     tmpbuf[1] = (char)((0x80 | tmpbuf[1]) - 0x5e + 0x20);
3258     tmpbuf[0] = (char)0x8f; /* SS3 */
3259   }
3260   if ((unsigned char)tmpbuf[1] < 0xa1 ||
3261       0xfe < (unsigned char)tmpbuf[1] ||
3262       (len > 2 && ((unsigned char)tmpbuf[2] < 0xa1 ||
3263                    0xfe < (unsigned char)tmpbuf[2]))) {
3264     return 0;
3265   }
3266   if (hexbuf[-1] == 'x' || hexbuf[-1] == 'X') {
3267     tmpbuf[0] = (char)0x8f;/*SS3*/
3268     len++;
3269   }
3270   if (tmpbuf[0]) {
3271     clen = MBstowcs(buf, tmpbuf, 2);
3272   }
3273   else {
3274     clen = MBstowcs(buf, tmpbuf + 1, 2);
3275   }
3276   for (i = 0, kanalen = 0 ; i < len ; i++) {
3277     if (yc->rAttr[yc->rCurs - len + i] & SENTOU) {
3278       do {
3279 	kanalen++;
3280       } while (!(yc->kAttr[yc->kCurs - kanalen] & SENTOU));
3281       yc->rAttr[yc->rCurs - len + i] &= ~SENTOU;
3282     }
3283   }
3284   yc->rAttr[yc->rCurs - len] |= SENTOU;
3285   kanaReplace(-kanalen, buf, clen, HENKANSUMI);
3286   yc->kAttr[yc->kCurs - clen] |= SENTOU;
3287   yc->kRStartp = yc->kCurs;
3288   yc->rStartp = yc->rCurs;
3289   yc->pmark = yc->cmark;
3290   yc->cmark = yc->kCurs;
3291   yc->n_susp_chars = 0; /* �����ڥ�ɤ��Ƥ���ʸ���������礬����Τǥ��ꥢ */
3292   return 1;
3293 }
3294 
3295 static int
mapAsHex(d)3296 mapAsHex(d)
3297      uiContext d;
3298 {
3299   yomiContext yc = (yomiContext)d->modec;
3300   int i, ch, len = 4, clen, kanalen, pos;
3301   char tmpbuf[8], *a;
3302   wchar_t *hexbuf;
3303   wchar_t buf[2];
3304   static allowTwoByte = 1;
3305   extern struct CannaConfig cannaconf;
3306 
3307   if (yc->kCurs < yc->cmark) {
3308     int tmp = yc->kCurs;
3309     yc->kCurs = yc->cmark;
3310     yc->cmark = tmp;
3311     kPos2rPos(yc, 0, yc->kCurs, (int *)0, &tmp);
3312     yc->rCurs = tmp;
3313   }
3314   else if (yc->kCurs == yc->cmark) {
3315     yc->kCurs = yc->kRStartp = yc->kEndp;
3316     yc->rCurs = yc->rStartp = yc->rEndp;
3317   }
3318 
3319   hexbuf = yc->romaji_buffer + yc->rCurs - 4;
3320 
3321   kPos2rPos(yc, 0, yc->cmark, (int *)0, &pos);
3322 
3323   if (hexbuf < yc->romaji_buffer + pos) {
3324     if (!allowTwoByte || hexbuf + 2 < yc->romaji_buffer + pos) {
3325       return 0;
3326     }
3327     hexbuf += 2;
3328     len = 2;
3329   }
3330  retry:
3331   for (i = 0, a = tmpbuf + 1; i < len ; i++) {
3332     ch = *(hexbuf + i);
3333     if ('0' <= ch && ch <= '9')
3334       ch -= '0';
3335     else if ('A' <= ch && ch <= 'F')
3336       ch -= 'A' - 10;
3337     else if ('a' <= ch && ch <= 'f')
3338       ch -= 'a' - 10;
3339     else if (allowTwoByte && i < 2 && 2 < len) {
3340       hexbuf += 2;
3341       len = 2;
3342       goto retry;
3343     }
3344     else {
3345       return 0;
3346     }
3347     *a++ = ch;
3348   }
3349   if (cannaconf.code_input == CANNA_CODE_SJIS) { /* sjis �����ɤ��ä��� */
3350     char eucbuf[4];  /* SS3 �Τ��Ȥ����뤿�� */
3351 
3352     tmpbuf[1] = tmpbuf[1] * 16 + tmpbuf[2];
3353     if (len > 2) {
3354       tmpbuf[2] = tmpbuf[3] * 16 + tmpbuf[4];
3355       tmpbuf[3] = '\0';
3356     }
3357     else {
3358       tmpbuf[2] = '\0';
3359     }
3360     if ((unsigned char)tmpbuf[1] < 0x81 ||
3361         (0x9f < (unsigned char)tmpbuf[1] && (unsigned char)tmpbuf[1] < 0xe0) ||
3362         0xfc < (unsigned char)tmpbuf[1] ||
3363         (len > 2 && ((unsigned char)tmpbuf[2] < 0x40 ||
3364                      0xfc < (unsigned char)tmpbuf[2] ||
3365                      (unsigned char)tmpbuf[2] == 0x7f))) {
3366       return 0;
3367     }
3368     RkCvtEuc((unsigned char *)eucbuf, sizeof(eucbuf),
3369                         (unsigned char *)tmpbuf + 1, 2);
3370     clen = MBstowcs(buf, eucbuf, 2);
3371   }
3372   else {
3373     tmpbuf[1] = 0x80 | (tmpbuf[1] * 16 + tmpbuf[2]);
3374     if (len > 2) {
3375       tmpbuf[2] = 0x80 | (tmpbuf[3] * 16 + tmpbuf[4]);
3376       tmpbuf[3] = '\0';
3377     }
3378     else {
3379       tmpbuf[2] = '\0';
3380     }
3381     if ((unsigned char)tmpbuf[1] < 0xa1 ||
3382         0xfe < (unsigned char)tmpbuf[1] ||
3383         (len > 2 && ((unsigned char)tmpbuf[2] < 0xa1 ||
3384                       0xfe < (unsigned char)tmpbuf[2]))) {
3385       return 0;
3386     }
3387     if (len == 2) {
3388       tmpbuf[1] &= 0x7f;
3389     }
3390     if (hexbuf > yc->romaji_buffer
3391         && len > 2 && (hexbuf[-1] == 'x' || hexbuf[-1] == 'X')) {
3392       tmpbuf[0] = (char)0x8f;/*SS3*/
3393       len++;
3394       clen = MBstowcs(buf, tmpbuf, 2);
3395     }
3396     else {
3397       clen = MBstowcs(buf, tmpbuf + 1, 2);
3398     }
3399   }
3400   for (i = 0, kanalen = 0 ; i < len ; i++) {
3401     if (yc->rAttr[yc->rCurs - len + i] & SENTOU) {
3402       do {
3403 	kanalen++;
3404       } while (!(yc->kAttr[yc->kCurs - kanalen] & SENTOU));
3405       yc->rAttr[yc->rCurs - len + i] &= ~SENTOU;
3406     }
3407   }
3408   yc->rAttr[yc->rCurs - len] |= SENTOU;
3409   kanaReplace(-kanalen, buf, clen, HENKANSUMI);
3410   yc->kAttr[yc->kCurs - clen] |= SENTOU;
3411   yc->kRStartp = yc->kCurs;
3412   yc->rStartp = yc->rCurs;
3413   yc->pmark = yc->cmark;
3414   yc->cmark = yc->kCurs;
3415   yc->n_susp_chars = 0; /* �����ڥ�ɤ��Ƥ���ʸ���������礬����Τǥ��ꥢ */
3416   return 1;
3417 }
3418 
3419 /* ConvertAsHex -- �����ʤȤߤʤ��Ƥ��Ѵ�
3420 
3421   ���޻����Ϥ����ȿžɽ������Ƥ���ʸ��������ʤ�ɽ������Ƥ��륳���ɤ�
3422   �ߤʤ����Ѵ����롣
3423 
3424   (MSB�ϣ��Ǥ⣱�Ǥ��ɤ�)
3425 
3426   */
3427 
3428 static ConvertAsHex pro((uiContext));
3429 
3430 static
ConvertAsHex(d)3431 ConvertAsHex(d)
3432 uiContext d;
3433 {
3434   yomiContext yc = (yomiContext)d->modec;
3435   extern struct CannaConfig cannaconf;
3436 
3437   if (yc->henkanInhibition & CANNA_YOMI_INHIBIT_ASHEX) {
3438     return NothingChangedWithBeep(d);
3439   }
3440   if (yc->savedFlags & CANNA_YOMI_MODE_SAVED) {
3441     restoreFlags(yc);
3442     currentModeInfo(d);
3443   }
3444   if (cannaconf.code_input != CANNA_CODE_KUTEN) {
3445     if (!mapAsHex(d)) {
3446       return NothingChangedWithBeep(d);
3447     }
3448   }
3449   else {
3450     if (!mapAsKuten(d)) {
3451       return NothingChangedWithBeep(d);
3452     }
3453   }
3454   if (yc->kCurs - 1 < yc->ys) {
3455     yc->ys = yc->kCurs - 1;
3456   }
3457   makeYomiReturnStruct(d);
3458   return 0;
3459 }
3460 
3461 /*
3462   convertAsHex  �����ʤο��������ʸ�����Ѵ�
3463 
3464   ���������Ū�˻��Ѥ��뤿��Υ롼����Ǥ��롣d->romaji_buffer �˴ޤ�
3465   ���ʸ��������ʤ�ɽ���줿���������ɤǤ���Ȥߤʤ��ơ����Υ����ɤ�
3466   ��ä�ɽ����������ʸ�����Ѵ����롣�Ѵ�����ʸ����� buffer_return
3467   �˳�Ǽ���롣�꥿�����ͤϥ��顼���ʤ���� buffer_return �˳�Ǽ����ʸ
3468   �����Ĺ���Ǥ���(�̾�ϣ��Ǥ���)�����顼��ȯ�����Ƥ�����ϡݣ�����Ǽ
3469   ����롣
3470 
3471   �⡼�ɤ��ѹ����ν����Ϥ��δؿ��ǤϹԤ��ʤ���
3472 
3473   �ޤ��Хåե��Υ��ꥢ�ʤɤ�Ԥ�ʤ��Τ���դ���٤��Ǥ��롣
3474 
3475   <�����>
3476     �����������ʤ��Ѵ��Ǥ������ϣ������Ǥʤ����ϣ����֤롣
3477 */
3478 
3479 int
cvtAsHex(d,buf,hexbuf,hexlen)3480 cvtAsHex(d, buf, hexbuf, hexlen)
3481 uiContext d;
3482 wchar_t *buf, *hexbuf;
3483 int hexlen;
3484 {
3485   int i;
3486   char tmpbuf[5], *a, *b;
3487   wchar_t rch;
3488 
3489   if (hexlen != 4) { /* ���Ϥ��줿ʸ�����Ĺ������ʸ���Ǥʤ��ΤǤ�����Ѵ�
3490 			���Ƥ����ʤ� */
3491     d->kanji_status_return->length = -1;
3492     return 0;
3493   }
3494   for (i = 0, a = tmpbuf; i < 4 ; i++) {
3495     rch = hexbuf[i]; /* �ޤ���ʸ�����Ф��������ʤο����ˤ��롣 */
3496     if ('0' <= rch && rch <= '9') {
3497       rch -= '0';
3498     }
3499     else if ('A' <= rch && rch <= 'F') {
3500       rch -= 'A' - 10;
3501     }
3502     else if ('a' <= rch && rch <= 'f') {
3503       rch -= 'a' - 10;
3504     }
3505     else {
3506       d->kanji_status_return->length = -1;
3507       return 0;
3508     }
3509     *a++ = (char)rch; /* ��괺������¸���Ƥ��� */
3510   }
3511   b = (a = tmpbuf) + 1;
3512   *a = (char)(0x80 | (*a * 16 + *b));
3513   *(tmpbuf+1) = 0x80 | (*(a += 2) * 16 + *(b += 2));
3514   *a = '\0';
3515   if ((unsigned char)*tmpbuf < 0xa1 ||
3516       0xfe < (unsigned char)*tmpbuf ||
3517       (unsigned char)*--a < 0xa1 ||
3518       0xfe < (unsigned char)*a) {
3519     return 0;
3520   } else {
3521     MBstowcs(buf, tmpbuf, 2);
3522     return 1;
3523   }
3524 }
3525 
convertAsHex(d)3526 convertAsHex(d)
3527 uiContext d;
3528 {
3529   yomiContext yc = (yomiContext)d->modec;
3530 
3531   return cvtAsHex(d, d->buffer_return, yc->romaji_buffer, yc->rEndp);
3532 }
3533 
3534 /*
3535    ���޻������Ѵ���­�롼�����Ϣ
3536  */
3537 
3538 static void
replaceSup2(ind,n)3539 replaceSup2(ind, n)
3540 int ind, n;
3541 {
3542   int i;
3543   wchar_t *temp, **p;
3544 
3545   if (ind < 0)
3546     return;
3547 
3548   temp = (p = keysup[ind].cand)[n];
3549   for (i = n ; i > 0 ; i--) {
3550     p[i] = p[i - 1];
3551   }
3552   p[0] = temp;
3553 }
3554 
3555 static void
replaceSup(ind,n)3556 replaceSup(ind, n)
3557 int ind, n;
3558 {
3559   int i, group;
3560   extern nkeysup;
3561 
3562   group = keysup[ind].groupid;
3563   for (i = 0 ; i < nkeysup ; i++) {
3564     if (keysup[i].groupid == group) {
3565       replaceSup2(i, n);
3566     }
3567   }
3568 }
3569 
3570 static everySupkey pro((uiContext, int, mode_context));
3571 
3572 static
everySupkey(d,retval,env)3573 everySupkey(d, retval, env)
3574 uiContext d;
3575 int retval;
3576 mode_context env;
3577 /* ARGSUSED */
3578 {
3579   ichiranContext ic = (ichiranContext)d->modec;
3580   wchar_t *cur;
3581 
3582   cur = ic->allkouho[*(ic->curIkouho)];
3583   d->kanji_status_return->revPos = 0;
3584   d->kanji_status_return->revLen = 0;
3585   d->kanji_status_return->echoStr = cur;
3586   d->kanji_status_return->length = WStrlen(cur);
3587 
3588   return retval;
3589 }
3590 
3591 static exitSupkey pro((uiContext, int, mode_context));
3592 
3593 static
exitSupkey(d,retval,env)3594 exitSupkey(d, retval, env)
3595 uiContext d;
3596 int retval;
3597 mode_context env;
3598 /* ARGSUSED */
3599 {
3600   yomiContext yc;
3601 
3602   popCallback(d); /* ������ݥå� */
3603 
3604   yc = (yomiContext)d->modec;
3605 
3606   replaceSup(findSup(yc->romaji_buffer[0]) - 1, yc->cursup);
3607 
3608 #ifdef NOT_KAKUTEI
3609   yc->rCurs = yc->rStartp = yc->rEndp;
3610   yc->kCurs = yc->kEndp;
3611   kanaReplace(-yc->kEndp, d->buffer_return, retval, HENKANSUMI | SUPKEY);
3612   yc->kRStartp = yc->kCurs;
3613   yc->kAttr[0] |= SENTOU;
3614   yc->rAttr[0] |= SENTOU | HENKANSUMI;
3615   for (i = 1 ; i < retval ; i++) {
3616     yc->kAttr[i] &= ~SENTOU;
3617   }
3618   currentModeInfo(d);
3619   makeYomiReturnStruct(d);
3620   return 0;
3621 #else
3622   /* ̤����ʸ����������� */
3623   RomajiClearYomi(d);
3624 
3625   /* ̤����ʸ���������ʤ��ʤä��Τǡ��ե⡼�ɤ����ܤ��� */
3626   restoreChikujiIfBaseChikuji(yc);
3627   d->current_mode = yc->curMode = yc->myEmptyMode;
3628   d->kanji_status_return->info |= KanjiEmptyInfo;
3629   currentModeInfo(d);
3630   makeYomiReturnStruct(d);
3631   return checkIfYomiQuit(d, retval);
3632 #endif
3633 }
3634 
3635 static quitSupkey pro((uiContext, int, mode_context));
3636 
3637 static
quitSupkey(d,retval,env)3638 quitSupkey(d, retval, env)
3639 uiContext d;
3640 int retval;
3641 mode_context env;
3642 /* ARGSUSED */
3643 {
3644   popCallback(d); /* ������ݥå� */
3645   makeYomiReturnStruct(d);
3646   currentModeInfo(d);
3647   return retval;
3648 }
3649 
selectKeysup(d,yc,ind)3650 selectKeysup(d, yc, ind)
3651 uiContext d;
3652 yomiContext yc;
3653 int ind;
3654 {
3655   int retval;
3656   ichiranContext ic;
3657   extern nkeysup;
3658 
3659   yc->cursup = 0;
3660   retval = selectOne(d, keysup[ind].cand, &(yc->cursup), keysup[ind].ncand,
3661 		     BANGOMAX,
3662 		     (unsigned)(!cannaconf.HexkeySelect ? NUMBERING : 0),
3663 		     0, WITH_LIST_CALLBACK,
3664 		     everySupkey, exitSupkey, quitSupkey, NO_CALLBACK);
3665 
3666   ic = (ichiranContext)d->modec;
3667   ic->majorMode = CANNA_MODE_IchiranMode;
3668   ic->minorMode = CANNA_MODE_IchiranMode;
3669 
3670   currentModeInfo(d);
3671   *(ic->curIkouho) = 0;
3672 
3673   /* ��������Ԥ������Ƹ���������Ф��ʤ� */
3674   if(ic->tooSmall) {
3675     d->status = AUX_CALLBACK;
3676     return(retval);
3677   }
3678 
3679   if ( !(ic->flags & ICHIRAN_ALLOW_CALLBACK) ) {
3680     makeGlineStatus(d);
3681   }
3682 
3683   return retval;
3684 }
3685 
3686 /*
3687   ������Ѵ�����褦�ʥ꡼�����ˤʤäƤ��뤫��
3688 
3689   �ɤ�ʤ��Ȥ�Ĵ�٤뤫�ȸ����ȡ��ޤ����꡼������⤬������Ѵ�����Ƥ�
3690   �뤫�ɤ�����Ĵ�٤롣���ˡ��꡼������ξü����Ƭʸ���ˤʤäƤ��뤳��
3691   ��Ĵ�٤����Ȥ������������Ϥ�äѤ�Ϥ�������
3692 
3693   ���������椫��Ȥ�����ޤǤȤ��� mark ��Ԥä����ˤ���˳�����Ѵ�
3694   ��Ԥ����Ȥ��������롣
3695 
3696  */
3697 
3698 static
regionGairaigo(yc,s,e)3699 regionGairaigo(yc, s, e)
3700 yomiContext yc;
3701 int s, e;
3702 {
3703   if ((yc->kAttr[s] & SENTOU) && (yc->kAttr[e] & SENTOU)) {
3704     return 1;
3705   }
3706   else {
3707     return 0;
3708   }
3709 }
3710 
3711 
3712 /*
3713   ������Ѵ��Ѥλ������äƤ��뤫��
3714  */
3715 
3716 static int
containGairaigo(yc)3717 containGairaigo(yc)
3718 yomiContext yc;
3719 {
3720   int i;
3721 
3722   for (i = 0 ; i < yc->kEndp ; i++) {
3723     if (yc->kAttr[i] & GAIRAIGO) {
3724       return 1;
3725     }
3726   }
3727   return 0;
3728 }
3729 
containUnconvertedKey(yc)3730 containUnconvertedKey(yc)
3731 yomiContext yc;
3732 {
3733   int i, s, e;
3734 
3735   if (containGairaigo(yc)) {
3736     return 0;
3737   }
3738 
3739   if ((s = yc->cmark) > yc->kCurs) {
3740     e = s;
3741     s = yc->kCurs;
3742   }
3743   else {
3744     e = yc->kCurs;
3745   }
3746 
3747   for (i = s ; i < e ; i++) {
3748     if ( !(yc->kAttr[i] & HENKANSUMI) ) {
3749       return 1;
3750     }
3751   }
3752   return 0;
3753 }
3754 
3755 /*
3756  * ���ʴ����Ѵ���Ԥ�(�Ѵ����������Ʋ����줿)��TanKouhoMode�˰ܹԤ���
3757  *
3758  * ������	uiContext
3759  * �����	���ェλ�� 0	�۾ェλ�� -1
3760  */
3761 
3762 static YomiHenkan pro((uiContext));
3763 
3764 static int
YomiHenkan(d)3765 YomiHenkan(d)
3766 uiContext	d;
3767 {
3768   yomiContext yc = (yomiContext)d->modec;
3769   int len, idx;
3770 
3771 #ifdef MEASURE_TIME
3772   struct tms timebuf;
3773   long   currenttime, times();
3774 
3775   currenttime = times(&timebuf);
3776 #endif
3777 
3778   if (yc->henkanInhibition & CANNA_YOMI_INHIBIT_HENKAN) {
3779     return NothingChangedWithBeep(d);
3780   }
3781 
3782   d->nbytes = 0;
3783   len = RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3784 
3785   if (containUnconvertedKey(yc)) {
3786     YomiMark(d);
3787     len = RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3788   }
3789 
3790   yc->kRStartp = yc->kCurs = yc->kEndp;
3791   yc->rStartp  = yc->rCurs = yc->rEndp;
3792 
3793   if (len == 0) { /* empty �⡼�ɤ˹ԤäƤ��ޤä� */
3794     d->more.todo = 1;
3795     d->more.ch = d->ch;
3796     d->more.fnum = 0;    /* ��� ch �Ǽ������������� */
3797     return d->nbytes;
3798   }
3799 
3800   if (yc->rEndp == 1 && (yc->kAttr[0] & SUPKEY) &&
3801       !yc->left && !yc->right &&
3802       (idx = findSup(yc->romaji_buffer[0])) &&
3803       keysup[idx - 1].ncand > 1) {
3804     return selectKeysup(d, yc, idx - 1);
3805   }
3806 
3807   if (!prepareHenkanMode(d)) {
3808     makeGLineMessageFromString(d, jrKanjiError);
3809     makeYomiReturnStruct(d);
3810     return 0;
3811   }
3812   yc->minorMode = CANNA_MODE_TankouhoMode;
3813   yc->kouhoCount = 1;
3814   if (doHenkan(d, 0, (wchar_t *)0) < 0) {
3815     makeGLineMessageFromString(d, jrKanjiError);
3816     return TanMuhenkan(d);
3817   }
3818   if (cannaconf.kouho_threshold > 0 &&
3819       yc->kouhoCount >= cannaconf.kouho_threshold) {
3820     return tanKouhoIchiran(d, 0);
3821   }
3822   currentModeInfo(d);
3823 
3824 #ifdef MEASURE_TIME
3825   hc->proctime = times(&timebuf);
3826   hc->proctime -= currenttime;
3827 #endif
3828 
3829   return 0;
3830 }
3831 
3832 static YomiHenkanNaive pro((uiContext));
3833 
3834 static int
YomiHenkanNaive(d)3835 YomiHenkanNaive(d)
3836 uiContext	d;
3837 {
3838   yomiContext yc = (yomiContext)d->modec;
3839 
3840   if (yc->generalFlags &
3841       (CANNA_YOMI_HANKAKU | CANNA_YOMI_ROMAJI | CANNA_YOMI_BASE_HANKAKU)) {
3842     return YomiInsert(d);
3843   }
3844   else {
3845     return YomiHenkan(d);
3846   }
3847 }
3848 
3849 static YomiHenkanOrNothing pro((uiContext));
3850 
3851 static int
YomiHenkanOrNothing(d)3852 YomiHenkanOrNothing(d)
3853 uiContext	d;
3854 {
3855   yomiContext yc = (yomiContext)d->modec;
3856 
3857   if (yc->generalFlags &
3858       (CANNA_YOMI_HANKAKU | CANNA_YOMI_ROMAJI | CANNA_YOMI_BASE_HANKAKU)) {
3859     return NothingChanged(d);
3860   }
3861   else {
3862     return YomiHenkan(d);
3863   }
3864 }
3865 
3866 /* �١���ʸ�����ڤ��ؤ� */
3867 
3868 extern EmptyBaseHira pro((uiContext)), EmptyBaseKata pro((uiContext));
3869 extern EmptyBaseEisu pro((uiContext));
3870 extern EmptyBaseZen pro((uiContext)), EmptyBaseHan pro((uiContext));
3871 
3872 static YomiBaseHira pro((uiContext));
3873 
3874 static
YomiBaseHira(d)3875 YomiBaseHira(d)
3876 uiContext d;
3877 {
3878   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3879   (void)EmptyBaseHira(d);
3880   makeYomiReturnStruct(d);
3881   return 0;
3882 }
3883 
3884 static YomiBaseKata pro((uiContext));
3885 
3886 static
YomiBaseKata(d)3887 YomiBaseKata(d)
3888 uiContext d;
3889 {
3890   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3891   (void)EmptyBaseKata(d);
3892   makeYomiReturnStruct(d);
3893   return 0;
3894 }
3895 
3896 static YomiBaseEisu pro((uiContext));
3897 
3898 static
YomiBaseEisu(d)3899 YomiBaseEisu(d)
3900 uiContext d;
3901 {
3902   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3903   (void)EmptyBaseEisu(d);
3904   makeYomiReturnStruct(d);
3905   return 0;
3906 }
3907 
3908 static YomiBaseZen pro((uiContext));
3909 
3910 static
YomiBaseZen(d)3911 YomiBaseZen(d)
3912 uiContext d;
3913 {
3914   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3915   (void)EmptyBaseZen(d);
3916   makeYomiReturnStruct(d);
3917   return 0;
3918 }
3919 
3920 static YomiBaseHan pro((uiContext));
3921 
3922 static
YomiBaseHan(d)3923 YomiBaseHan(d)
3924 uiContext d;
3925 {
3926   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3927   (void)EmptyBaseHan(d);
3928   makeYomiReturnStruct(d);
3929   return 0;
3930 }
3931 
3932 static YomiBaseKana pro((uiContext));
3933 
3934 static
YomiBaseKana(d)3935 YomiBaseKana(d)
3936 uiContext d;
3937 {
3938   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3939   (void)EmptyBaseKana(d);
3940   makeYomiReturnStruct(d);
3941   return 0;
3942 }
3943 
3944 static YomiBaseKakutei pro((uiContext));
3945 
3946 static
YomiBaseKakutei(d)3947 YomiBaseKakutei(d)
3948 uiContext d;
3949 {
3950   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3951   (void)EmptyBaseKakutei(d);
3952   makeYomiReturnStruct(d);
3953   return 0;
3954 }
3955 
3956 static YomiBaseHenkan pro((uiContext));
3957 
3958 static
YomiBaseHenkan(d)3959 YomiBaseHenkan(d)
3960 uiContext d;
3961 {
3962   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3963   (void)EmptyBaseHenkan(d);
3964   makeYomiReturnStruct(d);
3965   return 0;
3966 }
3967 
3968 int YomiBaseHiraKataToggle pro((uiContext));
3969 
YomiBaseHiraKataToggle(d)3970 YomiBaseHiraKataToggle(d)
3971 uiContext d;
3972 {
3973   yomiContext yc = (yomiContext)d->modec;
3974 
3975   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3976 
3977   if (yc->generalFlags & CANNA_YOMI_KATAKANA) {
3978     (void)EmptyBaseHira(d);
3979   }
3980   else {
3981     (void)EmptyBaseKata(d);
3982   }
3983   makeYomiReturnStruct(d);
3984   return 0;
3985 }
3986 
3987 int YomiBaseZenHanToggle pro((uiContext));
3988 
YomiBaseZenHanToggle(d)3989 YomiBaseZenHanToggle(d)
3990 uiContext d;
3991 {
3992   yomiContext yc = (yomiContext)d->modec;
3993 
3994   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
3995 
3996   if (yc->generalFlags & CANNA_YOMI_BASE_HANKAKU) {
3997     (void)EmptyBaseZen(d);
3998   }
3999   else {
4000     (void)EmptyBaseHan(d);
4001   }
4002   makeYomiReturnStruct(d);
4003   return 0;
4004 }
4005 
4006 int YomiBaseRotateForw pro((uiContext));
4007 
YomiBaseRotateForw(d)4008 YomiBaseRotateForw(d)
4009 uiContext d;
4010 {
4011   yomiContext yc = (yomiContext)d->modec;
4012 
4013   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
4014 
4015   if (!(yc->generalFlags & CANNA_YOMI_BASE_HANKAKU) &&
4016       ((yc->generalFlags & CANNA_YOMI_ROMAJI) ||
4017        ((yc->generalFlags & CANNA_YOMI_KATAKANA) &&
4018 	!cannaconf.InhibitHankakuKana) )) {
4019     (void)EmptyBaseHan(d);
4020   }
4021   else {
4022     yc->generalFlags &= ~CANNA_YOMI_BASE_HANKAKU;
4023     if (yc->generalFlags & CANNA_YOMI_ROMAJI) {
4024       (void)EmptyBaseHira(d);
4025     }
4026     else if (yc->generalFlags & CANNA_YOMI_KATAKANA) {
4027       (void)EmptyBaseEisu(d);
4028     }
4029     else {
4030       (void)EmptyBaseKata(d);
4031     }
4032   }
4033   makeYomiReturnStruct(d);
4034   return 0;
4035 }
4036 
4037 int YomiBaseRotateBack pro((uiContext));
4038 
YomiBaseRotateBack(d)4039 YomiBaseRotateBack(d)
4040 uiContext d;
4041 {
4042   yomiContext yc = (yomiContext)d->modec;
4043 
4044   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
4045 
4046   if (yc->generalFlags & CANNA_YOMI_BASE_HANKAKU) {
4047     (void)EmptyBaseZen(d);
4048   }
4049   else if (yc->generalFlags & CANNA_YOMI_KATAKANA) {
4050     (void)EmptyBaseHira(d);
4051   }
4052   else if (yc->generalFlags & CANNA_YOMI_ROMAJI) {
4053     if (!cannaconf.InhibitHankakuKana) {
4054       yc->generalFlags |= CANNA_YOMI_BASE_HANKAKU;
4055     }
4056     (void)EmptyBaseKata(d);
4057   }
4058   else {
4059     yc->generalFlags &= ~CANNA_YOMI_ZENKAKU;
4060     yc->generalFlags |= CANNA_YOMI_BASE_HANKAKU;
4061     (void)EmptyBaseEisu(d);
4062   }
4063   makeYomiReturnStruct(d);
4064   return 0;
4065 }
4066 
4067 int YomiBaseKanaEisuToggle pro((uiContext));
4068 
YomiBaseKanaEisuToggle(d)4069 YomiBaseKanaEisuToggle(d)
4070 uiContext d;
4071 {
4072   yomiContext yc = (yomiContext)d->modec;
4073 
4074   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
4075 
4076   if (yc->generalFlags & CANNA_YOMI_ROMAJI) {
4077     (void)EmptyBaseKana(d);
4078   }
4079   else {
4080     (void)EmptyBaseEisu(d);
4081   }
4082   makeYomiReturnStruct(d);
4083   return 0;
4084 }
4085 
4086 int YomiBaseKakuteiHenkanToggle pro((uiContext));
4087 
YomiBaseKakuteiHenkanToggle(d)4088 YomiBaseKakuteiHenkanToggle(d)
4089 uiContext d;
4090 {
4091   yomiContext yc = (yomiContext)d->modec;
4092 
4093   (void)RomajiFlushYomi(d, d->genbuf, ROMEBUFSIZE);
4094 
4095   if (yc->generalFlags & CANNA_YOMI_KAKUTEI) {
4096     (void)EmptyBaseHenkan(d);
4097   }
4098   else { /* �����ϰ����ǤϹԤ��ʤ� */
4099     (void)EmptyBaseKakutei(d);
4100   }
4101   makeYomiReturnStruct(d);
4102   return 0;
4103 }
4104 
4105 int YomiModeBackup pro((uiContext));
4106 
YomiModeBackup(d)4107 YomiModeBackup(d)
4108 uiContext d;
4109 {
4110   yomiContext yc = (yomiContext)d->modec;
4111 
4112   (void)saveFlags(yc);
4113   return NothingChanged(d);
4114 }
4115 
4116 /* �����Ѵ���Ϣ */
4117 
4118 /* cfuncdef
4119 
4120    exitJishu -- �����Ѵ�����ꤵ����
4121 
4122    ���δؿ��ϻ����Ѵ�����ꤵ�����ɤߥ⡼�ɤ���ä��Ȥ���Ǽ¹Ԥ����
4123    �ؿ��Ǥ��롣
4124 
4125    �ڻ����Ѵ��ȤΤ���«����
4126 
4127    ���δؿ��� jishu.c �˽��Ƥ��� JishuKakutei ���ƤӽФ��줿��
4128    ���ʤɤ˸ƤӽФ����ؿ��Ǥ��롣JishuKakutei �ǤϺǽ�Ū�ʻ���
4129    �λ���䤽���ϰϤλ�������������Ǽºݤ���Ū����ؤ��Ѵ���
4130    ���δؿ��ǹԤ�ʤ���Фʤ�ʤ����ʤ����ȸ����ȥ��޻��Ȥ��б�
4131    �Ť���������ݻ����Ƥ�����������Ǥ��� JishuKakutei �Ȥδ֤�
4132    ����«�ϰʲ����̤�
4133 
4134    (1) �ǽ�Ū�ʻ���� yc �λ����Ϣ�Υ��Ф��֤����
4135    (2) ����Ū�ˤϰʲ������롣
4136        jishu_kc    �ǽ�Ū�ʻ���μ��� (JISHU_ZEN_KATA �ʤ�)
4137        jishu_case  �ǽ�Ū�ʻ���Υ����� (CANNA_JISHU_UPPER �ʤ�)
4138        jishu_kEndp �����Ѵ����о��ϰ�
4139        jishu_rEndp �����Ѵ����о��ϰϤΥ��޻��Хåե��Ǥΰ���
4140    (3) yc->cmark �ޤǤϻ��郎�֤��Ѥ��ʤ��Τ���դ��롣
4141    (4) yc->kana_buffer ���֤������� exitJishu ���Ԥ���
4142    (5) yc->kana_buffer �ǻ����Ѵ��ϰϰʳ��Τ�Τ� yc->romaji_buffer
4143        ��⤦���٥��ԡ����ƥ��޻������Ѵ�����뤳�Ȥ��դ��ä����롣
4144    (6) ��������yc->kRStartp == yc->jishu_kEndp �ʤ�о嵭�ν����ϹԤ��
4145        ����
4146    (7) �嵭���֤���ʤ���ʬ�Υ��޻��� yc->jishu_rEndp �ʹߤǤ��롣
4147    (8) exitJishu �Ϥ�����ʬ�� yc->kana_buffer �˰�ư���⤦���٥��޻�
4148        �����Ѵ���Ԥ���
4149  */
4150 
exitJishu(d)4151 exitJishu(d)
4152 uiContext d;
4153 {
4154   yomiContext yc;
4155   int len, srclen, i, pos;
4156   BYTE jishu, jishu_case, head = 1;
4157   int jishu_kEndp, jishu_rEndp;
4158   int (*func1)(), (*func2)();
4159   int RkwCvtZen(), RkwCvtKana(), RkwCvtHira(), RkwCvtHan();
4160   long savedgf;
4161   wchar_t *buf, *p;
4162 #ifndef USE_MALLOC_FOR_BIG_ARRAY
4163   wchar_t xxxx[1024];
4164 #else
4165   wchar_t *xxxx = (wchar_t *)malloc(sizeof(wchar_t) * 1024);
4166   if (!xxxx) {
4167     return 0;
4168   }
4169 #endif
4170 
4171   /* �������鲼�ϴ����ʡ��ɤߡ٥⡼�� */
4172 
4173   yc = (yomiContext)d->modec;
4174 
4175   jishu = yc->jishu_kc;
4176   jishu_case = yc->jishu_case;
4177   jishu_kEndp = yc->jishu_kEndp;
4178   jishu_rEndp = yc->jishu_rEndp;
4179 
4180   leaveJishuMode(d, yc);
4181 
4182   /* �ƥ�ݥ��⡼�ɤ��ä��鸵���᤹ */
4183   if (yc->savedFlags & CANNA_YOMI_MODE_SAVED) {
4184     restoreFlags(yc);
4185   }
4186   /* �༡���ɤߥݥ������ꥢ */
4187   yc->ys = yc->cStartp;
4188 
4189   /* �ޤ��������Ѵ����줿��ʬ���Ѵ� */
4190   buf = d->genbuf;
4191   switch (jishu) {
4192   case JISHU_ZEN_KATA: /* ���ѥ������ʤ��Ѵ����� */
4193     func1 = RkwCvtZen;
4194     func2 = RkwCvtKana;
4195     goto jishuKakuteiKana;
4196 
4197   case JISHU_HAN_KATA: /* Ⱦ�ѥ������ʤ��Ѵ����� */
4198     func1 = RkwCvtKana;
4199     func2 = RkwCvtHan;
4200     goto jishuKakuteiKana;
4201 
4202   case JISHU_HIRA: /* �Ҥ餬�ʤ��Ѵ����� */
4203     func1 = RkwCvtZen;
4204     func2 = RkwCvtHira;
4205 
4206   jishuKakuteiKana:
4207     /* �ޤ����١��������޻��ΤȤ������Ϥ��줿��Τ�����Ф��ʤ��Ѵ����� */
4208     savedgf = yc->generalFlags;
4209     yc->generalFlags = savedgf & CANNA_YOMI_IGNORE_USERSYMBOLS;
4210     for (i = yc->cmark ; i < jishu_kEndp ;) {
4211       int j = i;
4212       while (i < jishu_kEndp && yc->kAttr[i] & STAYROMAJI) {
4213 	yc->kAttr[i++] &= ~(HENKANSUMI | STAYROMAJI);
4214       }
4215       if (j < i) {
4216 	kPos2rPos(yc, j, i, &yc->rStartp, &yc->rCurs);
4217 	yc->kRStartp = j;
4218 	yc->kCurs = i;
4219 	makePhonoOnBuffer(d, yc, (unsigned char)0, RK_FLUSH, 0);
4220 	jishu_kEndp += yc->kCurs - i;
4221 	i = yc->kCurs;
4222       }
4223       else {
4224 	i++;
4225       }
4226     }
4227     yc->generalFlags = savedgf;
4228 
4229     /* �����ǡ����޻������Ѵ�ñ�̤ǻ����Ѵ����� */
4230     for (i = yc->cmark ; i < jishu_kEndp ; i = yc->kCurs) {
4231       int j;
4232 
4233       for (j = i + 1 ; !(yc->kAttr[j] & SENTOU) ;) {
4234 	j++;
4235       }
4236       if(j > jishu_kEndp) {
4237 	j = jishu_kEndp;
4238       }
4239       srclen = j - i;
4240 
4241       len = (*func1)(xxxx, 1024, yc->kana_buffer + i, srclen);
4242       len = (*func2)(buf, ROMEBUFSIZE, xxxx, len);
4243       yc->kCurs = j;
4244       kanaReplace(-srclen, buf, len, 0);
4245       jishu_kEndp += len - srclen; /* yc->kCurs - j ��Ʊ���� */
4246 
4247       for (j = yc->kCurs - len ; j < yc->kCurs ; j++) {
4248 	yc->kAttr[j] = HENKANSUMI;
4249       }
4250       yc->kAttr[yc->kCurs - len] |= SENTOU;
4251     }
4252     break;
4253 
4254   case JISHU_ZEN_ALPHA: /* ���ѱѿ����Ѵ����� */
4255   case JISHU_HAN_ALPHA: /* Ⱦ�ѱѿ����Ѵ����� */
4256     p = yc->romaji_buffer;
4257     kPos2rPos(yc, 0, yc->cmark, (int *)0, &pos);
4258 
4259     for (i = pos ; i < jishu_rEndp ; i++) {
4260       xxxx[i - pos] =
4261 	(jishu_case == CANNA_JISHU_UPPER) ? WToupper(p[i]) :
4262         (jishu_case == CANNA_JISHU_LOWER) ? WTolower(p[i]) : p[i];
4263       if (jishu_case == CANNA_JISHU_CAPITALIZE) {
4264 	if (p[i] <= ' ') {
4265 	  head = 1;
4266 	}
4267 	else if (head) {
4268 	  head = 0;
4269 	  xxxx[i - pos] = WToupper(p[i]);
4270 	}
4271       }
4272     }
4273     xxxx[i - pos] = (wchar_t)0;
4274 #if 0
4275     if (jishu_case == CANNA_JISHU_CAPITALIZE) {
4276       xxxx[0] = WToupper(xxxx[0]);
4277     }
4278 #endif
4279     if (jishu == JISHU_ZEN_ALPHA) {
4280       len = RkwCvtZen(buf, ROMEBUFSIZE, xxxx, jishu_rEndp - pos);
4281     }
4282     else {
4283       len = RkwCvtNone(buf, ROMEBUFSIZE, xxxx, jishu_rEndp - pos);
4284     }
4285     yc->rCurs = jishu_rEndp;
4286     yc->kCurs = jishu_kEndp;
4287     kanaReplace(yc->cmark - yc->kCurs, buf, len, 0);
4288     jishu_kEndp = yc->kCurs;
4289 
4290     /* ��������Ƭ�ӥåȤ�Ω�Ƥ� */
4291     for (i = pos ; i < yc->rCurs ; i++) {
4292       yc->rAttr[i] = SENTOU;
4293     }
4294 
4295     len = yc->kCurs;
4296     for (i = yc->cmark ; i < len ; i++) {
4297       yc->kAttr[i] = HENKANSUMI | SENTOU;
4298     }
4299 
4300     /* ������ʬ */
4301     for (i = jishu_rEndp ; i < yc->rEndp ; i++) {
4302       yc->rAttr[i] = 0;
4303     }
4304     yc->rAttr[jishu_rEndp] = SENTOU;
4305 
4306     kanaReplace(yc->kEndp - jishu_kEndp, yc->romaji_buffer + jishu_rEndp,
4307 		yc->rEndp - jishu_rEndp, 0);
4308     yc->rAttr[jishu_rEndp] |= SENTOU;
4309     yc->kAttr[jishu_kEndp] |= SENTOU;
4310     yc->rStartp = jishu_rEndp;
4311     yc->kRStartp = jishu_kEndp;
4312 
4313     for (yc->kCurs = jishu_kEndp, yc->rCurs = jishu_rEndp ;
4314 	 yc->kCurs < yc->kEndp ;) {
4315       yc->kCurs++; yc->rCurs++;
4316       if (yc->kRStartp == yc->kCurs - 1) {
4317 	yc->kAttr[yc->kRStartp] |= SENTOU;
4318       }
4319       makePhonoOnBuffer(d, yc,
4320                           (unsigned char)yc->kana_buffer[yc->kCurs - 1], 0, 0);
4321     }
4322     if (yc->kRStartp != yc->kEndp) {
4323       if (yc->kRStartp == yc->kCurs - 1) {
4324 	yc->kAttr[yc->kRStartp] |= SENTOU;
4325       }
4326       makePhonoOnBuffer(d, yc, (unsigned char)0, RK_FLUSH, 0);
4327     }
4328     break;
4329 
4330   default:/* �ɤ�Ǥ�ʤ��ä����Ѵ�����ʤ��ΤDz��⤷�ʤ� */
4331     jishu_rEndp = jishu_kEndp = 0;
4332     break;
4333   }
4334   yc->kCurs = yc->kRStartp = yc->kEndp;
4335   yc->rCurs = yc->rStartp = yc->rEndp;
4336   yc->pmark = yc->cmark;
4337   yc->cmark = yc->kCurs;
4338   yc->jishu_kEndp = 0;
4339 #ifdef USE_MALLOC_FOR_BIG_ARRAY
4340   (void)free((char *)xxxx);
4341 #endif
4342   return 0;
4343 }
4344 
4345 static
YomiJishu(d,fn)4346 YomiJishu(d, fn) /* �ɤߥ⡼�ɤ���ľ�ܻ���⡼�ɤ� */
4347 uiContext d;
4348 int fn;
4349 {
4350   yomiContext yc = (yomiContext)d->modec;
4351 
4352   if (yc->henkanInhibition & CANNA_YOMI_INHIBIT_JISHU) {
4353     return NothingChangedWithBeep(d);
4354   }
4355   d->nbytes = 0;
4356   if ((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) &&
4357       !(yc->status & CHIKUJI_OVERWRAP) && yc->nbunsetsu) {
4358     yc->status |= CHIKUJI_OVERWRAP;
4359     moveToChikujiTanMode(d);
4360   }
4361   else if (! RomajiFlushYomi(d, (wchar_t *)NULL, 0)) {
4362     d->more.todo = 1;
4363     d->more.ch = d->ch;
4364     d->more.fnum = 0;    /* ��� ch �Ǽ������������� */
4365     return d->nbytes;
4366   }
4367   else {
4368     enterJishuMode(d, yc);
4369     yc->minorMode = CANNA_MODE_JishuMode;
4370   }
4371   currentModeInfo(d);
4372   d->more.todo = 1;
4373   d->more.ch = d->ch;
4374   d->more.fnum = fn;
4375   return 0;
4376 }
4377 
4378 static int
chikujiEndBun(d)4379 chikujiEndBun(d)
4380      uiContext d;
4381 {
4382   yomiContext yc = (yomiContext)d->modec;
4383   int ret = 0;
4384 
4385   if ((yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) && yc->nbunsetsu) {
4386     KanjiMode mdsv;
4387 #ifndef USE_MALLOC_FOR_BIG_ARRAY
4388     yomiContextRec ycsv;
4389 #else
4390     yomiContext ycsv;
4391 
4392     ycsv = (yomiContext)malloc(sizeof(yomiContextRec));
4393     if (ycsv) {
4394 #endif
4395 
4396     /* ���䤬�Ĥ���� */
4397 #ifdef USE_MALLOC_FOR_BIG_ARRAY
4398     * /* This is a little bit tricky source code */
4399 #endif
4400     ycsv = *yc;
4401     yc->kEndp = yc->rEndp = 0;
4402     mdsv = d->current_mode;
4403     ret = TanKakutei(d);
4404     d->current_mode = mdsv;
4405     *yc =
4406 #ifdef USE_MALLOC_FOR_BIG_ARRAY
4407       * /* this is also a little bit trick source code */
4408 #endif
4409       ycsv;
4410   }
4411 #ifdef USE_MALLOC_FOR_BIG_ARRAY
4412     (void)free((char *)ycsv);
4413   }
4414 #endif
4415   return(ret);
4416 }
4417 
4418 /* cfuncdef
4419 
4420    replaceEnglish -- ���ʥХåե�����޻����ᤷ�ƺƥ��޻������Ѵ�����
4421 
4422    d, yc      : ����ƥ�����
4423    start, end : ���޻����᤹�ϰ�
4424    RKflag     : RkwMapPhonogram ��Ϳ����ե饰
4425    engflag    : ��ñ�쥫�������Ѵ����뤫�ɤ����Υե饰
4426 
4427  */
4428 
4429 static void
replaceEnglish(d,yc,start,end,RKflag,engflag)4430 replaceEnglish(d, yc, start, end, RKflag, engflag)
4431 uiContext d;
4432 yomiContext yc;
4433 int start, end, RKflag, engflag;
4434 {
4435   int i;
4436 
4437   kanaReplace(yc->pmark - yc->cmark,
4438 	      yc->romaji_buffer + start, end - start, 0);
4439   yc->kRStartp = yc->pmark;
4440   yc->rStartp = start;
4441   for (i = start ; i < end ; i++) {
4442     yc->rAttr[i] &= ~SENTOU;
4443   }
4444   yc->rAttr[start] |= SENTOU;
4445   for (i = yc->pmark ; i < yc->kCurs ; i++) {
4446     yc->kAttr[i] &= ~(SENTOU | HENKANSUMI);
4447   }
4448   yc->kAttr[yc->pmark] |= SENTOU;
4449 
4450   yc->n_susp_chars = 0; /* ���޻������Ѵ����ľ���ʤΤǥ��ꥢ���� */
4451   makePhonoOnBuffer(d, yc, 0, (unsigned char)RKflag, engflag);
4452   yc->kRStartp = yc->kCurs;
4453   yc->rStartp = yc->rCurs;
4454 }
4455 
4456 int YomiMark pro((uiContext));
4457 
4458 int
YomiMark(d)4459 YomiMark(d)
4460 uiContext d;
4461 {
4462 #ifndef NOT_ENGLISH_TABLE
4463   int rc, rp, i;
4464 #endif
4465   yomiContext yc = (yomiContext)d->modec;
4466 
4467 #if defined(DEBUG)
4468   if (iroha_debug) {
4469     fprintf(stderr,"yc->kCurs=%d yc->cmark=%d\n", yc->kCurs,yc->cmark);
4470   }
4471 #endif /* DEBUG */
4472 
4473   if (yc->kCurs != yc->cmark) { /* ���� */
4474 
4475     if (yc->cmark < yc->kCurs) {
4476       yc->pmark = yc->cmark;
4477       yc->cmark = yc->kCurs;
4478     }
4479     else {
4480       /* �ʲ���pmark < cmark ���ꤷ�Ƥ������������Τǡ�
4481 	 cmark < pmark �ξ��� pmark �� cmark ��Ʊ���ͤˤ��Ƥ��ޤ���
4482 	 ����ä����ޤǤ� pmark �� cmark �����촹�����äƤ�������
4483 	 �������Ƥ��ޤ��ȡ����ߤΥޡ������⺸�ؤϥޡ������դ����ʤ�
4484 	 �ȸ������ȤˤʤäƤ��ޤ��� */
4485       yc->pmark = yc->cmark = yc->kCurs;
4486     }
4487     yc->englishtype = CANNA_ENG_NO;
4488   }
4489 #ifndef NOT_ENGLISH_TABLE
4490   if (englishdic) {
4491     if (regionGairaigo(yc, yc->pmark, yc->cmark)) {
4492       yc->englishtype++;
4493       yc->englishtype = (BYTE)((int)yc->englishtype % (int)(CANNA_ENG_NO + 1));
4494       if (yc->englishtype == CANNA_ENG_KANA) {
4495 	kPos2rPos(yc, yc->pmark, yc->cmark, &rp, &rc);
4496 	replaceEnglish(d, yc, rp, rc, RK_FLUSH, 1);
4497 	yc->cmark = yc->kCurs;
4498       }
4499     }
4500     else {
4501       makeYomiReturnStruct(d);
4502       return 0;
4503     }
4504 
4505     /* �ޤ��ϡ����ʤˤǤ����ñ�줬���ä����ɤ���������å� */
4506     rp = rc = 0;
4507     for (i = yc->pmark ; i < yc->cmark ; i++) {
4508       if (yc->kAttr[i] & GAIRAIGO) {
4509 	rp = i;
4510 	do {
4511 	  i++;
4512 	} while (!(yc->kAttr[i] & SENTOU));
4513 	rc = i;
4514 	break;
4515       }
4516     }
4517     if (rp || rc) {
4518       int rs, re, offset;
4519       wchar_t space2[2];
4520 
4521       kPos2rPos(yc, rp, rc, &rs, &re);
4522       switch (yc->englishtype) {
4523       case CANNA_ENG_KANA:
4524 	break;
4525       case CANNA_ENG_ENG1:
4526 	offset = yc->kCurs - rc;
4527 	yc->kCurs -= offset;
4528 	kanaReplace(rp - rc, yc->romaji_buffer + rs, re - rs,
4529 		    HENKANSUMI | GAIRAIGO);
4530 	yc->kAttr[yc->kCurs - re + rs] |= SENTOU;
4531 	yc->kCurs += offset;
4532 	yc->cmark = yc->kRStartp = yc->kCurs;
4533 	break;
4534       case CANNA_ENG_ENG2:
4535 	offset = yc->kCurs - rc;
4536 	yc->kCurs -= offset;
4537 	space2[0] = (wchar_t)' ';
4538 	space2[1] = (wchar_t)' ';
4539 	kanaReplace(rp - rc, space2, 2, HENKANSUMI | GAIRAIGO);
4540 	yc->kAttr[yc->kCurs - 2] |= SENTOU;
4541 	yc->kCurs--;
4542 	kanaReplace(0, yc->romaji_buffer + rs, re - rs, HENKANSUMI | GAIRAIGO);
4543 	yc->kAttr[yc->kCurs - re + rs] &= ~SENTOU;
4544 	yc->kCurs += offset + 1;
4545 	yc->cmark = yc->kRStartp = yc->kCurs;
4546 	break;
4547       case CANNA_ENG_NO:
4548 	kPos2rPos(yc, yc->pmark, yc->cmark, &rs, &re);
4549 	replaceEnglish(d, yc, rs, re, 0, 0);
4550 	yc->cmark = yc->kRStartp = yc->kCurs;
4551 	break;
4552       }
4553     }
4554   }
4555 #endif
4556   makeYomiReturnStruct(d);
4557   debug_yomi(yc);
4558   return 0;
4559 }
4560 
Yomisearchfunc(d,mode,whattodo,key,fnum)4561 Yomisearchfunc(d, mode, whattodo, key, fnum)
4562 uiContext d;
4563 KanjiMode mode;
4564 int whattodo;
4565 int key;
4566 int fnum;
4567 {
4568   yomiContext yc = (yomiContext)0;
4569   int len;
4570   extern KanjiModeRec yomi_mode;
4571 
4572   if (d) {
4573     yc = (yomiContext)d->modec;
4574   }
4575 
4576   if (yc && yc->id != YOMI_CONTEXT) {
4577     /* ���褢�ꤨ�ʤ������Х��äƤ��ơ������ʤäƤƤ� core ���Ǥ�����
4578        ���ʤ���Ф��Τ������������֤����Τ�ǰ�ΰ٤���Ƥ��� */
4579     yc = (yomiContext)0;
4580   }
4581 
4582   if (cannaconf.romaji_yuusen && yc) { /* �⤷��ͥ��ʤ� */
4583     len = yc->kCurs - yc->kRStartp;
4584     if (fnum == 0) {
4585       fnum = mode->keytbl[key];
4586     }
4587     if (fnum != CANNA_FN_FunctionalInsert && len > 0) {
4588       int n, m, t, flag, prevrule;
4589 #ifndef USE_MALLOC_FOR_BIG_ARRAY
4590       wchar_t kana[128], roma[128];
4591 #else
4592       wchar_t *kana, *roma;
4593       kana = (wchar_t *)malloc(sizeof(wchar_t) * 128);
4594       roma = (wchar_t *)malloc(sizeof(wchar_t) * 128);
4595       if (!kana || !roma) {
4596 	if (kana) {
4597 	  (void)free((char *)kana);
4598 	}
4599 	if (roma) {
4600 	  (void)free((char *)roma);
4601 	}
4602 	return 0; /* ? suspicious */
4603       }
4604 #endif
4605 
4606       flag = cannaconf.ignore_case ? RK_IGNORECASE : 0;
4607 
4608       WStrncpy(roma, yc->kana_buffer + yc->kRStartp, len);
4609       roma[len++] = (wchar_t)key;
4610 
4611       prevrule = yc->last_rule;
4612       if ((RkwMapPhonogram(yc->romdic, kana, 128, roma, len, (wchar_t)key,
4613 			   flag | RK_SOKON, &n, &m, &t, &prevrule) &&
4614 	   n == len) || n == 0) {
4615 	/* RK_SOKON ���դ���Τϵ켭���� */
4616 	fnum = CANNA_FN_FunctionalInsert;
4617       }
4618 #ifdef USE_MALLOC_FOR_BIG_ARRAY
4619       (void)free((char *)kana);
4620       (void)free((char *)roma);
4621 #endif
4622     }
4623   }
4624   return searchfunc(d, mode, whattodo, key, fnum);
4625 }
4626 
4627 /*
4628   trimYomi -- �ɤߥХåե��Τ����ΰ�ʳ�����
4629 
4630    sy ey  ���ʤ���ʬ�ǻĤ��ΰ衢���γ�¦�Ϻ���롣
4631    sr er  ���޻�             ��
4632  */
4633 
4634 void
trimYomi(d,sy,ey,sr,er)4635 trimYomi(d, sy, ey, sr, er)
4636 uiContext d;
4637 int sy, ey, sr, er;
4638 {
4639   yomiContext yc = (yomiContext)d->modec;
4640 
4641   yc->kCurs = ey;
4642   yc->rCurs = er;
4643 
4644   romajiReplace (yc->rEndp - er, (wchar_t *)NULL, 0, 0);
4645   kanaReplace   (yc->kEndp - ey, (wchar_t *)NULL, 0, 0);
4646 
4647   yc->kCurs = sy;
4648   yc->rCurs = sr;
4649 
4650   romajiReplace (-sr, (wchar_t *)NULL, 0, 0);
4651   kanaReplace   (-sy, (wchar_t *)NULL, 0, 0);
4652 }
4653 
4654 #if 0 /* unused */
4655 static int
4656 TbBubunKakutei(d)
4657 uiContext d;
4658 {
4659   tanContext tan, tc = (tanContext)d->modec;
4660   wchar_t *s = d->buffer_return, *e = s + d->n_buffer;
4661   int len;
4662 
4663   tan = tc;
4664   while (tan->left) {
4665     tan = tan->left;
4666   }
4667 
4668   len = doKakutei(d, tan, tc, s, e, (yomiContext *)0);
4669   d->modec = (mode_context)tc;
4670   tc->left = (tanContext)0;
4671   s += len;
4672   (void)TanMuhenkan(d);
4673   return len;
4674 }
4675 #endif
4676 
4677 int doTanConvertTb pro((uiContext, yomiContext));
4678 
4679 int TanBubunKakutei pro((uiContext));
4680 
4681 int
TanBubunKakutei(d)4682 TanBubunKakutei(d)
4683 uiContext d;
4684 {
4685   int len;
4686   tanContext tan;
4687   yomiContext yc = (yomiContext)d->modec;
4688   wchar_t *s = d->buffer_return, *e = s + d->n_buffer;
4689 
4690   if (yc->id == YOMI_CONTEXT) {
4691     doTanConvertTb(d, yc);
4692     yc = (yomiContext)d->modec;
4693   }
4694   tan = (tanContext)yc;
4695   while (tan->left) {
4696     tan = tan->left;
4697   }
4698   len = doKakutei(d, tan, (tanContext)yc, s, e, (yomiContext *)0);
4699   d->modec = (mode_context)yc;
4700   yc->left = (tanContext)0;
4701 
4702   makeYomiReturnStruct(d);
4703   currentModeInfo(d);
4704   return len;
4705 }
4706 
4707 #if 0
4708 /*
4709  * ������ʸ������ޤdz��ꤷ�������Ȱʹߤ�ʸ����ɤߤ��᤹
4710  *
4711  * ������	uiContext
4712  * �����	���ェλ�� 0	�۾ェλ�� -1
4713  */
4714 TanBubunKakutei(d)
4715 uiContext	d;
4716 {
4717   extern KanjiModeRec cy_mode, yomi_mode;
4718   wchar_t *ptr = d->buffer_return, *eptr = ptr + d->n_buffer;
4719   yomiContext yc = (yomiContext)d->modec;
4720   tanContext tan;
4721   int i, j, n, l = 0, len, con, ret = 0;
4722 #ifndef USE_MALLOC_FOR_BIG_ARRAY
4723   wchar_t tmpbuf[ROMEBUFSIZE];
4724 #else
4725   wchar_t *tmpbuf = (wchar_t *)malloc(sizeof(wchar_t) * ROMEBUFSIZE);
4726   if (!tmpbuf) {
4727     return 0;
4728   }
4729 #endif
4730 
4731   if (yc->id != YOMI_CONTEXT) {
4732     ret = TbBubunKakutei(d);
4733     goto return_ret;
4734   }
4735 
4736   tan = (tanContext)yc;
4737   while (tan->left) {
4738     tan = tan->left;
4739   }
4740 
4741   len = doKakutei(d, tan, (tanContext)yc, ptr, eptr, (yomiContext *)0);
4742   d->modec = (mode_context)yc;
4743   yc->left = (tanContext)0;
4744   ptr += len;
4745 
4746   if (yomiInfoLevel > 0) {  /* ���ݤʤΤ� yomiInfo ��ΤƤ� */
4747     d->kanji_status_return->info &= ~KanjiYomiInfo;
4748   }
4749 
4750   con = yc->context;
4751 
4752   /* ����ʸ���� ���� */
4753   for (i = 0, n = yc->curbun ; i < n ; i++) {
4754     if (RkwGoTo(con, i) < 0) {
4755       ret = makeRkError(d, "\312\270\300\341\244\316\260\334\306\260\244\313"
4756 	"\274\272\307\324\244\267\244\336\244\267\244\277");
4757                             /* ʸ��ΰ�ư�˼��Ԥ��ޤ��� */
4758       goto return_ret;
4759     }
4760     len = RkwGetKanji(con, ptr, (int)(eptr - ptr));
4761     if (len < 0) {
4762       (void)makeRkError(d, "\264\301\273\372\244\316\274\350\244\352\275\320"
4763 	"\244\267\244\313\274\272\307\324\244\267\244\336\244\267\244\277");
4764                            /* �����μ��Ф��˼��Ԥ��ޤ��� */
4765       ret = TanMuhenkan(d);
4766       goto return_ret;
4767     }
4768     ptr += len;
4769     j = RkwGetYomi(yc->context, tmpbuf, ROMEBUFSIZE);
4770     if (j < 0) {
4771       (void)makeRkError(d, "\245\271\245\306\245\244\245\277\245\271\244\362"
4772 	"\274\350\244\352\275\320\244\273\244\336\244\273\244\363\244\307"
4773 	"\244\267\244\277");
4774                            /* ���ƥ���������Ф��ޤ���Ǥ��� */
4775       ret = TanMuhenkan(d);
4776       goto return_ret;
4777     }
4778     l += j;
4779   }
4780   d->nbytes = ptr - d->buffer_return;
4781 
4782   for (i = j = 0 ; i < l ; i++) {
4783     if (yc->kAttr[i] & SENTOU) {
4784       do {
4785 	++j;
4786       } while (!(yc->rAttr[j] & SENTOU));
4787     }
4788   }
4789   yc->rStartp = yc->rCurs = j;
4790   romajiReplace(-j, (wchar_t *)NULL, 0, 0);
4791   yc->kRStartp = yc->kCurs = i;
4792   kanaReplace(-i, (wchar_t *)NULL, 0, 0);
4793 
4794   if (RkwEndBun(yc->context, cannaconf.Gakushu ? 1 : 0) == -1) {
4795     jrKanjiError = "\244\253\244\312\264\301\273\372\312\321\264\271\244\316"
4796 	"\275\252\316\273\244\313\274\272\307\324\244\267\244\336\244\267"
4797 	"\244\277";
4798                    /* ���ʴ����Ѵ��ν�λ�˼��Ԥ��ޤ��� */
4799     if (errno == EPIPE) {
4800       jrKanjiPipeError();
4801     }
4802   }
4803 
4804   if (yc->generalFlags & CANNA_YOMI_CHIKUJI_MODE) {
4805     yc->status &= CHIKUJI_NULL_STATUS;
4806     yc->cStartp = yc->cRStartp = 0;
4807     yc->kCurs = yc->kRStartp = yc->kEndp;
4808     yc->rCurs = yc->rStartp = yc->rEndp;
4809     yc->ys = yc->ye = yc->cStartp;
4810     clearHenkanContext(yc);
4811     d->current_mode = yc->curMode = yc->rEndp ? &cy_mode : yc->myEmptyMode;
4812   }
4813   else {
4814     d->current_mode = yc->curMode = &yomi_mode;
4815   }
4816   yc->minorMode = getBaseMode(yc);
4817 
4818   yc->nbunsetsu = 0;
4819 
4820   /* ñ������֤����ɤߤ����Ȥ��ˤ�̵����mark����Ƭ���᤹ */
4821   yc->cmark = yc->pmark = 0;
4822 
4823   abandonContext(d, yc);
4824 
4825   doMuhenkan(d, yc);
4826 
4827   makeYomiReturnStruct(d);
4828   currentModeInfo(d);
4829 
4830   ret = d->nbytes;
4831 
4832  return_ret:
4833 #ifdef USE_MALLOC_FOR_BIG_ARRAY
4834   (void)free((char *)tmpbuf);
4835 #endif
4836   return ret;
4837 }
4838 #endif /* 0 */
4839 
4840 /*
4841   removeKana -- yomiContext ����Ƭ���������(�༡�ǻȤ�)
4842 
4843   k -- ���ʤκ���
4844   r -- ���޻��κ���
4845   d �Ϥ���ʤ��褦�˸����뤬�ޥ���Ǽ¤ϻȤäƤ���Τ�ɬ�ס�
4846 
4847  */
4848 
4849 void
removeKana(d,yc,k,r)4850 removeKana(d, yc, k, r)
4851 uiContext d;
4852 yomiContext yc;
4853 int k, r;
4854 {
4855   int offs;
4856 
4857   offs = yc->kCurs - k;
4858   yc->kCurs = k;
4859   kanaReplace(-k, (wchar_t *)NULL, 0, 0);
4860   if (offs > 0) {
4861     yc->kCurs = offs;
4862   }
4863   yc->cmark = yc->kRStartp = yc->kCurs;
4864   offs = yc->rCurs - r;
4865   yc->rCurs = r;
4866   romajiReplace(-r, (wchar_t *)NULL, 0, 0);
4867   if (offs > 0) {
4868     yc->rCurs = offs;
4869   }
4870   yc->rStartp = yc->rCurs;
4871 }
4872 
4873 static YomiNextJishu pro((uiContext));
4874 
4875 static
YomiNextJishu(d)4876 YomiNextJishu(d) /* �ɤߥ⡼�ɤ���ν���ʸ�����Ѵ� */
4877 uiContext d;
4878 {
4879   return YomiJishu(d, CANNA_FN_Next);
4880 }
4881 
4882 static YomiPreviousJishu pro((uiContext));
4883 
4884 static
YomiPreviousJishu(d)4885 YomiPreviousJishu(d) /* �ɤߥ⡼�ɤ���εղ��ʸ�����Ѵ� */
4886 uiContext d;
4887 {
4888   return YomiJishu(d, CANNA_FN_Prev);
4889 }
4890 
4891 static YomiKanaRotate pro((uiContext));
4892 
4893 static
YomiKanaRotate(d)4894 YomiKanaRotate(d) /* �ɤߥ⡼�ɤ���ν��꤫��ʸ�����Ѵ� */
4895 uiContext d;
4896 {
4897   return YomiJishu(d, CANNA_FN_KanaRotate);
4898 }
4899 
4900 static YomiRomajiRotate pro((uiContext));
4901 
4902 static
YomiRomajiRotate(d)4903 YomiRomajiRotate(d) /* �ɤߥ⡼�ɤ���ν���ѿ�ʸ�����Ѵ� */
4904 uiContext d;
4905 {
4906   return YomiJishu(d, CANNA_FN_RomajiRotate);
4907 }
4908 
4909 static YomiCaseRotateForward pro((uiContext));
4910 
4911 static
YomiCaseRotateForward(d)4912 YomiCaseRotateForward(d) /* �ɤߥ⡼�ɤ���ν���ѿ�ʸ�����Ѵ� */
4913 uiContext d;
4914 {
4915   return YomiJishu(d, CANNA_FN_CaseRotate);
4916 }
4917 
4918 static YomiZenkaku pro((uiContext));
4919 
4920 static
YomiZenkaku(d)4921 YomiZenkaku(d) /* �ɤߥ⡼�ɤ���������Ѵ� */
4922 uiContext d;
4923 {
4924   return YomiJishu(d, CANNA_FN_Zenkaku);
4925 }
4926 
4927 static YomiHankaku pro((uiContext));
4928 
4929 static
YomiHankaku(d)4930 YomiHankaku(d) /* �ɤߥ⡼�ɤ����Ⱦ���Ѵ� */
4931 uiContext d;
4932 {
4933   if (cannaconf.InhibitHankakuKana)
4934     return NothingChangedWithBeep(d);
4935   else
4936     return YomiJishu(d, CANNA_FN_Hankaku);
4937 }
4938 
4939 static YomiHiraganaJishu pro((uiContext));
4940 
4941 static
YomiHiraganaJishu(d)4942 YomiHiraganaJishu(d) /* �ɤߥ⡼�ɤ������⡼�ɤΤҤ餬�ʤ� */
4943 uiContext d;
4944 {
4945   return YomiJishu(d, CANNA_FN_Hiragana);
4946 }
4947 
4948 static YomiKatakanaJishu pro((uiContext));
4949 
4950 static
YomiKatakanaJishu(d)4951 YomiKatakanaJishu(d) /* �ɤߥ⡼�ɤ������⡼�ɤΥ������ʤ� */
4952 uiContext d;
4953 {
4954   return YomiJishu(d, CANNA_FN_Katakana);
4955 }
4956 
4957 static YomiRomajiJishu pro((uiContext));
4958 
4959 static
YomiRomajiJishu(d)4960 YomiRomajiJishu(d) /* �ɤߥ⡼�ɤ������⡼�ɤΥ��޻��� */
4961 uiContext d;
4962 {
4963   return YomiJishu(d, CANNA_FN_Romaji);
4964 }
4965 
4966 static YomiToLower pro((uiContext));
4967 static
YomiToLower(d)4968 YomiToLower(d)
4969 uiContext d;
4970 {
4971   return YomiJishu(d, CANNA_FN_ToLower);
4972 }
4973 
4974 static YomiToUpper pro((uiContext));
4975 
4976 static
YomiToUpper(d)4977 YomiToUpper(d)
4978 uiContext d;
4979 {
4980   return YomiJishu(d, CANNA_FN_ToUpper);
4981 }
4982 
4983 static YomiCapitalize pro((uiContext));
4984 
4985 static
YomiCapitalize(d)4986 YomiCapitalize(d)
4987 uiContext d;
4988 {
4989   return YomiJishu(d, CANNA_FN_Capitalize);
4990 }
4991 
4992 /* �Ѹ쥫�������Ѵ��Τ��Ĥ�
4993 
4994  ��������Ѵ��ϻ����Ѵ��˼����ߤ���
4995 
4996    �Ĥ��ǤʤΤǥ������ڤ��ؤ��Τ��Ĥ�
4997 
4998  ���ģӣϤ��ʤ����ˡ֤��Υ�������ڤ��ؤ����ʤ��פȸ�������
4999  ������¾���顼�����å�
5000 
5001  */
5002 
5003 #ifndef wchar_t
5004 # error "wchar_t is already undefined"
5005 #endif
5006 #undef wchar_t
5007 /*********************************************************************
5008  *                       wchar_t replace end                         *
5009  *********************************************************************/
5010 
5011 #include "yomimap.h"
5012 /* vim: set sw=2: */
5013