scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit bf7035e84c924246113e6d6033b3513bd224f559
parent 3a4b6eedd35f30fc914d7e21270f659e11d1a318
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 21 May 2015 22:20:42 +0200

Simplify readline() function

This function had a rally complex status machine, when it was not
needed. This new implementation is short and clear.

Diffstat:
Mcc1/lex.c | 86++++++++++++++++++++++++++++++++++++++++----------------------------------------
1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/cc1/lex.c b/cc1/lex.c @@ -29,9 +29,8 @@ char yytext[IDENTSIZ + 1]; unsigned short yylen; static unsigned lex_ns = NS_IDEN; -static int safe; +static int safe, eof, incomment; static Input *input; -static int eof; bool addinput(char *fname) @@ -112,7 +111,7 @@ getfline(void) return input->nline; } -static int +static char readchar(void) { int c; @@ -121,8 +120,11 @@ readchar(void) repeat: while (feof(input->fp) && !eof) delinput(); - if (eof) - return EOF; + if (eof) { + if (incomment) + error("unterminated comment"); + return '\0'; + } fp = input->fp; if ((c = getc(fp)) == '\\') { @@ -133,57 +135,55 @@ repeat: } else if (c == EOF) { goto repeat; } else if (c == '\n' && ++input->nline == 0) { - die("input file '%s' too long", getfname()); + die("error:input file '%s' too long", getfname()); } return c; } static void +comment(char c) +{ + /* TODO: Ensure that incomment == 0 after a recovery */ + incomment = 1; + if (c == '*') { + for (;;) { + while (readchar() != '*') + /* nothing */; + if (readchar() == '/') + break; + } + } else { + while (readchar() != '\n') + /* nothing */; + } + incomment = 0; +} + +static void readline(void) { - int comment = 0, commentline = 0; char *bp, *lim; - int c; - - bp = input->line; - lim = bp + INPUTSIZ-1; + char c, peekc = 0; - for (;;) { - c = readchar(); - nextchar: - if (c == EOF) + lim = input->line + INPUTSIZ; + for (bp = input->line; bp != lim; *bp++ = c) { + c = (peekc) ? peekc : readchar(); + peekc = 0; + if (c == '\n' || c == '\0') break; - if (comment) { - if (c != '*') - continue; - if ((c = readchar()) != '/') - goto nextchar; - comment = 0; - c = ' '; - } else if (commentline) { - if (c != '\n') - continue; - commentline = 0; + if (c != '/') + continue; + if ((c = readchar()) != '*' && c != '/') { + peekc = c; + c = '/'; + } else { + comment(c); c = ' '; } - if (c == '\n') - break; - if (bp == lim) - die("line %u too big in file '%s'", - getfline(), getfname()); - if (c == '/') { - if ((c = readchar()) == '*') { - comment = 1; - continue; - } else if (c == '/') { - commentline = 1; - continue; - } - *bp++ = '/'; - goto nextchar; - } - *bp++ = c; } + + if (bp == lim) + error("line %u too big in file '%s'", getfline(), getfname()); *bp = '\0'; }