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

/*
 * C preprocessor.
 * Read next character.
 */
#include <time.h>
#ifdef   vax
#include "INC$LIB:cc0.h"
#else
#include "cc0.h"
#endif

/*
 * Look ahead for '#' or '(',
 * and restore the stream if you fail.
 * This gets reentered looking for '#'
 * when the search for a '(' passes newline.
 */
skipto(d) int d;
{
	register char *p, *sp;
	register int c;
	sp = dpshp;
	while ((c = get()) >= 0 && ct[c] == SKIP)
		dpshc(c);
	if (c >= 0)
		dpshc(c);
	if (c != d) {
		for (p = dpshp; p < sp; ++p)
			unget(*p);
		dpshp = sp;
		return 0;
	}
	dpshp = sp;
	return 1;
}

/*
 * Look at a newly opened file.
 */
emptyfilep()
{
	int c;
	c = getc(ifp);
	if (c == EOF) {
		c = '\n';
	}
	ungetc(c, ifp);
}

/*
 * Get a character.
 * This function returns the next character,
 * and implements one character pushback,
 * as well as the expanded macro stack.
 */
get()
{
    register int c;

    for (;;) {
	switch (dstackp->ds_type) {

	case DS_FUNGET:	/* Ungotten character from file */
		c = (dstackp++)->ds_char & 0377;
		goto file_char;

	case DS_FILE:	/* Read next character from source file */
		while ((c = getc(ifp)) < 0) {		/* Pop include stack */
 eof:			fclose(ifp);
			if (lastchar != '\n' && lastchar != EOF)
 eof_in_line:			cfatal("EOF in midline");
			if (istackp < istack+NLEV) {
				if (cstackp != istackp->i_cstackp)
					cerror("missing #endif");
				cstackp = istackp->i_cstackp;
				line = istackp->i_line;
				if (notvariant(VCPP)) {
					bput(LINE);
					iput((ival_t)line);
				}
				idp = istackp->i_file;
				setfname();
				ifp = istackp->i_fp;
				++istackp;
				continue;
			}
			if (cstackp < cstack+NLEV)
				cerror("missing #endif");
			cstackp = cstack + NLEV;
			lastchar = c;
			return c;			/* ie, EOF */
		}
  file_char:	lastchar = c;
		switch (ct[c]) {

		case SKIP:		/* New line? */
#if GEMDOS || MSDOS			/* Assuming use of bingetc() */
			if (c == '\r')
				continue;
#endif
			if (c == '\n') {
				if (incpp) {
				    ungetc(c, ifp);
				    return EOF;
				}
				if (instring) {
				    cerror("new line in %s literal",
				      instring=='"' ? "string" : "character");
				    ++line;
				    c = ' ';
				} else
				    notskip = 0;
			}
			notskip -= 1;
			break;

		case QUEST:		/* Trigraph? */
			if (notvariant(V3GRAPH))
				break;
			if ((c = getc(ifp)) < 0)
				goto eof_in_line;
			if (c != '?') {
				ungetc(c, ifp);
				c = '?';
				break;
			}
			if ((c = getc(ifp)) < 0)
				goto eof_in_line;
			switch (c) {
			case '=': ungetc('#', ifp); continue;
			case '(': ungetc('[', ifp); continue;
			case '/': ungetc('\\', ifp); continue;
			case ')': ungetc(']', ifp); continue;
			case '\'': ungetc('^', ifp); continue;
			case '<': ungetc('{', ifp); continue;
			case '!': ungetc('|', ifp); continue;
			case '>': ungetc('}', ifp); continue;
			case '-': ungetc('~', ifp); continue;
			default:
				ungetc(c, ifp);
				dspushc(DS_FUNGET, '?');
				c = '?';
			}
			break;

		case DIV:		/* Comment? */
			if (instring)
				break;
			if ((c = getc(ifp))< 0)
				goto eof_in_line;
			if (c != '*') {
				ungetc(c, ifp);
				c = '/';
				break;
			}
			for (;;) {
				if ((c = getc(ifp)) < 0)
 eof_in_comment:			cfatal("EOF in comment");
				if (c == '*') {
					if ((c = getc(ifp)) < 0)
						goto eof_in_comment;
					if (c == '/')
						break;
					ungetc(c, ifp);
				} else if (c == '/') {
					if ((c = getc(ifp)) < 0)
						goto eof_in_comment;
					if (c == '*')
						cwarn("nested comments");
					ungetc(c, ifp);
				} else if (c == '\n')
					++line;
			}
			c = ' ';
			break;

		case BACKDIV:		/* Splice? */
 try_again:		if ((c = getc(ifp)) < 0)
				goto eof_in_line;
			if (c != '\n') {
#if GEMDOS || MSDOS			/* Assuming use of bingetc() */
				if (c == '\r')
					goto try_again;
#endif
				ungetc(c, ifp);
				c = '\\';
				break;
			}
			++line;
			continue;

		case HIGH0:
		case HIGH1:
		case HIGH2:
		case HIGH3:
		case JUNK:
#if GEMDOS || MSDOS			/* Assuming use of bingetc() */
			if (c == 26)	/* ^Z */
				goto eof;
#endif
			if (instring || (c > ' ' && c < 0177))
				break;
			cerror("illegal cpp character (%d decimal)", c);
			continue;

		case SHARP:
			if (notskip != 0)
				break;
			++incpp;
			control();
			--incpp;
			continue;
		}
		notskip += 1;
		break;

	case DS_UNGET:	/* Read ungotten character */
		c = (dstackp++)->ds_char & 0377;
		break;

	case DS_STRNG:
		if ((c = *dstackp->ds_ptr++ & 0377) == 0) {
			++dstackp;
			continue;
		}
		break;

	case DS_UFILE:	/* Convert file name into string */
		if ((c = *dstackp->ds_ptr++ & 0377) == 0) {
			++dstackp;
			continue;
		}
		if (c == '\\' || c == '"') {
			unget(c);
			c = '\\';
		}
		break;

	case DS_SHARP:	/* Read and stringize */
		if ((c = *dstackp->ds_ptr++ & 0377) == 0) {
			++dstackp;
			continue;
		}
		if (dstackp->ds_char) {
			if (c == dstackp->ds_char) {
				dstackp->ds_char = 0;
				if (c == '"') {
					unget(c);
					c = '\\';
				}
			} else if (c == '\\') {
				c = *dstackp->ds_ptr++;
				unget(c);
				if (c == '"')
					unget('\\');
				unget('\\');
				c = '\\';
			}
		} else if (c == '"') {
			dstackp->ds_char = c;
			unget(c);
			c = '\\';
		} else if (c == '\'')
			dstackp->ds_char = c;
		else if (c >= SET0)
			continue;
		break;

	case DS_DPUTP:
		dputp = (dstackp++)->ds_ptr;
		continue;

	case DS_NAME:
		++dstackp;
		continue;

	case DS_IEOF:
		c = EOF;
		break;

	default:
		cbotch("bad ds_type %d", dstackp->ds_type);
	}
	if (c == '\n') ++line;
	if (cstate != 0 && incpp == 0)
		continue;
	return c;
    }
}

/*
 * One character pushback
 * for the callers of get().
 */
unget(c) int c;
{
	if (c < 0)
		return;
	dspushc(DS_UNGET, c);
	if (c == '\n')
		--line;
}


unix.superglobalmegacorp.com

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