head	1.13;
access;
symbols
	netbsd-11-0-RC4:1.13
	netbsd-11-0-RC3:1.13
	netbsd-11-0-RC2:1.13
	netbsd-11-0-RC1:1.13
	perseant-exfatfs-base-20250801:1.13
	netbsd-11:1.13.0.30
	netbsd-11-base:1.13
	netbsd-10-1-RELEASE:1.13
	perseant-exfatfs-base-20240630:1.13
	perseant-exfatfs:1.13.0.28
	perseant-exfatfs-base:1.13
	netbsd-8-3-RELEASE:1.13
	netbsd-9-4-RELEASE:1.13
	netbsd-10-0-RELEASE:1.13
	netbsd-10-0-RC6:1.13
	netbsd-10-0-RC5:1.13
	netbsd-10-0-RC4:1.13
	netbsd-10-0-RC3:1.13
	netbsd-10-0-RC2:1.13
	netbsd-10-0-RC1:1.13
	netbsd-10:1.13.0.26
	netbsd-10-base:1.13
	netbsd-9-3-RELEASE:1.13
	cjep_sun2x-base1:1.13
	cjep_sun2x:1.13.0.24
	cjep_sun2x-base:1.13
	cjep_staticlib_x-base1:1.13
	netbsd-9-2-RELEASE:1.13
	cjep_staticlib_x:1.13.0.22
	cjep_staticlib_x-base:1.13
	netbsd-9-1-RELEASE:1.13
	phil-wifi-20200421:1.13
	phil-wifi-20200411:1.13
	is-mlppp:1.13.0.20
	is-mlppp-base:1.13
	phil-wifi-20200406:1.13
	netbsd-8-2-RELEASE:1.13
	netbsd-9-0-RELEASE:1.13
	netbsd-9-0-RC2:1.13
	netbsd-9-0-RC1:1.13
	phil-wifi-20191119:1.13
	netbsd-9:1.13.0.18
	netbsd-9-base:1.13
	phil-wifi-20190609:1.13
	netbsd-8-1-RELEASE:1.13
	netbsd-8-1-RC1:1.13
	pgoyette-compat-merge-20190127:1.13
	pgoyette-compat-20190127:1.13
	pgoyette-compat-20190118:1.13
	pgoyette-compat-1226:1.13
	pgoyette-compat-1126:1.13
	pgoyette-compat-1020:1.13
	pgoyette-compat-0930:1.13
	pgoyette-compat-0906:1.13
	netbsd-7-2-RELEASE:1.12
	pgoyette-compat-0728:1.13
	netbsd-8-0-RELEASE:1.13
	phil-wifi:1.13.0.16
	phil-wifi-base:1.13
	pgoyette-compat-0625:1.13
	netbsd-8-0-RC2:1.13
	pgoyette-compat-0521:1.13
	pgoyette-compat-0502:1.13
	pgoyette-compat-0422:1.13
	netbsd-8-0-RC1:1.13
	pgoyette-compat-0415:1.13
	pgoyette-compat-0407:1.13
	pgoyette-compat-0330:1.13
	pgoyette-compat-0322:1.13
	pgoyette-compat-0315:1.13
	netbsd-7-1-2-RELEASE:1.12
	pgoyette-compat:1.13.0.14
	pgoyette-compat-base:1.13
	netbsd-7-1-1-RELEASE:1.12
	matt-nb8-mediatek:1.13.0.12
	matt-nb8-mediatek-base:1.13
	perseant-stdc-iso10646:1.13.0.10
	perseant-stdc-iso10646-base:1.13
	netbsd-8:1.13.0.8
	netbsd-8-base:1.13
	prg-localcount2-base3:1.13
	prg-localcount2-base2:1.13
	prg-localcount2-base1:1.13
	prg-localcount2:1.13.0.6
	prg-localcount2-base:1.13
	pgoyette-localcount-20170426:1.13
	bouyer-socketcan-base1:1.13
	pgoyette-localcount-20170320:1.13
	netbsd-7-1:1.12.0.16
	netbsd-7-1-RELEASE:1.12
	netbsd-7-1-RC2:1.12
	netbsd-7-nhusb-base-20170116:1.12
	bouyer-socketcan:1.13.0.4
	bouyer-socketcan-base:1.13
	pgoyette-localcount-20170107:1.13
	netbsd-7-1-RC1:1.12
	pgoyette-localcount-20161104:1.13
	netbsd-7-0-2-RELEASE:1.12
	localcount-20160914:1.13
	netbsd-7-nhusb:1.12.0.14
	netbsd-7-nhusb-base:1.12
	pgoyette-localcount-20160806:1.13
	pgoyette-localcount-20160726:1.13
	pgoyette-localcount:1.13.0.2
	pgoyette-localcount-base:1.13
	netbsd-7-0-1-RELEASE:1.12
	netbsd-7-0:1.12.0.12
	netbsd-7-0-RELEASE:1.12
	netbsd-7-0-RC3:1.12
	netbsd-7-0-RC2:1.12
	netbsd-7-0-RC1:1.12
	netbsd-5-2-3-RELEASE:1.10
	netbsd-5-1-5-RELEASE:1.10
	netbsd-6-0-6-RELEASE:1.11
	netbsd-6-1-5-RELEASE:1.11
	netbsd-7:1.12.0.10
	netbsd-7-base:1.12
	yamt-pagecache-base9:1.12
	yamt-pagecache-tag8:1.11.6.1
	netbsd-6-1-4-RELEASE:1.11
	netbsd-6-0-5-RELEASE:1.11
	tls-earlyentropy:1.12.0.8
	tls-earlyentropy-base:1.12
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.12
	riastradh-drm2-base3:1.12
	netbsd-6-1-3-RELEASE:1.11
	netbsd-6-0-4-RELEASE:1.11
	netbsd-5-2-2-RELEASE:1.10
	netbsd-5-1-4-RELEASE:1.10
	netbsd-6-1-2-RELEASE:1.11
	netbsd-6-0-3-RELEASE:1.11
	netbsd-5-2-1-RELEASE:1.10
	netbsd-5-1-3-RELEASE:1.10
	netbsd-6-1-1-RELEASE:1.11
	riastradh-drm2-base2:1.12
	riastradh-drm2-base1:1.12
	riastradh-drm2:1.12.0.4
	riastradh-drm2-base:1.12
	netbsd-6-1:1.11.0.14
	netbsd-6-0-2-RELEASE:1.11
	netbsd-6-1-RELEASE:1.11
	netbsd-6-1-RC4:1.11
	netbsd-6-1-RC3:1.11
	agc-symver:1.12.0.6
	agc-symver-base:1.12
	netbsd-6-1-RC2:1.11
	netbsd-6-1-RC1:1.11
	yamt-pagecache-base8:1.12
	netbsd-5-2:1.10.0.46
	netbsd-6-0-1-RELEASE:1.11
	yamt-pagecache-base7:1.12
	netbsd-5-2-RELEASE:1.10
	netbsd-5-2-RC1:1.10
	matt-nb6-plus-nbase:1.11
	yamt-pagecache-base6:1.12
	netbsd-6-0:1.11.0.12
	netbsd-6-0-RELEASE:1.11
	netbsd-6-0-RC2:1.11
	tls-maxphys:1.12.0.2
	tls-maxphys-base:1.12
	matt-nb6-plus:1.11.0.10
	matt-nb6-plus-base:1.11
	netbsd-6-0-RC1:1.11
	yamt-pagecache-base5:1.12
	yamt-pagecache-base4:1.12
	netbsd-6:1.11.0.8
	netbsd-6-base:1.11
	netbsd-5-1-2-RELEASE:1.10
	netbsd-5-1-1-RELEASE:1.10
	yamt-pagecache-base3:1.11
	yamt-pagecache-base2:1.11
	yamt-pagecache:1.11.0.6
	yamt-pagecache-base:1.11
	cherry-xenmp:1.11.0.4
	cherry-xenmp-base:1.11
	bouyer-quota2-nbase:1.11
	bouyer-quota2:1.11.0.2
	bouyer-quota2-base:1.11
	matt-mips64-premerge-20101231:1.11
	matt-nb5-mips64-premerge-20101231:1.10
	matt-nb5-pq3:1.10.0.44
	matt-nb5-pq3-base:1.10
	netbsd-5-1:1.10.0.42
	netbsd-5-1-RELEASE:1.10
	netbsd-5-1-RC4:1.10
	matt-nb5-mips64-k15:1.10
	netbsd-5-1-RC3:1.10
	netbsd-5-1-RC2:1.10
	netbsd-5-1-RC1:1.10
	netbsd-5-0-2-RELEASE:1.10
	matt-nb5-mips64-premerge-20091211:1.10
	matt-premerge-20091211:1.11
	OPENBSD20091026:1.1.1.3
	OPENBSD:1.1.1
	matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.10
	matt-nb4-mips64-k7-u2a-k9b:1.10
	matt-nb5-mips64-u1-k1-k5:1.10
	matt-nb5-mips64:1.10.0.40
	netbsd-5-0-1-RELEASE:1.10
	jym-xensuspend-nbase:1.10
	netbsd-5-0:1.10.0.38
	netbsd-5-0-RELEASE:1.10
	netbsd-5-0-RC4:1.10
	netbsd-5-0-RC3:1.10
	netbsd-5-0-RC2:1.10
	jym-xensuspend:1.10.0.36
	jym-xensuspend-base:1.10
	netbsd-5-0-RC1:1.10
	netbsd-5:1.10.0.34
	netbsd-5-base:1.10
	matt-mips64-base2:1.10
	matt-mips64:1.10.0.32
	mjf-devfs2:1.10.0.30
	mjf-devfs2-base:1.10
	netbsd-4-0-1-RELEASE:1.10
	wrstuden-revivesa-base-3:1.10
	wrstuden-revivesa-base-2:1.10
	wrstuden-fixsa-newbase:1.10
	wrstuden-revivesa-base-1:1.10
	yamt-pf42-base4:1.10
	yamt-pf42-base3:1.10
	hpcarm-cleanup-nbase:1.10
	yamt-pf42-baseX:1.10
	yamt-pf42-base2:1.10
	wrstuden-revivesa:1.10.0.28
	wrstuden-revivesa-base:1.10
	yamt-pf42:1.10.0.26
	yamt-pf42-base:1.10
	keiichi-mipv6-nbase:1.10
	keiichi-mipv6:1.10.0.24
	keiichi-mipv6-base:1.10
	matt-armv6-nbase:1.10
	matt-armv6-prevmlocking:1.10
	wrstuden-fixsa-base-1:1.10
	netbsd-4-0:1.10.0.22
	netbsd-4-0-RELEASE:1.10
	cube-autoconf:1.10.0.20
	cube-autoconf-base:1.10
	netbsd-4-0-RC5:1.10
	netbsd-4-0-RC4:1.10
	netbsd-4-0-RC3:1.10
	netbsd-4-0-RC2:1.10
	netbsd-4-0-RC1:1.10
	matt-armv6:1.10.0.18
	matt-armv6-base:1.10
	matt-mips64-base:1.10
	hpcarm-cleanup:1.10.0.16
	hpcarm-cleanup-base:1.10
	netbsd-3-1-1-RELEASE:1.10
	netbsd-3-0-3-RELEASE:1.10
	wrstuden-fixsa:1.10.0.14
	wrstuden-fixsa-base:1.10
	abandoned-netbsd-4-base:1.10
	abandoned-netbsd-4:1.10.0.8
	netbsd-3-1:1.10.0.10
	netbsd-3-1-RELEASE:1.10
	netbsd-3-0-2-RELEASE:1.10
	netbsd-3-1-RC4:1.10
	netbsd-3-1-RC3:1.10
	netbsd-3-1-RC2:1.10
	netbsd-3-1-RC1:1.10
	netbsd-4:1.10.0.12
	netbsd-4-base:1.10
	chap-midi-nbase:1.10
	netbsd-3-0-1-RELEASE:1.10
	chap-midi:1.10.0.6
	chap-midi-base:1.10
	netbsd-3-0:1.10.0.4
	netbsd-3-0-RELEASE:1.10
	netbsd-3-0-RC6:1.10
	netbsd-3-0-RC5:1.10
	netbsd-3-0-RC4:1.10
	netbsd-3-0-RC3:1.10
	netbsd-3-0-RC2:1.10
	netbsd-3-0-RC1:1.10
	netbsd-2-0-3-RELEASE:1.9.2.1
	netbsd-2-1:1.9.2.1.0.4
	netbsd-2-1-RELEASE:1.9.2.1
	netbsd-2-1-RC6:1.9.2.1
	netbsd-2-1-RC5:1.9.2.1
	netbsd-2-1-RC4:1.9.2.1
	netbsd-2-1-RC3:1.9.2.1
	netbsd-2-1-RC2:1.9.2.1
	netbsd-2-1-RC1:1.9.2.1
	netbsd-2-0-2-RELEASE:1.9.2.1
	netbsd-3:1.10.0.2
	netbsd-3-base:1.10
	netbsd-2-0-1-RELEASE:1.9.2.1
	netbsd-2:1.9.2.1.0.2
	netbsd-2-base:1.9.2.1
	netbsd-2-0-RELEASE:1.9.2.1
	netbsd-2-0-RC5:1.9.2.1
	netbsd-2-0-RC4:1.9.2.1
	netbsd-2-0-RC3:1.9.2.1
	netbsd-2-0-RC2:1.9.2.1
	netbsd-2-0-RC1:1.9.2.1
	netbsd-2-0:1.9.0.2
	netbsd-2-0-base:1.9
	netbsd-1-6-PATCH002-RELEASE:1.8
	netbsd-1-6-PATCH002:1.8
	netbsd-1-6-PATCH002-RC4:1.8
	netbsd-1-6-PATCH002-RC3:1.8
	netbsd-1-6-PATCH002-RC2:1.8
	netbsd-1-6-PATCH002-RC1:1.8
	netbsd-1-6-PATCH001:1.8
	netbsd-1-6-PATCH001-RELEASE:1.8
	netbsd-1-6-PATCH001-RC3:1.8
	netbsd-1-6-PATCH001-RC2:1.8
	netbsd-1-6-PATCH001-RC1:1.8
	fvdl_fs64_base:1.8
	netbsd-1-6-RELEASE:1.8
	netbsd-1-6-RC3:1.8
	netbsd-1-6-RC2:1.8
	netbsd-1-6-RC1:1.8
	netbsd-1-6:1.8.0.2
	netbsd-1-6-base:1.8
	netbsd-1-5-PATCH003:1.6
	netbsd-1-5-PATCH002:1.6
	netbsd-1-5-PATCH001:1.6
	netbsd-1-5-RELEASE:1.6
	netbsd-1-5-BETA2:1.6
	netbsd-1-5-BETA:1.6
	netbsd-1-4-PATCH003:1.6
	netbsd-1-5-ALPHA2:1.6
	netbsd-1-5:1.6.0.12
	netbsd-1-5-base:1.6
	minoura-xpg4dl-base:1.6
	minoura-xpg4dl:1.6.0.10
	netbsd-1-4-PATCH002:1.6
	wrstuden-devbsize-19991221:1.6
	wrstuden-devbsize:1.6.0.8
	wrstuden-devbsize-base:1.6
	comdex-fall-1999:1.6.0.6
	comdex-fall-1999-base:1.6
	netbsd-1-4-PATCH001:1.6
	netbsd-1-4-RELEASE:1.6
	netbsd-1-4:1.6.0.4
	netbsd-1-4-base:1.6
	netbsd-1-3-PATCH003:1.6
	netbsd-1-3-PATCH003-CANDIDATE2:1.6
	netbsd-1-3-PATCH003-CANDIDATE1:1.6
	netbsd-1-3-PATCH003-CANDIDATE0:1.6
	netbsd-1-3-PATCH002:1.6
	netbsd-1-3-PATCH001:1.6
	netbsd-1-3-RELEASE:1.6
	netbsd-1-3-BETA:1.6
	netbsd-1-3:1.6.0.2
	netbsd-1-3-base:1.6
	netbsd-1-2-PATCH001:1.5
	netbsd-1-2-RELEASE:1.5
	netbsd-1-2-BETA:1.5
	netbsd-1-2:1.5.0.8
	netbsd-1-2-base:1.5
	netbsd-1-1-PATCH001:1.5
	netbsd-1-1-RELEASE:1.5
	netbsd-1-1:1.5.0.4
	netbsd-1-1-base:1.5
	lite-2:1.1.1.2
	CSRG:1.1.1
	netbsd-1-0-PATCH06:1.5
	netbsd-1-0-PATCH05:1.5
	netbsd-1-0-PATCH04:1.5
	netbsd-1-0-PATCH03:1.5
	netbsd-1-0-PATCH02:1.5
	netbsd-1-0-PATCH1:1.5
	netbsd-1-0-PATCH0:1.5
	netbsd-1-0-RELEASE:1.5
	netbsd-1-0:1.5.0.2
	netbsd-1-0-base:1.5
	netbsd-0-9-RELEASE:1.2
	netbsd-0-9-BETA:1.2
	netbsd-0-9-ALPHA2:1.2
	netbsd-0-9-ALPHA:1.2
	netbsd-0-9:1.2.0.2
	netbsd-0-9-base:1.2
	netbsd-0-8:1.1.1.1
	netbsd-alpha-1:1.1.1.1
	patchkit-0-2-2:1.1.1.1
	WFJ-386bsd-01:1.1.1.1
	WFJ-920714:1.1.1;
locks; strict;
comment	@ * @;


1.13
date	2016.01.16.17.00.07;	author christos;	state Exp;
branches;
next	1.12;
commitid	ZaM9D6LNxUbg7bRy;

1.12
date	2012.03.20.20.34.58;	author matt;	state Exp;
branches;
next	1.11;

1.11
date	2009.10.26.21.11.28;	author christos;	state Exp;
branches
	1.11.6.1;
next	1.10;

1.10
date	2004.06.20.22.20.15;	author jmc;	state Exp;
branches;
next	1.9;

1.9
date	2003.08.07.11.14.32;	author agc;	state Exp;
branches
	1.9.2.1;
next	1.8;

1.8
date	2002.01.31.19.36.47;	author tv;	state Exp;
branches;
next	1.7;

1.7
date	2001.11.14.06.16.09;	author tv;	state Exp;
branches;
next	1.6;

1.6
date	97.10.19.04.39.57;	author lukem;	state Exp;
branches;
next	1.5;

1.5
date	94.06.19.03.58.37;	author glass;	state Exp;
branches;
next	1.4;

1.4
date	93.10.30.00.28.46;	author glass;	state Exp;
branches;
next	1.3;

1.3
date	93.08.02.17.54.42;	author mycroft;	state Exp;
branches;
next	1.2;

1.2
date	93.06.18.21.50.30;	author glass;	state Exp;
branches;
next	1.1;

1.1
date	93.03.21.09.45.37;	author cgd;	state Exp;
branches
	1.1.1.1;
next	;

1.11.6.1
date	2012.04.17.00.09.35;	author yamt;	state Exp;
branches;
next	;

1.9.2.1
date	2004.06.22.07.15.27;	author tron;	state Exp;
branches;
next	;

1.1.1.1
date	93.03.21.09.45.37;	author cgd;	state Exp;
branches;
next	1.1.1.2;

1.1.1.2
date	95.09.28.04.33.45;	author tls;	state Exp;
branches;
next	1.1.1.3;

1.1.1.3
date	2009.10.26.21.08.58;	author christos;	state Exp;
branches;
next	;


desc
@@


1.13
log
@Add disabled support for saving and restoring the symbol table.
@
text
@/*	$NetBSD: look.c,v 1.12 2012/03/20 20:34:58 matt Exp $	*/
/*	$OpenBSD: look.c,v 1.21 2009/10/14 17:23:17 sthen 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.
 */

/*
 * look.c
 * Facility: m4 macro processor
 * by: oz
 */
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: look.c,v 1.12 2012/03/20 20:34:58 matt Exp $");
#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 *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, void *u UNUSED)
{
	void *storage = xalloc(s, "hash alloc");
	if (storage)
		memset(storage, 0, s);
	return storage;
}

void
hash_free(void *p, size_t s UNUSED, void *u UNUSED)
{
	free(p);
}

void *
element_alloc(size_t s, void *u UNUSED)
{
	return xalloc(s, "element alloc");
}

void
init_macros(void)
{
	ohash_init(&macros, 10, &macro_info);
}

/*
 * find name in the hash table
 */
ndptr 
lookup(const char *name)
{
	return ohash_find(&macros, ohash_qlookup(&macros, name));
}

struct macro_definition *
lookup_macro_definition(const char *name)
{
	ndptr p;

	p = ohash_find(&macros, ohash_qlookup(&macros, 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 = xstrdup(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(&macros, name, &end);
	n = ohash_find(&macros, i);
	if (n == NULL) {
		n = ohash_create_entry(&macro_info, name, &end);
		ohash_insert(&macros, 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);
}

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(&macros, &i); n != NULL; 
	    n = ohash_next(&macros, &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(&macros, &i); p != NULL; 
		    p = ohash_next(&macros, &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;
}

#ifdef REAL_FREEZE
static void
recurse(FILE *f, ndptr n, struct macro_definition *d)
{
	if (d->next != NULL)
		recurse(f, n, d->next);

	// skip built-ins, because it is cheaper to do so
	// and initialize them manually
	if (d->type & (NOARGS|NEEDARGS))
		return;
	fprintf(f, "%c%zu,%zu\n%s%s\n",
	    (d->type & (NOARGS|NEEDARGS)) ? 'F' : 'T',
	    strlen(n->name), strlen(d->defn),
	    n->name, d->defn);
}

static void
dump_entry(FILE *f, ndptr n)
{
	if (n->d == NULL)
		return;
	recurse(f, n, n->d);
}

void
dump_state(FILE *f)
{
	ndptr n;
	unsigned int i;
	for (n = ohash_first(&macros, &i); n != NULL; 
	    n = ohash_next(&macros, &i))
		dump_entry(f, n);
}
#endif
@


1.12
log
@Use C89 function definitions
@
text
@d1 1
a1 1
/*	$NetBSD: look.c,v 1.11 2009/10/26 21:11:28 christos Exp $	*/
d45 1
a45 1
__RCSID("$NetBSD: look.c,v 1.11 2009/10/26 21:11:28 christos Exp $");
d281 35
@


1.11
log
@resolve conflicts.
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
d45 1
a45 1
__RCSID("$NetBSD$");
d70 1
a70 3
hash_alloc(s, u)
	size_t s;
	void *u 	UNUSED;
d79 1
a79 4
hash_free(p, s, u)
	void *p;
	size_t s	UNUSED;
	void *u 	UNUSED;
d85 1
a85 3
element_alloc(s, u)
	size_t s;
	void *u 	UNUSED;
d91 1
a91 1
init_macros()
@


1.11.6.1
log
@sync with head
@
text
@d70 3
a72 1
hash_alloc(size_t s, void *u UNUSED)
d81 4
a84 1
hash_free(void *p, size_t s UNUSED, void *u UNUSED)
d90 3
a92 1
element_alloc(size_t s, void *u UNUSED)
d98 1
a98 1
init_macros(void)
@


1.10
log
@Completely rework how tools/compat is done. Purge all uses/references to
_NETBSD_SOURCE as this makes cross building from older/newer versions of
NetBSD harder, not easier (and also makes the resulting tools 'different')

Wrap all required code with the inclusion of nbtool_config.h, attempt to
only use POSIX code in all places (or when reasonable test w. configure and
provide definitions: ala u_int, etc).

Reviewed by lukem. Tested on FreeBSD 4.9, Redhat Linux ES3, NetBSD 1.6.2 x86
NetBSD current (x86 and amd64) and Solaris 9.

Fixes PR's: PR#17762 PR#25944
@
text
@d1 2
a2 2
/*	$NetBSD: look.c,v 1.9 2003/08/07 11:14:32 agc Exp $	*/
/*	$OpenBSD: look.c,v 1.8 2001/09/17 08:11:13 espie Exp $	*/
a35 13
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif

#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@@(#)look.c	8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: look.c,v 1.9 2003/08/07 11:14:32 agc Exp $");
#endif
#endif /* not lint */

d41 5
a45 2

#include <sys/types.h>
d48 1
d51 1
d56 23
a78 1
static void freent __P((ndptr));
d80 21
a100 8
unsigned
hash(name)
	const char *name;
{
	unsigned int h = 0;
	while (*name)
		h = (h << 5) + h + *name++;
	return (h);
d107 7
a113 2
lookup(name)
	const char *name;
a115 1
	unsigned int h;
d117 5
a121 5
	h = hash(name);
	for (p = hashtab[h % HASHSIZE]; p != nil; p = p->nxtptr)
		if (h == p->hv && STREQ(name, p->name))
			break;
	return (p);
d124 2
a125 7
/*
 * hash and create an entry in the hash table.
 * The new entry is added in front of a hash bucket.
 */
ndptr 
addent(name)
	const char *name;
a126 1
	unsigned int h;
d129 13
a141 7
	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;
d144 35
a178 3
static void
freent(p)
	ndptr p;
d180 8
a187 4
	free((char *) p->name);
	if (p->defn != null)
		free((char *) p->defn);
	free((char *) p);
a189 3
/*
 * remove an entry from the hashtable
 */
d191 11
a201 24
remhash(name, all)
	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;
d203 16
a218 3
		else {
			tp = mp;
			mp = mp->nxtptr;
d222 66
@


1.9
log
@Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22365, verified by myself.
@
text
@d1 1
a1 1
/*	$NetBSD: look.c,v 1.8 2002/01/31 19:36:47 tv Exp $	*/
d36 4
d45 1
a45 1
__RCSID("$NetBSD: look.c,v 1.8 2002/01/31 19:36:47 tv Exp $");
@


1.9.2.1
log
@Pull up revision 1.10 (requested by jmc in ticket #527):
Completely rework how tools/compat is done. Purge all uses/references to
_NETBSD_SOURCE as this makes cross building from older/newer versions of
NetBSD harder, not easier (and also makes the resulting tools 'different')
Wrap all required code with the inclusion of nbtool_config.h, attempt to
only use POSIX code in all places (or when reasonable test w. configure and
provide definitions: ala u_int, etc).
Reviewed by lukem. Tested on FreeBSD 4.9, Redhat Linux ES3, NetBSD 1.6.2 x86
NetBSD current (x86 and amd64) and Solaris 9.
Fixes PR's: PR#17762 PR#25944
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
a35 4
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif

d41 1
a41 1
__RCSID("$NetBSD$");
@


1.8
log
@Protect __RCSID and __COPYRIGHT from being invoked if not defined.
@
text
@d1 1
a1 1
/*	$NetBSD: look.c,v 1.7 2001/11/14 06:16:09 tv Exp $	*/
d19 1
a19 5
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
d41 1
a41 1
__RCSID("$NetBSD: look.c,v 1.7 2001/11/14 06:16:09 tv Exp $");
@


1.7
log
@Pull in various changes from OpenBSD, most from Marc Espie, including:
* Provide some GNUisms as extensions.
* Provide dynamically growable string space.
* Make define(defn(foo)) work correctly for builtins.
(The current version is supposed to be capable of satisfying autoconf.)

All still relevant NetBSD changes have been preserved in this version, and
formatting and style fixes have been applied in various places.

Thanks to Masao Uebayashi <uebayasi@@soum.co.jp> for pointing this out.
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
d41 1
a41 1
#ifndef lint
d45 1
a45 1
__RCSID("$NetBSD: look.c,v 1.6 1997/10/19 04:39:57 lukem Exp $");
@


1.6
log
@WARNSify, fix .Nm usage, getopt returns -1 not EOF, deprecate register
@
text
@d1 3
d45 1
a45 1
__RCSID("$NetBSD$");
d58 1
d66 1
a66 2

int
d68 1
a68 1
	char *name;
d70 1
a70 1
	unsigned long h = 0;
d73 1
a73 1
	return (h % HASHSIZE);
d81 1
a81 1
	char *name;
d84 1
d86 3
a88 2
	for (p = hashtab[hash(name)]; p != nil; p = p->nxtptr)
		if (STREQ(name, p->name))
d99 1
a99 1
	char *name;
d101 1
a101 1
	int h;
d106 2
a107 2
	p->nxtptr = hashtab[h];
	hashtab[h] = p;
d109 1
d117 3
a119 5
	if (!(p->type & STATIC)) {
		free((char *) p->name);
		if (p->defn != null)
			free((char *) p->defn);
	}
d128 1
a128 1
	char *name;
d131 1
a131 1
	int h;
d135 1
a135 1
	mp = hashtab[h];
d138 1
a138 1
		if (STREQ(mp->name, name)) {
d141 2
a142 2
				freent(hashtab[h]);
				hashtab[h] = mp;
@


1.5
log
@upgrade to 4.4-lite m4.  no local changes of note
@
text
@d37 1
d39 1
d41 3
d60 3
d65 1
a65 1
register char *name;
d67 1
a67 1
	register unsigned long h = 0;
d78 1
a78 1
char *name;
d80 1
a80 1
	register ndptr p;
d94 1
a94 1
char *name;
d96 1
a96 1
	register int h;
d109 1
a109 1
ndptr p;
d124 2
a125 2
char *name;
int all;
d127 2
a128 2
	register int h;
	register ndptr xp, tp, mp;
@


1.4
log
@latest m4 from ozan.  now does the right thing w/respect to sendmail
@
text
@d1 35
a35 5
/*  File   : look.c
    Author : Ozan Yigit
    Updated: 4 May 1992
    Purpose: Hash table for M4 
*/
d37 3
a39 2
#include "mdef.h"
#include "extr.h"
d41 5
a45 1
ndptr hashtab[HASHSIZE];
d47 7
a54 3
/*
 * hash - get a hash value for string s
 */
d57 1
a57 1
char *name;
d59 4
a62 6
        register unsigned long h = 0;

        while (*name)
                h = (h << 5) + h + *name++;

        return h % HASHSIZE;
d65 2
a66 2
/* 
 * lookup(name) - find name in the hash table
d68 4
a71 3
ndptr lookup(name)
    char *name;
    {
d75 4
a78 4
	    if (strcmp(name, p->name) == 0)
		break;
	return p;
    }
d80 3
a82 4
/*  
 * addent(name) - hash and create an entry in the hash table.
 * The new entry is added at the front of a hash bucket.
 * BEWARE: the type and defn fields are UNDEFINED.
d84 12
a95 12
ndptr addent(name)
    char *name;
    {
	register ndptr p, *h;

	p = (ndptr)malloc(sizeof *p);
	if (p == NULL) error("m4: no more memory.");
	h = &hashtab[hash(name)];
	p->name = strsave(name);
	p->defn = null;
	p->nxtptr = *h;
	*h = p;
d97 1
a97 1
    }
d99 11
d111 2
a112 2
/*  
 * addkywd(name, type) - stores a keyword in the hash table.
d114 30
a143 39
void addkywd(name, type)
    char *name;
    int type;
    {
	register ndptr p = addent(name);
	p->type = type | STATIC;
    }


/* 
 * remhash(name, all)
 * remove one entry (all==0) or all entries (all!=0) for a given name
 * from the hash table.  All hash table entries must have been obtained
 * from malloc(), so it is safe to free the records themselves.
 * However, the ->name and ->defn fields might point to storage which
 * was obtained from strsave() -- in which case they may be freed -- or
 * to static storage -- in which case they must not be freed.  If the
 * STATIC bit is set, the fields are not to be freed.
 */
void remhash(name, all)
    char *name;
    int all;
    {
	register ndptr p, *h;
	/*  h always points to the pointer to p  */

	h = &hashtab[hash(name)];
	while ((p = *h) != nil) {
	    if (strcmp(p->name, name) == 0) {
		*h = p->nxtptr;			/* delink this record */		
		if (!(p->type & STATIC)) {	/* free the name and defn */
		    free(p->name);		/* if they came from strsave */
		    if (p->defn != null) free(p->defn);
		}				/* otherwise leave them */
		free(p);			/* free the record itself */
		if (!all) return;		/* first occurrence has gone */
	    } else {
		h = &(p->nxtptr);
	    }
d145 1
a145 2
    }

@


1.3
log
@Add RCS identifiers, remove some completely useless RCS logs and patchkit
headers, and a few other insignificant changes.
@
text
@a6 4
#ifndef lint
static char rcsid[] = "$Id: $";
#endif /* not lint */

@


1.2
log
@baseline of new version of m4 supplied by Ozan Yigit, original author
of the broken m4 we had.  This is his stuff virgin + our Makefile.
@
text
@d7 4
@


1.1
log
@Initial revision
@
text
@d1 5
a5 35
/*
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Ozan Yigit.
 *
 * 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. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. 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.
 */
d7 2
a8 3
#ifndef lint
static char sccsid[] = "@@(#)look.c	5.3 (Berkeley) 2/26/91";
#endif /* not lint */
d10 1
a10 5
/*
 * look.c
 * Facility: m4 macro processor
 * by: oz
 */
a11 5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mdef.h"
#include "extr.h"
d14 1
a14 2
 *  hash - compute hash value using the proverbial
 *	   hashing function. Taken from K&R.
d16 3
a18 2
hash (name)
register char *name;
d20 6
a25 4
	register int h = 0;
	while (*name)
		h += *name++;
	return (h % HASHSIZE);
d28 2
a29 3
/*
 * lookup - find name in the hash table
 *
d32 2
a33 2
char *name;
{
d37 4
a40 4
		if (strcmp(name, p->name) == 0)
			break;
	return (p);
}
d42 4
a45 4
/*
 * addent - hash and create an entry in the hash
 *	    table. The new entry is added in front
 *	    of a hash bucket.
d48 11
a58 13
char *name;
{
	register int h;
	ndptr p;

	h = hash(name);
	if ((p = (ndptr) malloc(sizeof(struct ndblock))) != NULL) {
		p->nxtptr = hashtab[h];
		hashtab[h] = p;
		p->name = strdup(name);
	}
	else
		error("m4: no more memory.");
d60 1
a60 12
}

/*
 * remhash - remove an entry from the hashtable
 *
 */
remhash(name, all)
char *name;
int all;
{
	register int h;
	register ndptr xp, tp, mp;
a61 24
	h = hash(name);
	mp = hashtab[h];
	tp = nil;
	while (mp != nil) {
		if (strcmp(mp->name, name) == 0) {
			mp = mp->nxtptr;
			if (tp == nil) {
				freent(hashtab[h]);
				hashtab[h] = mp;
			}
			else {
				xp = tp->nxtptr;
				tp->nxtptr = mp;
				freent(xp);
			}
			if (!all)
				break;
		}
		else {
			tp = mp;
			mp = mp->nxtptr;
		}
	}
}
d63 2
a64 3
/*
 * freent - free a hashtable information block
 *
d66 39
a104 7
freent(p)
ndptr p;
{
	if (!(p->type & STATIC)) {
		free(p->name);
		if (p->defn != null)
			free(p->defn);
d106 1
a106 2
	free(p);
}
@


1.1.1.1
log
@initial import of 386bsd-0.1 sources
@
text
@@


1.1.1.2
log
@imported from 44lite2
@
text
@d2 2
a3 2
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
d6 1
a6 1
 * Ozan Yigit at York University.
d38 1
a38 1
static char sccsid[] = "@@(#)look.c	8.1 (Berkeley) 6/6/93";
a46 1
#include <sys/types.h>
d51 1
a51 2
#include "stdd.h"
#include "extern.h"
d53 5
a57 2
int
hash(name)
d60 1
a60 1
	register unsigned long h = 0;
d62 1
a62 1
		h = (h << 5) + h + *name++;
d67 2
a68 1
 * find name in the hash table
d70 1
a70 2
ndptr 
lookup(name)
d76 1
a76 1
		if (STREQ(name, p->name))
d82 3
a84 2
 * hash and create an entry in the hash table.
 * The new entry is added in front of a hash bucket.
d86 1
a86 2
ndptr 
addent(name)
d93 7
a99 4
	p = (ndptr) xalloc(sizeof(struct ndblock));
	p->nxtptr = hashtab[h];
	hashtab[h] = p;
	p->name = xstrdup(name);
a102 12
static void
freent(p)
ndptr p;
{
	if (!(p->type & STATIC)) {
		free((char *) p->name);
		if (p->defn != null)
			free((char *) p->defn);
	}
	free((char *) p);
}

d104 2
a105 1
 * remove an entry from the hashtable
a106 1
void
d118 1
a118 1
		if (STREQ(mp->name, name)) {
d138 16
@


1.1.1.3
log
@Import new m4 from OpenBSD.
@
text
@a0 2
/*	$OpenBSD: look.c,v 1.21 2009/10/14 17:23:17 sthen Exp $	*/

d16 5
a20 1
 * 3. Neither the name of the University nor the names of its contributors
d37 4
d47 1
a49 2
#include <stdint.h>
#include <stddef.h>
a50 1
#include <ohash.h>
d55 8
a62 45
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(s, u)
	size_t s;
	void *u 	UNUSED;
{
	void *storage = xalloc(s, "hash alloc");
	if (storage)
		memset(storage, 0, s);
	return storage;
}

void
hash_free(p, s, u)
	void *p;
	size_t s	UNUSED;
	void *u 	UNUSED;
{
	free(p);
}

void *
element_alloc(s, u)
	size_t s;
	void *u 	UNUSED;
{
	return xalloc(s, "element alloc");
}

void
init_macros()
{
	ohash_init(&macros, 10, &macro_info);
d69 2
a70 1
lookup(const char *name)
d72 1
a72 2
	return ohash_find(&macros, ohash_qlookup(&macros, name));
}
d74 4
a77 10
struct macro_definition *
lookup_macro_definition(const char *name)
{
	ndptr p;

	p = ohash_find(&macros, ohash_qlookup(&macros, name));
	if (p)
		return p->d;
	else
		return NULL;
d80 7
a86 2
static void 
setup_definition(struct macro_definition *d, const char *defn, const char *name)
d88 1
d91 16
a106 10
	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;
d108 1
a108 48
	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(&macros, name, &end);
	n = ohash_find(&macros, i);
	if (n == NULL) {
		n = ohash_create_entry(&macro_info, name, &end);
		ohash_insert(&macros, 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);
d111 3
d115 24
a138 11
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);
d140 3
a142 16
		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);
a145 66

void
macro_for_all(void (*f)(const char *, struct macro_definition *))
{
	ndptr n;
	unsigned int i;

	for (n = ohash_first(&macros, &i); n != NULL; 
	    n = ohash_next(&macros, &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(&macros, &i); p != NULL; 
		    p = ohash_next(&macros, &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;
}

@

