xref: /openbsd/usr.bin/m4/look.c (revision db3296cf)
1 /*	$OpenBSD: look.c,v 1.15 2003/06/30 22:13:32 espie Exp $	*/
2 
3 /*
4  * Copyright (c) 1989, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Ozan Yigit at York University.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #ifndef lint
36 static char sccsid[] = "@(#)look.c	8.1 (Berkeley) 6/6/93";
37 #endif /* not lint */
38 
39 /*
40  * look.c
41  * Facility: m4 macro processor
42  * by: oz
43  */
44 
45 #include <sys/types.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <stddef.h>
49 #include <string.h>
50 #include <ohash.h>
51 #include "mdef.h"
52 #include "stdd.h"
53 #include "extern.h"
54 
55 static void *hash_alloc(size_t, void *);
56 static void hash_free(void *, size_t, void *);
57 static void *element_alloc(size_t, void *);
58 static void setup_definition(struct macro_definition *, const char *,
59     const char *);
60 
61 static struct ohash_info macro_info = {
62 	offsetof(struct ndblock, name),
63 	NULL, hash_alloc, hash_free, element_alloc };
64 
65 struct ohash macros;
66 
67 /* Support routines for hash tables.  */
68 void *
69 hash_alloc(s, u)
70 	size_t s;
71 	void *u 	UNUSED;
72 {
73 	void *storage = xalloc(s);
74 	if (storage)
75 		memset(storage, 0, s);
76 	return storage;
77 }
78 
79 void
80 hash_free(p, s, u)
81 	void *p;
82 	size_t s	UNUSED;
83 	void *u 	UNUSED;
84 {
85 	free(p);
86 }
87 
88 void *
89 element_alloc(s, u)
90 	size_t s;
91 	void *u 	UNUSED;
92 {
93 	return xalloc(s);
94 }
95 
96 void
97 init_macros()
98 {
99 	ohash_init(&macros, 10, &macro_info);
100 }
101 
102 /*
103  * find name in the hash table
104  */
105 ndptr
106 lookup(const char *name)
107 {
108 	return ohash_find(&macros, ohash_qlookup(&macros, name));
109 }
110 
111 struct macro_definition *
112 lookup_macro_definition(const char *name)
113 {
114 	ndptr p;
115 
116 	p = ohash_find(&macros, ohash_qlookup(&macros, name));
117 	if (p)
118 		return p->d;
119 	else
120 		return NULL;
121 }
122 
123 static void
124 setup_definition(struct macro_definition *d, const char *defn, const char *name)
125 {
126 	ndptr p;
127 
128 	if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0 &&
129 	    (p = macro_getbuiltin(defn+sizeof(BUILTIN_MARKER)-1)) != NULL) {
130 		d->type = macro_builtin_type(p);
131 		d->defn = xstrdup(defn+sizeof(BUILTIN_MARKER)-1);
132 	} else {
133 		if (!*defn)
134 			d->defn = null;
135 		else
136 			d->defn = xstrdup(defn);
137 		d->type = MACRTYPE;
138 	}
139 	if (STREQ(name, defn))
140 		d->type |= RECDEF;
141 }
142 
143 static ndptr
144 create_entry(const char *name)
145 {
146 	const char *end = NULL;
147 	unsigned int i;
148 	ndptr n;
149 
150 	i = ohash_qlookupi(&macros, name, &end);
151 	n = ohash_find(&macros, i);
152 	if (n == NULL) {
153 		n = ohash_create_entry(&macro_info, name, &end);
154 		ohash_insert(&macros, i, n);
155 		n->trace_flags = FLAG_NO_TRACE;
156 		n->builtin_type = MACRTYPE;
157 		n->d = NULL;
158 	}
159 	return n;
160 }
161 
162 void
163 macro_define(const char *name, const char *defn)
164 {
165 	ndptr n = create_entry(name);
166 	if (n->d != NULL) {
167 		if (n->d->defn != null)
168 			free(n->d->defn);
169 	} else {
170 		n->d = xalloc(sizeof(struct macro_definition));
171 		n->d->next = NULL;
172 	}
173 	setup_definition(n->d, defn, name);
174 }
175 
176 void
177 macro_pushdef(const char *name, const char *defn)
178 {
179 	ndptr n;
180 	struct macro_definition *d;
181 
182 	n = create_entry(name);
183 	d = xalloc(sizeof(struct macro_definition));
184 	d->next = n->d;
185 	n->d = d;
186 	setup_definition(n->d, defn, name);
187 }
188 
189 void
190 macro_undefine(const char *name)
191 {
192 	ndptr n = lookup(name);
193 	if (n != NULL) {
194 		struct macro_definition *r, *r2;
195 
196 		for (r = n->d; r != NULL; r = r2) {
197 			r2 = r->next;
198 			if (r->defn != null)
199 				free(r->defn);
200 			free(r);
201 		}
202 		n->d = NULL;
203 	}
204 }
205 
206 void
207 macro_popdef(const char *name)
208 {
209 	ndptr n = lookup(name);
210 
211 	if (n != NULL) {
212 		struct macro_definition *r = n->d;
213 		if (r != NULL) {
214 			n->d = r->next;
215 			if (r->defn != null)
216 				free(r->defn);
217 			free(r);
218 		}
219 	}
220 }
221 
222 void
223 macro_for_all(void (*f)(const char *, struct macro_definition *))
224 {
225 	ndptr n;
226 	unsigned int i;
227 
228 	for (n = ohash_first(&macros, &i); n != NULL;
229 	    n = ohash_next(&macros, &i))
230 		f(n->name, n->d);
231 }
232 
233 void
234 setup_builtin(const char *name, unsigned int type)
235 {
236 	ndptr n;
237 
238 	n = create_entry(name);
239 	n->builtin_type = type;
240 	n->d = xalloc(sizeof(struct macro_definition));
241 	n->d->defn = xstrdup(name);
242 	n->d->type = type;
243 	n->d->next = NULL;
244 }
245 
246 void
247 mark_traced(const char *name, int on)
248 {
249 	ndptr p;
250 	unsigned int i;
251 
252 	if (name == NULL) {
253 		if (on)
254 			trace_flags |= TRACE_ALL;
255 		else
256 			trace_flags &= ~TRACE_ALL;
257 		for (p = ohash_first(&macros, &i); p != NULL;
258 		    p = ohash_next(&macros, &i))
259 		    	p->trace_flags = FLAG_NO_TRACE;
260 	} else {
261 		p = create_entry(name);
262 		p->trace_flags = on;
263 	}
264 }
265 
266 ndptr
267 macro_getbuiltin(const char *name)
268 {
269 	ndptr p;
270 
271 	p = lookup(name);
272 	if (p == NULL || p->builtin_type == MACRTYPE)
273 		return NULL;
274 	else
275 		return p;
276 }
277 
278