1*4538623fSlukem /* $NetBSD: lookup.c,v 1.9 2009/04/13 04:35:36 lukem Exp $ */
23aab4f7dSthorpej
361f28255Scgd /*
4a5bfdf78Scgd * Copyright (c) 1983, 1993
5a5bfdf78Scgd * The Regents of the University of California. All rights reserved.
661f28255Scgd *
761f28255Scgd * Redistribution and use in source and binary forms, with or without
861f28255Scgd * modification, are permitted provided that the following conditions
961f28255Scgd * are met:
1061f28255Scgd * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd * notice, this list of conditions and the following disclaimer.
1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd * notice, this list of conditions and the following disclaimer in the
1461f28255Scgd * documentation and/or other materials provided with the distribution.
1589aaa1bbSagc * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd * may be used to endorse or promote products derived from this software
1761f28255Scgd * without specific prior written permission.
1861f28255Scgd *
1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd * SUCH DAMAGE.
3061f28255Scgd */
3161f28255Scgd
323b3cf635Slukem #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
343aab4f7dSthorpej #if 0
353aab4f7dSthorpej static char sccsid[] = "@(#)lookup.c 8.1 (Berkeley) 6/9/93";
363aab4f7dSthorpej #else
37*4538623fSlukem __RCSID("$NetBSD: lookup.c,v 1.9 2009/04/13 04:35:36 lukem Exp $");
383aab4f7dSthorpej #endif
3961f28255Scgd #endif /* not lint */
4061f28255Scgd
4161f28255Scgd #include "defs.h"
4261f28255Scgd
4361f28255Scgd /* symbol types */
4461f28255Scgd #define VAR 1
4561f28255Scgd #define CONST 2
4661f28255Scgd
4761f28255Scgd struct syment {
4861f28255Scgd int s_type;
4961f28255Scgd char *s_name;
5061f28255Scgd struct namelist *s_value;
5161f28255Scgd struct syment *s_next;
5261f28255Scgd };
5361f28255Scgd
5461f28255Scgd static struct syment *hashtab[HASHSIZE];
5561f28255Scgd
5661f28255Scgd /*
5761f28255Scgd * Define a variable from a command line argument.
5861f28255Scgd */
59a5bfdf78Scgd void
define(char * name)60a9b4ca62Swiz define(char *name)
6161f28255Scgd {
623b3cf635Slukem char *cp, *s;
633b3cf635Slukem struct namelist *nl;
6461f28255Scgd struct namelist *value;
6561f28255Scgd
663b3cf635Slukem value = NULL;
673b3cf635Slukem
6861f28255Scgd if (debug)
6961f28255Scgd printf("define(%s)\n", name);
7061f28255Scgd
713b3cf635Slukem cp = strchr(name, '=');
7261f28255Scgd if (cp == NULL)
7361f28255Scgd value = NULL;
7461f28255Scgd else if (cp[1] == '\0') {
7561f28255Scgd *cp = '\0';
7661f28255Scgd value = NULL;
7761f28255Scgd } else if (cp[1] != '(') {
7861f28255Scgd *cp++ = '\0';
7961f28255Scgd value = makenl(cp);
8061f28255Scgd } else {
8161f28255Scgd nl = NULL;
8261f28255Scgd *cp++ = '\0';
8361f28255Scgd do
8461f28255Scgd cp++;
8561f28255Scgd while (*cp == ' ' || *cp == '\t');
8661f28255Scgd for (s = cp; ; s++) {
8761f28255Scgd switch (*s) {
8861f28255Scgd case ')':
8961f28255Scgd *s = '\0';
9061f28255Scgd case '\0':
9161f28255Scgd break;
9261f28255Scgd case ' ':
9361f28255Scgd case '\t':
9461f28255Scgd *s++ = '\0';
9561f28255Scgd while (*s == ' ' || *s == '\t')
9661f28255Scgd s++;
9761f28255Scgd if (*s == ')')
9861f28255Scgd *s = '\0';
9961f28255Scgd break;
10061f28255Scgd default:
10161f28255Scgd continue;
10261f28255Scgd }
10361f28255Scgd if (nl == NULL)
10461f28255Scgd value = nl = makenl(cp);
10561f28255Scgd else {
10661f28255Scgd nl->n_next = makenl(cp);
10761f28255Scgd nl = nl->n_next;
10861f28255Scgd }
10961f28255Scgd if (*s == '\0')
11061f28255Scgd break;
11161f28255Scgd cp = s;
11261f28255Scgd }
11361f28255Scgd }
11461f28255Scgd (void) lookup(name, REPLACE, value);
11561f28255Scgd }
11661f28255Scgd
11761f28255Scgd /*
11861f28255Scgd * Lookup name in the table and return a pointer to it.
11961f28255Scgd * LOOKUP - just do lookup, return NULL if not found.
12061f28255Scgd * INSERT - insert name with value, error if already defined.
12161f28255Scgd * REPLACE - insert or replace name with value.
12261f28255Scgd */
12361f28255Scgd
12461f28255Scgd struct namelist *
lookup(char * name,int action,struct namelist * value)125a9b4ca62Swiz lookup(char *name, int action, struct namelist *value)
12661f28255Scgd {
1273b3cf635Slukem unsigned n;
1283b3cf635Slukem char *cp;
1293b3cf635Slukem struct syment *s;
130*4538623fSlukem char lbuf[256];
13161f28255Scgd
13261f28255Scgd if (debug)
1333b3cf635Slukem printf("lookup(%s, %d, %lx)\n", name, action, (long)value);
13461f28255Scgd
13561f28255Scgd n = 0;
13661f28255Scgd for (cp = name; *cp; )
13761f28255Scgd n += *cp++;
13861f28255Scgd n %= HASHSIZE;
13961f28255Scgd
14061f28255Scgd for (s = hashtab[n]; s != NULL; s = s->s_next) {
14161f28255Scgd if (strcmp(name, s->s_name))
14261f28255Scgd continue;
14361f28255Scgd if (action != LOOKUP) {
14461f28255Scgd if (action != INSERT || s->s_type != CONST) {
145*4538623fSlukem (void)snprintf(lbuf, sizeof(lbuf),
146336eeb5fSthorpej "%s redefined", name);
147*4538623fSlukem yyerror(lbuf);
14861f28255Scgd }
14961f28255Scgd }
15061f28255Scgd return(s->s_value);
15161f28255Scgd }
15261f28255Scgd
15361f28255Scgd if (action == LOOKUP) {
154*4538623fSlukem (void)snprintf(lbuf, sizeof(lbuf), "%s undefined", name);
155*4538623fSlukem yyerror(lbuf);
15661f28255Scgd return(NULL);
15761f28255Scgd }
15861f28255Scgd
15961f28255Scgd s = ALLOC(syment);
16061f28255Scgd if (s == NULL)
16161f28255Scgd fatal("ran out of memory\n");
16261f28255Scgd s->s_next = hashtab[n];
16361f28255Scgd hashtab[n] = s;
16461f28255Scgd s->s_type = action == INSERT ? VAR : CONST;
16561f28255Scgd s->s_name = name;
16661f28255Scgd s->s_value = value;
16761f28255Scgd return(value);
16861f28255Scgd }
169