Ultrix-3.1/src/cmd/ctrace/lookup.c
/**********************************************************************
* Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. *
* All Rights Reserved. *
* Reference "/usr/src/COPYRIGHT" for applicable restrictions. *
**********************************************************************/
/*
* SCCSID: @(#)lookup.c 3.0 4/21/86
* (System V) lookup.c 1.3
*/
/* ctrace - C program debugging tool
*
* keyword look-up routine for the scanner
*/
#include "global.h"
#include "y.tab.h"
enum bool stdio_preprocessed = no; /* stdio.h already preprocessed */
enum bool setjmp_preprocessed = no; /* setjmp.h already preprocessed */
static struct keystruct {
char *text;
int token;
struct keystruct *next;
} keyword[] = {
"BADMAG", MACRO, NULL,
"EOF", CONSTANT, NULL,
"NULL", CONSTANT, NULL,
"auto", CLASS, NULL,
"break", BREAK_CONT, NULL,
"case", CASE, NULL,
"char", TYPE, NULL,
"continue", BREAK_CONT, NULL,
"default", DEFAULT, NULL,
"do", DO, NULL,
"double", TYPE, NULL,
"else", ELSE, NULL,
"enum", ENUM, NULL,
"extern", CLASS, NULL,
"fgets", STRRES, NULL,
"float", TYPE, NULL,
"for", FOR, NULL,
"fortran", CLASS, NULL,
"gets", STRRES, NULL,
"goto", GOTO, NULL,
"if", IF, NULL,
"int", TYPE, NULL,
"long", TYPE, NULL,
"register", CLASS, NULL,
"return", RETURN, NULL,
"short", TYPE, NULL,
"sizeof", SIZEOF, NULL,
"static", CLASS, NULL,
"stderr", CONSTANT, NULL,
"stdin", CONSTANT, NULL,
"stdout", CONSTANT, NULL,
"strcat", STRCAT, NULL,
"strcmp", STRCMP, NULL,
"strcpy", STRCPY, NULL,
"strlen", STRLEN, NULL,
"strncat", STRNCAT, NULL,
"strncmp", STRNCMP, NULL,
"struct", STRUCT_UNION, NULL,
"switch", SWITCH, NULL,
"typedef", TYPEDEF, NULL,
"union", STRUCT_UNION, NULL,
"unsigned", TYPE, NULL,
"void", TYPE, NULL,
"while", WHILE, NULL,
"_iobuf", IOBUF, NULL,
"jmp_buf", JMP_BUF, NULL,
};
#define KEYWORDS (sizeof(keyword) / sizeof(struct keystruct))
#define HASHSIZE KEYWORDS + 10 /* approximate number of keywords and typedef names */
static struct keystruct *hashtab[HASHSIZE]; /* pointer table */
/* put the keywords into the symbol table */
init_symtab()
{
register int i;
for (i = 0; i < KEYWORDS; ++i)
hashlink(&keyword[i]);
}
/* see if this identifier is a keyword or typedef name */
lookup(ident)
register char *ident;
{
register struct keystruct *p;
/* look up the identifier in the symbol table */
for (p = hashtab[hash(ident)]; p != NULL; p = p->next)
if (strcmp(ident, p->text) == 0) {
if (p->token == IOBUF) { /* Unix 3.0 check */
stdio_preprocessed = yes;
return(IDENT);
}
if (p->token == JMP_BUF) {
setjmp_preprocessed = yes;
return(IDENT);
}
return(p->token);
}
/* this is an identifier */
return(IDENT);
}
/* add a type to the symbol table */
add_type(ident)
char *ident;
{
add_symbol(ident, TYPE);
}
/* add an identifier to the symbol table */
add_symbol(ident, type)
char *ident;
int type;
{
struct keystruct *p;
char *strsave(), *malloc();
int t;
if ((t = lookup(ident)) == IDENT) {
p = (struct keystruct *) malloc(sizeof(*p));
if (p == NULL || (p->text = strsave(ident)) == NULL) {
fatal("out of storage");
}
else {
t = p->token = type;
hashlink(p);
if (type == TYPE && strcmp(p->text, "FILE") == 0) /* Unix 4.0 check */
stdio_preprocessed = yes;
}
}
return(t);
}
char *
strsave(s)
char *s;
{
char *p, *malloc(), *strcpy();
if ((p = malloc((unsigned) (strlen(s) + 1))) != NULL)
strcpy(p, s);
return(p);
}
static
hashlink(p)
register struct keystruct *p;
{
register int hashval;
hashval = hash(p->text);
p->next = hashtab[hashval];
hashtab[hashval] = p;
}
static
hash(s) /* form hash value for string */
register char *s;
{
register int hashval;
for (hashval = 0; *s != '\0'; )
hashval += *s++;
return(hashval % HASHSIZE);
}