Formerly main.c.~66~

This commit is contained in:
Roland McGrath 1993-01-07 00:34:28 +00:00
parent e2622b0fea
commit adde98d27b

243
main.c
View File

@ -234,14 +234,13 @@ static struct command_switch switches[] =
{ 'f', string, (char *) &makefiles, 0, 0, 0, 0, 0, { 'f', string, (char *) &makefiles, 0, 0, 0, 0, 0,
"file", "FILE", "file", "FILE",
"Read FILE as a makefile" }, "Read FILE as a makefile" },
{ 'h', usage_and_exit, { 'h', usage_and_exit, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
"help", 0, "help", 0,
"Print this message and exit" }, "Print this message and exit" },
{ 'i', flag, (char *) &ignore_errors_flag, 1, 1, 0, 0, 0, { 'i', flag, (char *) &ignore_errors_flag, 1, 1, 0, 0, 0,
"ignore-errors", 0, "ignore-errors", 0,
"Ignore errors from commands" }, "Ignore errors from commands" },
{ 'I', string, (char *) &include_directories, 0, 0, 0, 0, 0, { 'I', string, (char *) &include_directories, 1, 0, 0, 0, 0,
"include-dir", "DIRECTORY", "include-dir", "DIRECTORY",
"Search DIRECTORY for included makefiles" }, "Search DIRECTORY for included makefiles" },
{ 'j', positive_int, (char *) &job_slots, 1, 1, 0, { 'j', positive_int, (char *) &job_slots, 1, 1, 0,
@ -284,7 +283,7 @@ static struct command_switch switches[] =
{ 't', flag, (char *) &touch_flag, 1, 1, 1, 0, 0, { 't', flag, (char *) &touch_flag, 1, 1, 1, 0, 0,
"touch", 0, "touch", 0,
"Touch targets instead of remaking them" }, "Touch targets instead of remaking them" },
{ 'v', flag, (char *) &print_version_flag, 0, 0, 0, 0, 0, { 'v', flag, (char *) &print_version_flag, 1, 0, 0, 0, 0,
"version", 0, "version", 0,
"Print the version number of make" }, "Print the version number of make" },
{ 'w', flag, (char *) &print_directory_flag, 1, 1, 0, 0, 0, { 'w', flag, (char *) &print_directory_flag, 1, 1, 0, 0, 0,
@ -358,6 +357,7 @@ main (argc, argv, envp)
char **argv; char **argv;
char **envp; char **envp;
{ {
extern void init_dir ();
extern RETSIGTYPE fatal_error_signal (), child_handler (); extern RETSIGTYPE fatal_error_signal (), child_handler ();
register struct file *f; register struct file *f;
register unsigned int i; register unsigned int i;
@ -473,7 +473,9 @@ main (argc, argv, envp)
/* Decode the switches. */ /* Decode the switches. */
decode_switches (argc, argv); decode_env_switches ("MAKEFLAGS", 9);
decode_env_switches ("MFLAGS", 6);
decode_switches (argc, argv, 0);
/* Print version information. */ /* Print version information. */
@ -545,7 +547,7 @@ main (argc, argv, envp)
if (cmd_defs_idx > 0) if (cmd_defs_idx > 0)
{ {
cmd_defs[cmd_defs_idx - 1] = '\0'; cmd_defs[cmd_defs_idx - 1] = '\0';
(void) define_variable ("MAKEOVERRIDES", 13, cmd_defs, o_override, 0); (void) define_variable ("MAKEOVERRIDES", 13, cmd_defs, o_default, 0);
} }
free (cmd_defs); free (cmd_defs);
@ -559,15 +561,15 @@ main (argc, argv, envp)
&& argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 0) && argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 0)
argv[0] = concat (current_directory, "/", argv[0]); argv[0] = concat (current_directory, "/", argv[0]);
(void) define_variable ("MAKE_COMMAND", 12, argv[0], o_env, 0); (void) define_variable ("MAKE_COMMAND", 12, argv[0], o_default, 0);
/* Append the command-line variable definitions gathered above /* Append the command-line variable definitions gathered above
so sub-makes will get them as command-line definitions. */ so sub-makes will get them as command-line definitions. */
(void) define_variable ("MAKE", 4, (void) define_variable ("MAKE", 4,
"$(MAKE_COMMAND) $(MAKEOVERRIDES)", o_env, 1); "$(MAKE_COMMAND) $(MAKEOVERRIDES)", o_default, 1);
/* If there were -c flags, move ourselves about. */ /* If there were -C flags, move ourselves about. */
if (directories != 0) if (directories != 0)
for (i = 0; directories->list[i] != 0; ++i) for (i = 0; directories->list[i] != 0; ++i)
@ -683,6 +685,7 @@ main (argc, argv, envp)
read_makefiles read_makefiles
= read_all_makefiles (makefiles == 0 ? (char **) 0 : makefiles->list); = read_all_makefiles (makefiles == 0 ? (char **) 0 : makefiles->list);
/* Decode switches again, in case the variables were set by the makefile. */
decode_env_switches ("MAKEFLAGS", 9); decode_env_switches ("MAKEFLAGS", 9);
decode_env_switches ("MFLAGS", 6); decode_env_switches ("MFLAGS", 6);
@ -1009,32 +1012,25 @@ main (argc, argv, envp)
return 0; return 0;
} }
/* Parsing of arguments, decoding of switches. */
static char options[sizeof (switches) / sizeof (switches[0]) * 3];
static struct option long_options[(sizeof (switches) / sizeof (switches[0])) +
(sizeof (long_option_aliases) /
sizeof (long_option_aliases[0]))];
/* Fill in the string and vector for getopt. */
static void static void
decode_switches (argc, argv) init_switches ()
int argc;
char **argv;
{ {
char bad = 0; register char *p;
register unsigned int i;
register struct command_switch *cs;
register struct stringlist *sl;
char *p;
char options[sizeof (switches) / sizeof (switches[0]) * 3];
struct option long_options[(sizeof (switches) / sizeof (switches[0])) +
(sizeof (long_option_aliases) /
sizeof (long_option_aliases[0]))];
register int c; register int c;
register unsigned int i;
decode_env_switches ("MAKEFLAGS", 9); if (options[0] != '\0')
decode_env_switches ("MFLAGS", 6); /* Already done. */
return;
other_args = (struct stringlist *) xmalloc (sizeof (struct stringlist));
other_args->max = argc + 1;
other_args->list = (char **) xmalloc ((argc + 1) * sizeof (char *));
other_args->idx = 1;
other_args->list[0] = savestring (argv[0], strlen (argv[0]));
/* Fill in the string and vector for getopt. */
p = options; p = options;
for (i = 0; switches[i].c != '\0'; ++i) for (i = 0; switches[i].c != '\0'; ++i)
{ {
@ -1071,8 +1067,42 @@ decode_switches (argc, argv)
++c) ++c)
long_options[i++] = long_option_aliases[c]; long_options[i++] = long_option_aliases[c];
long_options[i].name = 0; long_options[i].name = 0;
}
/* Decode switches from ARGC and ARGV.
They came from the environment if ENV is nonzero. */
static void
decode_switches (argc, argv, env)
int argc;
char **argv;
int env;
{
int bad = 0;
register struct command_switch *cs;
register struct stringlist *sl;
register int c;
if (!env)
{
other_args = (struct stringlist *) xmalloc (sizeof (struct stringlist));
other_args->max = argc + 1;
other_args->list = (char **) xmalloc ((argc + 1) * sizeof (char *));
other_args->idx = 1;
other_args->list[0] = savestring (argv[0], strlen (argv[0]));
}
/* getopt does most of the parsing for us.
First, get its vectors set up. */
init_switches ();
/* Let getopt produce error messages for the command line,
but not for options from the environment. */
opterr = !env;
/* Reset getopt's state. */
optind = 0;
/* getopt does most of the parsing for us. */
while ((c = getopt_long (argc, argv, while ((c = getopt_long (argc, argv,
options, long_options, (int *) 0)) != EOF) options, long_options, (int *) 0)) != EOF)
{ {
@ -1085,6 +1115,12 @@ decode_switches (argc, argv)
for (cs = switches; cs->c != '\0'; ++cs) for (cs = switches; cs->c != '\0'; ++cs)
if (cs->c == c) if (cs->c == c)
{ {
/* Whether or not we will actually do anything with
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 = !env || cs->env;
switch (cs->type) switch (cs->type)
{ {
default: default:
@ -1099,10 +1135,14 @@ decode_switches (argc, argv)
case flag: case flag:
case flag_off: case flag_off:
*(int *) cs->value_ptr = cs->type == flag; if (doit)
*(int *) cs->value_ptr = cs->type == flag;
break; break;
case string: case string:
if (!doit)
break;
if (optarg == 0) if (optarg == 0)
optarg = cs->noarg_value; optarg = cs->noarg_value;
@ -1131,14 +1171,19 @@ decode_switches (argc, argv)
if (optarg == 0 && argc > optind if (optarg == 0 && argc > optind
&& isdigit (argv[optind][0])) && isdigit (argv[optind][0]))
optarg = argv[optind++]; optarg = argv[optind++];
if (!doit)
break;
if (optarg != 0) if (optarg != 0)
{ {
int i = atoi (optarg); int i = atoi (optarg);
if (i < 1) if (i < 1)
{ {
error ("the `-%c' option requires a \ if (doit)
error ("the `-%c' option requires a \
positive integral argument", positive integral argument",
cs->c); cs->c);
bad = 1; bad = 1;
} }
else else
@ -1150,12 +1195,15 @@ positive integral argument",
break; break;
case floating: case floating:
*(double *) cs->value_ptr if (optarg == 0 && optind < argc
= (optarg != 0 ? atof (optarg) && (isdigit (argv[optind][0]) || argv[optind][0] == '.'))
: (optind < argc && (isdigit (argv[optind][0]) optarg = argv[optind++];
|| argv[optind][0] == '.'))
? atof (argv[optind++]) if (doit)
: *(double *) cs->noarg_value); *(double *) cs->value_ptr
= (optarg != 0 ? atof (optarg)
: *(double *) cs->noarg_value);
break; break;
} }
@ -1164,15 +1212,20 @@ positive integral argument",
} }
} }
while (optind < argc) if (!env)
{ {
char *arg = argv[optind++]; /* Collect the remaining args in the `other_args' string list. */
if (arg[0] != '-' || arg[1] != '\0')
other_args->list[other_args->idx++] = arg;
}
other_args->list[other_args->idx] = 0;
if (bad) while (optind < argc)
{
char *arg = argv[optind++];
if (arg[0] != '-' || arg[1] != '\0')
other_args->list[other_args->idx++] = arg;
}
other_args->list[other_args->idx] = 0;
}
if (bad && !env)
{ {
/* Print a nice usage message. */ /* Print a nice usage message. */
@ -1184,7 +1237,7 @@ positive integral argument",
fputs ("Options:\n", stderr); fputs ("Options:\n", stderr);
for (cs = switches; cs->c != '\0'; ++cs) for (cs = switches; cs->c != '\0'; ++cs)
{ {
char buf[1024], arg[50]; char buf[1024], arg[50], *p;
if (cs->description[0] == '-') if (cs->description[0] == '-')
continue; continue;
@ -1207,6 +1260,7 @@ positive integral argument",
p += strlen (p); p += strlen (p);
if (cs->long_name != 0) if (cs->long_name != 0)
{ {
unsigned int i;
sprintf (p, ", --%s%s", cs->long_name, arg); sprintf (p, ", --%s%s", cs->long_name, arg);
p += strlen (p); p += strlen (p);
for (i = 0; i < (sizeof (long_option_aliases) / for (i = 0; i < (sizeof (long_option_aliases) /
@ -1255,66 +1309,63 @@ positive integral argument",
} }
} }
/* Decode switches from environment variable ENVAR (which is LEN chars long).
We do this by chopping the value into a vector of words, prepending a
dash to the first word if it lacks one, and passing the vector to
decode_switches. */
static void static void
decode_env_switches (envar, len) decode_env_switches (envar, len)
char *envar; char *envar;
unsigned int len; unsigned int len;
{ {
struct variable *v; char *varref = alloca (2 + len + 2);
register char *args; char *value, *args;
register struct command_switch *cs; int argc;
char **argv;
v = lookup_variable (envar, len); /* Get the variable's value. */
if (v == 0 || *v->value == '\0') varref[0] = '$';
varref[1] = '(';
bcopy (envar, &varref[2], len);
varref[2 + len] = ')';
varref[2 + len + 1] = '\0';
value = variable_expand (varref);
/* Skip whitespace, and check for an empty value. */
value = next_token (value);
len = strlen (value);
if (len == 0)
return; return;
for (args = v->value; *args != '\0'; ++args) /* Make a copy of the value in ARGS, where we will munge it.
for (cs = switches; cs->c != '\0'; ++cs) If it does not begin with a dash, prepend one. */
if (cs->c == *args) args = (char *) alloca (1 + len + 2);
if (cs->env) if (value[0] != '-')
switch (cs->type) args[0] = '-';
{ bcopy (value, value[0] == '-' ? args : &args[1], len + 1);
case string: /* Write an extra null terminator so our loop below will
/* None of these allow environment changes. */ never be in danger of looking past the end of the string. */
default: args[(value[0] == '-' ? 0 : 1) + len + 1] = '\0';
abort ();
case flag: /* Allocate a vector that is definitely big enough. */
case flag_off: argv = (char **) alloca (len * sizeof (char *));
*(int *) cs->value_ptr = cs->type == flag; argc = 0;
break; do
case positive_int: {
while (isspace (args[1])) argv[argc++] = args;
++args; args = end_of_token (args);
if (isdigit(args[1])) *args++ = '\0';
{ } while (*args != '\0');
int i = atoi (&args[1]); argv[argc] = 0;
while (isdigit (args[1]))
++args; /* Parse those words. */
if (i >= 1) decode_switches (argc, argv, 1);
*(unsigned int *) cs->value_ptr = i;
}
else
*(unsigned int *) cs->value_ptr
= *(unsigned int *) cs->noarg_value;
break;
case floating:
while (isspace (args[1]))
++args;
if (args[1] == '.' || isdigit (args[1]))
{
*(double *) cs->value_ptr = atof (&args[1]);
while (args[1] == '.' || isdigit (args[1]))
++args;
}
else
*(double *) cs->value_ptr = *(double *) cs->noarg_value;
break;
}
} }
/* Define the MAKEFLAGS and MFLAGS variables to reflect the settings of the /* Define the MAKEFLAGS and MFLAGS variables to reflect the settings of the
command switches. Include positive_int and floating options if PF. command switches. Include positive_int and floating options if PF.
Don't include options with the `no_makefile' flag is if MAKEFILE. */ Don't include options with the `no_makefile' flag set if MAKEFILE. */
static void static void
define_makeflags (pf, makefile) define_makeflags (pf, makefile)