1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)lookup.c 5.4 (Berkeley) 06/29/88"; 20 #endif /* not lint */ 21 22 #include "defs.h" 23 24 /* symbol types */ 25 #define VAR 1 26 #define CONST 2 27 28 struct syment { 29 int s_type; 30 char *s_name; 31 struct namelist *s_value; 32 struct syment *s_next; 33 }; 34 35 static struct syment *hashtab[HASHSIZE]; 36 37 /* 38 * Define a variable from a command line argument. 39 */ 40 define(name) 41 char *name; 42 { 43 register char *cp, *s; 44 register struct namelist *nl; 45 struct namelist *value; 46 47 if (debug) 48 printf("define(%s)\n", name); 49 50 cp = index(name, '='); 51 if (cp == NULL) 52 value = NULL; 53 else if (cp[1] == '\0') { 54 *cp = '\0'; 55 value = NULL; 56 } else if (cp[1] != '(') { 57 *cp++ = '\0'; 58 value = makenl(cp); 59 } else { 60 nl = NULL; 61 *cp++ = '\0'; 62 do 63 cp++; 64 while (*cp == ' ' || *cp == '\t'); 65 for (s = cp; ; s++) { 66 switch (*s) { 67 case ')': 68 *s = '\0'; 69 case '\0': 70 break; 71 case ' ': 72 case '\t': 73 *s++ = '\0'; 74 while (*s == ' ' || *s == '\t') 75 s++; 76 if (*s == ')') 77 *s = '\0'; 78 break; 79 default: 80 continue; 81 } 82 if (nl == NULL) 83 value = nl = makenl(cp); 84 else { 85 nl->n_next = makenl(cp); 86 nl = nl->n_next; 87 } 88 if (*s == '\0') 89 break; 90 cp = s; 91 } 92 } 93 (void) lookup(name, REPLACE, value); 94 } 95 96 /* 97 * Lookup name in the table and return a pointer to it. 98 * LOOKUP - just do lookup, return NULL if not found. 99 * INSERT - insert name with value, error if already defined. 100 * REPLACE - insert or replace name with value. 101 */ 102 103 struct namelist * 104 lookup(name, action, value) 105 char *name; 106 int action; 107 struct namelist *value; 108 { 109 register unsigned n; 110 register char *cp; 111 register struct syment *s; 112 char buf[256]; 113 114 if (debug) 115 printf("lookup(%s, %d, %x)\n", name, action, value); 116 117 n = 0; 118 for (cp = name; *cp; ) 119 n += *cp++; 120 n %= HASHSIZE; 121 122 for (s = hashtab[n]; s != NULL; s = s->s_next) { 123 if (strcmp(name, s->s_name)) 124 continue; 125 if (action != LOOKUP) { 126 if (action != INSERT || s->s_type != CONST) { 127 (void)sprintf(buf, "%s redefined", name); 128 yyerror(buf); 129 } 130 } 131 return(s->s_value); 132 } 133 134 if (action == LOOKUP) { 135 (void)sprintf(buf, "%s undefined", name); 136 yyerror(buf); 137 return(NULL); 138 } 139 140 s = ALLOC(syment); 141 if (s == NULL) 142 fatal("ran out of memory\n"); 143 s->s_next = hashtab[n]; 144 hashtab[n] = s; 145 s->s_type = action == INSERT ? VAR : CONST; 146 s->s_name = name; 147 s->s_value = value; 148 return(value); 149 } 150