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
 .\

Reply via email to