148763Sbostic /*-
2*62360Sbostic * Copyright (c) 1988, 1993
3*62360Sbostic * The Regents of the University of California. All rights reserved.
431896Sminshall *
548763Sbostic * %sccs.include.redist.c%
631896Sminshall */
731896Sminshall
831896Sminshall #ifndef lint
9*62360Sbostic static char sccsid[] = "@(#)dohits.c 8.1 (Berkeley) 06/06/93";
1033811Sbostic #endif /* not lint */
1131896Sminshall
1231896Sminshall /*
1329995Sminshall * This program scans a file which describes a keyboard. The output
1429995Sminshall * of the program is a series of 'C' declarations which describe a
1529995Sminshall * mapping between (scancode, shiftstate, altstate) and 3270 functions,
1629995Sminshall * characters, and AIDs.
1729995Sminshall *
1829995Sminshall * The format of the input file is as follows:
1929995Sminshall *
2029995Sminshall * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
2129995Sminshall *
2229995Sminshall * keynumber is in decimal, and starts in column 1.
2329995Sminshall * scancode is hexadecimal.
2429995Sminshall * unshifted, etc. - these are either a single ascii character,
2529995Sminshall * or the name of a function or an AID-generating key.
2629995Sminshall *
2729995Sminshall * all fields are separated by a single space.
2829995Sminshall */
2929995Sminshall
3029995Sminshall #include <stdio.h>
3131102Sminshall #if defined(unix)
3231065Sminshall #include <strings.h>
3331102Sminshall #else /* defined(unix) */
3431102Sminshall #include <string.h>
3531102Sminshall #endif /* defined(unix) */
3629995Sminshall #include <ctype.h>
3731175Sminshall #include "../general/general.h"
3831875Sminshall #include "../api/asc_ebc.h"
3931875Sminshall #include "../api/ebc_disp.h"
4030052Sminshall #include "../ctlr/function.h"
4129995Sminshall
4229995Sminshall #include "dohits.h"
4329995Sminshall
4429995Sminshall struct Hits Hits[256]; /* one for each of 0x00-0xff */
4529995Sminshall
4629995Sminshall struct thing *table[100];
4729995Sminshall
4830052Sminshall extern char *malloc();
4930052Sminshall
5029995Sminshall unsigned int
dohash(seed,string)5129995Sminshall dohash(seed, string)
5229995Sminshall unsigned int seed;
5329995Sminshall char *string;
5429995Sminshall {
5529995Sminshall register unsigned int i = seed;
5629995Sminshall register unsigned char c;
5729995Sminshall
5829995Sminshall while (c = *string++) {
5929995Sminshall if (c >= 0x60) {
6030086Sminshall c -= (0x60+0x20);
6129995Sminshall } else {
6229995Sminshall c -= 0x20;
6329995Sminshall }
6429995Sminshall i = (i>>26) + (i<<6) + (c&0x3f);
6529995Sminshall }
6629995Sminshall return i;
6729995Sminshall }
6829995Sminshall
6929995Sminshall void
add(first,second,value)7029995Sminshall add(first, second, value)
7130077Sminshall char *first, *second;
7230077Sminshall int value;
7329995Sminshall {
7429995Sminshall struct thing **item, *this;
7529995Sminshall
7629995Sminshall item = &firstentry(second);
7729995Sminshall this = (struct thing *) malloc(sizeof *this);
7829995Sminshall this->next = *item;
7929995Sminshall *item = this;
8029995Sminshall this->value = value;
8129995Sminshall strcpy(this->name, first);
8229995Sminshall strcpy(this->name+strlen(this->name), second);
8329995Sminshall }
8429995Sminshall
8529995Sminshall void
scanwhite(file,prefix)8630077Sminshall scanwhite(file, prefix)
8730077Sminshall char *file, /* Name of file to scan for whitespace prefix */
8829995Sminshall *prefix; /* prefix of what should be picked up */
8929995Sminshall {
9029995Sminshall FILE *ourfile;
9129995Sminshall char compare[100];
9229995Sminshall char what[100], value[100];
9329995Sminshall char line[200];
9430077Sminshall
9530077Sminshall sprintf(compare, " %s%%[^,\t \n]", prefix);
9630077Sminshall if ((ourfile = fopen(file, "r")) == NULL) {
9730077Sminshall perror("fopen");
9830077Sminshall exit(1);
9930077Sminshall }
10030077Sminshall while (!feof(ourfile)) {
10130077Sminshall if (fscanf(ourfile, compare, what) == 1) {
10230077Sminshall add(prefix, what, 0);
10330077Sminshall }
10430077Sminshall do {
10530077Sminshall if (fgets(line, sizeof line, ourfile) == NULL) {
10630077Sminshall if (!feof(ourfile)) {
10730077Sminshall perror("fgets");
10830077Sminshall }
10930077Sminshall break;
11030077Sminshall }
11130077Sminshall } while (line[strlen(line)-1] != '\n');
11230077Sminshall }
11330077Sminshall }
11430077Sminshall
11530077Sminshall void
scandefine(file,prefix)11630077Sminshall scandefine(file, prefix)
11730077Sminshall char *file, /* Name of file to scan for #define prefix */
11830077Sminshall *prefix; /* prefix of what should be picked up */
11930077Sminshall {
12030077Sminshall FILE *ourfile;
12130077Sminshall char compare[100];
12230077Sminshall char what[100], value[100];
12330077Sminshall char line[200];
12429995Sminshall int whatitis;
12529995Sminshall
12629995Sminshall sprintf(compare, "#define %s%%s %%s", prefix);
12729995Sminshall if ((ourfile = fopen(file, "r")) == NULL) {
12829995Sminshall perror("fopen");
12929995Sminshall exit(1);
13029995Sminshall }
13129995Sminshall while (!feof(ourfile)) {
13229995Sminshall if (fscanf(ourfile, compare, what, value) == 2) {
13329995Sminshall if (value[0] == '0') {
13429995Sminshall if ((value[1] == 'x') || (value[1] == 'X')) {
13529995Sminshall sscanf(value, "0x%x", &whatitis);
13629995Sminshall } else {
13729995Sminshall sscanf(value, "0%o", &whatitis);
13829995Sminshall }
13929995Sminshall } else {
14029995Sminshall sscanf(value, "%d", &whatitis);
14129995Sminshall }
14229995Sminshall add(prefix, what, whatitis);
14329995Sminshall }
14429995Sminshall do {
14529995Sminshall if (fgets(line, sizeof line, ourfile) == NULL) {
14629995Sminshall if (!feof(ourfile)) {
14729995Sminshall perror("fgets");
14829995Sminshall }
14929995Sminshall break;
15029995Sminshall }
15129995Sminshall } while (line[strlen(line)-1] != '\n');
15229995Sminshall }
15329995Sminshall }
15429995Sminshall
savechr(c)15530052Sminshall char *savechr(c)
15630052Sminshall unsigned char c;
15730052Sminshall {
15830052Sminshall char *foo;
15929995Sminshall
16030052Sminshall foo = malloc(sizeof c);
16130052Sminshall if (foo == 0) {
16230052Sminshall fprintf(stderr, "No room for ascii characters!\n");
16330052Sminshall exit(1);
16430052Sminshall }
16530052Sminshall *foo = c;
16630052Sminshall return foo;
16730052Sminshall }
16830052Sminshall
16929995Sminshall char *
doit(hit,type,hits)17029995Sminshall doit(hit, type, hits)
17129995Sminshall struct hit *hit;
17229995Sminshall unsigned char *type;
17329995Sminshall struct Hits *hits;
17429995Sminshall {
17529995Sminshall struct thing *this;
17629995Sminshall
17730077Sminshall hit->ctlrfcn = FCN_NULL;
17829995Sminshall if (type[0] == 0) {
17929995Sminshall return 0;
18029995Sminshall }
18129995Sminshall if (type[1] == 0) { /* character */
18230077Sminshall hit->ctlrfcn = FCN_CHARACTER;
18331614Sminshall hit->code = ebc_disp[asc_ebc[type[0]]];
18430052Sminshall return savechr(*type); /* The character is the name */
18529995Sminshall } else {
18629995Sminshall for (this = firstentry(type); this; this = this->next) {
18729995Sminshall if ((type[0] == this->name[4])
18829995Sminshall && (strcmp(type, this->name+4) == 0)) {
18929995Sminshall this->hits = hits;
19029995Sminshall if (this->name[0] == 'F') {
19130077Sminshall hit->ctlrfcn = FCN_NULL; /* XXX */
19229995Sminshall } else {
19330077Sminshall hit->ctlrfcn = FCN_AID;
19429995Sminshall }
19529995Sminshall return this->name;
19629995Sminshall }
19729995Sminshall }
19830052Sminshall fprintf(stderr, "Error: Unknown type %s.\n", type);
19929995Sminshall return 0;
20029995Sminshall }
20129995Sminshall }
20229995Sminshall
20329995Sminshall
20429995Sminshall void
dohits(aidfile,fcnfile)20530077Sminshall dohits(aidfile, fcnfile)
20630077Sminshall char *aidfile, *fcnfile;
20729995Sminshall {
20829995Sminshall unsigned char plain[100], shifted[100], alted[100], shiftalted[100];
20929995Sminshall unsigned char line[200];
21029995Sminshall int keynumber, scancode;
21129995Sminshall int empty;
21229995Sminshall int i;
21329995Sminshall struct hit *hit;
21429995Sminshall struct hits *ph;
21529995Sminshall struct Hits *Ph;
21629995Sminshall
21729995Sminshall memset((char *)Hits, 0, sizeof Hits);
21829995Sminshall
21929995Sminshall /*
22029995Sminshall * First, we read "host3270.h" to find the names/values of
22129995Sminshall * various AID; then we read kbd3270.h to find the names/values
22229995Sminshall * of various FCNs.
22329995Sminshall */
22429995Sminshall
22530077Sminshall if (aidfile == 0) {
22630077Sminshall aidfile = "../ctlr/hostctlr.h";
22730077Sminshall }
22830077Sminshall scandefine(aidfile, "AID_");
22930077Sminshall if (fcnfile == 0) {
23030077Sminshall fcnfile = "../ctlr/function.h";
23130077Sminshall }
23230077Sminshall scanwhite(fcnfile, "FCN_");
23329995Sminshall
23429995Sminshall while (gets(line) != NULL) {
23529995Sminshall if (!isdigit(line[0])) {
23629995Sminshall continue;
23729995Sminshall }
23829995Sminshall plain[0] = shifted[0] = alted[0] = shiftalted[0] = 0;
23929995Sminshall keynumber = -1;
24029995Sminshall scancode = -1;
24129995Sminshall (void) sscanf(line, "%d %x %s %s %s %s", &keynumber,
24229995Sminshall &scancode, plain, shifted, alted, shiftalted);
24329995Sminshall if ((keynumber == -1) || (scancode == -1)
24429995Sminshall || ((plain[0] == 0)
24529995Sminshall && (shifted[0] == 0)
24629995Sminshall && (alted[0] == 0)
24729995Sminshall && (shiftalted[0] == 0))) {
24829995Sminshall continue;
24929995Sminshall }
25029995Sminshall if (scancode >= 256) {
25130052Sminshall fprintf(stderr,
25230052Sminshall "Error: scancode 0x%02x for keynumber %d\n", scancode,
25329995Sminshall keynumber);
25429995Sminshall break;
25529995Sminshall }
25630077Sminshall if (Hits[scancode].hits.hit[0].ctlrfcn != undefined) {
25730052Sminshall fprintf(stderr,
25830052Sminshall "Error: duplicate scancode 0x%02x for keynumber %d\n",
25929995Sminshall scancode, keynumber);
26029995Sminshall break;
26129995Sminshall }
26229995Sminshall hit = Hits[scancode].hits.hit;
26329995Sminshall Hits[scancode].hits.keynumber = keynumber;
26429995Sminshall Hits[scancode].name[0] = doit(hit, plain, &Hits[scancode]);
26529995Sminshall Hits[scancode].name[1] = doit(hit+1, shifted, &Hits[scancode]);
26629995Sminshall Hits[scancode].name[2] = doit(hit+2, alted, &Hits[scancode]);
26729995Sminshall Hits[scancode].name[3] = doit(hit+3, shiftalted, &Hits[scancode]);
26829995Sminshall }
26929995Sminshall }
270