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