Mercurial > freewnn
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 /******************************************************************************/ |