Mercurial > freewnn
comparison Wnn/conv/cvt_key.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: cvt_key.c,v 1.4 2002/05/12 22:47:03 hiroo 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 * Copyright FreeWnn Project 1999, 2000, 2002 | |
14 * | |
15 * Maintainer: FreeWnn Project <freewnn@tomo.gr.jp> | |
16 * | |
17 * This program is free software; you can redistribute it and/or modify | |
18 * it under the terms of the GNU General Public License as published by | |
19 * the Free Software Foundation; either version 2 of the License, or | |
20 * (at your option) any later version. | |
21 * | |
22 * This program is distributed in the hope that it will be useful, | |
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 * GNU General Public License for more details. | |
26 * | |
27 * You should have received a copy of the GNU General Public License | |
28 * along with this program; if not, write to the Free Software | |
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
30 */ | |
31 | |
32 /*********************************************************************** | |
33 convert_key.c ___ | |
34 87/12/19|訂補| | |
35  ̄ ̄ ̄ | |
36 タイムアウト処理を伴う、ファンクションキーコンバート処理。 | |
37 ***********************************************************************/ | |
38 /* Version 4.0 | |
39 */ | |
40 #include <signal.h> | |
41 #include <setjmp.h> | |
42 #include "cvt_head.h" | |
43 | |
44 /* | |
45 keyin1()を呼び出すためには、次の手続きが必要です。 | |
46 | |
47 (1) tgetent()(4.2BSD)もしくはsetupterm()(System V)によって、 | |
48 キーボードのterm情報が入っているエントリを読み込みます。 | |
49 (2) convert_getstrs() によって、読んだ情報を専用のエリアにコピーします。 | |
50 これによって、他のエントリのterm情報を読み込んでも、(1)で得た情報が | |
51 失われなくなります。 | |
52 (3) convert_key_setup()を呼び、変換の初期設定をします。 | |
53 | |
54 convert_getterm()によって、(1)と(2)が一度にできます。 | |
55 また、convert_key_init()によって(2)と(3)が、 | |
56 convert_getterm_init()によって(1)から(3)までが、それぞれ一度にできます。 | |
57 | |
58 なお、これらの convert_ で始まるライブラリ関数は、convert_read.c にて | |
59 定義されています。 | |
60 | |
61 4.2BSDの場合に旧版で呼ぶ必要のあったgetterm_fkeydata()は、 | |
62 不必要になったため廃止されました。 | |
63 */ | |
64 | |
65 extern struct CONVCODE tbl[]; | |
66 extern int cnv_tbl_cnt; /* convert table count */ | |
67 | |
68 | |
69 /** intの配列 h をビットベクタとみなし、第iビットをチェックあるいは立てる */ | |
70 #define BITONP(h, i) (h[i / BITSIZ] & (1 << (i % BITSIZ))) | |
71 #define BITOFP(h, i) (!BITONP(h, i)) | |
72 #define BIT_UP(h, i) (h[i / BITSIZ] |= (1 << (i % BITSIZ))) | |
73 #define BITDWN(h, i) (h[i / BITSIZ] &= ~(1 << (i % BITSIZ))) | |
74 | |
75 /** 変換コードのチェックとコード変換 */ | |
76 int | |
77 key_check (inbuf, conv_tbl, tbl_cnt, check_flg) | |
78 int inbuf[]; /* ソースストリング */ | |
79 struct CONVCODE conv_tbl[]; /* コード変換テーブル */ | |
80 int tbl_cnt; | |
81 int check_flg[]; | |
82 { | |
83 int dist, base; | |
84 char *code_p; | |
85 int i; | |
86 | |
87 for (base = 0; inbuf[base] != -1; base++) | |
88 { | |
89 for (dist = 0; dist < tbl_cnt; dist++) | |
90 { | |
91 if (BITONP (check_flg, dist) && conv_tbl[dist].fromkey != 0) | |
92 { | |
93 code_p = conv_tbl[dist].fromkey + base; | |
94 if (*code_p == (char) inbuf[base]) | |
95 { | |
96 if (*(code_p + 1) == (char) 0) | |
97 { | |
98 /* マッチした */ | |
99 for (i = 0, base++; (inbuf[i] = inbuf[base]) != -1; i++, base++); | |
100 return (conv_tbl[dist].tokey); | |
101 } | |
102 /* まだマッチしていない */ | |
103 } | |
104 else | |
105 { | |
106 BITDWN (check_flg, dist); /* 無効 */ | |
107 } | |
108 } | |
109 } | |
110 } | |
111 | |
112 /* ビットベクタ check_flg[] の第0〜tblcntビットに立ったまま残っている | |
113 ものがあるか調べる。 */ | |
114 for (i = 0; i < tbl_cnt / BITSIZ; i++) | |
115 { | |
116 if (check_flg[i]) | |
117 return (-1); | |
118 } | |
119 if ((tbl_cnt %= BITSIZ) && (check_flg[i] & ~(~0 << tbl_cnt))) | |
120 return (-1); | |
121 /* return -1 … まだ未決定の物がある */ | |
122 | |
123 return (-2); /* 変換対象となる物はない */ | |
124 } | |
125 | |
126 /** 指定された変換テーブルに従ってコード変換する。*/ | |
127 int | |
128 convert_key (inkey, conv_tbl, tbl_cnt, matching_flg, in_buf) | |
129 int (*inkey) (); /* キー入力関数 */ | |
130 struct CONVCODE conv_tbl[]; /* 変換テーブル */ | |
131 int tbl_cnt; /* conv_tbl[] の個数 */ | |
132 int matching_flg; /* マッチングしなかったストリングの処理指定 | |
133 0 : 返値として返す | |
134 1 : そのストリングは捨てる */ | |
135 char *in_buf; | |
136 { | |
137 #define MAX 20 /* キー入力バッファの最大値 */ | |
138 | |
139 static int inbuf[MAX]; /* キー入力バッファ */ | |
140 /* バッファの終端は、-1 で示される。 */ | |
141 | |
142 int out_cnt; /* 出力バッファの出力カウント */ | |
143 | |
144 static int buf_cnt = 0; /* inbuf の入力時のカウンタ */ | |
145 | |
146 int check_flg[CHANGE_MAX]; | |
147 /* ビットベクタとして扱われ、マッチング時に対象となっているconv_tbl[] | |
148 を示す。1の時対象となり、0で非対象 */ | |
149 | |
150 int i, c, flg = 0; /* work */ | |
151 | |
152 for (i = 0; i < div_up (tbl_cnt, BITSIZ); check_flg[i++] = ~0); | |
153 /* 配列check_flgをビットベクタ扱いし、その第0〜tbl_cnt ビットを立てる。 | |
154 但し、実際はその少し先まで立つ */ | |
155 | |
156 for (;;) | |
157 { | |
158 if (flg != 0 || buf_cnt == 0) | |
159 { | |
160 inbuf[buf_cnt] = (*inkey) (); /* 一文字入力 */ | |
161 in_buf[buf_cnt] = (char) (inbuf[buf_cnt] & 0xff); | |
162 if (inbuf[buf_cnt] == -1) | |
163 { | |
164 if (buf_cnt > 0) | |
165 { | |
166 c = -2; /* タイムアウト */ | |
167 goto LABEL; | |
168 } | |
169 else | |
170 { | |
171 continue; | |
172 } | |
173 } | |
174 else | |
175 { | |
176 inbuf[++buf_cnt] = -1; /* ターミネータ */ | |
177 } | |
178 } | |
179 flg++; | |
180 | |
181 if (buf_cnt >= MAX - 1) | |
182 { | |
183 in_buf[0] = '\0'; | |
184 return (-1); /* ERROR */ | |
185 } | |
186 | |
187 c = key_check (inbuf, conv_tbl, tbl_cnt, check_flg); | |
188 LABEL: | |
189 switch (c) | |
190 { | |
191 case -1: /* 未決定 */ | |
192 continue; | |
193 | |
194 case -2: /* 変換対象でないことが決定した */ | |
195 buf_cnt--; | |
196 out_cnt = 0; | |
197 c = inbuf[out_cnt++]; | |
198 for (i = 0; inbuf[i] != -1; inbuf[i++] = inbuf[out_cnt++]); | |
199 if (matching_flg != 0) | |
200 { | |
201 flg = 0; | |
202 continue; | |
203 } | |
204 in_buf[0] = '\0'; | |
205 return (c); | |
206 | |
207 default: /* 変換されたコード */ | |
208 in_buf[buf_cnt] = '\0'; | |
209 buf_cnt = 0; | |
210 return (c); | |
211 } | |
212 } | |
213 } | |
214 | |
215 /** コード変換を伴うキー入力関数 */ | |
216 int | |
217 keyin1 (get_ch, in_buf) | |
218 int (*get_ch) (); /* getchar() と同様の関数 */ | |
219 char *in_buf; | |
220 { | |
221 int ret; | |
222 | |
223 for (;;) | |
224 { | |
225 if (cnv_tbl_cnt == 0) | |
226 { | |
227 ret = (*get_ch) (); | |
228 if (ret >= 0) | |
229 return (ret); | |
230 } | |
231 else | |
232 { | |
233 return (convert_key (get_ch, tbl, cnv_tbl_cnt, 0, in_buf)); | |
234 } | |
235 } | |
236 } |