[RFC PATCH v4 3/3] Tests for .ONESHELL with a prerequisite

Britton Leo Kerin <[email protected]>
Newsgroups gmane.comp.gnu.make.bugs
Message-ID <[email protected]>
---
 src/job.c                      |  22 -
 tests/scripts/targets/ONESHELL | 848 +++++++++++++++++++++++++++++++++
 2 files changed, 848 insertions(+), 22 deletions(-)

diff --git a/src/job.c b/src/job.c
index f0a7f6cb..cd24d290 100644
--- a/src/job.c
+++ b/src/job.c
@@ -1135,28 +1135,6 @@ free_child (struct child *child)
       unsigned short ncommand_lines;
       if ( child->file->oneshell ) {
         ncommand_lines = child->file->cmds->oneshell_ncommand_lines;
-        // FIXME: WORK POINT: well this checkpoint hits with a built-in
-        // implicit rule but how do we test this from a test, since the
-        // built-in rules are all one line?  Just add a comment to the test
-        // script indicating that it's been tried, and that things have been
-        // arranged that way to avoid changing code paths for the built-in
-        // suffix and implicit rules?  Same issue when built-in suffix rules
-        // are triggered (though for all I know they essentially compile
-        // to the corresponding implicit rule with which they shave a cmds
-        // structure (I sort of think they don't but I'd need to check)
-        //
-        // Other things that I've tried that still need tests written:
-        //   * match-anything implicit terminal rules (::)
-        //   * match-anything implicit non-terminal rules (not ::)
-        //   * implicit rules
-        //   * .DEFAULT rules
-        //   * double-suffix rules
-        //   * single-suffic rules
-        //
-        // Things that haven't been tried yet:
-        //   * That all the line flags (no output, no errors, recurse, and
-        //     recurse due to $(MAKE)) var ref work as documented
-        //
         mCP ();
       }
       else {
diff --git a/tests/scripts/targets/ONESHELL b/tests/scripts/targets/ONESHELL
index 0ae9b5b7..0f3fad01 100644
--- a/tests/scripts/targets/ONESHELL
+++ b/tests/scripts/targets/ONESHELL
@@ -40,6 +40,7 @@ all:
 ');
 }
 
+# FIXME: test if we actually expect a POSIX-style shell before running this?
 # Again, but this time with inner prefix chars
 
 run_make_test(q!
@@ -63,6 +64,7 @@ all:
               '', '');
 
 
+# FIXME: test if we actually expect a POSIX-style shell before running this?
 # This time with outer and inner prefix chars
 
 run_make_test(q!
@@ -76,6 +78,7 @@ all:
 
 # Now try using a different interpreter
 # This doesn't work on Windows right now
+
 if ($port_type ne 'W32') {
     run_make_test(q!
 .RECIPEPREFIX = >
@@ -135,6 +138,851 @@ all:; @print "it works: $$foo\n"
 !, '', 'it works: bar');
 }
 
+# .ONESHELL with a prerequisite
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+normal_target:
+	a=$$$$
+	[ 0"$$a" -ne "$$$$" ] || echo fail
+oneshell_target:
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+
+# Another target when there exists a .ONESHELL with a prerequisite
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+normal_target:
+	a=$$$$
+	[ 0"$$a" -ne "$$$$" ] || echo fail
+oneshell_target:
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'normal_target', 'a=$$
+[ 0"$a" -ne "$$" ] || echo fail
+');
+
+# .ONESHELL with a prerequisite that doesn't have a recipe
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+oneshell_target:
+!,
+              'oneshell_target', "#MAKE#: Nothing to be done for 'oneshell_target'.");
+
+# .ONESHELL with a prerequisite with multi-word SHELLFLAGS
+
+if ($multi_ok) {
+    run_make_test(q!
+.ONESHELL: oneshell_target
+.SHELLFLAGS = -e -c
+oneshell_target:
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+}
+
+# FIXME: test if we actually expect a POSIX-style shell before running this?
+# .ONESHELL with a prerequisite with inner prefix chars
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+oneshell_target:
+	a=$$$$
+	@-+    [ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+
+# .ONESHELL with a prerequisite with outer prefix chars
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+oneshell_target:
+	@a=$$$$
+	 [ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target', '');
+
+# FIXME: test if we actually expect a POSIX-style shell before running this?
+# .ONESHELL with a prerequisite with outer and inner prefix chars
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+oneshell_target:
+	@a=$$$$
+	 -@     +[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target', '');
+
+
+# .ONESHELL with a prerequisite using a different interpreter
+# This doesn't work on Windows right now
+
+if ($port_type ne 'W32') {
+    run_make_test(q!
+.RECIPEPREFIX = >
+.ONESHELL: oneshell_target
+SHELL = #PERL#
+.SHELLFLAGS = -e
+oneshell_target:
+>	   @$$a=5
+>	    +7;
+>	@y=qw(a b c);
+>print "a = $$a, y = (@y)\n";
+!,
+                  'oneshell_target', "a = 12, y = (a b c)\n");
+
+    # Simple .SHELLFLAGS, no quotes.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL:
+SHELL = #PERL#
+.SHELLFLAGS = -e
+oneshell_target:; @print "it works\n"
+!, 'oneshell_target', 'it works');
+
+    # Pass a quoted string with spaces to oneshell.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL: oneshell_target
+SHELL = #PERL#
+.SHELLFLAGS = -w -E 'use warnings FATAL => "all";' -E
+oneshell_target:; @print "it works\n"
+!, 'oneshell_target', 'it works');
+
+    # Empty .SHELLFLAGS.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL: oneshell_target
+SHELL = #PERL#
+.SHELLFLAGS =
+oneshell_target:; @print "it works"
+!, 'oneshell_target', "Can't open perl script \"print \"it works\"\": $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:5: oneshell_target] Error $ERR_no_such_file_code", 512);
+
+    # No .SHELLFLAGS.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL: oneshell_target
+SHELL = #PERL#
+oneshell_target:; @print "it works"
+!, 'oneshell_target', "Can't open perl script \"print \"it works\"\": $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:4: oneshell_target] Error $ERR_no_such_file_code", 512);
+
+    # Pass a quoted string with spaces to oneshell.
+    # sv 61805.
+    run_make_test(q!
+.ONESHELL: oneshell_target
+SHELL = #PERL#
+.SHELLFLAGS = -w -E 'use warnings FATAL => "all";' -E 'my $$foo = "bar";' -E
+oneshell_target:; @print "it works: $$foo\n"
+!, 'oneshell_target', 'it works: bar');
+}
+
+# .ONESHELL with a prerequisite covered by a static pattern rule
+
+create_file('oneshell_target.foo');
+run_make_test(q!
+.ONESHELL: oneshell_target.bar
+oneshell_target.bar: %.bar: %.foo
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target.bar', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+rmfiles('oneshell_target.foo');
+
+# .ONESHELL with a prerequisite covered by an implicit rule
+
+create_file('oneshell_target.foo');
+run_make_test(q!
+.ONESHELL: oneshell_target.bar
+%.bar: %.foo
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target.bar', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+rmfiles('oneshell_target.foo');
+
+# .ONESHELL with a prerequisite covered by a match-anything implicit terminal
+# rule
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+%::
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+
+# .ONESHELL with a prerequisite covered by a match-anything implicit
+# non-terminal rule
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+%:
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+
+# .ONESHELL with a prerequisite covered by a .DEFAULT: rule
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+.DEFAULT:
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+
+# .ONESHELL with a prerequisite covered by a double-suffix rule
+
+create_file('oneshell_target.foo');
+run_make_test(q!
+.ONESHELL: oneshell_target.bar
+.SUFFIXES: .foo .bar
+.foo.bar:
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target.bar', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+rmfiles('oneshell_target.foo');
+
+# .ONESHELL with a prerequisite covered by a single-suffix rule
+
+create_file('oneshell_target.foo');
+run_make_test(q!
+.ONESHELL: oneshell_target
+.SUFFIXES: .foo
+.foo:
+	a=$$$$
+	[ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+              'oneshell_target', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+rmfiles('oneshell_target.foo');
+
+# FIXME: I think for static pattern rules it should be a hard error for part
+# of the covered set to be oneshell and part not.  It's always perilous
+# to guess what users have in mind, but it's seems like a pretty safe bet
+# they don't really intend the same chunk of code from the same rule to be
+# sometimes evaluated as oneshell and sometimes not.  For static pattern rules
+# this seems even more certain: a big part of the attraction of static pattern
+# rules is that they avoid a lot of the oddities and potential confusion of
+# implicit rules, and a variable holding the covered set probably already
+# exists, so also using it in the .ONESHELL: prerequisites list is low-effort.
+# IMO this and similar tests should be changed to confirm this error.
+
+# .ONESHELL with a prerequisite covered by a static pattern rule does not cause
+# other targets matched by the rule to be oneshell
+
+create_file('non_oneshell_target.foo');
+run_make_test(q!
+.ONESHELL: oneshell_target.bar
+oneshell_target.bar non_oneshell_target.bar: %.bar: %.foo
+	a=$$$$
+	[ 0"$$a" -ne "$$$$" ] || echo fail
+!,
+              'non_oneshell_target.bar', 'a=$$
+[ 0"$a" -ne "$$" ] || echo fail
+');
+rmfiles('non_oneshell_target.foo');
+
+# FIXME: I think for all types of implicit rules, .DEFAULT: rules, and
+# suffix rules at least a warning should be produced if the same recipe is
+# sometimes evaluated under oneshell and sometimes not.  See the comments
+# in the above fixme about the same issue with static pattern rules for
+# more details.  If it was decided to always make this situation an error
+# the implementation could be simplified (there would be no need to maintain
+# both normal and oneshell_* fields in struct commands).  This and similar
+# tests should be changed to verify that this warning or error is produced.
+
+# .ONESHELL with a prerequisite covered by an implicit rule does not cause
+# other targets matched by the rule to be oneshell
+
+create_file('non_oneshell_target.foo');
+run_make_test(q!
+.ONESHELL: oneshell_target.bar
+%.bar: %.foo
+	a=$$$$
+	[ 0"$$a" -ne "$$$$" ] || echo fail
+!,
+              'non_oneshell_target.bar', 'a=$$
+[ 0"$a" -ne "$$" ] || echo fail
+');
+rmfiles('non_oneshell_target.foo');
+
+# .ONESHELL with a prerequisite covered by a match-anything implicit terminal
+# rule does not cause other targets matched by the rule to be oneshell
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+%::
+	a=$$$$
+	[ 0"$$a" -ne "$$$$" ] || echo fail
+!,
+              'non_oneshell_target', 'a=$$
+[ 0"$a" -ne "$$" ] || echo fail
+');
+
+
+# .ONESHELL with a prerequisite covered by a match-anything implicit
+# non-terminal rule does not cause other targets matched by the rule to be
+# oneshell
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+%:
+	a=$$$$
+	[ 0"$$a" -ne "$$$$" ] || echo fail
+!,
+              'non_oneshell_target', 'a=$$
+[ 0"$a" -ne "$$" ] || echo fail
+');
+
+# .ONESHELL with a prerequisite covered by a .DEFAULT: rule does not cause
+# other targets matched by the rule to be oneshell
+
+run_make_test(q!
+.ONESHELL: oneshell_target
+.DEFAULT:
+	a=$$$$
+	[ 0"$$a" -ne "$$$$" ] || echo fail
+!,
+              'non_oneshell_target', 'a=$$
+[ 0"$a" -ne "$$" ] || echo fail
+');
+
+
+# .ONESHELL with a prerequisite covered by a double-suffix rule does not cause
+# other targets matched by the rule to be oneshell
+
+create_file('non_oneshell_target.foo');
+run_make_test(q!
+.ONESHELL: oneshell_target.bar
+.SUFFIXES: .foo .bar
+.foo.bar:
+	a=$$$$
+	[ 0"$$a" -ne "$$$$" ] || echo fail
+!,
+              'non_oneshell_target.bar', 'a=$$
+[ 0"$a" -ne "$$" ] || echo fail
+');
+rmfiles('non_oneshell_target.foo');
+
+# .ONESHELL with a prerequisite covered by a single-suffix rule does not cause
+# other targets matched by the rule to be oneshell
+
+create_file('non_oneshell_target.foo');
+run_make_test(q!
+.ONESHELL: oneshell_target
+.SUFFIXES: .foo
+.foo:
+	a=$$$$
+	[ 0"$$a" -ne "$$$$" ] || echo fail
+!,
+              'non_oneshell_target', 'a=$$
+[ 0"$a" -ne "$$" ] || echo fail
+');
+rmfiles('non_oneshell_target.foo');
+
+# FIXME: some other groups of tests could be organized and described in this
+# same slightly hierarchical way.  Alternately, if it's considered better
+# to keep everything flat and just have redundant comments, all tests in
+# this group could be changed to be like the other new tests.
+
+# Interactions between per-target .ONESHELL and special prefix characters.
+# These test are perhaps slightly over-effusive with respect to the
+# implementation.
+{
+    # There are seven types of rules: static pattern, implicit, match-anything
+    # terminal, match-anything non-terminal, .DEFAULT, double-suffix, and
+    # single-suffix.
+    #
+    # There are four behaviors of interest: .ONESHELL and non-.ONESHELL
+    # targets (which share a recipe with a .ONESHELL target) with 1st
+    # line prefix and with "internal" prefix.
+    #
+    # Test all combinations, taking the '@' prefix as representative:
+
+    # .ONESHELL target with 1st line prefix X static pattern
+# {{{1
+# .ONESHELL with a prerequisite covered by a static pattern rule causes
+# modified interpretation of prefix characters on the first recipe line
+
+    create_file('oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+oneshell_target.bar: %.bar: %.foo
+	@true
+	true
+!,
+                'oneshell_target.bar', '');
+    rmfiles('oneshell_target.foo');
+# }}}1
+    # .ONESHELL target with 1st line prefix X implicit
+# {{{1
+# .ONESHELL with a prerequisite covered by an implicit rule causes
+# modified interpretation of prefix characters on the first recipe line
+
+    create_file('oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+%.bar: %.foo
+	@true
+	true
+!,
+                'oneshell_target.bar', '');
+    rmfiles('oneshell_target.foo');
+# }}}1
+    # .ONESHELL target with 1st line prefix X match-anything terminal
+# {{{1
+
+# .ONESHELL with a prerequisite covered by a match-anything implicit terminal
+# rule causes modified interpretation of prefix characters on the first recipe
+# line
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+%::
+	@true
+	true
+!,
+                  'oneshell_target', '');
+# }}}1
+    # .ONESHELL target with 1st line prefix X match-anything non-terminal
+# {{{1
+
+# .ONESHELL with a prerequisite covered by an match-anything implicit
+# non-terminal rule causes modified interpretation of prefix characters on the
+# first recipe line
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+%:
+	@true
+	true
+!,
+                  'oneshell_target', '');
+    rmfiles('oneshell_target');
+# }}}1
+    # .ONESHELL target with 1st line prefix X .DEFAULT
+# {{{1
+
+# .ONESHELL with a prerequisite covered by an match-anything implicit
+# non-terminal rule causes modified interpretation of prefix characters on the
+# first recipe line
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+.DEFAULT:
+	@true
+	true
+!,
+                  'oneshell_target', '');
+    rmfiles('oneshell_target');
+# }}}1
+    # .ONESHELL target with 1st line prefix X double-suffix
+# {{{1
+# .ONESHELL with a prerequisite covered by a double-suffix rule causes modified
+# interpretation of prefix characters on the first recipe line
+
+    create_file('oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+.SUFFIXES: .foo .bar
+.foo.bar:
+	@true
+	true
+!,
+                'oneshell_target.bar', '');
+    rmfiles('oneshell_target.foo');
+# }}}1
+    # .ONESHELL target with 1st line prefix X single-suffix
+# {{{1
+# .ONESHELL with a prerequisite covered by a single-suffix rule causes modified
+# interpretation of prefix characters on the first recipe line
+
+    create_file('oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target
+.SUFFIXES: .foo
+.foo:
+	@true
+	true
+!,
+                'oneshell_target', '');
+    rmfiles('non_oneshell_target.foo');
+# }}}1
+
+    # FIXME: these need test for "POSIX-style" shell:
+    # .ONESHELL target with 1st line prefix X static pattern
+# {{{1
+# .ONESHELL with a prerequisite covered by a static pattern rule causes special
+# prefix characters on "internal" recipe lines to be ignored and removed
+
+    create_file('oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+oneshell_target.bar: %.bar: %.foo
+	true
+	@true
+!,
+                'oneshell_target.bar', 'true
+true');
+    rmfiles('oneshell_target.foo');
+# }}}1
+    # .ONESHELL target with "internal" prefix X implicit
+# {{{1
+# .ONESHELL with a prerequisite covered by an implicit rule causes special
+# prefix characters on "internal" recipe lines to be ignored and removed
+
+    create_file('oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+%.bar: %.foo
+	true
+	@true
+!,
+                'oneshell_target.bar', 'true
+true');
+    rmfiles('oneshell_target.foo');
+# }}}1
+    # .ONESHELL target with "internal" prefix X match-anything terminal
+# {{{1
+# .ONESHELL with a prerequisite covered by a match-anything implicit terminal
+# rule causes prefix characters on "internal" recipe lines to be ignored and
+# removed
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+%::
+	true
+	@true
+!,
+                  'oneshell_target', 'true
+true');
+# }}}1
+    # .ONESHELL target with "internal" prefix X match-anything non-terminal
+# {{{1
+# .ONESHELL with a prerequisite covered by a match-anything implicit terminal
+# rule causes prefix characters on "internal" recipe lines to be ignored and
+# removed
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+%:
+	true
+	@true
+!,
+                  'oneshell_target', 'true
+true');
+# }}}1
+    # .ONESHELL target with "internal" prefix X .DEFAULT
+# {{{1
+# .ONESHELL with a prerequisite covered by a match-anything implicit terminal
+# rule causes prefix characters on "internal" recipe lines to be ignored and
+# removed
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+.DEFAULT:
+	true
+	@true
+!,
+                  'oneshell_target', 'true
+true');
+# }}}1
+    # .ONESHELL target with "internal" prefix X double-suffix
+# {{{1
+# .ONESHELL with a prerequisite covered by a double-suffix rule causes special
+# prefix characters on "internal" recipe lines to be ignored and removed
+
+    create_file('oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+.SUFFIXES: .foo .bar
+.foo.bar:
+	true
+	@true
+!,
+                  'oneshell_target.bar', 'true
+true');
+    rmfiles('oneshell_target.foo');
+# }}}1
+    # .ONESHELL target with "internal" prefix X single-suffix
+# {{{1
+# .ONESHELL with a prerequisite covered by a single-suffix rule causes special
+# prefix characters on "internal" recipe lines to be ignored and removed
+
+    create_file('oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target
+.SUFFIXES: .foo
+.foo:
+	true
+	@true
+!,
+                'oneshell_target', 'true
+true');
+    rmfiles('oneshell_target.foo');
+# }}}1
+
+    # non-.ONESHELL target with 1st line special X static pattern
+# {{{1
+# .ONESHELL with a prerequisite covered by a static pattern rule does not cause
+# other targets matched by the rule to have the interpretation of internal
+# prefix characters in the recipe changed
+
+    create_file('non_oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+oneshell_target.bar non_oneshell_target.bar: %.bar: %.foo
+	true
+	@true
+!,
+                'non_oneshell_target.bar', 'true');
+    rmfiles('non_oneshell_target.foo');
+# }}}1
+    # non-.ONESHELL target with 1st line special X implicit
+# {{{1
+# .ONESHELL with a prerequisite covered by an implicit rule does not cause
+# other targets matched by the rule to have the interpretation of internal
+# prefix characters in the recipe changed
+
+    create_file('non_oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+%.bar: %.foo
+	true
+	@true
+!,
+                  'non_oneshell_target.bar', 'true');
+    rmfiles('non_oneshell_target.foo');
+# }}}1
+    # non-.ONESHELL target with 1st line special X match-anything terminal
+# {{{1
+# .ONESHELL with a prerequisite covered by a match-anything implicit terminal
+# rule does not cause other targets matched by the rule to have the
+# interpretation of internal prefix characters in the recipe changed
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+%::
+	true
+	@true
+!,
+                  'non_oneshell_target', 'true');
+# }}}1
+    # non-.ONESHELL target with 1st line special X match-anything non-terminal
+# {{{1
+# .ONESHELL with a prerequisite covered by a match-anything implicit
+# non-terminal rule does not cause other targets matched by the rule to have
+# the interpretation of internal prefix characters in the recipe changed
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+%:
+	true
+	@true
+!,
+                  'non_oneshell_target', 'true');
+# }}}1
+    # non-.ONESHELL target with 1st line special X .DEFAULT
+# {{{1
+# .ONESHELL with a prerequisite covered by a .DEFAULT: rule does not cause
+# other targets matched by the rule to have the interpretation of internal
+# prefix characters in the recipe changed
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+.DEFAULT:
+	true
+	@true
+!,
+                  'non_oneshell_target', 'true');
+# }}}1
+    # non-.ONESHELL target with 1st line special X double-suffix
+# {{{1
+# .ONESHELL with a prerequisite covered by a double-suffix rule does not cause
+# other targets matched by the rule to have the interpretation of internal
+# prefix characters in the recipe changed
+
+    create_file('non_oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+.SUFFIXES: .foo .bar
+.foo.bar:
+	true
+	@true
+!,
+                'non_oneshell_target.bar', 'true');
+    rmfiles('non_oneshell_target.foo');
+# }}}1
+    # non-.ONESHELL target with 1st line special X single-suffix
+# {{{1
+# .ONESHELL with a prerequisite covered by a single-suffix rule does not cause
+# other targets matched by the rule to have the interpretation of internal
+# prefix characters in the recipe changed
+
+    create_file('non_oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target
+.SUFFIXES: .foo
+.foo:
+	true
+	@true
+!,
+                'non_oneshell_target', 'true');
+    rmfiles('non_oneshell_target.foo');
+# }}}1
+
+    # non-.ONESHELL target with "internal" prefix X static pattern
+# {{{1
+# .ONESHELL with a prerequisite covered by an implicit rule does not cause
+# other targets matched by the rule to have the interpretation of "internal"
+# prefix characters in the recipe changed
+
+    create_file('non_oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+oneshell_target.bar non_oneshell_target.bar: %.bar: %.foo
+	true
+	@true
+!,
+                'non_oneshell_target.bar', 'true');
+    rmfiles('non_oneshell_target.foo');
+# }}}1
+    # non-.ONESHELL target with "internal" prefix X implicit
+# {{{1
+# .ONESHELL with a prerequisite covered by an implicit rule does not cause
+# other targets matched by the rule to have the interpretation of "internal"
+# prefix characters in the recipe changed
+
+    create_file('non_oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+%.bar: %.foo
+	true
+	@true
+!,
+                'non_oneshell_target.bar', 'true');
+    rmfiles('non_oneshell_target.foo');
+# }}}1
+    # non-.ONESHELL target with "internal" prefix X match-anything terminal
+# {{{1
+# .ONESHELL with a prerequisite covered by a match-anything implicit terminal
+# rule does not cause other targets matched by the rule to have the
+# interpretation of "internal" prefix characters in the recipe changed
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+%::
+	true
+	@true
+!,
+                  'non_oneshell_target', 'true');
+# }}}1
+    # non-.ONESHELL target with "internal" prefix X match-anything non-terminal
+# {{{1
+# .ONESHELL with a prerequisite covered by a match-anything implicit
+# non-terminal rule does not cause other targets matched by the rule to have
+# the interpretation of "internal" prefix characters in the recipe
+# changed
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+%:
+	true
+	@true
+!,
+                  'non_oneshell_target', 'true');
+# }}}1
+    # non-.ONESHELL target with "internal" prefix X .DEFAULT
+# {{{1
+# .ONESHELL with a prerequisite covered by a .DEFAULT: rule does not cause
+# other targets matched by the rule to have the interpretation of "internal"
+# prefix characters in the recipe changed
+
+    run_make_test(q!
+.ONESHELL: oneshell_target
+.DEFAULT:
+	true
+	@true
+!,
+                  'non_oneshell_target', 'true');
+# }}}1
+    # non-.ONESHELL target with "internal" prefix X double-suffix
+# {{{1
+# .ONESHELL with a prerequisite covered by a double-suffix rule does not cause
+# other targets matched by the rule to have the interpretation of internal
+# prefix characters in the recipe changed
+
+    create_file('non_oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target.bar
+.SUFFIXES: .foo .bar
+.foo.bar:
+	true
+	@true
+!,
+                  'non_oneshell_target.bar', 'true');
+    rmfiles('non_oneshell_target.foo');
+# }}}1
+    # non-.ONESHELL target with "internal" prefix X double-suffix
+# {{{1
+# .ONESHELL with a prerequisite covered by a single-suffix rule does not cause
+# other targets matched by the rule to have the interpretation of internal
+# prefix characters in the recipe changed
+
+    create_file('non_oneshell_target.foo');
+    run_make_test(q!
+.ONESHELL: oneshell_target
+.SUFFIXES: .foo
+.foo:
+	true
+	@true
+!,
+                  'non_oneshell_target', 'true');
+    rmfiles('non_oneshell_target.foo');
+# }}}1
+
+};
+
+# FIXME: the docs don't specify whether identification of MAKE references
+# in recipes in oneshell targets triggers special handling of -t, -n, and
+# -q flags
+
+# FIXME: the effect of $(MAKE) references in oneshell targets should be tested
+
+# FIXME: I checked manually that the code path for built-in implicit rules
+# doesn't change when they aren't explicit .ONESHELL prerequisites, but it's
+# hard to verify this with a test since all such rules consist of a single
+# line (I think they're theoretically identical anyway for this reason,
+# but it seem imprudent to change their code path) so no such tests exist yet.
+
 # This tells the test driver that the perl test script executed properly.
 1;
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.