xref: /netbsd-src/usr.bin/m4/look.c (revision 59e8ea8f4c41224bb164038885d42752a098cc0c)
1*59e8ea8fSchristos /*	$NetBSD: look.c,v 1.13 2016/01/16 17:00:07 christos Exp $	*/
2f3efdb75Schristos /*	$OpenBSD: look.c,v 1.21 2009/10/14 17:23:17 sthen Exp $	*/
34b087712Stv 
4a7c89f0fSglass /*
5a7c89f0fSglass  * Copyright (c) 1989, 1993
6a7c89f0fSglass  *	The Regents of the University of California.  All rights reserved.
7a7c89f0fSglass  *
8a7c89f0fSglass  * This code is derived from software contributed to Berkeley by
9a7c89f0fSglass  * Ozan Yigit at York University.
10a7c89f0fSglass  *
11a7c89f0fSglass  * Redistribution and use in source and binary forms, with or without
12a7c89f0fSglass  * modification, are permitted provided that the following conditions
13a7c89f0fSglass  * are met:
14a7c89f0fSglass  * 1. Redistributions of source code must retain the above copyright
15a7c89f0fSglass  *    notice, this list of conditions and the following disclaimer.
16a7c89f0fSglass  * 2. Redistributions in binary form must reproduce the above copyright
17a7c89f0fSglass  *    notice, this list of conditions and the following disclaimer in the
18a7c89f0fSglass  *    documentation and/or other materials provided with the distribution.
1989aaa1bbSagc  * 3. Neither the name of the University nor the names of its contributors
20a7c89f0fSglass  *    may be used to endorse or promote products derived from this software
21a7c89f0fSglass  *    without specific prior written permission.
22a7c89f0fSglass  *
23a7c89f0fSglass  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24a7c89f0fSglass  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25a7c89f0fSglass  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26a7c89f0fSglass  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27a7c89f0fSglass  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28a7c89f0fSglass  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29a7c89f0fSglass  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30a7c89f0fSglass  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31a7c89f0fSglass  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32a7c89f0fSglass  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33a7c89f0fSglass  * SUCH DAMAGE.
3461f28255Scgd  */
3561f28255Scgd 
3661f28255Scgd /*
37a7c89f0fSglass  * look.c
38a7c89f0fSglass  * Facility: m4 macro processor
39a7c89f0fSglass  * by: oz
4061f28255Scgd  */
41f3efdb75Schristos #if HAVE_NBTOOL_CONFIG_H
42f3efdb75Schristos #include "nbtool_config.h"
43f3efdb75Schristos #endif
44f3efdb75Schristos #include <sys/cdefs.h>
45*59e8ea8fSchristos __RCSID("$NetBSD: look.c,v 1.13 2016/01/16 17:00:07 christos Exp $");
46a7c89f0fSglass #include <stdio.h>
47a7c89f0fSglass #include <stdlib.h>
48f3efdb75Schristos #include <stdint.h>
494b087712Stv #include <stddef.h>
50a7c89f0fSglass #include <string.h>
51f3efdb75Schristos #include <ohash.h>
52a7c89f0fSglass #include "mdef.h"
53a7c89f0fSglass #include "stdd.h"
54a7c89f0fSglass #include "extern.h"
55a7c89f0fSglass 
56f3efdb75Schristos static void *hash_alloc(size_t, void *);
57f3efdb75Schristos static void hash_free(void *, size_t, void *);
58f3efdb75Schristos static void *element_alloc(size_t, void *);
59f3efdb75Schristos static void setup_definition(struct macro_definition *, const char *,
60f3efdb75Schristos     const char *);
616f9ec05aSlukem 
62f3efdb75Schristos static struct ohash_info macro_info = {
63f3efdb75Schristos 	offsetof(struct ndblock, name),
64f3efdb75Schristos 	NULL, hash_alloc, hash_free, element_alloc };
65f3efdb75Schristos 
66f3efdb75Schristos struct ohash macros;
67f3efdb75Schristos 
68f3efdb75Schristos /* Support routines for hash tables.  */
69f3efdb75Schristos void *
hash_alloc(size_t s,void * u UNUSED)70d34c2845Smatt hash_alloc(size_t s, void *u UNUSED)
7161f28255Scgd {
72f3efdb75Schristos 	void *storage = xalloc(s, "hash alloc");
73f3efdb75Schristos 	if (storage)
74f3efdb75Schristos 		memset(storage, 0, s);
75f3efdb75Schristos 	return storage;
76f3efdb75Schristos }
77f3efdb75Schristos 
78f3efdb75Schristos void
hash_free(void * p,size_t s UNUSED,void * u UNUSED)79d34c2845Smatt hash_free(void *p, size_t s UNUSED, void *u UNUSED)
80f3efdb75Schristos {
81f3efdb75Schristos 	free(p);
82f3efdb75Schristos }
83f3efdb75Schristos 
84f3efdb75Schristos void *
element_alloc(size_t s,void * u UNUSED)85d34c2845Smatt element_alloc(size_t s, void *u UNUSED)
86f3efdb75Schristos {
87f3efdb75Schristos 	return xalloc(s, "element alloc");
88f3efdb75Schristos }
89f3efdb75Schristos 
90f3efdb75Schristos void
init_macros(void)91d34c2845Smatt init_macros(void)
92f3efdb75Schristos {
93f3efdb75Schristos 	ohash_init(&macros, 10, &macro_info);
9461f28255Scgd }
9561f28255Scgd 
9661f28255Scgd /*
97a7c89f0fSglass  * find name in the hash table
9861f28255Scgd  */
99a7c89f0fSglass ndptr
lookup(const char * name)100f3efdb75Schristos lookup(const char *name)
10161f28255Scgd {
102f3efdb75Schristos 	return ohash_find(&macros, ohash_qlookup(&macros, name));
103a7c89f0fSglass }
104a7c89f0fSglass 
105f3efdb75Schristos struct macro_definition *
lookup_macro_definition(const char * name)106f3efdb75Schristos lookup_macro_definition(const char *name)
107a7c89f0fSglass {
108a7c89f0fSglass 	ndptr p;
109a7c89f0fSglass 
110f3efdb75Schristos 	p = ohash_find(&macros, ohash_qlookup(&macros, name));
111f3efdb75Schristos 	if (p)
112f3efdb75Schristos 		return p->d;
113f3efdb75Schristos 	else
114f3efdb75Schristos 		return NULL;
11561f28255Scgd }
11661f28255Scgd 
117a7c89f0fSglass static void
setup_definition(struct macro_definition * d,const char * defn,const char * name)118f3efdb75Schristos setup_definition(struct macro_definition *d, const char *defn, const char *name)
119f3efdb75Schristos {
120a7c89f0fSglass 	ndptr p;
121f3efdb75Schristos 
122f3efdb75Schristos 	if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0 &&
123f3efdb75Schristos 	    (p = macro_getbuiltin(defn+sizeof(BUILTIN_MARKER)-1)) != NULL) {
124f3efdb75Schristos 		d->type = macro_builtin_type(p);
125f3efdb75Schristos 		d->defn = xstrdup(defn+sizeof(BUILTIN_MARKER)-1);
126f3efdb75Schristos 	} else {
127f3efdb75Schristos 		if (!*defn)
128f3efdb75Schristos 			d->defn = xstrdup(null);
129f3efdb75Schristos 		else
130f3efdb75Schristos 			d->defn = xstrdup(defn);
131f3efdb75Schristos 		d->type = MACRTYPE;
132f3efdb75Schristos 	}
133f3efdb75Schristos 	if (STREQ(name, defn))
134f3efdb75Schristos 		d->type |= RECDEF;
1350d66213fSglass }
1360d66213fSglass 
137f3efdb75Schristos static ndptr
create_entry(const char * name)138f3efdb75Schristos create_entry(const char *name)
139f3efdb75Schristos {
140f3efdb75Schristos 	const char *end = NULL;
141f3efdb75Schristos 	unsigned int i;
142f3efdb75Schristos 	ndptr n;
143f3efdb75Schristos 
144f3efdb75Schristos 	i = ohash_qlookupi(&macros, name, &end);
145f3efdb75Schristos 	n = ohash_find(&macros, i);
146f3efdb75Schristos 	if (n == NULL) {
147f3efdb75Schristos 		n = ohash_create_entry(&macro_info, name, &end);
148f3efdb75Schristos 		ohash_insert(&macros, i, n);
149f3efdb75Schristos 		n->trace_flags = FLAG_NO_TRACE;
150f3efdb75Schristos 		n->builtin_type = MACRTYPE;
151f3efdb75Schristos 		n->d = NULL;
152f3efdb75Schristos 	}
153f3efdb75Schristos 	return n;
154f3efdb75Schristos }
155f3efdb75Schristos 
156a7c89f0fSglass void
macro_define(const char * name,const char * defn)157f3efdb75Schristos macro_define(const char *name, const char *defn)
15861f28255Scgd {
159f3efdb75Schristos 	ndptr n = create_entry(name);
160f3efdb75Schristos 	if (n->d != NULL) {
161f3efdb75Schristos 		if (n->d->defn != null)
162f3efdb75Schristos 			free(n->d->defn);
163f3efdb75Schristos 	} else {
164f3efdb75Schristos 		n->d = xalloc(sizeof(struct macro_definition), NULL);
165f3efdb75Schristos 		n->d->next = NULL;
166f3efdb75Schristos 	}
167f3efdb75Schristos 	setup_definition(n->d, defn, name);
168f3efdb75Schristos }
16961f28255Scgd 
170f3efdb75Schristos void
macro_pushdef(const char * name,const char * defn)171f3efdb75Schristos macro_pushdef(const char *name, const char *defn)
172f3efdb75Schristos {
173f3efdb75Schristos 	ndptr n;
174f3efdb75Schristos 	struct macro_definition *d;
175f3efdb75Schristos 
176f3efdb75Schristos 	n = create_entry(name);
177f3efdb75Schristos 	d = xalloc(sizeof(struct macro_definition), NULL);
178f3efdb75Schristos 	d->next = n->d;
179f3efdb75Schristos 	n->d = d;
180f3efdb75Schristos 	setup_definition(n->d, defn, name);
181a7c89f0fSglass }
182f3efdb75Schristos 
183f3efdb75Schristos void
macro_undefine(const char * name)184f3efdb75Schristos macro_undefine(const char *name)
185f3efdb75Schristos {
186f3efdb75Schristos 	ndptr n = lookup(name);
187f3efdb75Schristos 	if (n != NULL) {
188f3efdb75Schristos 		struct macro_definition *r, *r2;
189f3efdb75Schristos 
190f3efdb75Schristos 		for (r = n->d; r != NULL; r = r2) {
191f3efdb75Schristos 			r2 = r->next;
192f3efdb75Schristos 			if (r->defn != null)
193f3efdb75Schristos 				free(r->defn);
194f3efdb75Schristos 			free(r);
195a7c89f0fSglass 		}
196f3efdb75Schristos 		n->d = NULL;
197a7c89f0fSglass 	}
198f3efdb75Schristos }
199f3efdb75Schristos 
200f3efdb75Schristos void
macro_popdef(const char * name)201f3efdb75Schristos macro_popdef(const char *name)
202f3efdb75Schristos {
203f3efdb75Schristos 	ndptr n = lookup(name);
204f3efdb75Schristos 
205f3efdb75Schristos 	if (n != NULL) {
206f3efdb75Schristos 		struct macro_definition *r = n->d;
207f3efdb75Schristos 		if (r != NULL) {
208f3efdb75Schristos 			n->d = r->next;
209f3efdb75Schristos 			if (r->defn != null)
210f3efdb75Schristos 				free(r->defn);
211f3efdb75Schristos 			free(r);
21261f28255Scgd 		}
21361f28255Scgd 	}
21461f28255Scgd }
215f3efdb75Schristos 
216f3efdb75Schristos void
macro_for_all(void (* f)(const char *,struct macro_definition *))217f3efdb75Schristos macro_for_all(void (*f)(const char *, struct macro_definition *))
218f3efdb75Schristos {
219f3efdb75Schristos 	ndptr n;
220f3efdb75Schristos 	unsigned int i;
221f3efdb75Schristos 
222f3efdb75Schristos 	for (n = ohash_first(&macros, &i); n != NULL;
223f3efdb75Schristos 	    n = ohash_next(&macros, &i))
224f3efdb75Schristos 		if (n->d != NULL)
225f3efdb75Schristos 			f(n->name, n->d);
226f3efdb75Schristos }
227f3efdb75Schristos 
228f3efdb75Schristos void
setup_builtin(const char * name,unsigned int type)229f3efdb75Schristos setup_builtin(const char *name, unsigned int type)
230f3efdb75Schristos {
231f3efdb75Schristos 	ndptr n;
232f3efdb75Schristos 	char *name2;
233f3efdb75Schristos 
234f3efdb75Schristos 	if (prefix_builtins) {
235f3efdb75Schristos 		name2 = xalloc(strlen(name)+3+1, NULL);
236f3efdb75Schristos 		memcpy(name2, "m4_", 3);
237f3efdb75Schristos 		memcpy(name2 + 3, name, strlen(name)+1);
238f3efdb75Schristos 	} else
239f3efdb75Schristos 		name2 = xstrdup(name);
240f3efdb75Schristos 
241f3efdb75Schristos 	n = create_entry(name2);
242f3efdb75Schristos 	n->builtin_type = type;
243f3efdb75Schristos 	n->d = xalloc(sizeof(struct macro_definition), NULL);
244f3efdb75Schristos 	n->d->defn = name2;
245f3efdb75Schristos 	n->d->type = type;
246f3efdb75Schristos 	n->d->next = NULL;
247f3efdb75Schristos }
248f3efdb75Schristos 
249f3efdb75Schristos void
mark_traced(const char * name,int on)250f3efdb75Schristos mark_traced(const char *name, int on)
251f3efdb75Schristos {
252f3efdb75Schristos 	ndptr p;
253f3efdb75Schristos 	unsigned int i;
254f3efdb75Schristos 
255f3efdb75Schristos 	if (name == NULL) {
256f3efdb75Schristos 		if (on)
257f3efdb75Schristos 			trace_flags |= TRACE_ALL;
258f3efdb75Schristos 		else
259f3efdb75Schristos 			trace_flags &= ~TRACE_ALL;
260f3efdb75Schristos 		for (p = ohash_first(&macros, &i); p != NULL;
261f3efdb75Schristos 		    p = ohash_next(&macros, &i))
262f3efdb75Schristos 		    	p->trace_flags = FLAG_NO_TRACE;
263f3efdb75Schristos 	} else {
264f3efdb75Schristos 		p = create_entry(name);
265f3efdb75Schristos 		p->trace_flags = on;
266f3efdb75Schristos 	}
267f3efdb75Schristos }
268f3efdb75Schristos 
269f3efdb75Schristos ndptr
macro_getbuiltin(const char * name)270f3efdb75Schristos macro_getbuiltin(const char *name)
271f3efdb75Schristos {
272f3efdb75Schristos 	ndptr p;
273f3efdb75Schristos 
274f3efdb75Schristos 	p = lookup(name);
275f3efdb75Schristos 	if (p == NULL || p->builtin_type == MACRTYPE)
276f3efdb75Schristos 		return NULL;
277f3efdb75Schristos 	else
278f3efdb75Schristos 		return p;
279f3efdb75Schristos }
280f3efdb75Schristos 
281*59e8ea8fSchristos #ifdef REAL_FREEZE
282*59e8ea8fSchristos static void
recurse(FILE * f,ndptr n,struct macro_definition * d)283*59e8ea8fSchristos recurse(FILE *f, ndptr n, struct macro_definition *d)
284*59e8ea8fSchristos {
285*59e8ea8fSchristos 	if (d->next != NULL)
286*59e8ea8fSchristos 		recurse(f, n, d->next);
287*59e8ea8fSchristos 
288*59e8ea8fSchristos 	// skip built-ins, because it is cheaper to do so
289*59e8ea8fSchristos 	// and initialize them manually
290*59e8ea8fSchristos 	if (d->type & (NOARGS|NEEDARGS))
291*59e8ea8fSchristos 		return;
292*59e8ea8fSchristos 	fprintf(f, "%c%zu,%zu\n%s%s\n",
293*59e8ea8fSchristos 	    (d->type & (NOARGS|NEEDARGS)) ? 'F' : 'T',
294*59e8ea8fSchristos 	    strlen(n->name), strlen(d->defn),
295*59e8ea8fSchristos 	    n->name, d->defn);
296*59e8ea8fSchristos }
297*59e8ea8fSchristos 
298*59e8ea8fSchristos static void
dump_entry(FILE * f,ndptr n)299*59e8ea8fSchristos dump_entry(FILE *f, ndptr n)
300*59e8ea8fSchristos {
301*59e8ea8fSchristos 	if (n->d == NULL)
302*59e8ea8fSchristos 		return;
303*59e8ea8fSchristos 	recurse(f, n, n->d);
304*59e8ea8fSchristos }
305*59e8ea8fSchristos 
306*59e8ea8fSchristos void
dump_state(FILE * f)307*59e8ea8fSchristos dump_state(FILE *f)
308*59e8ea8fSchristos {
309*59e8ea8fSchristos 	ndptr n;
310*59e8ea8fSchristos 	unsigned int i;
311*59e8ea8fSchristos 	for (n = ohash_first(&macros, &i); n != NULL;
312*59e8ea8fSchristos 	    n = ohash_next(&macros, &i))
313*59e8ea8fSchristos 		dump_entry(f, n);
314*59e8ea8fSchristos }
315*59e8ea8fSchristos #endif
316