From: Dmitry Goncharov Date: Sat, 18 Jun 2022 21:14:46 +0000 (-0400) Subject: [SV 62514] Honor command line interface flags X-Git-Tag: 4.3.90~60 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c3b39d0654c3c5d8b24aaa07d2e6767c0d6e7dd6;p=thirdparty%2Fmake.git [SV 62514] Honor command line interface flags 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. --- diff --git a/src/main.c b/src/main.c index 3dcbe441..d31223dd 100644 --- a/src/main.c +++ b/src/main.c @@ -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 \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) diff --git a/src/makeint.h b/src/makeint.h index bb013fd1..47c7a600 100644 --- a/src/makeint.h +++ b/src/makeint.h @@ -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; diff --git a/src/variable.c b/src/variable.c index db3282fc..3cddfd6d 100644 --- a/src/variable.c +++ b/src/variable.c @@ -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; } diff --git a/tests/scripts/variables/MAKEFLAGS b/tests/scripts/variables/MAKEFLAGS index 5f51ecbf..c8d32631 100644 --- a/tests/scripts/variables/MAKEFLAGS +++ b/tests/scripts/variables/MAKEFLAGS @@ -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;