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