xref: /csrg-svn/usr.bin/rdist/lookup.c (revision 15110)
1*15110Sralph #ifndef lint
2*15110Sralph static	char *sccsid = "@(#)lookup.c	4.1 (Berkeley) 83/09/27";
3*15110Sralph #endif
4*15110Sralph 
5*15110Sralph #include "defs.h"
6*15110Sralph 
7*15110Sralph /*
8*15110Sralph  * Define a variable from a command line argument.
9*15110Sralph  */
10*15110Sralph define(name)
11*15110Sralph 	char *name;
12*15110Sralph {
13*15110Sralph 	register char *cp, *s;
14*15110Sralph 	register struct block *bp, *value;
15*15110Sralph 
16*15110Sralph 	if (debug)
17*15110Sralph 		printf("define(%s)\n", name);
18*15110Sralph 
19*15110Sralph 	cp = index(name, '=');
20*15110Sralph 	if (cp == NULL || cp[1] == '\0')
21*15110Sralph 		value = NULL;
22*15110Sralph 	else if (cp[1] != '(') {
23*15110Sralph 		*cp++ = '\0';
24*15110Sralph 		value = makeblock(NAME, cp);
25*15110Sralph 	} else {
26*15110Sralph 		bp = NULL;
27*15110Sralph 		*cp++ = '\0';
28*15110Sralph 		do
29*15110Sralph 			cp++;
30*15110Sralph 		while (*cp == ' ' || *cp == '\t');
31*15110Sralph 		for (s = cp; ; s++) {
32*15110Sralph 			switch (*s) {
33*15110Sralph 			case ')':
34*15110Sralph 				*s = '\0';
35*15110Sralph 			case '\0':
36*15110Sralph 				break;
37*15110Sralph 			case ' ':
38*15110Sralph 			case '\t':
39*15110Sralph 				*s++ = '\0';
40*15110Sralph 				while (*s == ' ' || *s == '\t')
41*15110Sralph 					s++;
42*15110Sralph 				if (*s == ')')
43*15110Sralph 					*s = '\0';
44*15110Sralph 				break;
45*15110Sralph 			default:
46*15110Sralph 				continue;
47*15110Sralph 			}
48*15110Sralph 			if (bp == NULL)
49*15110Sralph 				value = bp = makeblock(NAME, cp);
50*15110Sralph 			else {
51*15110Sralph 				bp->b_next = makeblock(NAME, cp);
52*15110Sralph 				bp = bp->b_next;
53*15110Sralph 			}
54*15110Sralph 			if (*s == '\0')
55*15110Sralph 				break;
56*15110Sralph 			cp = s;
57*15110Sralph 		}
58*15110Sralph 	}
59*15110Sralph 	bp = makeblock(VAR, name);
60*15110Sralph 	bp->b_args = value;
61*15110Sralph 	(void) lookup(bp->b_name, bp, 1);
62*15110Sralph }
63*15110Sralph 
64*15110Sralph static struct block *hashtab[HASHSIZE];
65*15110Sralph 
66*15110Sralph /*
67*15110Sralph  * Lookup name in the table and return a pointer to it.
68*15110Sralph  * Insert == 0 - just do lookup, return NULL if not found.
69*15110Sralph  * insert == 1 - insert name with value, error if already defined.
70*15110Sralph  * insert == 2 - replace name with value if not entered with insert == 1.
71*15110Sralph  */
72*15110Sralph 
73*15110Sralph struct block *
74*15110Sralph lookup(name, value, insert)
75*15110Sralph 	char *name;
76*15110Sralph 	struct block *value;
77*15110Sralph 	int insert;
78*15110Sralph {
79*15110Sralph 	register unsigned n;
80*15110Sralph 	register char *cp;
81*15110Sralph 	register struct block *b, *f;
82*15110Sralph 
83*15110Sralph 	if (debug)
84*15110Sralph 		printf("lookup(%s, %x, %d)\n", name, value, insert);
85*15110Sralph 
86*15110Sralph 	n = 0;
87*15110Sralph 	for (cp = name; *cp; )
88*15110Sralph 		n += *cp++;
89*15110Sralph 	n %= HASHSIZE;
90*15110Sralph 
91*15110Sralph 	for (b = hashtab[n]; b != NULL; b = b->b_next) {
92*15110Sralph 		if (strcmp(name, b->b_name))
93*15110Sralph 			continue;
94*15110Sralph 		if (insert) {
95*15110Sralph 			if (b->b_type == NAME) {
96*15110Sralph 				warn("%s redefined\n", name);
97*15110Sralph 				f = b->b_args;
98*15110Sralph 				b->b_args = value->b_args;
99*15110Sralph 				value->b_args = f;
100*15110Sralph 			} else if (value->b_type == VAR)
101*15110Sralph 				fatal("%s redefined\n", name);
102*15110Sralph 			while (f = value->b_next) {
103*15110Sralph 				value->b_next = f->b_next;
104*15110Sralph 				free(f->b_name);
105*15110Sralph 				free(f);
106*15110Sralph 			}
107*15110Sralph 			free(value->b_name);
108*15110Sralph 			free(value);
109*15110Sralph 		}
110*15110Sralph 		return(b);
111*15110Sralph 	}
112*15110Sralph 
113*15110Sralph 	if (!insert)
114*15110Sralph 		fatal("%s not defined", name);
115*15110Sralph 
116*15110Sralph 	value->b_next = hashtab[n];
117*15110Sralph 	hashtab[n] = value;
118*15110Sralph 	return(value);
119*15110Sralph }
120*15110Sralph 
121*15110Sralph /*
122*15110Sralph  * Make a block for lists of variables, commands, etc.
123*15110Sralph  */
124*15110Sralph struct block *
125*15110Sralph makeblock(type, name)
126*15110Sralph 	int type;
127*15110Sralph 	register char *name;
128*15110Sralph {
129*15110Sralph 	register char *cp;
130*15110Sralph 	register struct block *bp;
131*15110Sralph 
132*15110Sralph 	bp = ALLOC(block);
133*15110Sralph 	if (bp == NULL)
134*15110Sralph 		fatal("ran out of memory\n");
135*15110Sralph 	bp->b_type = type;
136*15110Sralph 	bp->b_next = bp->b_args = NULL;
137*15110Sralph 	if (type == NAME || type == VAR) {
138*15110Sralph 		bp->b_name = cp = (char *) malloc(strlen(name) + 1);
139*15110Sralph 		if (cp == NULL)
140*15110Sralph 			fatal("ran out of memory\n");
141*15110Sralph 		while (*cp++ = *name++)
142*15110Sralph 			;
143*15110Sralph 	} else
144*15110Sralph 		bp->b_name = NULL;
145*15110Sralph 	return(bp);
146*15110Sralph }
147