264 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			264 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* $Id$ */
 | 
						|
/*
 | 
						|
 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | 
						|
 * See the copyright notice in the ACK home directory, in the file "Copyright".
 | 
						|
 */
 | 
						|
/* PREPROCESSOR DRIVER */
 | 
						|
 | 
						|
#include <system.h>
 | 
						|
#include "input.h"
 | 
						|
#include "obufsize.h"
 | 
						|
#include "LLlex.h"
 | 
						|
#include "class.h"
 | 
						|
#include "idf.h"
 | 
						|
#include "idfsize.h"
 | 
						|
#include "bits.h"
 | 
						|
#include "line_prefix.h"
 | 
						|
 | 
						|
#ifdef DOBITS
 | 
						|
char bits[128];
 | 
						|
#endif
 | 
						|
 | 
						|
char _obuf[OBUFSIZE];
 | 
						|
extern int do_preprocess;
 | 
						|
 | 
						|
Xflush()
 | 
						|
{
 | 
						|
	if (do_preprocess) sys_write(STDOUT, _obuf, OBUFSIZE);
 | 
						|
}
 | 
						|
 | 
						|
preprocess(fn)
 | 
						|
	char *fn;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
	register char *op = _obuf;
 | 
						|
	register char *ob = &_obuf[OBUFSIZE];
 | 
						|
	char Xbuf[256];
 | 
						|
	int lineno = 0;
 | 
						|
	extern char options[];
 | 
						|
 | 
						|
#define flush(X)	(! do_preprocess || sys_write(STDOUT,_obuf,X))
 | 
						|
#define echo(ch) 	if (op == ob) { Xflush(); op = _obuf; } *op++ = (ch);
 | 
						|
#define newline()	echo('\n')
 | 
						|
 | 
						|
	if (! options['P']) {
 | 
						|
		/* Generate a line directive communicating the
 | 
						|
		   source filename
 | 
						|
		*/
 | 
						|
		register char *p = Xbuf;
 | 
						|
 | 
						|
		sprint(p, "%s 1 \"%s\"\n",
 | 
						|
			LINE_PREFIX,
 | 
						|
			FileName);
 | 
						|
		while (*p) {
 | 
						|
			echo(*p++);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	for (;;) {
 | 
						|
		LineNumber++;
 | 
						|
		lineno++;
 | 
						|
		LoadChar(c);
 | 
						|
		while (c == '#') {
 | 
						|
			domacro();
 | 
						|
			lineno++;
 | 
						|
			newline();
 | 
						|
			LoadChar(c);
 | 
						|
		}
 | 
						|
		if (lineno != LineNumber || fn != FileName) {
 | 
						|
			fn = FileName;
 | 
						|
			lineno = LineNumber;
 | 
						|
			if (! options['P']) {
 | 
						|
				register char *p = Xbuf;
 | 
						|
 | 
						|
				sprint(p, "%s %d \"%s\"\n",
 | 
						|
					LINE_PREFIX,
 | 
						|
					LineNumber,
 | 
						|
					FileName);
 | 
						|
				while (*p) {
 | 
						|
					echo(*p++);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		for (;;) {
 | 
						|
			if (c & 0200)  {
 | 
						|
				if (c == EOI) {
 | 
						|
					newline();
 | 
						|
					flush(op-_obuf);
 | 
						|
					return;
 | 
						|
				}
 | 
						|
				fatal("non-ascii character read");
 | 
						|
			}
 | 
						|
			if (c == '/') {
 | 
						|
				LoadChar(c);
 | 
						|
				if (c == '*') {
 | 
						|
					NoUnstack++;
 | 
						|
					if (options['C']) {
 | 
						|
						echo('/');
 | 
						|
						echo('*');
 | 
						|
					}
 | 
						|
					for (;;) {
 | 
						|
						LoadChar(c);
 | 
						|
						if (c == '\n') {
 | 
						|
							++LineNumber;
 | 
						|
							++lineno;
 | 
						|
							echo(c);
 | 
						|
						}
 | 
						|
						else if (c == EOI) {
 | 
						|
							newline();
 | 
						|
							flush(op - _obuf);
 | 
						|
							return;
 | 
						|
						}
 | 
						|
						else if (c == '*') {
 | 
						|
							if (options['C']) {
 | 
						|
								echo(c);
 | 
						|
							}
 | 
						|
							LoadChar(c);
 | 
						|
							if (c == '/') {
 | 
						|
							   if (options['C']) {
 | 
						|
								echo(c);
 | 
						|
							   }
 | 
						|
							   break;
 | 
						|
							}
 | 
						|
							else {
 | 
						|
								PushBack();
 | 
						|
							}
 | 
						|
						}
 | 
						|
						else if (options['C']) {
 | 
						|
							echo(c);
 | 
						|
						}
 | 
						|
					}
 | 
						|
					NoUnstack--;
 | 
						|
					LoadChar(c);
 | 
						|
					continue;
 | 
						|
				}
 | 
						|
				echo('/');
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
			switch(class(c)) {
 | 
						|
			case STNL:
 | 
						|
				echo(c);
 | 
						|
				break;
 | 
						|
			case STSTR:
 | 
						|
			case STCHAR: {
 | 
						|
				register int stopc = c;
 | 
						|
				int escaped;
 | 
						|
	
 | 
						|
				do {
 | 
						|
 | 
						|
					escaped = 0;
 | 
						|
					echo(c);
 | 
						|
					LoadChar(c);
 | 
						|
					if (c == '\n') {
 | 
						|
						break;
 | 
						|
					}
 | 
						|
					else if (c == EOI) {
 | 
						|
						newline();
 | 
						|
						flush(op-_obuf);
 | 
						|
						return;
 | 
						|
					}
 | 
						|
					if (c == '\\') {
 | 
						|
						echo(c);
 | 
						|
						LoadChar(c);
 | 
						|
						if (c == '\n') {
 | 
						|
							++LineNumber;
 | 
						|
							lineno++;
 | 
						|
						}
 | 
						|
						else escaped = 1;
 | 
						|
					}
 | 
						|
				} while (escaped || c != stopc);
 | 
						|
				echo(c);
 | 
						|
				if (c == '\n')
 | 
						|
					break;	/* Don't eat # */
 | 
						|
				LoadChar(c);
 | 
						|
				continue;
 | 
						|
				}
 | 
						|
			case STNUM:
 | 
						|
#define getdec(c)	do { echo(c); LoadChar(c);} while (is_dig(c))
 | 
						|
#define gethex(c)	do { echo(c); LoadChar(c);} while (is_hex(c))
 | 
						|
 | 
						|
				if (c != '0') {
 | 
						|
					getdec(c);
 | 
						|
					if (c == '.') getdec(c);
 | 
						|
					if (c == 'e') {
 | 
						|
						echo(c);
 | 
						|
						LoadChar(c);
 | 
						|
						if (c == '+' || c == '-') {
 | 
						|
							echo(c);
 | 
						|
							LoadChar(c);
 | 
						|
						}
 | 
						|
						if (is_dig(c)) getdec(c);
 | 
						|
					}
 | 
						|
				}
 | 
						|
				else {
 | 
						|
					echo(c);
 | 
						|
					LoadChar(c);
 | 
						|
					if (c == 'x' || c == 'X') gethex(c);
 | 
						|
					else if (is_dig(c)) getdec(c);
 | 
						|
				}
 | 
						|
				continue;
 | 
						|
			    case STIDF: {
 | 
						|
				extern int idfsize;		/* ??? */
 | 
						|
				char buf[IDFSIZE + 1];
 | 
						|
				register char *tg = &buf[0];
 | 
						|
				register char *maxpos = &buf[idfsize];
 | 
						|
				register struct idf *idef;
 | 
						|
 | 
						|
#define tstmac(bx)	if (!(bits[c] & bx)) goto nomac
 | 
						|
#define cpy		if (Unstacked) EnableMacros(); *tg++ = c
 | 
						|
#define load		LoadChar(c); if (!in_idf(c)) goto endidf
 | 
						|
 | 
						|
#ifdef DOBITS
 | 
						|
				cpy; tstmac(bit0); load;
 | 
						|
				cpy; tstmac(bit1); load;
 | 
						|
				cpy; tstmac(bit2); load;
 | 
						|
				cpy; tstmac(bit3); load;
 | 
						|
				cpy; tstmac(bit4); load;
 | 
						|
				cpy; tstmac(bit5); load;
 | 
						|
				cpy; tstmac(bit6); load;
 | 
						|
				cpy; tstmac(bit7); load;
 | 
						|
#endif
 | 
						|
 | 
						|
				for(;;) {
 | 
						|
					if (tg < maxpos) {
 | 
						|
						cpy;
 | 
						|
					}
 | 
						|
					else break;
 | 
						|
					load;
 | 
						|
				}
 | 
						|
			endidf:
 | 
						|
				PushBack();
 | 
						|
				*tg = '\0';	/* mark the end of the identifier */
 | 
						|
				idef = findidf(buf);
 | 
						|
				if (idef && idef->id_macro) {
 | 
						|
					do {
 | 
						|
						LoadChar(c);
 | 
						|
					} while  (in_idf(c));
 | 
						|
					PushBack();
 | 
						|
					if (replace(idef)) {
 | 
						|
						LoadChar(c);
 | 
						|
						continue;
 | 
						|
					}
 | 
						|
				}
 | 
						|
			nomac:
 | 
						|
				*tg = 0;
 | 
						|
				tg = buf;
 | 
						|
				while (*tg) {
 | 
						|
					echo(*tg++);
 | 
						|
				}
 | 
						|
				LoadChar(c);
 | 
						|
				while (in_idf(c)) {
 | 
						|
					echo(c);
 | 
						|
					LoadChar(c);
 | 
						|
				}
 | 
						|
				continue;
 | 
						|
				}
 | 
						|
			    default:
 | 
						|
			    	echo(c);
 | 
						|
			    	LoadChar(c);
 | 
						|
			    	continue;
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	/*NOTREACHED*/
 | 
						|
}
 |