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