2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 /* $Id: preprocess.c,v 1.18 1994/06/24 11:37:53 ceriel Exp $ */
6 /* PREPROCESSOR DRIVER */
19 #include "ln_prefix.h"
26 extern int InputLevel;
28 extern char *sprint();
32 sys_write(STDOUT, _obuf, OBUFSIZE);
35 static char *SkipComment();
36 extern char options[];
38 /* #pragma directives are saved here and passed to the compiler later on.
45 static struct prag_info *pragma_tab;
50 register int size = ITEXTSIZE;
51 char *cur_line = Malloc((unsigned)size);
52 register char *c_ptr = cur_line;
53 register int c = GetChar();
54 register int delim = 0;
57 if (c_ptr + 1 - cur_line == size) {
58 cur_line = Realloc(cur_line, (unsigned)(size + ITEXTSIZE));
59 c_ptr = cur_line + size - 1;
72 else if (c == '\'' || c == '"') {
76 if ((c = GetChar()) != '*' || InputLevel) {
89 pragma_tab = (struct prag_info *)Malloc(sizeof(struct prag_info));
91 pragma_tab = (struct prag_info *)Realloc((char *)pragma_tab
92 , (unsigned)(sizeof(struct prag_info) * (pragma_nr+1)));
95 error("unclosed opening %c", delim);
97 pragma_tab[pragma_nr].pr_linnr = LineNumber;
98 pragma_tab[pragma_nr].pr_fil = FileName;
99 pragma_tab[pragma_nr].pr_text = cur_line;
110 register char *op = _obuf;
111 register char *ob = &_obuf[OBUFSIZE];
115 #define flush(X) (sys_write(STDOUT,_obuf,X))
116 #define echo(ch) if (op == ob) { Xflush(); op = _obuf; } *op++ = (ch);
117 #define newline() op--; while (op >= _obuf && (*op == ' ' || *op == '\t')) op--; op++; echo('\n')
120 /* Generate a line directive communicating the
123 register char *p = Xbuf;
125 sprint(p, "%s 1 \"%s\"\n",
133 #define do_line_dir(lineno, fn) \
134 if (lineno != LineNumber || fn != FileName) { \
136 lineno = LineNumber; \
137 if (! options['P']) { \
138 register char *p = Xbuf; \
139 sprint(Xbuf, "%s %d \"%s\"\n", \
145 && (class(*op) == STSKIP \
146 || *op == '\n')) op--; \
161 /* first flush the saved pragma's */
164 int LiNo = LineNumber;
165 char *FiNam = FileName;
167 while (i < pragma_nr) {
168 register char *c_ptr = "#pragma";
170 LineNumber = pragma_tab[i].pr_linnr;
171 FileName = pragma_tab[i].pr_fil;
172 do_line_dir(lineno, fn);
173 while (*c_ptr) { echo(*c_ptr++); }
174 c_ptr = pragma_tab[i].pr_text;
175 while (*c_ptr) { echo(*c_ptr++); }
177 free(pragma_tab[i].pr_text);
180 free((char *) pragma_tab);
181 pragma_tab = (struct prag_info *)0;
185 do_line_dir(lineno, fn);
189 while (class(c) == STSKIP || c == '/') {
194 op = SkipComment(op, &lineno);
196 if (!options['C']) { echo(' '); }
214 } else startline = 0;
216 do_line_dir(lineno, fn);
219 /* illegal character */
223 flush((int)(op-_obuf));
226 fatal("non-ascii character read");
230 if (c == '/' && !InputLevel) {
233 op = SkipComment(op, &lineno);
235 if (!options['C']) { echo(' '); }
243 /* switch on character */
251 register int stopc = c;
259 /* the compiler will complain */
264 flush((int)(op-_obuf));
275 } while (escaped || c != stopc);
278 break; /* Don't eat # */
283 /* The following code is quit ugly. This because
284 * ..3 == . .3 , whereas ...3 == ... 3
290 if ((c = GetChar()) == '.') {
291 echo('.'); echo('.');
298 } else if (!is_dig(c)) {
303 while (in_idf(c) || c == '.') {
305 if (c == 'e' || c == 'E') {
307 if (c == '+' || c == '-') {
311 } else c = GetChar();
317 if (c == '"' || c == '\'') {
323 extern int idfsize; /* ??? */
324 char buf[IDFSIZE + 1];
325 register char *tg = &buf[0];
326 register char *maxpos = &buf[idfsize];
327 register struct idf *idef;
328 int NoExpandNext = 0;
330 #define tstmac(bx) if (!(bits[c] & bx)) goto nomac
331 #define cpy *tg++ = c
332 #define load c = GetChar(); if (!in_idf(c)) goto endidf
334 /* unstack macro's when allowed. */
343 cpy; tstmac(bit0); load;
344 cpy; tstmac(bit1); load;
345 cpy; tstmac(bit2); load;
346 cpy; tstmac(bit3); load;
347 cpy; tstmac(bit4); load;
348 cpy; tstmac(bit5); load;
349 cpy; tstmac(bit6); load;
350 cpy; tstmac(bit7); load;
360 if (c != EOF) UnGetChar();
361 *tg = '\0'; /* mark the end of the identifier */
362 if ((idef = findidf(buf))
364 && ReplaceMacros && !NoExpandNext) {
375 if (in_idf(c)) { echo(' '); }
393 echo(' '); /* seperate tokens */
397 /* else fallthrough */
410 SkipComment(op, lineno)
414 char *ob = &_obuf[OBUFSIZE];
415 register int c, oldc = '\0';
426 flush((int)(op - _obuf));
447 } else if (oldc == '/') {
448 warning("comment inside comment ?");