xref: /386bsd/usr/src/usr.bin/tn3270/tools/dohits.c (revision a2142627)
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