1228063Sbapt/* $OpenBSD: look.c,v 1.22 2010/09/07 19:58:09 marco Exp $ */ 295060Sjmallett 31590Srgrimes/* 41590Srgrimes * Copyright (c) 1989, 1993 51590Srgrimes * The Regents of the University of California. All rights reserved. 61590Srgrimes * 71590Srgrimes * This code is derived from software contributed to Berkeley by 81590Srgrimes * Ozan Yigit at York University. 91590Srgrimes * 101590Srgrimes * Redistribution and use in source and binary forms, with or without 111590Srgrimes * modification, are permitted provided that the following conditions 121590Srgrimes * are met: 131590Srgrimes * 1. Redistributions of source code must retain the above copyright 141590Srgrimes * notice, this list of conditions and the following disclaimer. 151590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161590Srgrimes * notice, this list of conditions and the following disclaimer in the 171590Srgrimes * documentation and/or other materials provided with the distribution. 18228063Sbapt * 3. Neither the name of the University nor the names of its contributors 191590Srgrimes * may be used to endorse or promote products derived from this software 201590Srgrimes * without specific prior written permission. 211590Srgrimes * 221590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321590Srgrimes * SUCH DAMAGE. 331590Srgrimes */ 3495060Sjmallett#include <sys/cdefs.h> 3595060Sjmallett__FBSDID("$FreeBSD: releng/10.3/usr.bin/m4/look.c 228063 2011-11-28 13:32:39Z bapt $"); 361590Srgrimes 371590Srgrimes/* 381590Srgrimes * look.c 391590Srgrimes * Facility: m4 macro processor 401590Srgrimes * by: oz 411590Srgrimes */ 421590Srgrimes 431590Srgrimes#include <sys/types.h> 441590Srgrimes#include <stdio.h> 451590Srgrimes#include <stdlib.h> 46228063Sbapt#include <stdint.h> 4795060Sjmallett#include <stddef.h> 481590Srgrimes#include <string.h> 49228063Sbapt#include <ohash.h> 501590Srgrimes#include "mdef.h" 511590Srgrimes#include "stdd.h" 521590Srgrimes#include "extern.h" 531590Srgrimes 54228063Sbaptstatic void *hash_alloc(size_t, void *); 55228063Sbaptstatic void hash_free(void *, size_t, void *); 56228063Sbaptstatic void *element_alloc(size_t, void *); 57228063Sbaptstatic void setup_definition(struct macro_definition *, const char *, 58228063Sbapt const char *); 5995060Sjmallett 60228063Sbaptstatic struct ohash_info macro_info = { 61228063Sbapt offsetof(struct ndblock, name), 62228063Sbapt NULL, hash_alloc, hash_free, element_alloc }; 63228063Sbapt 64228063Sbaptstruct ohash macros; 65228063Sbapt 66228063Sbapt/* Support routines for hash tables. */ 67228063Sbaptvoid * 68228063Sbapthash_alloc(size_t s, __unused void *u) 691590Srgrimes{ 70228063Sbapt void *storage = xalloc(s, "hash alloc"); 71228063Sbapt if (storage) 72228063Sbapt memset(storage, 0, s); 73228063Sbapt return storage; 741590Srgrimes} 751590Srgrimes 76228063Sbaptvoid 77228063Sbapthash_free(void *p, __unused size_t s, __unused void *u) 78228063Sbapt{ 79228063Sbapt free(p); 80228063Sbapt} 81228063Sbapt 82228063Sbaptvoid * 83228063Sbaptelement_alloc(size_t s, __unused void *u) 84228063Sbapt{ 85228063Sbapt return xalloc(s, "element alloc"); 86228063Sbapt} 87228063Sbapt 88228063Sbaptvoid 89228063Sbaptinit_macros(void) 90228063Sbapt{ 91228063Sbapt ohash_init(¯os, 10, ¯o_info); 92228063Sbapt} 93228063Sbapt 941590Srgrimes/* 951590Srgrimes * find name in the hash table 961590Srgrimes */ 97100014Sjmallettndptr 9895887Sjmallettlookup(const char *name) 991590Srgrimes{ 100228063Sbapt return ohash_find(¯os, ohash_qlookup(¯os, name)); 101228063Sbapt} 102228063Sbapt 103228063Sbaptstruct macro_definition * 104228063Sbaptlookup_macro_definition(const char *name) 105228063Sbapt{ 10695060Sjmallett ndptr p; 1071590Srgrimes 108228063Sbapt p = ohash_find(¯os, ohash_qlookup(¯os, name)); 109228063Sbapt if (p) 110228063Sbapt return p->d; 111228063Sbapt else 112228063Sbapt return NULL; 1131590Srgrimes} 1141590Srgrimes 115228063Sbaptstatic void 116228063Sbaptsetup_definition(struct macro_definition *d, const char *defn, const char *name) 1171590Srgrimes{ 1181590Srgrimes ndptr p; 1191590Srgrimes 120228063Sbapt if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0 && 121228063Sbapt (p = macro_getbuiltin(defn+sizeof(BUILTIN_MARKER)-1)) != NULL) { 122228063Sbapt d->type = macro_builtin_type(p); 123228063Sbapt d->defn = xstrdup(defn+sizeof(BUILTIN_MARKER)-1); 124228063Sbapt } else { 125228063Sbapt if (!*defn) 126228063Sbapt d->defn = __DECONST(char *, null); 127228063Sbapt else 128228063Sbapt d->defn = xstrdup(defn); 129228063Sbapt d->type = MACRTYPE; 130228063Sbapt } 131228063Sbapt if (STREQ(name, defn)) 132228063Sbapt d->type |= RECDEF; 1331590Srgrimes} 1341590Srgrimes 135228063Sbaptstatic ndptr 136228063Sbaptcreate_entry(const char *name) 1371590Srgrimes{ 138228063Sbapt const char *end = NULL; 139228063Sbapt unsigned int i; 140228063Sbapt ndptr n; 141228063Sbapt 142228063Sbapt i = ohash_qlookupi(¯os, name, &end); 143228063Sbapt n = ohash_find(¯os, i); 144228063Sbapt if (n == NULL) { 145228063Sbapt n = ohash_create_entry(¯o_info, name, &end); 146228063Sbapt ohash_insert(¯os, i, n); 147228063Sbapt n->trace_flags = FLAG_NO_TRACE; 148228063Sbapt n->builtin_type = MACRTYPE; 149228063Sbapt n->d = NULL; 150228063Sbapt } 151228063Sbapt return n; 1521590Srgrimes} 1531590Srgrimes 1541590Srgrimesvoid 155228063Sbaptmacro_define(const char *name, const char *defn) 1561590Srgrimes{ 157228063Sbapt ndptr n = create_entry(name); 158228063Sbapt if (n->d != NULL) { 159228063Sbapt if (n->d->defn != null) 160228063Sbapt free(n->d->defn); 161228063Sbapt } else { 162228063Sbapt n->d = xalloc(sizeof(struct macro_definition), NULL); 163228063Sbapt n->d->next = NULL; 164228063Sbapt } 165228063Sbapt setup_definition(n->d, defn, name); 166228063Sbapt} 1671590Srgrimes 168228063Sbaptvoid 169228063Sbaptmacro_pushdef(const char *name, const char *defn) 170228063Sbapt{ 171228063Sbapt ndptr n; 172228063Sbapt struct macro_definition *d; 173228063Sbapt 174228063Sbapt n = create_entry(name); 175228063Sbapt d = xalloc(sizeof(struct macro_definition), NULL); 176228063Sbapt d->next = n->d; 177228063Sbapt n->d = d; 178228063Sbapt setup_definition(n->d, defn, name); 179228063Sbapt} 180228063Sbapt 181228063Sbaptvoid 182228063Sbaptmacro_undefine(const char *name) 183228063Sbapt{ 184228063Sbapt ndptr n = lookup(name); 185228063Sbapt if (n != NULL) { 186228063Sbapt struct macro_definition *r, *r2; 187228063Sbapt 188228063Sbapt for (r = n->d; r != NULL; r = r2) { 189228063Sbapt r2 = r->next; 190228063Sbapt if (r->defn != null) 191228063Sbapt free(r->defn); 192228063Sbapt free(r); 1931590Srgrimes } 194228063Sbapt n->d = NULL; 195228063Sbapt } 196228063Sbapt} 197228063Sbapt 198228063Sbaptvoid 199228063Sbaptmacro_popdef(const char *name) 200228063Sbapt{ 201228063Sbapt ndptr n = lookup(name); 202228063Sbapt 203228063Sbapt if (n != NULL) { 204228063Sbapt struct macro_definition *r = n->d; 205228063Sbapt if (r != NULL) { 206228063Sbapt n->d = r->next; 207228063Sbapt if (r->defn != null) 208228063Sbapt free(r->defn); 209228063Sbapt free(r); 2101590Srgrimes } 2111590Srgrimes } 2121590Srgrimes} 213228063Sbapt 214228063Sbaptvoid 215228063Sbaptmacro_for_all(void (*f)(const char *, struct macro_definition *)) 216228063Sbapt{ 217228063Sbapt ndptr n; 218228063Sbapt unsigned int i; 219228063Sbapt 220228063Sbapt for (n = ohash_first(¯os, &i); n != NULL; 221228063Sbapt n = ohash_next(¯os, &i)) 222228063Sbapt if (n->d != NULL) 223228063Sbapt f(n->name, n->d); 224228063Sbapt} 225228063Sbapt 226228063Sbaptvoid 227228063Sbaptsetup_builtin(const char *name, unsigned int type) 228228063Sbapt{ 229228063Sbapt ndptr n; 230228063Sbapt char *name2; 231228063Sbapt 232228063Sbapt if (prefix_builtins) { 233228063Sbapt name2 = xalloc(strlen(name)+3+1, NULL); 234228063Sbapt memcpy(name2, "m4_", 3); 235228063Sbapt memcpy(name2 + 3, name, strlen(name)+1); 236228063Sbapt } else 237228063Sbapt name2 = xstrdup(name); 238228063Sbapt 239228063Sbapt n = create_entry(name2); 240228063Sbapt n->builtin_type = type; 241228063Sbapt n->d = xalloc(sizeof(struct macro_definition), NULL); 242228063Sbapt n->d->defn = name2; 243228063Sbapt n->d->type = type; 244228063Sbapt n->d->next = NULL; 245228063Sbapt} 246228063Sbapt 247228063Sbaptvoid 248228063Sbaptmark_traced(const char *name, int on) 249228063Sbapt{ 250228063Sbapt ndptr p; 251228063Sbapt unsigned int i; 252228063Sbapt 253228063Sbapt if (name == NULL) { 254228063Sbapt if (on) 255228063Sbapt trace_flags |= TRACE_ALL; 256228063Sbapt else 257228063Sbapt trace_flags &= ~TRACE_ALL; 258228063Sbapt for (p = ohash_first(¯os, &i); p != NULL; 259228063Sbapt p = ohash_next(¯os, &i)) 260228063Sbapt p->trace_flags = FLAG_NO_TRACE; 261228063Sbapt } else { 262228063Sbapt p = create_entry(name); 263228063Sbapt p->trace_flags = on; 264228063Sbapt } 265228063Sbapt} 266228063Sbapt 267228063Sbaptndptr 268228063Sbaptmacro_getbuiltin(const char *name) 269228063Sbapt{ 270228063Sbapt ndptr p; 271228063Sbapt 272228063Sbapt p = lookup(name); 273228063Sbapt if (p == NULL || p->builtin_type == MACRTYPE) 274228063Sbapt return NULL; 275228063Sbapt else 276228063Sbapt return p; 277228063Sbapt} 278