1 /*- 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)dohits.c 8.1 (Berkeley) 06/06/93"; 10 #endif /* not lint */ 11 12 /* 13 * This program scans a file which describes a keyboard. The output 14 * of the program is a series of 'C' declarations which describe a 15 * mapping between (scancode, shiftstate, altstate) and 3270 functions, 16 * characters, and AIDs. 17 * 18 * The format of the input file is as follows: 19 * 20 * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ] 21 * 22 * keynumber is in decimal, and starts in column 1. 23 * scancode is hexadecimal. 24 * unshifted, etc. - these are either a single ascii character, 25 * or the name of a function or an AID-generating key. 26 * 27 * all fields are separated by a single space. 28 */ 29 30 #include <stdio.h> 31 #if defined(unix) 32 #include <strings.h> 33 #else /* defined(unix) */ 34 #include <string.h> 35 #endif /* defined(unix) */ 36 #include <ctype.h> 37 #include "../general/general.h" 38 #include "../api/asc_ebc.h" 39 #include "../api/ebc_disp.h" 40 #include "../ctlr/function.h" 41 42 #include "dohits.h" 43 44 struct Hits Hits[256]; /* one for each of 0x00-0xff */ 45 46 struct thing *table[100]; 47 48 extern char *malloc(); 49 50 unsigned int 51 dohash(seed, string) 52 unsigned int seed; 53 char *string; 54 { 55 register unsigned int i = seed; 56 register unsigned char c; 57 58 while (c = *string++) { 59 if (c >= 0x60) { 60 c -= (0x60+0x20); 61 } else { 62 c -= 0x20; 63 } 64 i = (i>>26) + (i<<6) + (c&0x3f); 65 } 66 return i; 67 } 68 69 void 70 add(first, second, value) 71 char *first, *second; 72 int value; 73 { 74 struct thing **item, *this; 75 76 item = &firstentry(second); 77 this = (struct thing *) malloc(sizeof *this); 78 this->next = *item; 79 *item = this; 80 this->value = value; 81 strcpy(this->name, first); 82 strcpy(this->name+strlen(this->name), second); 83 } 84 85 void 86 scanwhite(file, prefix) 87 char *file, /* Name of file to scan for whitespace prefix */ 88 *prefix; /* prefix of what should be picked up */ 89 { 90 FILE *ourfile; 91 char compare[100]; 92 char what[100], value[100]; 93 char line[200]; 94 95 sprintf(compare, " %s%%[^,\t \n]", prefix); 96 if ((ourfile = fopen(file, "r")) == NULL) { 97 perror("fopen"); 98 exit(1); 99 } 100 while (!feof(ourfile)) { 101 if (fscanf(ourfile, compare, what) == 1) { 102 add(prefix, what, 0); 103 } 104 do { 105 if (fgets(line, sizeof line, ourfile) == NULL) { 106 if (!feof(ourfile)) { 107 perror("fgets"); 108 } 109 break; 110 } 111 } while (line[strlen(line)-1] != '\n'); 112 } 113 } 114 115 void 116 scandefine(file, prefix) 117 char *file, /* Name of file to scan for #define prefix */ 118 *prefix; /* prefix of what should be picked up */ 119 { 120 FILE *ourfile; 121 char compare[100]; 122 char what[100], value[100]; 123 char line[200]; 124 int whatitis; 125 126 sprintf(compare, "#define %s%%s %%s", prefix); 127 if ((ourfile = fopen(file, "r")) == NULL) { 128 perror("fopen"); 129 exit(1); 130 } 131 while (!feof(ourfile)) { 132 if (fscanf(ourfile, compare, what, value) == 2) { 133 if (value[0] == '0') { 134 if ((value[1] == 'x') || (value[1] == 'X')) { 135 sscanf(value, "0x%x", &whatitis); 136 } else { 137 sscanf(value, "0%o", &whatitis); 138 } 139 } else { 140 sscanf(value, "%d", &whatitis); 141 } 142 add(prefix, what, whatitis); 143 } 144 do { 145 if (fgets(line, sizeof line, ourfile) == NULL) { 146 if (!feof(ourfile)) { 147 perror("fgets"); 148 } 149 break; 150 } 151 } while (line[strlen(line)-1] != '\n'); 152 } 153 } 154 155 char *savechr(c) 156 unsigned char c; 157 { 158 char *foo; 159 160 foo = malloc(sizeof c); 161 if (foo == 0) { 162 fprintf(stderr, "No room for ascii characters!\n"); 163 exit(1); 164 } 165 *foo = c; 166 return foo; 167 } 168 169 char * 170 doit(hit, type, hits) 171 struct hit *hit; 172 unsigned char *type; 173 struct Hits *hits; 174 { 175 struct thing *this; 176 177 hit->ctlrfcn = FCN_NULL; 178 if (type[0] == 0) { 179 return 0; 180 } 181 if (type[1] == 0) { /* character */ 182 hit->ctlrfcn = FCN_CHARACTER; 183 hit->code = ebc_disp[asc_ebc[type[0]]]; 184 return savechr(*type); /* The character is the name */ 185 } else { 186 for (this = firstentry(type); this; this = this->next) { 187 if ((type[0] == this->name[4]) 188 && (strcmp(type, this->name+4) == 0)) { 189 this->hits = hits; 190 if (this->name[0] == 'F') { 191 hit->ctlrfcn = FCN_NULL; /* XXX */ 192 } else { 193 hit->ctlrfcn = FCN_AID; 194 } 195 return this->name; 196 } 197 } 198 fprintf(stderr, "Error: Unknown type %s.\n", type); 199 return 0; 200 } 201 } 202 203 204 void 205 dohits(aidfile, fcnfile) 206 char *aidfile, *fcnfile; 207 { 208 unsigned char plain[100], shifted[100], alted[100], shiftalted[100]; 209 unsigned char line[200]; 210 int keynumber, scancode; 211 int empty; 212 int i; 213 struct hit *hit; 214 struct hits *ph; 215 struct Hits *Ph; 216 217 memset((char *)Hits, 0, sizeof Hits); 218 219 /* 220 * First, we read "host3270.h" to find the names/values of 221 * various AID; then we read kbd3270.h to find the names/values 222 * of various FCNs. 223 */ 224 225 if (aidfile == 0) { 226 aidfile = "../ctlr/hostctlr.h"; 227 } 228 scandefine(aidfile, "AID_"); 229 if (fcnfile == 0) { 230 fcnfile = "../ctlr/function.h"; 231 } 232 scanwhite(fcnfile, "FCN_"); 233 234 while (gets(line) != NULL) { 235 if (!isdigit(line[0])) { 236 continue; 237 } 238 plain[0] = shifted[0] = alted[0] = shiftalted[0] = 0; 239 keynumber = -1; 240 scancode = -1; 241 (void) sscanf(line, "%d %x %s %s %s %s", &keynumber, 242 &scancode, plain, shifted, alted, shiftalted); 243 if ((keynumber == -1) || (scancode == -1) 244 || ((plain[0] == 0) 245 && (shifted[0] == 0) 246 && (alted[0] == 0) 247 && (shiftalted[0] == 0))) { 248 continue; 249 } 250 if (scancode >= 256) { 251 fprintf(stderr, 252 "Error: scancode 0x%02x for keynumber %d\n", scancode, 253 keynumber); 254 break; 255 } 256 if (Hits[scancode].hits.hit[0].ctlrfcn != undefined) { 257 fprintf(stderr, 258 "Error: duplicate scancode 0x%02x for keynumber %d\n", 259 scancode, keynumber); 260 break; 261 } 262 hit = Hits[scancode].hits.hit; 263 Hits[scancode].hits.keynumber = keynumber; 264 Hits[scancode].name[0] = doit(hit, plain, &Hits[scancode]); 265 Hits[scancode].name[1] = doit(hit+1, shifted, &Hits[scancode]); 266 Hits[scancode].name[2] = doit(hit+2, alted, &Hits[scancode]); 267 Hits[scancode].name[3] = doit(hit+3, shiftalted, &Hits[scancode]); 268 } 269 } 270