diff options
| author | rillig <rillig@NetBSD.org> | 2023-05-08 09:01:20 +0000 |
|---|---|---|
| committer | rillig <rillig@NetBSD.org> | 2023-05-08 09:01:20 +0000 |
| commit | 9efaea6000b02478f1989849fc7a60593d655ae9 (patch) | |
| tree | 3985256357ab681bc9f0f4d67f574ac24b74ee84 /usr.bin/make | |
| parent | ebe425a903580ff17e65ee10f2d678bf4bba44f6 (diff) | |
make: fix parsing of unusual line continuations in .for loops
Diffstat (limited to 'usr.bin/make')
| -rw-r--r-- | usr.bin/make/for.c | 24 | ||||
| -rw-r--r-- | usr.bin/make/unit-tests/directive-for.exp | 7 | ||||
| -rw-r--r-- | usr.bin/make/unit-tests/directive-for.mk | 21 |
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 .\ |
