File: [local] / src / usr.bin / m4 / look.c (download)
Revision 1.14, Mon Jun 30 22:11:38 2003 UTC (20 years, 11 months ago) by espie
Branch: MAIN
Changes since 1.13: +26 -6 lines
add a flag for each macro name that records built-in status.
Fold built-in lookup into normal lookup.
okay millert@
|
/* $OpenBSD: look.c,v 1.14 2003/06/30 22:11:38 espie Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ozan Yigit at York University.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char sccsid[] = "@(#)look.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
/*
* look.c
* Facility: m4 macro processor
* by: oz
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <ohash.h>
#include "mdef.h"
#include "stdd.h"
#include "extern.h"
struct ndblock { /* hashtable structure */
unsigned int builtin_type;
struct macro_definition *d;
char name[1]; /* entry name.. */
};
extern void *hash_alloc(size_t, void *);
extern void hash_free(void *, size_t, void *);
extern 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 };
static struct ohash macros;
void
init_macros()
{
ohash_init(¯os, 7, ¯o_info);
}
/*
* find name in the hash table
*/
ndptr
lookup(const char *name)
{
return ohash_find(¯os, ohash_qlookup(¯os, name));
}
struct macro_definition *
lookup_macro_definition(const char *name)
{
ndptr p;
p = lookup(name);
if (p)
return p->d;
else
return NULL;
}
static void
setup_definition(struct macro_definition *d, const char *defn, const char *name)
{
ndptr 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 = null;
else
d->defn = xstrdup(defn);
d->type = MACRTYPE;
}
if (STREQ(name, defn))
d->type |= RECDEF;
}
static ndptr
create_entry(const char *name)
{
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->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));
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));
d->next = n->d;
n->d = d;
setup_definition(n->d, defn, name);
}
void
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);
}
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))
f(n->name, n->d);
}
void
setup_builtin(const char *name, unsigned int type)
{
ndptr n;
n = create_entry(name);
n->builtin_type = type;
n->d = xalloc(sizeof(struct macro_definition));
n->d->defn = xstrdup(name);
n->d->type = type;
n->d->next = NULL;
}
const char *
macro_name(ndptr p)
{
return p->name;
}
struct macro_definition *
macro_getdef(ndptr p)
{
return p->d;
}
ndptr
macro_getbuiltin(const char *name)
{
ndptr p;
p = lookup(name);
if (p == NULL || p->builtin_type == MACRTYPE)
return NULL;
else
return p;
}
int
macro_builtin_type(ndptr p)
{
return p->builtin_type;
}