1 /*-
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 static char sccsid[] = "@(#)dohits.c 4.2 (Berkeley) 4/26/91";
36 #endif /* not lint */
37
38 /*
39 * This program scans a file which describes a keyboard. The output
40 * of the program is a series of 'C' declarations which describe a
41 * mapping between (scancode, shiftstate, altstate) and 3270 functions,
42 * characters, and AIDs.
43 *
44 * The format of the input file is as follows:
45 *
46 * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
47 *
48 * keynumber is in decimal, and starts in column 1.
49 * scancode is hexadecimal.
50 * unshifted, etc. - these are either a single ascii character,
51 * or the name of a function or an AID-generating key.
52 *
53 * all fields are separated by a single space.
54 */
55
56 #include <stdio.h>
57 #if defined(unix)
58 #include <strings.h>
59 #else /* defined(unix) */
60 #include <string.h>
61 #endif /* defined(unix) */
62 #include <ctype.h>
63 #include "../general/general.h"
64 #include "../api/asc_ebc.h"
65 #include "../api/ebc_disp.h"
66 #include "../ctlr/function.h"
67
68 #include "dohits.h"
69
70 struct Hits Hits[256]; /* one for each of 0x00-0xff */
71
72 struct thing *table[100];
73
74 extern char *malloc();
75
76 unsigned int
dohash(seed,string)77 dohash(seed, string)
78 unsigned int seed;
79 char *string;
80 {
81 register unsigned int i = seed;
82 register unsigned char c;
83
84 while (c = *string++) {
85 if (c >= 0x60) {
86 c -= (0x60+0x20);
87 } else {
88 c -= 0x20;
89 }
90 i = (i>>26) + (i<<6) + (c&0x3f);
91 }
92 return i;
93 }
94
95 void
add(first,second,value)96 add(first, second, value)
97 char *first, *second;
98 int value;
99 {
100 struct thing **item, *this;
101
102 item = &firstentry(second);
103 this = (struct thing *) malloc(sizeof *this);
104 this->next = *item;
105 *item = this;
106 this->value = value;
107 strcpy(this->name, first);
108 strcpy(this->name+strlen(this->name), second);
109 }
110
111 void
scanwhite(file,prefix)112 scanwhite(file, prefix)
113 char *file, /* Name of file to scan for whitespace prefix */
114 *prefix; /* prefix of what should be picked up */
115 {
116 FILE *ourfile;
117 char compare[100];
118 char what[100], value[100];
119 char line[200];
120
121 sprintf(compare, " %s%%[^,\t \n]", prefix);
122 if ((ourfile = fopen(file, "r")) == NULL) {
123 perror("fopen");
124 exit(1);
125 }
126 while (!feof(ourfile)) {
127 if (fscanf(ourfile, compare, what) == 1) {
128 add(prefix, what, 0);
129 }
130 do {
131 if (fgets(line, sizeof line, ourfile) == NULL) {
132 if (!feof(ourfile)) {
133 perror("fgets");
134 }
135 break;
136 }
137 } while (line[strlen(line)-1] != '\n');
138 }
139 }
140
141 void
scandefine(file,prefix)142 scandefine(file, prefix)
143 char *file, /* Name of file to scan for #define prefix */
144 *prefix; /* prefix of what should be picked up */
145 {
146 FILE *ourfile;
147 char compare[100];
148 char what[100], value[100];
149 char line[200];
150 int whatitis;
151
152 sprintf(compare, "#define %s%%s %%s", prefix);
153 if ((ourfile = fopen(file, "r")) == NULL) {
154 perror("fopen");
155 exit(1);
156 }
157 while (!feof(ourfile)) {
158 if (fscanf(ourfile, compare, what, value) == 2) {
159 if (value[0] == '0') {
160 if ((value[1] == 'x') || (value[1] == 'X')) {
161 sscanf(value, "0x%x", &whatitis);
162 } else {
163 sscanf(value, "0%o", &whatitis);
164 }
165 } else {
166 sscanf(value, "%d", &whatitis);
167 }
168 add(prefix, what, whatitis);
169 }
170 do {
171 if (fgets(line, sizeof line, ourfile) == NULL) {
172 if (!feof(ourfile)) {
173 perror("fgets");
174 }
175 break;
176 }
177 } while (line[strlen(line)-1] != '\n');
178 }
179 }
180
savechr(c)181 char *savechr(c)
182 unsigned char c;
183 {
184 char *foo;
185
186 foo = malloc(sizeof c);
187 if (foo == 0) {
188 fprintf(stderr, "No room for ascii characters!\n");
189 exit(1);
190 }
191 *foo = c;
192 return foo;
193 }
194
195 char *
doit(hit,type,hits)196 doit(hit, type, hits)
197 struct hit *hit;
198 unsigned char *type;
199 struct Hits *hits;
200 {
201 struct thing *this;
202
203 hit->ctlrfcn = FCN_NULL;
204 if (type[0] == 0) {
205 return 0;
206 }
207 if (type[1] == 0) { /* character */
208 hit->ctlrfcn = FCN_CHARACTER;
209 hit->code = ebc_disp[asc_ebc[type[0]]];
210 return savechr(*type); /* The character is the name */
211 } else {
212 for (this = firstentry(type); this; this = this->next) {
213 if ((type[0] == this->name[4])
214 && (strcmp(type, this->name+4) == 0)) {
215 this->hits = hits;
216 if (this->name[0] == 'F') {
217 hit->ctlrfcn = FCN_NULL; /* XXX */
218 } else {
219 hit->ctlrfcn = FCN_AID;
220 }
221 return this->name;
222 }
223 }
224 fprintf(stderr, "Error: Unknown type %s.\n", type);
225 return 0;
226 }
227 }
228
229
230 void
dohits(aidfile,fcnfile)231 dohits(aidfile, fcnfile)
232 char *aidfile, *fcnfile;
233 {
234 unsigned char plain[100], shifted[100], alted[100], shiftalted[100];
235 unsigned char line[200];
236 int keynumber, scancode;
237 int empty;
238 int i;
239 struct hit *hit;
240 struct hits *ph;
241 struct Hits *Ph;
242
243 memset((char *)Hits, 0, sizeof Hits);
244
245 /*
246 * First, we read "host3270.h" to find the names/values of
247 * various AID; then we read kbd3270.h to find the names/values
248 * of various FCNs.
249 */
250
251 if (aidfile == 0) {
252 aidfile = "../ctlr/hostctlr.h";
253 }
254 scandefine(aidfile, "AID_");
255 if (fcnfile == 0) {
256 fcnfile = "../ctlr/function.h";
257 }
258 scanwhite(fcnfile, "FCN_");
259
260 while (gets(line) != NULL) {
261 if (!isdigit(line[0])) {
262 continue;
263 }
264 plain[0] = shifted[0] = alted[0] = shiftalted[0] = 0;
265 keynumber = -1;
266 scancode = -1;
267 (void) sscanf(line, "%d %x %s %s %s %s", &keynumber,
268 &scancode, plain, shifted, alted, shiftalted);
269 if ((keynumber == -1) || (scancode == -1)
270 || ((plain[0] == 0)
271 && (shifted[0] == 0)
272 && (alted[0] == 0)
273 && (shiftalted[0] == 0))) {
274 continue;
275 }
276 if (scancode >= 256) {
277 fprintf(stderr,
278 "Error: scancode 0x%02x for keynumber %d\n", scancode,
279 keynumber);
280 break;
281 }
282 if (Hits[scancode].hits.hit[0].ctlrfcn != undefined) {
283 fprintf(stderr,
284 "Error: duplicate scancode 0x%02x for keynumber %d\n",
285 scancode, keynumber);
286 break;
287 }
288 hit = Hits[scancode].hits.hit;
289 Hits[scancode].hits.keynumber = keynumber;
290 Hits[scancode].name[0] = doit(hit, plain, &Hits[scancode]);
291 Hits[scancode].name[1] = doit(hit+1, shifted, &Hits[scancode]);
292 Hits[scancode].name[2] = doit(hit+2, alted, &Hits[scancode]);
293 Hits[scancode].name[3] = doit(hit+3, shiftalted, &Hits[scancode]);
294 }
295 }
296