xref: /original-bsd/usr.bin/rdist/lookup.c (revision 00986467)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)lookup.c	5.4 (Berkeley) 06/29/88";
20 #endif /* not lint */
21 
22 #include "defs.h"
23 
24 	/* symbol types */
25 #define VAR	1
26 #define CONST	2
27 
28 struct syment {
29 	int	s_type;
30 	char	*s_name;
31 	struct	namelist *s_value;
32 	struct	syment *s_next;
33 };
34 
35 static struct syment *hashtab[HASHSIZE];
36 
37 /*
38  * Define a variable from a command line argument.
39  */
40 define(name)
41 	char *name;
42 {
43 	register char *cp, *s;
44 	register struct namelist *nl;
45 	struct namelist *value;
46 
47 	if (debug)
48 		printf("define(%s)\n", name);
49 
50 	cp = index(name, '=');
51 	if (cp == NULL)
52 		value = NULL;
53 	else if (cp[1] == '\0') {
54 		*cp = '\0';
55 		value = NULL;
56 	} else if (cp[1] != '(') {
57 		*cp++ = '\0';
58 		value = makenl(cp);
59 	} else {
60 		nl = NULL;
61 		*cp++ = '\0';
62 		do
63 			cp++;
64 		while (*cp == ' ' || *cp == '\t');
65 		for (s = cp; ; s++) {
66 			switch (*s) {
67 			case ')':
68 				*s = '\0';
69 			case '\0':
70 				break;
71 			case ' ':
72 			case '\t':
73 				*s++ = '\0';
74 				while (*s == ' ' || *s == '\t')
75 					s++;
76 				if (*s == ')')
77 					*s = '\0';
78 				break;
79 			default:
80 				continue;
81 			}
82 			if (nl == NULL)
83 				value = nl = makenl(cp);
84 			else {
85 				nl->n_next = makenl(cp);
86 				nl = nl->n_next;
87 			}
88 			if (*s == '\0')
89 				break;
90 			cp = s;
91 		}
92 	}
93 	(void) lookup(name, REPLACE, value);
94 }
95 
96 /*
97  * Lookup name in the table and return a pointer to it.
98  * LOOKUP - just do lookup, return NULL if not found.
99  * INSERT - insert name with value, error if already defined.
100  * REPLACE - insert or replace name with value.
101  */
102 
103 struct namelist *
104 lookup(name, action, value)
105 	char *name;
106 	int action;
107 	struct namelist *value;
108 {
109 	register unsigned n;
110 	register char *cp;
111 	register struct syment *s;
112 	char buf[256];
113 
114 	if (debug)
115 		printf("lookup(%s, %d, %x)\n", name, action, value);
116 
117 	n = 0;
118 	for (cp = name; *cp; )
119 		n += *cp++;
120 	n %= HASHSIZE;
121 
122 	for (s = hashtab[n]; s != NULL; s = s->s_next) {
123 		if (strcmp(name, s->s_name))
124 			continue;
125 		if (action != LOOKUP) {
126 			if (action != INSERT || s->s_type != CONST) {
127 				(void)sprintf(buf, "%s redefined", name);
128 				yyerror(buf);
129 			}
130 		}
131 		return(s->s_value);
132 	}
133 
134 	if (action == LOOKUP) {
135 		(void)sprintf(buf, "%s undefined", name);
136 		yyerror(buf);
137 		return(NULL);
138 	}
139 
140 	s = ALLOC(syment);
141 	if (s == NULL)
142 		fatal("ran out of memory\n");
143 	s->s_next = hashtab[n];
144 	hashtab[n] = s;
145 	s->s_type = action == INSERT ? VAR : CONST;
146 	s->s_name = name;
147 	s->s_value = value;
148 	return(value);
149 }
150