[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.
This commit is contained in:
Dmitry Goncharov 2022-06-18 17:14:46 -04:00 committed by Paul Smith
parent 3ec497f8f8
commit c3b39d0654
4 changed files with 81 additions and 57 deletions

View 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)

View 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;

View 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;
}

View 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;