123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* $Id$ */
- /* PREPROCESSOR DRIVER */
- #include <stdlib.h>
- #include <stdio.h>
- #include <system.h>
- #include <alloc.h>
- #include "input.h"
- #include "obufsize.h"
- #include "arith.h"
- #include "LLlex.h"
- #include "class.h"
- #include "macro.h"
- #include "idf.h"
- #include "idfsize.h"
- #include "bits.h"
- #include "ln_prefix.h"
- #include "textsize.h"
- char _obuf[OBUFSIZE];
- #ifdef DOBITS
- char bits[128];
- #endif
- extern int InputLevel;
- extern char *sprint();
- void Xflush()
- {
- sys_write(STDOUT, _obuf, OBUFSIZE);
- }
- extern char options[];
- /* #pragma directives are saved here and passed to the compiler later on.
- */
- struct prag_info {
- int pr_linnr;
- char *pr_fil;
- char *pr_text;
- };
- static struct prag_info *pragma_tab;
- static int pragma_nr;
- static char *SkipComment(char *op, int *lineno);
- void preprocess(char *fn);
- void do_pragma()
- {
- int size = ITEXTSIZE;
- char *cur_line = Malloc((unsigned)size);
- char *c_ptr = cur_line;
- int c = GetChar();
- int delim = 0;
- while(c != '\n') {
- if (c_ptr + 1 - cur_line == size) {
- cur_line = Realloc(cur_line, (unsigned)(size + ITEXTSIZE));
- c_ptr = cur_line + size - 1;
- size += ITEXTSIZE;
- }
- if (delim) {
- if (c == delim) {
- delim = 0;
- }
- else if (c == '\\') {
- *c_ptr++ = c;
- c = GetChar();
- if (c == '\n') break;
- }
- }
- else if (c == '\'' || c == '"') {
- delim = c;
- }
- else if (c == '/') {
- if ((c = GetChar()) != '*' || InputLevel) {
- *c_ptr++ = '/';
- }
- else {
- skipcomment();
- continue;
- }
- }
- *c_ptr++ = c;
- c = GetChar();
- }
- *c_ptr = '\0';
- if (!pragma_nr) {
- pragma_tab = (struct prag_info *)Malloc(sizeof(struct prag_info));
- } else {
- pragma_tab = (struct prag_info *)Realloc((char *)pragma_tab
- , (unsigned)(sizeof(struct prag_info) * (pragma_nr+1)));
- }
- if (delim) {
- error("unclosed opening %c", delim);
- }
- pragma_tab[pragma_nr].pr_linnr = LineNumber;
- pragma_tab[pragma_nr].pr_fil = FileName;
- pragma_tab[pragma_nr].pr_text = cur_line;
- pragma_nr++;
- LineNumber++;
- }
- char Xbuf[256];
- void preprocess(char *fn)
- {
- int c;
- char *op = _obuf;
- char *ob = &_obuf[OBUFSIZE];
- int lineno = 0;
- int startline;
- #define flush(X) (sys_write(STDOUT,_obuf,X))
- #define echo(ch) if (op == ob) { Xflush(); op = _obuf; } *op++ = (ch);
- #define newline() op--; while (op >= _obuf && (*op == ' ' || *op == '\t')) op--; op++; echo('\n')
- if (!options['P']) {
- /* Generate a line directive communicating the
- source filename
- */
- char *p = Xbuf;
- sprint(p, "%s 1 \"%s\"\n",
- LINE_PREFIX,
- FileName);
- while (*p) {
- echo(*p++);
- }
- }
- #define do_line_dir(lineno, fn) \
- if (lineno != LineNumber || fn != FileName) { \
- fn = FileName; \
- lineno = LineNumber; \
- if (! options['P']) { \
- char *p = Xbuf; \
- sprint(Xbuf, "%s %d \"%s\"\n", \
- LINE_PREFIX, \
- (int)LineNumber, \
- FileName); \
- op--; \
- while (op >= _obuf \
- && (class(*(unsigned char *)op) == STSKIP \
- || *op == '\n')) op--; \
- op++; \
- newline(); \
- while (*p) { \
- echo(*p++); \
- } \
- } \
- }
- for (;;) {
- LineNumber++;
- lineno++;
- startline = 1;
- c = GetChar();
- while (startline) {
- /* first flush the saved pragma's */
- if (pragma_nr) {
- int i = 0;
- int LiNo = LineNumber;
- char *FiNam = FileName;
-
- while (i < pragma_nr) {
- char *c_ptr = "#pragma";
-
- LineNumber = pragma_tab[i].pr_linnr;
- FileName = pragma_tab[i].pr_fil;
- do_line_dir(lineno, fn);
- while (*c_ptr) { echo(*c_ptr++); }
- c_ptr = pragma_tab[i].pr_text;
- while (*c_ptr) { echo(*c_ptr++); }
- newline(); lineno++;
- free(pragma_tab[i].pr_text);
- i++;
- }
- free((char *) pragma_tab);
- pragma_tab = (struct prag_info *)0;
- pragma_nr = 0;
- LineNumber = LiNo;
- FileName = FiNam;
- do_line_dir(lineno, fn);
- }
- while (class(c) == STSKIP || c == '/') {
- if (c == '/') {
- if (!InputLevel) {
- c = GetChar();
- if (c == '*') {
- op = SkipComment(op, &lineno);
- if (!op) return;
- if (!options['C']) { echo(' '); }
- c = GetChar();
- continue;
- }
- UnGetChar();
- c = '/';
- }
- break;
- }
- echo(c);
- c = GetChar();
- }
- if (c == '#') {
- domacro();
- lineno++;
- newline();
- do_line_dir(lineno, fn);
- c = GetChar();
- } else startline = 0;
- }
- do_line_dir(lineno, fn);
- for (;;) {
- /* illegal character */
- if (c & 0200) {
- if (c == EOI) {
- newline();
- flush((int)(op-_obuf));
- return;
- }
- fatal("non-ascii character read");
- }
- /* comments */
- if (c == '/' && !InputLevel) {
- c = GetChar();
- if (c == '*') {
- op = SkipComment(op, &lineno);
- if (!op) return;
- if (!options['C']) { echo(' '); }
- c = GetChar();
- continue;
- }
- echo('/');
- continue;
- }
- /* switch on character */
- switch(class(c)) {
- case STNL:
- newline();
- break;
- case STSTR:
- case STCHAR:
- {
- int stopc = c;
- int escaped;
- do {
- escaped = 0;
- echo(c);
- c = GetChar();
- if (c == '\n') {
- /* the compiler will complain */
- break;
- }
- else if (c == EOI) {
- newline();
- flush((int)(op-_obuf));
- return;
- }
- if (c == '\\') {
- echo(c);
- c = GetChar();
- if (c == '\n') {
- ++LineNumber;
- lineno++;
- } else escaped = 1;
- }
- } while (escaped || c != stopc);
- echo(c);
- if (c == '\n')
- break; /* Don't eat # */
- c = GetChar();
- continue;
- }
- case STNUM:
- /* The following code is quit ugly. This because
- * ..3 == . .3 , whereas ...3 == ... 3
- */
- echo(c);
- if (c == '.') {
- c = GetChar();
- if (c == '.') {
- if ((c = GetChar()) == '.') {
- echo('.'); echo('.');
- c = GetChar();
- continue;
- }
- UnGetChar();
- c = '.';
- continue;
- } else if (!is_dig(c)) {
- continue;
- } else { echo(c); }
- }
- c = GetChar();
- while (in_idf(c) || c == '.') {
- echo(c);
- if (c == 'e' || c == 'E') {
- c = GetChar();
- if (c == '+' || c == '-') {
- echo(c);
- c = GetChar();
- }
- } else c = GetChar();
- }
- continue;
- case STELL:
- c = GetChar();
- UnGetChar();
- if (c == '"' || c == '\'') {
- echo('L');
- continue;
- }
- c = 'L';
- case STIDF: {
- extern int idfsize; /* ??? */
- char buf[IDFSIZE + 1];
- char *tg = &buf[0];
- char *maxpos = &buf[idfsize];
- struct idf *idef;
- int NoExpandNext = 0;
- #define tstmac(bx) if (!(bits[c] & bx)) goto nomac
- #define cpy *tg++ = c
- #define load c = GetChar(); if (!in_idf(c)) goto endidf
- /* unstack macro's when allowed. */
- if (Unstacked)
- EnableMacros();
- if (c == NOEXPM) {
- NoExpandNext = 1;
- c = GetChar();
- }
- #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:
- if (c != EOF) UnGetChar();
- *tg = '\0'; /* mark the end of the identifier */
- if ((idef = findidf(buf))
- && idef->id_macro
- && ReplaceMacros && !NoExpandNext) {
- if (replace(idef)) {
- echo(' ');
- c = GetChar();
- continue;
- }
- tg = buf;
- while (*tg) {
- echo(*tg++);
- }
- c = GetChar();
- if (in_idf(c)) { echo(' '); }
- continue;
- }
- nomac:
- *tg = '\0';
- tg = buf;
- while (*tg) {
- echo(*tg++);
- }
- c = GetChar();
- while (in_idf(c)) {
- echo(c);
- c = GetChar();
- }
- continue;
- }
- case STMSPEC:
- if (InputLevel) {
- echo(' '); /* seperate tokens */
- c = GetChar();
- continue;
- }
- /* else fallthrough */
- default:
- echo(c);
- c = GetChar();
- continue;
- }
- break;
- }
- }
- /*NOTREACHED*/
- }
- static char *SkipComment(char *op, int *lineno)
- {
- char *ob = &_obuf[OBUFSIZE];
- int c, oldc = '\0';
- NoUnstack++;
- if (options['C']) {
- echo('/');
- echo('*');
- }
- c = GetChar();
- for(;;) {
- if (c == EOI) {
- newline();
- flush((int)(op - _obuf));
- op = 0;
- break;
- }
- if (options['C']) {
- echo(c);
- }
- if (c == '\n') {
- ++LineNumber;
- ++*lineno;
- if (!options['C']) {
- echo(c);
- }
- }
- if (c == '*') {
- c = GetChar();
- if (c == '/') {
- if (options['C']) {
- echo(c);
- }
- break; /* for(;;) */
- } else if (oldc == '/') {
- warning("comment inside comment ?");
- }
- oldc = '*';
- } else {
- oldc = c;
- c = GetChar();
- }
- }
- NoUnstack--;
- return op;
- }
|