diff --git a/src/main.c b/src/main.c index 27f145c5..a5600391 100644 --- a/src/main.c +++ b/src/main.c @@ -136,6 +136,7 @@ int verify_flag; static int silent_flag; static const int default_silent_flag = 0; +static enum variable_origin silent_origin = o_default; /* Nonzero means either -s was given, or .SILENT-with-no-deps was seen. */ @@ -190,6 +191,7 @@ int no_builtin_variables_flag = 0; int keep_going_flag; static const int default_keep_going_flag = 0; +static enum variable_origin keep_going_origin = o_default; /* Nonzero means check symlink mtimes. */ @@ -197,6 +199,7 @@ int check_symlink_flag = 0; static int print_directory_flag = -1; static const int default_print_directory_flag = -1; +static enum variable_origin print_directory_origin = o_default; /* Nonzero means print version information. */ @@ -405,30 +408,31 @@ static int trace_flag = 0; struct command_switch { - int c; /* The switch character. */ + int c; /* The switch character. */ - enum /* Type of the value. */ + enum /* Type of the value. */ { - flag, /* Turn int flag on. */ - flag_off, /* Turn int flag off. */ - string, /* One string per invocation. */ - strlist, /* One string per switch. */ - filename, /* A string containing a file name. */ - positive_int, /* A positive integer. */ - floating, /* A floating-point number (double). */ - ignore /* Ignored. */ + flag, /* Turn int flag on. */ + flag_off, /* Turn int flag off. */ + string, /* One string per invocation. */ + strlist, /* One string per switch. */ + filename, /* A string containing a file name. */ + positive_int, /* A positive integer. */ + floating, /* A floating-point number (double). */ + ignore /* Ignored. */ } type; - void *value_ptr; /* Pointer to the value-holding variable. */ + void *value_ptr; /* Pointer to the value-holding variable. */ - unsigned int env:1; /* Can come from MAKEFLAGS. */ - unsigned int toenv:1; /* Should be put in MAKEFLAGS. */ - unsigned int no_makefile:1; /* Don't propagate when remaking makefiles. */ + unsigned int env:1; /* Can come from MAKEFLAGS. */ + unsigned int toenv:1; /* Should be put in MAKEFLAGS. */ + unsigned int no_makefile:1; /* Don't propagate when remaking makefiles. */ - const void *noarg_value; /* Pointer to value used if no arg given. */ - const void *default_value; /* Pointer to default value. */ + const void *noarg_value; /* Pointer to value used if no arg given. */ + const void *default_value; /* Pointer to default value. */ - const char *long_name; /* Long option name. */ + const char *long_name; /* Long option name. */ + enum variable_origin *origin; /* Origin of the value. */ }; /* The table of command switches. @@ -439,61 +443,62 @@ struct command_switch static const struct command_switch switches[] = { - { 'b', ignore, 0, 0, 0, 0, 0, 0, 0 }, - { 'B', flag, &always_make_set, 1, 1, 0, 0, 0, "always-make" }, - { 'd', flag, &debug_flag, 1, 1, 0, 0, 0, 0 }, - { 'e', flag, &env_overrides, 1, 1, 0, 0, 0, "environment-overrides", }, - { 'E', strlist, &eval_strings, 1, 0, 0, 0, 0, "eval" }, - { 'h', flag, &print_usage_flag, 0, 0, 0, 0, 0, "help" }, - { 'i', flag, &ignore_errors_flag, 1, 1, 0, 0, 0, "ignore-errors" }, + { 'b', ignore, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 'B', flag, &always_make_set, 1, 1, 0, 0, 0, "always-make", 0 }, + { 'd', flag, &debug_flag, 1, 1, 0, 0, 0, 0, 0 }, + { 'e', flag, &env_overrides, 1, 1, 0, 0, 0, "environment-overrides", 0 }, + { 'E', strlist, &eval_strings, 1, 0, 0, 0, 0, "eval", 0 }, + { 'h', flag, &print_usage_flag, 0, 0, 0, 0, 0, "help", 0 }, + { 'i', flag, &ignore_errors_flag, 1, 1, 0, 0, 0, "ignore-errors", 0 }, { 'k', flag, &keep_going_flag, 1, 1, 0, 0, &default_keep_going_flag, - "keep-going" }, - { 'L', flag, &check_symlink_flag, 1, 1, 0, 0, 0, "check-symlink-times" }, - { 'm', ignore, 0, 0, 0, 0, 0, 0, 0 }, - { 'n', flag, &just_print_flag, 1, 1, 1, 0, 0, "just-print" }, - { 'p', flag, &print_data_base_flag, 1, 1, 0, 0, 0, "print-data-base" }, - { 'q', flag, &question_flag, 1, 1, 1, 0, 0, "question" }, - { 'r', flag, &no_builtin_rules_flag, 1, 1, 0, 0, 0, "no-builtin-rules" }, + "keep-going", &keep_going_origin }, + { 'L', flag, &check_symlink_flag, 1, 1, 0, 0, 0, "check-symlink-times", 0 }, + { 'm', ignore, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 'n', flag, &just_print_flag, 1, 1, 1, 0, 0, "just-print", 0 }, + { 'p', flag, &print_data_base_flag, 1, 1, 0, 0, 0, "print-data-base", 0 }, + { 'q', flag, &question_flag, 1, 1, 1, 0, 0, "question", 0 }, + { 'r', flag, &no_builtin_rules_flag, 1, 1, 0, 0, 0, "no-builtin-rules", 0 }, { 'R', flag, &no_builtin_variables_flag, 1, 1, 0, 0, 0, - "no-builtin-variables" }, - { 's', flag, &silent_flag, 1, 1, 0, 0, &default_silent_flag, "silent" }, + "no-builtin-variables", 0 }, + { 's', flag, &silent_flag, 1, 1, 0, 0, &default_silent_flag, "silent", + &silent_origin }, { 'S', flag_off, &keep_going_flag, 1, 1, 0, 0, &default_keep_going_flag, - "no-keep-going" }, - { 't', flag, &touch_flag, 1, 1, 1, 0, 0, "touch" }, - { 'v', flag, &print_version_flag, 1, 0, 0, 0, 0, "version" }, + "no-keep-going", &keep_going_origin }, + { 't', flag, &touch_flag, 1, 1, 1, 0, 0, "touch", 0 }, + { 'v', flag, &print_version_flag, 1, 0, 0, 0, 0, "version", 0 }, { 'w', flag, &print_directory_flag, 1, 1, 0, 0, - &default_print_directory_flag, "print-directory" }, + &default_print_directory_flag, "print-directory", &print_directory_origin }, /* These options take arguments. */ - { 'C', filename, &directories, 0, 0, 0, 0, 0, "directory" }, - { 'f', filename, &makefiles, 0, 0, 0, 0, 0, "file" }, + { 'C', filename, &directories, 0, 0, 0, 0, 0, "directory", 0 }, + { 'f', filename, &makefiles, 0, 0, 0, 0, 0, "file", 0 }, { 'I', filename, &include_dirs, 1, 1, 0, 0, 0, - "include-dir" }, + "include-dir", 0 }, { 'j', positive_int, &arg_job_slots, 1, 1, 0, &inf_jobs, &default_job_slots, - "jobs" }, + "jobs", 0 }, { 'l', floating, &max_load_average, 1, 1, 0, &default_load_average, - &default_load_average, "load-average" }, - { 'o', filename, &old_files, 0, 0, 0, 0, 0, "old-file" }, - { 'O', string, &output_sync_option, 1, 1, 0, "target", 0, "output-sync" }, - { 'W', filename, &new_files, 0, 0, 0, 0, 0, "what-if" }, + &default_load_average, "load-average", 0 }, + { 'o', filename, &old_files, 0, 0, 0, 0, 0, "old-file", 0 }, + { 'O', string, &output_sync_option, 1, 1, 0, "target", 0, "output-sync", 0 }, + { 'W', filename, &new_files, 0, 0, 0, 0, 0, "what-if", 0 }, /* These are long-style options. */ - { CHAR_MAX+1, strlist, &db_flags, 1, 1, 0, "basic", 0, "debug" }, - { CHAR_MAX+2, string, &jobserver_auth, 1, 1, 0, 0, 0, JOBSERVER_AUTH_OPT }, - { CHAR_MAX+3, flag, &trace_flag, 1, 1, 0, 0, 0, "trace" }, + { CHAR_MAX+1, strlist, &db_flags, 1, 1, 0, "basic", 0, "debug", 0 }, + { CHAR_MAX+2, string, &jobserver_auth, 1, 1, 0, 0, 0, JOBSERVER_AUTH_OPT, 0 }, + { CHAR_MAX+3, flag, &trace_flag, 1, 1, 0, 0, 0, "trace", 0 }, { CHAR_MAX+4, flag_off, &print_directory_flag, 1, 1, 0, 0, - &default_print_directory_flag, "no-print-directory" }, + &default_print_directory_flag, "no-print-directory", &print_directory_origin }, { CHAR_MAX+5, flag, &warn_undefined_variables_flag, 1, 1, 0, 0, 0, - "warn-undefined-variables" }, - { CHAR_MAX+7, string, &sync_mutex, 1, 1, 0, 0, 0, "sync-mutex" }, + "warn-undefined-variables", 0 }, + { CHAR_MAX+7, string, &sync_mutex, 1, 1, 0, 0, 0, "sync-mutex", 0 }, { CHAR_MAX+8, flag_off, &silent_flag, 1, 1, 0, 0, &default_silent_flag, - "no-silent" }, - { CHAR_MAX+9, string, &jobserver_auth, 1, 0, 0, 0, 0, "jobserver-fds" }, + "no-silent", &silent_origin }, + { CHAR_MAX+9, string, &jobserver_auth, 1, 0, 0, 0, 0, "jobserver-fds", 0 }, /* There is special-case handling for this in decode_switches() as well. */ - { TEMP_STDIN_OPT, filename, &makefiles, 0, 0, 0, 0, 0, "temp-stdin" }, - { CHAR_MAX+11, string, &shuffle_mode, 1, 1, 0, "random", 0, "shuffle" }, - { CHAR_MAX+12, string, &jobserver_style, 1, 0, 0, 0, 0, "jobserver-style" }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0 } + { TEMP_STDIN_OPT, filename, &makefiles, 0, 0, 0, 0, 0, "temp-stdin", 0 }, + { CHAR_MAX+11, string, &shuffle_mode, 1, 1, 0, "random", 0, "shuffle", 0 }, + { CHAR_MAX+12, string, &jobserver_style, 1, 0, 0, 0, 0, "jobserver-style", 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; /* Secondary long names for options. */ @@ -3148,7 +3153,9 @@ decode_switches (int argc, const char **argv, enum variable_origin origin) this switch. We test this individually inside the switch below rather than just once outside it, so that options which are to be ignored still consume args. */ - int doit = origin == o_command || cs->env; + int doit = (origin == o_command + || (cs->env && + (cs->origin == NULL || origin >= *cs->origin))); switch (cs->type) { @@ -3161,7 +3168,11 @@ decode_switches (int argc, const char **argv, enum variable_origin origin) case flag: case flag_off: if (doit) - *(int *) cs->value_ptr = cs->type == flag; + { + *(int *) cs->value_ptr = cs->type == flag; + if (cs->origin) + *cs->origin = origin; + } break; case string: @@ -3194,6 +3205,8 @@ decode_switches (int argc, const char **argv, enum variable_origin origin) char **val = (char **)cs->value_ptr; free (*val); *val = xstrdup (coptarg); + if (cs->origin) + *cs->origin = origin; break; } @@ -3227,7 +3240,11 @@ decode_switches (int argc, const char **argv, enum variable_origin origin) } if (cs->type == strlist) - sl->list[sl->idx++] = xstrdup (coptarg); + { + sl->list[sl->idx++] = xstrdup (coptarg); + if (cs->origin) + *cs->origin = origin; + } else if (cs->c == TEMP_STDIN_OPT) { if (stdin_offset > 0) @@ -3235,9 +3252,15 @@ decode_switches (int argc, const char **argv, enum variable_origin origin) /* We don't need to expand the temp file. */ stdin_offset = sl->idx; sl->list[sl->idx++] = strcache_add (coptarg); + if (cs->origin) + *cs->origin = origin; } else - sl->list[sl->idx++] = expand_command_line_file (coptarg); + { + sl->list[sl->idx++] = expand_command_line_file (coptarg); + if (cs->origin) + *cs->origin = origin; + } sl->list[sl->idx] = 0; break; @@ -3269,11 +3292,19 @@ decode_switches (int argc, const char **argv, enum variable_origin origin) bad = 1; } else - *(unsigned int *) cs->value_ptr = i; + { + *(unsigned int *) cs->value_ptr = i; + if (cs->origin) + *cs->origin = origin; + } } else - *(unsigned int *) cs->value_ptr - = *(unsigned int *) cs->noarg_value; + { + *(unsigned int *) cs->value_ptr + = *(unsigned int *) cs->noarg_value; + if (cs->origin) + *cs->origin = origin; + } break; case floating: @@ -3282,8 +3313,12 @@ decode_switches (int argc, const char **argv, enum variable_origin origin) coptarg = argv[optind++]; if (doit) - *(double *) cs->value_ptr = (coptarg != 0 ? atof (coptarg) - : *(double *) cs->noarg_value); + { + *(double *) cs->value_ptr = (coptarg != 0 ? atof (coptarg) + : *(double *) cs->noarg_value); + if (cs->origin) + *cs->origin = origin; + } break; }