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>
22 
23 #define	LETS_SEE_ASCII
24 #include "../keyboard/m4.out"
25 #undef	LETS_SEE_ASCII
26 
27 #include "../ascii/ascebc.h"
28 #include "../ctlr/ebc_disp.h"
29 #include "../ctlr/function.h"
30 
31 #include "dohits.h"
32 
33 
34 void
35 main(argc, argv)
36 int	argc;
37 char	*argv[];
38 {
39     int scancode;
40     int asciicode;
41     int empty;
42     int i;
43     int c;
44     int found;
45     struct hits *ph;
46     struct Hits *Ph;
47     TC_Ascii_t *TC;
48     struct thing *this;
49     struct {
50 	char *shift;
51 	int	scancode;
52     } tbl[128], *Pt;
53     static char *shiftof[] = { "normal", "shifted", "alted", "shiftalted" };
54     char *aidfile = 0, *fcnfile = 0;
55 
56     if (argc > 1) {
57 	if (argv[1][0] != '-') {
58 	    aidfile = argv[1];
59 	}
60     }
61     if (argc > 2) {
62 	if (argv[2][0] != '-') {
63 	    fcnfile = argv[2];
64 	}
65     }
66 
67     dohits(aidfile, fcnfile);		/* Set up "Hits" */
68 
69     printf("/*\n");
70     printf(" * Ascii to scancode conversion table.  First\n");
71     printf(" * 128 bytes (0-127) correspond with actual Ascii\n");
72     printf(" * characters; the rest are TC types from termcodes.m4\n");
73     printf(" * (actually, from m4.out).\n");
74     printf(" */\n");
75     printf("struct asctosc {\n");
76     printf("\tenum shiftvalue { cantdo, normal, shifted, alted,");
77     printf(" shiftalted } shift;\n\tunsigned char scancode;");
78     printf("\n} asctosc[] = {\n");
79     /* Build the ascii part of the table. */
80     for (Ph = Hits, scancode = 0; Ph <= Hits+highestof(Hits);
81 							Ph++, scancode++) {
82 	ph = &Ph->hits;
83 	for (i = 0; i < 4; i++) {
84 	    if (ph->hit[i].ctlrfcn == FCN_CHARACTER) {
85 		c = Ph->name[i][0];	/* "name" of this one */
86 		if (tbl[c].shift[0] == 0) {
87 		    tbl[c].shift = shiftof[i];
88 		    tbl[c].scancode = scancode;
89 		}
90 	    }
91 	}
92     }
93     /* Now, output the table */
94     for (Pt = tbl, asciicode = 0; Pt <= tbl+highestof(tbl); Pt++, asciicode++) {
95 	if (Pt->shift[0] == 0) {
96 	    if (isprint(asciicode) && (asciicode != ' ')) {
97 		fprintf(stderr, "Unable to produce scancode sequence for");
98 		fprintf(stderr, " ASCII character [%c]!\n", asciicode);
99 	    }
100 	    printf("\t{ cantdo, 0 },\t");
101 	} else {
102 	    printf("\t{ %s, 0x%x },", Pt->shift, Pt->scancode);
103 	}
104 	printf("\t/* 0x%x", asciicode);
105 	if (isprint(asciicode)) {
106 	    printf(" [%c]", asciicode);
107 	}
108 	printf(" */\n");
109     }
110 
111 
112     for (TC = &TC_Ascii[TC_LOWEST-TC_LOWEST];
113 		TC < &TC_Ascii[TC_LOWEST_USER-TC_LOWEST]; TC++, asciicode++) {
114 	printf("\t{ cantdo, 0 },\t");
115 	printf("\t/* 0x%x */\n", asciicode);
116     }
117     for (TC = &TC_Ascii[TC_LOWEST_USER-TC_LOWEST];
118 		TC <= &TC_Ascii[TC_HIGHEST-TC_LOWEST]; TC++, asciicode++) {
119 	/* Hack for "PFK" names (which should be "PF") */
120 	if (memcmp(TC->tc_name, "PFK", 3) == 0) {
121 	    static char PFonly[100] = "PF";
122 
123 	    strcpy(PFonly+2, TC->tc_name+3);
124 	    TC->tc_name = PFonly;
125 	}
126 	found = 0;
127 	for (this = firstentry(TC->tc_name); (!found) && this;
128 							this = this->next) {
129 	    if ((this->name[4] == TC->tc_name[0])
130 			&& (strcmp(this->name+4, TC->tc_name) == 0)) {
131 		/* this is the entry */
132 		/* What we have is a TC entry matching a scancode entry */
133 		Ph = this->hits;		/* now, get hits */
134 		if (Ph == 0) {
135 		    continue;
136 		}
137 		for (i = 0; i < 4; i++) {
138 		    if ((Ph->name[i][4] == TC->tc_name[0])
139 			    && (strcmp(Ph->name[i]+4, TC->tc_name) == 0)) {
140 			/* This is THE hit! */
141 			found = 1;
142 			printf("\t{ ");
143 			switch (i) {
144 			case 0:
145 			    printf("normal, ");
146 			    break;
147 			case 1:
148 			    printf("shifted, ");
149 			    break;
150 			case 2:
151 			    printf("alted, ");
152 			    break;
153 			case 3:
154 			    printf("shitfalted, ");
155 			    break;
156 			}
157 			printf("0x%02x },", Ph-Hits);
158 			break;
159 		    }
160 		}
161 	    }
162 	}
163 	if (!found) {
164 	    printf("\t{ cantdo, 0 },\t");
165 	    fprintf(stderr, "Unable to produce TC_%s with scan codes!\n",
166 				TC->tc_name);
167 	}
168 	printf("\t/* 0x%x - %s */\n", asciicode, TC->tc_name);
169     }
170     printf("};\n");
171 }
172