Sync usage with man page.
[netbsd-mini2440.git] / usr.bin / m4 / look.c
blobe04dbb492d74808db9d26f8b6ad2313e27a92829
1 /* $NetBSD$ */
2 /* $OpenBSD: look.c,v 1.21 2009/10/14 17:23:17 sthen Exp $ */
4 /*
5 * Copyright (c) 1989, 1993
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * Ozan Yigit at York University.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
37 * look.c
38 * Facility: m4 macro processor
39 * by: oz
41 #if HAVE_NBTOOL_CONFIG_H
42 #include "nbtool_config.h"
43 #endif
44 #include <sys/cdefs.h>
45 __RCSID("$NetBSD$");
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <stdint.h>
49 #include <stddef.h>
50 #include <string.h>
51 #include <ohash.h>
52 #include "mdef.h"
53 #include "stdd.h"
54 #include "extern.h"
56 static void *hash_alloc(size_t, void *);
57 static void hash_free(void *, size_t, void *);
58 static void *element_alloc(size_t, void *);
59 static void setup_definition(struct macro_definition *, const char *,
60 const char *);
62 static struct ohash_info macro_info = {
63 offsetof(struct ndblock, name),
64 NULL, hash_alloc, hash_free, element_alloc };
66 struct ohash macros;
68 /* Support routines for hash tables. */
69 void *
70 hash_alloc(s, u)
71 size_t s;
72 void *u UNUSED;
74 void *storage = xalloc(s, "hash alloc");
75 if (storage)
76 memset(storage, 0, s);
77 return storage;
80 void
81 hash_free(p, s, u)
82 void *p;
83 size_t s UNUSED;
84 void *u UNUSED;
86 free(p);
89 void *
90 element_alloc(s, u)
91 size_t s;
92 void *u UNUSED;
94 return xalloc(s, "element alloc");
97 void
98 init_macros()
100 ohash_init(&macros, 10, &macro_info);
104 * find name in the hash table
106 ndptr
107 lookup(const char *name)
109 return ohash_find(&macros, ohash_qlookup(&macros, name));
112 struct macro_definition *
113 lookup_macro_definition(const char *name)
115 ndptr p;
117 p = ohash_find(&macros, ohash_qlookup(&macros, name));
118 if (p)
119 return p->d;
120 else
121 return NULL;
124 static void
125 setup_definition(struct macro_definition *d, const char *defn, const char *name)
127 ndptr p;
129 if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0 &&
130 (p = macro_getbuiltin(defn+sizeof(BUILTIN_MARKER)-1)) != NULL) {
131 d->type = macro_builtin_type(p);
132 d->defn = xstrdup(defn+sizeof(BUILTIN_MARKER)-1);
133 } else {
134 if (!*defn)
135 d->defn = xstrdup(null);
136 else
137 d->defn = xstrdup(defn);
138 d->type = MACRTYPE;
140 if (STREQ(name, defn))
141 d->type |= RECDEF;
144 static ndptr
145 create_entry(const char *name)
147 const char *end = NULL;
148 unsigned int i;
149 ndptr n;
151 i = ohash_qlookupi(&macros, name, &end);
152 n = ohash_find(&macros, i);
153 if (n == NULL) {
154 n = ohash_create_entry(&macro_info, name, &end);
155 ohash_insert(&macros, i, n);
156 n->trace_flags = FLAG_NO_TRACE;
157 n->builtin_type = MACRTYPE;
158 n->d = NULL;
160 return n;
163 void
164 macro_define(const char *name, const char *defn)
166 ndptr n = create_entry(name);
167 if (n->d != NULL) {
168 if (n->d->defn != null)
169 free(n->d->defn);
170 } else {
171 n->d = xalloc(sizeof(struct macro_definition), NULL);
172 n->d->next = NULL;
174 setup_definition(n->d, defn, name);
177 void
178 macro_pushdef(const char *name, const char *defn)
180 ndptr n;
181 struct macro_definition *d;
183 n = create_entry(name);
184 d = xalloc(sizeof(struct macro_definition), NULL);
185 d->next = n->d;
186 n->d = d;
187 setup_definition(n->d, defn, name);
190 void
191 macro_undefine(const char *name)
193 ndptr n = lookup(name);
194 if (n != NULL) {
195 struct macro_definition *r, *r2;
197 for (r = n->d; r != NULL; r = r2) {
198 r2 = r->next;
199 if (r->defn != null)
200 free(r->defn);
201 free(r);
203 n->d = NULL;
207 void
208 macro_popdef(const char *name)
210 ndptr n = lookup(name);
212 if (n != NULL) {
213 struct macro_definition *r = n->d;
214 if (r != NULL) {
215 n->d = r->next;
216 if (r->defn != null)
217 free(r->defn);
218 free(r);
223 void
224 macro_for_all(void (*f)(const char *, struct macro_definition *))
226 ndptr n;
227 unsigned int i;
229 for (n = ohash_first(&macros, &i); n != NULL;
230 n = ohash_next(&macros, &i))
231 if (n->d != NULL)
232 f(n->name, n->d);
235 void
236 setup_builtin(const char *name, unsigned int type)
238 ndptr n;
239 char *name2;
241 if (prefix_builtins) {
242 name2 = xalloc(strlen(name)+3+1, NULL);
243 memcpy(name2, "m4_", 3);
244 memcpy(name2 + 3, name, strlen(name)+1);
245 } else
246 name2 = xstrdup(name);
248 n = create_entry(name2);
249 n->builtin_type = type;
250 n->d = xalloc(sizeof(struct macro_definition), NULL);
251 n->d->defn = name2;
252 n->d->type = type;
253 n->d->next = NULL;
256 void
257 mark_traced(const char *name, int on)
259 ndptr p;
260 unsigned int i;
262 if (name == NULL) {
263 if (on)
264 trace_flags |= TRACE_ALL;
265 else
266 trace_flags &= ~TRACE_ALL;
267 for (p = ohash_first(&macros, &i); p != NULL;
268 p = ohash_next(&macros, &i))
269 p->trace_flags = FLAG_NO_TRACE;
270 } else {
271 p = create_entry(name);
272 p->trace_flags = on;
276 ndptr
277 macro_getbuiltin(const char *name)
279 ndptr p;
281 p = lookup(name);
282 if (p == NULL || p->builtin_type == MACRTYPE)
283 return NULL;
284 else
285 return p;