129995Sminshall /*
2*31896Sminshall  *	Copyright (c) 1984-1987 by the Regents of the
3*31896Sminshall  *	University of California and by Gregory Glenn Minshall.
4*31896Sminshall  *
5*31896Sminshall  *	Permission to use, copy, modify, and distribute these
6*31896Sminshall  *	programs and their documentation for any purpose and
7*31896Sminshall  *	without fee is hereby granted, provided that this
8*31896Sminshall  *	copyright and permission appear on all copies and
9*31896Sminshall  *	supporting documentation, the name of the Regents of
10*31896Sminshall  *	the University of California not be used in advertising
11*31896Sminshall  *	or publicity pertaining to distribution of the programs
12*31896Sminshall  *	without specific prior permission, and notice be given in
13*31896Sminshall  *	supporting documentation that copying and distribution is
14*31896Sminshall  *	by permission of the Regents of the University of California
15*31896Sminshall  *	and by Gregory Glenn Minshall.  Neither the Regents of the
16*31896Sminshall  *	University of California nor Gregory Glenn Minshall make
17*31896Sminshall  *	representations about the suitability of this software
18*31896Sminshall  *	for any purpose.  It is provided "as is" without
19*31896Sminshall  *	express or implied warranty.
20*31896Sminshall  */
21*31896Sminshall 
22*31896Sminshall #ifndef lint
23*31896Sminshall static char sccsid[] = "@(#)dohits.c	1.10 (Berkeley) 07/17/87";
24*31896Sminshall #endif	/* not lint */
25*31896Sminshall 
26*31896Sminshall /*
2729995Sminshall  * This program scans a file which describes a keyboard.  The output
2829995Sminshall  * of the program is a series of 'C' declarations which describe a
2929995Sminshall  * mapping between (scancode, shiftstate, altstate) and 3270 functions,
3029995Sminshall  * characters, and AIDs.
3129995Sminshall  *
3229995Sminshall  * The format of the input file is as follows:
3329995Sminshall  *
3429995Sminshall  * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
3529995Sminshall  *
3629995Sminshall  * keynumber is in decimal, and starts in column 1.
3729995Sminshall  * scancode is hexadecimal.
3829995Sminshall  * unshifted, etc. - these are either a single ascii character,
3929995Sminshall  *			or the name of a function or an AID-generating key.
4029995Sminshall  *
4129995Sminshall  * all fields are separated by a single space.
4229995Sminshall  */
4329995Sminshall 
4429995Sminshall #include <stdio.h>
4531102Sminshall #if	defined(unix)
4631065Sminshall #include <strings.h>
4731102Sminshall #else	/* defined(unix) */
4831102Sminshall #include <string.h>
4931102Sminshall #endif	/* defined(unix) */
5029995Sminshall #include <ctype.h>
5131175Sminshall #include "../general/general.h"
5231875Sminshall #include "../api/asc_ebc.h"
5331875Sminshall #include "../api/ebc_disp.h"
5430052Sminshall #include "../ctlr/function.h"
5529995Sminshall 
5629995Sminshall #include "dohits.h"
5729995Sminshall 
5829995Sminshall struct Hits Hits[256];		/* one for each of 0x00-0xff */
5929995Sminshall 
6029995Sminshall struct thing *table[100];
6129995Sminshall 
6230052Sminshall extern char *malloc();
6330052Sminshall 
6429995Sminshall unsigned int
6529995Sminshall dohash(seed, string)
6629995Sminshall unsigned int seed;
6729995Sminshall char *string;
6829995Sminshall {
6929995Sminshall     register unsigned int i = seed;
7029995Sminshall     register unsigned char c;
7129995Sminshall 
7229995Sminshall     while (c = *string++) {
7329995Sminshall 	if (c >= 0x60) {
7430086Sminshall 	    c -= (0x60+0x20);
7529995Sminshall 	} else {
7629995Sminshall 	    c -= 0x20;
7729995Sminshall 	}
7829995Sminshall 	i = (i>>26) + (i<<6) + (c&0x3f);
7929995Sminshall     }
8029995Sminshall     return i;
8129995Sminshall }
8229995Sminshall 
8329995Sminshall void
8429995Sminshall add(first, second, value)
8530077Sminshall char *first, *second;
8630077Sminshall int value;
8729995Sminshall {
8829995Sminshall     struct thing **item, *this;
8929995Sminshall 
9029995Sminshall     item = &firstentry(second);
9129995Sminshall     this = (struct thing *) malloc(sizeof *this);
9229995Sminshall     this->next = *item;
9329995Sminshall     *item = this;
9429995Sminshall     this->value = value;
9529995Sminshall     strcpy(this->name, first);
9629995Sminshall     strcpy(this->name+strlen(this->name), second);
9729995Sminshall }
9829995Sminshall 
9929995Sminshall void
10030077Sminshall scanwhite(file, prefix)
10130077Sminshall char *file,		/* Name of file to scan for whitespace prefix */
10229995Sminshall      *prefix;		/* prefix of what should be picked up */
10329995Sminshall {
10429995Sminshall     FILE *ourfile;
10529995Sminshall     char compare[100];
10629995Sminshall     char what[100], value[100];
10729995Sminshall     char line[200];
10830077Sminshall 
10930077Sminshall     sprintf(compare, " %s%%[^,\t \n]", prefix);
11030077Sminshall     if ((ourfile = fopen(file, "r")) == NULL) {
11130077Sminshall 	perror("fopen");
11230077Sminshall 	exit(1);
11330077Sminshall     }
11430077Sminshall     while (!feof(ourfile)) {
11530077Sminshall 	if (fscanf(ourfile, compare,  what) == 1) {
11630077Sminshall 	    add(prefix, what, 0);
11730077Sminshall 	}
11830077Sminshall 	do {
11930077Sminshall 	    if (fgets(line, sizeof line, ourfile) == NULL) {
12030077Sminshall 		if (!feof(ourfile)) {
12130077Sminshall 		    perror("fgets");
12230077Sminshall 		}
12330077Sminshall 		break;
12430077Sminshall 	    }
12530077Sminshall 	} while (line[strlen(line)-1] != '\n');
12630077Sminshall     }
12730077Sminshall }
12830077Sminshall 
12930077Sminshall void
13030077Sminshall scandefine(file, prefix)
13130077Sminshall char *file,		/* Name of file to scan for #define prefix */
13230077Sminshall      *prefix;		/* prefix of what should be picked up */
13330077Sminshall {
13430077Sminshall     FILE *ourfile;
13530077Sminshall     char compare[100];
13630077Sminshall     char what[100], value[100];
13730077Sminshall     char line[200];
13829995Sminshall     int whatitis;
13929995Sminshall 
14029995Sminshall     sprintf(compare, "#define %s%%s %%s", prefix);
14129995Sminshall     if ((ourfile = fopen(file, "r")) == NULL) {
14229995Sminshall 	perror("fopen");
14329995Sminshall 	exit(1);
14429995Sminshall     }
14529995Sminshall     while (!feof(ourfile)) {
14629995Sminshall 	if (fscanf(ourfile, compare,  what, value) == 2) {
14729995Sminshall 	    if (value[0] == '0') {
14829995Sminshall 		if ((value[1] == 'x') || (value[1] == 'X')) {
14929995Sminshall 		    sscanf(value, "0x%x", &whatitis);
15029995Sminshall 		} else {
15129995Sminshall 		    sscanf(value, "0%o", &whatitis);
15229995Sminshall 		}
15329995Sminshall 	    } else {
15429995Sminshall 		sscanf(value, "%d", &whatitis);
15529995Sminshall 	    }
15629995Sminshall 	    add(prefix, what, whatitis);
15729995Sminshall 	}
15829995Sminshall 	do {
15929995Sminshall 	    if (fgets(line, sizeof line, ourfile) == NULL) {
16029995Sminshall 		if (!feof(ourfile)) {
16129995Sminshall 		    perror("fgets");
16229995Sminshall 		}
16329995Sminshall 		break;
16429995Sminshall 	    }
16529995Sminshall 	} while (line[strlen(line)-1] != '\n');
16629995Sminshall     }
16729995Sminshall }
16829995Sminshall 
16930052Sminshall char *savechr(c)
17030052Sminshall unsigned char c;
17130052Sminshall {
17230052Sminshall     char *foo;
17329995Sminshall 
17430052Sminshall     foo = malloc(sizeof c);
17530052Sminshall     if (foo == 0) {
17630052Sminshall 	fprintf(stderr, "No room for ascii characters!\n");
17730052Sminshall 	exit(1);
17830052Sminshall     }
17930052Sminshall     *foo = c;
18030052Sminshall     return foo;
18130052Sminshall }
18230052Sminshall 
18329995Sminshall char *
18429995Sminshall doit(hit, type, hits)
18529995Sminshall struct hit *hit;
18629995Sminshall unsigned char *type;
18729995Sminshall struct Hits *hits;
18829995Sminshall {
18929995Sminshall     struct thing *this;
19029995Sminshall 
19130077Sminshall     hit->ctlrfcn = FCN_NULL;
19229995Sminshall     if (type[0] == 0) {
19329995Sminshall 	return 0;
19429995Sminshall     }
19529995Sminshall     if (type[1] == 0) {		/* character */
19630077Sminshall 	hit->ctlrfcn = FCN_CHARACTER;
19731614Sminshall 	hit->code = ebc_disp[asc_ebc[type[0]]];
19830052Sminshall 	return savechr(*type);		/* The character is the name */
19929995Sminshall     } else {
20029995Sminshall 	for (this = firstentry(type); this; this = this->next) {
20129995Sminshall 	    if ((type[0] == this->name[4])
20229995Sminshall 				&& (strcmp(type, this->name+4) == 0)) {
20329995Sminshall 		this->hits = hits;
20429995Sminshall 		if (this->name[0] == 'F') {
20530077Sminshall 		    hit->ctlrfcn = FCN_NULL;	/* XXX */
20629995Sminshall 		} else {
20730077Sminshall 		    hit->ctlrfcn = FCN_AID;
20829995Sminshall 		}
20929995Sminshall 		return this->name;
21029995Sminshall 	    }
21129995Sminshall 	}
21230052Sminshall 	fprintf(stderr, "Error: Unknown type %s.\n", type);
21329995Sminshall 	return 0;
21429995Sminshall     }
21529995Sminshall }
21629995Sminshall 
21729995Sminshall 
21829995Sminshall void
21930077Sminshall dohits(aidfile, fcnfile)
22030077Sminshall char	*aidfile, *fcnfile;
22129995Sminshall {
22229995Sminshall     unsigned char plain[100], shifted[100], alted[100], shiftalted[100];
22329995Sminshall     unsigned char line[200];
22429995Sminshall     int keynumber, scancode;
22529995Sminshall     int empty;
22629995Sminshall     int i;
22729995Sminshall     struct hit *hit;
22829995Sminshall     struct hits *ph;
22929995Sminshall     struct Hits *Ph;
23029995Sminshall 
23129995Sminshall     memset((char *)Hits, 0, sizeof Hits);
23229995Sminshall 
23329995Sminshall     /*
23429995Sminshall      * First, we read "host3270.h" to find the names/values of
23529995Sminshall      * various AID; then we read kbd3270.h to find the names/values
23629995Sminshall      * of various FCNs.
23729995Sminshall      */
23829995Sminshall 
23930077Sminshall     if (aidfile == 0) {
24030077Sminshall 	aidfile = "../ctlr/hostctlr.h";
24130077Sminshall     }
24230077Sminshall     scandefine(aidfile, "AID_");
24330077Sminshall     if (fcnfile == 0) {
24430077Sminshall         fcnfile = "../ctlr/function.h";
24530077Sminshall     }
24630077Sminshall     scanwhite(fcnfile, "FCN_");
24729995Sminshall 
24829995Sminshall     while (gets(line) != NULL) {
24929995Sminshall 	if (!isdigit(line[0])) {
25029995Sminshall 	    continue;
25129995Sminshall 	}
25229995Sminshall 	plain[0] = shifted[0] = alted[0] = shiftalted[0] = 0;
25329995Sminshall 	keynumber = -1;
25429995Sminshall 	scancode = -1;
25529995Sminshall 	(void) sscanf(line, "%d %x %s %s %s %s", &keynumber,
25629995Sminshall 		    &scancode, plain, shifted, alted, shiftalted);
25729995Sminshall 	if ((keynumber == -1) || (scancode == -1)
25829995Sminshall 		|| ((plain[0] == 0)
25929995Sminshall 		    && (shifted[0] == 0)
26029995Sminshall 		    && (alted[0] == 0)
26129995Sminshall 		    && (shiftalted[0] == 0))) {
26229995Sminshall 	    continue;
26329995Sminshall 	}
26429995Sminshall 	if (scancode >= 256) {
26530052Sminshall 	    fprintf(stderr,
26630052Sminshall 		"Error: scancode 0x%02x for keynumber %d\n", scancode,
26729995Sminshall 		    keynumber);
26829995Sminshall 	    break;
26929995Sminshall 	}
27030077Sminshall 	if (Hits[scancode].hits.hit[0].ctlrfcn != undefined) {
27130052Sminshall 	    fprintf(stderr,
27230052Sminshall 		"Error: duplicate scancode 0x%02x for keynumber %d\n",
27329995Sminshall 		    scancode, keynumber);
27429995Sminshall 	    break;
27529995Sminshall 	}
27629995Sminshall 	hit = Hits[scancode].hits.hit;
27729995Sminshall 	Hits[scancode].hits.keynumber = keynumber;
27829995Sminshall 	Hits[scancode].name[0] = doit(hit, plain, &Hits[scancode]);
27929995Sminshall 	Hits[scancode].name[1] = doit(hit+1, shifted, &Hits[scancode]);
28029995Sminshall 	Hits[scancode].name[2] = doit(hit+2, alted, &Hits[scancode]);
28129995Sminshall 	Hits[scancode].name[3] = doit(hit+3, shiftalted, &Hits[scancode]);
28229995Sminshall     }
28329995Sminshall }
284