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