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
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
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
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
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 
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 *
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
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