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 /** int������ h ��ӥåȥ٥����Ȥߤʤ�����i�ӥåȤ�����å����뤤��Ω�Ƥ� */
69 #define BITONP(h, i) (h[i / BITSIZ] &  (1 << (i % BITSIZ)))
70 #define BITOFP(h, i) (!BITONP(h, i))
71 #define BIT_UP(h, i) (h[i / BITSIZ] |= (1 << (i % BITSIZ)))
72 #define BITDWN(h, i) (h[i / BITSIZ] &= ~(1 << (i % BITSIZ)))
73 
74 /** �Ѵ������ɤΥ����å��ȥ������Ѵ� */
75 int
key_check(int inbuf[],struct CONVCODE conv_tbl[],int tbl_cnt,int check_flg[])76 key_check (int inbuf[],			/* ���������ȥ�� */
77 	   struct CONVCODE conv_tbl[],	/* �������Ѵ��ơ��֥� */
78 	   int tbl_cnt,
79 	   int check_flg[])
80 {
81 	int dist, base;
82 	char *code_p;
83 	int i;
84 
85 	for (base = 0; inbuf[base] != -1; base++) {
86 		for (dist = 0; dist < tbl_cnt; dist++) {
87 			if (BITONP (check_flg, dist) && conv_tbl[dist].fromkey != 0) {
88 				code_p = conv_tbl[dist].fromkey + base;
89 
90 				if (*code_p == (char) inbuf[base]) {
91 					if (*(code_p + 1) == (char) 0) {
92 						/* �ޥå����� */
93 						for (i = 0, base++; (inbuf[i] = inbuf[base]) != -1; i++, base++);
94 						return (conv_tbl[dist].tokey);
95 					}
96 					/* �ޤ��ޥå����Ƥ��ʤ� */
97 				} else {
98 					/* ̵�� */
99 					BITDWN (check_flg, dist);
100 				}
101 			}
102 		}
103 	}
104 
105 	/* �ӥåȥ٥��� check_flg[] ����0��tblcnt�ӥåȤ�Ω�ä��ޤ޻ĤäƤ���
106 	   ��Τ����뤫Ĵ�٤롣 */
107 
108 	for (i = 0; i < tbl_cnt / BITSIZ; i++) {
109 		if (check_flg[i])
110 			return (-1);
111 	}
112 
113 	if ((tbl_cnt %= BITSIZ) && (check_flg[i] & ~(~0 << tbl_cnt)))
114 		return (-1);
115 	/* return -1 �� �ޤ�̤�����ʪ������ */
116 
117 	/* �Ѵ��оݤȤʤ�ʪ�Ϥʤ� */
118 	return (-2);
119 }
120 
121 /** ���ꤵ�줿�Ѵ��ơ��֥�˽��äƥ������Ѵ����롣*/
122 int
convert_key(int (* inkey)(),struct CONVCODE conv_tbl[],int tbl_cnt,int matching_flg,char * in_buf)123 convert_key (int (*inkey)(),		/* �������ϴؿ� */
124 	     struct CONVCODE conv_tbl[],	/* �Ѵ��ơ��֥� */
125 	     int tbl_cnt,		/* conv_tbl[] �θĿ� */
126 	     int matching_flg,       /* �ޥå������ʤ��ä����ȥ���ν�������
127 					0 : ���ͤȤ����֤�
128 					1 : ���Υ��ȥ���ϼΤƤ�   */
129 	     char *in_buf)
130 {
131 #define MAX     20              /* �������ϥХåե��κ����� */
132 
133         /* �������ϥХåե� */
134 	/* �Хåե��ν�ü�ϡ�-1 �Ǽ�����롣 */
135 	static int inbuf[MAX];
136 
137 	/* ���ϥХåե��ν��ϥ������ */
138 	int out_cnt;
139 
140 	/* inbuf �����ϻ��Υ�����   */
141 	static int buf_cnt = 0;
142 
143 
144 	/* �ӥåȥ٥����Ȥ��ư���졢�ޥå��������оݤȤʤäƤ���conv_tbl[]
145 	   ������1�λ��оݤȤʤꡢ0�����о� */
146 	int check_flg[CHANGE_MAX];
147 
148 	/* work */
149 	int i, c, flg = 0;
150 
151 	for (i = 0; i < div_up (tbl_cnt, BITSIZ); check_flg[i++] = ~0);
152 	/* ����check_flg��ӥåȥ٥�����������������0��tbl_cnt �ӥåȤ�Ω�Ƥ롣
153 	   â�����ºݤϤ��ξ�����ޤ�Ω�� */
154 
155 	for (;;) {
156 		if (flg != 0 || buf_cnt == 0) {
157 			inbuf[buf_cnt] = (*inkey) (); /* ��ʸ������ */
158 			in_buf[buf_cnt] = (char) (inbuf[buf_cnt] & 0xff);
159 			if (inbuf[buf_cnt] == -1) {
160 				if (buf_cnt > 0) {
161 					c = -2;
162 					/* �����ॢ���� */
163 					goto LABEL;
164 				} else {
165 					continue;
166 				}
167 			} else {
168 				/* �����ߥ͡��� */
169 				inbuf[++buf_cnt] = -1;
170 			}
171 		}
172 		flg++;
173 
174 		if (buf_cnt >= MAX - 1) {
175 			in_buf[0] = '\0';
176 
177 			/* ERROR */
178 			return (-1);
179 		}
180 
181 		c = key_check (inbuf, conv_tbl, tbl_cnt, check_flg);
182 
183 	LABEL:
184 		switch (c) {
185 		case -1:
186 			/* ̤���� */
187 			continue;
188 
189 		case -2:
190 			/* �Ѵ��оݤǤʤ����Ȥ����ꤷ�� */
191 			buf_cnt--;
192 			out_cnt = 0;
193 			c = inbuf[out_cnt++];
194 			for (i = 0; inbuf[i] != -1; inbuf[i++] = inbuf[out_cnt++]);
195 
196 			if (matching_flg != 0) {
197 				flg = 0;
198 				continue;
199 			}
200 
201 			in_buf[0] = '\0';
202 			return (c);
203 
204 		default:
205 			/* �Ѵ����줿������ */
206 			in_buf[buf_cnt] = '\0';
207 			buf_cnt = 0;
208 			return (c);
209 		}
210 	}
211 }
212 
213  /** �������Ѵ���ȼ���������ϴؿ� */
214 int
keyin1(int (* get_ch)(),char * in_buf)215 keyin1(int (*get_ch)(),          /* getchar() ��Ʊ�ͤδؿ� */
216        char *in_buf)
217 {
218 	int ret;
219 
220 	for (;;) {
221 		if (cnv_tbl_cnt == 0) {
222 			ret = (*get_ch)();
223 			if (ret >= 0)
224 				return (ret);
225 		} else {
226 			return (convert_key(get_ch, tbl, cnv_tbl_cnt, 0, in_buf));
227 		}
228 	}
229 }
230