Module Name: src
Committed By: rillig
Date: Mon May 8 09:01:20 UTC 2023
Modified Files:
src/usr.bin/make: for.c
src/usr.bin/make/unit-tests: directive-for.exp directive-for.mk
Log Message:
make: fix parsing of unusual line continuations in .for loops
To generate a diff of this commit:
cvs rdiff -u -r1.171 -r1.172 src/usr.bin/make/for.c
cvs rdiff -u -r1.12 -r1.13 src/usr.bin/make/unit-tests/directive-for.exp
cvs rdiff -u -r1.15 -r1.16 src/usr.bin/make/unit-tests/directive-for.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/make/for.c
diff -u src/usr.bin/make/for.c:1.171 src/usr.bin/make/for.c:1.172
--- src/usr.bin/make/for.c:1.171 Tue Feb 14 21:38:31 2023
+++ src/usr.bin/make/for.c Mon May 8 09:01:20 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.171 2023/02/14 21:38:31 rillig Exp $ */
+/* $NetBSD: for.c,v 1.172 2023/05/08 09:01:20 rillig Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -58,7 +58,7 @@
#include "make.h"
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
-MAKE_RCSID("$NetBSD: for.c,v 1.171 2023/02/14 21:38:31 rillig Exp $");
+MAKE_RCSID("$NetBSD: for.c,v 1.172 2023/05/08 09:01:20 rillig Exp $");
typedef struct ForLoop {
@@ -72,6 +72,22 @@ typedef struct ForLoop {
static ForLoop *accumFor; /* Loop being accumulated */
+/* See LK_FOR_BODY. */
+static void
+skip_whitespace_or_line_continuation(const char **pp)
+{
+ const char *p = *pp;
+ for (;;) {
+ if (ch_isspace(*p))
+ p++;
+ else if (p[0] == '\\' && p[1] == '\n')
+ p += 2;
+ else
+ break;
+ }
+ *pp = p;
+}
+
static ForLoop *
ForLoop_New(void)
{
@@ -221,7 +237,7 @@ For_Eval(const char *line)
ForLoop *f;
p = line + 1; /* skip the '.' */
- cpp_skip_whitespace(&p);
+ skip_whitespace_or_line_continuation(&p);
if (IsFor(p)) {
p += 3;
@@ -254,7 +270,7 @@ For_Accum(const char *line, int *forLeve
if (*p == '.') {
p++;
- cpp_skip_whitespace(&p);
+ skip_whitespace_or_line_continuation(&p);
if (IsEndfor(p)) {
DEBUG1(FOR, "For: end for %d\n", *forLevel);
Index: src/usr.bin/make/unit-tests/directive-for.exp
diff -u src/usr.bin/make/unit-tests/directive-for.exp:1.12 src/usr.bin/make/unit-tests/directive-for.exp:1.13
--- src/usr.bin/make/unit-tests/directive-for.exp:1.12 Sat Jan 8 20:21:34 2022
+++ src/usr.bin/make/unit-tests/directive-for.exp Mon May 8 09:01:20 2023
@@ -26,17 +26,16 @@ make: "directive-for.mk" line 187: 1 ope
make: "directive-for.mk" line 203: for-less endfor
make: "directive-for.mk" line 204: if-less endif
make: "directive-for.mk" line 212: if-less endif
+For: new loop 2
+For: end for 2
For: end for 1
For: loop body:
.\
for inner in i
.\
endfor
-make: "directive-for.mk" line 229: Unexpected end of file in .for loop
+For: end for 1
For: loop body:
-.\
- endfor
-make: "directive-for.mk" line 227: for-less endfor
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
Index: src/usr.bin/make/unit-tests/directive-for.mk
diff -u src/usr.bin/make/unit-tests/directive-for.mk:1.15 src/usr.bin/make/unit-tests/directive-for.mk:1.16
--- src/usr.bin/make/unit-tests/directive-for.mk:1.15 Sat Oct 1 09:23:04 2022
+++ src/usr.bin/make/unit-tests/directive-for.mk Mon May 8 09:01:20 2023
@@ -1,4 +1,4 @@
-# $NetBSD: directive-for.mk,v 1.15 2022/10/01 09:23:04 rillig Exp $
+# $NetBSD: directive-for.mk,v 1.16 2023/05/08 09:01:20 rillig Exp $
#
# Tests for the .for directive.
#
@@ -214,12 +214,19 @@ var= outer
.endif # no 'if-less endif'
-# When make parses a .for loop, it assumes that there is no line break between
-# the '.' and the 'for' or 'endfor', as there is no practical reason to break
-# the line at this point. When make scans the outer .for loop, it does not
-# recognize the inner directives as such. When make scans the inner .for
-# loop, it recognizes the '.\n for' but does not recognize the '.\n endfor',
-# as LK_FOR_BODY preserves the backslash-newline sequences.
+# Before for.c 1.172 from 2023-05-08, when make parsed a .for loop, it
+# assumed that there was no line continuation between the '.' and the 'for'
+# or 'endfor', as there is no practical reason to break the line at this
+# point.
+#
+# When make scanned the outer .for loop, it did not recognize the inner .for
+# loop as such and instead treated it as an unknown directive. The body of
+# the outer .for loop thus ended above the '.endfor'.
+#
+# When make scanned the inner .for loop, it did not recognize the inner
+# .endfor as such, which led to a parse error 'Unexpected end of file in .for
+# loop' from the '.endfor' line, followed by a second parse error 'for-less
+# .endfor' from the '.\\n endfor' line.
.MAKEFLAGS: -df
.for outer in o
.\