From 28af22c256a385db7d65a42ff6de0b8573131236 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 30 Oct 2022 14:24:42 +0000 Subject: make: different treatment for escaped NL in macro in command Austin Group defect report 1549 has been accepted. It requires that an escaped newline inside a macro expansion in a command is replaced by a space. Other escaped newlines in commands are left in place, as before. --- miscutils/make.c | 30 ++++++++++++++++++++++++------ testsuite/make.tests | 13 +++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/miscutils/make.c b/miscutils/make.c index df46256bb..111ab2914 100644 --- a/miscutils/make.c +++ b/miscutils/make.c @@ -1401,17 +1401,35 @@ static char * process_command(char *s) { char *t, *u; + int len = strlen(s) + 1; + char *outside = xzalloc(len); - // Remove tab following escaped newline. Stop processing at a - // non-escaped newline. - for (t = u = s; *u && *u != '\n'; u++) { - *t++ = *u; + for (t = skip_macro(s); *t; t = skip_macro(t + 1)) { + outside[t - s] = 1; + } + + // Process escaped newlines. Stop at first non-escaped newline. + for (t = u = s; *u && *u != '\n'; ) { if (u[0] == '\\' && u[1] == '\n') { - *t++ = '\n'; - u += (u[2] == '\t') ? 2 : 1; + if (posix || outside[u - s]) { + // Outside macro: remove tab following escaped newline. + *t++ = *u++; + *t++ = *u++; + u += (*u == '\t'); + } else { + // Inside macro: replace escaped newline and any leading + // whitespace on the following line with a single space. + u += 2; + while (isspace(*u)) + ++u; + *t++ = ' '; + } + } else { + *t++ = *u++; } } *t = '\0'; + free(outside); return s; } diff --git a/testsuite/make.tests b/testsuite/make.tests index 35d3b7149..8b46faf3c 100755 --- a/testsuite/make.tests +++ b/testsuite/make.tests @@ -307,6 +307,19 @@ target: file1 .WAIT file2 ' cd .. || exit 1; rm -rf make.tempdir 2>/dev/null +# Escaped newlines inside macro expansions in commands get different +# treatment than those outside. In POSIX 2017 the output is 'a b ab'. +testing "make replace escaped NL in macro in command with space" \ + "make -f -" \ + "a b a b\n" "" ' +M=word +N=${M:word=a\ +b} +target: + @echo ${N} ${M:word=a\ +b} +' + testing "make double-colon rule" \ "make -f -" "target1\ntarget2\n" "" ' target:: -- cgit v1.2.3-55-g6feb