Annotation of src/usr.bin/m4/look.c, Revision 1.12
1.12 ! espie 1: /* $OpenBSD: look.c,v 1.11 2003/06/03 02:56:10 millert 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: #ifndef lint
36: static char sccsid[] = "@(#)look.c 8.1 (Berkeley) 6/6/93";
37: #endif /* not lint */
38:
39: /*
40: * look.c
41: * Facility: m4 macro processor
42: * by: oz
43: */
44:
45: #include <sys/types.h>
46: #include <stdio.h>
47: #include <stdlib.h>
1.3 espie 48: #include <stddef.h>
1.1 deraadt 49: #include <string.h>
50: #include "mdef.h"
51: #include "stdd.h"
52: #include "extern.h"
53:
1.12 ! espie 54: struct ndblock { /* hastable structure */
! 55: char *name; /* entry name.. */
! 56: struct macro_definition d;
! 57: unsigned int hv; /* hash function value.. */
! 58: ndptr nxtptr; /* link to next entry.. */
! 59: };
! 60:
1.9 millert 61: static void freent(ndptr);
1.12 ! espie 62: static void remhash(const char *, int);
! 63: static unsigned hash(const char *);
! 64: static ndptr addent(const char *);
1.5 espie 65:
1.12 ! espie 66: static unsigned int
1.10 espie 67: hash(const char *name)
1.1 deraadt 68: {
1.7 millert 69: unsigned int h = 0;
1.1 deraadt 70: while (*name)
71: h = (h << 5) + h + *name++;
1.6 espie 72: return (h);
1.1 deraadt 73: }
74:
75: /*
76: * find name in the hash table
77: */
78: ndptr
1.10 espie 79: lookup(const char *name)
1.1 deraadt 80: {
1.4 espie 81: ndptr p;
1.7 millert 82: unsigned int h;
1.1 deraadt 83:
1.6 espie 84: h = hash(name);
1.12 ! espie 85: for (p = hashtab[h % HASHSIZE]; p != NULL; p = p->nxtptr)
1.6 espie 86: if (h == p->hv && STREQ(name, p->name))
1.1 deraadt 87: break;
88: return (p);
89: }
90:
91: /*
92: * hash and create an entry in the hash table.
93: * The new entry is added in front of a hash bucket.
94: */
1.12 ! espie 95: static ndptr
1.10 espie 96: addent(const char *name)
1.1 deraadt 97: {
1.7 millert 98: unsigned int h;
1.1 deraadt 99: ndptr p;
100:
101: h = hash(name);
102: p = (ndptr) xalloc(sizeof(struct ndblock));
1.6 espie 103: p->nxtptr = hashtab[h % HASHSIZE];
104: hashtab[h % HASHSIZE] = p;
1.1 deraadt 105: p->name = xstrdup(name);
1.6 espie 106: p->hv = h;
1.1 deraadt 107: return p;
108: }
109:
110: static void
1.10 espie 111: freent(ndptr p)
1.1 deraadt 112: {
1.8 espie 113: free((char *) p->name);
1.12 ! espie 114: if (p->d.defn != null)
! 115: free((char *) p->d.defn);
1.1 deraadt 116: free((char *) p);
117: }
118:
119: /*
120: * remove an entry from the hashtable
121: */
1.12 ! espie 122: static void
1.10 espie 123: remhash(const char *name, int all)
1.1 deraadt 124: {
1.7 millert 125: unsigned int h;
1.4 espie 126: ndptr xp, tp, mp;
1.1 deraadt 127:
128: h = hash(name);
1.6 espie 129: mp = hashtab[h % HASHSIZE];
1.12 ! espie 130: tp = NULL;
! 131: while (mp != NULL) {
1.6 espie 132: if (mp->hv == h && STREQ(mp->name, name)) {
1.1 deraadt 133: mp = mp->nxtptr;
1.12 ! espie 134: if (tp == NULL) {
1.6 espie 135: freent(hashtab[h % HASHSIZE]);
136: hashtab[h % HASHSIZE] = mp;
1.1 deraadt 137: }
138: else {
139: xp = tp->nxtptr;
140: tp->nxtptr = mp;
141: freent(xp);
142: }
143: if (!all)
144: break;
145: }
146: else {
147: tp = mp;
148: mp = mp->nxtptr;
149: }
150: }
1.12 ! espie 151: }
! 152:
! 153: struct macro_definition *
! 154: lookup_macro_definition(const char *name)
! 155: {
! 156: ndptr p;
! 157:
! 158: p = lookup(name);
! 159: if (p)
! 160: return &(p->d);
! 161: else
! 162: return NULL;
! 163: }
! 164:
! 165: static void
! 166: setup_definition(struct macro_definition *d, const char *defn)
! 167: {
! 168: int n;
! 169:
! 170: if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0) {
! 171: n = builtin_type(defn+sizeof(BUILTIN_MARKER)-1);
! 172: if (n != -1) {
! 173: d->type = n & TYPEMASK;
! 174: if ((n & NOARGS) == 0)
! 175: d->type |= NEEDARGS;
! 176: d->defn = xstrdup(defn+sizeof(BUILTIN_MARKER)-1);
! 177: return;
! 178: }
! 179: }
! 180: if (!*defn)
! 181: d->defn = null;
! 182: else
! 183: d->defn = xstrdup(defn);
! 184: d->type = MACRTYPE;
! 185: }
! 186:
! 187: void
! 188: macro_define(const char *name, const char *defn)
! 189: {
! 190: ndptr p;
! 191:
! 192: if ((p = lookup(name)) == NULL)
! 193: p = addent(name);
! 194: else if (p->d.defn != null)
! 195: free((char *) p->d.defn);
! 196: setup_definition(&(p->d), defn);
! 197: if (STREQ(name, defn))
! 198: p->d.type |= RECDEF;
! 199: }
! 200:
! 201: void
! 202: macro_pushdef(const char *name, const char *defn)
! 203: {
! 204: ndptr p;
! 205:
! 206: p = addent(name);
! 207: setup_definition(&(p->d), defn);
! 208: if (STREQ(name, defn))
! 209: p->d.type |= RECDEF;
! 210: }
! 211:
! 212: void
! 213: macro_undefine(const char *name)
! 214: {
! 215: remhash(name, ALL);
! 216: }
! 217:
! 218: void
! 219: macro_popdef(const char *name)
! 220: {
! 221: remhash(name, TOP);
! 222: }
! 223:
! 224: void
! 225: macro_for_all(void (*f)(const char *, struct macro_definition *))
! 226: {
! 227: int n;
! 228: ndptr p;
! 229:
! 230: for (n = 0; n < HASHSIZE; n++)
! 231: for (p = hashtab[n]; p != NULL; p = p->nxtptr)
! 232: f(p->name, &(p->d));
! 233: }
! 234:
! 235: void
! 236: setup_builtin(const char *name, unsigned int type)
! 237: {
! 238: unsigned int h;
! 239: ndptr p;
! 240:
! 241: h = hash(name);
! 242: p = (ndptr) xalloc(sizeof(struct ndblock));
! 243: p->nxtptr = hashtab[h % HASHSIZE];
! 244: hashtab[h % HASHSIZE] = p;
! 245: p->name = xstrdup(name);
! 246: p->d.defn = xstrdup(name);
! 247: p->hv = h;
! 248: p->d.type = type;
! 249: }
! 250:
! 251: const char *
! 252: macro_name(ndptr p)
! 253: {
! 254: return p->name;
! 255: }
! 256:
! 257: struct macro_definition *
! 258: macro_getdef(ndptr p)
! 259: {
! 260: return &(p->d);
1.1 deraadt 261: }