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