1 /* $OpenBSD: lookup.c,v 1.14 2012/11/12 01:14:41 guenther Exp $ */ 2 3 /* 4 * Copyright (c) 1983 Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include "defs.h" 33 34 /* symbol types */ 35 #define VAR 1 36 #define CONST 2 37 38 struct syment { 39 int s_type; 40 char *s_name; 41 struct namelist *s_value; 42 struct syment *s_next; 43 }; 44 45 static struct syment *hashtab[HASHSIZE]; 46 47 /* 48 * Define a variable from a command line argument. 49 */ 50 void 51 define(char *name) 52 { 53 char *cp, *s; 54 struct namelist *nl; 55 struct namelist *value; 56 57 debugmsg(DM_CALL, "define(%s)", name); 58 59 cp = strchr(name, '='); 60 if (cp == NULL) 61 value = NULL; 62 else if (cp[1] == '\0') { 63 *cp = '\0'; 64 value = NULL; 65 } else if (cp[1] != '(') { 66 *cp++ = '\0'; 67 value = makenl(cp); 68 } else { 69 value = NULL; 70 nl = NULL; 71 *cp++ = '\0'; 72 do 73 cp++; 74 while (*cp == ' ' || *cp == '\t'); 75 for (s = cp; ; s++) { 76 switch (*s) { 77 case ')': 78 *s = '\0'; 79 case '\0': 80 break; 81 case ' ': 82 case '\t': 83 *s++ = '\0'; 84 while (*s == ' ' || *s == '\t') 85 s++; 86 if (*s == ')') 87 *s = '\0'; 88 break; 89 default: 90 continue; 91 } 92 if (nl == NULL) 93 value = nl = makenl(cp); 94 else { 95 nl->n_next = makenl(cp); 96 nl = nl->n_next; 97 } 98 if (*s == '\0') 99 break; 100 cp = s; 101 } 102 } 103 (void) lookup(name, REPLACE, value); 104 } 105 106 /* 107 * Lookup name in the table and return a pointer to it. 108 * LOOKUP - just do lookup, return NULL if not found. 109 * INSERT - insert name with value, error if already defined. 110 * REPLACE - insert or replace name with value. 111 */ 112 113 struct namelist * 114 lookup(char *name, int action, struct namelist *value) 115 { 116 unsigned int n; 117 char *cp; 118 struct syment *s; 119 char ebuf[BUFSIZ]; 120 121 debugmsg(DM_CALL, "lookup(%s, %d, %p)", name, action, value); 122 123 n = 0; 124 for (cp = name; *cp; ) 125 n += *cp++; 126 n %= HASHSIZE; 127 128 for (s = hashtab[n]; s != NULL; s = s->s_next) { 129 if (strcmp(name, s->s_name)) 130 continue; 131 if (action != LOOKUP) { 132 if (action != INSERT || s->s_type != CONST) { 133 (void) snprintf(ebuf, sizeof(ebuf), 134 "%.*s redefined", 135 (int)(sizeof(ebuf) - 136 sizeof(" redefined")), name); 137 yyerror(ebuf); 138 } 139 } 140 return(s->s_value); 141 } 142 143 if (action == LOOKUP) { 144 (void) snprintf(ebuf, sizeof(ebuf), "%.*s undefined", 145 (int)(sizeof(ebuf) - sizeof(" undefined")), 146 name); 147 yyerror(ebuf); 148 return(NULL); 149 } 150 151 s = ALLOC(syment); 152 s->s_next = hashtab[n]; 153 hashtab[n] = s; 154 s->s_type = action == INSERT ? VAR : CONST; 155 s->s_name = name; 156 s->s_value = value; 157 158 return(value); 159 } 160