1 /* $NetBSD: look.c,v 1.11 2009/10/26 21:11:28 christos Exp $ */ 2 /* $OpenBSD: look.c,v 1.21 2009/10/14 17:23:17 sthen Exp $ */ 3 4 /* 5 * Copyright (c) 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Ozan Yigit at York University. 10 * 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. 22 * 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. 34 */ 35 36 /* 37 * look.c 38 * Facility: m4 macro processor 39 * by: oz 40 */ 41 #if HAVE_NBTOOL_CONFIG_H 42 #include "nbtool_config.h" 43 #endif 44 #include <sys/cdefs.h> 45 __RCSID("$NetBSD: look.c,v 1.11 2009/10/26 21:11:28 christos Exp $"); 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" 55 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 *); 61 62 static struct ohash_info macro_info = { 63 offsetof(struct ndblock, name), 64 NULL, hash_alloc, hash_free, element_alloc }; 65 66 struct ohash macros; 67 68 /* Support routines for hash tables. */ 69 void * 70 hash_alloc(s, u) 71 size_t s; 72 void *u UNUSED; 73 { 74 void *storage = xalloc(s, "hash alloc"); 75 if (storage) 76 memset(storage, 0, s); 77 return storage; 78 } 79 80 void 81 hash_free(p, s, u) 82 void *p; 83 size_t s UNUSED; 84 void *u UNUSED; 85 { 86 free(p); 87 } 88 89 void * 90 element_alloc(s, u) 91 size_t s; 92 void *u UNUSED; 93 { 94 return xalloc(s, "element alloc"); 95 } 96 97 void 98 init_macros() 99 { 100 ohash_init(¯os, 10, ¯o_info); 101 } 102 103 /* 104 * find name in the hash table 105 */ 106 ndptr 107 lookup(const char *name) 108 { 109 return ohash_find(¯os, ohash_qlookup(¯os, name)); 110 } 111 112 struct macro_definition * 113 lookup_macro_definition(const char *name) 114 { 115 ndptr p; 116 117 p = ohash_find(¯os, ohash_qlookup(¯os, name)); 118 if (p) 119 return p->d; 120 else 121 return NULL; 122 } 123 124 static void 125 setup_definition(struct macro_definition *d, const char *defn, const char *name) 126 { 127 ndptr p; 128 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; 139 } 140 if (STREQ(name, defn)) 141 d->type |= RECDEF; 142 } 143 144 static ndptr 145 create_entry(const char *name) 146 { 147 const char *end = NULL; 148 unsigned int i; 149 ndptr n; 150 151 i = ohash_qlookupi(¯os, name, &end); 152 n = ohash_find(¯os, i); 153 if (n == NULL) { 154 n = ohash_create_entry(¯o_info, name, &end); 155 ohash_insert(¯os, i, n); 156 n->trace_flags = FLAG_NO_TRACE; 157 n->builtin_type = MACRTYPE; 158 n->d = NULL; 159 } 160 return n; 161 } 162 163 void 164 macro_define(const char *name, const char *defn) 165 { 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; 173 } 174 setup_definition(n->d, defn, name); 175 } 176 177 void 178 macro_pushdef(const char *name, const char *defn) 179 { 180 ndptr n; 181 struct macro_definition *d; 182 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); 188 } 189 190 void 191 macro_undefine(const char *name) 192 { 193 ndptr n = lookup(name); 194 if (n != NULL) { 195 struct macro_definition *r, *r2; 196 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); 202 } 203 n->d = NULL; 204 } 205 } 206 207 void 208 macro_popdef(const char *name) 209 { 210 ndptr n = lookup(name); 211 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); 219 } 220 } 221 } 222 223 void 224 macro_for_all(void (*f)(const char *, struct macro_definition *)) 225 { 226 ndptr n; 227 unsigned int i; 228 229 for (n = ohash_first(¯os, &i); n != NULL; 230 n = ohash_next(¯os, &i)) 231 if (n->d != NULL) 232 f(n->name, n->d); 233 } 234 235 void 236 setup_builtin(const char *name, unsigned int type) 237 { 238 ndptr n; 239 char *name2; 240 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); 247 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; 254 } 255 256 void 257 mark_traced(const char *name, int on) 258 { 259 ndptr p; 260 unsigned int i; 261 262 if (name == NULL) { 263 if (on) 264 trace_flags |= TRACE_ALL; 265 else 266 trace_flags &= ~TRACE_ALL; 267 for (p = ohash_first(¯os, &i); p != NULL; 268 p = ohash_next(¯os, &i)) 269 p->trace_flags = FLAG_NO_TRACE; 270 } else { 271 p = create_entry(name); 272 p->trace_flags = on; 273 } 274 } 275 276 ndptr 277 macro_getbuiltin(const char *name) 278 { 279 ndptr p; 280 281 p = lookup(name); 282 if (p == NULL || p->builtin_type == MACRTYPE) 283 return NULL; 284 else 285 return p; 286 } 287 288