scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 615f2e2509a94bd67cf4992cb9418a39a637b96f
parent 6d8bae308fef0e3a0c6678a61fb375733e30e535
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 19 Jan 2024 11:02:53 +0100

make: Deal escaped newlines in rule lines

When a escaped newline is detected in the definition of a rule
it and all the following whitespaces must be replaced by a single
space. Skipspaces() cannot be used because it is used in several
scopes where the newline and escape has to be deal in a different
way.

Diffstat:
Msrc/cmd/make/parser.c | 43++++++++++++++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/src/cmd/make/parser.c b/src/cmd/make/parser.c @@ -296,7 +296,8 @@ repeat: c = getc(fp); if (c == '\n' || c == EOF) { input->loc.lineno++; - *s++ = c; + if (c == '\n') + *s++ = c; break; } if (c == '#') { @@ -370,6 +371,7 @@ back(int c) { if (c == EOF) return c; + assert(input->pos > 0); input->buf[--input->pos] = c; } @@ -608,17 +610,38 @@ expandstring(char *line, Target *tp) } static int +readchar(void) +{ + int c; + + while ((c = nextc()) != EOF) { + if (c == ' ' || c == '\t') + continue; + if (c == '\\') { + if ((c = nextc()) == '\n') + continue; + back(c); + c = '\\'; + } + break; + } + + return c; +} + +static int next(void) { int c; repeat: - skipspaces(); + c = readchar(); - switch (c = nextc()) { + switch (c) { case EOF: strcpy(token, "<EOF>"); - return tok = EOF; + tok = EOF; + break; case '$': if ((c = nextc()) == '$') goto single; @@ -632,11 +655,17 @@ repeat: single: token[0] = c; token[1] = '\0'; - return tok = c; + tok = c; + break; default: + if (!validchar(c)) + error("unexpected character '%c'", c); back(c); - return tok = item(); + tok = item(); + break; } + + return tok; } static char * @@ -772,7 +801,7 @@ parseinput(void) targets = NULL; next(); - if (tok == '\n' || tok == EOF) + if (tok == '\n') continue; while (tok == ITEM) {