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