xref: /netbsd-src/usr.bin/rdist/lookup.c (revision 4538623f7e2e583e67094db262fb7a08805a3af5)
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