diff options
Diffstat (limited to 'usr.bin/m4/look.c')
-rw-r--r-- | usr.bin/m4/look.c | 271 |
1 files changed, 201 insertions, 70 deletions
diff --git a/usr.bin/m4/look.c b/usr.bin/m4/look.c index fe03f0e..904c055 100644 --- a/usr.bin/m4/look.c +++ b/usr.bin/m4/look.c @@ -1,4 +1,4 @@ -/* $OpenBSD: look.c,v 1.10 2002/04/26 16:15:16 espie Exp $ */ +/* $OpenBSD: look.c,v 1.22 2010/09/07 19:58:09 marco Exp $ */ /* * Copyright (c) 1989, 1993 @@ -15,7 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -31,13 +31,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ - -#if 0 -#ifndef lint -static char sccsid[] = "@(#)look.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ -#endif - #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -50,21 +43,52 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> #include <stdio.h> #include <stdlib.h> +#include <stdint.h> #include <stddef.h> #include <string.h> +#include <ohash.h> #include "mdef.h" #include "stdd.h" #include "extern.h" -static void freent(ndptr); +static void *hash_alloc(size_t, void *); +static void hash_free(void *, size_t, void *); +static void *element_alloc(size_t, void *); +static void setup_definition(struct macro_definition *, const char *, + const char *); + +static struct ohash_info macro_info = { + offsetof(struct ndblock, name), + NULL, hash_alloc, hash_free, element_alloc }; + +struct ohash macros; + +/* Support routines for hash tables. */ +void * +hash_alloc(size_t s, __unused void *u) +{ + void *storage = xalloc(s, "hash alloc"); + if (storage) + memset(storage, 0, s); + return storage; +} + +void +hash_free(void *p, __unused size_t s, __unused void *u) +{ + free(p); +} + +void * +element_alloc(size_t s, __unused void *u) +{ + return xalloc(s, "element alloc"); +} -unsigned int -hash(const char *name) +void +init_macros(void) { - unsigned int h = 0; - while (*name) - h = (h << 5) + h + *name++; - return (h); + ohash_init(¯os, 10, ¯o_info); } /* @@ -73,74 +97,181 @@ hash(const char *name) ndptr lookup(const char *name) { + return ohash_find(¯os, ohash_qlookup(¯os, name)); +} + +struct macro_definition * +lookup_macro_definition(const char *name) +{ ndptr p; - unsigned int h; - h = hash(name); - for (p = hashtab[h % HASHSIZE]; p != nil; p = p->nxtptr) - if (h == p->hv && STREQ(name, p->name)) - break; - return (p); + p = ohash_find(¯os, ohash_qlookup(¯os, name)); + if (p) + return p->d; + else + return NULL; } -/* - * hash and create an entry in the hash table. - * The new entry is added in front of a hash bucket. - */ -ndptr -addent(const char *name) +static void +setup_definition(struct macro_definition *d, const char *defn, const char *name) { - unsigned int h; ndptr p; - h = hash(name); - p = (ndptr) xalloc(sizeof(struct ndblock)); - p->nxtptr = hashtab[h % HASHSIZE]; - hashtab[h % HASHSIZE] = p; - p->name = xstrdup(name); - p->hv = h; - return p; + if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0 && + (p = macro_getbuiltin(defn+sizeof(BUILTIN_MARKER)-1)) != NULL) { + d->type = macro_builtin_type(p); + d->defn = xstrdup(defn+sizeof(BUILTIN_MARKER)-1); + } else { + if (!*defn) + d->defn = __DECONST(char *, null); + else + d->defn = xstrdup(defn); + d->type = MACRTYPE; + } + if (STREQ(name, defn)) + d->type |= RECDEF; } -static void -freent(ndptr p) +static ndptr +create_entry(const char *name) { - free((char *) p->name); - if (p->defn != null) - free((char *) p->defn); - free((char *) p); + const char *end = NULL; + unsigned int i; + ndptr n; + + i = ohash_qlookupi(¯os, name, &end); + n = ohash_find(¯os, i); + if (n == NULL) { + n = ohash_create_entry(¯o_info, name, &end); + ohash_insert(¯os, i, n); + n->trace_flags = FLAG_NO_TRACE; + n->builtin_type = MACRTYPE; + n->d = NULL; + } + return n; +} + +void +macro_define(const char *name, const char *defn) +{ + ndptr n = create_entry(name); + if (n->d != NULL) { + if (n->d->defn != null) + free(n->d->defn); + } else { + n->d = xalloc(sizeof(struct macro_definition), NULL); + n->d->next = NULL; + } + setup_definition(n->d, defn, name); +} + +void +macro_pushdef(const char *name, const char *defn) +{ + ndptr n; + struct macro_definition *d; + + n = create_entry(name); + d = xalloc(sizeof(struct macro_definition), NULL); + d->next = n->d; + n->d = d; + setup_definition(n->d, defn, name); } -/* - * remove an entry from the hashtable - */ void -remhash(const char *name, int all) -{ - unsigned int h; - ndptr xp, tp, mp; - - h = hash(name); - mp = hashtab[h % HASHSIZE]; - tp = nil; - while (mp != nil) { - if (mp->hv == h && STREQ(mp->name, name)) { - mp = mp->nxtptr; - if (tp == nil) { - freent(hashtab[h % HASHSIZE]); - hashtab[h % HASHSIZE] = mp; - } - else { - xp = tp->nxtptr; - tp->nxtptr = mp; - freent(xp); - } - if (!all) - break; +macro_undefine(const char *name) +{ + ndptr n = lookup(name); + if (n != NULL) { + struct macro_definition *r, *r2; + + for (r = n->d; r != NULL; r = r2) { + r2 = r->next; + if (r->defn != null) + free(r->defn); + free(r); } - else { - tp = mp; - mp = mp->nxtptr; + n->d = NULL; + } +} + +void +macro_popdef(const char *name) +{ + ndptr n = lookup(name); + + if (n != NULL) { + struct macro_definition *r = n->d; + if (r != NULL) { + n->d = r->next; + if (r->defn != null) + free(r->defn); + free(r); } } } + +void +macro_for_all(void (*f)(const char *, struct macro_definition *)) +{ + ndptr n; + unsigned int i; + + for (n = ohash_first(¯os, &i); n != NULL; + n = ohash_next(¯os, &i)) + if (n->d != NULL) + f(n->name, n->d); +} + +void +setup_builtin(const char *name, unsigned int type) +{ + ndptr n; + char *name2; + + if (prefix_builtins) { + name2 = xalloc(strlen(name)+3+1, NULL); + memcpy(name2, "m4_", 3); + memcpy(name2 + 3, name, strlen(name)+1); + } else + name2 = xstrdup(name); + + n = create_entry(name2); + n->builtin_type = type; + n->d = xalloc(sizeof(struct macro_definition), NULL); + n->d->defn = name2; + n->d->type = type; + n->d->next = NULL; +} + +void +mark_traced(const char *name, int on) +{ + ndptr p; + unsigned int i; + + if (name == NULL) { + if (on) + trace_flags |= TRACE_ALL; + else + trace_flags &= ~TRACE_ALL; + for (p = ohash_first(¯os, &i); p != NULL; + p = ohash_next(¯os, &i)) + p->trace_flags = FLAG_NO_TRACE; + } else { + p = create_entry(name); + p->trace_flags = on; + } +} + +ndptr +macro_getbuiltin(const char *name) +{ + ndptr p; + + p = lookup(name); + if (p == NULL || p->builtin_type == MACRTYPE) + return NULL; + else + return p; +} |