1 /* $OpenBSD: lookup.c,v 1.15 2015/01/20 09:00:16 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 <string.h> 33 34 #include "client.h" 35 36 /* symbol types */ 37 #define VAR 1 38 #define CONST 2 39 40 struct syment { 41 int s_type; 42 char *s_name; 43 struct namelist *s_value; 44 struct syment *s_next; 45 }; 46 47 static struct syment *hashtab[HASHSIZE]; 48 49 /* 50 * Define a variable from a command line argument. 51 */ 52 void 53 define(char *name) 54 { 55 char *cp, *s; 56 struct namelist *nl; 57 struct namelist *value; 58 59 debugmsg(DM_CALL, "define(%s)", name); 60 61 cp = strchr(name, '='); 62 if (cp == NULL) 63 value = NULL; 64 else if (cp[1] == '\0') { 65 *cp = '\0'; 66 value = NULL; 67 } else if (cp[1] != '(') { 68 *cp++ = '\0'; 69 value = makenl(cp); 70 } else { 71 value = NULL; 72 nl = NULL; 73 *cp++ = '\0'; 74 do 75 cp++; 76 while (*cp == ' ' || *cp == '\t'); 77 for (s = cp; ; s++) { 78 switch (*s) { 79 case ')': 80 *s = '\0'; 81 case '\0': 82 break; 83 case ' ': 84 case '\t': 85 *s++ = '\0'; 86 while (*s == ' ' || *s == '\t') 87 s++; 88 if (*s == ')') 89 *s = '\0'; 90 break; 91 default: 92 continue; 93 } 94 if (nl == NULL) 95 value = nl = makenl(cp); 96 else { 97 nl->n_next = makenl(cp); 98 nl = nl->n_next; 99 } 100 if (*s == '\0') 101 break; 102 cp = s; 103 } 104 } 105 (void) lookup(name, REPLACE, value); 106 } 107 108 /* 109 * Lookup name in the table and return a pointer to it. 110 * LOOKUP - just do lookup, return NULL if not found. 111 * INSERT - insert name with value, error if already defined. 112 * REPLACE - insert or replace name with value. 113 */ 114 115 struct namelist * 116 lookup(char *name, int action, struct namelist *value) 117 { 118 unsigned int n; 119 char *cp; 120 struct syment *s; 121 char ebuf[BUFSIZ]; 122 123 debugmsg(DM_CALL, "lookup(%s, %d, %p)", name, action, value); 124 125 n = 0; 126 for (cp = name; *cp; ) 127 n += *cp++; 128 n %= HASHSIZE; 129 130 for (s = hashtab[n]; s != NULL; s = s->s_next) { 131 if (strcmp(name, s->s_name)) 132 continue; 133 if (action != LOOKUP) { 134 if (action != INSERT || s->s_type != CONST) { 135 (void) snprintf(ebuf, sizeof(ebuf), 136 "%.*s redefined", 137 (int)(sizeof(ebuf) - 138 sizeof(" redefined")), name); 139 yyerror(ebuf); 140 } 141 } 142 return(s->s_value); 143 } 144 145 if (action == LOOKUP) { 146 (void) snprintf(ebuf, sizeof(ebuf), "%.*s undefined", 147 (int)(sizeof(ebuf) - sizeof(" undefined")), 148 name); 149 yyerror(ebuf); 150 return(NULL); 151 } 152 153 s = ALLOC(syment); 154 s->s_next = hashtab[n]; 155 hashtab[n] = s; 156 s->s_type = action == INSERT ? VAR : CONST; 157 s->s_name = name; 158 s->s_value = value; 159 160 return(value); 161 } 162