129995Sminshall /*
229995Sminshall  * This program scans a file which describes a keyboard.  The output
329995Sminshall  * of the program is a series of 'C' declarations which describe a
429995Sminshall  * mapping between (scancode, shiftstate, altstate) and 3270 functions,
529995Sminshall  * characters, and AIDs.
629995Sminshall  *
729995Sminshall  * The format of the input file is as follows:
829995Sminshall  *
929995Sminshall  * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
1029995Sminshall  *
1129995Sminshall  * keynumber is in decimal, and starts in column 1.
1229995Sminshall  * scancode is hexadecimal.
1329995Sminshall  * unshifted, etc. - these are either a single ascii character,
1429995Sminshall  *			or the name of a function or an AID-generating key.
1529995Sminshall  *
1629995Sminshall  * all fields are separated by a single space.
1729995Sminshall  */
1829995Sminshall 
1929995Sminshall #include <stdio.h>
2029995Sminshall #include <string.h>
2129995Sminshall #include <ctype.h>
2230052Sminshall #include "../ascii/ascebc.h"
2330052Sminshall #include "../ctlr/ebc_disp.h"
2430052Sminshall #include "../ctlr/function.h"
2529995Sminshall 
2629995Sminshall #include "dohits.h"
2729995Sminshall 
2829995Sminshall struct Hits Hits[256];		/* one for each of 0x00-0xff */
2929995Sminshall 
3029995Sminshall struct thing *table[100];
3129995Sminshall 
3230052Sminshall extern char *malloc();
3330052Sminshall 
3429995Sminshall unsigned int
3529995Sminshall dohash(seed, string)
3629995Sminshall unsigned int seed;
3729995Sminshall char *string;
3829995Sminshall {
3929995Sminshall     register unsigned int i = seed;
4029995Sminshall     register unsigned char c;
4129995Sminshall 
4229995Sminshall     while (c = *string++) {
4329995Sminshall 	if (c >= 0x60) {
4429995Sminshall 	    c - = (0x60+0x20);
4529995Sminshall 	} else {
4629995Sminshall 	    c -= 0x20;
4729995Sminshall 	}
4829995Sminshall 	i = (i>>26) + (i<<6) + (c&0x3f);
4929995Sminshall     }
5029995Sminshall     return i;
5129995Sminshall }
5229995Sminshall 
5329995Sminshall void
5429995Sminshall add(first, second, value)
55*30077Sminshall char *first, *second;
56*30077Sminshall int value;
5729995Sminshall {
5829995Sminshall     struct thing **item, *this;
5929995Sminshall 
6029995Sminshall     item = &firstentry(second);
6129995Sminshall     this = (struct thing *) malloc(sizeof *this);
6229995Sminshall     this->next = *item;
6329995Sminshall     *item = this;
6429995Sminshall     this->value = value;
6529995Sminshall     strcpy(this->name, first);
6629995Sminshall     strcpy(this->name+strlen(this->name), second);
6729995Sminshall }
6829995Sminshall 
6929995Sminshall void
70*30077Sminshall scanwhite(file, prefix)
71*30077Sminshall char *file,		/* Name of file to scan for whitespace prefix */
7229995Sminshall      *prefix;		/* prefix of what should be picked up */
7329995Sminshall {
7429995Sminshall     FILE *ourfile;
7529995Sminshall     char compare[100];
7629995Sminshall     char what[100], value[100];
7729995Sminshall     char line[200];
78*30077Sminshall 
79*30077Sminshall     sprintf(compare, " %s%%[^,\t \n]", prefix);
80*30077Sminshall     if ((ourfile = fopen(file, "r")) == NULL) {
81*30077Sminshall 	perror("fopen");
82*30077Sminshall 	exit(1);
83*30077Sminshall     }
84*30077Sminshall     while (!feof(ourfile)) {
85*30077Sminshall 	if (fscanf(ourfile, compare,  what) == 1) {
86*30077Sminshall 	    add(prefix, what, 0);
87*30077Sminshall 	}
88*30077Sminshall 	do {
89*30077Sminshall 	    if (fgets(line, sizeof line, ourfile) == NULL) {
90*30077Sminshall 		if (!feof(ourfile)) {
91*30077Sminshall 		    perror("fgets");
92*30077Sminshall 		}
93*30077Sminshall 		break;
94*30077Sminshall 	    }
95*30077Sminshall 	} while (line[strlen(line)-1] != '\n');
96*30077Sminshall     }
97*30077Sminshall }
98*30077Sminshall 
99*30077Sminshall void
100*30077Sminshall scandefine(file, prefix)
101*30077Sminshall char *file,		/* Name of file to scan for #define prefix */
102*30077Sminshall      *prefix;		/* prefix of what should be picked up */
103*30077Sminshall {
104*30077Sminshall     FILE *ourfile;
105*30077Sminshall     char compare[100];
106*30077Sminshall     char what[100], value[100];
107*30077Sminshall     char line[200];
10829995Sminshall     int whatitis;
10929995Sminshall 
11029995Sminshall     sprintf(compare, "#define %s%%s %%s", prefix);
11129995Sminshall     if ((ourfile = fopen(file, "r")) == NULL) {
11229995Sminshall 	perror("fopen");
11329995Sminshall 	exit(1);
11429995Sminshall     }
11529995Sminshall     while (!feof(ourfile)) {
11629995Sminshall 	if (fscanf(ourfile, compare,  what, value) == 2) {
11729995Sminshall 	    if (value[0] == '0') {
11829995Sminshall 		if ((value[1] == 'x') || (value[1] == 'X')) {
11929995Sminshall 		    sscanf(value, "0x%x", &whatitis);
12029995Sminshall 		} else {
12129995Sminshall 		    sscanf(value, "0%o", &whatitis);
12229995Sminshall 		}
12329995Sminshall 	    } else {
12429995Sminshall 		sscanf(value, "%d", &whatitis);
12529995Sminshall 	    }
12629995Sminshall 	    add(prefix, what, whatitis);
12729995Sminshall 	}
12829995Sminshall 	do {
12929995Sminshall 	    if (fgets(line, sizeof line, ourfile) == NULL) {
13029995Sminshall 		if (!feof(ourfile)) {
13129995Sminshall 		    perror("fgets");
13229995Sminshall 		}
13329995Sminshall 		break;
13429995Sminshall 	    }
13529995Sminshall 	} while (line[strlen(line)-1] != '\n');
13629995Sminshall     }
13729995Sminshall }
13829995Sminshall 
13930052Sminshall char *savechr(c)
14030052Sminshall unsigned char c;
14130052Sminshall {
14230052Sminshall     char *foo;
14329995Sminshall 
14430052Sminshall     foo = malloc(sizeof c);
14530052Sminshall     if (foo == 0) {
14630052Sminshall 	fprintf(stderr, "No room for ascii characters!\n");
14730052Sminshall 	exit(1);
14830052Sminshall     }
14930052Sminshall     *foo = c;
15030052Sminshall     return foo;
15130052Sminshall }
15230052Sminshall 
15329995Sminshall char *
15429995Sminshall doit(hit, type, hits)
15529995Sminshall struct hit *hit;
15629995Sminshall unsigned char *type;
15729995Sminshall struct Hits *hits;
15829995Sminshall {
15929995Sminshall     struct thing *this;
16029995Sminshall 
161*30077Sminshall     hit->ctlrfcn = FCN_NULL;
16229995Sminshall     if (type[0] == 0) {
16329995Sminshall 	return 0;
16429995Sminshall     }
16529995Sminshall     if (type[1] == 0) {		/* character */
166*30077Sminshall 	hit->ctlrfcn = FCN_CHARACTER;
16729995Sminshall 	hit->code = ebc_disp[ascebc[AE_IN][type[0]]];
16830052Sminshall 	return savechr(*type);		/* The character is the name */
16929995Sminshall     } else {
17029995Sminshall 	for (this = firstentry(type); this; this = this->next) {
17129995Sminshall 	    if ((type[0] == this->name[4])
17229995Sminshall 				&& (strcmp(type, this->name+4) == 0)) {
17329995Sminshall 		this->hits = hits;
17429995Sminshall 		if (this->name[0] == 'F') {
175*30077Sminshall 		    hit->ctlrfcn = FCN_NULL;	/* XXX */
17629995Sminshall 		} else {
177*30077Sminshall 		    hit->ctlrfcn = FCN_AID;
17829995Sminshall 		}
17929995Sminshall 		return this->name;
18029995Sminshall 	    }
18129995Sminshall 	}
18230052Sminshall 	fprintf(stderr, "Error: Unknown type %s.\n", type);
18329995Sminshall 	return 0;
18429995Sminshall     }
18529995Sminshall }
18629995Sminshall 
18729995Sminshall 
18829995Sminshall void
189*30077Sminshall dohits(aidfile, fcnfile)
190*30077Sminshall char	*aidfile, *fcnfile;
19129995Sminshall {
19229995Sminshall     unsigned char plain[100], shifted[100], alted[100], shiftalted[100];
19329995Sminshall     unsigned char line[200];
19429995Sminshall     int keynumber, scancode;
19529995Sminshall     int empty;
19629995Sminshall     int i;
19729995Sminshall     struct hit *hit;
19829995Sminshall     struct hits *ph;
19929995Sminshall     struct Hits *Ph;
20029995Sminshall 
20129995Sminshall     memset((char *)Hits, 0, sizeof Hits);
20229995Sminshall 
20329995Sminshall     /*
20429995Sminshall      * First, we read "host3270.h" to find the names/values of
20529995Sminshall      * various AID; then we read kbd3270.h to find the names/values
20629995Sminshall      * of various FCNs.
20729995Sminshall      */
20829995Sminshall 
209*30077Sminshall     if (aidfile == 0) {
210*30077Sminshall 	aidfile = "../ctlr/hostctlr.h";
211*30077Sminshall     }
212*30077Sminshall     scandefine(aidfile, "AID_");
213*30077Sminshall     if (fcnfile == 0) {
214*30077Sminshall         fcnfile = "../ctlr/function.h";
215*30077Sminshall     }
216*30077Sminshall     scanwhite(fcnfile, "FCN_");
21729995Sminshall 
21829995Sminshall     while (gets(line) != NULL) {
21929995Sminshall 	if (!isdigit(line[0])) {
22029995Sminshall 	    continue;
22129995Sminshall 	}
22229995Sminshall 	plain[0] = shifted[0] = alted[0] = shiftalted[0] = 0;
22329995Sminshall 	keynumber = -1;
22429995Sminshall 	scancode = -1;
22529995Sminshall 	(void) sscanf(line, "%d %x %s %s %s %s", &keynumber,
22629995Sminshall 		    &scancode, plain, shifted, alted, shiftalted);
22729995Sminshall 	if ((keynumber == -1) || (scancode == -1)
22829995Sminshall 		|| ((plain[0] == 0)
22929995Sminshall 		    && (shifted[0] == 0)
23029995Sminshall 		    && (alted[0] == 0)
23129995Sminshall 		    && (shiftalted[0] == 0))) {
23229995Sminshall 	    continue;
23329995Sminshall 	}
23429995Sminshall 	if (scancode >= 256) {
23530052Sminshall 	    fprintf(stderr,
23630052Sminshall 		"Error: scancode 0x%02x for keynumber %d\n", scancode,
23729995Sminshall 		    keynumber);
23829995Sminshall 	    break;
23929995Sminshall 	}
240*30077Sminshall 	if (Hits[scancode].hits.hit[0].ctlrfcn != undefined) {
24130052Sminshall 	    fprintf(stderr,
24230052Sminshall 		"Error: duplicate scancode 0x%02x for keynumber %d\n",
24329995Sminshall 		    scancode, keynumber);
24429995Sminshall 	    break;
24529995Sminshall 	}
24629995Sminshall 	hit = Hits[scancode].hits.hit;
24729995Sminshall 	Hits[scancode].hits.keynumber = keynumber;
24829995Sminshall 	Hits[scancode].name[0] = doit(hit, plain, &Hits[scancode]);
24929995Sminshall 	Hits[scancode].name[1] = doit(hit+1, shifted, &Hits[scancode]);
25029995Sminshall 	Hits[scancode].name[2] = doit(hit+2, alted, &Hits[scancode]);
25129995Sminshall 	Hits[scancode].name[3] = doit(hit+3, shiftalted, &Hits[scancode]);
25229995Sminshall     }
25329995Sminshall }
254