comparison Xwnmo/romkan_m/rk_main.c @ 0:bbc77ca4def5

initial import
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Thu, 13 Dec 2007 04:30:14 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bbc77ca4def5
1 /*
2 * $Id: rk_main.c,v 1.2 2001/06/14 18:16:09 ura Exp $
3 */
4
5 /*
6 * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7 * This file is part of FreeWnn.
8 *
9 * Copyright Kyoto University Research Institute for Mathematical Sciences
10 * 1987, 1988, 1989, 1990, 1991, 1992
11 * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
12 * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
13 *
14 * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with GNU Emacs; see the file COPYING. If not, write to the
28 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * Commentary:
31 *
32 * Change log:
33 *
34 * Last modified date: 8,Feb.1999
35 *
36 * Code:
37 *
38 */
39 /***********************************************************************
40 rk_main.c
41 87.12. 3 改 正
42
43 ローマ字かな変換・その他、入力コードを変換するプログラム。
44 ASCIIコード使用を、前提としている。
45 このファイルは、変換のメインルーチン。
46 ***********************************************************************/
47 /* Version 3.1 88/06/14 H.HASHIMOTO
48 */
49 #ifndef OMRON_LIB
50 #include "rk_header.h"
51 #include "rk_extvars.h"
52 #ifdef MULTI
53 #include "rk_multi.h"
54 #endif /*MULTI*/
55 #endif
56 #include "rext.h"
57 #ifdef MULTI
58 #define DISOUT ((cur_rk->flags & RK_NONISE) ? cur_rk->rk_output : cur_rk->disout)
59 /* フラグの値はromkan_init3()の中で設定され、そのRK_NONISEのビットの値の
60 標準は0。従ってDISOUTの標準値はdisout。これをrk_outputに変えると、偽コード
61 (除:LTREOF)を一切出さない(但し、キー入力があれば必ず何かを返すように
62 してある時に限り、EOLTTRをも返す)。 */
63 #else /* !MULTI */
64 #ifdef KDSP
65 # ifdef MVUX
66 letter displine[DSPLIN]; /* デバッグ用 表示の一行分を記憶 */
67 # endif
68 #endif
69
70 /* 88/06/02 V3.1 */
71 static letter nil[1] = { EOLTTR };
72 static letter *curdis;
73 static int codein_len;
74 static letter *codeout, *remainkbf;
75 static letter ungetc_buf = EOLTTR; /* romkan_ungetcが一文字退避しておくバッファ */
76 static letter unnext_buf = EOLTTR; /* romkan_unnextが 〃 */
77
78 static letter (*keyin_method) (); /* キーイン関数のアドレス */
79 static int (*bytcnt_method) (); /* バイトカウント関数のアドレス */
80 static int (*kbytcnt_method) (); /* キー入力解釈用バイトカウント関数のアドレス */
81
82 /* モード表名(又はそのパス名)を保存 *//* 初期設定がいい加減! */
83 static char prv_modfnm[REALFN] = "\0";
84
85 #define DISOUT ((flags & RK_NONISE) ? rk_output : disout)
86 /* フラグの値はromkan_init3()の中で設定され、そのRK_NONISEのビットの値の
87 標準は0。従ってDISOUTの標準値はdisout。これをrk_outputに変えると、偽コード
88 (除:LTREOF)を一切出さない(但し、キー入力があれば必ず何かを返すように
89 してある時に限り、EOLTTRをも返す)。 */
90
91 static /* V3.1 */
92 char eofflg; /* romkan_next()からLTREOFが来たときに、romkan_henkan()内で1
93 にする。これの値が非0なら変換対応表の(error)を無視して、
94 本処理バッファ内の未確定コードも、強制的に変換させる。更に
95 LTREOFが来た時に特別にある出力を出すように指定されていれば
96 その処理も行う(但し、その処理は急ごしらえで不完全)。その
97 処理中はeofflgは2。 */
98
99 static letter evalbuf[2][2][OUTSIZ];
100 static letter delchr, delchr2 = EOLTTR, nisedl; /* DELのキャラクタは二個まで持てる */
101
102 /* 88/05/31 V3.1 */
103 static letter rk_input; /* 入力。3バイトまでは変更なしに対応可 */
104 static letter disout[OUTSIZ]; /* 本処理からの出力のバッファ */
105 static letter rk_output[OUTSIZ]; /* 後処理からの出力(最終出力)のバッファ */
106 static letter keybuf[KBFSIZ], urabuf[KBFSIZ]; /* 本処理バッファとその退避領域 */
107 static int lastoutlen, lastkbflen;
108 static int hyonum;
109 #endif /* MULTI */
110
111 static void romkan_delete (), mchevl (), add_at_eof (), free_for_all_area (), ltrevlcpy (), set_rubout (), maeato_henkan (), codeout_chg ();
112
113 /* letterを返す関数の定義及び宣言(一部にはcharのものも混じっている) */
114
115 static int head_bytecount (), p_eq (), hen_ikisrc (), match (), henkan_ok (), romkan_restart ();
116 static letter mchedsrc ();
117 letter romkan_next (), romkan_unnext ();
118 letter romkan_getc (), romkan_ungetc (), *romkan_henkan ();
119 letter to_zenalpha (), to_zenhira (), to_zenkata ();
120 /* to_zenhira;kata は濁点を持つ文字を一まとめにしない。 */
121
122 static letter *
123 ltrcpy (lp1, lp2)
124 fast letter *lp1, *lp2; /* V3.1 */
125 {
126 fast letter *org; /* V3.1 */
127
128 org = lp1;
129 while ((*lp1++ = *lp2++) != EOLTTR);
130 return (org);
131 }
132
133 #ifdef nodef
134 static letter *
135 ltrncpy (lp1, lp2, n) /* 末尾に'EOLTTR'をセット */
136 letter *lp1, *lp2;
137 int n;
138 {
139 fast letter *org;
140
141 org = lp1;
142 for (; n; --n)
143 if (EOLTTR == (*lp1++ = *lp2++))
144 return (org);
145 *lp1 = EOLTTR;
146 return (org);
147 }
148 #endif
149
150 /** letterの列の末尾に一文字つなげる */
151 static /* V3.1 */
152 letter *
153 ltr1cat (lp, l)
154 fast letter *lp, l; /* V3.1 */
155 {
156 fast letter *org; /* V3.1 */
157
158 org = lp;
159 totail (lp);
160 *lp++ = l;
161 *lp = EOLTTR;
162 return (org);
163 }
164
165 /** 文字列の末尾に一文字つなげる。ltr1catのchar版 */
166 #ifdef OMRON_LIB
167 static
168 #endif
169 char *
170 chrcat (s, c)
171 fast char *s, c; /* V3.1 */
172 {
173 fast char *org; /* V3.1 */
174
175 org = s;
176 strtail (s);
177 *s++ = c;
178 *s = '\0';
179 return (org);
180 }
181
182 static letter *
183 ltrcat (lp1, lp2)
184 fast letter *lp1, *lp2; /* V3.1 */
185 {
186 fast letter *org; /* V3.1 */
187
188 org = lp1;
189 totail (lp1);
190 ltrcpy (lp1, lp2);
191 return (org);
192 }
193
194 /** letterの列lp2の各要素の最上位ビットを立ててから、lp1の後ろにつなげる。*/
195 static /* V3.1 */
196 letter *
197 bitup_ltrcat (lp1, lp2)
198 fast letter *lp1, *lp2; /* V3.1 */
199 {
200 fast letter *org; /* V3.1 */
201
202 org = lp1;
203 totail (lp1);
204
205 while ((*lp1 = *lp2++) != EOLTTR)
206 *lp1++ |= HG1BIT;
207 /** lp2 の要素全ての最上位ビットを立てる。*lp2がNISEBP(rk_spclval.h
208 でdefine)などのときは最初から最上位が立ってるからよい */
209
210 return (org);
211 }
212
213 /** ltrcatしたあと、結果の文字列の末尾にポインタをもっていく。*/
214 #ifdef OMRON_LIB
215 static
216 #endif
217 letter *
218 ltrgrow (lp1, lp2)
219 fast letter *lp1, *lp2; /* V3.1 */
220 {
221 totail (lp1);
222 while ((*lp1 = *lp2++) != EOLTTR)
223 lp1++;
224 return (lp1);
225 }
226
227 int
228 ltrlen (lp)
229 fast letter *lp; /* V3.1 */
230 {
231 fast letter *org; /* V3.1 */
232
233 for (org = lp; *lp != EOLTTR; lp++);
234 return (lp - org);
235 }
236
237 /** letterの列の最後の文字へのポインタを返す。但し空文字列に対しては
238 そのまま返す。*/
239 static letter *
240 ltrend (lp)
241 fast letter *lp; /* V3.1 */
242 {
243 return ((*lp != EOLTTR) ? (lp + ltrlen (lp) - 1) : lp);
244 }
245
246 /** 文字列の最後の文字へのポインタを返す。ltrend()のchar版。ltrend()と
247 同様、空文字列のときは特例がある。*/
248 #ifdef OMRON_LIB
249 static
250 #endif
251 char *
252 strend (s)
253 fast char *s; /* V3.1 */
254 {
255 return (*s ? (s + strlen (s) - 1) : s);
256 }
257
258 int
259 ltrcmp (lp1, lp2)
260 fast letter *lp1, *lp2; /* V3.1 */
261 {
262 for (; *lp1 == *lp2; lp1++, lp2++)
263 if (*lp1 == EOLTTR)
264 return (0);
265 return (*lp1 > *lp2 ? 1 : -1);
266 }
267
268 #ifdef nodef
269 int
270 ltrncmp (lp1, lp2, n)
271 letter *lp1, *lp2;
272 int n;
273 {
274 for (; n && *lp1 == *lp2; n--, lp1++, lp2++)
275 if (*lp1 == EOLTTR)
276 return (0);
277 return (n == 0 ? 0 : (*lp1 > *lp2 ? 1 : -1));
278 }
279
280 /* 88/06/14 V3.1 */
281 /******************************************************************************/
282 #ifndef OMRON
283 letter *
284 ltr_index (lp, l)
285 letter l, *lp;
286 {
287 for (; *lp != EOLTTR; lp++)
288 if (*lp == l)
289 return (lp);
290 return (NULL);
291 }
292 #endif
293 /******************************************************************************/
294 #endif
295
296 static /* V3.1 */
297 letter *
298 ltr_rindex (lp, l)
299 fast letter l, *lp; /* V3.1 */
300 {
301 fast letter *lp2; /* V3.1 */
302
303 for (lp += ltrlen (lp2 = lp); lp2 != lp;)
304 if (*--lp == l)
305 return (lp);
306 return (NULL);
307 }
308
309 /** 文字列の末尾一文字をカットする。*/
310 /*static V3.1 */
311 letter *
312 ltr1cut (lp)
313 fast letter *lp; /* V3.1 */
314 {
315 fast int l; /* V3.1 */
316
317 if (0 == (l = ltrlen (lp)))
318 BUGreport (0); /* Illegal POP */
319 *(lp + --l) = EOLTTR;
320 return (lp);
321 }
322
323 /** letterの一文字を長さ1の文字列に変換する */
324 static /* V3.1 */
325 letter *
326 ltr_to_ltrseq (lp, l)
327 letter *lp, l;
328 {
329 *lp++ = l;
330 *lp-- = EOLTTR;
331 return (lp);
332 }
333
334 /** charの列からletterを一つ取り出す。但し'\0'はEOLTTRに変える */
335 #ifdef OMRON_LIB
336 static
337 #endif
338 letter
339 letterpick (lbfpptr)
340 fast uns_chr **lbfpptr;
341 {
342 fast letter l = 0;
343 fast int i; /* V3.1 */
344
345 for (i = (*(cur_rk_table->bytcnt_method)) (*lbfpptr); i; i--)
346 l = (l << 8) + *(*lbfpptr)++;
347 return (l == 0 ? EOLTTR : l);
348 }
349
350 /** 入力されたコードを文字単位にまとめる。但しEOFはLTREOF(rk_spclval.h
351 にて定義)に変える。*/
352 /* *INDENT-OFF* */
353 letter
354 romkan_next ()
355 /* *INDENT-ON* */
356 {
357 letter in;
358 int i, n;
359 uns_chr c;
360
361 /* unnextされている場合は、それを取り出す。 */
362 if (cur_rk->unnext_buf != EOLTTR)
363 return (in = cur_rk->unnext_buf, cur_rk->unnext_buf = EOLTTR, in);
364
365 if ((letter) EOF == (in = (*(cur_rk_table->keyin_method)) ()))
366 return (LTREOF);
367 c = (in &= 0xff);
368 n = (*(cur_rk_table->kbytcnt_method)) (&c);
369 for (i = 1; i < n; i++)
370 in = (in << 8) + ((*(cur_rk_table->keyin_method)) () & 0xff);
371 return (in);
372 }
373
374 /* letterの文字 l とcharの文字 c の比較。エンドマーク同士(letter列の
375 エンドマークはEOLTTR、char列のは'\0')も一致とみなす。 */
376 #define ltrchreq(l, c) ((l) == (c) && (c) != 0 || (l) == EOLTTR && (c) == 0)
377
378 /** letterの文字列とcharの文字列の比較 但し大小比較は符号なしとしてやる */
379 #ifdef OMRON_LIB
380 static
381 #endif
382 int
383 ltrstrcmp (l, s)
384 fast letter *l; /* V3.1 */
385 fast char *s; /* V3.1 */
386 {
387 for (; ltrchreq (*l, *s); l++, s++)
388 if (*s == 0)
389 return (0);
390 return (1);
391 /*
392 return((*l < (uns_chr)*s || *l == EOLTTR)? -1 : 1);
393 */
394 }
395
396 /** 最後にマッチした文字 つまりurabufの最後。urabufが空だとEOLTTRを返す */
397 static /* V3.1 */
398 letter
399 lastmch ()
400 {
401 return (*(ltrend (cur_rk->urabuf)));
402 }
403
404 /* end of 'letter' functions */
405
406
407 /** 変換バッファのクリア */
408 /* 注意! romkan_clear()を呼ぶ時は、必ずその前に、cur_rkをセットすること */
409 void
410 romkan_clear ()
411 {
412 #ifdef KDSP
413 # ifdef MVUX
414 *displine = EOLTTR;
415 # endif
416 #endif
417 cur_rk->ungetc_buf = *(cur_rk->keybuf) = *(cur_rk->urabuf) = *(cur_rk->disout) = *(cur_rk->rk_output) = EOLTTR;
418 cur_rk->curdis = DISOUT;
419 cur_rk->lastoutlen = cur_rk->lastkbflen = 0;
420 }
421
422 /** WnnV4.0マルチクライアント用のRomkan構造体を初期化する **/
423 Romkan *
424 rk_buf_init ()
425 {
426 register Romkan *p;
427 register int i;
428
429 if ((p = (Romkan *) malloc (sizeof (Romkan))) == NULL)
430 {
431 return (NULL);
432 }
433 malloc_for_henmatch (&(p->rk_henmatch), cur_rk_table->rk_hensuudef.count);
434 malloc_for_modesw (&(p->rk_modesw), cur_rk_table->rk_modesw.max);
435 p->rk_modesw.max = cur_rk_table->rk_modesw.max;
436 p->rk_modesw.count = cur_rk_table->rk_modesw.count;
437 for (i = 0; i < cur_rk_table->rk_modesw.max; i++)
438 {
439 p->rk_modesw.point[i] = cur_rk_table->rk_modesw.point[i];
440 }
441 malloc_for_usehyo (&(p->rk_usehyo), cur_rk_table->rk_usehyo.size);
442 p->rk_usehyo.size = cur_rk_table->rk_usehyo.size;
443 for (i = 0; i < (cur_rk_table->rk_usehyo.size + 1); i++)
444 {
445 p->rk_usehyo.usemaehyo[i] = cur_rk_table->rk_usehyo.usemaehyo[i];
446 p->rk_usehyo.usehyo[i] = cur_rk_table->rk_usehyo.usehyo[i];
447 p->rk_usehyo.useatohyo[i] = cur_rk_table->rk_usehyo.useatohyo[i];
448 }
449 p->rk_errstat = NULL;
450 p->flags = 0;
451 p->nil[0] = EOLTTR;
452 p->ungetc_buf = EOLTTR;
453 p->unnext_buf = EOLTTR;
454 p->delchr2 = EOLTTR;
455 p->ebf_sw = NULL;
456 p->oneletter[0] = p->oneletter[1] = EOLTTR;
457 p->keybuf[0] = p->urabuf[0] = p->disout[0] = p->rk_output[0] = EOLTTR;
458 p->rk_table = (RomkanTable *) NULL;
459 return (p);
460 }
461
462 RomkanTable *
463 rk_table_buf_init ()
464 {
465 RomkanTable *p;
466 if ((p = (RomkanTable *) malloc (sizeof (RomkanTable))) == NULL)
467 {
468 return (NULL);
469 }
470 p->flags = 0;
471 p->rk_usehyo.size = -1;
472 p->prv_modfnm[0] = NULL;
473 return (p);
474 }
475
476
477 void
478 rk_close (p)
479 Romkan *p;
480 {
481 /*free_for_all_area(); *//* V3.1 */
482 free_for_modesw (&(p->rk_modesw));
483 free_for_henmatch (&(p->rk_henmatch));
484 free_for_usehyo (&(p->rk_usehyo));
485 free (p);
486 }
487
488 /** 表を読み込んで変換の初期設定をする。(part 3)*/
489 /* WnnV4.0マルチクライアントの場合
490 romkan_init3は、Romkan構造体へのポインタを返します。
491 その後、romkanをする場合は、グローバル変数cur_rkに
492 そのポインタを入れなければならない。
493 但し、romkan_init3()は、内部で一時的にcur_rkをセットし、
494 returnする時に元の値に戻します。 */
495
496 #ifdef nodef
497 /* 88/06/13 V3.1 */
498 /** 変換表のクリア */
499 static /* V3.1 */
500 void
501 romkan_reset ()
502 {
503 if (cur_rk_table->rk_modenaibu.org != NULL)
504 {
505 cur_rk_table->rk_modenaibu.org[0] = 0; /* Terminator */
506 }
507 choosehyo ();
508 romkan_clear ();
509 }
510 #endif
511
512
513 RomkanTable *
514 romkan_table_init (p, modhyo, keyinfn, bytcntfn, kbytcntfn, flags_)
515 RomkanTable *p;
516 fast char *modhyo; /* モード定義表の名又はそのパス名 */
517 letter (*keyinfn) ();
518 fast int (*bytcntfn) ();
519 fast int (*kbytcntfn) ();
520 fast int flags_;
521 {
522 int errcod; /* 今の所1のみ */
523 fast RomkanTable *tmp_cur_rk_table;
524 fast RomkanTable *rk_table_buf;
525
526 tmp_cur_rk_table = cur_rk_table;
527 if (p == NULL)
528 {
529 if ((rk_table_buf = (RomkanTable *) rk_table_buf_init ()) == NULL)
530 {
531 return (NULL);
532 }
533 }
534 else
535 {
536 rk_table_buf = p;
537 }
538 cur_rk_table = rk_table_buf;
539 cur_rk_table->keyin_method = keyinfn;
540 cur_rk_table->bytcnt_method = (bytcntfn == NULL ? head_bytecount : bytcntfn);
541 cur_rk_table->kbytcnt_method = (kbytcntfn == NULL ? cur_rk_table->bytcnt_method : kbytcntfn);
542 /* 88/05/30/ V3.1 */
543 if (modhyo == NULL)
544 modhyo = "";
545 strcpy (cur_rk_table->prv_modfnm, modhyo); /* V3.1 */
546 if ((errcod = setjmp (cur_rk_table->env0)) != 0)
547 {
548 /* 88/06/13 V3.1 */
549 free_for_all_area (); /* V3.1 */
550 fprintf (stderr, "romkan_init failed.");
551 }
552 else
553 {
554 readdata (modhyo); /* 88/06/08 V3.1 */
555 }
556 cur_rk_table = tmp_cur_rk_table;
557 if (!errcod)
558 {
559 return (rk_table_buf);
560 }
561 else
562 {
563 free (rk_table_buf);
564 return (NULL);
565 }
566 }
567
568
569 /** 表を読み込んで変換の初期設定をする。(part 3)*/
570
571 Romkan *
572 romkan_init3 (delchr_, nisedl_, delchr2_, flags_)
573 letter delchr_; /* DELとして使うコード */
574 letter nisedl_; /* 偽DELとして使うコード */
575 letter delchr2_; /* DELとして使うコードが二つある場合そのもう一方 */
576 int flags_;
577 /* 以下のフラグが利用可。これらはrk_spclval.hにて定義。
578 RK_CHMOUT:モードチェンジを知らせるコードを返すか?
579 RK_KEYACK:キーインに対し必ず何かを返すか
580 RK_NONISE:偽コードを出さないようにするか
581 RK_REDRAW:Wnn用特殊フラグ(redraw用のフラグを出すかどうか)
582 RK_SIMPLD:deleteの動作を単純にするか
583 */
584 {
585 Romkan *tmp_cur_rk;
586 Romkan *rk_buf;
587
588 tmp_cur_rk = cur_rk;
589
590 if (setjmp (cur_rk_table->env0) != 0)
591 {
592 return (NULL);
593 }
594
595 if ((rk_buf = (Romkan *) rk_buf_init ()) == NULL)
596 {
597 return (NULL);
598 }
599 cur_rk = rk_buf;
600 /* 偽コードを出すかの設定はromkan_clearで使うので、フラグの設定を
601 先にやっておかないといけない。 */
602 cur_rk->flags = flags_;
603 cur_rk->curdis = DISOUT;
604 cur_rk->delchr = delchr_;
605 cur_rk->nisedl = nisedl_;
606 cur_rk->delchr2 = delchr2_;
607 /** 実はDELのキャラクタを二個まで持てる。二個目:delchr2は、未設定の
608 とき(値がEOLTTR)は無視される。それ以外は、delchr2が入力されると
609 delchrが入力されたのと同じ振る舞いをする。*/
610
611 choosehyo ();
612 cur_rk = tmp_cur_rk;
613 return (rk_buf);
614 }
615
616 #define ifflg(a, b) ((a) ? (b) : 0)
617
618 /** 表を読み込んで変換の初期設定をする。(part 2: キー入力に対し必ず何か
619 返すようにするか、キーバッファをクリアするかどうかなども指定可)*/
620
621 Romkan *
622 romkan_init2 (delchr_, chmoutf, keyinfn, bytcntfn, keyackf, restartf, nonisecodf)
623 char chmoutf, keyackf, restartf, nonisecodf;
624 letter delchr_;
625 letter (*keyinfn) ();
626 int (*bytcntfn) (); /* 引数の詳細はromkan_init3を参照 */
627 {
628 return (romkan_init3 (delchr_, toNISE (delchr_), EOLTTR, keyinfn, bytcntfn, (int (*)()) NULL, ifflg (chmoutf, RK_CHMOUT) | ifflg (keyackf, RK_KEYACK) | ifflg (nonisecodf, RK_NONISE)));
629 }
630
631 /** 表を読み込んで変換の初期設定をする。(part 1)*/
632 Romkan *
633 romkan_init (delchr_, chmoutf, keyinfn, bytcntfn)
634 char chmoutf;
635 letter delchr_;
636 letter (*keyinfn) ();
637 int (*bytcntfn) (); /* 引数の詳細はromkan_init3を参照 */
638 {
639 return (romkan_init2 (delchr_, chmoutf, keyinfn, bytcntfn, 0, 0, 0));
640 }
641
642
643 /** バイトカウント関数のデフォルト。sの指している所に入っているのが
644 何バイトコードかを返す。
645 romkan_nextに注意。そちらでは、バイトカウント関数の値は
646 引数の一文字目にのみ依存すると仮定している。*/
647 static /* V3.1 */
648 int
649 head_bytecount (s)
650 fast uns_chr *s;
651 {
652 fast uns_chr c = *s;
653 #ifdef IKIS
654 return ((c <= 0xa0 || c == 0xff) ? 1 : 2);
655 #else
656 if (c == SS2)
657 return (2);
658 if (c == SS3)
659 return (3);
660 if (c <= 0xa0)
661 return (1);
662 else
663 return (2);
664 #endif
665 }
666
667 /** 変換された文字を順次返す */
668 /* *INDENT-OFF* */
669 letter
670 romkan_getc ()
671 /* *INDENT-ON* */
672 {
673 fast letter l; /* V3.1 */
674
675 /* ungetcされている場合は、それを取り出す。 */
676 if (cur_rk->ungetc_buf != EOLTTR)
677 return (l = cur_rk->ungetc_buf, cur_rk->ungetc_buf = EOLTTR, l);
678
679 while (*(cur_rk->curdis) == EOLTTR)
680 {
681 /* romkan_next()の値がLTREOFの時も、そのまま送れば良い。 */
682 cur_rk->curdis = romkan_henkan (romkan_next ());
683
684 /* keyackflgが非0なら、キーインがあれば必ず何か返す。その
685 ため、返すべきものがない時はEOLTTRを返すことにする。 */
686 if (cur_rk->flags & RK_KEYACK)
687 break;
688 }
689
690 if (EOLTTR != (l = *(cur_rk->curdis)))
691 cur_rk->curdis++;
692 return (l);
693 /* 偽物の文字なら、HG1BITが立っている。 */
694 /* 特別なコード(例えば偽のBEEPとしてNISEBP)を返すときがある。それらは
695 rk_spclval.hに定義されている。 */
696 }
697
698 /** romkan_getcの下位関数として、入力を一文字受け取って
699 変換結果の文字列を出力する。*/
700 letter *
701 romkan_henkan (mae_in)
702 letter mae_in;
703 {
704 letter mae_out[2], *p;
705
706 /* if(*(cur_rk->curdis) != EOLTTR){p = cur_rk->curdis; cur_rk->curdis = cur_rk->nil; return(p);} */
707 /* ↑これではmae_inが無視される */
708 cur_rk->curdis = cur_rk->nil;
709
710 /* 前・後処理への入力は常にただ一文字 */
711 mae_out[0] = mae_out[1] = EOLTTR;
712
713 cur_rk->eofflg = cur_rk->rk_errstat = 0;
714 *(cur_rk->rk_output) = *(cur_rk->disout) = EOLTTR;
715
716 maeato_henkan (mae_in, mae_out, cur_rk->rk_usehyo.usemaehyo);
717 cur_rk->rk_input = *mae_out;
718
719 if (cur_rk->rk_input == LTREOF)
720 {
721 /* LTREOFが来た場合、(error)を無視し、本処理バッファの末尾迄
722 強制変換する。そのためにeofflgを1にする。その後、結果の
723 末尾に、LTREOFが来た時の特別コード(指定されていれば)と、
724 LTREOFをつなぐ。 */
725 cur_rk->eofflg = 1;
726 match ();
727
728 cur_rk->eofflg = 2;
729 add_at_eof (); /* codeoutに、LTREOFが来た時出すコードが入る。 */
730 ltr1cat (cur_rk->codeout, LTREOF);
731
732 ltrcat (cur_rk->disout, cur_rk->codeout);
733 ltrcat (cur_rk->rk_output, cur_rk->codeout);
734 }
735 else if (cur_rk->rk_input == EOLTTR)
736 {
737 /* EOLTTRが来た場合も、上と同様の処理を行うが、LTREOFは
738 つながない。なお、これはromkan_getc()を呼んでいる時は
739 起こらない(romkan_next()がEOLTTRを返さないから)。 */
740 cur_rk->eofflg = 1;
741 match ();
742 }
743 else if (cur_rk->rk_input == cur_rk->delchr || cur_rk->rk_input == cur_rk->delchr2)
744 {
745 /* delchr2が未設定ならその値はEOLTTRなのでrk_inputと等しくない。 */
746 romkan_delete (cur_rk->rk_input); /* V3.1 */
747 }
748 else
749 {
750 ltr1cat (cur_rk->keybuf, cur_rk->rk_input);
751 ltr1cat (cur_rk->disout, toNISE (cur_rk->rk_input));
752 match ();
753 }
754
755 if (!(cur_rk->flags & RK_CHMOUT))
756 {
757 /* chmoutflgが0の時は、CHMSIGを出さない。 */
758 for (p = DISOUT;; p++)
759 {
760 while (*p == CHMSIG)
761 ltrcpy (p, p + 1);
762 if (*p == EOLTTR)
763 break;
764 }
765 }
766
767 if ((cur_rk->flags & RK_REDRAW) && NULL != (p = ltr_rindex (cur_rk->disout, cur_rk->nisedl)))
768 {
769 for (p++; *p != EOLTTR || (ltr1cat (cur_rk->disout, REDRAW), 0); p++)
770 if (!isSPCL (*p))
771 break;
772 }
773 /* wnnのredrawのフラグが立っていて、disoutがnisedl以後特殊コードのみ
774 で終わっていたら、REDRAWを出して、Wnnに変換行のredrawをさせる。 */
775
776 return (DISOUT);
777 }
778
779
780 /******************************************************************************/
781 /* デバッグ用関数 */
782 #ifdef KDSP
783 # ifdef MVUX
784
785 pridbg2 (a, b, c)
786 char *a, *c;
787 letter *b;
788 {
789 printf ("%s", a);
790 dump_fordbg (b);
791 printf ("%s", c);
792 }
793
794 ltr_displen (l)
795 letter l;
796 {
797 while (l >= 256)
798 l >>= 8;
799
800 if (l == 0)
801 return (0);
802 if (l < ' ')
803 return (0);
804 if (168 <= l && l <= 170)
805 return (1);
806 return (l > 160 ? 2 : 1);
807 }
808
809 dump_fordbg (lp)
810 letter *lp;
811 {
812 while (*lp != EOLTTR)
813 printf ("%x/", *lp++);
814 }
815
816 print_fordbg (lp)
817 letter *lp;
818 {
819 while (*lp != EOLTTR)
820 putletter (*lp++ & ~HG1BIT);
821 }
822
823 print_ltrseq (lp)
824 letter *lp;
825 {
826 while (*lp != EOLTTR)
827 print_ltr (*lp++ & ~HG1BIT);
828 }
829
830 print_ltr (l)
831 letter l;
832 {
833 letter *disptail;
834 int i;
835
836 if (!isSPCL (l))
837 l &= ~HG1BIT;
838
839 if (l == CHMSIG)
840 #ifdef CHMDSP
841 printf ("...mode=%s\n", romkan_dispmode ())
842 #endif
843 ;
844 else
845 #define BEEPCH '\007'
846 #define NEWLIN '\n'
847 if (l == BEEPCH || l == NISEBP)
848 putchar (BEEPCH);
849 else if (l == NEWLIN)
850 {
851 *(cur_rk->displine) = *(cur_rk->keybuf) = *(cur_rk->urabuf) = EOLTTR;
852 cur_rk->lastoutlen = cur_rk->lastkbflen = 0;
853 putchar (l);
854 }
855 else if (l == cur_rk->delchr || l == cur_rk->nisedl)
856 {
857 if (*(cur_rk->displine) == EOLTTR)
858 putchar (BEEPCH);
859 else
860 {
861 disptail = ltrend (cur_rk->displine);
862 for (i = ltr_displen (*disptail); i; i--)
863 printf ("\031 \031");
864 *disptail = EOLTTR;
865 }
866 }
867 else
868 {
869 ltr1cat (cur_rk->displine, l);
870 putletter (l);
871 }
872 }
873
874 # endif /* of #ifdef MVUX */
875 #endif
876 /* デバッグ用関数終わり */
877
878
879 /* 88/06/10 V3.1 */
880 /** DELが入力されたときの処理をする */
881 static /* V3.1 */
882 void
883 romkan_delete (input_del)
884 letter input_del;
885 {
886 if (ltrlen (cur_rk->keybuf) > ((cur_rk->flags & RK_SIMPLD) ? 0 : cur_rk->lastkbflen))
887 {
888 ltr1cut (cur_rk->keybuf);
889 set_rubout (cur_rk->disout, 1, cur_rk->nisedl);
890 }
891 else
892 {
893 if (*(cur_rk->urabuf) != EOLTTR && !(cur_rk->flags & RK_SIMPLD))
894 {
895 ltr1cut (ltrcpy (cur_rk->keybuf, cur_rk->urabuf));
896 *(cur_rk->urabuf) = EOLTTR;
897
898 set_rubout (cur_rk->rk_output, cur_rk->lastoutlen, input_del);
899
900 set_rubout (cur_rk->disout, cur_rk->lastkbflen, cur_rk->nisedl);
901 bitup_ltrcat (ltrcat (cur_rk->disout, cur_rk->rk_output), cur_rk->keybuf);
902
903 cur_rk->lastkbflen = cur_rk->lastoutlen = 0;
904 }
905 else
906 {
907 set_rubout (cur_rk->disout, 1, input_del);
908 set_rubout (cur_rk->rk_output, 1, input_del);
909 }
910 }
911 }
912
913 /** letterの列 lp1 と lp2 のマッチを試みる。返値は、lp1がlp2の頭部と
914 一致の時 -1、lp1またはその頭部とlp2が一致のときは一致長(lp2が
915 空文字列の時を含む。この場合返値は0)、それ以外は -2。
916 lp2側に式が含まれていたら評価をする。lp1側には式を含んではだめ */
917 static /* V3.1 */
918 int
919 prefixp (lp1, lp2)
920 letter *lp1, *lp2;
921 {
922 /* 1行マッチさせるごとに、まずmatch情報をクリアしてから。
923 つまり、rk_henmatch.point[0].ltrmch = EOLTTR; としておく。 */
924
925 fast int mch_len = 0, d_len; /* V3.1 */
926
927 for (;;)
928 {
929 if (*lp2 == EOLTTR)
930 return (mch_len);
931 if (*lp1 == EOLTTR)
932 return (-1);
933 if ((d_len = p_eq (&lp2, &lp1)) < 0)
934 return (d_len);
935 mch_len += d_len;
936 }
937 }
938
939 /** num番目の変数が既にある文字とマッチしていると仮定して、その文字を返す */
940 static /* V3.1 */
941 letter
942 mchedsrc (num)
943 fast int num; /* V3.1 */
944 {
945 fast matchpair *pairptr; /* V3.1 */
946
947 if (cur_rk->rk_henmatch.size <= 0)
948 return (0);
949 for (pairptr = cur_rk->rk_henmatch.point; pairptr->ltrmch != EOLTTR; pairptr++)
950 {
951 if (num == pairptr->hennum)
952 return (pairptr->ltrmch);
953 }
954 return (BUGreport (8), 0);
955 }
956
957 /** num番目の変数が文字 l とマッチするか調べる。その変数がunboundだった
958 場合は l にbindする。マッチしたら(bindの時を含む)1、しないと0を返す */
959 static /* V3.1 */
960 int
961 mchsrc (num, l)
962 fast int num; /* V3.1 */
963 fast letter l; /* V3.1 */
964 {
965 fast matchpair *pairptr; /* V3.1 */
966
967 if (hen_ikisrc (num, l) == 0)
968 return (0);
969 if (cur_rk->rk_henmatch.size <= 0)
970 return (0);
971 for (pairptr = cur_rk->rk_henmatch.point; pairptr->ltrmch != EOLTTR; pairptr++)
972 {
973 if (num == pairptr->hennum)
974 return (pairptr->ltrmch == l);
975 }
976
977 pairptr->ltrmch = l;
978 pairptr->hennum = num;
979 (++pairptr)->ltrmch = EOLTTR;
980 return (1);
981 }
982
983 /** l1pから一単位を取って評価し、文字l2と一致するかどうかを返す。評価した
984 結果が一文字にならなかったら、当然一致しない。*/
985 static /* V3.1 */
986 int
987 l_eq (l1p, l2)
988 letter *l1p, l2;
989 {
990 letter evlrsl[RSLMAX];
991
992 switch (SHUBET (*l1p))
993 {
994 case 0:
995 return (*l1p == l2);
996 case 1:
997 return (mchsrc ((int) LWRMSK (*l1p), l2));
998 case 2:
999 mchevl (&l1p, evlrsl);
1000 return (evlrsl[0] == l2 && evlrsl[1] == EOLTTR);
1001 default:
1002 return (BUGreport (1), 0);
1003 }
1004 }
1005
1006 /** prefixp内で使用 但し引数の順序は逆、すなわち式が含まれうるのはl1pp側
1007 のみ。l1ppから一単位ぶん取って評価したものとl2ppのマッチを試みる。それ
1008 がl2ppまたはその頭部とマッチすれば一致長を返し(l1ppの評価結果が空文字
1009 列の時を含む。この場合返値は0)、逆にl1ppの評価結果の頭部とl2ppがマッ
1010 チした時は -1を返す。マッチが失敗したら返値は -2。*/
1011 static /* V3.1 */
1012 int
1013 p_eq (l1pp, l2pp)
1014 fast letter **l1pp, **l2pp; /* V3.1 */
1015 {
1016 int num;
1017 letter evlrsl[RSLMAX], *rslptr;
1018 fast int retval = -2; /* V3.1 */
1019
1020 /* l2pp側には式を含まない筈 */
1021 if (!is_HON (**l2pp))
1022 {
1023 /* if(is_HON(**l1pp)) retval = p_eq(l2pp, l1pp); else */
1024 BUGreport (9);
1025 }
1026 else
1027 {
1028 switch (SHUBET (**l1pp))
1029 {
1030 case 0: /* 文字同士 */
1031 retval = (*(*l1pp)++ == *(*l2pp)++ ? 1 : -2);
1032 break;
1033 case 1: /* 変数と文字 */
1034 num = LWRMSK (*(*l1pp)++);
1035 retval = (mchsrc (num, *(*l2pp)++) ? 1 : -2);
1036 break;
1037 case 2: /* 式と文字 */
1038 mchevl (l1pp, rslptr = evlrsl);
1039 for (retval = 0; *rslptr != EOLTTR; retval++)
1040 {
1041 if (**l2pp == EOLTTR)
1042 {
1043 retval = -1;
1044 break;
1045 }
1046 else if (*rslptr++ != *(*l2pp)++)
1047 {
1048 retval = -2;
1049 break;
1050 }
1051 }
1052 break;
1053 default:
1054 BUGreport (2);
1055 }
1056 }
1057
1058 return (retval);
1059 }
1060
1061 /** l1pから一単位評価してl2pに入れる */
1062 #ifdef MULTI
1063
1064
1065 #define XY2INT(X, Y) (((X) << 24) | (Y)) /* これが1回しかYを評価しないことに
1066 依存して書いてある箇所がある 注意! */
1067
1068 /** l1pから一単位評価してl2pに入れる */
1069 static void
1070 mchevl (l1pp, l2p)
1071 letter **l1pp, *l2p;
1072 {
1073 letter *l1p, tmpevl[RSLMAX];
1074
1075 l1p = *l1pp;
1076
1077 switch (SHUBET (*l1p))
1078 {
1079 case 0:
1080 *l2p++ = *l1p++;
1081 break;
1082 case 1:
1083 *l2p++ = mchedsrc ((int) LWRMSK (*l1p++));
1084 break;
1085 case 2: /* toupper, tolower, error, … */
1086 switch (LWRMSK (*l1p++))
1087 {
1088 case 2:
1089 mchevl (&l1p, tmpevl);
1090 *l2p++ = to_upper (*tmpevl);
1091 break;
1092 case 3:
1093 mchevl (&l1p, tmpevl);
1094 *l2p++ = to_lower (*tmpevl);
1095 break;
1096 case 4:
1097 *l2p++ = CHMSIG;
1098 *l2p++ = *l1p++;
1099 *l2p++ = 0;
1100 break; /* EOLではない */
1101 case 5:
1102 *l2p++ = CHMSIG;
1103 *l2p++ = *l1p++;
1104 *l2p++ = 1;
1105 break;
1106 case 6:
1107 *l2p++ = CHMSIG;
1108 *l2p++ = *l1p++;
1109 *l2p++ = 2;
1110 break;
1111 case 7:
1112 mchevl (&l1p, tmpevl);
1113 *l2p++ = to_updown (*tmpevl);
1114 break;
1115 case 8:
1116 mchevl (&l1p, tmpevl);
1117 *l2p++ = to_zenalpha (*tmpevl);
1118 break;
1119 case 9:
1120 mchevl (&l1p, tmpevl);
1121 *l2p++ = to_hira (*tmpevl);
1122 break;
1123 case 10:
1124 mchevl (&l1p, tmpevl);
1125 *l2p++ = to_kata (*tmpevl);
1126 break;
1127 case 11:
1128 mchevl (&l1p, tmpevl);
1129 to_hankata (*tmpevl, &l2p);
1130 break; /* 特殊 */
1131 case 12:
1132 mchevl (&l1p, tmpevl);
1133 *l2p++ = to_zenhira (*tmpevl);
1134 break;
1135 case 13:
1136 mchevl (&l1p, tmpevl);
1137 *l2p++ = to_zenkata (*tmpevl);
1138 break;
1139 case 14:
1140 mchevl (&l1p, tmpevl);
1141 *l2p = *tmpevl;
1142 mchevl (&l1p, tmpevl);
1143 *l2p += *tmpevl;
1144 LWRCUT (*l2p++);
1145 break;
1146 case 15:
1147 mchevl (&l1p, tmpevl);
1148 *l2p = *tmpevl;
1149 mchevl (&l1p, tmpevl);
1150 *l2p -= *tmpevl;
1151 LWRCUT (*l2p++);
1152 break;
1153 case 16:
1154 mchevl (&l1p, tmpevl);
1155 *l2p = *tmpevl;
1156 mchevl (&l1p, tmpevl);
1157 *l2p *= *tmpevl;
1158 LWRCUT (*l2p++);
1159 break;
1160 case 17:
1161 mchevl (&l1p, tmpevl);
1162 *l2p = *tmpevl;
1163 mchevl (&l1p, tmpevl);
1164 if (!*tmpevl)
1165 *l2p = LTRHUG;
1166 else
1167 *l2p /= *tmpevl;
1168 LWRCUT (*l2p++);
1169 break;
1170 case 18:
1171 mchevl (&l1p, tmpevl);
1172 *l2p = *tmpevl;
1173 mchevl (&l1p, tmpevl);
1174 if (!*tmpevl)
1175 *l2p = LTRHUG;
1176 else
1177 *l2p %= *tmpevl;
1178 LWRCUT (*l2p++);
1179 break;
1180 /* 19〜21・30は、条件を満たすと空文字列、
1181 そうでないとUNUSDCを文字列として返す。 */
1182 case 19:
1183 mchevl (&l1p, tmpevl);
1184 if (lastmch () != *tmpevl)
1185 *l2p++ = UNUSDC;
1186 break;
1187 case 20:
1188 if (!(cur_rk->rk_modesw.point)[LWRMSK (*l1p++)])
1189 *l2p++ = UNUSDC;
1190 break;
1191 case 21:
1192 if (cur_rk->rk_modesw.point[LWRMSK (*l1p++)])
1193 *l2p++ = UNUSDC;
1194 break;
1195 case 22:
1196 *l2p++ = REASIG;
1197 break;
1198 case 23:
1199 *l2p++ = cur_rk->delchr;
1200 break;
1201 case 24:
1202 *l2p++ = CHMSIG;
1203 *l2p++ = 0; /* これで「all」を表す */
1204 *l2p++ = 0;
1205 break;
1206 case 25:
1207 *l2p++ = CHMSIG;
1208 *l2p++ = 0;
1209 *l2p++ = 1;
1210 break;
1211 case 26:
1212 mchevl (&l1p, tmpevl);
1213 *l2p = *tmpevl;
1214 mchevl (&l1p, tmpevl);
1215 *l2p &= *tmpevl;
1216 LWRCUT (*l2p++);
1217 break;
1218 case 27:
1219 mchevl (&l1p, tmpevl);
1220 *l2p = *tmpevl;
1221 mchevl (&l1p, tmpevl);
1222 *l2p |= *tmpevl;
1223 LWRCUT (*l2p++);
1224 break;
1225 case 28:
1226 mchevl (&l1p, tmpevl);
1227 *l2p = ~(*tmpevl);
1228 LWRCUT (*l2p++);
1229 break;
1230 case 29:
1231 *l2p++ = URBFCL;
1232 break;
1233 case 30:
1234 if (cur_rk->eofflg != 2 || *(cur_rk->keybuf) != EOLTTR)
1235 *l2p++ = UNUSDC;
1236 break;
1237 case 31:
1238 {
1239 letter code, basenum;
1240
1241 mchevl (&l1p, tmpevl);
1242 code = *tmpevl;
1243 mchevl (&l1p, tmpevl);
1244 if ((basenum = *tmpevl) <= 1 || BASEMX < basenum)
1245 basenum = 10;
1246 to_digit (code, basenum, &l2p);
1247 }
1248 break;
1249 case 32:
1250 mchevl (&l1p, tmpevl);
1251 dakuadd (*tmpevl, &l2p);
1252 break; /* 特殊 */
1253 case 33:
1254 mchevl (&l1p, tmpevl);
1255 handakuadd (*tmpevl, &l2p);
1256 break; /* 特殊 */
1257 case 34:
1258 mchevl (&l1p, tmpevl);
1259 *l2p++ = ltov (*tmpevl);
1260 break;
1261 case 35:
1262 *l2p++ = ERRCOD;
1263 break;
1264 /* case 36: omitted */
1265 case 37:
1266 *l2p++ = CHMSIG;
1267 /*
1268 *l2p++ = LWRMSK(*l1p++);
1269 */
1270 *l2p++ = *l1p++;
1271 *l2p++ = *l1p++;
1272 break;
1273 case 38:
1274 *l2p++ = CHMSIG;
1275 *l2p++ = XY2INT (2, LWRMSK (*l1p++));
1276 *l2p++ = *l1p++;
1277 break;
1278 case 39:
1279 *l2p++ = CHMSIG;
1280 *l2p++ = XY2INT (3, LWRMSK (*l1p++));
1281 *l2p++ = *l1p++;
1282 break;
1283 case 40:
1284 {
1285 letter modnum;
1286
1287 modnum = LWRMSK (*l1p++);
1288 if (cur_rk->rk_modesw.point[modnum] != *l1p++)
1289 *l2p++ = UNUSDC;
1290 break;
1291 }
1292 case 41:
1293 {
1294 letter modnum;
1295
1296 modnum = LWRMSK (*l1p++);
1297 if (cur_rk->rk_modesw.point[modnum] == *l1p++)
1298 *l2p++ = UNUSDC;
1299 break;
1300 }
1301 case 42:
1302 {
1303 letter modnum;
1304
1305 modnum = LWRMSK (*l1p++);
1306 if (cur_rk->rk_modesw.point[modnum] >= *l1p++)
1307 *l2p++ = UNUSDC;
1308 break;
1309 }
1310 case 43:
1311 {
1312 letter modnum;
1313
1314 modnum = LWRMSK (*l1p++);
1315 if (cur_rk->rk_modesw.point[modnum] <= *l1p++)
1316 *l2p++ = UNUSDC;
1317 break;
1318 }
1319 case 44:
1320 mchevl (&l1p, tmpevl);
1321 *l2p++ = SENDCH;
1322 *l2p++ = *tmpevl;
1323 break;
1324 default: /* case 0及び上記以外 */ ;
1325 BUGreport (7);
1326 }
1327 }
1328
1329 *l2p = EOLTTR;
1330 *l1pp = l1p;
1331 }
1332 #else /*!MULTI */
1333 static /* V3.1 */
1334 mchevl (l1pp, l2p)
1335 letter **l1pp, *l2p;
1336 {
1337 letter *l1p, tmpevl[RSLMAX];
1338
1339 l1p = *l1pp;
1340
1341 switch (SHUBET (*l1p))
1342 {
1343 case 0:
1344 *l2p++ = *l1p++;
1345 break;
1346 case 1:
1347 *l2p++ = mchedsrc ((int) LWRMSK (*l1p++));
1348 break;
1349 case 2: /* toupper, tolower, error, … */
1350 switch (LWRMSK (*l1p++))
1351 {
1352 case 1:
1353 mchevl (&l1p, tmpevl);
1354 *l2p++ = to_upper (*tmpevl);
1355 break;
1356 case 2:
1357 mchevl (&l1p, tmpevl);
1358 *l2p++ = to_lower (*tmpevl);
1359 break;
1360 case 3:
1361 *l2p++ = ERRCOD;
1362 break;
1363 case 4:
1364 *l2p++ = CHMSIG;
1365 *l2p++ = *l1p++;
1366 *l2p++ = 0;
1367 break; /* EOLではない */
1368 case 5:
1369 *l2p++ = CHMSIG;
1370 *l2p++ = *l1p++;
1371 *l2p++ = 1;
1372 break;
1373 case 6:
1374 *l2p++ = CHMSIG;
1375 *l2p++ = *l1p++;
1376 *l2p++ = 2;
1377 break;
1378 case 7:
1379 mchevl (&l1p, tmpevl);
1380 *l2p++ = to_updown (*tmpevl);
1381 break;
1382 case 8:
1383 mchevl (&l1p, tmpevl);
1384 *l2p++ = to_zenalpha (*tmpevl);
1385 break;
1386 case 9:
1387 mchevl (&l1p, tmpevl);
1388 *l2p++ = to_hira (*tmpevl);
1389 break;
1390 case 10:
1391 mchevl (&l1p, tmpevl);
1392 *l2p++ = to_kata (*tmpevl);
1393 break;
1394 case 11:
1395 mchevl (&l1p, tmpevl);
1396 to_hankata (*tmpevl, &l2p);
1397 break; /* 特殊 */
1398 case 12:
1399 mchevl (&l1p, tmpevl);
1400 *l2p++ = to_zenhira (*tmpevl);
1401 break;
1402 case 13:
1403 mchevl (&l1p, tmpevl);
1404 *l2p++ = to_zenkata (*tmpevl);
1405 break;
1406 case 14:
1407 mchevl (&l1p, tmpevl);
1408 *l2p = *tmpevl;
1409 mchevl (&l1p, tmpevl);
1410 *l2p += *tmpevl;
1411 LWRCUT (*l2p++);
1412 break;
1413 case 15:
1414 mchevl (&l1p, tmpevl);
1415 *l2p = *tmpevl;
1416 mchevl (&l1p, tmpevl);
1417 *l2p -= *tmpevl;
1418 LWRCUT (*l2p++);
1419 break;
1420 case 16:
1421 mchevl (&l1p, tmpevl);
1422 *l2p = *tmpevl;
1423 mchevl (&l1p, tmpevl);
1424 *l2p *= *tmpevl;
1425 LWRCUT (*l2p++);
1426 break;
1427 case 17:
1428 mchevl (&l1p, tmpevl);
1429 *l2p = *tmpevl;
1430 mchevl (&l1p, tmpevl);
1431 if (!*tmpevl)
1432 *l2p = LTRHUG;
1433 else
1434 *l2p /= *tmpevl;
1435 LWRCUT (*l2p++);
1436 break;
1437 case 18:
1438 mchevl (&l1p, tmpevl);
1439 *l2p++ = ltov (*tmpevl);
1440 break;
1441 /* 19〜21・30は、条件を満たすと空文字列、
1442 そうでないとUNUSDCを文字列として返す。 */
1443 case 19:
1444 mchevl (&l1p, tmpevl);
1445 if (lastmch () != *tmpevl)
1446 *l2p++ = UNUSDC;
1447 break;
1448 case 20:
1449 if (!(cur_rk->rk_modesw.point)[LWRMSK (*l1p++)])
1450 *l2p++ = UNUSDC;
1451 break;
1452 case 21:
1453 if (cur_rk->rk_modesw.point[LWRMSK (*l1p++)])
1454 *l2p++ = UNUSDC;
1455 break;
1456 case 22:
1457 *l2p++ = REASIG;
1458 break;
1459 case 23:
1460 *l2p++ = cur_rk->delchr;
1461 break;
1462 case 24:
1463 *l2p++ = CHMSIG;
1464 *l2p++ = 0; /* これで「all」を表す */
1465 *l2p++ = 0;
1466 break;
1467 case 25:
1468 *l2p++ = CHMSIG;
1469 *l2p++ = 0;
1470 *l2p++ = 1;
1471 break;
1472 case 26:
1473 mchevl (&l1p, tmpevl);
1474 *l2p = *tmpevl;
1475 mchevl (&l1p, tmpevl);
1476 *l2p &= *tmpevl;
1477 LWRCUT (*l2p++);
1478 break;
1479 case 27:
1480 mchevl (&l1p, tmpevl);
1481 *l2p = *tmpevl;
1482 mchevl (&l1p, tmpevl);
1483 *l2p |= *tmpevl;
1484 LWRCUT (*l2p++);
1485 break;
1486 case 28:
1487 mchevl (&l1p, tmpevl);
1488 *l2p = ~(*tmpevl);
1489 LWRCUT (*l2p++);
1490 break;
1491 case 29:
1492 *l2p++ = URBFCL;
1493 break;
1494 case 30:
1495 if (cur_rk->eofflg != 2 || *(cur_rk->keybuf) != EOLTTR)
1496 *l2p++ = UNUSDC;
1497 break;
1498 case 31:
1499 {
1500 letter code, basenum;
1501
1502 mchevl (&l1p, tmpevl);
1503 code = *tmpevl;
1504 mchevl (&l1p, tmpevl);
1505 if ((basenum = *tmpevl) <= 1 || BASEMX < basenum)
1506 basenum = 10;
1507 to_digit (code, basenum, &l2p);
1508 }
1509 break;
1510 case 32:
1511 mchevl (&l1p, tmpevl);
1512 dakuadd (*tmpevl, &l2p);
1513 break; /* 特殊 */
1514 case 33:
1515 mchevl (&l1p, tmpevl);
1516 handakuadd (*tmpevl, &l2p);
1517 break; /* 特殊 */
1518 default: /* case 0及び上記以降 */ ;
1519 BUGreport (7);
1520 }
1521 }
1522
1523 *l2p = EOLTTR;
1524 *l1pp = l1p;
1525 }
1526 #endif /*!MULTI */
1527
1528 /** num番目の変数の変域が文字 l を含むかどうかを返す */
1529 static /* V3.1 */
1530 int
1531 hen_ikisrc (num, l)
1532 int num;
1533 letter l;
1534 {
1535 fast letter *defptr; /* V3.1 */
1536
1537 defptr = cur_rk_table->rk_hyo.point[cur_rk->hyonum].hensudef[num]; /* V3.1 */
1538 if (*defptr == VARRNG)
1539 {
1540 for (defptr++; *defptr != EOLTTR;)
1541 if (*defptr++ <= l && l <= *defptr++)
1542 return (1);
1543 return (0);
1544 }
1545
1546 for (; *defptr != EOLTTR; defptr++)
1547 {
1548 if (l == *defptr)
1549 return (1);
1550 }
1551 return (0);
1552 }
1553
1554 /** 変換のメインルーチン。本処理を行うが、ついでに後処理もやっている。
1555 ちなみに前処理は、romkan_getcの下位関数romkan_henkanの中で、
1556 この関数を呼ぶ前にやっている。
1557 この関数は、romkan_nextから一文字来る度に呼ばれる。呼び出された直後は
1558 outputは空文字列、disoutには入力コード一文字が入っている。
1559 この関数で得られる文字の列が、romkan_henkanに渡り、
1560 romkan_getcは、それを文字ごとに分解して返す。
1561 (error)でエラーが引き起こされた場合は0を返し、正常終了時は1を返す */
1562 static /* V3.1 */
1563 int
1564 match ()
1565 {
1566 int henkanflg = 0, okcode = 0, chm_exist;
1567 letter *q; /* V3.1 */
1568 letter urabufcreate[KBFSIZ], orgkeybuf[KBFSIZ];
1569 letter *urabufjunbi, *outcutptr, *dis_end;
1570 /* 88/03/01/ V3.1 */
1571 letter nokoribuf[KBFSIZ];
1572
1573 if (*(cur_rk->keybuf) == EOLTTR)
1574 {
1575 *(cur_rk->urabuf) = EOLTTR;
1576 return (1);
1577 }
1578
1579 ltrcpy (urabufjunbi = orgkeybuf, cur_rk->keybuf);
1580 outcutptr = cur_rk->rk_output;
1581
1582 while ((okcode = henkan_ok ()) > 0)
1583 {
1584 henkanflg = 1;
1585
1586 codeout_chg ();
1587 ltrcat (cur_rk->rk_output, cur_rk->codeout);
1588 /* 88/03/01/ V3.1 */
1589 /*
1590 p = keybuf + codein_len;
1591
1592 ltrcat(ltrcpy(keybuf, remainkbf), p);
1593 */
1594 ltrcpy (nokoribuf, cur_rk->keybuf + cur_rk->codein_len);
1595 ltrcat (ltrcpy (cur_rk->keybuf, cur_rk->remainkbf), nokoribuf);
1596
1597 if (okcode == 2)
1598 {
1599 ltrcpy (urabufjunbi = urabufcreate, cur_rk->keybuf);
1600 totail (outcutptr);
1601 }
1602 }
1603
1604 if (okcode == 0)
1605 {
1606 ltr1cut (ltrcpy (cur_rk->keybuf, orgkeybuf));
1607 ltr_to_ltrseq (cur_rk->disout, NISEBP);
1608 *(cur_rk->rk_output) = EOLTTR;
1609 return (0);
1610 }
1611 if (henkanflg)
1612 {
1613 ltrcpy (cur_rk->urabuf, urabufjunbi);
1614
1615 set_rubout (cur_rk->disout, ltrlen (orgkeybuf) - 1, cur_rk->nisedl);
1616
1617 dis_end = cur_rk->disout;
1618 totail (dis_end);
1619 ltrcpy (dis_end, cur_rk->rk_output);
1620
1621 /* モードチェンジを直ちに知らせるため CHMSIGを出力
1622 (romkan_chmack(1)をやってないと、あとで一文字ずつに
1623 分解する時点で、CHMSIGをカット)。
1624 但し、rk_outputからは、CHMSIGを抜く。
1625 また、CHMSIGは末尾に1回しか出力しない
1626 (2回以上あっても、1回にまとめて、末尾に置く)。 */
1627 for (chm_exist = 0, q = cur_rk->rk_output;; q++)
1628 {
1629 while (*q == CHMSIG)
1630 {
1631 chm_exist = 1;
1632 if (ltrcpy (q, q + 1) < outcutptr)
1633 outcutptr--;
1634 }
1635 if (*q == EOLTTR)
1636 break;
1637 }
1638 if (chm_exist)
1639 {
1640 /* CHMSIGを1つにまとめたものをdis_endにつなげ直す。
1641 このif文をカットすれば、CHMSIGのとりまとめはやらない */
1642 ltr1cat (ltrcpy (dis_end, cur_rk->rk_output), CHMSIG);
1643 }
1644
1645 bitup_ltrcat (cur_rk->disout, cur_rk->keybuf);
1646 cur_rk->lastoutlen = ltrlen (outcutptr);
1647 cur_rk->lastkbflen = ltrlen (cur_rk->keybuf);
1648 }
1649 return (1);
1650 }
1651
1652 /** LTREOFが入ったときに、何か出すように指定されているか調べて、
1653 codeoutをその結果の文字列(指定がなかったら当然空)にポイントする。
1654 超急ごしらえで、特殊コード等は一切無視する。*/
1655 static /* V3.1 */
1656 void
1657 add_at_eof ()
1658 {
1659 fast dat *datptr; /* V3.1 */
1660 fast int i; /* V3.1 */
1661 fast int hyoseq; /* V3.1 */
1662 letter *p;
1663 letter evlrsl[RSLMAX];
1664
1665 /* 88/06/14 V3.1 */
1666 for (hyoseq = 0; cur_rk_table->rk_hyo.point != NULL && (cur_rk->hyonum = cur_rk->rk_usehyo.usehyo[hyoseq]) != -1; hyoseq++)
1667 {
1668 for (i = 0, datptr = cur_rk_table->rk_hyo.point[cur_rk->hyonum].data; (p = datptr[i].code[0]) != NULL; i++)
1669 {
1670 if (cur_rk->rk_henmatch.size > 0)
1671 {
1672 cur_rk->rk_henmatch.point[0].ltrmch = EOLTTR;
1673 }
1674 while (*p != EOLTTR)
1675 {
1676 switch (SHUBET (*p))
1677 {
1678 case 0: /* 文字 */
1679 case 1: /* 変数 */
1680 /* これらがある場合は、NULLとは
1681 マッチし得ない。 */
1682 goto Pass;
1683 case 2: /* 式 */
1684 mchevl (&p, evlrsl);
1685 if (*evlrsl != EOLTTR)
1686 goto Pass;
1687 /* 入力コード部に、評価すると
1688 空文字列になるものが、他にはない
1689 ことが前提。 */
1690 }
1691 }
1692
1693 ltrevlcpy (cur_rk->codeout = p = cur_rk->evalbuf[0][0], datptr[i].code[1]);
1694 while (*p != EOLTTR)
1695 {
1696 if (isSPCL (*p))
1697 ltrcpy (p, p + 1);
1698 else
1699 p++;
1700 }
1701 codeout_chg ();
1702 return;
1703
1704 Pass:;
1705 }
1706 }
1707 cur_rk->codeout = cur_rk->nil;
1708 }
1709
1710 /* 88/06/02 V3.1 */
1711 /** num番目のモードをチェンジし、変換表を選択し直す。引数 mod の値が0なら
1712 モードをoff、1ならon、2なら切り替える。旧modの値(0か1)を返す。*/
1713 static int
1714 chgmod (num, mod)
1715 int num, mod;
1716 {
1717 fast int oldmod; /* V3.1 */
1718
1719 oldmod = cur_rk->rk_modesw.point[num];
1720 cur_rk->rk_modesw.point[num] = (mod != 2 ? mod : !oldmod);
1721 choosehyo ();
1722 return (oldmod);
1723 }
1724
1725 /** 全モードを、modが1ならon、0ならoffに切り換える。2ならswitchする。*/
1726 static void
1727 allchgmod (mod)
1728 int mod;
1729 {
1730 fast int i; /* V3.1 */
1731
1732 /* 88/06/07 V3.1 */
1733 for (i = 0; i < cur_rk->rk_modesw.count; i++)
1734 cur_rk->rk_modesw.point[i] = (mod != 2 ? mod : !(cur_rk->rk_modesw.point[i]));
1735 choosehyo ();
1736 }
1737
1738 /** 一回マッチを試みる。返値は、マッチして確定した場合1(モードチェンジが
1739 混じっている場合は2)、マッチしたが未確定の時-1、マッチしなかったら0。
1740 実行中は、変数 l に、それまでに一致した長さの最高記録を入れており、
1741 より長く一致するものが見つかるごとに、これを更新する。lの値は、マッチ
1742 していても0になることもある。p_eq() 及び prefixp() の注釈文を参照。*/
1743 static /* V3.1 */
1744 int
1745 henkan_ok ()
1746 {
1747 fast dat *datptr; /* V3.1 */
1748 fast int i, k; /* V3.1 */
1749 fast int l, j, hyoseq; /* V3.1 */
1750 char urabuf_clrf; /* モードチェンジなどで、urabufをクリアする必要が
1751 生じた場合はこれが立ち、その結果、henkan_ok()
1752 が1を返すべきところで2を返す。それを見て、
1753 match()がurabufなどの調整をする。 */
1754 fast letter *p; /* V3.1 */
1755 #ifndef MULTI
1756 static char ebf_sw = 0; /* V3.1 */
1757 static letter oneletter[2] = { EOLTTR, EOLTTR }; /* V3.1 */
1758 #endif /*!MULTI */
1759
1760 if (*(cur_rk->keybuf) == EOLTTR)
1761 return (-1);
1762
1763 /* 88/06/14 V3.1 */
1764 for (l = -1, hyoseq = 0; cur_rk_table->rk_hyo.point != NULL && cur_rk->rk_usehyo.usehyo != NULL && (cur_rk->hyonum = cur_rk->rk_usehyo.usehyo[hyoseq]) != -1; hyoseq++)
1765 {
1766 for (i = 0, datptr = cur_rk_table->rk_hyo.point[cur_rk->hyonum].data; (p = datptr[i].code[0]) != NULL; i++)
1767 {
1768 if (cur_rk->rk_henmatch.size > 0)
1769 {
1770 cur_rk->rk_henmatch.point[0].ltrmch = EOLTTR;
1771 }
1772 switch (k = prefixp (cur_rk->keybuf, p))
1773 {
1774 case -2:
1775 break;
1776 case -1:
1777 if (cur_rk->eofflg != 0)
1778 break;
1779 /* eofflgが立っていたら、未確定の可能性は
1780 捨てる。 */
1781
1782 return (-1);
1783 default:
1784 if (k > l)
1785 {
1786 cur_rk->ebf_sw = !cur_rk->ebf_sw;
1787 for (j = 1; j <= 2; j++)
1788 {
1789 ltrevlcpy (cur_rk->evalbuf[cur_rk->ebf_sw][j - 1], datptr[i].code[j]);
1790 }
1791
1792 l = k;
1793 }
1794 }
1795 }
1796 }
1797
1798 if (l >= 0)
1799 {
1800 cur_rk->codein_len = l;
1801 cur_rk->codeout = cur_rk->evalbuf[cur_rk->ebf_sw][0];
1802 cur_rk->remainkbf = cur_rk->evalbuf[cur_rk->ebf_sw][1];
1803
1804 for (urabuf_clrf = 0, p = cur_rk->codeout; *p != EOLTTR; p++)
1805 {
1806 switch (*p)
1807 {
1808 case CHMSIG:
1809 /* codeoutの1,2バイト目に
1810 モード番号とスイッチが入ってる */
1811 if (*(p + 1) == 0)
1812 allchgmod ((int) *(p + 2));
1813 else
1814 chgmod ((int) LWRMSK (*(p + 1)), (int) *(p + 2));
1815 ltrcpy (p + 1, p + 3);
1816 /* CHMSIGだけ残して1,2バイト目cut */
1817
1818 urabuf_clrf = 1;
1819 break;
1820 case URBFCL:
1821 /* urabufのクリアを明示的に指定する */
1822 urabuf_clrf = 1;
1823 ltrcpy (p, p + 1);
1824 p--; /* 一文字前にずれるため、
1825 for文の p++ を相殺して、
1826 同じ地点をもう一度見る。 */
1827 break;
1828 }
1829 }
1830
1831 if (*(cur_rk->codeout) == ERRCOD)
1832 {
1833 if (cur_rk->eofflg == 0)
1834 {
1835 cur_rk->rk_errstat = 1;
1836 return (0);
1837 }
1838
1839 /* (error)であって、しかもeofflgが立ってたら、keybuf
1840 の末尾まで、そのまま出す。 */
1841 cur_rk->codein_len = ltrlen (cur_rk->keybuf);
1842 cur_rk->codeout = ltrcpy (cur_rk->evalbuf[cur_rk->ebf_sw][0], cur_rk->keybuf);
1843 cur_rk->remainkbf = cur_rk->nil;
1844 cur_rk->rk_errstat = 2;
1845
1846 return (1);
1847 }
1848 /* (error)は単独でしか書けないので、エラー検出はこれで十分。 */
1849
1850 if (*(cur_rk->codeout) == REASIG)
1851 {
1852 *(cur_rk->codeout) = (romkan_restart () != 0 ? EOLTTR : CHMSIG);
1853 /* 再readでエラったらモードチェンジの通知はしない */
1854
1855 urabuf_clrf = 1;
1856 }
1857 /* 表の再read。但し、これが起こったことを外に知らせるのはCHMSIGで
1858 このコードそのものは外へ出ない。(restart)は、(error)同様、
1859 単独でしか書けないので、検出はこれで十分。 */
1860
1861 return (urabuf_clrf ? 2 : 1);
1862 }
1863
1864 /* 表に現れていないコードはそのまま返す */
1865
1866 cur_rk->codein_len = 1;
1867 *(cur_rk->codeout = cur_rk->oneletter) = *(cur_rk->keybuf);
1868 cur_rk->remainkbf = cur_rk->nil;
1869 return (1);
1870 }
1871
1872 static void
1873 free_for_all_area ()
1874 {
1875 fast int i;
1876
1877 free_for_modetable_struct (&(cur_rk_table->rk_defmode));
1878 free_for_modetable_struct (&(cur_rk_table->rk_taiouhyo));
1879 free_for_modetable_struct (&(cur_rk_table->rk_path));
1880 free_for_modebuf (&(cur_rk_table->rk_modebuf));
1881 free_for_hyobuf (&(cur_rk_table->rk_hyobuf));
1882 free_for_heniki (&(cur_rk_table->rk_heniki));
1883 free_for_hensuu (&(cur_rk_table->rk_hensuu));
1884
1885 free_for_modetable_struct (&(cur_rk_table->rk_dspmode));
1886 /* free_for_modesw(&(cur_rk_table->rk_modesw)); */
1887 free_for_modenaibu (&(cur_rk_table->rk_modenaibu));
1888 for (i = 0; i < cur_rk_table->rk_hyo.size; i++)
1889 {
1890 free_for_hyo_area (&(cur_rk_table->rk_hyo), i);
1891 }
1892 free_for_hyo (&(cur_rk_table->rk_hyo));
1893 /* free_for_usehyo(&(cur_rk_table->rk_usehyo)); */
1894 free_for_hensuudef (&(cur_rk_table->rk_hensuudef));
1895 /* free_for_henmatch(&(cur_rk_table->rk_henmatch)); */
1896 }
1897
1898 /* 88/06/10 V3.1 */
1899 /* romkan_restart内で使うマクロ */
1900 #define taihi(X, Y) {(X) = (Y);}
1901 #define clear(X, N) {memset((char *)(&(X)), 0, (N));}
1902 #define recov(X, Y) taihi((Y), (X))
1903
1904 /** 表の動的再読み込みをする。現在の内部表現を全て退避し、前と同じ
1905 ディレクトリ(に、現在のところ限定)から表を読み込む。もし、
1906 読み込み中にエラーを検出すれば、もとの内部データを復活し非0を返す。*/
1907 static /* V3.1 */
1908 int
1909 romkan_restart ()
1910 {
1911 fast int i /*, j */ ; /* V3.1 */
1912 RomkanTable *rk_t = cur_rk_table;
1913
1914 modenaibutable rk_modenaibu_sv;
1915 modeswtable rk_modesw_sv;
1916 modetable rk_dspmode_sv;
1917 hyotable rk_hyo_sv;
1918 /* usehyotable rk_usehyo_sv; */
1919 hensuudeftable rk_hensuudef_sv;
1920 /* matchtable rk_henmatch_sv; */
1921
1922 /* char *dspmod_sv[2][2]; */
1923
1924 /* 待避 */
1925 taihi (rk_modenaibu_sv, rk_t->rk_modenaibu);
1926 taihi (rk_modesw_sv, rk_t->rk_modesw);
1927 taihi (rk_dspmode_sv, rk_t->rk_dspmode);
1928 taihi (rk_hyo_sv, rk_t->rk_hyo);
1929 /* taihi(rk_usehyo_sv, rk_t->rk_usehyo); */
1930 taihi (rk_hensuudef_sv, rk_t->rk_hensuudef);
1931 /* taihi(rk_henmatch_sv, rk_t->rk_henmatch);
1932
1933 for(i = 0; i < 2; i++)
1934 for(j = 0; j < 2; j++) dspmod_sv[i][j] = rk_t->dspmod[i][j];
1935 */
1936
1937 /* 消去 */
1938 clear (rk_t->rk_modenaibu, sizeof (modenaibutable));
1939 clear (rk_t->rk_modesw, sizeof (modeswtable));
1940 clear (rk_t->rk_dspmode, sizeof (modetable));
1941 clear (rk_t->rk_hyo, sizeof (hyotable));
1942 /* clear(rk_t->rk_usehyo, sizeof(usehyotable)); */
1943 clear (rk_t->rk_hensuudef, sizeof (hensuudeftable));
1944 /* clear(rk_t->rk_henmatch, sizeof(matchtable)); */
1945
1946 if (NULL != romkan_table_init (rk_t, rk_t->prv_modfnm, rk_t->keyin_method, rk_t->bytcnt_method, rk_t->kbytcnt_method, rk_t->flags))
1947 {
1948 /* 正常終了 */
1949 /* 88/06/10 V3.1 */
1950 /* 不要領域の削除 */
1951 free_for_modenaibu (&rk_modenaibu_sv);
1952 free_for_modesw (&rk_modesw_sv);
1953 free_for_modetable_struct (&rk_dspmode_sv);
1954 for (i = 0; i < rk_hyo_sv.size; i++)
1955 {
1956 free_for_hyo_area (&rk_hyo_sv, i);
1957 }
1958 free_for_hyo (&rk_hyo_sv);
1959 /* free_for_usehyo(&rk_usehyo_sv); */
1960 free_for_hensuudef (&rk_hensuudef_sv);
1961 /* free_for_henmatch(&rk_henmatch_sv); */
1962
1963 return (0);
1964 }
1965
1966 /* 異常終了 */
1967 /* 88/06/10 V3.1 */
1968 /* 不要領域の削除 */
1969 free_for_modenaibu (&(rk_t->rk_modenaibu));
1970 free_for_modesw (&(rk_t->rk_modesw));
1971 free_for_modetable_struct (&(rk_t->rk_dspmode));
1972 for (i = 0; i < rk_t->rk_hyo.size; i++)
1973 {
1974 free_for_hyo_area (&(rk_t->rk_hyo), i);
1975 }
1976 free_for_hyo (&(rk_t->rk_hyo));
1977 /* free_for_usehyo(&(rk_t->rk_usehyo)); */
1978 free_for_hensuudef (&(rk_t->rk_hensuudef));
1979 /* free_for_henmatch(&(rk_t->rk_henmatch)); */
1980
1981 /* 復帰 */
1982 recov (rk_modenaibu_sv, rk_t->rk_modenaibu);
1983 recov (rk_modesw_sv, rk_t->rk_modesw);
1984 recov (rk_dspmode_sv, rk_t->rk_dspmode);
1985 recov (rk_hyo_sv, rk_t->rk_hyo);
1986 /* recov(rk_usehyo_sv, rk_t->rk_usehyo); */
1987 recov (rk_hensuudef_sv, rk_t->rk_hensuudef);
1988 /* recov(rk_henmatch_sv, rk_t->rk_henmatch);
1989
1990 for(i = 0; i < 2; i++)
1991 for(j = 0; j < 2; j++) rk_t->dspmod[i][j] = dspmod_sv[i][j];
1992 */
1993 return (1);
1994 }
1995
1996 /** lp2から評価して得た文字列をlp1にコピー */
1997 static /* V3.1 */
1998 void
1999 ltrevlcpy (lp1, lp2)
2000 letter *lp1, *lp2;
2001 {
2002 while (*lp2 != EOLTTR)
2003 {
2004 mchevl (&lp2, lp1);
2005 totail (lp1);
2006 }
2007 *lp1 = EOLTTR;
2008 }
2009
2010 static /* V3.1 */
2011 void
2012 set_rubout (lp, n, del)
2013 /** lpに 「del」n個の列をセットする。ここに del は 'delchr'か'nisedl' */
2014 fast letter *lp, del; /* V3.1 */
2015 fast int n; /* V3.1 */
2016 {
2017 for (; n; n--)
2018 *lp++ = del;
2019 *lp = EOLTTR;
2020 }
2021
2022 /** これが実行されたらバグ。但し実行はそのまま続く */
2023 #ifdef OMRON_LIB
2024 static
2025 #endif
2026 void
2027 BUGreport (n)
2028 int n;
2029 {
2030 fprintf (stderr, "\r\nromkan-Bug%d!!\r\n", n);
2031 }
2032
2033 /** 前処理(mae_in→mae_out)又は後処理(ato_in→ato_out)を行う。*/
2034 static /* V3.1 */
2035 void
2036 maeato_henkan (in, outp, m_a_hyo)
2037 letter in; /* 入力の一文字 */
2038 letter *outp; /* 出力はここに入る */
2039 int *m_a_hyo; /* どの前・後処理表が選択されているかの情報 */
2040 {
2041 fast dat *datptr; /* V3.1 */
2042 fast int i, hyoseq; /* V3.1 */
2043 fast letter *curdat; /* V3.1 */
2044
2045 if (isSPCL (in))
2046 {
2047 /* LTREOFやCHMSIGが来うるので、特殊コードはそのまま返すように
2048 細工しておかないといけない。 */
2049 ltr_to_ltrseq (outp, in);
2050 return;
2051 }
2052
2053 /* 88/06/14 V3.1 */
2054 for (hyoseq = 0; m_a_hyo != NULL && (cur_rk->hyonum = m_a_hyo[hyoseq]) != -1; hyoseq++)
2055 {
2056 for (i = 0, datptr = cur_rk_table->rk_hyo.point[cur_rk->hyonum].data; NULL != (curdat = datptr[i].code[0]); i++)
2057 {
2058 if (cur_rk->rk_henmatch.size > 0)
2059 {
2060 cur_rk->rk_henmatch.point[0].ltrmch = EOLTTR;
2061 }
2062 if (!l_eq (curdat, in))
2063 continue;
2064
2065 ltrevlcpy (outp, datptr[i].code[1]);
2066 return;
2067 }
2068 }
2069 ltr_to_ltrseq (outp, in);
2070 }
2071
2072 /** 後処理 */
2073 static /* V3.1 */
2074 void
2075 codeout_chg ()
2076 {
2077 fast letter *saishu_outp; /* V3.1 */
2078 letter saishu_out[OUTSIZ]; /* V3.1 */
2079
2080 *(saishu_outp = saishu_out) = EOLTTR;
2081
2082 for (; *(cur_rk->codeout) != EOLTTR; cur_rk->codeout++)
2083 {
2084 maeato_henkan (*(cur_rk->codeout), saishu_outp, cur_rk->rk_usehyo.useatohyo);
2085 totail (saishu_outp);
2086 }
2087
2088 cur_rk->codeout = saishu_out;
2089 }
2090
2091 /** 一文字プッシュ・バック */
2092 /* *INDENT-OFF* */
2093 letter
2094 romkan_ungetc (l)
2095 letter l;
2096 /* *INDENT-ON* */
2097 {
2098 return (cur_rk->ungetc_buf = l);
2099 }
2100
2101 /** romkan_nextに対し一文字プッシュ・バック */
2102 /* *INDENT-OFF* */
2103 letter
2104 romkan_unnext (l)
2105 letter l;
2106 /* *INDENT-ON* */
2107 {
2108 return (cur_rk->unnext_buf = l);
2109 }
2110
2111 /* 88/06/02 V3.1 */
2112 /******************************************************************************/
2113 #ifndef OMRON
2114 /** deleteとして使うキャラクタの設定(偽deleteも)。これを実行後は
2115 romkan_clearを実行しておかないと混乱のもとになります。(廃止予定)*/
2116 void
2117 romkan_setdel (delchr_, nisedl_)
2118 letter delchr_, nisedl_;
2119 {
2120 cur_rk->delchr = delchr_;
2121 cur_rk->nisedl = nisedl_;
2122 }
2123 #endif
2124 /******************************************************************************/