ack/util/cpp/preprocess.c

251 lines
4.5 KiB
C
Raw Normal View History

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 "maxincl.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
char _obuf[OBUFSIZE];
#ifdef DOBITS
char bits[128];
#endif
1987-01-07 11:10:33 +00:00
Xflush()
{
sys_write(STDOUT, _obuf, OBUFSIZE);
}
1987-01-06 15:16:53 +00:00
preprocess(fn)
char *fn;
{
register int c;
register char *op = _obuf;
register char *ob = &_obuf[OBUFSIZE];
char Xbuf[256];
int lineno = 0;
1987-01-06 15:16:53 +00:00
extern char options[];
1987-01-07 11:10:33 +00:00
#define flush(X) (sys_write(STDOUT,_obuf,X))
#define echo(ch) if (op == ob) { Xflush(); op = _obuf; } *op++ = (ch);
1987-01-06 15:16:53 +00:00
#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++);
}
}
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) {
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') {
1987-01-06 15:16:53 +00:00
++LineNumber;
++lineno;
echo(c);
}
else if (c == EOI) {
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;
do {
echo(c);
LoadChar(c);
if (c == '\n') {
++LineNumber;
lineno++;
break;
1987-01-06 15:16:53 +00:00
}
else if (c == EOI) {
flush(op-_obuf);
return;
}
if (c == '\\') {
echo(c);
LoadChar(c);
if (c == '\n') {
++LineNumber;
lineno++;
}
}
1987-01-06 15:16:53 +00:00
}
while (c != stopc);
echo(c);
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;
}
load;
}
endidf:
PushBack();
*tg = '\0'; /* mark the end of the identifier */
idef = findidf(buf);
if ((idef && idef->id_macro && replace(idef))) {
LoadChar(c);
continue;
}
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*/
}