]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 62514] Honor command line interface flags
authorDmitry Goncharov <dgoncharov@users.sf.net>
Sat, 18 Jun 2022 21:14:46 +0000 (17:14 -0400)
committerPaul Smith <psmith@gnu.org>
Sat, 9 Jul 2022 14:43:33 +0000 (10:43 -0400)
Commit f2771aa614 introduced a bug where some switches were left out
of MAKEFLAGS.  Instead of resetting switches, get the same results by
filtering out duplicates.

* src/makeint.h: Remove reset_switches.
* src/main.c: (reset_switches): Remove reset_switches.
* (main): Remove call to reset_switches.
* (decode_switches): Filter out duplicate flags.
* src/variable.c: (set_special_var):  Remove call to reset_switches.
* tests/scripts/variables/MAKEFLAGS: Verify that duplicate flags are
properly filtered out.

src/main.c
src/makeint.h
src/variable.c
tests/scripts/variables/MAKEFLAGS

index 3dcbe441621604b8d105cac8bcddd66a4ce3e7f9..d31223dd41115ed09616d2fa7785c2c35a394408 100644 (file)
@@ -1998,9 +1998,6 @@ main (int argc, char **argv, char **envp)
     /* Read all the makefiles.  */
     read_files = read_all_makefiles (makefiles == 0 ? 0 : makefiles->list);
 
-    /* Reset switches that are taken from MAKEFLAGS so we don't get dups.  */
-    reset_switches ();
-
     arg_job_slots = INVALID_JOB_SLOTS;
 
     /* Decode switches again, for variables set by the makefile.  */
@@ -3025,55 +3022,6 @@ print_usage (int bad)
   fprintf (usageto, _("Report bugs to <bug-make@gnu.org>\n"));
 }
 
-/* Reset switches that come from MAKEFLAGS and go to MAKEFLAGS.
-   Before re-parsing MAKEFLAGS, start from scratch.  */
-
-void
-reset_switches ()
-{
-  const struct command_switch *cs;
-
-  for (cs = switches; cs->c != '\0'; ++cs)
-    if (cs->value_ptr && cs->env && cs->toenv)
-      switch (cs->type)
-        {
-        case ignore:
-          break;
-
-        case flag:
-        case flag_off:
-          if (cs->default_value)
-            *(int *) cs->value_ptr = *(int *) cs->default_value;
-          break;
-
-        case positive_int:
-        case string:
-          /* These types are handled specially... leave them alone :(  */
-          break;
-
-        case floating:
-          if (cs->default_value)
-            *(double *) cs->value_ptr = *(double *) cs->default_value;
-          break;
-
-        case filename:
-        case strlist:
-          {
-            /* The strings are in the cache so don't free them.  */
-            struct stringlist *sl = *(struct stringlist **) cs->value_ptr;
-            if (sl)
-              {
-                sl->idx = 0;
-                sl->list[0] = 0;
-              }
-          }
-          break;
-
-        default:
-          abort ();
-        }
-}
-
 /* Decode switches from ARGC and ARGV.
    They came from the environment if ENV is nonzero.  */
 
@@ -3187,6 +3135,19 @@ decode_switches (int argc, const char **argv, int env)
                       sl->list = xrealloc ((void *)sl->list,
                                            sl->max * sizeof (char *));
                     }
+
+                  /* Filter out duplicate options.
+                   * Allow duplicate makefiles for backward compatibility.  */
+                  if (cs->c != 'f')
+                    {
+                      unsigned int k;
+                      for (k = 0; k < sl->idx; ++k)
+                        if (streq (sl->list[k], coptarg))
+                          break;
+                      if (k < sl->idx)
+                        break;
+                    }
+
                   if (cs->type == strlist)
                     sl->list[sl->idx++] = xstrdup (coptarg);
                   else if (cs->c == TEMP_STDIN_OPT)
index bb013fd1d400cd3c605d0d28c26141a2543da1db..47c7a6005f79fdaf07e52aaa3f0d4590ca562327 100644 (file)
@@ -535,7 +535,6 @@ void out_of_memory () NORETURN;
 #define ONS(_t,_a,_f,_n,_s)   _t((_a), INTSTR_LENGTH + strlen (_s), \
                                  (_f), (_n), (_s))
 
-void reset_switches ();
 void decode_env_switches (const char*, size_t line);
 void die (int) NORETURN;
 void pfatal_with_name (const char *) NORETURN;
index db3282fce9585bb804f71a0e0c53f6fc7f64febd..3cddfd6d5102b274e34bd2458d8244d4c0a75c8d 100644 (file)
@@ -1145,10 +1145,7 @@ set_special_var (struct variable *var)
       cmd_prefix = var->value[0]=='\0' ? RECIPEPREFIX_DEFAULT : var->value[0];
     }
   else if (streq (var->name, MAKEFLAGS_NAME))
-    {
-      reset_switches ();
-      decode_env_switches (STRING_SIZE_TUPLE(MAKEFLAGS_NAME));
-    }
+    decode_env_switches (STRING_SIZE_TUPLE(MAKEFLAGS_NAME));
 
   return var;
 }
index 5f51ecbf97aba7956b9a46db3b68cc54e451d1c7..c8d32631a8b9df0cd5e8bfbf7a503d70f521694b 100644 (file)
@@ -62,4 +62,71 @@ MAKEFLAGS= -I- -Ifoo -Ibar $MAKEFLAGS= -I- -Ifoo -Ibar');
 rmdir('foo');
 rmdir('bar');
 
+# Test that command line switches are all present in MAKEFLAGS.
+# sv 62514.
+my @opts;
+
+# Simple flags.
+@opts = ('i', 'k', 'n', 'q', 'r', 's', 'w', 'd');
+exists $FEATURES{'check-symlink'} and push @opts, 'L';
+
+for my $opt (@opts) {
+  run_make_test(q!
+MAKEFLAGS:=B
+all:; $(info makeflags='$(MAKEFLAGS)')
+!, "-$opt", "/makeflags='B$opt'/");
+}
+
+# Switches which carry arguments.
+@opts = (' -I/tmp', ' -Onone', ' --debug=b', ' -l2.5');
+for my $opt (@opts) {
+  run_make_test(q!
+MAKEFLAGS:=B
+all:; $(info makeflags='$(MAKEFLAGS)')
+!, "$opt", "/makeflags='B$opt'/");
+}
+
+# Long options which take no arguments.
+# sv 62514.
+@opts = (' --no-print-directory', ' --warn-undefined-variables', ' --trace');
+for my $opt (@opts) {
+run_make_test(q!
+MAKEFLAGS:=B
+all:; $(info makeflags='$(MAKEFLAGS)')
+!, "$opt", "/makeflags='B$opt'/");
+}
+
+# Test that make filters out duplicates.
+# Each option is specified in the makefile, env and on the command line.
+@opts = (' -I/tmp', ' -Onone', ' --debug=b', ' -l2.5');
+$ENV{'MAKEFLAGS'} = $opt;
+for my $opt (@opts) {
+  run_make_test("
+MAKEFLAGS:=B $opt
+all:; \$(info makeflags='\$(MAKEFLAGS)')
+", "$opt", "/makeflags='B$opt'/");
+}
+
+# Test that make filters out duplicates.
+# Each option is specified in the makefile, env and on the command line.
+# decode_switches reallocates when the number of parameters in sl->list exceeds 5.
+# This test exercises the realloc branch.
+$ENV{'MAKEFLAGS'} = '-I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6 -I2 -I2';
+run_make_test(q!
+MAKEFLAGS:=B -I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6 -I2 -I2
+all:; $(info makeflags='$(MAKEFLAGS)')
+!,
+'-I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6',
+"/makeflags='B -I1 -I2 -I3 -I4 -I5 -I6 -l2.5 -Onone --debug=b'/");
+
+# A mix of multiple flags from env, the makefile and command line.
+# Skip -L since it's not available everywhere
+$ENV{'MAKEFLAGS'} = 'ikB --no-print-directory --warn-undefined-variables --trace';
+run_make_test(q!
+MAKEFLAGS:=iknqrswd -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5
+all:; $(info makeflags='$(MAKEFLAGS)')
+!,
+'-Onone -l2.5 -l2.5 -Onone -I/tmp -iknqrswd -i -n -s -k -I/tmp',
+"/makeflags='Bdiknqrsw -I/tmp -l2.5 -Onone --trace --warn-undefined-variables'/");
+
 1;