1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)lookup.c 5.5 (Berkeley) 06/01/90"; 10 #endif /* not lint */ 11 12 #include "defs.h" 13 14 /* symbol types */ 15 #define VAR 1 16 #define CONST 2 17 18 struct syment { 19 int s_type; 20 char *s_name; 21 struct namelist *s_value; 22 struct syment *s_next; 23 }; 24 25 static struct syment *hashtab[HASHSIZE]; 26 27 /* 28 * Define a variable from a command line argument. 29 */ 30 define(name) 31 char *name; 32 { 33 register char *cp, *s; 34 register struct namelist *nl; 35 struct namelist *value; 36 37 if (debug) 38 printf("define(%s)\n", name); 39 40 cp = index(name, '='); 41 if (cp == NULL) 42 value = NULL; 43 else if (cp[1] == '\0') { 44 *cp = '\0'; 45 value = NULL; 46 } else if (cp[1] != '(') { 47 *cp++ = '\0'; 48 value = makenl(cp); 49 } else { 50 nl = NULL; 51 *cp++ = '\0'; 52 do 53 cp++; 54 while (*cp == ' ' || *cp == '\t'); 55 for (s = cp; ; s++) { 56 switch (*s) { 57 case ')': 58 *s = '\0'; 59 case '\0': 60 break; 61 case ' ': 62 case '\t': 63 *s++ = '\0'; 64 while (*s == ' ' || *s == '\t') 65 s++; 66 if (*s == ')') 67 *s = '\0'; 68 break; 69 default: 70 continue; 71 } 72 if (nl == NULL) 73 value = nl = makenl(cp); 74 else { 75 nl->n_next = makenl(cp); 76 nl = nl->n_next; 77 } 78 if (*s == '\0') 79 break; 80 cp = s; 81 } 82 } 83 (void) lookup(name, REPLACE, value); 84 } 85 86 /* 87 * Lookup name in the table and return a pointer to it. 88 * LOOKUP - just do lookup, return NULL if not found. 89 * INSERT - insert name with value, error if already defined. 90 * REPLACE - insert or replace name with value. 91 */ 92 93 struct namelist * 94 lookup(name, action, value) 95 char *name; 96 int action; 97 struct namelist *value; 98 { 99 register unsigned n; 100 register char *cp; 101 register struct syment *s; 102 char buf[256]; 103 104 if (debug) 105 printf("lookup(%s, %d, %x)\n", name, action, value); 106 107 n = 0; 108 for (cp = name; *cp; ) 109 n += *cp++; 110 n %= HASHSIZE; 111 112 for (s = hashtab[n]; s != NULL; s = s->s_next) { 113 if (strcmp(name, s->s_name)) 114 continue; 115 if (action != LOOKUP) { 116 if (action != INSERT || s->s_type != CONST) { 117 (void)sprintf(buf, "%s redefined", name); 118 yyerror(buf); 119 } 120 } 121 return(s->s_value); 122 } 123 124 if (action == LOOKUP) { 125 (void)sprintf(buf, "%s undefined", name); 126 yyerror(buf); 127 return(NULL); 128 } 129 130 s = ALLOC(syment); 131 if (s == NULL) 132 fatal("ran out of memory\n"); 133 s->s_next = hashtab[n]; 134 hashtab[n] = s; 135 s->s_type = action == INSERT ? VAR : CONST; 136 s->s_name = name; 137 s->s_value = value; 138 return(value); 139 } 140