aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-08-08 12:17:54 +0100
committerRon Yorston <rmy@pobox.com>2024-08-08 12:24:28 +0100
commite90345c1048f2c53074a1bd88e7870ee6a452b01 (patch)
tree08fd6ce81f7f322df21e0f2d7b7e7cd44f12cd61
parentc7f8fcfb3e26067019de01fdeeffd1ab556f73b9 (diff)
downloadbusybox-w32-e90345c1048f2c53074a1bd88e7870ee6a452b01.tar.gz
busybox-w32-e90345c1048f2c53074a1bd88e7870ee6a452b01.tar.bz2
busybox-w32-e90345c1048f2c53074a1bd88e7870ee6a452b01.zip
make: allow empty commands
pdpmake didn't allow rules to have empty commands. There are circumstances where this may be useful. Make the following changes: - Add a flag to readline() to indicate the next line is expected to be a command. If this flag is true and the input line starts with a tab return it immediately, thus skipping the check for an empty line or comment line. - In docmds() skip tabs and spaces after a command prefix. If the resulting command is empty don't print it or try to execute it. - In newcmd() allow empty commands. Adds 48-96 bytes. (pdpmake GitHub issue 56)
-rw-r--r--miscutils/make.c22
-rwxr-xr-xtestsuite/make.tests11
2 files changed, 23 insertions, 10 deletions
diff --git a/miscutils/make.c b/miscutils/make.c
index c65d32e78..1dfbd8c44 100644
--- a/miscutils/make.c
+++ b/miscutils/make.c
@@ -456,9 +456,6 @@ newcmd(struct cmd **cphead, char *str)
456 while (isspace(*str)) 456 while (isspace(*str))
457 str++; 457 str++;
458 458
459 if (*str == '\0') // No command, leave current head unchanged
460 return;
461
462 while (*cphead) 459 while (*cphead)
463 cphead = &(*cphead)->c_next; 460 cphead = &(*cphead)->c_next;
464 *cphead = xzalloc(sizeof(struct cmd)); 461 *cphead = xzalloc(sizeof(struct cmd));
@@ -1708,7 +1705,7 @@ make_fgets(char *s, int size, FILE *fd)
1708 * Ignore comment lines. Return NULL on EOF. 1705 * Ignore comment lines. Return NULL on EOF.
1709 */ 1706 */
1710static char * 1707static char *
1711readline(FILE *fd) 1708readline(FILE *fd, int want_command)
1712{ 1709{
1713 char *p, *str = NULL; 1710 char *p, *str = NULL;
1714 int pos = 0; 1711 int pos = 0;
@@ -1748,6 +1745,9 @@ readline(FILE *fd)
1748 } 1745 }
1749 dispno = lineno; 1746 dispno = lineno;
1750 1747
1748 if (want_command && *str == '\t')
1749 return str;
1750
1751 // Check for comment lines and lines that are conditionally skipped. 1751 // Check for comment lines and lines that are conditionally skipped.
1752 p = str; 1752 p = str;
1753 while (isblank(*p)) 1753 while (isblank(*p))
@@ -2043,7 +2043,7 @@ input(FILE *fd, int ilevel)
2043 bool minus; 2043 bool minus;
2044 2044
2045 lineno = 0; 2045 lineno = 0;
2046 str1 = readline(fd); 2046 str1 = readline(fd, FALSE);
2047 while (str1) { 2047 while (str1) {
2048 str2 = NULL; 2048 str2 = NULL;
2049 if (*str1 == '\t') // Command without target 2049 if (*str1 == '\t') // Command without target
@@ -2292,7 +2292,7 @@ input(FILE *fd, int ilevel)
2292 2292
2293 // Create list of commands 2293 // Create list of commands
2294 startno = dispno; 2294 startno = dispno;
2295 while ((str2 = readline(fd)) && *str2 == '\t') { 2295 while ((str2 = readline(fd, TRUE)) && *str2 == '\t') {
2296 newcmd(&cp, process_command(str2)); 2296 newcmd(&cp, process_command(str2));
2297 free(str2); 2297 free(str2);
2298 } 2298 }
@@ -2343,7 +2343,7 @@ input(FILE *fd, int ilevel)
2343 end_loop: 2343 end_loop:
2344 free(str1); 2344 free(str1);
2345 dispno = lineno; 2345 dispno = lineno;
2346 str1 = str2 ? str2 : readline(fd); 2346 str1 = str2 ? str2 : readline(fd, FALSE);
2347 free(copy); 2347 free(copy);
2348 free(expanded); 2348 free(expanded);
2349#if ENABLE_FEATURE_MAKE_POSIX 2349#if ENABLE_FEATURE_MAKE_POSIX
@@ -2427,7 +2427,9 @@ docmds(struct name *np, struct cmd *cp)
2427 sdomake = TRUE + 1; 2427 sdomake = TRUE + 1;
2428 else 2428 else
2429 break; 2429 break;
2430 q++; 2430 do {
2431 q++;
2432 } while (isblank(*q));
2431 } 2433 }
2432 2434
2433 if (sdomake > TRUE) { 2435 if (sdomake > TRUE) {
@@ -2437,7 +2439,7 @@ docmds(struct name *np, struct cmd *cp)
2437 } else if (!sdomake) 2439 } else if (!sdomake)
2438 ssilent = dotouch; 2440 ssilent = dotouch;
2439 2441
2440 if (!ssilent) { 2442 if (!ssilent && *q != '\0') { // Ignore empty commands
2441 puts(q); 2443 puts(q);
2442 fflush_all(); 2444 fflush_all();
2443 } 2445 }
@@ -2448,7 +2450,7 @@ docmds(struct name *np, struct cmd *cp)
2448 continue; 2450 continue;
2449 } 2451 }
2450 2452
2451 if (sdomake) { 2453 if (sdomake && *q != '\0') { // Ignore empty commands
2452 // Get the shell to execute it 2454 // Get the shell to execute it
2453 int status; 2455 int status;
2454 char *cmd = !signore && posix ? auto_concat("set -e;", q) : q; 2456 char *cmd = !signore && posix ? auto_concat("set -e;", q) : q;
diff --git a/testsuite/make.tests b/testsuite/make.tests
index 2425ae99d..5485233f6 100755
--- a/testsuite/make.tests
+++ b/testsuite/make.tests
@@ -31,6 +31,17 @@ testing "make .DEFAULT rule for prerequisite" \
31target: source 31target: source
32' 32'
33 33
34mkdir make.tempdir && cd make.tempdir || exit 1
35touch target.xyz
36testing "make empty command overrides inference rule" \
37 "make -f - target 2>/dev/null" "" "" '
38.SUFFIXES: .xyz
39.xyz:
40 @echo xyz
41target: ;
42'
43cd .. || exit 1; rm -rf make.tempdir 2>/dev/null
44
34# Macros should be expanded before suffix substitution. The suffixes 45# Macros should be expanded before suffix substitution. The suffixes
35# can be obtained by macro expansion. 46# can be obtained by macro expansion.
36testing "make macro expansion and suffix substitution" \ 47testing "make macro expansion and suffix substitution" \