129995Sminshall /*
2*33811Sbostic  * Copyright (c) 1988 Regents of the University of California.
3*33811Sbostic  * All rights reserved.
431896Sminshall  *
5*33811Sbostic  * Redistribution and use in source and binary forms are permitted
6*33811Sbostic  * provided that this notice is preserved and that due credit is given
7*33811Sbostic  * to the University of California at Berkeley. The name of the University
8*33811Sbostic  * may not be used to endorse or promote products derived from this
9*33811Sbostic  * software without specific prior written permission. This software
10*33811Sbostic  * is provided ``as is'' without express or implied warranty.
1131896Sminshall  */
1231896Sminshall 
1331896Sminshall #ifndef lint
14*33811Sbostic static char sccsid[] = "@(#)dohits.c	3.2 (Berkeley) 03/28/88";
15*33811Sbostic #endif /* not lint */
1631896Sminshall 
1731896Sminshall /*
1829995Sminshall  * This program scans a file which describes a keyboard.  The output
1929995Sminshall  * of the program is a series of 'C' declarations which describe a
2029995Sminshall  * mapping between (scancode, shiftstate, altstate) and 3270 functions,
2129995Sminshall  * characters, and AIDs.
2229995Sminshall  *
2329995Sminshall  * The format of the input file is as follows:
2429995Sminshall  *
2529995Sminshall  * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
2629995Sminshall  *
2729995Sminshall  * keynumber is in decimal, and starts in column 1.
2829995Sminshall  * scancode is hexadecimal.
2929995Sminshall  * unshifted, etc. - these are either a single ascii character,
3029995Sminshall  *			or the name of a function or an AID-generating key.
3129995Sminshall  *
3229995Sminshall  * all fields are separated by a single space.
3329995Sminshall  */
3429995Sminshall 
3529995Sminshall #include <stdio.h>
3631102Sminshall #if	defined(unix)
3731065Sminshall #include <strings.h>
3831102Sminshall #else	/* defined(unix) */
3931102Sminshall #include <string.h>
4031102Sminshall #endif	/* defined(unix) */
4129995Sminshall #include <ctype.h>
4231175Sminshall #include "../general/general.h"
4331875Sminshall #include "../api/asc_ebc.h"
4431875Sminshall #include "../api/ebc_disp.h"
4530052Sminshall #include "../ctlr/function.h"
4629995Sminshall 
4729995Sminshall #include "dohits.h"
4829995Sminshall 
4929995Sminshall struct Hits Hits[256];		/* one for each of 0x00-0xff */
5029995Sminshall 
5129995Sminshall struct thing *table[100];
5229995Sminshall 
5330052Sminshall extern char *malloc();
5430052Sminshall 
5529995Sminshall unsigned int
5629995Sminshall dohash(seed, string)
5729995Sminshall unsigned int seed;
5829995Sminshall char *string;
5929995Sminshall {
6029995Sminshall     register unsigned int i = seed;
6129995Sminshall     register unsigned char c;
6229995Sminshall 
6329995Sminshall     while (c = *string++) {
6429995Sminshall 	if (c >= 0x60) {
6530086Sminshall 	    c -= (0x60+0x20);
6629995Sminshall 	} else {
6729995Sminshall 	    c -= 0x20;
6829995Sminshall 	}
6929995Sminshall 	i = (i>>26) + (i<<6) + (c&0x3f);
7029995Sminshall     }
7129995Sminshall     return i;
7229995Sminshall }
7329995Sminshall 
7429995Sminshall void
7529995Sminshall add(first, second, value)
7630077Sminshall char *first, *second;
7730077Sminshall int value;
7829995Sminshall {
7929995Sminshall     struct thing **item, *this;
8029995Sminshall 
8129995Sminshall     item = &firstentry(second);
8229995Sminshall     this = (struct thing *) malloc(sizeof *this);
8329995Sminshall     this->next = *item;
8429995Sminshall     *item = this;
8529995Sminshall     this->value = value;
8629995Sminshall     strcpy(this->name, first);
8729995Sminshall     strcpy(this->name+strlen(this->name), second);
8829995Sminshall }
8929995Sminshall 
9029995Sminshall void
9130077Sminshall scanwhite(file, prefix)
9230077Sminshall char *file,		/* Name of file to scan for whitespace prefix */
9329995Sminshall      *prefix;		/* prefix of what should be picked up */
9429995Sminshall {
9529995Sminshall     FILE *ourfile;
9629995Sminshall     char compare[100];
9729995Sminshall     char what[100], value[100];
9829995Sminshall     char line[200];
9930077Sminshall 
10030077Sminshall     sprintf(compare, " %s%%[^,\t \n]", prefix);
10130077Sminshall     if ((ourfile = fopen(file, "r")) == NULL) {
10230077Sminshall 	perror("fopen");
10330077Sminshall 	exit(1);
10430077Sminshall     }
10530077Sminshall     while (!feof(ourfile)) {
10630077Sminshall 	if (fscanf(ourfile, compare,  what) == 1) {
10730077Sminshall 	    add(prefix, what, 0);
10830077Sminshall 	}
10930077Sminshall 	do {
11030077Sminshall 	    if (fgets(line, sizeof line, ourfile) == NULL) {
11130077Sminshall 		if (!feof(ourfile)) {
11230077Sminshall 		    perror("fgets");
11330077Sminshall 		}
11430077Sminshall 		break;
11530077Sminshall 	    }
11630077Sminshall 	} while (line[strlen(line)-1] != '\n');
11730077Sminshall     }
11830077Sminshall }
11930077Sminshall 
12030077Sminshall void
12130077Sminshall scandefine(file, prefix)
12230077Sminshall char *file,		/* Name of file to scan for #define prefix */
12330077Sminshall      *prefix;		/* prefix of what should be picked up */
12430077Sminshall {
12530077Sminshall     FILE *ourfile;
12630077Sminshall     char compare[100];
12730077Sminshall     char what[100], value[100];
12830077Sminshall     char line[200];
12929995Sminshall     int whatitis;
13029995Sminshall 
13129995Sminshall     sprintf(compare, "#define %s%%s %%s", prefix);
13229995Sminshall     if ((ourfile = fopen(file, "r")) == NULL) {
13329995Sminshall 	perror("fopen");
13429995Sminshall 	exit(1);
13529995Sminshall     }
13629995Sminshall     while (!feof(ourfile)) {
13729995Sminshall 	if (fscanf(ourfile, compare,  what, value) == 2) {
13829995Sminshall 	    if (value[0] == '0') {
13929995Sminshall 		if ((value[1] == 'x') || (value[1] == 'X')) {
14029995Sminshall 		    sscanf(value, "0x%x", &whatitis);
14129995Sminshall 		} else {
14229995Sminshall 		    sscanf(value, "0%o", &whatitis);
14329995Sminshall 		}
14429995Sminshall 	    } else {
14529995Sminshall 		sscanf(value, "%d", &whatitis);
14629995Sminshall 	    }
14729995Sminshall 	    add(prefix, what, whatitis);
14829995Sminshall 	}
14929995Sminshall 	do {
15029995Sminshall 	    if (fgets(line, sizeof line, ourfile) == NULL) {
15129995Sminshall 		if (!feof(ourfile)) {
15229995Sminshall 		    perror("fgets");
15329995Sminshall 		}
15429995Sminshall 		break;
15529995Sminshall 	    }
15629995Sminshall 	} while (line[strlen(line)-1] != '\n');
15729995Sminshall     }
15829995Sminshall }
15929995Sminshall 
16030052Sminshall char *savechr(c)
16130052Sminshall unsigned char c;
16230052Sminshall {
16330052Sminshall     char *foo;
16429995Sminshall 
16530052Sminshall     foo = malloc(sizeof c);
16630052Sminshall     if (foo == 0) {
16730052Sminshall 	fprintf(stderr, "No room for ascii characters!\n");
16830052Sminshall 	exit(1);
16930052Sminshall     }
17030052Sminshall     *foo = c;
17130052Sminshall     return foo;
17230052Sminshall }
17330052Sminshall 
17429995Sminshall char *
17529995Sminshall doit(hit, type, hits)
17629995Sminshall struct hit *hit;
17729995Sminshall unsigned char *type;
17829995Sminshall struct Hits *hits;
17929995Sminshall {
18029995Sminshall     struct thing *this;
18129995Sminshall 
18230077Sminshall     hit->ctlrfcn = FCN_NULL;
18329995Sminshall     if (type[0] == 0) {
18429995Sminshall 	return 0;
18529995Sminshall     }
18629995Sminshall     if (type[1] == 0) {		/* character */
18730077Sminshall 	hit->ctlrfcn = FCN_CHARACTER;
18831614Sminshall 	hit->code = ebc_disp[asc_ebc[type[0]]];
18930052Sminshall 	return savechr(*type);		/* The character is the name */
19029995Sminshall     } else {
19129995Sminshall 	for (this = firstentry(type); this; this = this->next) {
19229995Sminshall 	    if ((type[0] == this->name[4])
19329995Sminshall 				&& (strcmp(type, this->name+4) == 0)) {
19429995Sminshall 		this->hits = hits;
19529995Sminshall 		if (this->name[0] == 'F') {
19630077Sminshall 		    hit->ctlrfcn = FCN_NULL;	/* XXX */
19729995Sminshall 		} else {
19830077Sminshall 		    hit->ctlrfcn = FCN_AID;
19929995Sminshall 		}
20029995Sminshall 		return this->name;
20129995Sminshall 	    }
20229995Sminshall 	}
20330052Sminshall 	fprintf(stderr, "Error: Unknown type %s.\n", type);
20429995Sminshall 	return 0;
20529995Sminshall     }
20629995Sminshall }
20729995Sminshall 
20829995Sminshall 
20929995Sminshall void
21030077Sminshall dohits(aidfile, fcnfile)
21130077Sminshall char	*aidfile, *fcnfile;
21229995Sminshall {
21329995Sminshall     unsigned char plain[100], shifted[100], alted[100], shiftalted[100];
21429995Sminshall     unsigned char line[200];
21529995Sminshall     int keynumber, scancode;
21629995Sminshall     int empty;
21729995Sminshall     int i;
21829995Sminshall     struct hit *hit;
21929995Sminshall     struct hits *ph;
22029995Sminshall     struct Hits *Ph;
22129995Sminshall 
22229995Sminshall     memset((char *)Hits, 0, sizeof Hits);
22329995Sminshall 
22429995Sminshall     /*
22529995Sminshall      * First, we read "host3270.h" to find the names/values of
22629995Sminshall      * various AID; then we read kbd3270.h to find the names/values
22729995Sminshall      * of various FCNs.
22829995Sminshall      */
22929995Sminshall 
23030077Sminshall     if (aidfile == 0) {
23130077Sminshall 	aidfile = "../ctlr/hostctlr.h";
23230077Sminshall     }
23330077Sminshall     scandefine(aidfile, "AID_");
23430077Sminshall     if (fcnfile == 0) {
23530077Sminshall         fcnfile = "../ctlr/function.h";
23630077Sminshall     }
23730077Sminshall     scanwhite(fcnfile, "FCN_");
23829995Sminshall 
23929995Sminshall     while (gets(line) != NULL) {
24029995Sminshall 	if (!isdigit(line[0])) {
24129995Sminshall 	    continue;
24229995Sminshall 	}
24329995Sminshall 	plain[0] = shifted[0] = alted[0] = shiftalted[0] = 0;
24429995Sminshall 	keynumber = -1;
24529995Sminshall 	scancode = -1;
24629995Sminshall 	(void) sscanf(line, "%d %x %s %s %s %s", &keynumber,
24729995Sminshall 		    &scancode, plain, shifted, alted, shiftalted);
24829995Sminshall 	if ((keynumber == -1) || (scancode == -1)
24929995Sminshall 		|| ((plain[0] == 0)
25029995Sminshall 		    && (shifted[0] == 0)
25129995Sminshall 		    && (alted[0] == 0)
25229995Sminshall 		    && (shiftalted[0] == 0))) {
25329995Sminshall 	    continue;
25429995Sminshall 	}
25529995Sminshall 	if (scancode >= 256) {
25630052Sminshall 	    fprintf(stderr,
25730052Sminshall 		"Error: scancode 0x%02x for keynumber %d\n", scancode,
25829995Sminshall 		    keynumber);
25929995Sminshall 	    break;
26029995Sminshall 	}
26130077Sminshall 	if (Hits[scancode].hits.hit[0].ctlrfcn != undefined) {
26230052Sminshall 	    fprintf(stderr,
26330052Sminshall 		"Error: duplicate scancode 0x%02x for keynumber %d\n",
26429995Sminshall 		    scancode, keynumber);
26529995Sminshall 	    break;
26629995Sminshall 	}
26729995Sminshall 	hit = Hits[scancode].hits.hit;
26829995Sminshall 	Hits[scancode].hits.keynumber = keynumber;
26929995Sminshall 	Hits[scancode].name[0] = doit(hit, plain, &Hits[scancode]);
27029995Sminshall 	Hits[scancode].name[1] = doit(hit+1, shifted, &Hits[scancode]);
27129995Sminshall 	Hits[scancode].name[2] = doit(hit+2, alted, &Hits[scancode]);
27229995Sminshall 	Hits[scancode].name[3] = doit(hit+3, shiftalted, &Hits[scancode]);
27329995Sminshall     }
27429995Sminshall }
275