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