1 /* 2 * Copyright (c) 1983, 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[] = "@(#)lookup.c 8.1 (Berkeley) 06/09/93"; 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 void 31 define(name) 32 char *name; 33 { 34 register char *cp, *s; 35 register struct namelist *nl; 36 struct namelist *value; 37 38 if (debug) 39 printf("define(%s)\n", name); 40 41 cp = index(name, '='); 42 if (cp == NULL) 43 value = NULL; 44 else if (cp[1] == '\0') { 45 *cp = '\0'; 46 value = NULL; 47 } else if (cp[1] != '(') { 48 *cp++ = '\0'; 49 value = makenl(cp); 50 } else { 51 nl = NULL; 52 *cp++ = '\0'; 53 do 54 cp++; 55 while (*cp == ' ' || *cp == '\t'); 56 for (s = cp; ; s++) { 57 switch (*s) { 58 case ')': 59 *s = '\0'; 60 case '\0': 61 break; 62 case ' ': 63 case '\t': 64 *s++ = '\0'; 65 while (*s == ' ' || *s == '\t') 66 s++; 67 if (*s == ')') 68 *s = '\0'; 69 break; 70 default: 71 continue; 72 } 73 if (nl == NULL) 74 value = nl = makenl(cp); 75 else { 76 nl->n_next = makenl(cp); 77 nl = nl->n_next; 78 } 79 if (*s == '\0') 80 break; 81 cp = s; 82 } 83 } 84 (void) lookup(name, REPLACE, value); 85 } 86 87 /* 88 * Lookup name in the table and return a pointer to it. 89 * LOOKUP - just do lookup, return NULL if not found. 90 * INSERT - insert name with value, error if already defined. 91 * REPLACE - insert or replace name with value. 92 */ 93 94 struct namelist * 95 lookup(name, action, value) 96 char *name; 97 int action; 98 struct namelist *value; 99 { 100 register unsigned n; 101 register char *cp; 102 register struct syment *s; 103 char buf[256]; 104 105 if (debug) 106 printf("lookup(%s, %d, %x)\n", name, action, value); 107 108 n = 0; 109 for (cp = name; *cp; ) 110 n += *cp++; 111 n %= HASHSIZE; 112 113 for (s = hashtab[n]; s != NULL; s = s->s_next) { 114 if (strcmp(name, s->s_name)) 115 continue; 116 if (action != LOOKUP) { 117 if (action != INSERT || s->s_type != CONST) { 118 (void)sprintf(buf, "%s redefined", name); 119 yyerror(buf); 120 } 121 } 122 return(s->s_value); 123 } 124 125 if (action == LOOKUP) { 126 (void)sprintf(buf, "%s undefined", name); 127 yyerror(buf); 128 return(NULL); 129 } 130 131 s = ALLOC(syment); 132 if (s == NULL) 133 fatal("ran out of memory\n"); 134 s->s_next = hashtab[n]; 135 hashtab[n] = s; 136 s->s_type = action == INSERT ? VAR : CONST; 137 s->s_name = name; 138 s->s_value = value; 139 return(value); 140 } 141