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