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