diff options
-rw-r--r-- | miscutils/make.c | 30 | ||||
-rwxr-xr-x | 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 * | |||
1401 | process_command(char *s) | 1401 | process_command(char *s) |
1402 | { | 1402 | { |
1403 | char *t, *u; | 1403 | char *t, *u; |
1404 | int len = strlen(s) + 1; | ||
1405 | char *outside = xzalloc(len); | ||
1404 | 1406 | ||
1405 | // Remove tab following escaped newline. Stop processing at a | 1407 | for (t = skip_macro(s); *t; t = skip_macro(t + 1)) { |
1406 | // non-escaped newline. | 1408 | outside[t - s] = 1; |
1407 | for (t = u = s; *u && *u != '\n'; u++) { | 1409 | } |
1408 | *t++ = *u; | 1410 | |
1411 | // Process escaped newlines. Stop at first non-escaped newline. | ||
1412 | for (t = u = s; *u && *u != '\n'; ) { | ||
1409 | if (u[0] == '\\' && u[1] == '\n') { | 1413 | if (u[0] == '\\' && u[1] == '\n') { |
1410 | *t++ = '\n'; | 1414 | if (posix || outside[u - s]) { |
1411 | u += (u[2] == '\t') ? 2 : 1; | 1415 | // Outside macro: remove tab following escaped newline. |
1416 | *t++ = *u++; | ||
1417 | *t++ = *u++; | ||
1418 | u += (*u == '\t'); | ||
1419 | } else { | ||
1420 | // Inside macro: replace escaped newline and any leading | ||
1421 | // whitespace on the following line with a single space. | ||
1422 | u += 2; | ||
1423 | while (isspace(*u)) | ||
1424 | ++u; | ||
1425 | *t++ = ' '; | ||
1426 | } | ||
1427 | } else { | ||
1428 | *t++ = *u++; | ||
1412 | } | 1429 | } |
1413 | } | 1430 | } |
1414 | *t = '\0'; | 1431 | *t = '\0'; |
1432 | free(outside); | ||
1415 | return s; | 1433 | return s; |
1416 | } | 1434 | } |
1417 | 1435 | ||
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 | |||
307 | ' | 307 | ' |
308 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null | 308 | cd .. || exit 1; rm -rf make.tempdir 2>/dev/null |
309 | 309 | ||
310 | # Escaped newlines inside macro expansions in commands get different | ||
311 | # treatment than those outside. In POSIX 2017 the output is 'a b ab'. | ||
312 | testing "make replace escaped NL in macro in command with space" \ | ||
313 | "make -f -" \ | ||
314 | "a b a b\n" "" ' | ||
315 | M=word | ||
316 | N=${M:word=a\ | ||
317 | b} | ||
318 | target: | ||
319 | @echo ${N} ${M:word=a\ | ||
320 | b} | ||
321 | ' | ||
322 | |||
310 | testing "make double-colon rule" \ | 323 | testing "make double-colon rule" \ |
311 | "make -f -" "target1\ntarget2\n" "" ' | 324 | "make -f -" "target1\ntarget2\n" "" ' |
312 | target:: | 325 | target:: |