Annotation of src/usr.bin/m4/look.c, Revision 1.23
1.23 ! espie 1: /* $OpenBSD: look.c,v 1.22 2010/09/07 19:58:09 marco Exp $ */
1.2 deraadt 2:
1.1 deraadt 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.
1.11 millert 18: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 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: /*
36: * look.c
37: * Facility: m4 macro processor
38: * by: oz
39: */
40:
41: #include <stdio.h>
42: #include <stdlib.h>
1.18 espie 43: #include <stdint.h>
1.3 espie 44: #include <stddef.h>
1.1 deraadt 45: #include <string.h>
1.13 espie 46: #include <ohash.h>
1.1 deraadt 47: #include "mdef.h"
48: #include "stdd.h"
49: #include "extern.h"
50:
1.23 ! espie 51: static void *hash_calloc(size_t, size_t, void *);
! 52: static void hash_free(void *, void *);
1.15 espie 53: static void *element_alloc(size_t, void *);
1.22 marco 54: static void setup_definition(struct macro_definition *, const char *,
1.13 espie 55: const char *);
56:
57: static struct ohash_info macro_info = {
58: offsetof(struct ndblock, name),
1.23 ! espie 59: NULL, hash_calloc, hash_free, element_alloc };
1.13 espie 60:
1.15 espie 61: struct ohash macros;
62:
63: /* Support routines for hash tables. */
64: void *
1.23 ! espie 65: hash_calloc(size_t n, size_t s, void *u UNUSED)
1.15 espie 66: {
1.23 ! espie 67: void *storage = xcalloc(n, s, "hash alloc");
1.15 espie 68: return storage;
69: }
70:
71: void
1.23 ! espie 72: hash_free(void *p, void *u UNUSED)
1.15 espie 73: {
74: free(p);
75: }
76:
77: void *
1.23 ! espie 78: element_alloc(size_t s, void *u UNUSED)
1.15 espie 79: {
1.16 espie 80: return xalloc(s, "element alloc");
1.15 espie 81: }
1.13 espie 82:
83: void
84: init_macros()
85: {
1.15 espie 86: ohash_init(¯os, 10, ¯o_info);
1.1 deraadt 87: }
88:
89: /*
90: * find name in the hash table
91: */
1.22 marco 92: ndptr
1.10 espie 93: lookup(const char *name)
1.1 deraadt 94: {
1.13 espie 95: return ohash_find(¯os, ohash_qlookup(¯os, name));
1.12 espie 96: }
97:
98: struct macro_definition *
99: lookup_macro_definition(const char *name)
100: {
101: ndptr p;
102:
1.15 espie 103: p = ohash_find(¯os, ohash_qlookup(¯os, name));
1.12 espie 104: if (p)
1.13 espie 105: return p->d;
1.12 espie 106: else
107: return NULL;
108: }
109:
1.22 marco 110: static void
1.13 espie 111: setup_definition(struct macro_definition *d, const char *defn, const char *name)
1.12 espie 112: {
1.14 espie 113: ndptr p;
1.12 espie 114:
1.13 espie 115: if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0 &&
1.14 espie 116: (p = macro_getbuiltin(defn+sizeof(BUILTIN_MARKER)-1)) != NULL) {
117: d->type = macro_builtin_type(p);
1.13 espie 118: d->defn = xstrdup(defn+sizeof(BUILTIN_MARKER)-1);
119: } else {
120: if (!*defn)
121: d->defn = null;
122: else
123: d->defn = xstrdup(defn);
124: d->type = MACRTYPE;
125: }
126: if (STREQ(name, defn))
127: d->type |= RECDEF;
128: }
129:
130: static ndptr
131: create_entry(const char *name)
132: {
133: const char *end = NULL;
134: unsigned int i;
135: ndptr n;
136:
137: i = ohash_qlookupi(¯os, name, &end);
138: n = ohash_find(¯os, i);
139: if (n == NULL) {
140: n = ohash_create_entry(¯o_info, name, &end);
141: ohash_insert(¯os, i, n);
1.15 espie 142: n->trace_flags = FLAG_NO_TRACE;
1.14 espie 143: n->builtin_type = MACRTYPE;
1.13 espie 144: n->d = NULL;
1.12 espie 145: }
1.13 espie 146: return n;
1.12 espie 147: }
148:
149: void
150: macro_define(const char *name, const char *defn)
151: {
1.13 espie 152: ndptr n = create_entry(name);
153: if (n->d != NULL) {
154: if (n->d->defn != null)
155: free(n->d->defn);
156: } else {
1.16 espie 157: n->d = xalloc(sizeof(struct macro_definition), NULL);
1.13 espie 158: n->d->next = NULL;
159: }
160: setup_definition(n->d, defn, name);
1.12 espie 161: }
162:
163: void
164: macro_pushdef(const char *name, const char *defn)
165: {
1.13 espie 166: ndptr n;
167: struct macro_definition *d;
1.22 marco 168:
1.13 espie 169: n = create_entry(name);
1.16 espie 170: d = xalloc(sizeof(struct macro_definition), NULL);
1.13 espie 171: d->next = n->d;
172: n->d = d;
173: setup_definition(n->d, defn, name);
1.12 espie 174: }
175:
176: void
177: macro_undefine(const char *name)
178: {
1.13 espie 179: ndptr n = lookup(name);
180: if (n != NULL) {
181: struct macro_definition *r, *r2;
182:
183: for (r = n->d; r != NULL; r = r2) {
184: r2 = r->next;
185: if (r->defn != null)
186: free(r->defn);
187: free(r);
188: }
189: n->d = NULL;
190: }
1.12 espie 191: }
192:
193: void
194: macro_popdef(const char *name)
195: {
1.13 espie 196: ndptr n = lookup(name);
197:
198: if (n != NULL) {
199: struct macro_definition *r = n->d;
200: if (r != NULL) {
201: n->d = r->next;
202: if (r->defn != null)
203: free(r->defn);
204: free(r);
205: }
206: }
1.12 espie 207: }
208:
209: void
210: macro_for_all(void (*f)(const char *, struct macro_definition *))
211: {
1.13 espie 212: ndptr n;
213: unsigned int i;
1.12 espie 214:
1.22 marco 215: for (n = ohash_first(¯os, &i); n != NULL;
1.13 espie 216: n = ohash_next(¯os, &i))
1.19 guenther 217: if (n->d != NULL)
218: f(n->name, n->d);
1.12 espie 219: }
220:
1.22 marco 221: void
1.12 espie 222: setup_builtin(const char *name, unsigned int type)
223: {
1.13 espie 224: ndptr n;
1.20 sthen 225: char *name2;
1.12 espie 226:
1.21 sthen 227: if (prefix_builtins) {
1.20 sthen 228: name2 = xalloc(strlen(name)+3+1, NULL);
229: memcpy(name2, "m4_", 3);
230: memcpy(name2 + 3, name, strlen(name)+1);
231: } else
232: name2 = xstrdup(name);
233:
234: n = create_entry(name2);
1.14 espie 235: n->builtin_type = type;
1.16 espie 236: n->d = xalloc(sizeof(struct macro_definition), NULL);
1.20 sthen 237: n->d->defn = name2;
1.13 espie 238: n->d->type = type;
239: n->d->next = NULL;
1.12 espie 240: }
241:
1.15 espie 242: void
243: mark_traced(const char *name, int on)
1.12 espie 244: {
1.15 espie 245: ndptr p;
246: unsigned int i;
1.12 espie 247:
1.15 espie 248: if (name == NULL) {
249: if (on)
250: trace_flags |= TRACE_ALL;
251: else
252: trace_flags &= ~TRACE_ALL;
1.22 marco 253: for (p = ohash_first(¯os, &i); p != NULL;
1.15 espie 254: p = ohash_next(¯os, &i))
1.22 marco 255: p->trace_flags = FLAG_NO_TRACE;
1.15 espie 256: } else {
257: p = create_entry(name);
258: p->trace_flags = on;
259: }
1.1 deraadt 260: }
1.14 espie 261:
1.22 marco 262: ndptr
1.14 espie 263: macro_getbuiltin(const char *name)
264: {
265: ndptr p;
266:
267: p = lookup(name);
268: if (p == NULL || p->builtin_type == MACRTYPE)
269: return NULL;
270: else
271: return p;
272: }