File:  [MW Coherent from dump] / coherent / b / bin / c / n0 / cpp.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:37 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * n0/cpp.c
 * C preprocessor.
 * This version of cpp runs as a module of cc0.
 */

#ifdef   vax
#include "INC$LIB:cc0.h"
#else
#include "cc0.h"
#endif

/*
 * Low-level functions and macros.
 */

/*
 * Stash characters into the 'dbuf'
 * where most things are being accumulated.
 */

dputc(c) int c;
{
	if (dputp < dpshp)
		*dputp++ = c;
	else
		dfull("dput");
}
dpshc(c) int c;
{
	if (--dpshp > dputp)
		*dpshp = c;
	else
		dfull("dpsh");
}
dspush(t, p) int t; char *p;
{
	if (--dstackp > dlistp) {
		dstackp->ds_type = t;
		dstackp->ds_char = 0;
		dstackp->ds_ptr = p;
	} else
		dfull("dspush");
}
dspushc(t, c) int t, c;
{
	if (--dstackp > dlistp) {
		dstackp->ds_type = t;
		dstackp->ds_char = c;
		dstackp->ds_ptr = 0;
	} else
		dfull("dspushc");
}
dslist(t, p) int t; char *p;
{
	if (dlistp < dstackp) {
		dlistp->ds_type = t;
		dlistp->ds_char = 0;
		(dlistp++)->ds_ptr = p;
	} else
		dfull("dslist");
}
dslistc(t, c) int t, c;
{
	if (dlistp < dstackp) {
		dlistp->ds_type = t;
		dlistp->ds_char = c;
		(dlistp++)->ds_ptr = 0;
	} else
		dfull("dslistc");
}

dfull(where) char *where;
{
	cfatal("macro expansion buffer overflow in %s", where);
}

dputs(p) register char *p;
{
	register int c;

	while (c = *p++) dputc(c);
}

dpshs(p) register char *p;
{
	register int c;

	while (c = *p++) dpshc(c);
}

dputstr(d) register int d;
{
	register int c;
	instring = c = d;
	for (;;) {
		dputc(c);
		if ((c = get()) < 0 || c == '\n' || c == d)
			break;
		if (c == '\\') {
			dputc(c);
			if ((c = get()) < 0 || c == '\n') {
				dputc(' ');
				break;
			}
		}
	}
	dputc(d);
	instring = 0;
	return c;
}

dpshstr(d) register int d;
{
	register int c;
	instring = c = d;
	for (;;) {
		dpshc(c);
		if ((c = get()) < 0 || c == '\n' || c == d)
			break;
		if (c == '\\') {
			dpshc(c);
			if ((c = get()) < 0 || c == '\n') {
				dpshc(' ');
				break;
			}
		}
	}
	dpshc(d);
	instring = 0;
	return c;
}

dputnum(c) register int c;
{
	++incpp;
	if (c == '.') {
		unget(c = get());
		if (c < 0 || ct[c] != CON) {
			dputc('.');
			--incpp;
			return;
		}
		getnum(get(), 1);
	} else
		getnum(c, 0);
	dputs(id);
	--incpp;
}

dpshnum(c) register int c;
{
	++incpp;
	if (c == '.') {
		unget(c = get());
		if (c < 0 || ct[c] != CON) {
			dpshc('.');
			--incpp;
			return;
		}
		getnum(get(), 1);
	} else
		getnum(c, 0);
	dpshs(id);
	--incpp;
}

/*
 * Hide set handling.
 */

#if	OVERLAID
/* For the OVERLAID compiler, keep a list of malloc'ed HIDESETs to free. */
typedef	struct	hidelist {
	struct hidelist	*h_hlp;
	HIDESET		*h_hsp;
} HIDELIST;
static HIDELIST *hidelist;

/*
 * Release hide sets.
 * More bother than it's worth, but tidy.
 */
freehide()
{
	register HIDELIST *hp;

	while ((hp = hidelist) != NULL) {
		hidelist = hp->h_hlp;
		free(hp->h_hsp);
		free(hp);
	}
	hidefree = hidesets = NULL;
}

#endif

/* Allocate a new hide set element */
HIDESET *newhide()
{
	register HIDESET *hp;
	register HIDEMEM *mp;
	register int n;
#if	OVERLAID
	register HIDELIST *hlp;
#endif

	if ((hp = hidefree) == NULL) {
		n = 8;
		hidefree = hp = new(n*sizeof(HIDESET));
#if	OVERLAID
		hlp = (HIDELIST *)new(sizeof(HIDELIST));
		hlp->h_hlp = hidelist;
		hlp->h_hsp = hp;
		hidelist = hlp;
#endif
		while (--n > 0) {
			hp->h_next_set = hp+1;
			hp->h_this_set = NULL;
			hp += 1;
		}
		hp->h_next_set = NULL;
		hp->h_this_set = NULL;
		hp = hidefree;
	}
	if ((mp = hp->h_this_set) == NULL) {
		hidefree = hp->h_next_set;
		hp->h_next_set = NULL;
		return hp;
	}
	hp->h_this_set = mp->h_next_mem;
	mp->h_this_mem = NULL;
	mp->h_next_mem = NULL;
	return mp;
}

/* return the HIDESET corresponding to index x */
HIDEMEM *hideget(x) register int x;
{
	register HIDESET *hp;

	if ((x -= SET0) == 0)
		return NULL;
	for (hp = hidesets; --x > 0; hp = hp->h_next_set)
		if (hp == NULL)
			cbotch("impossible hide set");
	return hp->h_this_set;
}

/* Compare hidesets for equality */
hideeq(mp1, mp2) register HIDEMEM *mp1, *mp2;
{
	for (;;) {
		if (mp1 == NULL)
			if (mp2 == NULL)
				return 1;
			else
				return 0;
		else if (mp2 == NULL)
			return 0;
		else if (mp1->h_this_mem != mp2->h_this_mem)
			return 0;
		mp1 = mp1->h_next_mem;
		mp2 = mp2->h_next_mem;
	}
}

/* Enter a hideset into the universe and return its index */
hideent(mp) HIDEMEM *mp;
{
	register HIDESET **hpp, *hp;
	register int x;
	HIDESET *tp;

	tp = hp = newhide();
	hp->h_this_set = mp;
	x = SET0;
	hpp = &hidesets;
	while ((hp = *hpp) != NULL) {
		++x;
		if (hideeq(hp->h_this_set, mp)) {
			hp = tp;
			hp->h_next_set = hidefree;
			hidefree = hp;
			return x;
		}
		hpp = &hp->h_next_set;
	}
	++x;
	*hpp = tp;
	return x;
}

HIDEMEM *hideapp(mp1, tp) HIDEMEM *mp1; TOK *tp;
{
	register HIDEMEM **mp;
	for (mp = &mp1; *mp != NULL; mp = &((*mp)->h_next_mem))
		;
	*mp = newhide();
	(*mp)->h_this_mem = tp;
	return mp1;
}

/* Return true if the current id[] is hidden */
hidden()
{
	register HIDEMEM *mp;

	for (mp = hideget(idhide); mp != NULL; mp = mp->h_next_mem)
		if (idp == mp->h_this_mem)
			return 1;
	return 0;
}

/* Return the intersection of s1 and s2 */
hideint(s1, s2) int s1, s2;
{
	register HIDEMEM *mp1, *mp2, *mp3;
	if (s1 == SET0)
		return s1;
	if (s2 == SET0)
		return s2;
	if (s1 == -1) {
		return s2;
	}
	if (s2 == -1)
		return s1;
	if (s1 == s2)
		return s1;
	mp1 = hideget(s1);
	mp2 = hideget(s2);
	mp3 = NULL;
	while (mp1 != NULL && mp2 != NULL) {
		if (mp1->h_this_mem == mp2->h_this_mem) {
			mp3 = hideapp(mp3, mp1->h_this_mem);
			mp1 = mp1->h_next_mem;
			mp2 = mp2->h_next_mem;
			continue;
		}
		if (mp1->h_this_mem < mp2->h_this_mem) {
			mp1 = mp1->h_next_mem;
			continue;
		}
		if (mp2->h_this_mem < mp1->h_this_mem) {
			mp2 = mp2->h_next_mem;
			continue;
		}
	}
	return hideent(mp3);
}

/* Return the union of s1 and s2 */
hideaug(s1, s2) int s1, s2;
{
	register HIDEMEM *mp1, *mp2, *mp3;
	if (s1 == SET0)
		return s2;
	if (s2 == SET0)
		return s1;
	mp1 = hideget(s1);
	mp2 = hideget(s2);
	mp3 = NULL;
	while (mp1 != NULL || mp2 != NULL) {
		if (mp1 == NULL) {
			mp3 = hideapp(mp3, mp2->h_this_mem);
			mp2 = mp2->h_next_mem;
			continue;
		}
		if (mp2 == NULL) {
			mp3 = hideapp(mp3, mp1->h_this_mem);
			mp1 = mp1->h_next_mem;
			continue;
		}
		if (mp1->h_this_mem == mp2->h_this_mem) {
			mp3 = hideapp(mp3, mp1->h_this_mem);
			mp1 = mp1->h_next_mem;
			mp2 = mp2->h_next_mem;
			continue;
		}
		if (mp1->h_this_mem < mp2->h_this_mem) {
			mp3 = hideapp(mp3, mp1->h_this_mem);
			mp1 = mp1->h_next_mem;
			continue;
		}
		if (mp2->h_this_mem < mp1->h_this_mem) {
			mp3 = hideapp(mp3, mp2->h_this_mem);
			mp2 = mp2->h_next_mem;
			continue;
		}
	}
	return hideent(mp3);
}

/* Return the hide set for tp */
hideset(tp) register TOK *tp;
{
	/* Determine if we are at source file level */
	{
		register DSTACK *dsp;
		for (dsp = dstackp; dsp < dstack+NDLEV; dsp += 1)
			if (dsp->ds_type == DS_NAME)
				goto part2;
	}
	/* Release the previous hide set universe */
	if (hidesets != NULL) {
		register HIDESET **pp, *hp;
		for (pp = &hidesets; (hp = *pp) != NULL; pp = &hp->h_next_set)
			;
		*pp = hidefree;
		hidefree = hidesets;
		hidesets = NULL;
	}
 part2:	return hideent(hideapp(NULL, tp));
}

/*
 * The following four functions are called from cc0 main().
 */

/*
 * Install a new symbol with given value.
 *	-Dname=value
 */
cppd(name, value) char *name, *value;
{
	register CPPSYM *sp;

	setid(name);
	sp = newcpp(-1, value, strlen(value)+1);
	sp->s_sp = idp->t_sym;
	idp->t_sym = sp;
}

/*
 * Undefine a cpp symbol.
 *	-Uname
 */
cppu(name) char *name;
{
	setid(name);
	undefine();
}

/*
 * Add a directory to the list to be searched for include files.
 *	-Ipath
 */
cppi(path) char *path;
{
	if (ndirs >= NDIRS)
		cfatal("too many directories in include list");
	incdirs[ndirs++] = path;
}

/*
 * cpp loop for generating
 * preprocessed text files.
 *	isvariant(VCPP) != 0
 */
cppwork()
{
	register int c, d;
	register char *p;
	register int myline;
	register char *myfile;

	myfile = file;
	myline = line;
	while ((c = get()) >= 0) {
		switch (ct[c]) {

		case DIV:
			putc(c, ofp);
			if (notvariant(VCPPC))
				continue;
			/*
			 * Watch out for comments in cpp -C mode,
			 * single and double quotes otherwise cause problems.
			 */
			if ((c = get()) >= 0
			 && (c == '*' || isvariant(VCPLUS) && c == '/')) {
				putc(c, ofp);
				if (c == '*') {
					/* Copy normal C-style comment. */
					while ((c = getc(ifp)) >= 0) {
						putc(c, ofp);
						if (c != '*')
							continue;
						if ((c = getc(ifp)) >= 0) {
							putc(c, ofp);
							if (c != '/')
								continue;
							break;
						}
					}
				} else {
					/* Copy //-delimited C++ online comment. */
					while ((c = getc(ifp)) >= 0 && c != '\n')
						putc(c, ofp);
					if (c == '\n')
						ungetc(c, ifp);
				}
			} else
				ungetc(c, ifp);
			continue;

		case ID:
			if (expand(c))
				continue;
			for (p = id; c = *p++; putc(c, ofp));
			continue;

		case QUOTE:
		case STRING:
			putc(c, ofp);
			instring = c;
			while ((d = get()) >= 0 && d != c) {
				putc(d, ofp);
				if (d == '\\')
					putc(get(), ofp);
			}
			instring = 0;
			if (d < 0)
				cerror("EOF in string");
			else
				putc(d, ofp);
			continue;

		default:
			putc(c, ofp);
			if (c != '\n')
				continue;
			if (myfile != file) {
				myfile = file;
				myline = line;
				continue;
			}
			if (++myline == line)
				continue;
			myline = line;
			if (notvariant(VCPPE))
				fprintf(ofp, "#line %d\n", line);
			continue;
		}
	}
}

/* end of n0/cpp.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.