summaryrefslogtreecommitdiff
path: root/usr.bin/make
diff options
context:
space:
mode:
authorrillig <rillig@NetBSD.org>2023-05-08 09:01:20 +0000
committerrillig <rillig@NetBSD.org>2023-05-08 09:01:20 +0000
commit9efaea6000b02478f1989849fc7a60593d655ae9 (patch)
tree3985256357ab681bc9f0f4d67f574ac24b74ee84 /usr.bin/make
parentebe425a903580ff17e65ee10f2d678bf4bba44f6 (diff)
make: fix parsing of unusual line continuations in .for loops
Diffstat (limited to 'usr.bin/make')
-rw-r--r--usr.bin/make/for.c24
-rw-r--r--usr.bin/make/unit-tests/directive-for.exp7
-rw-r--r--usr.bin/make/unit-tests/directive-for.mk21
3 files changed, 37 insertions, 15 deletions
diff --git a/usr.bin/make/for.c b/usr.bin/make/for.c
index 089d32efed7..3b606da63bc 100644
--- a/usr.bin/make/for.c
+++ b/usr.bin/make/for.c
@@ -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 *forLevel)
if (*p == '.') {
p++;
- cpp_skip_whitespace(&p);
+ skip_whitespace_or_line_continuation(&p);
if (IsEndfor(p)) {
DEBUG1(FOR, "For: end for %d\n", *forLevel);
diff --git a/usr.bin/make/unit-tests/directive-for.exp b/usr.bin/make/unit-tests/directive-for.exp
index dda487917e6..af99d5f41cf 100644
--- a/usr.bin/make/unit-tests/directive-for.exp
+++ b/usr.bin/make/unit-tests/directive-for.exp
@@ -26,17 +26,16 @@ make: "directive-for.mk" line 187: 1 open conditional
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
diff --git a/usr.bin/make/unit-tests/directive-for.mk b/usr.bin/make/unit-tests/directive-for.mk
index 95171c68031..9b05ad90d9c 100644
--- a/usr.bin/make/unit-tests/directive-for.mk
+++ b/usr.bin/make/unit-tests/directive-for.mk
@@ -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
.\