xref: /original-bsd/usr.bin/rdist/lookup.c (revision 3705696b)
1 /*
2  * Copyright (c) 1983, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)lookup.c	8.1 (Berkeley) 06/09/93";
10 #endif /* not lint */
11 
12 #include "defs.h"
13 
14 	/* symbol types */
15 #define VAR	1
16 #define CONST	2
17 
18 struct syment {
19 	int	s_type;
20 	char	*s_name;
21 	struct	namelist *s_value;
22 	struct	syment *s_next;
23 };
24 
25 static struct syment *hashtab[HASHSIZE];
26 
27 /*
28  * Define a variable from a command line argument.
29  */
30 void
31 define(name)
32 	char *name;
33 {
34 	register char *cp, *s;
35 	register struct namelist *nl;
36 	struct namelist *value;
37 
38 	if (debug)
39 		printf("define(%s)\n", name);
40 
41 	cp = index(name, '=');
42 	if (cp == NULL)
43 		value = NULL;
44 	else if (cp[1] == '\0') {
45 		*cp = '\0';
46 		value = NULL;
47 	} else if (cp[1] != '(') {
48 		*cp++ = '\0';
49 		value = makenl(cp);
50 	} else {
51 		nl = NULL;
52 		*cp++ = '\0';
53 		do
54 			cp++;
55 		while (*cp == ' ' || *cp == '\t');
56 		for (s = cp; ; s++) {
57 			switch (*s) {
58 			case ')':
59 				*s = '\0';
60 			case '\0':
61 				break;
62 			case ' ':
63 			case '\t':
64 				*s++ = '\0';
65 				while (*s == ' ' || *s == '\t')
66 					s++;
67 				if (*s == ')')
68 					*s = '\0';
69 				break;
70 			default:
71 				continue;
72 			}
73 			if (nl == NULL)
74 				value = nl = makenl(cp);
75 			else {
76 				nl->n_next = makenl(cp);
77 				nl = nl->n_next;
78 			}
79 			if (*s == '\0')
80 				break;
81 			cp = s;
82 		}
83 	}
84 	(void) lookup(name, REPLACE, value);
85 }
86 
87 /*
88  * Lookup name in the table and return a pointer to it.
89  * LOOKUP - just do lookup, return NULL if not found.
90  * INSERT - insert name with value, error if already defined.
91  * REPLACE - insert or replace name with value.
92  */
93 
94 struct namelist *
95 lookup(name, action, value)
96 	char *name;
97 	int action;
98 	struct namelist *value;
99 {
100 	register unsigned n;
101 	register char *cp;
102 	register struct syment *s;
103 	char buf[256];
104 
105 	if (debug)
106 		printf("lookup(%s, %d, %x)\n", name, action, value);
107 
108 	n = 0;
109 	for (cp = name; *cp; )
110 		n += *cp++;
111 	n %= HASHSIZE;
112 
113 	for (s = hashtab[n]; s != NULL; s = s->s_next) {
114 		if (strcmp(name, s->s_name))
115 			continue;
116 		if (action != LOOKUP) {
117 			if (action != INSERT || s->s_type != CONST) {
118 				(void)sprintf(buf, "%s redefined", name);
119 				yyerror(buf);
120 			}
121 		}
122 		return(s->s_value);
123 	}
124 
125 	if (action == LOOKUP) {
126 		(void)sprintf(buf, "%s undefined", name);
127 		yyerror(buf);
128 		return(NULL);
129 	}
130 
131 	s = ALLOC(syment);
132 	if (s == NULL)
133 		fatal("ran out of memory\n");
134 	s->s_next = hashtab[n];
135 	hashtab[n] = s;
136 	s->s_type = action == INSERT ? VAR : CONST;
137 	s->s_name = name;
138 	s->s_value = value;
139 	return(value);
140 }
141