1 /*-
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)dohits.c 8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11
12 /*
13 * This program scans a file which describes a keyboard. The output
14 * of the program is a series of 'C' declarations which describe a
15 * mapping between (scancode, shiftstate, altstate) and 3270 functions,
16 * characters, and AIDs.
17 *
18 * The format of the input file is as follows:
19 *
20 * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
21 *
22 * keynumber is in decimal, and starts in column 1.
23 * scancode is hexadecimal.
24 * unshifted, etc. - these are either a single ascii character,
25 * or the name of a function or an AID-generating key.
26 *
27 * all fields are separated by a single space.
28 */
29
30 #include <stdio.h>
31 #if defined(unix)
32 #include <strings.h>
33 #else /* defined(unix) */
34 #include <string.h>
35 #endif /* defined(unix) */
36 #include <ctype.h>
37 #include "../general/general.h"
38 #include "../api/asc_ebc.h"
39 #include "../api/ebc_disp.h"
40 #include "../ctlr/function.h"
41
42 #include "dohits.h"
43
44 struct Hits Hits[256]; /* one for each of 0x00-0xff */
45
46 struct thing *table[100];
47
48 extern char *malloc();
49
50 unsigned int
dohash(seed,string)51 dohash(seed, string)
52 unsigned int seed;
53 char *string;
54 {
55 register unsigned int i = seed;
56 register unsigned char c;
57
58 while (c = *string++) {
59 if (c >= 0x60) {
60 c -= (0x60+0x20);
61 } else {
62 c -= 0x20;
63 }
64 i = (i>>26) + (i<<6) + (c&0x3f);
65 }
66 return i;
67 }
68
69 void
add(first,second,value)70 add(first, second, value)
71 char *first, *second;
72 int value;
73 {
74 struct thing **item, *this;
75
76 item = &firstentry(second);
77 this = (struct thing *) malloc(sizeof *this);
78 this->next = *item;
79 *item = this;
80 this->value = value;
81 strcpy(this->name, first);
82 strcpy(this->name+strlen(this->name), second);
83 }
84
85 void
scanwhite(file,prefix)86 scanwhite(file, prefix)
87 char *file, /* Name of file to scan for whitespace prefix */
88 *prefix; /* prefix of what should be picked up */
89 {
90 FILE *ourfile;
91 char compare[100];
92 char what[100], value[100];
93 char line[200];
94
95 sprintf(compare, " %s%%[^,\t \n]", prefix);
96 if ((ourfile = fopen(file, "r")) == NULL) {
97 perror("fopen");
98 exit(1);
99 }
100 while (!feof(ourfile)) {
101 if (fscanf(ourfile, compare, what) == 1) {
102 add(prefix, what, 0);
103 }
104 do {
105 if (fgets(line, sizeof line, ourfile) == NULL) {
106 if (!feof(ourfile)) {
107 perror("fgets");
108 }
109 break;
110 }
111 } while (line[strlen(line)-1] != '\n');
112 }
113 }
114
115 void
scandefine(file,prefix)116 scandefine(file, prefix)
117 char *file, /* Name of file to scan for #define prefix */
118 *prefix; /* prefix of what should be picked up */
119 {
120 FILE *ourfile;
121 char compare[100];
122 char what[100], value[100];
123 char line[200];
124 int whatitis;
125
126 sprintf(compare, "#define %s%%s %%s", prefix);
127 if ((ourfile = fopen(file, "r")) == NULL) {
128 perror("fopen");
129 exit(1);
130 }
131 while (!feof(ourfile)) {
132 if (fscanf(ourfile, compare, what, value) == 2) {
133 if (value[0] == '0') {
134 if ((value[1] == 'x') || (value[1] == 'X')) {
135 sscanf(value, "0x%x", &whatitis);
136 } else {
137 sscanf(value, "0%o", &whatitis);
138 }
139 } else {
140 sscanf(value, "%d", &whatitis);
141 }
142 add(prefix, what, whatitis);
143 }
144 do {
145 if (fgets(line, sizeof line, ourfile) == NULL) {
146 if (!feof(ourfile)) {
147 perror("fgets");
148 }
149 break;
150 }
151 } while (line[strlen(line)-1] != '\n');
152 }
153 }
154
savechr(c)155 char *savechr(c)
156 unsigned char c;
157 {
158 char *foo;
159
160 foo = malloc(sizeof c);
161 if (foo == 0) {
162 fprintf(stderr, "No room for ascii characters!\n");
163 exit(1);
164 }
165 *foo = c;
166 return foo;
167 }
168
169 char *
doit(hit,type,hits)170 doit(hit, type, hits)
171 struct hit *hit;
172 unsigned char *type;
173 struct Hits *hits;
174 {
175 struct thing *this;
176
177 hit->ctlrfcn = FCN_NULL;
178 if (type[0] == 0) {
179 return 0;
180 }
181 if (type[1] == 0) { /* character */
182 hit->ctlrfcn = FCN_CHARACTER;
183 hit->code = ebc_disp[asc_ebc[type[0]]];
184 return savechr(*type); /* The character is the name */
185 } else {
186 for (this = firstentry(type); this; this = this->next) {
187 if ((type[0] == this->name[4])
188 && (strcmp(type, this->name+4) == 0)) {
189 this->hits = hits;
190 if (this->name[0] == 'F') {
191 hit->ctlrfcn = FCN_NULL; /* XXX */
192 } else {
193 hit->ctlrfcn = FCN_AID;
194 }
195 return this->name;
196 }
197 }
198 fprintf(stderr, "Error: Unknown type %s.\n", type);
199 return 0;
200 }
201 }
202
203
204 void
dohits(aidfile,fcnfile)205 dohits(aidfile, fcnfile)
206 char *aidfile, *fcnfile;
207 {
208 unsigned char plain[100], shifted[100], alted[100], shiftalted[100];
209 unsigned char line[200];
210 int keynumber, scancode;
211 int empty;
212 int i;
213 struct hit *hit;
214 struct hits *ph;
215 struct Hits *Ph;
216
217 memset((char *)Hits, 0, sizeof Hits);
218
219 /*
220 * First, we read "host3270.h" to find the names/values of
221 * various AID; then we read kbd3270.h to find the names/values
222 * of various FCNs.
223 */
224
225 if (aidfile == 0) {
226 aidfile = "../ctlr/hostctlr.h";
227 }
228 scandefine(aidfile, "AID_");
229 if (fcnfile == 0) {
230 fcnfile = "../ctlr/function.h";
231 }
232 scanwhite(fcnfile, "FCN_");
233
234 while (gets(line) != NULL) {
235 if (!isdigit(line[0])) {
236 continue;
237 }
238 plain[0] = shifted[0] = alted[0] = shiftalted[0] = 0;
239 keynumber = -1;
240 scancode = -1;
241 (void) sscanf(line, "%d %x %s %s %s %s", &keynumber,
242 &scancode, plain, shifted, alted, shiftalted);
243 if ((keynumber == -1) || (scancode == -1)
244 || ((plain[0] == 0)
245 && (shifted[0] == 0)
246 && (alted[0] == 0)
247 && (shiftalted[0] == 0))) {
248 continue;
249 }
250 if (scancode >= 256) {
251 fprintf(stderr,
252 "Error: scancode 0x%02x for keynumber %d\n", scancode,
253 keynumber);
254 break;
255 }
256 if (Hits[scancode].hits.hit[0].ctlrfcn != undefined) {
257 fprintf(stderr,
258 "Error: duplicate scancode 0x%02x for keynumber %d\n",
259 scancode, keynumber);
260 break;
261 }
262 hit = Hits[scancode].hits.hit;
263 Hits[scancode].hits.keynumber = keynumber;
264 Hits[scancode].name[0] = doit(hit, plain, &Hits[scancode]);
265 Hits[scancode].name[1] = doit(hit+1, shifted, &Hits[scancode]);
266 Hits[scancode].name[2] = doit(hit+2, alted, &Hits[scancode]);
267 Hits[scancode].name[3] = doit(hit+3, shiftalted, &Hits[scancode]);
268 }
269 }
270