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