]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 61805] Support quoted whitespace in .SHELLFLAGS with .ONESHELL
authorDmitry Goncharov <dgoncharov@users.sf.net>
Mon, 24 Jan 2022 05:57:28 +0000 (00:57 -0500)
committerPaul Smith <psmith@gnu.org>
Sun, 6 Feb 2022 23:46:32 +0000 (18:46 -0500)
* src/job.c (construct_command_argv_internal): Call recursively to
parse .SHELLFLAGS when .ONESHELL is active.
* tests/scripts/targets/ONESHELL: Add tests.

src/job.c
tests/scripts/targets/ONESHELL

index 3c52074e5e5ae3a8b7988ce2dbe2152b183e82c6..9ae3cd6b19fde703e6db00c17822542ca1b98327 100644 (file)
--- a/src/job.c
+++ b/src/job.c
@@ -2657,8 +2657,8 @@ void clean_tmp (void)
    avoid using a shell.  This routine handles only ' quoting, and " quoting
    when no backslash, $ or ' characters are seen in the quotes.  Starting
    quotes may be escaped with a backslash.  If any of the characters in
-   sh_chars is seen, or any of the builtin commands listed in sh_cmds
-   is the first word of a line, the shell is used.
+   sh_chars is seen, or any of the builtin commands listed in sh_cmds is the
+   first word of a line, the shell is used.
 
    If RESTP is not NULL, *RESTP is set to point to the first newline in LINE.
    If *RESTP is NULL, newlines will be ignored.
@@ -2666,10 +2666,14 @@ void clean_tmp (void)
    SHELL is the shell to use, or nil to use the default shell.
    IFS is the value of $IFS, or nil (meaning the default).
 
-   FLAGS is the value of lines_flags for this command line.  It is
-   used in the WINDOWS32 port to check whether + or $(MAKE) were found
-   in this command line, in which case the effect of just_print_flag
-   is overridden.  */
+   FLAGS is the value of lines_flags for this command line.  It is used in the
+   WINDOWS32 port to check whether + or $(MAKE) were found in this command
+   line, in which case the effect of just_print_flag is overridden.
+
+   The returned value is either NULL if the line was empty, or else a pointer
+   to an array of strings.  The fist pointer points to the memory used by all
+   the strings, so to free you free the 0'th element then the returned pointer
+   (see the FREE_ARGV macro).  */
 
 static char **
 construct_command_argv_internal (char *line, char **restp, const char *shell,
@@ -3369,11 +3373,16 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
             new_argv[n++] = xstrdup ("");
           else
             {
-              const char *s = shellflags;
-              char *t;
-              size_t len;
-              while ((t = find_next_token (&s, &len)) != 0)
-                new_argv[n++] = xstrndup (t, len);
+              /* Parse shellflags using construct_command_argv_internal to
+                 handle quotes. */
+              char **argv;
+              char *f;
+              f = alloca (sflags_len + 1); // +1 for null terminator.
+              memcpy (f, shellflags, sflags_len + 1);
+              argv = construct_command_argv_internal (f, 0, 0, 0, 0, flags, 0);
+              for (char **a = argv; a && *a; ++a)
+                new_argv[n++] = *a;
+              free (argv);
             }
 
           /* Set the command to invoke.  */
index 3876966aec57917dbe215884646bd8a8cb4696ba..481de088eda6062a9c9dd182674ec10b5bee3e2c 100644 (file)
@@ -89,6 +89,55 @@ all:
 >print "a = $$a, y = (@y)\n";
 !,
                   '', "a = 12, y = (a b c)\n");
+
+    # Simple .SHELLFLAGS, no quotes.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL:
+SHELL = #PERL#
+.SHELLFLAGS = -e
+all:; @print "it works\n"
+!, '', 'it works');
+
+    # Pass a quoted string with spaces to oneshell.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL:
+SHELL = #PERL#
+.SHELLFLAGS = -w -E 'use warnings FATAL => "all";' -E
+all:; @print "it works\n"
+!, '', 'it works');
+
+    # Empty .SHELLFLAGS.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL:
+SHELL = #PERL#
+.SHELLFLAGS =
+all:; @print "it works"
+!, '', "Can't open perl script \"print \"it works\"\": $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:5: all] Error 2", 512);
+
+    # No .SHELLFLAGS.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL:
+SHELL = #PERL#
+all:; @print "it works"
+!, '', "Can't open perl script \"print \"it works\"\": $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:4: all] Error 2", 512);
+
+    # Pass a quoted string with spaces to oneshell.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL:
+SHELL = #PERL#
+.SHELLFLAGS = -w -E 'use warnings FATAL => "all";' -E 'my $$foo = "bar";' -E
+all:; @print "it works: $$foo\n"
+!, '', 'it works: bar');
 }
 
+# This tells the test driver that the perl test script executed properly.
 1;
+
+### Local Variables:
+### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
+### End: