|
|
#include <stdio.h>
#include <math.h>
#include <string.h>
#define TRUE (~0)
#define FALSE 0
#define TABLESIZE 1100
struct entry { struct entry *t_link; char *t_name; char *t_lex; unsigned short t_id; } *table[TABLESIZE];
FILE *infile, *outfile; unsigned short nsym = 0; unsigned short hashstore = TRUE; unsigned short f386 = TRUE;
extern char *_strdup(); extern char *malloc(); extern unsigned short hash(); extern unsigned short atoi(); static tfree(); /* defined below */ static struct entry *talloc(); /* defined below */
/* Local functions */ void s_entries ( struct entry *, char * ); void enter ( char *, char *, unsigned short );
__cdecl main( ac, av ) int ac; char **av; { char ent[30], name[30], lex[30], ts[30], tc[30]; unsigned short size, count; register unsigned short i; register struct entry *p; struct entry *q; char *a; double n, j, ssq, sum;
ac--; av++;
while (**av == '-') { ac--; a = *av++;
while (*++a){
if (_stricmp(a, "dnoV386") == 0){ f386 = FALSE; break; } else if (*a == 'h') hashstore = ~hashstore; else { fprintf( stderr, "usage: genkey [-dnoV386] [-h] [infile] [outfile]\n" ); exit( 1 ); } } }
if (ac < 1) infile = stdin; else { ac--;
if ((infile = fopen( *av++, "r" )) == NULL) { fprintf( stderr, "Cannot open input file %s\n", *--av ); exit( 1 ); } }
if (ac < 1) outfile = stdout; else if ((outfile = fopen( *av, "w" )) == NULL) { fprintf( stderr, "Cannot open output file %s\n", *av ); exit( 1 ); }
#ifdef DEBUG
setbuf( outfile, NULL ); #endif
/* copy first line of file */
do { i = getc( infile ); putc( i, outfile ); } while (i != '\n');
while (fscanf( infile, " %s %s %s\n", tc, ts, name) == 3) { count = atoi( tc ); size = atoi( ts );
#ifdef DEBUG
printf( "DEBUG: name=%s, size=%u, count=%u\n", name, size, count ); #endif
for (i = 0; i < TABLESIZE; table[i++] = NULL) ;
for (i = 0; i < count; i++) if (fscanf( infile, " %s %s\n", ent, lex ) == 2) {
#ifdef DEBUG
printf( "DEBUG: ent=%s, lex=%s\n", ent, lex ); #endif
enter( ent, lex, size ); } else { fprintf( stderr, "Error in input file\n" ); exit( 1 ); }
#ifdef DEBUG
printf( "DEBUG: finished input loop\n" ); #endif
print_table( size );
#ifdef DEBUG
printf( "DEBUG: finished print_table()\n" ); #endif
print_struct( name, size );
#ifdef DEBUG
printf("DEBUG: finished print_struct()\n" ); #endif
n = sum = ssq = 0.0;
for (i = 0; i < TABLESIZE; i++) { j = 0.0;
if (p = table[i]) { n += 1.0;
do { q = p->t_link; tfree( p ); j += 1.0; } while (p = q);
sum += j; ssq += j * j; } }
#ifdef DEBUG
printf( "DEBUG: finished statistics loop\n" ); #endif
printf( "%6s: Size = %3u, Buckets = %3u, Avg = %.2f, Std = %.2f\n", name, (unsigned short)sum, (unsigned short)n, sum / n, sqrt( (ssq - sum * sum / n) / (n - 1.0) ) );
#ifdef DEBUG
printf( "DEBUG: finished this table; looking for more\n" ); #endif
}
exit( 0 ); }
/****************************************************************/ /* */ /* enter : make an ent into the symbol table. */ /* */ /****************************************************************/
void enter ( ent, lex, size ) char *ent; char *lex; unsigned short size; { register unsigned short hashval; register struct entry *p; int cb; int fIs386Only;
cb = strlen(ent); fIs386Only = !strcmp(ent + strlen(ent) - 4, ".386");
if (!f386 && fIs386Only) return;
if (fIs386Only) *(ent + cb - 4) = '\0';
p = talloc(); p->t_id = nsym++; hashval = hash( ent ) % size; p->t_link = table[hashval]; table[hashval] = p;
if ((p->t_name = _strdup( ent )) == NULL || (p->t_lex = _strdup( lex )) == NULL) memerror(); }
/****************************************************************/ /* */ /* print_table : output the table we have built. */ /* */ /****************************************************************/
print_table ( size ) unsigned short size; { register unsigned short i; register struct entry *p;
fprintf( outfile, "/***\n" );
for (i = 0; i < size; i++) { fprintf( outfile, " *\t[%u]\n", i );
for (p = table[i]; p; p = p->t_link) fprintf( outfile, " *\t\t%s,\t%s\n", p->t_name, p->t_lex ); }
fprintf( outfile, " */\n" ); }
/****************************************************************/ /* */ /* print_struct : print the initialization structures. */ /* */ /****************************************************************/
print_struct ( name, size ) char *name; unsigned short size; { register unsigned short i;
for (i = 0; i < size; i++) s_entries( table[i], name );
s_symbols( name, size ); s_header( name, size ); }
/****************************************************************/ /* */ /* s_entries : print the symbol names and defs. */ /* */ /****************************************************************/
void s_entries ( p, name ) register struct entry *p; char *name; { struct reverse { struct entry *actual; struct reverse *next; } *head = NULL; register struct reverse *q;
if (!p) return;
while (p) {
/*
** all definitions must be reversed so that output will be that a ** unit will be defined before it is used. */
if ((q = (struct reverse *)malloc( sizeof(struct reverse) )) == NULL) memerror();
q->actual = p; q->next = head; head = q; p = p->t_link; }
for (q = head; q; q = q->next) { fprintf( outfile, "static KEYSYM\t%s%u\t= {", name, q->actual->t_id );
if (hashstore) if (q->actual->t_link) fprintf( outfile, "&%s%u,\"%s\",%u,%s", name, q->actual->t_link->t_id, q->actual->t_name, hash( q->actual->t_name ), q->actual->t_lex ); else fprintf( outfile, "0,\"%s\",%u,%s", q->actual->t_name, hash( q->actual->t_name ), q->actual->t_lex ); else if (q->actual->t_link) fprintf( outfile, "&%s%u,\"%s\",%s", name, q->actual->t_link->t_id, q->actual->t_name, q->actual->t_lex ); else fprintf( outfile, "0,\"%s\",%s", q->actual->t_name, q->actual->t_lex );
fprintf( outfile, "};\n" ); }
for (q = head; q; head = q) { q = q->next; free( head ); } }
/****************************************************************/ /* */ /* s_symbols : output the structure defining the */ /* symbol table. */ /* */ /****************************************************************/
s_symbols ( name, size ) char *name; unsigned short size; { register unsigned short i;
fprintf( outfile, "\nstatic KEYSYM FARSYM *%s_words[%u] = {\n", name, size );
for (i = 0; i < size; i++) if (table[i]) fprintf( outfile, "\t&%s%u%c\n", name, table[i]->t_id, ((i < (size - 1)) ? ',' : ' ') ); else fprintf( outfile, "\t0%c\n", ((i < (size - 1)) ? ',' : ' ') );
fprintf( outfile, "\t};\n" ); }
/****************************************************************/ /* */ /* s_header : output the header for the symbol table. */ /* */ /****************************************************************/
s_header ( name, size ) char *name; unsigned short size; { fprintf( outfile, "\nKEYWORDS %s_table = {%s_words,%u};\n\n\n", name, name, size ); }
static struct entry *head = NULL;
/****************************************************************/ /* */ /* talloc -- allocate space for a table entry */ /* */ /****************************************************************/
static struct entry * talloc () { register struct entry *p;
if (p = head) { head = head->t_link; return( p ); }
if ((p = (struct entry *)malloc( sizeof(struct entry) ))) return( p );
memerror(); }
/****************************************************************/ /* */ /* tfree -- free space for a table entry */ /* */ /****************************************************************/
static tfree ( p ) struct entry *p; { free( p->t_name ); free( p->t_lex ); p->t_link = head; head = p; }
/****************************************************************/ /* */ /* memerr -- ran out of heap space; die */ /* */ /****************************************************************/
memerror () { fprintf( stderr, "Out of heap space\n" ); exit( 1 ); }
#ifdef XENIX
int _stricmp ( first, last ) register char *first; register char *last; { register f; register l;
do { if ((f = *first++) >= 'A' && f <= 'Z') f += 'a' - 'A';
if ((l = *last++) >= 'A' && l <= 'Z') l += 'a' - 'A'; } while (f && f == l);
return( f - l ); }
#endif /* XENIX */
|