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