Exemplo n.º 1
0
Arquivo: token.c Projeto: Sciumo/pcc
/*
 * Scan quickly the input file searching for:
 *	- '#' directives
 *	- keywords (if not flslvl)
 *	- comments
 *
 *	Handle strings, numbers and trigraphs with care.
 *	Only data from pp files are scanned here, never any rescans.
 *	TODO: Only print out strings before calling other functions.
 */
static void
fastscan(void)
{
	struct symtab *nl;
	int ch, i;
	usch *cp;

	goto run;
	for (;;) {
		ch = inch();
xloop:		if (ch == -1)
			return;
#ifdef PCC_DEBUG
		if (dflag>1)
			printf("fastscan ch %d (%c)\n", ch, ch > 31 ? ch : '@');
#endif
		if ((spechr[ch] & C_SPEC) == 0) {
			PUTCH(ch);
			continue;
		}
		switch (ch) {
		case EBLOCK:
		case WARN:
		case CONC:
			error("bad char passed");
			break;

		case '/': /* Comments */
			if ((ch = inch()) == '/') {
cppcmt:				if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
				do {
					if (Cflag) PUTCH(ch);
					ch = inch();
				} while (ch != -1 && ch != '\n');
				goto xloop;
			} else if (ch == '*') {
				eatcmnt();
			} else {
				PUTCH('/');
				goto xloop;
			}
			break;

		case '\n': /* newlines, for pp directives */
			i = ifiles->escln + 1;
			ifiles->lineno += i;
			ifiles->escln = 0;
			while (i-- > 0)
				putch('\n');
run:			for(;;) {
				ch = inch();
				if (ch == '/') {
					ch = inch();
					if (ch == '/')
						goto cppcmt;
					if (ch == '*') {
						eatcmnt();
						continue;
					}
					unch(ch);
					ch = '/';
				}
				if (ch != ' ' && ch != '\t')
					break;
				PUTCH(ch);
			}
			if (ch == '#') {
				ppdir();
				continue;
			} else if (ch == '%') {
				ch = inch();
				if (ch == ':') {
					ppdir();
					continue;
				}
				unch(ch);
				ch = '%';
			}
			goto xloop;

		case '\"': /* strings */
str:			PUTCH(ch);
			while ((ch = inch()) != '\"') {
				if (ch == '\\') {
					PUTCH('\\');
					ch = inch();
				}
				if (ch == '\n') {
					warning("unterminated string literal");
					goto xloop;
				}
				if (ch == -1)
					return;
				PUTCH(ch);
			}
			PUTCH(ch);
			break;

		case '.':  /* for pp-number */
			PUTCH(ch);
			ch = inch();
			if (ch < '0' || ch > '9')
				goto xloop;

			/* FALLTHROUGH */
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			do {
nxp:				PUTCH(ch);
				ch = inch();
				if (ch == -1)
					return;
				if (spechr[ch] & C_EP) {
					PUTCH(ch);
					ch = inch();
					if (ch == '-' || ch == '+')
						goto nxp;
					if (ch == -1)
						return;
				}
			} while ((spechr[ch] & C_ID) || (ch == '.'));
			goto xloop;

		case '\'': /* character constant */
con:			PUTCH(ch);
			if (tflag)
				break; /* character constants ignored */
			while ((ch = inch()) != '\'') {
				if (ch == '\\') {
					PUTCH('\\');
					ch = inch();
				}
				if (ch == '\n') {
					warning("unterminated character constant");
					goto xloop;
				}
				if (ch == -1)
					return;
				PUTCH(ch);
			}
			PUTCH(ch);
			break;

		case 'L':
			ch = inch();
			if (ch == '\"') {
				PUTCH('L');
				goto str;
			}
			if (ch == '\'') {
				PUTCH('L');
				goto con;
			}
			unch(ch);
			ch = 'L';

			/* FALLTHROUGH */
		default:
#ifdef PCC_DEBUG
			if ((spechr[ch] & C_ID) == 0)
				error("fastscan");
#endif
			i = 0;
			do {
				yytext[i++] = (usch)ch;
				ch = inch();
			} while (ch != -1 && (spechr[ch] & C_ID));

			if (flslvl)
				goto xloop;

			yytext[i] = 0;
			unch(ch);

			cp = stringbuf;
			if ((nl = lookup(yytext, FIND)) && kfind(nl)) {
				putstr(stringbuf);
			} else
				putstr(yytext);
			stringbuf = cp;

			break;
		}
	}
}
Exemplo n.º 2
0
Arquivo: token.c Projeto: pauley/pcc
/*
 * Scan quickly the input file searching for:
 *	- '#' directives
 *	- keywords (if not flslvl)
 *	- comments
 *
 *	Handle strings, numbers and trigraphs with care.
 *	Only data from pp files are scanned here, never any rescans.
 *	TODO: Only print out strings before calling other functions.
 */
static void
fastscan(void)
{
	struct symtab *nl;
	int ch, i;

	goto run;
	for (;;) {
		ch = NXTCH();
xloop:		if (ch == -1)
			return;
		if ((spechr[ch] & C_SPEC) == 0) {
			PUTCH(ch);
			continue;
		}
		switch (ch) {
		case '/': /* Comments */
			if ((ch = inch()) == '/') {
				if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
				do {
					if (Cflag) PUTCH(ch);
					ch = inch();
				} while (ch != -1 && ch != '\n');
				goto xloop;
			} else if (ch == '*') {
				if (Cflag) { PUTCH('/'); PUTCH('*'); }
				for (;;) {
					ch = inch();
					if (ch == '\n') {
						ifiles->lineno++;
						PUTCH('\n');
					}
					if (ch == -1)
						return;
					if (ch == '*') {
						ch = inch();
						if (ch == '/') {
							if (Cflag) {
								PUTCH('*');
								PUTCH('/');
							} else
								PUTCH(' ');
							break;
						}
						unch(ch);
						ch = '*';
					}
					if (Cflag) PUTCH(ch);
				}
			} else {
				PUTCH('/');
				goto xloop;
			}
			break;

		case '?':  /* trigraphs */
			if ((ch = chktg()))
				goto xloop;
			PUTCH('?');
			break;

		case '\\':
			if ((ch = NXTCH()) == '\n') {
				ifiles->lineno++;
				continue;
			} else {
				PUTCH('\\');
			}
			goto xloop;

		case '\n': /* newlines, for pp directives */
			ifiles->lineno++;
			do {
				PUTCH(ch);
run:				ch = NXTCH();
			} while (ch == ' ' || ch == '\t');
			if (ch == '#') {
				ppdir();
				continue;
			} else if (ch == '%') {
				ch = NXTCH();
				if (ch == ':') {
					ppdir();
					continue;
				} else {
					unch(ch);
					ch = '%';
				}
			}
			goto xloop;

		case '\"': /* strings */
str:			PUTCH(ch);
			while ((ch = inch()) != '\"') {
				PUTCH(ch);
				if (ch == '\\') {
					ch = inch();
					PUTCH(ch);
				}
				if (ch < 0)
					return;
			}
			PUTCH(ch);
			break;

		case '.':  /* for pp-number */
			PUTCH(ch);
			ch = NXTCH();
			if (ch < '0' || ch > '9')
				goto xloop;
			/* FALLTHROUGH */
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			do {
				PUTCH(ch);
				ch = NXTCH();
				if (spechr[ch] & C_EP) {
					PUTCH(ch);
					ch = NXTCH();
					if (ch == '-' || ch == '+')
						continue;
				}
			} while ((spechr[ch] & C_ID) || (ch == '.'));
			goto xloop;

		case '\'': /* character literal */
con:			PUTCH(ch);
			if (tflag)
				continue; /* character constants ignored */
			while ((ch = NXTCH()) != '\'') {
				PUTCH(ch);
				if (ch == '\\') {
					ch = NXTCH();
					PUTCH(ch);
				} else if (ch < 0)
					return;
				else if (ch == '\n')
					goto xloop;
			}
			PUTCH(ch);
			break;

		case 'L':
			ch = NXTCH();
			if (ch == '\"') {
				PUTCH('L');
				goto str;
			}
			if (ch == '\'') {
				PUTCH('L');
				goto con;
			}
			unch(ch);
			ch = 'L';
			/* FALLTHROUGH */
		default:
			if ((spechr[ch] & C_ID) == 0)
				error("fastscan");
			if (flslvl) {
				while (spechr[ch] & C_ID)
					ch = NXTCH();
				goto xloop;
			}
			i = 0;
			do {
				yytext[i++] = (usch)ch;
				ch = NXTCH();
				if (ch == '\\') {
					ch = NXTCH();
					if (ch != '\n') {
						unch('\n');
						ch = '\\';
					} else {
						ifiles->lineno++;
						ch = NXTCH();
					}
				}
				if (ch < 0)
					return;
			} while (spechr[ch] & C_ID);
			yytext[i] = 0;
			unch(ch);
			if ((nl = lookup((usch *)yytext, FIND)) != 0) {
				usch *op = stringbuf;
				putstr(gotident(nl));
				stringbuf = op;
			} else
				putstr((usch *)yytext);
			break;
		}
	}
}
Exemplo n.º 3
0
/*
 * Scan quickly the input file searching for:
 *	- '#' directives
 *	- keywords (if not flslvl)
 *	- comments
 *
 *	Handle strings, numbers and trigraphs with care.
 *	Only data from pp files are scanned here, never any rescans.
 *	This loop is always at trulvl.
 */
void
fastscan(void)
{
	struct iobuf *ob, rbs, *rb = &rbs;
	extern struct iobuf pb;
	struct iobuf *ib = ifiles->ib;
	struct symtab *nl;
	int ch, c2;
	usch *dp;

#define	IDSIZE	128
	rb->buf = xmalloc(IDSIZE+1);
	rb->cptr = 0;
	rb->bsz = IDSIZE;

	goto run;

	for (;;) {
		/* tight loop to find special chars */
		/* should use getchar/putchar here */
		for (;;) {
			if (ib->cptr < ib->bsz)
				ch = ib->buf[ib->cptr++];
			else
				ch = qcchar();
xloop:			if (ch < 0) ch = 0; /* XXX */
			if ((spechr[ch] & C_SPEC) != 0)
				break;
			putch(ch);
		}

		switch (ch) {
		case 0:
			free(rb->buf);
			return;

		case WARN:
		case CONC:
			error("bad char passed");
			break;

		case '/': /* Comments */
			incmnt++;
			ch = qcchar();
			incmnt--;
			if (ch  == '/' || ch == '*') {
				if (Cflag == 0) {
					int n = ifiles->lineno;
					fastcmnt2(ch);
					if (n == ifiles->lineno)
						putch(' '); /* 5.1.1.2 p3 */
				} else
					Ccmnt2(&pb, ch);
			} else {
				putch('/');
				goto xloop;
			}
			break;

		case '\n': /* newlines, for pp directives */
			/* take care of leftover \n */
			while (ifiles->escln > 0) {
				putch('\n');
				ifiles->escln--;
				ifiles->lineno++;
			}
			putch('\n');
			ifiles->lineno++;

			/* search for a # */
run:			while ((ch = qcchar()) == '\t' || ch == ' ')
				putch(ch);
			if (ch == '%') {
				if ((c2 = qcchar()) != ':')
					unch(c2);
				else
					ch = '#';
			}
			if (ch  == '#')
				ppdir();
			else
				goto xloop;
			break;

		case '?':
			if (ib->cptr+1 >= ib->bsz)
				inpbuf(2);
			if (ib->buf[ib->cptr] == '?') {
				ib->cptr++;
				if ((ch = chktg2(ib->buf[ib->cptr++])))
					goto xloop;
				ib->cptr -= 2;
			}
			putch('?');
			break;

		case '\'': /* character constant */
			if (tflag) {
				putch(ch);
				break;	/* character constants ignored */
			}
			/* FALLTHROUGH */
		case '\"': /* strings */
			if (skpows)
				cntline();
			faststr(ch, &pb);
			break;

		case '.':  /* for pp-number */
			if ((spechr[c2 = qcchar()] & C_DIGIT) == 0) {
				putch('.');
				goto xloop;
			}
			unch(c2);
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			if (skpows)
				cntline();
			ch = fastnum(ch, &pb);
			goto xloop;

		case 'L':
		case 'U':
		case 'u':
			if (ib->cptr+2 >= ib->bsz)
				inpbuf(2);
			if ((c2 = ib->buf[ib->cptr]) == '\"' || c2 == '\'') {
				putch(ch);
				break;
			} else if (c2 == '8' && ch == 'u' &&
			    ib->buf[ib->cptr+1] == '\"') {
				ib->cptr++;
				putstr((usch *)"u8");
				break;
			}
			/* FALLTHROUGH */
		default:
#ifdef PCC_DEBUG
			if ((spechr[ch] & C_ID) == 0)
				error("fastscan");
#endif
			if (flslvl)
				error("fastscan flslvl");
			rb->cptr = 0;
			dp = bufid(ch, rb);
			if ((nl = lookup(dp, FIND)) != NULL) {
				if ((ob = kfind(nl)) != NULL) {
					if (*ob->buf == '-' || *ob->buf == '+')
						putch(' ');
					if (skpows)
						cntline();
					buftobuf(ob, &pb);
					if (ob->cptr > 0 &&
					    (ob->buf[ob->cptr-1] == '-' ||
					    ob->buf[ob->cptr-1] == '+'))
						putch(' ');
					bufree(ob);
				}
			} else {
				putstr(dp);
			}
			break;

		case '\\':
			ib->buf[--ib->cptr] = '\\';
			if ((ch = qcchar()) != '\\')
				goto xloop;
			putch('\\');
			break;
		}
	}
}
Exemplo n.º 4
0
/*
 * Scan quickly the input file searching for:
 *	- '#' directives
 *	- keywords (if not flslvl)
 *	- comments
 *
 *	Handle strings, numbers and trigraphs with care.
 *	Only data from pp files are scanned here, never any rescans.
 *	TODO: Only print out strings before calling other functions.
 */
static void
fastscan(void)
{
	struct symtab *nl;
	int ch, i = 0;
	int nnl = 0;
	usch *cp;

	goto run;
	for (;;) {
		ch = NXTCH();
xloop:		if (ch == -1)
			return;
#ifdef PCC_DEBUG
		if (dflag>1)
			printf("fastscan ch %d (%c)\n", ch, ch > 31 ? ch : '@');
#endif
		if ((spechr[ch] & C_SPEC) == 0) {
			PUTCH(ch);
			continue;
		}
		switch (ch) {
		case EBLOCK:
		case WARN:
		case CONC:
			error("bad char passed");
			break;

		case '/': /* Comments */
			if ((ch = inch()) == '/') {
cppcmt:				if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
				do {
					if (Cflag) PUTCH(ch);
					ch = inch();
				} while (ch != -1 && ch != '\n');
				goto xloop;
			} else if (ch == '*') {
				if (eatcmnt())
					return;
			} else {
				PUTCH('/');
				goto xloop;
			}
			break;

		case '?':  /* trigraphs */
			if ((ch = chktg()))
				goto xloop;
			PUTCH('?');
			break;

		case '\\':
			if ((ch = NXTCH()) == '\n') {
				ifiles->lineno++;
				continue;
			} else {
				PUTCH('\\');
			}
			goto xloop;

		case '\n': /* newlines, for pp directives */
			while (nnl > 0) { PUTCH('\n'); nnl--; }
run2:			ifiles->lineno++;
			do {
				PUTCH(ch);
run:				ch = NXTCH();
				if (ch == '/') {
					ch = NXTCH();
					if (ch == '/')
						goto cppcmt;
					if (ch == '*') {
						if (eatcmnt())
							return;
						goto run;
					} 
					unch(ch);
					ch = '/';
				}
			} while (ch == ' ' || ch == '\t');
			if (ch == '\\') {
				ch = NXTCH();
				if (ch == '\n')
					goto run2;
				unch(ch);
				ch = '\\';
			}
			if (ch == '#') {
				ppdir();
				continue;
			} else if (ch == '%') {
				ch = NXTCH();
				if (ch == ':') {
					ppdir();
					continue;
				} else {
					unch(ch);
					ch = '%';
				}
			} else if (ch == '?') {
				if ((ch = chktg()) == '#') {
					ppdir();
					continue;
				} else if (ch == 0) 
					ch = '?';
			}
			goto xloop;

		case '\"': /* strings */
str:			PUTCH(ch);
			while ((ch = NXTCH()) != '\"') {
				if (ch == '\n')
					goto xloop;
				if (ch == '\\') {
					if ((ch = NXTCH()) != '\n') {
						PUTCH('\\');
						PUTCH(ch);
					} else
						nnl++;
					continue;
                                }
				if (ch < 0)
					return;
				PUTCH(ch);
			}
			PUTCH(ch);
			break;

		case '.':  /* for pp-number */
			PUTCH(ch);
			ch = NXTCH();
			if (ch < '0' || ch > '9')
				goto xloop;
			/* FALLTHROUGH */
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			do {
				PUTCH(ch);
nxt:				ch = NXTCH();
				if (ch == '\\') {
					ch = NXTCH();
					if (ch == '\n') {
						goto nxt;
					} else {
						unch(ch);
						ch = '\\';
					}
				}
				if (spechr[ch] & C_EP) {
					PUTCH(ch);
					ch = NXTCH();
					if (ch == '-' || ch == '+')
						continue;
				}
			} while ((spechr[ch] & C_ID) || (ch == '.'));
			goto xloop;

		case '\'': /* character literal */
con:			PUTCH(ch);
			if (tflag)
				continue; /* character constants ignored */
			while ((ch = NXTCH()) != '\'') {
				if (ch == '\n')
					goto xloop;
				if (ch == '\\') {
					if ((ch = NXTCH()) != '\n') {
						PUTCH('\\');
						PUTCH(ch);
					} else
						nnl++;
					continue;
				}
				if (ch < 0)
					return;
				PUTCH(ch);
			}
			PUTCH(ch);
			break;

		case 'L':
			ch = NXTCH();
			if (ch == '\"') {
				PUTCH('L');
				goto str;
			}
			if (ch == '\'') {
				PUTCH('L');
				goto con;
			}
			unch(ch);
			ch = 'L';
			/* FALLTHROUGH */
		default:
			if ((spechr[ch] & C_ID) == 0)
				error("fastscan");
			if (flslvl) {
				while (spechr[ch] & C_ID)
					ch = NXTCH();
				goto xloop;
			}
			i = 0;
			do {
				yytext[i++] = (usch)ch;
				ch = NXTCH();
				if (ch == '\\') {
					ch = NXTCH();
					if (ch != '\n') {
						unch(ch);
						ch = '\\';
					} else {
						putch('\n');
						ifiles->lineno++;
						ch = NXTCH();
					}
				}
				if (ch < 0)
					return;
			} while (spechr[ch] & C_ID);

			yytext[i] = 0;
			unch(ch);

			cp = stringbuf;
			if ((nl = lookup((usch *)yytext, FIND)) && kfind(nl)) {
				putstr(stringbuf);
			} else
				putstr((usch *)yytext);
			stringbuf = cp;

			break;
		}
	}
}