1987-03-10 11:49:39 +00:00
|
|
|
/* $Header$ */
|
1987-03-09 19:15:41 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*/
|
1987-01-06 15:16:53 +00:00
|
|
|
/* 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"
|
1987-02-05 14:58:24 +00:00
|
|
|
#include "line_prefix.h"
|
1987-01-06 15:16:53 +00:00
|
|
|
|
|
|
|
#ifdef DOBITS
|
|
|
|
char bits[128];
|
|
|
|
#endif
|
|
|
|
|
1990-01-23 15:25:21 +00:00
|
|
|
char _obuf[OBUFSIZE];
|
1990-02-12 11:47:50 +00:00
|
|
|
extern int do_preprocess;
|
1990-01-23 15:25:21 +00:00
|
|
|
|
1987-01-07 11:10:33 +00:00
|
|
|
Xflush()
|
|
|
|
{
|
1990-02-12 11:47:50 +00:00
|
|
|
if (do_preprocess) sys_write(STDOUT, _obuf, OBUFSIZE);
|
1987-01-07 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
1987-01-06 15:16:53 +00:00
|
|
|
preprocess(fn)
|
|
|
|
char *fn;
|
|
|
|
{
|
|
|
|
register int c;
|
|
|
|
register char *op = _obuf;
|
|
|
|
register char *ob = &_obuf[OBUFSIZE];
|
1987-03-02 08:50:08 +00:00
|
|
|
char Xbuf[256];
|
|
|
|
int lineno = 0;
|
1987-01-06 15:16:53 +00:00
|
|
|
extern char options[];
|
|
|
|
|
1990-02-12 11:47:50 +00:00
|
|
|
#define flush(X) (! do_preprocess || sys_write(STDOUT,_obuf,X))
|
1987-01-07 11:10:33 +00:00
|
|
|
#define echo(ch) if (op == ob) { Xflush(); op = _obuf; } *op++ = (ch);
|
1987-01-06 15:16:53 +00:00
|
|
|
#define newline() echo('\n')
|
|
|
|
|
1987-03-02 08:50:08 +00:00
|
|
|
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++);
|
|
|
|
}
|
|
|
|
}
|
1987-01-06 15:16:53 +00:00
|
|
|
for (;;) {
|
|
|
|
LineNumber++;
|
|
|
|
lineno++;
|
|
|
|
LoadChar(c);
|
|
|
|
while (c == '#') {
|
|
|
|
domacro();
|
|
|
|
lineno++;
|
|
|
|
newline();
|
|
|
|
LoadChar(c);
|
|
|
|
}
|
1987-01-12 14:21:14 +00:00
|
|
|
if (lineno != LineNumber || fn != FileName) {
|
1987-01-06 15:16:53 +00:00
|
|
|
fn = FileName;
|
|
|
|
lineno = LineNumber;
|
1987-01-12 14:21:14 +00:00
|
|
|
if (! options['P']) {
|
|
|
|
register char *p = Xbuf;
|
|
|
|
|
1987-02-05 14:58:24 +00:00
|
|
|
sprint(p, "%s %d \"%s\"\n",
|
|
|
|
LINE_PREFIX,
|
|
|
|
LineNumber,
|
|
|
|
FileName);
|
1987-01-12 14:21:14 +00:00
|
|
|
while (*p) {
|
|
|
|
echo(*p++);
|
|
|
|
}
|
1987-01-07 11:10:33 +00:00
|
|
|
}
|
1987-01-06 15:16:53 +00:00
|
|
|
}
|
|
|
|
for (;;) {
|
|
|
|
if (c & 0200) {
|
|
|
|
if (c == EOI) {
|
1989-10-12 11:16:02 +00:00
|
|
|
newline();
|
1987-01-06 15:16:53 +00:00
|
|
|
flush(op-_obuf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fatal("non-ascii character read");
|
|
|
|
}
|
|
|
|
if (c == '/') {
|
|
|
|
LoadChar(c);
|
|
|
|
if (c == '*') {
|
|
|
|
NoUnstack++;
|
|
|
|
if (options['C']) {
|
|
|
|
echo('/');
|
|
|
|
echo('*');
|
|
|
|
}
|
|
|
|
for (;;) {
|
|
|
|
LoadChar(c);
|
1987-03-05 11:07:16 +00:00
|
|
|
if (c == '\n') {
|
1987-01-06 15:16:53 +00:00
|
|
|
++LineNumber;
|
|
|
|
++lineno;
|
|
|
|
echo(c);
|
|
|
|
}
|
|
|
|
else if (c == EOI) {
|
1989-10-12 11:16:02 +00:00
|
|
|
newline();
|
1987-01-06 15:16:53 +00:00
|
|
|
flush(op - _obuf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (c == '*') {
|
1987-01-07 11:10:33 +00:00
|
|
|
if (options['C']) {
|
|
|
|
echo(c);
|
|
|
|
}
|
1987-01-06 15:16:53 +00:00
|
|
|
LoadChar(c);
|
|
|
|
if (c == '/') {
|
1987-01-07 11:10:33 +00:00
|
|
|
if (options['C']) {
|
|
|
|
echo(c);
|
|
|
|
}
|
|
|
|
break;
|
1987-01-06 15:16:53 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
PushBack();
|
|
|
|
}
|
|
|
|
}
|
1987-01-07 11:10:33 +00:00
|
|
|
else if (options['C']) {
|
|
|
|
echo(c);
|
|
|
|
}
|
1987-01-06 15:16:53 +00:00
|
|
|
}
|
|
|
|
NoUnstack--;
|
|
|
|
LoadChar(c);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
echo('/');
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
switch(class(c)) {
|
|
|
|
case STNL:
|
|
|
|
echo(c);
|
|
|
|
break;
|
|
|
|
case STSTR:
|
|
|
|
case STCHAR: {
|
|
|
|
register int stopc = c;
|
1987-08-20 16:00:18 +00:00
|
|
|
int escaped;
|
1987-01-06 15:16:53 +00:00
|
|
|
|
|
|
|
do {
|
1987-08-20 16:00:18 +00:00
|
|
|
|
|
|
|
escaped = 0;
|
1987-01-06 15:16:53 +00:00
|
|
|
echo(c);
|
|
|
|
LoadChar(c);
|
|
|
|
if (c == '\n') {
|
1987-02-03 23:28:09 +00:00
|
|
|
break;
|
1987-01-06 15:16:53 +00:00
|
|
|
}
|
|
|
|
else if (c == EOI) {
|
1989-10-12 11:16:02 +00:00
|
|
|
newline();
|
1987-01-06 15:16:53 +00:00
|
|
|
flush(op-_obuf);
|
|
|
|
return;
|
|
|
|
}
|
1987-02-03 23:28:09 +00:00
|
|
|
if (c == '\\') {
|
|
|
|
echo(c);
|
|
|
|
LoadChar(c);
|
|
|
|
if (c == '\n') {
|
|
|
|
++LineNumber;
|
|
|
|
lineno++;
|
|
|
|
}
|
1990-08-10 17:57:32 +00:00
|
|
|
else escaped = 1;
|
1987-02-03 23:28:09 +00:00
|
|
|
}
|
1989-10-12 11:16:02 +00:00
|
|
|
} while (escaped || c != stopc);
|
1987-01-06 15:16:53 +00:00
|
|
|
echo(c);
|
1987-07-24 09:21:24 +00:00
|
|
|
if (c == '\n')
|
|
|
|
break; /* Don't eat # */
|
1987-01-06 15:16:53 +00:00
|
|
|
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;
|
|
|
|
}
|
1990-02-14 11:57:41 +00:00
|
|
|
else break;
|
1987-01-06 15:16:53 +00:00
|
|
|
load;
|
|
|
|
}
|
|
|
|
endidf:
|
|
|
|
PushBack();
|
|
|
|
*tg = '\0'; /* mark the end of the identifier */
|
|
|
|
idef = findidf(buf);
|
1990-02-14 11:57:41 +00:00
|
|
|
if (idef && idef->id_macro) {
|
|
|
|
do {
|
|
|
|
LoadChar(c);
|
|
|
|
} while (in_idf(c));
|
|
|
|
PushBack();
|
|
|
|
if (replace(idef)) {
|
|
|
|
LoadChar(c);
|
|
|
|
continue;
|
|
|
|
}
|
1987-01-06 15:16:53 +00:00
|
|
|
}
|
|
|
|
nomac:
|
|
|
|
*tg = 0;
|
|
|
|
tg = buf;
|
1987-01-07 11:10:33 +00:00
|
|
|
while (*tg) {
|
|
|
|
echo(*tg++);
|
|
|
|
}
|
1987-01-06 15:16:53 +00:00
|
|
|
LoadChar(c);
|
|
|
|
while (in_idf(c)) {
|
|
|
|
echo(c);
|
|
|
|
LoadChar(c);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
echo(c);
|
|
|
|
LoadChar(c);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|