xref: /freebsd/usr.bin/m4/look.c (revision bd2bfb58)
1 /*	$OpenBSD: look.c,v 1.10 2002/04/26 16:15:16 espie Exp $	*/
2 
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.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38 
39 #include <sys/cdefs.h>
40 __SCCSID("@(#)look.c	8.1 (Berkeley) 6/6/93");
41 __RCSID_SOURCE("$OpenBSD: look.c,v 1.10 2002/04/26 16:15:16 espie Exp $");
42 __FBSDID("$FreeBSD$");
43 
44 /*
45  * look.c
46  * Facility: m4 macro processor
47  * by: oz
48  */
49 
50 #include <sys/types.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <stddef.h>
54 #include <string.h>
55 #include "mdef.h"
56 #include "stdd.h"
57 #include "extern.h"
58 
59 static void freent(ndptr);
60 
61 unsigned int
62 hash(const char *name)
63 {
64 	unsigned int h = 0;
65 	while (*name)
66 		h = (h << 5) + h + *name++;
67 	return (h);
68 }
69 
70 /*
71  * find name in the hash table
72  */
73 ndptr
74 lookup(const char *name)
75 {
76 	ndptr p;
77 	unsigned int h;
78 
79 	h = hash(name);
80 	for (p = hashtab[h % HASHSIZE]; p != nil; p = p->nxtptr)
81 		if (h == p->hv && STREQ(name, p->name))
82 			break;
83 	return (p);
84 }
85 
86 /*
87  * hash and create an entry in the hash table.
88  * The new entry is added in front of a hash bucket.
89  */
90 ndptr
91 addent(const char *name)
92 {
93 	unsigned int h;
94 	ndptr p;
95 
96 	h = hash(name);
97 	p = (ndptr) xalloc(sizeof(struct ndblock));
98 	p->nxtptr = hashtab[h % HASHSIZE];
99 	hashtab[h % HASHSIZE] = p;
100 	p->name = xstrdup(name);
101 	p->hv = h;
102 	return p;
103 }
104 
105 static void
106 freent(ndptr p)
107 {
108 	free((char *) p->name);
109 	if (p->defn != null)
110 		free((char *) p->defn);
111 	free((char *) p);
112 }
113 
114 /*
115  * remove an entry from the hashtable
116  */
117 void
118 remhash(const char *name, int all)
119 {
120 	unsigned int h;
121 	ndptr xp, tp, mp;
122 
123 	h = hash(name);
124 	mp = hashtab[h % HASHSIZE];
125 	tp = nil;
126 	while (mp != nil) {
127 		if (mp->hv == h && STREQ(mp->name, name)) {
128 			mp = mp->nxtptr;
129 			if (tp == nil) {
130 				freent(hashtab[h % HASHSIZE]);
131 				hashtab[h % HASHSIZE] = mp;
132 			}
133 			else {
134 				xp = tp->nxtptr;
135 				tp->nxtptr = mp;
136 				freent(xp);
137 			}
138 			if (!all)
139 				break;
140 		}
141 		else {
142 			tp = mp;
143 			mp = mp->nxtptr;
144 		}
145 	}
146 }
147